[BROKEN] Trying to get elliptic curve working, which is much too slow at the moment.

This commit is contained in:
2018-05-31 18:37:18 +01:00
parent dde1092f49
commit bdf7f81b20
16 changed files with 99817 additions and 19350 deletions

View File

@@ -1,4 +1,4 @@
use cryptonum::unsigned::{UCN,divmod};
use cryptonum::unsigned::{BarrettUCN,UCN,divmod};
use num::BigInt;
use num::bigint::Sign;
use std::fmt;
@@ -67,14 +67,27 @@ impl SCN {
(old_r, old_s, old_t)
}
pub fn divmod(&self, x: &SCN, m: &UCN) -> SCN {
let sm = SCN::from(m.clone());
let xmod = x % &sm;
pub fn reduce(&self, m: &BarrettUCN) -> SCN {
println!("signed reduce");
SCN{ negative: false, value: self.value.reduce(m) }
}
pub fn divmod(&self, x: &SCN, m: &BarrettUCN) -> SCN {
println!("STEP1");
let xmod = x.reduce(m);
println!("STEP2");
assert!(!xmod.negative);
let i = xmod.value.modinv(&m);
println!("STEP3");
let i = xmod.value.modinv(&m.m);
println!("STEP4");
let si = SCN::from(i);
println!("STEP5");
let yi = self * si;
yi % sm
println!("STEP6: {:X}", yi);
println!(" mod {:X}", m.m);
let res = yi.reduce(m);
println!("STEP7");
res
}
}

View File

