[BROKEN] Start adding support for ECDSA public keys.
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
pub mod curve;
|
||||
pub mod point;
|
||||
pub mod private;
|
||||
pub mod public;
|
||||
@@ -7,6 +7,7 @@ pub trait ECCPoint {
|
||||
type Scale;
|
||||
|
||||
fn default() -> Self;
|
||||
fn double_scalar_mult(x1: &Self::Scale, p1: &Self, x2: &Self::Scale, p2: &Self) -> Self;
|
||||
fn negate(&self) -> Self;
|
||||
fn double(&self) -> Self;
|
||||
fn add(&self, other: &Self) -> Self;
|
||||
@@ -46,6 +47,42 @@ 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>
|
||||
{
|
||||
let mut newy = $base::new(false, $curve::p());
|
||||
@@ -234,6 +271,47 @@ macro_rules! point_tests
|
||||
assert_eq!(b, res.y, "y equivalence");
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn add_scale2() {
|
||||
let fname = build_test_path("ecc/add_scale2",stringify!($curve));
|
||||
run_test(fname.to_string(), 8, |case| {
|
||||
println!("-----------------------------------------------");
|
||||
let (negx, xbytes) = case.get("x").unwrap();
|
||||
let (negy, ybytes) = case.get("y").unwrap();
|
||||
let (negp, pbytes) = case.get("p").unwrap();
|
||||
let (negq, qbytes) = case.get("q").unwrap();
|
||||
let (negn, nbytes) = case.get("n").unwrap();
|
||||
let (negm, mbytes) = case.get("m").unwrap();
|
||||
let (negr, rbytes) = case.get("r").unwrap();
|
||||
let (negs, sbytes) = case.get("s").unwrap();
|
||||
|
||||
let x = $stype::new(*negx, $utype::from_bytes(xbytes));
|
||||
let y = $stype::new(*negy, $utype::from_bytes(ybytes));
|
||||
println!("x1: {:X}", x);
|
||||
println!("y1: {:X}", y);
|
||||
let p = $stype::new(*negp, $utype::from_bytes(pbytes));
|
||||
let q = $stype::new(*negq, $utype::from_bytes(qbytes));
|
||||
println!("x2: {:X}", p);
|
||||
println!("y2: {:X}", q);
|
||||
let n = $stype::new(*negn, $utype::from_bytes(nbytes));
|
||||
println!("n: {:X}", n);
|
||||
let m = $stype::new(*negm, $utype::from_bytes(mbytes));
|
||||
println!("m: {:X}", m);
|
||||
let r = $stype::new(*negr, $utype::from_bytes(rbytes));
|
||||
let s = $stype::new(*negs, $utype::from_bytes(sbytes));
|
||||
println!("rx: {:X}", r);
|
||||
println!("ry: {:X}", s);
|
||||
let p1 = Point::<$curve>{ x: x, y: y };
|
||||
let p2 = Point::<$curve>{ x: p, y: q };
|
||||
let res = Point::<$curve>::double_scalar_mult(&n, &p1, &m, &p2);
|
||||
println!("mx: {:X}", res.x);
|
||||
println!("my: {:X}", res.y);
|
||||
assert_eq!(r, res.x, "x equivalence");
|
||||
assert_eq!(s, res.y, "y equivalence");
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
68
src/ecdsa/public.rs
Normal file
68
src/ecdsa/public.rs
Normal file
@@ -0,0 +1,68 @@
|
||||
use cryptonum::signed::*;
|
||||
use cryptonum::unsigned::*;
|
||||
use digest::{BlockInput,Digest,Input,FixedOutput,Reset};
|
||||
use dsa::rfc6979::{DSASignature,KIterator,bits2int};
|
||||
use ecdsa::curve::{EllipticCurve,P192,P224,P256,P384,P521};
|
||||
use ecdsa::point::{ECCPoint,Point};
|
||||
use hmac::{Hmac,Mac};
|
||||
use std::cmp::min;
|
||||
|
||||
pub struct ECCPublic<Curve: EllipticCurve> {
|
||||
q: Point<Curve>
|
||||
}
|
||||
|
||||
pub trait ECCPublicKey {
|
||||
type Curve : EllipticCurve;
|
||||
type Unsigned;
|
||||
|
||||
fn new(d: Point<Self::Curve>) -> Self;
|
||||
fn verify<Hash>(&self, m: &[u8], sig: DSASignature<Self::Unsigned>) -> bool
|
||||
where
|
||||
Hash: BlockInput + Clone + Default + Digest + FixedOutput + Input + Reset,
|
||||
Hmac<Hash>: Mac;
|
||||
}
|
||||
|
||||
impl ECCPublicKey for ECCPublic<P192>
|
||||
{
|
||||
type Curve = P192;
|
||||
type Unsigned = U192;
|
||||
|
||||
fn new(q: Point<P192>) -> ECCPublic<P192>
|
||||
{
|
||||
ECCPublic{ q }
|
||||
}
|
||||
|
||||
fn verify<Hash>(&self, m: &[u8], sig: DSASignature<Self::Unsigned>) -> bool
|
||||
where
|
||||
Hash: BlockInput + Clone + Default + Digest + FixedOutput + Input + Reset,
|
||||
Hmac<Hash>: Mac
|
||||
{
|
||||
let n = <P192>::n();
|
||||
|
||||
if sig.r.is_zero() || (sig.r >= n) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if sig.s.is_zero() || (sig.s >= n) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// e = the leftmost min(N, outlen) bits of Hash(M').
|
||||
let mut digest_bytes = <Hash>::digest(m).to_vec();
|
||||
let len = min(digest_bytes.len(), P192::size() / 8);
|
||||
digest_bytes.truncate(len);
|
||||
|
||||
if let Some(c) = sig.s.modinv(&n) {
|
||||
let e = U192::from_bytes(&digest_bytes);
|
||||
let u1 = e.modmul(&c, &n);
|
||||
let u2 = sig.r.modmul(&c, &n);
|
||||
let g = Point::<P192>::default();
|
||||
let u1i = I192::from(u1);
|
||||
let u2i = I192::from(u2);
|
||||
let point = Point::<P192>::double_scalar_mult(&u1i, &g, &u2i, &self.q);
|
||||
!point.x.is_negative() && (sig.r == U192::from(point.x))
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user