This appears to work ... maybe. slowly.
This commit is contained in:
@@ -17,7 +17,6 @@ impl ECCPrivate<P192>
|
|||||||
ECCPrivate{ d }
|
ECCPrivate{ d }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
pub fn sign<Hash>(&self, m: &[u8]) -> DSASignature<U192>
|
pub fn sign<Hash>(&self, m: &[u8]) -> DSASignature<U192>
|
||||||
where
|
where
|
||||||
Hash: BlockInput + Clone + Default + Digest + FixedOutput + Input + Reset,
|
Hash: BlockInput + Clone + Default + Digest + FixedOutput + Input + Reset,
|
||||||
@@ -36,8 +35,11 @@ impl ECCPrivate<P192>
|
|||||||
//
|
//
|
||||||
let h1 = <Hash>::digest(m);
|
let h1 = <Hash>::digest(m);
|
||||||
let size = <P192>::size();
|
let size = <P192>::size();
|
||||||
|
println!("h1: {:?}", h1);
|
||||||
let h0: U192 = bits2int(&h1, size);
|
let h0: U192 = bits2int(&h1, size);
|
||||||
|
println!("h0: {:X}", h0);
|
||||||
let h = h0 % <P192>::n();
|
let h = h0 % <P192>::n();
|
||||||
|
println!("h: {:X}", h);
|
||||||
|
|
||||||
// 2. A random value modulo q, dubbed k, is generated. That value
|
// 2. A random value modulo q, dubbed k, is generated. That value
|
||||||
// shall not be 0; hence, it lies in the [1, q-1] range. Most
|
// shall not be 0; hence, it lies in the [1, q-1] range. Most
|
||||||
@@ -45,7 +47,7 @@ impl ECCPrivate<P192>
|
|||||||
// process used to generate k. In plain DSA or ECDSA, k should
|
// process used to generate k. In plain DSA or ECDSA, k should
|
||||||
// be selected through a random selection that chooses a value
|
// be selected through a random selection that chooses a value
|
||||||
// among the q-1 possible values with uniform probability.
|
// among the q-1 possible values with uniform probability.
|
||||||
for k in KIterator::<Hash,U192>::new(&h1, size, &<P192>::n(), &<P192>::b()) {
|
for k in KIterator::<Hash,U192>::new(&h1, size, &<P192>::n(), &self.d) {
|
||||||
// 3. A value r (modulo q) is computed from k and the key
|
// 3. A value r (modulo q) is computed from k and the key
|
||||||
// parameters:
|
// parameters:
|
||||||
// * For DSA ...
|
// * For DSA ...
|
||||||
@@ -53,6 +55,7 @@ impl ECCPrivate<P192>
|
|||||||
//
|
//
|
||||||
// If r turns out to be zero, a new k should be selected and r
|
// If r turns out to be zero, a new k should be selected and r
|
||||||
// computed again (this is an utterly improbable occurrence).
|
// computed again (this is an utterly improbable occurrence).
|
||||||
|
println!("k: {:X}", k);
|
||||||
let g = Point::<P192>::default();
|
let g = Point::<P192>::default();
|
||||||
let ki = I192::new(false, k.clone());
|
let ki = I192::new(false, k.clone());
|
||||||
let kg = g.scale(&ki);
|
let kg = g.scale(&ki);
|
||||||
@@ -74,11 +77,69 @@ impl ECCPrivate<P192>
|
|||||||
if let Some(kinv) = k.modinv(&n) {
|
if let Some(kinv) = k.modinv(&n) {
|
||||||
let xr = &self.d * &r;
|
let xr = &self.d * &r;
|
||||||
let hxr = U384::from(&h) + xr;
|
let hxr = U384::from(&h) + xr;
|
||||||
let base = U192::from(hxr * U448::from(kinv));
|
let base = hxr * U448::from(kinv);
|
||||||
let s = base % n;
|
let s = U192::from(base % U896::from(n));
|
||||||
return DSASignature{ r, s };
|
return DSASignature{ r, s };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
panic!("The world is broken; couldn't find a k in sign().");
|
panic!("The world is broken; couldn't find a k in sign().");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use sha2::{Sha224,Sha256,Sha384,Sha512};
|
||||||
|
use super::*;
|
||||||
|
use testing::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn p192_sign() {
|
||||||
|
let fname = build_test_path("ecc/sign","P192");
|
||||||
|
run_test(fname.to_string(), 9, |case| {
|
||||||
|
let (negd, dbytes) = case.get("d").unwrap();
|
||||||
|
let (negk, kbytes) = case.get("k").unwrap();
|
||||||
|
let (negx, xbytes) = case.get("x").unwrap();
|
||||||
|
let (negy, ybytes) = case.get("y").unwrap();
|
||||||
|
let (negm, mbytes) = case.get("m").unwrap();
|
||||||
|
let (negh, hbytes) = case.get("h").unwrap();
|
||||||
|
let (negr, rbytes) = case.get("r").unwrap();
|
||||||
|
let (negs, sbytes) = case.get("s").unwrap();
|
||||||
|
|
||||||
|
assert!(!negd && !negk && !negx && !negy &&
|
||||||
|
!negm && !negh && !negr && !negs);
|
||||||
|
let d = U192::from_bytes(dbytes);
|
||||||
|
let _ = U192::from_bytes(xbytes);
|
||||||
|
let _ = U192::from_bytes(ybytes);
|
||||||
|
let h = U192::from_bytes(hbytes);
|
||||||
|
let r = U192::from_bytes(rbytes);
|
||||||
|
let s = U192::from_bytes(sbytes);
|
||||||
|
|
||||||
|
{
|
||||||
|
let (negn, nbytes) = case.get("n").unwrap();
|
||||||
|
println!("nbytes<{}>: {:?}", usize::from(h.clone()), nbytes);
|
||||||
|
println!("hash<224>: {:?}", Sha224::digest(mbytes));
|
||||||
|
println!("hash<256>: {:?}", Sha256::digest(mbytes));
|
||||||
|
println!("hash<384>: {:?}", Sha384::digest(mbytes));
|
||||||
|
println!("hash<512>: {:?}", Sha512::digest(mbytes));
|
||||||
|
println!("kbytes: {:?}", kbytes);
|
||||||
|
let k = U192::from_bytes(kbytes);
|
||||||
|
println!("k: {:X}", k);
|
||||||
|
println!("target r: {:X}", r);
|
||||||
|
println!("target s: {:X}", s);
|
||||||
|
}
|
||||||
|
|
||||||
|
let private = ECCPrivate::new(d);
|
||||||
|
let sig = match usize::from(h) {
|
||||||
|
224 => private.sign::<Sha224>(mbytes),
|
||||||
|
256 => private.sign::<Sha256>(mbytes),
|
||||||
|
384 => private.sign::<Sha384>(mbytes),
|
||||||
|
512 => private.sign::<Sha512>(mbytes),
|
||||||
|
x => panic!("Unknown hash algorithm {}", x)
|
||||||
|
};
|
||||||
|
println!("my r: {:X}", sig.r);
|
||||||
|
println!("my s: {:X}", sig.s);
|
||||||
|
assert_eq!(r, sig.r, "r signature check");
|
||||||
|
assert_eq!(s, sig.s, "s signature check");
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -8,13 +8,14 @@ import Crypto.Number.Generate(generateBetween)
|
|||||||
import Crypto.PubKey.ECC.ECDSA(PrivateKey(..),PublicKey(..),Signature(..),signWith)
|
import Crypto.PubKey.ECC.ECDSA(PrivateKey(..),PublicKey(..),Signature(..),signWith)
|
||||||
import Crypto.PubKey.ECC.Generate(generate)
|
import Crypto.PubKey.ECC.Generate(generate)
|
||||||
import Crypto.PubKey.ECC.Prim(scalarGenerate,pointAdd,pointNegate,pointDouble,pointBaseMul,pointMul)
|
import Crypto.PubKey.ECC.Prim(scalarGenerate,pointAdd,pointNegate,pointDouble,pointBaseMul,pointMul)
|
||||||
import Crypto.PubKey.ECC.Types(Curve,CurveName(..),Point(..),getCurveByName)
|
import Crypto.PubKey.ECC.Types(Curve,CurveName(..),Point(..),common_curve,curveSizeBits,ecc_n,getCurveByName)
|
||||||
import Crypto.Random(DRG(..),getRandomBytes,withDRG)
|
import Crypto.Random(DRG(..),getRandomBytes,withDRG)
|
||||||
import qualified Data.ByteString as S
|
import qualified Data.ByteString as S
|
||||||
import qualified Data.Map.Strict as Map
|
import qualified Data.Map.Strict as Map
|
||||||
import Math(showX,showBin)
|
import Math(showX,showBin)
|
||||||
|
import RFC6979(generateKStream)
|
||||||
import Task(Task(..))
|
import Task(Task(..))
|
||||||
import Utils(HashAlg(..),generateHash,showHash)
|
import Utils(HashAlg(..),generateHash,runHash,showHash)
|
||||||
|
|
||||||
curves :: [(String, Curve)]
|
curves :: [(String, Curve)]
|
||||||
curves = [("P192", getCurveByName SEC_p192r1),
|
curves = [("P192", getCurveByName SEC_p192r1),
|
||||||
@@ -124,18 +125,27 @@ signTest name curve = Task {
|
|||||||
(msg, drg2) = withDRG drg1 $ do x <- generateBetween 0 256
|
(msg, drg2) = withDRG drg1 $ do x <- generateBetween 0 256
|
||||||
getRandomBytes (fromIntegral x)
|
getRandomBytes (fromIntegral x)
|
||||||
(hash, drg3) = withDRG drg2 generateHash
|
(hash, drg3) = withDRG drg2 generateHash
|
||||||
k = 5
|
n = ecc_n (common_curve curve)
|
||||||
in case signWith' k priv hash msg of
|
PrivateKey _ d = priv
|
||||||
Nothing -> go (memory0, drg3)
|
kStream = generateKStream hash msg d n (curveSizeBits curve)
|
||||||
Just sig ->
|
findGoodK stream =
|
||||||
let PublicKey _ (Point x y) = pub
|
case stream of
|
||||||
PrivateKey _ d = priv
|
[] ->
|
||||||
res = Map.fromList [("d", showX d),
|
go (memory0, drg3)
|
||||||
("x", showX x), ("y", showX y),
|
(k : restks) ->
|
||||||
("m", showBin msg), ("h", showHash hash),
|
case signWith' k priv hash msg of
|
||||||
("r", showX (sign_r sig)),
|
Nothing ->
|
||||||
("s", showX (sign_s sig))]
|
findGoodK restks
|
||||||
in (res, d, (memory0, drg3))
|
Just sig ->
|
||||||
|
let PublicKey _ (Point x y) = pub
|
||||||
|
res = Map.fromList [("d", showX d), ("k", showX k),
|
||||||
|
("x", showX x), ("y", showX y),
|
||||||
|
("m", showBin msg), ("h", showHash hash),
|
||||||
|
("n", showBin (runHash hash msg)),
|
||||||
|
("r", showX (sign_r sig)),
|
||||||
|
("s", showX (sign_s sig))]
|
||||||
|
in (res, d, (memory0, drg3))
|
||||||
|
in findGoodK kStream
|
||||||
|
|
||||||
signWith' :: Integer -> PrivateKey -> HashAlg -> S.ByteString -> Maybe Signature
|
signWith' :: Integer -> PrivateKey -> HashAlg -> S.ByteString -> Maybe Signature
|
||||||
signWith' k priv Sha224 msg = signWith k priv SHA224 msg
|
signWith' k priv Sha224 msg = signWith k priv SHA224 msg
|
||||||
|
|||||||
16016
testdata/ecc/sign/P192.test
vendored
16016
testdata/ecc/sign/P192.test
vendored
File diff suppressed because it is too large
Load Diff
15868
testdata/ecc/sign/P224.test
vendored
15868
testdata/ecc/sign/P224.test
vendored
File diff suppressed because it is too large
Load Diff
15912
testdata/ecc/sign/P256.test
vendored
15912
testdata/ecc/sign/P256.test
vendored
File diff suppressed because it is too large
Load Diff
15856
testdata/ecc/sign/P384.test
vendored
15856
testdata/ecc/sign/P384.test
vendored
File diff suppressed because it is too large
Load Diff
15938
testdata/ecc/sign/P521.test
vendored
15938
testdata/ecc/sign/P521.test
vendored
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user