@@ -132,34 +132,54 @@ impl UCN {
pub fn barrett_u(&self) -> BarrettUCN {
let k = self.contents.len();
self.barrett_uk(k)
}
pub fn barrett_uk(&self, k: usize) -> BarrettUCN {
let b = UCN::from(1 as u8) << (64 * 2 * k);
let u = b / self;
BarrettUCN{ u: u, k: k, m: self.clone() }
}
pub fn reduce(&self, u: &BarrettUCN) -> UCN {
println!("unsigned reduce");
println!(" self: {:X} ({})", self, self.contents.len());
println!(" m: {:X} ({})", u.m, u.m.contents.len());
// 1. q1←⌊x/bk1⌋, q2←q1 · μ, q3←⌊q2/bk+1⌋.
let q1 = self >> (64 * (u.k - 1));
println!("reduce1");
let q2 = q1 * &u.u;
println!("reduce2");
let q3 = q2 >> (64 * (u.k + 1));
println!("reduce3");
// 2. r1←x mod bk+1, r2←q3 · m mod bk+1, r←r1 r2.
// 3. If r<0 then r←r+bk+1.
let mut r1 = self.clone();
r1.contents.resize(u.k + 1, 0);
println!("reduce4");
let mut r2 = q3 * &u.m;
r2.contents.resize(u.k + 1, 0);
println!("reduce5");
println!(" r1: {:X}", r1);
println!(" r2: {:X}", r2);
let mut r = if r1 >= r2 {
println!("reduce5a");
r1 - r2
} else {
println!("reduce5b");
let mut bk1cont = Vec::with_capacity(u.k + 1);
bk1cont.resize(u.k, 0);
bk1cont.push(1);
(r1 + UCN{ contents: bk1cont }) - r2
};
println!("reduce6");
println!(" r = {:X}", r);
println!(" m = {:X}", u.m);
// 4. Whiler≥mdo:r←rm.
while &r >= &u.m {
r -= &u.m;
}
println!("reduce7");
// 5. Return(r).
r
}
@@ -881,6 +901,7 @@ pub fn divmod(quotient: &mut Vec<u64>, remainder: &mut Vec<u64>,
let qit1 = UCN{ contents: vec![q[i - t - 1]] };
let ybit1 = &y << (64 * (i - t - 1));
let subbit = &qit1 * &ybit1;
let orig_x_len = x.contents.len();
if subbit <= x {
x -= subbit;
} else {
@@ -889,6 +910,9 @@ pub fn divmod(quotient: &mut Vec<u64>, remainder: &mut Vec<u64>,
x -= subbit - ybit1;
q[i - t - 1] -= 1;
}
while x.contents.len() < orig_x_len {
x.contents.insert(0, 0);
}
i -= 1;
}
// 4. r <- x
@@ -898,6 +922,7 @@ pub fn divmod(quotient: &mut Vec<u64>, remainder: &mut Vec<u64>,
// everything earlier; this removes it.
x.contents.remove(0);
}
x.clean();
remainder.append(&mut x.contents);
// 5. return (q,r)
while (q.len() > 0) && (q[q.len() - 1] == 0) {

View File

@@ -1,216 +1,374 @@
use cryptonum::{SCN,UCN};
use cryptonum::{BarrettUCN,SCN,UCN};
use ecdsa::point::ECPoint;
use std::fmt;
#[allow(non_snake_case)]
#[derive(Clone,Debug,PartialEq)]
pub struct EllipticCurve {
pub p: UCN,
pub n: UCN,
pub SEED: UCN,
pub c: UCN,
pub a: UCN,
pub b: UCN,
pub Gx: SCN,
pub Gy: SCN
pub name: &'static str,
pub p: [u8; 66],
pub n: [u8; 66],
pub seed: [u8; 66],
pub c: [u8; 66],
pub a: [u8; 66],
pub b: [u8; 66],
pub gx: [u8; 66],
pub gy: [u8; 66]
}
impl fmt::Debug for EllipticCurve {
fn fmt (&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.name)
}
}
impl PartialEq for EllipticCurve {
fn eq(&self, other: &EllipticCurve) -> bool {
self.name == other.name
}
}
impl EllipticCurve {
/// Create a new elliptic curve structure that represents NIST's
/// p192 curve.
pub fn p192() -> EllipticCurve {
EllipticCurve {
p: UCN::from_bytes(&vec![
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]),
n: UCN::from_bytes(&vec![
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0x99, 0xde, 0xf8, 0x36,
0x14, 0x6b, 0xc9, 0xb1, 0xb4, 0xd2, 0x28, 0x31]),
SEED: UCN::from_bytes(&vec![
0x30, 0x45, 0xae, 0x6f, 0xc8, 0x42, 0x2f, 0x64,
0xed, 0x57, 0x95, 0x28, 0xd3, 0x81, 0x20, 0xea,
0xe1, 0x21, 0x96, 0xd5]),
c: UCN::from_bytes(&vec![
0x30, 0x99, 0xd2, 0xbb, 0xbf, 0xcb, 0x25, 0x38,
0x54, 0x2d, 0xcd, 0x5f, 0xb0, 0x78, 0xb6, 0xef,
0x5f, 0x3d, 0x6f, 0xe2, 0xc7, 0x45, 0xde, 0x65]),
a: UCN::from_bytes(&vec![
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc]),
b: UCN::from_bytes(&vec![
0x64, 0x21, 0x05, 0x19, 0xe5, 0x9c, 0x80, 0xe7,
0x0f, 0xa7, 0xe9, 0xab, 0x72, 0x24, 0x30, 0x49,
0xfe, 0xb8, 0xde, 0xec, 0xc1, 0x46, 0xb9, 0xb1]),
Gx: SCN::from(UCN::from_bytes(&vec![
0x18, 0x8d, 0xa8, 0x0e, 0xb0, 0x30, 0x90, 0xf6,
0x7c, 0xbf, 0x20, 0xeb, 0x43, 0xa1, 0x88, 0x00,
0xf4, 0xff, 0x0a, 0xfd, 0x82, 0xff, 0x10, 0x12])),
Gy: SCN::from(UCN::from_bytes(&vec![
0x07, 0x19, 0x2b, 0x95, 0xff, 0xc8, 0xda, 0x78,
0x63, 0x10, 0x11, 0xed, 0x6b, 0x24, 0xcd, 0xd5,
0x73, 0xf9, 0x77, 0xa1, 0x1e, 0x79, 0x48, 0x11]))
}
pub fn get_p(&self) -> UCN {
UCN::from_bytes(&self.p)
}
/// Create a new elliptic curve structure that represents NIST's
/// p224 curve.
pub fn p224() -> EllipticCurve {
EllipticCurve {
p: UCN::from_bytes(&vec![
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
pub fn get_pu(&self) -> BarrettUCN {
self.get_p().barrett_uk(self.get_p().contents.len() + 4)
}
pub fn get_n(&self) -> UCN {
UCN::from_bytes(&self.n)
}
pub fn get_seed(&self) -> UCN {
UCN::from_bytes(&self.seed)
}
pub fn get_c(&self) -> UCN {
UCN::from_bytes(&self.c)
}
pub fn get_a(&self) -> UCN {
UCN::from_bytes(&self.a)
}
pub fn get_b(&self) -> UCN {
UCN::from_bytes(&self.b)
}
pub fn default(&'static self) -> ECPoint {
let x = SCN::from(UCN::from_bytes(&self.gx));
let y = SCN::from(UCN::from_bytes(&self.gy));
ECPoint::new(self, x, y)
}
}
pub const NIST_P192: EllipticCurve = EllipticCurve {
name: "secp192r1",
p: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x01]),
n: UCN::from_bytes(&vec![
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x16, 0xa2,
0xe0, 0xb8, 0xf0, 0x3e, 0x13, 0xdd, 0x29, 0x45,
0x5c, 0x5c, 0x2a, 0x3d]),
SEED: UCN::from_bytes(&vec![
0xbd, 0x71, 0x34, 0x47, 0x99, 0xd5, 0xc7, 0xfc,
0xdc, 0x45, 0xb5, 0x9f, 0xa3, 0xb9, 0xab, 0x8f,
0x6a, 0x94, 0x8b, 0xc5]),
c: UCN::from_bytes(&vec![
0x5b, 0x05, 0x6c, 0x7e, 0x11, 0xdd, 0x68, 0xf4,
0x04, 0x69, 0xee, 0x7f, 0x3c, 0x7a, 0x7d, 0x74,
0xf7, 0xd1, 0x21, 0x11, 0x65, 0x06, 0xd0, 0x31,
0x21, 0x82, 0x91, 0xfb]),
a: UCN::from_bytes(&vec![
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xfe]),
b: UCN::from_bytes(&vec![
0xb4, 0x05, 0x0a, 0x85, 0x0c, 0x04, 0xb3, 0xab,
0xf5, 0x41, 0x32, 0x56, 0x50, 0x44, 0xb0, 0xb7,
0xd7, 0xbf, 0xd8, 0xba, 0x27, 0x0b, 0x39, 0x43,
0x23, 0x55, 0xff, 0xb4]),
Gx: SCN::from(UCN::from_bytes(&vec![
0xb7, 0x0e, 0x0c, 0xbd, 0x6b, 0xb4, 0xbf, 0x7f,
0x32, 0x13, 0x90, 0xb9, 0x4a, 0x03, 0xc1, 0xd3,
0x56, 0xc2, 0x11, 0x22, 0x34, 0x32, 0x80, 0xd6,
0x11, 0x5c, 0x1d, 0x21])),
Gy: SCN::from(UCN::from_bytes(&vec![
0xbd, 0x37, 0x63, 0x88, 0xb5, 0xf7, 0x23, 0xfb,
0x4c, 0x22, 0xdf, 0xe6, 0xcd, 0x43, 0x75, 0xa0,
0x5a, 0x07, 0x47, 0x64, 0x44, 0xd5, 0x81, 0x99,
0x85, 0x00, 0x7e, 0x34]))
}
}
/// Create a new elliptic curve structure that represents NIST's
/// p256 curve.
pub fn p256() -> EllipticCurve {
EllipticCurve {
p: UCN::from_bytes(&vec![
0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]),
n: UCN::from_bytes(&vec![
0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xbc, 0xe6, 0xfa, 0xad, 0xa7, 0x17, 0x9e, 0x84,
0xf3, 0xb9, 0xca, 0xc2, 0xfc, 0x63, 0x25, 0x51]),
SEED: UCN::from_bytes(&vec![
0xc4, 0x9d, 0x36, 0x08, 0x86, 0xe7, 0x04, 0x93,
0x6a, 0x66, 0x78, 0xe1, 0x13, 0x9d, 0x26, 0xb7,
0x81, 0x9f, 0x7e, 0x90]),
c: UCN::from_bytes(&vec![
0x7e, 0xfb, 0xa1, 0x66, 0x29, 0x85, 0xbe, 0x94,
0x03, 0xcb, 0x05, 0x5c, 0x75, 0xd4, 0xf7, 0xe0,
0xce, 0x8d, 0x84, 0xa9, 0xc5, 0x11, 0x4a, 0xbc,
0xaf, 0x31, 0x77, 0x68, 0x01, 0x04, 0xfa, 0x0d]),
a: UCN::from_bytes(&vec![
0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc]),
b: UCN::from_bytes(&vec![
0x5a, 0xc6, 0x35, 0xd8, 0xaa, 0x3a, 0x93, 0xe7,
0xb3, 0xeb, 0xbd, 0x55, 0x76, 0x98, 0x86, 0xbc,
0x65, 0x1d, 0x06, 0xb0, 0xcc, 0x53, 0xb0, 0xf6,
0x3b, 0xce, 0x3c, 0x3e, 0x27, 0xd2, 0x60, 0x4b]),
Gx: SCN::from(UCN::from_bytes(&vec![
0x6b, 0x17, 0xd1, 0xf2, 0xe1, 0x2c, 0x42, 0x47,
0xf8, 0xbc, 0xe6, 0xe5, 0x63, 0xa4, 0x40, 0xf2,
0x77, 0x03, 0x7d, 0x81, 0x2d, 0xeb, 0x33, 0xa0,
0xf4, 0xa1, 0x39, 0x45, 0xd8, 0x98, 0xc2, 0x96])),
Gy: SCN::from(UCN::from_bytes(&vec![
0x4f, 0xe3, 0x42, 0xe2, 0xfe, 0x1a, 0x7f, 0x9b,
0x8e, 0xe7, 0xeb, 0x4a, 0x7c, 0x0f, 0x9e, 0x16,
0x2b, 0xce, 0x33, 0x57, 0x6b, 0x31, 0x5e, 0xce,
0xcb, 0xb6, 0x40, 0x68, 0x37, 0xbf, 0x51, 0xf5]))
}
}
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff ],
n: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x99, 0xde,
0xf8, 0x36, 0x14, 0x6b, 0xc9, 0xb1, 0xb4, 0xd2,
0x28, 0x31 ],
seed: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x45,
0xae, 0x6f, 0xc8, 0x42, 0x2f, 0x64, 0xed, 0x57,
0x95, 0x28, 0xd3, 0x81, 0x20, 0xea, 0xe1, 0x21,
0x96, 0xd5 ],
c: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x30, 0x99, 0xd2, 0xbb, 0xbf, 0xcb,
0x25, 0x38, 0x54, 0x2d, 0xcd, 0x5f, 0xb0, 0x78,
0xb6, 0xef, 0x5f, 0x3d, 0x6f, 0xe2, 0xc7, 0x45,
0xde, 0x65 ],
a: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xfc ],
b: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x64, 0x21, 0x05, 0x19, 0xe5, 0x9c,
0x80, 0xe7, 0x0f, 0xa7, 0xe9, 0xab, 0x72, 0x24,
0x30, 0x49, 0xfe, 0xb8, 0xde, 0xec, 0xc1, 0x46,
0xb9, 0xb1 ],
gx: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x18, 0x8d, 0xa8, 0x0e, 0xb0, 0x30,
0x90, 0xf6, 0x7c, 0xbf, 0x20, 0xeb, 0x43, 0xa1,
0x88, 0x00, 0xf4, 0xff, 0x0a, 0xfd, 0x82, 0xff,
0x10, 0x12 ],
gy: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x07, 0x19, 0x2b, 0x95, 0xff, 0xc8,
0xda, 0x78, 0x63, 0x10, 0x11, 0xed, 0x6b, 0x24,
0xcd, 0xd5, 0x73, 0xf9, 0x77, 0xa1, 0x1e, 0x79,
0x48, 0x11 ]
};
/// Create a new elliptic curve structure that represents NIST's
/// p256 curve.
pub fn p384() -> EllipticCurve {
EllipticCurve {
p: UCN::from_bytes(&vec![
pub const NIST_P224: EllipticCurve = EllipticCurve {
name: "secp224r1",
p: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x01],
n: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0x16, 0xa2, 0xe0, 0xb8,
0xf0, 0x3e, 0x13, 0xdd, 0x29, 0x45, 0x5c, 0x5c,
0x2a, 0x3d],
seed: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbd, 0x71,
0x34, 0x47, 0x99, 0xd5, 0xc7, 0xfc, 0xdc, 0x45,
0xb5, 0x9f, 0xa3, 0xb9, 0xab, 0x8f, 0x6a, 0x94,
0x8b, 0xc5],
c: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5b, 0x05,
0x6c, 0x7e, 0x11, 0xdd, 0x68, 0xf4, 0x04, 0x69,
0xee, 0x7f, 0x3c, 0x7a, 0x7d, 0x74, 0xf7, 0xd1,
0x21, 0x11, 0x65, 0x06, 0xd0, 0x31, 0x21, 0x82,
0x91, 0xfb],
a: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe,
0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff]),
n: UCN::from_bytes(&vec![
0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xc7, 0x63, 0x4d, 0x81, 0xf4, 0x37, 0x2d, 0xdf,
0x58, 0x1a, 0x0d, 0xb2, 0x48, 0xb0, 0xa7, 0x7a,
0xec, 0xec, 0x19, 0x6a, 0xcc, 0xc5, 0x29, 0x73]),
SEED: UCN::from_bytes(&vec![
0xa3, 0x35, 0x92, 0x6a, 0xa3, 0x19, 0xa2, 0x7a,
0x1d, 0x00, 0x89, 0x6a, 0x67, 0x73, 0xa4, 0x82,
0x7a, 0xcd, 0xac, 0x73]),
c: UCN::from_bytes(&vec![
0x79, 0xd1, 0xe6, 0x55, 0xf8, 0x68, 0xf0, 0x2f,
0xff, 0x48, 0xdc, 0xde, 0xe1, 0x41, 0x51, 0xdd,
0xb8, 0x06, 0x43, 0xc1, 0x40, 0x6d, 0x0c, 0xa1,
0x0d, 0xfe, 0x6f, 0xc5, 0x20, 0x09, 0x54, 0x0a,
0x49, 0x5e, 0x80, 0x42, 0xea, 0x5f, 0x74, 0x4f,
0x6e, 0x18, 0x46, 0x67, 0xcc, 0x72, 0x24, 0x83]),
a: UCN::from_bytes(&vec![
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe,
0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xfc]),
b: UCN::from_bytes(&vec![
0xb3, 0x31, 0x2f, 0xa7, 0xe2, 0x3e, 0xe7, 0xe4,
0x98, 0x8e, 0x05, 0x6b, 0xe3, 0xf8, 0x2d, 0x19,
0x18, 0x1d, 0x9c, 0x6e, 0xfe, 0x81, 0x41, 0x12,
0x03, 0x14, 0x08, 0x8f, 0x50, 0x13, 0x87, 0x5a,
0xc6, 0x56, 0x39, 0x8d, 0x8a, 0x2e, 0xd1, 0x9d,
0x2a, 0x85, 0xc8, 0xed, 0xd3, 0xec, 0x2a, 0xef]),
Gx: SCN::from(UCN::from_bytes(&vec![
0xaa, 0x87, 0xca, 0x22, 0xbe, 0x8b, 0x05, 0x37,
0x8e, 0xb1, 0xc7, 0x1e, 0xf3, 0x20, 0xad, 0x74,
0x6e, 0x1d, 0x3b, 0x62, 0x8b, 0xa7, 0x9b, 0x98,
0x59, 0xf7, 0x41, 0xe0, 0x82, 0x54, 0x2a, 0x38,
0x55, 0x02, 0xf2, 0x5d, 0xbf, 0x55, 0x29, 0x6c,
0x3a, 0x54, 0x5e, 0x38, 0x72, 0x76, 0x0a, 0xb7])),
Gy: SCN::from(UCN::from_bytes(&vec![
0x36, 0x17, 0xde, 0x4a, 0x96, 0x26, 0x2c, 0x6f,
0x5d, 0x9e, 0x98, 0xbf, 0x92, 0x92, 0xdc, 0x29,
0xf8, 0xf4, 0x1d, 0xbd, 0x28, 0x9a, 0x14, 0x7c,
0xe9, 0xda, 0x31, 0x13, 0xb5, 0xf0, 0xb8, 0xc0,
0x0a, 0x60, 0xb1, 0xce, 0x1d, 0x7e, 0x81, 0x9d,
0x7a, 0x43, 0x1d, 0x7c, 0x90, 0xea, 0x0e, 0x5f]))
}
}
0xff, 0xfe],
b: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb4, 0x05,
0x0a, 0x85, 0x0c, 0x04, 0xb3, 0xab, 0xf5, 0x41,
0x32, 0x56, 0x50, 0x44, 0xb0, 0xb7, 0xd7, 0xbf,
0xd8, 0xba, 0x27, 0x0b, 0x39, 0x43, 0x23, 0x55,
0xff, 0xb4],
gx: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb7, 0x0e,
0x0c, 0xbd, 0x6b, 0xb4, 0xbf, 0x7f, 0x32, 0x13,
0x90, 0xb9, 0x4a, 0x03, 0xc1, 0xd3, 0x56, 0xc2,
0x11, 0x22, 0x34, 0x32, 0x80, 0xd6, 0x11, 0x5c,
0x1d, 0x21],
gy: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbd, 0x37,
0x63, 0x88, 0xb5, 0xf7, 0x23, 0xfb, 0x4c, 0x22,
0xdf, 0xe6, 0xcd, 0x43, 0x75, 0xa0, 0x5a, 0x07,
0x47, 0x64, 0x44, 0xd5, 0x81, 0x99, 0x85, 0x00,
0x7e, 0x34]
};
/// Create a new elliptic curve structure that represents NIST's
/// p256 curve.
pub fn p521() -> EllipticCurve {
EllipticCurve {
p: UCN::from_bytes(&vec![
0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
pub const NIST_P256: EllipticCurve = EllipticCurve {
name: "secp256r1",
p: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff],
n: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xbc, 0xe6, 0xfa, 0xad, 0xa7, 0x17,
0x9e, 0x84, 0xf3, 0xb9, 0xca, 0xc2, 0xfc, 0x63,
0x25, 0x51],
seed: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc4, 0x9d,
0x36, 0x08, 0x86, 0xe7, 0x04, 0x93, 0x6a, 0x66,
0x78, 0xe1, 0x13, 0x9d, 0x26, 0xb7, 0x81, 0x9f,
0x7e, 0x90],
c: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x7e, 0xfb, 0xa1, 0x66, 0x29, 0x85,
0xbe, 0x94, 0x03, 0xcb, 0x05, 0x5c, 0x75, 0xd4,
0xf7, 0xe0, 0xce, 0x8d, 0x84, 0xa9, 0xc5, 0x11,
0x4a, 0xbc, 0xaf, 0x31, 0x77, 0x68, 0x01, 0x04,
0xfa, 0x0d],
a: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xfc],
b: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x5a, 0xc6, 0x35, 0xd8, 0xaa, 0x3a,
0x93, 0xe7, 0xb3, 0xeb, 0xbd, 0x55, 0x76, 0x98,
0x86, 0xbc, 0x65, 0x1d, 0x06, 0xb0, 0xcc, 0x53,
0xb0, 0xf6, 0x3b, 0xce, 0x3c, 0x3e, 0x27, 0xd2,
0x60, 0x4b],
gx: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x6b, 0x17, 0xd1, 0xf2, 0xe1, 0x2c,
0x42, 0x47, 0xf8, 0xbc, 0xe6, 0xe5, 0x63, 0xa4,
0x40, 0xf2, 0x77, 0x03, 0x7d, 0x81, 0x2d, 0xeb,
0x33, 0xa0, 0xf4, 0xa1, 0x39, 0x45, 0xd8, 0x98,
0xc2, 0x96],
gy: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x4f, 0xe3, 0x42, 0xe2, 0xfe, 0x1a,
0x7f, 0x9b, 0x8e, 0xe7, 0xeb, 0x4a, 0x7c, 0x0f,
0x9e, 0x16, 0x2b, 0xce, 0x33, 0x57, 0x6b, 0x31,
0x5e, 0xce, 0xcb, 0xb6, 0x40, 0x68, 0x37, 0xbf,
0x51, 0xf5]
};
pub const NIST_P384: EllipticCurve = EllipticCurve {
name: "secp384r1",
p: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
0xff, 0xff],
n: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xc7, 0x63, 0x4d, 0x81, 0xf4, 0x37,
0x2d, 0xdf, 0x58, 0x1a, 0x0d, 0xb2, 0x48, 0xb0,
0xa7, 0x7a, 0xec, 0xec, 0x19, 0x6a, 0xcc, 0xc5,
0x29, 0x73],
seed: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa3, 0x35,
0x92, 0x6a, 0xa3, 0x19, 0xa2, 0x7a, 0x1d, 0x00,
0x89, 0x6a, 0x67, 0x73, 0xa4, 0x82, 0x7a, 0xcd,
0xac, 0x73],
c: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x79, 0xd1, 0xe6, 0x55, 0xf8, 0x68,
0xf0, 0x2f, 0xff, 0x48, 0xdc, 0xde, 0xe1, 0x41,
0x51, 0xdd, 0xb8, 0x06, 0x43, 0xc1, 0x40, 0x6d,
0x0c, 0xa1, 0x0d, 0xfe, 0x6f, 0xc5, 0x20, 0x09,
0x54, 0x0a, 0x49, 0x5e, 0x80, 0x42, 0xea, 0x5f,
0x74, 0x4f, 0x6e, 0x18, 0x46, 0x67, 0xcc, 0x72,
0x24, 0x83],
a: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
0xff, 0xfc],
b: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xb3, 0x31, 0x2f, 0xa7, 0xe2, 0x3e,
0xe7, 0xe4, 0x98, 0x8e, 0x05, 0x6b, 0xe3, 0xf8,
0x2d, 0x19, 0x18, 0x1d, 0x9c, 0x6e, 0xfe, 0x81,
0x41, 0x12, 0x03, 0x14, 0x08, 0x8f, 0x50, 0x13,
0x87, 0x5a, 0xc6, 0x56, 0x39, 0x8d, 0x8a, 0x2e,
0xd1, 0x9d, 0x2a, 0x85, 0xc8, 0xed, 0xd3, 0xec,
0x2a, 0xef],
gx: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xaa, 0x87, 0xca, 0x22, 0xbe, 0x8b,
0x05, 0x37, 0x8e, 0xb1, 0xc7, 0x1e, 0xf3, 0x20,
0xad, 0x74, 0x6e, 0x1d, 0x3b, 0x62, 0x8b, 0xa7,
0x9b, 0x98, 0x59, 0xf7, 0x41, 0xe0, 0x82, 0x54,
0x2a, 0x38, 0x55, 0x02, 0xf2, 0x5d, 0xbf, 0x55,
0x29, 0x6c, 0x3a, 0x54, 0x5e, 0x38, 0x72, 0x76,
0x0a, 0xb7],
gy: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x36, 0x17, 0xde, 0x4a, 0x96, 0x26,
0x2c, 0x6f, 0x5d, 0x9e, 0x98, 0xbf, 0x92, 0x92,
0xdc, 0x29, 0xf8, 0xf4, 0x1d, 0xbd, 0x28, 0x9a,
0x14, 0x7c, 0xe9, 0xda, 0x31, 0x13, 0xb5, 0xf0,
0xb8, 0xc0, 0x0a, 0x60, 0xb1, 0xce, 0x1d, 0x7e,
0x81, 0x9d, 0x7a, 0x43, 0x1d, 0x7c, 0x90, 0xea,
0x0e, 0x5f]
};
pub const NIST_P521: EllipticCurve = EllipticCurve {
name: "secp521r1",
p: [ 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
@@ -218,9 +376,8 @@ impl EllipticCurve {
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff]),
n: UCN::from_bytes(&vec![
0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff ],
n: [ 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
@@ -228,23 +385,26 @@ impl EllipticCurve {
0x96, 0x6b, 0x7f, 0xcc, 0x01, 0x48, 0xf7, 0x09,
0xa5, 0xd0, 0x3b, 0xb5, 0xc9, 0xb8, 0x89, 0x9c,
0x47, 0xae, 0xbb, 0x6f, 0xb7, 0x1e, 0x91, 0x38,
0x64, 0x09]),
SEED: UCN::from_bytes(&vec![
0xd0, 0x9e, 0x88, 0x00, 0x29, 0x1c, 0xb8, 0x53,
0x96, 0xcc, 0x67, 0x17, 0x39, 0x32, 0x84, 0xaa,
0xa0, 0xda, 0x64, 0xba]),
c: UCN::from_bytes(&vec![
0xb4, 0x8b, 0xfa, 0x5f, 0x42, 0x0a, 0x34, 0x94,
0x95, 0x39, 0xd2, 0xbd, 0xfc, 0x26, 0x4e, 0xee,
0xeb, 0x07, 0x76, 0x88, 0xe4, 0x4f, 0xbf, 0x0a,
0xd8, 0xf6, 0xd0, 0xed, 0xb3, 0x7b, 0xd6, 0xb5,
0x33, 0x28, 0x10, 0x00, 0x51, 0x8e, 0x19, 0xf1,
0xb9, 0xff, 0xbe, 0x0f, 0xe9, 0xed, 0x8a, 0x3c,
0x22, 0x00, 0xb8, 0xf8, 0x75, 0xe5, 0x23, 0x86,
0x8c, 0x70, 0xc1, 0xe5, 0xbf, 0x55, 0xba, 0xd6,
0x37]),
a: UCN::from_bytes(&vec![
0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0x64, 0x09 ],
seed: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, 0x9e,
0x88, 0x00, 0x29, 0x1c, 0xb8, 0x53, 0x96, 0xcc,
0x67, 0x17, 0x39, 0x32, 0x84, 0xaa, 0xa0, 0xda,
0x64, 0xba ],
c: [ 0x00, 0xb4, 0x8b, 0xfa, 0x5f, 0x42, 0x0a, 0x34,
0x94, 0x95, 0x39, 0xd2, 0xbd, 0xfc, 0x26, 0x4e,
0xee, 0xeb, 0x07, 0x76, 0x88, 0xe4, 0x4f, 0xbf,
0x0a, 0xd8, 0xf6, 0xd0, 0xed, 0xb3, 0x7b, 0xd6,
0xb5, 0x33, 0x28, 0x10, 0x00, 0x51, 0x8e, 0x19,
0xf1, 0xb9, 0xff, 0xbe, 0x0f, 0xe9, 0xed, 0x8a,
0x3c, 0x22, 0x00, 0xb8, 0xf8, 0x75, 0xe5, 0x23,
0x86, 0x8c, 0x70, 0xc1, 0xe5, 0xbf, 0x55, 0xba,
0xd6, 0x37 ],
a: [ 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
@@ -252,39 +412,32 @@ impl EllipticCurve {
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xfc]),
b: UCN::from_bytes(&vec![
0x51, 0x95, 0x3e, 0xb9, 0x61, 0x8e, 0x1c, 0x9a,
0x1f, 0x92, 0x9a, 0x21, 0xa0, 0xb6, 0x85, 0x40,
0xee, 0xa2, 0xda, 0x72, 0x5b, 0x99, 0xb3, 0x15,
0xf3, 0xb8, 0xb4, 0x89, 0x91, 0x8e, 0xf1, 0x09,
0xe1, 0x56, 0x19, 0x39, 0x51, 0xec, 0x7e, 0x93,
0x7b, 0x16, 0x52, 0xc0, 0xbd, 0x3b, 0xb1, 0xbf,
0x07, 0x35, 0x73, 0xdf, 0x88, 0x3d, 0x2c, 0x34,
0xf1, 0xef, 0x45, 0x1f, 0xd4, 0x6b, 0x50, 0x3f,
0x00]),
Gx: SCN::from(UCN::from_bytes(&vec![
0xc6, 0x85, 0x8e, 0x06, 0xb7, 0x04, 0x04, 0xe9,
0xcd, 0x9e, 0x3e, 0xcb, 0x66, 0x23, 0x95, 0xb4,
0x42, 0x9c, 0x64, 0x81, 0x39, 0x05, 0x3f, 0xb5,
0x21, 0xf8, 0x28, 0xaf, 0x60, 0x6b, 0x4d, 0x3d,
0xba, 0xa1, 0x4b, 0x5e, 0x77, 0xef, 0xe7, 0x59,
0x28, 0xfe, 0x1d, 0xc1, 0x27, 0xa2, 0xff, 0xa8,
0xde, 0x33, 0x48, 0xb3, 0xc1, 0x85, 0x6a, 0x42,
0x9b, 0xf9, 0x7e, 0x7e, 0x31, 0xc2, 0xe5, 0xbd,
0x66])),
Gy: SCN::from(UCN::from_bytes(&vec![
0x18, 0x39, 0x29, 0x6a, 0x78, 0x9a, 0x3b, 0xc0,
0x04, 0x5c, 0x8a, 0x5f, 0xb4, 0x2c, 0x7d, 0x1b,
0xd9, 0x98, 0xf5, 0x44, 0x49, 0x57, 0x9b, 0x44,
0x68, 0x17, 0xaf, 0xbd, 0x17, 0x27, 0x3e, 0x66,
0x2c, 0x97, 0xee, 0x72, 0x99, 0x5e, 0xf4, 0x26,
0x40, 0xc5, 0x50, 0xb9, 0x01, 0x3f, 0xad, 0x07,
0x61, 0x35, 0x3c, 0x70, 0x86, 0xa2, 0x72, 0xc2,
0x40, 0x88, 0xbe, 0x94, 0x76, 0x9f, 0xd1, 0x66,
0x50]))
}
}
}
0xff, 0xfc ],
b: [ 0x00, 0x51, 0x95, 0x3e, 0xb9, 0x61, 0x8e, 0x1c,
0x9a, 0x1f, 0x92, 0x9a, 0x21, 0xa0, 0xb6, 0x85,
0x40, 0xee, 0xa2, 0xda, 0x72, 0x5b, 0x99, 0xb3,
0x15, 0xf3, 0xb8, 0xb4, 0x89, 0x91, 0x8e, 0xf1,
0x09, 0xe1, 0x56, 0x19, 0x39, 0x51, 0xec, 0x7e,
0x93, 0x7b, 0x16, 0x52, 0xc0, 0xbd, 0x3b, 0xb1,
0xbf, 0x07, 0x35, 0x73, 0xdf, 0x88, 0x3d, 0x2c,
0x34, 0xf1, 0xef, 0x45, 0x1f, 0xd4, 0x6b, 0x50,
0x3f, 0x00 ],
gx: [ 0x00, 0xc6, 0x85, 0x8e, 0x06, 0xb7, 0x04, 0x04,
0xe9, 0xcd, 0x9e, 0x3e, 0xcb, 0x66, 0x23, 0x95,
0xb4, 0x42, 0x9c, 0x64, 0x81, 0x39, 0x05, 0x3f,
0xb5, 0x21, 0xf8, 0x28, 0xaf, 0x60, 0x6b, 0x4d,
0x3d, 0xba, 0xa1, 0x4b, 0x5e, 0x77, 0xef, 0xe7,
0x59, 0x28, 0xfe, 0x1d, 0xc1, 0x27, 0xa2, 0xff,
0xa8, 0xde, 0x33, 0x48, 0xb3, 0xc1, 0x85, 0x6a,
0x42, 0x9b, 0xf9, 0x7e, 0x7e, 0x31, 0xc2, 0xe5,
0xbd, 0x66 ],
gy: [ 0x00, 0x18, 0x39, 0x29, 0x6a, 0x78, 0x9a, 0x3b,
0xc0, 0x04, 0x5c, 0x8a, 0x5f, 0xb4, 0x2c, 0x7d,
0x1b, 0xd9, 0x98, 0xf5, 0x44, 0x49, 0x57, 0x9b,
0x44, 0x68, 0x17, 0xaf, 0xbd, 0x17, 0x27, 0x3e,
0x66, 0x2c, 0x97, 0xee, 0x72, 0x99, 0x5e, 0xf4,
0x26, 0x40, 0xc5, 0x50, 0xb9, 0x01, 0x3f, 0xad,
0x07, 0x61, 0x35, 0x3c, 0x70, 0x86, 0xa2, 0x72,
0xc2, 0x40, 0x88, 0xbe, 0x94, 0x76, 0x9f, 0xd1,
0x66, 0x50 ]
};

