This appears to work ... maybe. slowly.

This commit is contained in:
2019-01-27 19:02:52 -08:00
parent 4af5446e80
commit 4529562cb8
7 changed files with 44889 additions and 34808 deletions

View File

@@ -17,7 +17,6 @@ impl ECCPrivate<P192>
ECCPrivate{ d }
}
pub fn sign<Hash>(&self, m: &[u8]) -> DSASignature<U192>
where
Hash: BlockInput + Clone + Default + Digest + FixedOutput + Input + Reset,
@@ -36,8 +35,11 @@ impl ECCPrivate<P192>
//
let h1 = <Hash>::digest(m);
let size = <P192>::size();
println!("h1: {:?}", h1);
let h0: U192 = bits2int(&h1, size);
println!("h0: {:X}", h0);
let h = h0 % <P192>::n();
println!("h: {:X}", h);
// 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
@@ -45,7 +47,7 @@ impl ECCPrivate<P192>
// process used to generate k. In plain DSA or ECDSA, k should
// be selected through a random selection that chooses a value
// 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
// parameters:
// * For DSA ...
@@ -53,6 +55,7 @@ impl ECCPrivate<P192>
//
// If r turns out to be zero, a new k should be selected and r
// computed again (this is an utterly improbable occurrence).
println!("k: {:X}", k);
let g = Point::<P192>::default();
let ki = I192::new(false, k.clone());
let kg = g.scale(&ki);
@@ -74,11 +77,69 @@ impl ECCPrivate<P192>
if let Some(kinv) = k.modinv(&n) {
let xr = &self.d * &r;
let hxr = U384::from(&h) + xr;
let base = U192::from(hxr * U448::from(kinv));
let s = base % n;
let base = hxr * U448::from(kinv);
let s = U192::from(base % U896::from(n));
return DSASignature{ r, s };
}
}
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");
});
}
}

View File

@@ -8,13 +8,14 @@ import Crypto.Number.Generate(generateBetween)
import Crypto.PubKey.ECC.ECDSA(PrivateKey(..),PublicKey(..),Signature(..),signWith)
import Crypto.PubKey.ECC.Generate(generate)
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 qualified Data.ByteString as S
import qualified Data.Map.Strict as Map
import Math(showX,showBin)
import RFC6979(generateKStream)
import Task(Task(..))
import Utils(HashAlg(..),generateHash,showHash)
import Utils(HashAlg(..),generateHash,runHash,showHash)
curves :: [(String, Curve)]
curves = [("P192", getCurveByName SEC_p192r1),
@@ -124,18 +125,27 @@ signTest name curve = Task {
(msg, drg2) = withDRG drg1 $ do x <- generateBetween 0 256
getRandomBytes (fromIntegral x)
(hash, drg3) = withDRG drg2 generateHash
k = 5
in case signWith' k priv hash msg of
Nothing -> go (memory0, drg3)
n = ecc_n (common_curve curve)
PrivateKey _ d = priv
kStream = generateKStream hash msg d n (curveSizeBits curve)
findGoodK stream =
case stream of
[] ->
go (memory0, drg3)
(k : restks) ->
case signWith' k priv hash msg of
Nothing ->
findGoodK restks
Just sig ->
let PublicKey _ (Point x y) = pub
PrivateKey _ d = priv
res = Map.fromList [("d", showX d),
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' k priv Sha224 msg = signWith k priv SHA224 msg

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff