[FIXED] Fairly ridiculous implementation of ECDSA verification
This commit is contained in:
@@ -2,16 +2,22 @@ use cryptonum::signed::*;
|
|||||||
use cryptonum::unsigned::*;
|
use cryptonum::unsigned::*;
|
||||||
use ecdsa::curve::*;
|
use ecdsa::curve::*;
|
||||||
|
|
||||||
pub trait ECCPoint {
|
pub trait ECCPoint : Sized {
|
||||||
type Curve: EllipticCurve;
|
type Curve: EllipticCurve;
|
||||||
type Scale;
|
type Scale;
|
||||||
|
|
||||||
fn default() -> Self;
|
fn default() -> Self;
|
||||||
fn double_scalar_mult(x1: &Self::Scale, p1: &Self, x2: &Self::Scale, p2: &Self) -> Self;
|
|
||||||
fn negate(&self) -> Self;
|
fn negate(&self) -> Self;
|
||||||
fn double(&self) -> Self;
|
fn double(&self) -> Self;
|
||||||
fn add(&self, other: &Self) -> Self;
|
fn add(&self, other: &Self) -> Self;
|
||||||
fn scale(&self, amt: &Self::Scale) -> Self;
|
fn scale(&self, amt: &Self::Scale) -> Self;
|
||||||
|
fn double_scalar_mult(x1: &Self::Scale, p1: &Self, x2: &Self::Scale, p2: &Self) -> Self
|
||||||
|
{
|
||||||
|
// FIXME: Replace this with something not stupid.
|
||||||
|
let big1 = p1.scale(x1);
|
||||||
|
let big2 = p2.scale(x2);
|
||||||
|
big1.add(&big2)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Point<T: EllipticCurve>
|
pub struct Point<T: EllipticCurve>
|
||||||
@@ -47,42 +53,6 @@ macro_rules! point_impl
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn double_scalar_mult(x1: &$base, p1: &Self, x2: &$base, p2: &Self) -> Self
|
|
||||||
{
|
|
||||||
if x1.is_negative() {
|
|
||||||
return Point::<$curve>::double_scalar_mult(&x1.abs(), &p1.negate(), x2, p2);
|
|
||||||
}
|
|
||||||
|
|
||||||
if x2.is_negative() {
|
|
||||||
return Point::<$curve>::double_scalar_mult(x1, p2, &x2.abs(), &p2.negate());
|
|
||||||
}
|
|
||||||
|
|
||||||
let p0 = p1.add(p2);
|
|
||||||
let mut i = $curve::size() - 1;
|
|
||||||
|
|
||||||
// Find the point where we should start our loop
|
|
||||||
assert!(!x1.is_zero() || !x2.is_zero());
|
|
||||||
while x1.testbit(i) || x2.testbit(i) { i -= 1; }
|
|
||||||
// our base value is the addition of the input points
|
|
||||||
let mut acc = p1.add(&p2);
|
|
||||||
loop {
|
|
||||||
let q = acc.double();
|
|
||||||
|
|
||||||
match (x1.testbit(i), x2.testbit(i)) {
|
|
||||||
(true, true) => acc = p0.add(&q),
|
|
||||||
(true, false) => acc = p1.add(&q),
|
|
||||||
(false, true) => acc = p2.add(&q),
|
|
||||||
(false, false) => acc = q
|
|
||||||
}
|
|
||||||
|
|
||||||
if i == 0 {
|
|
||||||
return acc;
|
|
||||||
} else {
|
|
||||||
i -= 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn negate(&self) -> Point<$curve>
|
fn negate(&self) -> Point<$curve>
|
||||||
{
|
{
|
||||||
let mut newy = $base::new(false, $curve::p());
|
let mut newy = $base::new(false, $curve::p());
|
||||||
|
|||||||
@@ -66,3 +66,43 @@ impl ECCPublicKey for ECCPublic<P192>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
use sha2::{Sha224,Sha256,Sha384,Sha512};
|
||||||
|
#[cfg(test)]
|
||||||
|
use testing::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn p192() {
|
||||||
|
let fname = build_test_path("ecc/sign",stringify!(P192));
|
||||||
|
run_test(fname.to_string(), 9, |case| {
|
||||||
|
let (negd, dbytes) = case.get("d").unwrap();
|
||||||
|
let (negk, _bytes) = 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 _ = U192::from_bytes(dbytes);
|
||||||
|
let x = U192::from_bytes(xbytes);
|
||||||
|
let y = U192::from_bytes(ybytes);
|
||||||
|
let h = U192::from_bytes(hbytes);
|
||||||
|
let r = U192::from_bytes(rbytes);
|
||||||
|
let s = U192::from_bytes(sbytes);
|
||||||
|
|
||||||
|
let point = Point::<P192>{ x: I192::from(x), y: I192::from(y) };
|
||||||
|
let public = ECCPublic::<P192>::new(point);
|
||||||
|
let sig = DSASignature::new(r, s);
|
||||||
|
match usize::from(h) {
|
||||||
|
224 => assert!(public.verify::<Sha224>(mbytes, sig)),
|
||||||
|
256 => assert!(public.verify::<Sha256>(mbytes, sig)),
|
||||||
|
384 => assert!(public.verify::<Sha384>(mbytes, sig)),
|
||||||
|
512 => assert!(public.verify::<Sha512>(mbytes, sig)),
|
||||||
|
x => panic!("Unknown hash algorithm {}", x)
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user