View File

@@ -1,86 +1,187 @@
use cryptonum::{SCN,UCN};
use dsa::rfc6979::*;
use ecdsa::curves::EllipticCurve;
use ecdsa::math::ECCPoint;
use ecdsa::private::ECDSAPrivate;
use ecdsa::public::ECDSAPublic;
use sha1::Sha1;
use sha2::{Sha224,Sha256,Sha384,Sha512};
//use dsa::rfc6979::*;
use ecdsa::curves::*;
use ecdsa::point::ECPoint;
//use ecdsa::private::ECDSAPrivate;
//use ecdsa::public::ECDSAPublic;
//use sha1::Sha1;
//use sha2::{Sha224,Sha256,Sha384,Sha512};
use testing::run_test;
fn get_curve(cbytes: &[u8]) -> EllipticCurve {
fn get_curve(cbytes: &[u8]) -> &'static EllipticCurve {
match usize::from(UCN::from_bytes(cbytes)) {
0x192 => EllipticCurve::p192(),
0x224 => EllipticCurve::p224(),
0x256 => EllipticCurve::p256(),
0x384 => EllipticCurve::p384(),
0x521 => EllipticCurve::p521(),
_ => panic!("Unacceptable curve identifier")
0x192 => &NIST_P192,
0x224 => &NIST_P224,
0x256 => &NIST_P256,
0x384 => &NIST_P384,
0x521 => &NIST_P521,
x => panic!("Unacceptable curve identifier {}", x)
}
}
#[test]
fn verification_tests()
fn point_negate()
{
run_test("tests/ecdsa/signature.test", 8, |case| {
let (neg0, cbytes) = case.get("c").unwrap();
let (negx, xbytes) = case.get("x").unwrap();
let (negy, ybytes) = case.get("y").unwrap();
let (neg1, hbytes) = case.get("h").unwrap();
let (neg2, msg) = case.get("m").unwrap();
run_test("tests/ecdsa/ec_negate.test", 5, |case| {
let (neg0, abytes) = case.get("a").unwrap();
let (neg1, bbytes) = case.get("b").unwrap();
let (neg2, cbytes) = case.get("c").unwrap();
let (neg3, xbytes) = case.get("x").unwrap();
let (neg4, ybytes) = case.get("y").unwrap();
assert!(!neg0 && !neg1 && !neg2 && !neg3 && !neg4);
let curve = get_curve(&cbytes);
let x = SCN::from(UCN::from_bytes(xbytes));
let y = SCN::from(UCN::from_bytes(ybytes));
let orig = ECPoint::new(curve, x, y);
let a = SCN::from(UCN::from_bytes(abytes));
let b = SCN::from(UCN::from_bytes(bbytes));
let inverted = ECPoint::new(curve, a, b);
assert_eq!(inverted, orig.negate());
});
}
#[test]
fn point_double()
{
run_test("tests/ecdsa/ec_dble.test", 5, |case| {
println!("START");
let (neg0, abytes) = case.get("a").unwrap();
let (neg1, bbytes) = case.get("b").unwrap();
let (neg2, cbytes) = case.get("c").unwrap();
let (neg3, xbytes) = case.get("x").unwrap();
let (neg4, ybytes) = case.get("y").unwrap();
assert!(!neg0 && !neg1 && !neg2 && !neg3 && !neg4);
println!("SEC1");
let curve = get_curve(&cbytes);
println!("SEC2");
let x = SCN::from(UCN::from_bytes(xbytes));
let y = SCN::from(UCN::from_bytes(ybytes));
let orig = ECPoint::new(curve, x, y);
println!("SEC3");
let a = SCN::from(UCN::from_bytes(abytes));
let b = SCN::from(UCN::from_bytes(bbytes));
let doubled = ECPoint::new(curve, a, b);
println!("SEC4");
assert_eq!(doubled, orig.double());
});
}
#[test]
fn point_add()
{
run_test("tests/ecdsa/ec_add.test", 7, |case| {
let (neg0, abytes) = case.get("a").unwrap();
let (neg1, bbytes) = case.get("b").unwrap();
let (neg2, qbytes) = case.get("q").unwrap();
let (neg3, rbytes) = case.get("r").unwrap();
let (neg4, sbytes) = case.get("s").unwrap();
let (neg4, cbytes) = case.get("c").unwrap();
let (neg5, xbytes) = case.get("x").unwrap();
let (neg6, ybytes) = case.get("y").unwrap();
assert!(!neg0 & !neg1 & !neg2 & !neg3 & !neg4);
let curve = get_curve(cbytes);
let ux = UCN::from_bytes(xbytes);
let uy = UCN::from_bytes(ybytes);
let x = SCN{ negative: *negx, value: ux };
let y = SCN{ negative: *negy, value: uy };
let point = ECCPoint::new(&curve, x, y);
let public = ECDSAPublic::new(&curve, &point);
let r = UCN::from_bytes(rbytes);
let s = UCN::from_bytes(sbytes);
println!("r: {:X}", r);
let sig = DSASignature{ r: r, s: s };
match usize::from(UCN::from_bytes(hbytes)) {
0x1 => assert!(public.verify::<Sha1>(msg, &sig)),
0x224 => assert!(public.verify::<Sha224>(msg, &sig)),
0x256 => assert!(public.verify::<Sha256>(msg, &sig)),
0x384 => assert!(public.verify::<Sha384>(msg, &sig)),
0x512 => assert!(public.verify::<Sha512>(msg, &sig)),
v => panic!("Bad hash size {}!", v)
}
assert!(!neg0 && !neg1 && !neg2 && !neg3 && !neg4 && !neg5 && !neg6);
let curve = get_curve(&cbytes);
let x = SCN::from(UCN::from_bytes(xbytes));
let y = SCN::from(UCN::from_bytes(ybytes));
let p1 = ECPoint::new(curve, x, y);
let q = SCN::from(UCN::from_bytes(qbytes));
let r = SCN::from(UCN::from_bytes(rbytes));
let p2 = ECPoint::new(curve, q, r);
let a = SCN::from(UCN::from_bytes(abytes));
let b = SCN::from(UCN::from_bytes(bbytes));
let result = ECPoint::new(curve, a, b);
assert_eq!(result, p1.add(&p2));
});
}
#[test]
fn signing_tests()
fn point_scale()
{
run_test("tests/ecdsa/signature.test", 8, |case| {
let (neg0, cbytes) = case.get("c").unwrap();
let (neg1, dbytes) = case.get("d").unwrap();
let (neg2, hbytes) = case.get("h").unwrap();
let (neg3, msg) = case.get("m").unwrap();
let (neg4, rbytes) = case.get("r").unwrap();
let (neg5, sbytes) = case.get("s").unwrap();
run_test("tests/ecdsa/ec_mul.test", 6, |case| {
let (neg0, abytes) = case.get("a").unwrap();
let (neg1, bbytes) = case.get("b").unwrap();
let (neg2, kbytes) = case.get("k").unwrap();
let (neg3, cbytes) = case.get("c").unwrap();
let (neg4, xbytes) = case.get("x").unwrap();
let (neg5, ybytes) = case.get("y").unwrap();
assert!(!neg0 & !neg1 & !neg2 & !neg3 & !neg4 & !neg5);
let curve = get_curve(cbytes);
let d = UCN::from_bytes(dbytes);
let private = ECDSAPrivate::new(&curve, &d);
let r = UCN::from_bytes(rbytes);
let s = UCN::from_bytes(sbytes);
let sig = DSASignature{ r: r, s: s };
match usize::from(UCN::from_bytes(hbytes)) {
0x1 => assert_eq!(sig, private.sign::<Sha1>(msg)),
0x224 => assert_eq!(sig, private.sign::<Sha224>(msg)),
0x256 => assert_eq!(sig, private.sign::<Sha256>(msg)),
0x384 => assert_eq!(sig, private.sign::<Sha384>(msg)),
0x512 => assert_eq!(sig, private.sign::<Sha512>(msg)),
v => panic!("Bad hash size {}!", v)
}
assert!(!neg0 && !neg1 && !neg2 && !neg3 && !neg4 && !neg5);
let curve = get_curve(&cbytes);
let x = SCN::from(UCN::from_bytes(xbytes));
let y = SCN::from(UCN::from_bytes(ybytes));
let base = ECPoint::new(curve, x, y);
let k = UCN::from_bytes(kbytes);
let a = SCN::from(UCN::from_bytes(abytes));
let b = SCN::from(UCN::from_bytes(bbytes));
let result = ECPoint::new(curve, a, b);
assert_eq!(result, base.scale(&k));
});
}
//#[test]
//fn verification_tests()
//{
// run_test("tests/ecdsa/signature.test", 8, |case| {
// let (neg0, cbytes) = case.get("c").unwrap();
// let (negx, xbytes) = case.get("x").unwrap();
// let (negy, ybytes) = case.get("y").unwrap();
// let (neg1, hbytes) = case.get("h").unwrap();
// let (neg2, msg) = case.get("m").unwrap();
// let (neg3, rbytes) = case.get("r").unwrap();
// let (neg4, sbytes) = case.get("s").unwrap();
//
// assert!(!neg0 & !neg1 & !neg2 & !neg3 & !neg4);
// let curve = get_curve(cbytes);
// let ux = UCN::from_bytes(xbytes);
// let uy = UCN::from_bytes(ybytes);
// let x = SCN{ negative: *negx, value: ux };
// let y = SCN{ negative: *negy, value: uy };
// let point = ECCPoint::new(&curve, x, y);
// let public = ECDSAPublic::new(&curve, &point);
// let r = UCN::from_bytes(rbytes);
// let s = UCN::from_bytes(sbytes);
// println!("r: {:X}", r);
// let sig = DSASignature{ r: r, s: s };
//
// match usize::from(UCN::from_bytes(hbytes)) {
// 0x1 => assert!(public.verify::<Sha1>(msg, &sig)),
// 0x224 => assert!(public.verify::<Sha224>(msg, &sig)),
// 0x256 => assert!(public.verify::<Sha256>(msg, &sig)),
// 0x384 => assert!(public.verify::<Sha384>(msg, &sig)),
// 0x512 => assert!(public.verify::<Sha512>(msg, &sig)),
// v => panic!("Bad hash size {}!", v)
// }
// });
//}
//
//#[test]
//fn signing_tests()
//{
// run_test("tests/ecdsa/signature.test", 8, |case| {
// let (neg0, cbytes) = case.get("c").unwrap();
// let (neg1, dbytes) = case.get("d").unwrap();
// let (neg2, hbytes) = case.get("h").unwrap();
// let (neg3, msg) = case.get("m").unwrap();
// let (neg4, rbytes) = case.get("r").unwrap();
// let (neg5, sbytes) = case.get("s").unwrap();
//
// assert!(!neg0 & !neg1 & !neg2 & !neg3 & !neg4 & !neg5);
// let curve = get_curve(cbytes);
// let d = UCN::from_bytes(dbytes);
// let private = ECDSAPrivate::new(&curve, &d);
// let r = UCN::from_bytes(rbytes);
// let s = UCN::from_bytes(sbytes);
// let sig = DSASignature{ r: r, s: s };
//
// match usize::from(UCN::from_bytes(hbytes)) {
// 0x1 => assert_eq!(sig, private.sign::<Sha1>(msg)),
// 0x224 => assert_eq!(sig, private.sign::<Sha224>(msg)),
// 0x256 => assert_eq!(sig, private.sign::<Sha256>(msg)),
// 0x384 => assert_eq!(sig, private.sign::<Sha384>(msg)),
// 0x512 => assert_eq!(sig, private.sign::<Sha512>(msg)),
// v => panic!("Bad hash size {}!", v)
// }
// });
//}

View File

@@ -1,162 +0,0 @@
use cryptonum::{SCN,UCN};
use ecdsa::curves::EllipticCurve;
#[allow(non_snake_case)]
#[derive(Clone,Debug,PartialEq)]
pub struct ECCPoint {
pub curve: EllipticCurve,
pub x: SCN,
pub y: SCN
}
pub fn point_add_two_muls(n1: &UCN, p1: &ECCPoint, n2: &UCN, p2: &ECCPoint)
-> ECCPoint
{
let scaled1 = p1.scale(&n1);
let scaled2 = p2.scale(&n2);
scaled1.add(&scaled2)
}
impl ECCPoint {
pub fn new(ec: &EllipticCurve, x: SCN, y: SCN) -> ECCPoint {
ECCPoint { curve: ec.clone(), x: x, y: y }
}
pub fn default(ec: &EllipticCurve) -> ECCPoint {
ECCPoint {
curve: ec.clone(),
x: ec.Gx.clone(),
y: ec.Gy.clone()
}
}
pub fn negate(&self) -> ECCPoint {
ECCPoint {
curve: self.curve.clone(),
x: self.x.clone(),
y: SCN::from(self.curve.p.clone()) - self.y.clone()
}
}
pub fn double(&self) -> ECCPoint {
let ua = SCN::from(self.curve.a.clone());
let up = SCN::from(self.curve.p.clone());
// lambda = (3 * xp ^ 2 + a) / 2 yp
let xpsq = &self.x * &self.x;
let lambda_top = &(&SCN::from(3) * &xpsq) + &ua;
let lambda_bot = &self.y << 1;
let lambda = lambda_top.divmod(&lambda_bot, &self.curve.p);
// xr = lambda ^ 2 - 2 xp
let xr_left = &lambda * &lambda;
let xr_right = &self.x << 1;
let xr = (xr_left - xr_right) % &up;
// yr = lambda (xp - xr) - yp
let xdiff = &self.x - &xr;
let yr_left = &lambda * &xdiff;
let yr = (&yr_left - &self.y) % &up;
//
ECCPoint{ curve: self.curve.clone(), x: xr, y: yr }
}
pub fn add(&self, other: &ECCPoint) -> ECCPoint {
assert!(self.curve == other.curve);
let xdiff = &self.x - &other.x;
let ydiff = &self.y - &other.y;
let s = ydiff.divmod(&xdiff, &self.curve.p);
let pp = SCN::from(self.curve.p.clone());
let xr = (&(&s * &s) - &self.x - &other.x) % &pp;
let yr = (&s * (&self.x - &xr) - &self.y) % &pp;
ECCPoint{ curve: self.curve.clone(), x: xr, y: yr }
}
pub fn scale(&self, d: &UCN) -> ECCPoint {
assert!(!d.is_zero());
let one = UCN::from(1u64);
#[allow(non_snake_case)]
let mut Q = self.clone();
let i = d.bits() - 2;
let mut mask = &one << i;
while !mask.is_zero() {
Q = Q.double();
let test = d & &mask;
if !test.is_zero() {
Q = Q.add(&self);
}
mask >>= 1;
}
Q
}
}
pub fn bits2int(x: &[u8], qlen: usize) -> UCN {
let mut value = UCN::from_bytes(x);
let vlen = x.len() * 8;
if vlen > qlen {
value >>= vlen - qlen;
}
value
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn p256_double() {
let xbytes = vec![0x7c, 0xf2, 0x7b, 0x18, 0x8d, 0x03, 0x4f, 0x7e,
0x8a, 0x52, 0x38, 0x03, 0x04, 0xb5, 0x1a, 0xc3,
0xc0, 0x89, 0x69, 0xe2, 0x77, 0xf2, 0x1b, 0x35,
0xa6, 0x0b, 0x48, 0xfc, 0x47, 0x66, 0x99, 0x78];
let ybytes = vec![0x07, 0x77, 0x55, 0x10, 0xdb, 0x8e, 0xd0, 0x40,
0x29, 0x3d, 0x9a, 0xc6, 0x9f, 0x74, 0x30, 0xdb,
0xba, 0x7d, 0xad, 0xe6, 0x3c, 0xe9, 0x82, 0x29,
0x9e, 0x04, 0xb7, 0x9d, 0x22, 0x78, 0x73, 0xd1];
let x = SCN::from(UCN::from_bytes(&xbytes));
let y = SCN::from(UCN::from_bytes(&ybytes));
let base = ECCPoint::default(&EllipticCurve::p256());
let res = base.double();
let goal = ECCPoint{ curve: base.curve.clone(), x: x, y: y };
assert_eq!(res, goal);
}
#[test]
fn p256_add() {
let xbytes = vec![0x5e, 0xcb, 0xe4, 0xd1, 0xa6, 0x33, 0x0a, 0x44,
0xc8, 0xf7, 0xef, 0x95, 0x1d, 0x4b, 0xf1, 0x65,
0xe6, 0xc6, 0xb7, 0x21, 0xef, 0xad, 0xa9, 0x85,
0xfb, 0x41, 0x66, 0x1b, 0xc6, 0xe7, 0xfd, 0x6c];
let ybytes = vec![0x87, 0x34, 0x64, 0x0c, 0x49, 0x98, 0xff, 0x7e,
0x37, 0x4b, 0x06, 0xce, 0x1a, 0x64, 0xa2, 0xec,
0xd8, 0x2a, 0xb0, 0x36, 0x38, 0x4f, 0xb8, 0x3d,
0x9a, 0x79, 0xb1, 0x27, 0xa2, 0x7d, 0x50, 0x32];
let x = SCN::from(UCN::from_bytes(&xbytes));
let y = SCN::from(UCN::from_bytes(&ybytes));
let base = ECCPoint::default(&EllipticCurve::p256());
let res = base.add(&base.double());
let goal = ECCPoint{ curve: base.curve.clone(), x: x, y: y };
assert_eq!(res, goal);
}
#[test]
fn p256_scale() {
let xbytes = vec![0xea, 0x68, 0xd7, 0xb6, 0xfe, 0xdf, 0x0b, 0x71,
0x87, 0x89, 0x38, 0xd5, 0x1d, 0x71, 0xf8, 0x72,
0x9e, 0x0a, 0xcb, 0x8c, 0x2c, 0x6d, 0xf8, 0xb3,
0xd7, 0x9e, 0x8a, 0x4b, 0x90, 0x94, 0x9e, 0xe0];
let ybytes = vec![0x2a, 0x27, 0x44, 0xc9, 0x72, 0xc9, 0xfc, 0xe7,
0x87, 0x01, 0x4a, 0x96, 0x4a, 0x8e, 0xa0, 0xc8,
0x4d, 0x71, 0x4f, 0xea, 0xa4, 0xde, 0x82, 0x3f,
0xe8, 0x5a, 0x22, 0x4a, 0x4d, 0xd0, 0x48, 0xfa];
let x = SCN::from(UCN::from_bytes(&xbytes));
let y = SCN::from(UCN::from_bytes(&ybytes));
let base = ECCPoint::default(&EllipticCurve::p256());
let res = base.scale(&UCN::from(9 as u64));
let goal = ECCPoint{ curve: base.curve.clone(), x: x, y: y };
assert_eq!(res, goal);
}
}

View File

@@ -1,60 +1,61 @@
mod curves;
#[cfg(test)]
mod gold_tests;
mod math;
mod private;
mod public;
pub use self::private::ECDSAPrivate;
pub use self::public::ECDSAPublic;
use cryptonum::UCN;
use rand::{Rng,OsRng};
use self::curves::EllipticCurve;
use self::math::ECCPoint;
#[derive(Clone,Debug,PartialEq)]
pub struct ECDSAKeyPair {
pub private: ECDSAPrivate,
pub public: ECDSAPublic
}
impl ECDSAKeyPair {
pub fn generate(params: &EllipticCurve)
-> ECDSAKeyPair
{
let mut rng = OsRng::new().unwrap();
ECDSAKeyPair::generate_w_rng(&mut rng, params)
}
pub fn generate_w_rng<G: Rng>(rng: &mut G, params: &EllipticCurve)
-> ECDSAKeyPair
{
let one = UCN::from(1u64);
#[allow(non_snake_case)]
let N = params.n.bits();
let bits_to_generate = N + 64;
let bytes_to_generate = (bits_to_generate + 7) / 8;
let bits: Vec<u8> = rng.gen_iter().take(bytes_to_generate).collect();
let bits_generated = bytes_to_generate * 8;
let mut c = UCN::from_bytes(&bits);
c >>= bits_generated - bits_to_generate;
let nm1 = &params.n - &one;
let d = (c % &nm1) + &one;
#[allow(non_snake_case)]
let Q = ECCPoint::default(params).scale(&d);
ECDSAKeyPair {
private: ECDSAPrivate {
curve: params.clone(),
d: d
},
public: ECDSAPublic {
curve: params.clone(),
Q: Q
}
}
}
}
mod point;
//mod private;
//mod public;
//
//pub use self::private::ECDSAPrivate;
//pub use self::public::ECDSAPublic;
pub use self::curves::{NIST_P192,NIST_P224,NIST_P256,NIST_P384,NIST_P521};
//
//use cryptonum::UCN;
//use rand::{Rng,OsRng};
//use self::curves::EllipticCurve;
//use self::math::ECCPoint;
//
//#[derive(Clone,Debug,PartialEq)]
//pub struct ECDSAKeyPair {
// pub private: ECDSAPrivate,
// pub public: ECDSAPublic
//}
//
//impl ECDSAKeyPair {
// pub fn generate(params: &'static EllipticCurve)
// -> ECDSAKeyPair
// {
// let mut rng = OsRng::new().unwrap();
// ECDSAKeyPair::generate_w_rng(&mut rng, params)
//
// }
//
// pub fn generate_w_rng<G: Rng>(rng: &mut G, params: &'static EllipticCurve)
// -> ECDSAKeyPair
// {
// let one = UCN::from(1u64);
// #[allow(non_snake_case)]
// let N = params.n.bits();
// let bits_to_generate = N + 64;
// let bytes_to_generate = (bits_to_generate + 7) / 8;
// let bits: Vec<u8> = rng.gen_iter().take(bytes_to_generate).collect();
// let bits_generated = bytes_to_generate * 8;
// let mut c = UCN::from_bytes(&bits);
// c >>= bits_generated - bits_to_generate;
// let nm1 = &params.n - &one;
// let d = (c % &nm1) + &one;
// #[allow(non_snake_case)]
// let Q = ECCPoint::default(params).scale(&d);
// ECDSAKeyPair {
// private: ECDSAPrivate {
// curve: params,
// d: d
// },
// public: ECDSAPublic {
// curve: params,
// Q: Q
// }
// }
// }
//}
//
//

227
src/ecdsa/point.rs Normal file
View File

@@ -0,0 +1,227 @@
use cryptonum::{SCN,UCN};
use ecdsa::curves::EllipticCurve;
#[derive(Clone,Debug,PartialEq)]
pub struct ECPoint {
pub curve: &'static EllipticCurve,
pub value: ECPointValue
}
#[derive(Clone,Debug,PartialEq)]
pub enum ECPointValue {
Infinity,
Point(SCN, SCN)
}
impl ECPoint {
pub fn new(ec: &'static EllipticCurve, x: SCN, y: SCN) -> ECPoint {
ECPoint {
curve: ec,
value: ECPointValue::Point(x, y)
}
}
pub fn zero(ec: &'static EllipticCurve) -> ECPoint {
ECPoint { curve: ec, value: ECPointValue::Infinity }
}
pub fn negate(&self) -> ECPoint {
match self.value {
ECPointValue::Infinity =>
self.clone(),
ECPointValue::Point(ref x, ref y) => {
let newy = SCN::from(self.curve.get_p()) - y;
let newv = ECPointValue::Point(x.clone(), newy);
ECPoint{ curve: self.curve, value: newv }
}
}
}
pub fn get_x(&self) -> SCN {
match self.value {
ECPointValue::Infinity =>
SCN::zero(),
ECPointValue::Point(ref x, _) =>
x.clone()
}
}
pub fn get_y(&self) -> SCN {
match self.value {
ECPointValue::Infinity =>
SCN::zero(),
ECPointValue::Point(_, ref y) =>
y.clone()
}
}
pub fn double(&self) -> ECPoint {
match self.value {
ECPointValue::Infinity =>
self.clone(),
ECPointValue::Point(ref x, ref y) => {
let ua = SCN::from(self.curve.get_a());
let up = SCN::from(self.curve.get_p());
// lambda = (3 * xp ^ 2 + a) / 2 yp
let mut lambda = x * x;
lambda *= SCN::from(3);
lambda += &ua;
let twoy = y << 1;
lambda = lambda.divmod(&twoy, &self.curve.get_pu());
// xr = lambda ^ 2 - 2 xp
let mut xr = &lambda * &lambda;
let xr_right = x << 1;
xr -= xr_right;
assert!(!xr.is_negative());
xr %= &up;
// yr = lambda (xp - xr) - yp
let xdiff = x - &xr;
let mut yr = &lambda * &xdiff;
yr -= y;
assert!(!yr.is_negative());
yr %= up;
//
ECPoint {
curve: self.curve,
value: ECPointValue::Point(xr, yr)
}
}
}
}
pub fn add(&self, other: &ECPoint) -> ECPoint {
assert_eq!(self.curve, other.curve);
match (&self.value, &other.value) {
(ECPointValue::Infinity, ECPointValue::Infinity) =>
self.clone(),
(ECPointValue::Infinity, _) =>
other.clone(),
(_, ECPointValue::Infinity) =>
self.clone(),
(ECPointValue::Point(ref sx, ref sy),
ECPointValue::Point(ref ox, ref oy)) => {
let xdiff = sx - ox;
let ydiff = sy - oy;
let pu = self.curve.get_pu();
let s = ydiff.divmod(&xdiff, &pu);
let mut xr = &s * &s;
xr -= sx;
xr -= ox;
xr = xr.reduce(&pu);
let mut yr = sx - &xr;
yr *= &s;
yr -= sy;
yr = yr.reduce(&pu);
let val = ECPointValue::Point(xr, yr);
ECPoint{ curve: self.curve, value: val }
}
}
}
pub fn scale(&self, d: &UCN) -> ECPoint {
match self.value {
ECPointValue::Infinity =>
self.clone(),
ECPointValue::Point(_, _) => {
if d.is_zero() {
return ECPoint::zero(self.curve);
}
let mut q = self.clone();
let i = d.bits() - 2;
let mut mask = UCN::from(1u64) << i;
while !mask.is_zero() {
q = q.double();
let test = d & &mask;
if !test.is_zero() {
q = q.add(&self);
}
mask >>= 1;
}
q
}
}
}
}
//
// pub fn bits2int(x: &[u8], qlen: usize) -> UCN {
// let mut value = UCN::from_bytes(x);
// let vlen = x.len() * 8;
//
// if vlen > qlen {
// value >>= vlen - qlen;
// }
//
// value
// }
//
// pub fn point_add_two_muls(k1: &UCN, p1: &ECCPoint, k2: &UCN, p2: &ECCPoint)
// -> ECCPoint
// {
// panic!("point_add_two_muls()")
// }
//
// #[cfg(test)]
// mod tests {
// use super::*;
//
// #[test]
// fn p256_double() {
// let xbytes = vec![0x7c, 0xf2, 0x7b, 0x18, 0x8d, 0x03, 0x4f, 0x7e,
// 0x8a, 0x52, 0x38, 0x03, 0x04, 0xb5, 0x1a, 0xc3,
// 0xc0, 0x89, 0x69, 0xe2, 0x77, 0xf2, 0x1b, 0x35,
// 0xa6, 0x0b, 0x48, 0xfc, 0x47, 0x66, 0x99, 0x78];
// let ybytes = vec![0x07, 0x77, 0x55, 0x10, 0xdb, 0x8e, 0xd0, 0x40,
// 0x29, 0x3d, 0x9a, 0xc6, 0x9f, 0x74, 0x30, 0xdb,
// 0xba, 0x7d, 0xad, 0xe6, 0x3c, 0xe9, 0x82, 0x29,
// 0x9e, 0x04, 0xb7, 0x9d, 0x22, 0x78, 0x73, 0xd1];
// let x = SCN::from(UCN::from_bytes(&xbytes));
// let y = SCN::from(UCN::from_bytes(&ybytes));
// let base = ECCPoint::default(&EllipticCurve::p256());
// let res = base.double();
// let goal = ECCPoint{ curve: base.curve,
// value: ECCPointValue::Point(x,y) };
// assert_eq!(res, goal);
// }
//
// #[test]
// fn p256_add() {
// let xbytes = vec![0x5e, 0xcb, 0xe4, 0xd1, 0xa6, 0x33, 0x0a, 0x44,
// 0xc8, 0xf7, 0xef, 0x95, 0x1d, 0x4b, 0xf1, 0x65,
// 0xe6, 0xc6, 0xb7, 0x21, 0xef, 0xad, 0xa9, 0x85,
// 0xfb, 0x41, 0x66, 0x1b, 0xc6, 0xe7, 0xfd, 0x6c];
// let ybytes = vec![0x87, 0x34, 0x64, 0x0c, 0x49, 0x98, 0xff, 0x7e,
// 0x37, 0x4b, 0x06, 0xce, 0x1a, 0x64, 0xa2, 0xec,
// 0xd8, 0x2a, 0xb0, 0x36, 0x38, 0x4f, 0xb8, 0x3d,
// 0x9a, 0x79, 0xb1, 0x27, 0xa2, 0x7d, 0x50, 0x32];
// let x = SCN::from(UCN::from_bytes(&xbytes));
// let y = SCN::from(UCN::from_bytes(&ybytes));
// let base = ECCPoint::default(&EllipticCurve::p256());
// let res = base.add(&base.double());
// let goal = ECCPoint{ curve: base.curve,
// value: ECCPointValue::Point(x,y) };
// assert_eq!(res, goal);
// }
//
// #[test]
// fn p256_scale() {
// let xbytes = vec![0xea, 0x68, 0xd7, 0xb6, 0xfe, 0xdf, 0x0b, 0x71,
// 0x87, 0x89, 0x38, 0xd5, 0x1d, 0x71, 0xf8, 0x72,
// 0x9e, 0x0a, 0xcb, 0x8c, 0x2c, 0x6d, 0xf8, 0xb3,
// 0xd7, 0x9e, 0x8a, 0x4b, 0x90, 0x94, 0x9e, 0xe0];
// let ybytes = vec![0x2a, 0x27, 0x44, 0xc9, 0x72, 0xc9, 0xfc, 0xe7,
// 0x87, 0x01, 0x4a, 0x96, 0x4a, 0x8e, 0xa0, 0xc8,
// 0x4d, 0x71, 0x4f, 0xea, 0xa4, 0xde, 0x82, 0x3f,
// 0xe8, 0x5a, 0x22, 0x4a, 0x4d, 0xd0, 0x48, 0xfa];
// let x = SCN::from(UCN::from_bytes(&xbytes));
// let y = SCN::from(UCN::from_bytes(&ybytes));
// let base = ECCPoint::default(&EllipticCurve::p256());
// let res = base.scale(&UCN::from(9 as u64));
// let goal = ECCPoint{ curve: base.curve,
// value: ECCPointValue::Point(x,y) };
// assert_eq!(res, goal);
// }
// }

View File

@@ -8,14 +8,16 @@ use hmac::Hmac;
#[derive(Clone,Debug,PartialEq)]
pub struct ECDSAPrivate {
pub(crate) curve: EllipticCurve,
pub(crate) curve: &'static EllipticCurve,
pub(crate) d: UCN
}
impl ECDSAPrivate {
pub fn new(c: &EllipticCurve, d: &UCN) -> ECDSAPrivate {
pub fn new(c: &'static EllipticCurve, d: &UCN)
-> ECDSAPrivate
{
ECDSAPrivate {
curve: c.clone(),
curve: c,
d: d.clone()
}
}
@@ -64,10 +66,10 @@ impl ECDSAPrivate {
//
// If r turns out to be zero, a new k should be selected and r
// computed again (this is an utterly improbable occurrence).
let g = ECCPoint::default(&self.curve);
let g = ECCPoint::default(self.curve);
let kg = g.scale(&k);
let ni = SCN::from(self.curve.n.clone());
let r = &kg.x % &ni;
let r = &kg.get_x() % &ni;
if r.is_zero() {
continue;
}
@@ -77,7 +79,7 @@ impl ECDSAPrivate {
//
// The pair (r, s) is the signature.
let kinv = SCN::from(k.modinv(&ni.value));
let s = ((SCN::from(h.clone()) + (&kg.x * &r)) * &kinv) % &ni;
let s = ((SCN::from(h.clone()) + (&kg.get_x() * &r)) * &kinv) % &ni;
if s.is_zero() {
continue;
}

View File

@@ -8,14 +8,16 @@ use hmac::Hmac;
#[allow(non_snake_case)]
#[derive(Clone,Debug,PartialEq)]
pub struct ECDSAPublic {
pub(crate) curve: EllipticCurve,
pub(crate) curve: &'static EllipticCurve,
pub(crate) Q: ECCPoint
}
impl ECDSAPublic {
pub fn new(curve: &EllipticCurve, point: &ECCPoint) -> ECDSAPublic {
pub fn new(curve: &'static EllipticCurve, point: &ECCPoint)
-> ECDSAPublic
{
ECDSAPublic {
curve: curve.clone(),
curve: curve,
Q: point.clone()
}
}
@@ -49,11 +51,12 @@ impl ECDSAPublic {
let u2 = (&sig.r * &c) % n;
let x = point_add_two_muls(&u1, &ECCPoint::default(&self.curve),
&u2, &self.Q);
let xx = x.get_x();
if x.x.is_negative() {
if xx.is_negative() {
return false;
}
(x.x.value % n) == sig.r
(xx.value % n) == sig.r
}
}

View File

@@ -11,6 +11,10 @@ import java.lang.Math;
import java.lang.Thread;
import java.math.BigInteger;
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import org.bouncycastle.asn1.nist.NISTNamedCurves;
import org.bouncycastle.asn1.x9.X9ECParameters;
import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
@@ -27,188 +31,288 @@ import org.bouncycastle.crypto.params.ECPrivateKeyParameters;
import org.bouncycastle.crypto.params.ECPublicKeyParameters;
import org.bouncycastle.crypto.signers.ECDSASigner;
import org.bouncycastle.crypto.signers.HMacDSAKCalculator;
import org.bouncycastle.math.ec.ECAlgorithms;
import org.bouncycastle.math.ec.ECPoint;
class Generator {
private FileWriter out;
private SecureRandom rng;
final static int COUNT = 500;
final static int NUM_THREADS = 4;
public Generator(SecureRandom r, FileWriter o) {
rng = r;
out = o;
}
public void runTests(String curveName, int count)
public static void main(String[] args)
throws IOException, InterruptedException
{
Thread threads[] = new Thread[NUM_THREADS];
System.out.print("Generating " + curveName + " tests ");
for(int i = 0; i < NUM_THREADS; i++) {
X9ECParameters x9ECParameters = NISTNamedCurves.getByName(curveName);
ECDomainParameters params = new ECDomainParameters(x9ECParameters.getCurve(),
x9ECParameters.getG(),
x9ECParameters.getN());
Runner runner = new Runner(params, count / NUM_THREADS, this);
Thread runThread = new Thread(runner);
runThread.start();
threads[i] = runThread;
new Generator().run();
}
for(Thread thread : threads) {
public Generator() { }
public void run()
throws IOException, InterruptedException
{
OutFiles outfiles = new OutFiles();
String[] curves = { "P-192", "P-224", "P-256", "P-384", "P-521" };
ArrayList<Thread> threads = new ArrayList<Thread>();
System.out.print("Generating: ");
for(String curve : curves) {
X9ECParameters params = NISTNamedCurves.getByName(curve);
ECDomainParameters dp = new ECDomainParameters(params.getCurve(),
params.getG(),
params.getN());
Runner runner = new Runner(outfiles, dp);
Thread thread = new Thread(runner);
thread.start();
threads.add(thread);
}
for(Thread thread: threads) {
thread.join();
}
System.out.println(" done.");
}
public synchronized void output(AsymmetricCipherKeyPair kp,
int digestsize,
byte[] message,
BigInteger[] rs)
throws IOException
public class OutFiles {
public FileWriter negate;
public FileWriter dble;
public FileWriter add;
public FileWriter mul;
public FileWriter add2mul;
public FileWriter sig;
public OutFiles()
{
ECPublicKeyParameters pub = (ECPublicKeyParameters)kp.getPublic();
ECPrivateKeyParameters priv = (ECPrivateKeyParameters)kp.getPrivate();
out.write("c: " + pub.getParameters().getCurve().getFieldSize() + "\n");
out.write("x: " + pub.getQ().getAffineXCoord().toBigInteger().toString(16) + "\n");
out.write("y: " + pub.getQ().getAffineYCoord().toBigInteger().toString(16) + "\n");
out.write("d: " + priv.getD().toString(16) + "\n");
out.write("h: " + digestsize + "\n");
out.write("m: " + asHex(message) + "\n");
out.write("r: " + rs[0].toString(16) + "\n");
out.write("s: " + rs[1].toString(16) + "\n");
out.flush();
System.out.print(".");
try {
negate = new FileWriter("ec_negate.test", false);
dble = new FileWriter("ec_dble.test", false);
add = new FileWriter("ec_add.test", false);
mul = new FileWriter("ec_mul.test", false);
add2mul = new FileWriter("ec_add2mul.test", false);
sig = new FileWriter("signature.test", false);
} catch(IOException e) {
System.out.println("Blech: " + e);
}
}
public synchronized void dump(FileWriter file, Map<String,String> x) {
try {
for(Map.Entry<String,String> entry : x.entrySet()) {
file.write(entry.getKey());
file.write(": ");
file.write(entry.getValue());
file.write("\n");
file.flush();
if(file == negate) { System.out.print("N"); };
if(file == dble) { System.out.print("D"); };
if(file == add) { System.out.print("A"); };
if(file == mul) { System.out.print("M"); };
if(file == add2mul) { System.out.print("2"); };
if(file == sig) { System.out.print("S"); };
System.out.flush();
}
private Digest appropriateDigest(int nsize)
throws IOException
{
switch(nsize) {
case 1: return new SHA1Digest();
case 160: return new SHA1Digest();
case 224: return new SHA224Digest();
case 256: return new SHA256Digest();
case 384: return new SHA384Digest();
case 512: return new SHA512Digest();
default:
throw new IOException("Bad digest size!");
} catch(IOException e) {
System.out.println("Argh: " + e);
}
}
}
private int randomDigestSize()
throws IOException
{
switch(getRandomChoice(5)) {
case 0: return 1;
case 1: return 224;
case 2: return 256;
case 3: return 384;
case 4: return 512;
default:
throw new IOException("The world broke.");
}
public class Runner implements Runnable {
private OutFiles outfiles;
private SecureRandom rng;
private ECDomainParameters ecparams;
private BigInteger two;
public Runner(OutFiles outfiles, ECDomainParameters params) {
this.outfiles = outfiles;
this.ecparams = params;
this.rng = new SecureRandom();
this.two = BigInteger.valueOf(2);
}
private int getRandomChoice(int modulus) {
byte randoms[] = new byte[2];
rng.nextBytes(randoms);
int random = ((int)randoms[0] << 8) + ((int)randoms[1]);
return (Math.abs(random) % modulus);
public void run() {
for(int i = 0; i < COUNT; i++) { generateNegateTests(); }
for(int i = 0; i < COUNT; i++) { generateDoubleTests(); }
for(int i = 0; i < COUNT; i++) { generateAddTests(); }
for(int i = 0; i < COUNT; i++) { generateMulTests(); }
for(int i = 0; i < COUNT; i++) { generateAdd2MulTests(); }
for(int i = 0; i < COUNT; i++) { generateSignatureTests(); }
}
private String asHex(byte[] data) {
String result = "";
public void generateNegateTests() {
ECPoint p = getPoint();
ECPoint n = p.negate().normalize();
HashMap<String,String> m = new HashMap<String,String>();
for(byte value : data) {
result = result + String.format("%02x", value);
m.put("c", Integer.toString(ecparams.getN().bitLength()));
m.put("x", p.getAffineXCoord().toBigInteger().toString(16));
m.put("y", p.getAffineYCoord().toBigInteger().toString(16));
m.put("a", n.getAffineXCoord().toBigInteger().toString(16));
m.put("b", n.getAffineYCoord().toBigInteger().toString(16));
outfiles.dump(outfiles.negate, m);
}
return result;
public void generateDoubleTests() {
ECPoint p = getPoint();
ECPoint n = p.twice().normalize();
HashMap<String,String> m = new HashMap<String,String>();
m.put("c", Integer.toString(ecparams.getN().bitLength()));
m.put("x", p.getAffineXCoord().toBigInteger().toString(16));
m.put("y", p.getAffineYCoord().toBigInteger().toString(16));
m.put("a", n.getAffineXCoord().toBigInteger().toString(16));
m.put("b", n.getAffineYCoord().toBigInteger().toString(16));
outfiles.dump(outfiles.dble, m);
}
public static void main(String[] args)
throws IOException, InterruptedException
{
SecureRandom rng = new SecureRandom();
FileWriter outfile = new FileWriter("signature.test", false);
Generator gen = new Generator(rng, outfile);
public void generateAddTests() {
ECPoint p1 = getPoint();
ECPoint p2 = getPoint();
ECPoint q = p1.add(p2).normalize();
HashMap<String,String> m = new HashMap<String,String>();
gen.runTests("P-192", 500);
gen.runTests("P-224", 500);
gen.runTests("P-256", 500);
gen.runTests("P-384", 500);
gen.runTests("P-521", 500);
m.put("c", Integer.toString(ecparams.getN().bitLength()));
m.put("x", p1.getAffineXCoord().toBigInteger().toString(16));
m.put("y", p1.getAffineYCoord().toBigInteger().toString(16));
m.put("q", p2.getAffineXCoord().toBigInteger().toString(16));
m.put("r", p2.getAffineYCoord().toBigInteger().toString(16));
m.put("a", q.getAffineXCoord().toBigInteger().toString(16));
m.put("b", q.getAffineYCoord().toBigInteger().toString(16));
outfiles.dump(outfiles.add, m);
}
private class Runner implements Runnable {
private ECDomainParameters params;
private int count;
private Generator parent;
public void generateMulTests() {
ECPoint p = getPoint();
BigInteger k = getConstant();
ECPoint q = p.multiply(k).normalize();
HashMap<String,String> m = new HashMap<String,String>();
public Runner(ECDomainParameters params, int count, Generator parent)
{
this.params = params;
this.count = count;
this.parent = parent;
m.put("c", Integer.toString(ecparams.getN().bitLength()));
m.put("x", p.getAffineXCoord().toBigInteger().toString(16));
m.put("y", p.getAffineYCoord().toBigInteger().toString(16));
m.put("k", k.toString(16));
m.put("a", q.getAffineXCoord().toBigInteger().toString(16));
m.put("b", q.getAffineYCoord().toBigInteger().toString(16));
outfiles.dump(outfiles.mul, m);
}
public void run()
{
for(int i = 0; i < count; i++) {
runTest();
}
public void generateAdd2MulTests() {
ECPoint p = getPoint();
BigInteger a = getConstant();
ECPoint q = getPoint();
BigInteger b = getConstant();
ECPoint r = ECAlgorithms.sumOfTwoMultiplies(p,a,q,b).normalize();
HashMap<String,String> m = new HashMap<String,String>();
m.put("c", Integer.toString(ecparams.getN().bitLength()));
m.put("x", p.getAffineXCoord().toBigInteger().toString(16));
m.put("y", p.getAffineYCoord().toBigInteger().toString(16));
m.put("a", a.toString(16));
m.put("q", q.getAffineXCoord().toBigInteger().toString(16));
m.put("r", q.getAffineYCoord().toBigInteger().toString(16));
m.put("b", b.toString(16));
m.put("s", r.getAffineXCoord().toBigInteger().toString(16));
m.put("t", r.getAffineYCoord().toBigInteger().toString(16));
outfiles.dump(outfiles.add2mul, m);
}
private AsymmetricCipherKeyPair getKeyPair()
{
ECKeyGenerationParameters params =
new ECKeyGenerationParameters(this.params, this.parent.rng);
ECKeyPairGenerator keygen = new ECKeyPairGenerator();
keygen.init(params);
return keygen.generateKeyPair();
public void generateSignatureTests() {
AsymmetricCipherKeyPair kp = getKeyPair();
ECPublicKeyParameters pub = (ECPublicKeyParameters)kp.getPublic();
ECPrivateKeyParameters priv = (ECPrivateKeyParameters)kp.getPrivate();
byte message[] = getMessage();
int digestsize = getDigestSize();
byte hash[] = runHash(message, digestsize);
Digest msgdigest = getHash(digestsize);
HMacDSAKCalculator kgen = new HMacDSAKCalculator(msgdigest);
ECDSASigner signer = new ECDSASigner(kgen);
signer.init(true, priv);
BigInteger rs[] = signer.generateSignature(hash);
HashMap<String,String> m = new HashMap<String,String>();
m.put("c", Integer.toString(ecparams.getN().bitLength()));
m.put("x", pub.getQ().getAffineXCoord().toBigInteger().toString(16));
m.put("y", pub.getQ().getAffineYCoord().toBigInteger().toString(16));
m.put("d", priv.getD().toString(16));
m.put("h", Integer.toString(digestsize));
m.put("m", asHex(message));
m.put("r", rs[0].toString(16));
m.put("s", rs[1].toString(16));
outfiles.dump(outfiles.sig, m);
}
private byte[] getMessage()
{
int msgsize = getRandomChoice(1024);
byte message[] = new byte[msgsize];
rng.nextBytes(message);
return message;
}
private byte[] runHash(byte[] msg, int digestsize)
throws IOException
{
Digest digestfn = appropriateDigest(digestsize);
private byte[] runHash(byte[] msg, int size) {
Digest digestfn = getHash(size);
digestfn.update(msg, 0, msg.length);
byte result[] = new byte[digestfn.getDigestSize()];
digestfn.doFinal(result, 0);
return result;
}
private void runTest()
{
try {
AsymmetricCipherKeyPair kp = getKeyPair();
ECPublicKeyParameters pub = (ECPublicKeyParameters)kp.getPublic();
ECPrivateKeyParameters priv = (ECPrivateKeyParameters)kp.getPrivate();
private AsymmetricCipherKeyPair getKeyPair() {
ECKeyGenerationParameters params =
new ECKeyGenerationParameters(ecparams, rng);
ECKeyPairGenerator keygen = new ECKeyPairGenerator();
keygen.init(params);
return keygen.generateKeyPair();
}
byte message[] = getMessage();
int digestsize = randomDigestSize();
byte hash[] = runHash(message, digestsize);
private byte[] getMessage() {
int msgsize = rng.nextInt(1024);
byte message[] = new byte[msgsize];
rng.nextBytes(message);
return message;
}
Digest msgdigest = appropriateDigest(digestsize);
HMacDSAKCalculator kgen = new HMacDSAKCalculator(msgdigest);
ECDSASigner signer = new ECDSASigner(kgen);
signer.init(true, priv);
BigInteger rs[] = signer.generateSignature(hash);
parent.output(kp, digestsize, message, rs);
} catch(IOException exc) {
System.out.println("EXCEPTION!");
run();
private ECPoint getPoint() {
BigInteger k = getConstant();
return ecparams.getG().multiply(k).normalize();
}
private BigInteger getConstant() {
BigInteger n = ecparams.getN();
int nBitLength = n.bitLength();
for(;;) {
BigInteger d = new BigInteger(nBitLength, rng);
if(d.compareTo(two) < 0 || (d.compareTo(n) >= 0)) {
continue;
}
return d;
}
}
private int getDigestSize() {
switch(rng.nextInt(5)) {
case 0: return 1;
case 1: return 224;
case 2: return 256;
case 3: return 384;
case 4: return 512;
default:
return 999;
}
}
private Digest getHash(int nsize) {
switch(nsize) {
case 1: return new SHA1Digest();
case 224: return new SHA1Digest();
case 256: return new SHA1Digest();
case 384: return new SHA1Digest();
case 512: return new SHA1Digest();
default:
return null;
}
}
private String asHex(byte[] data) {
String result = "";
for(byte value : data) {
result = result + String.format("%02x", value);
}
return result;
}
}
}

17500
tests/ecdsa/ec_add.test Normal file

File diff suppressed because it is too large Load Diff

22500
tests/ecdsa/ec_add2mul.test Normal file

File diff suppressed because it is too large Load Diff

12500
tests/ecdsa/ec_dble.test Normal file

File diff suppressed because it is too large Load Diff

15000
tests/ecdsa/ec_mul.test Normal file

File diff suppressed because it is too large Load Diff

12500
tests/ecdsa/ec_negate.test Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff