[BROKEN] Trying to get elliptic curve working, which is much too slow at the moment.
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
use cryptonum::unsigned::{UCN,divmod};
|
use cryptonum::unsigned::{BarrettUCN,UCN,divmod};
|
||||||
use num::BigInt;
|
use num::BigInt;
|
||||||
use num::bigint::Sign;
|
use num::bigint::Sign;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
@@ -67,14 +67,27 @@ impl SCN {
|
|||||||
(old_r, old_s, old_t)
|
(old_r, old_s, old_t)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn divmod(&self, x: &SCN, m: &UCN) -> SCN {
|
pub fn reduce(&self, m: &BarrettUCN) -> SCN {
|
||||||
let sm = SCN::from(m.clone());
|
println!("signed reduce");
|
||||||
let xmod = x % &sm;
|
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);
|
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);
|
let si = SCN::from(i);
|
||||||
|
println!("STEP5");
|
||||||
let yi = self * si;
|
let yi = self * si;
|
||||||
yi % sm
|
println!("STEP6: {:X}", yi);
|
||||||
|
println!(" mod {:X}", m.m);
|
||||||
|
let res = yi.reduce(m);
|
||||||
|
println!("STEP7");
|
||||||
|
res
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -132,34 +132,54 @@ impl UCN {
|
|||||||
|
|
||||||
pub fn barrett_u(&self) -> BarrettUCN {
|
pub fn barrett_u(&self) -> BarrettUCN {
|
||||||
let k = self.contents.len();
|
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 b = UCN::from(1 as u8) << (64 * 2 * k);
|
||||||
let u = b / self;
|
let u = b / self;
|
||||||
BarrettUCN{ u: u, k: k, m: self.clone() }
|
BarrettUCN{ u: u, k: k, m: self.clone() }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn reduce(&self, u: &BarrettUCN) -> UCN {
|
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/bk−1⌋, q2←q1 · μ, q3←⌊q2/bk+1⌋.
|
// 1. q1←⌊x/bk−1⌋, q2←q1 · μ, q3←⌊q2/bk+1⌋.
|
||||||
let q1 = self >> (64 * (u.k - 1));
|
let q1 = self >> (64 * (u.k - 1));
|
||||||
|
println!("reduce1");
|
||||||
let q2 = q1 * &u.u;
|
let q2 = q1 * &u.u;
|
||||||
|
println!("reduce2");
|
||||||
let q3 = q2 >> (64 * (u.k + 1));
|
let q3 = q2 >> (64 * (u.k + 1));
|
||||||
|
println!("reduce3");
|
||||||
// 2. r1←x mod bk+1, r2←q3 · m mod bk+1, r←r1 − r2.
|
// 2. r1←x mod bk+1, r2←q3 · m mod bk+1, r←r1 − r2.
|
||||||
// 3. If r<0 then r←r+bk+1.
|
// 3. If r<0 then r←r+bk+1.
|
||||||
let mut r1 = self.clone();
|
let mut r1 = self.clone();
|
||||||
r1.contents.resize(u.k + 1, 0);
|
r1.contents.resize(u.k + 1, 0);
|
||||||
|
println!("reduce4");
|
||||||
let mut r2 = q3 * &u.m;
|
let mut r2 = q3 * &u.m;
|
||||||
r2.contents.resize(u.k + 1, 0);
|
r2.contents.resize(u.k + 1, 0);
|
||||||
|
println!("reduce5");
|
||||||
|
println!(" r1: {:X}", r1);
|
||||||
|
println!(" r2: {:X}", r2);
|
||||||
let mut r = if r1 >= r2 {
|
let mut r = if r1 >= r2 {
|
||||||
|
println!("reduce5a");
|
||||||
r1 - r2
|
r1 - r2
|
||||||
} else {
|
} else {
|
||||||
|
println!("reduce5b");
|
||||||
let mut bk1cont = Vec::with_capacity(u.k + 1);
|
let mut bk1cont = Vec::with_capacity(u.k + 1);
|
||||||
bk1cont.resize(u.k, 0);
|
bk1cont.resize(u.k, 0);
|
||||||
bk1cont.push(1);
|
bk1cont.push(1);
|
||||||
(r1 + UCN{ contents: bk1cont }) - r2
|
(r1 + UCN{ contents: bk1cont }) - r2
|
||||||
};
|
};
|
||||||
|
println!("reduce6");
|
||||||
|
println!(" r = {:X}", r);
|
||||||
|
println!(" m = {:X}", u.m);
|
||||||
// 4. Whiler≥mdo:r←r−m.
|
// 4. Whiler≥mdo:r←r−m.
|
||||||
while &r >= &u.m {
|
while &r >= &u.m {
|
||||||
r -= &u.m;
|
r -= &u.m;
|
||||||
}
|
}
|
||||||
|
println!("reduce7");
|
||||||
// 5. Return(r).
|
// 5. Return(r).
|
||||||
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 qit1 = UCN{ contents: vec![q[i - t - 1]] };
|
||||||
let ybit1 = &y << (64 * (i - t - 1));
|
let ybit1 = &y << (64 * (i - t - 1));
|
||||||
let subbit = &qit1 * &ybit1;
|
let subbit = &qit1 * &ybit1;
|
||||||
|
let orig_x_len = x.contents.len();
|
||||||
if subbit <= x {
|
if subbit <= x {
|
||||||
x -= subbit;
|
x -= subbit;
|
||||||
} else {
|
} else {
|
||||||
@@ -889,6 +910,9 @@ pub fn divmod(quotient: &mut Vec<u64>, remainder: &mut Vec<u64>,
|
|||||||
x -= subbit - ybit1;
|
x -= subbit - ybit1;
|
||||||
q[i - t - 1] -= 1;
|
q[i - t - 1] -= 1;
|
||||||
}
|
}
|
||||||
|
while x.contents.len() < orig_x_len {
|
||||||
|
x.contents.insert(0, 0);
|
||||||
|
}
|
||||||
i -= 1;
|
i -= 1;
|
||||||
}
|
}
|
||||||
// 4. r <- x
|
// 4. r <- x
|
||||||
@@ -898,6 +922,7 @@ pub fn divmod(quotient: &mut Vec<u64>, remainder: &mut Vec<u64>,
|
|||||||
// everything earlier; this removes it.
|
// everything earlier; this removes it.
|
||||||
x.contents.remove(0);
|
x.contents.remove(0);
|
||||||
}
|
}
|
||||||
|
x.clean();
|
||||||
remainder.append(&mut x.contents);
|
remainder.append(&mut x.contents);
|
||||||
// 5. return (q,r)
|
// 5. return (q,r)
|
||||||
while (q.len() > 0) && (q[q.len() - 1] == 0) {
|
while (q.len() > 0) && (q[q.len() - 1] == 0) {
|
||||||
|
|||||||
@@ -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 struct EllipticCurve {
|
||||||
pub p: UCN,
|
pub name: &'static str,
|
||||||
pub n: UCN,
|
pub p: [u8; 66],
|
||||||
pub SEED: UCN,
|
pub n: [u8; 66],
|
||||||
pub c: UCN,
|
pub seed: [u8; 66],
|
||||||
pub a: UCN,
|
pub c: [u8; 66],
|
||||||
pub b: UCN,
|
pub a: [u8; 66],
|
||||||
pub Gx: SCN,
|
pub b: [u8; 66],
|
||||||
pub Gy: SCN
|
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 {
|
impl EllipticCurve {
|
||||||
/// Create a new elliptic curve structure that represents NIST's
|
pub fn get_p(&self) -> UCN {
|
||||||
/// p192 curve.
|
UCN::from_bytes(&self.p)
|
||||||
pub fn p192() -> EllipticCurve {
|
}
|
||||||
EllipticCurve {
|
|
||||||
p: UCN::from_bytes(&vec![
|
pub fn get_pu(&self) -> BarrettUCN {
|
||||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
self.get_p().barrett_uk(self.get_p().contents.len() + 4)
|
||||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe,
|
}
|
||||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]),
|
|
||||||
n: UCN::from_bytes(&vec![
|
pub fn get_n(&self) -> UCN {
|
||||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
UCN::from_bytes(&self.n)
|
||||||
0xff, 0xff, 0xff, 0xff, 0x99, 0xde, 0xf8, 0x36,
|
}
|
||||||
0x14, 0x6b, 0xc9, 0xb1, 0xb4, 0xd2, 0x28, 0x31]),
|
|
||||||
SEED: UCN::from_bytes(&vec![
|
pub fn get_seed(&self) -> UCN {
|
||||||
0x30, 0x45, 0xae, 0x6f, 0xc8, 0x42, 0x2f, 0x64,
|
UCN::from_bytes(&self.seed)
|
||||||
0xed, 0x57, 0x95, 0x28, 0xd3, 0x81, 0x20, 0xea,
|
}
|
||||||
0xe1, 0x21, 0x96, 0xd5]),
|
|
||||||
c: UCN::from_bytes(&vec![
|
pub fn get_c(&self) -> UCN {
|
||||||
0x30, 0x99, 0xd2, 0xbb, 0xbf, 0xcb, 0x25, 0x38,
|
UCN::from_bytes(&self.c)
|
||||||
0x54, 0x2d, 0xcd, 0x5f, 0xb0, 0x78, 0xb6, 0xef,
|
}
|
||||||
0x5f, 0x3d, 0x6f, 0xe2, 0xc7, 0x45, 0xde, 0x65]),
|
|
||||||
a: UCN::from_bytes(&vec![
|
pub fn get_a(&self) -> UCN {
|
||||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
UCN::from_bytes(&self.a)
|
||||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe,
|
}
|
||||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc]),
|
|
||||||
b: UCN::from_bytes(&vec![
|
pub fn get_b(&self) -> UCN {
|
||||||
0x64, 0x21, 0x05, 0x19, 0xe5, 0x9c, 0x80, 0xe7,
|
UCN::from_bytes(&self.b)
|
||||||
0x0f, 0xa7, 0xe9, 0xab, 0x72, 0x24, 0x30, 0x49,
|
}
|
||||||
0xfe, 0xb8, 0xde, 0xec, 0xc1, 0x46, 0xb9, 0xb1]),
|
|
||||||
Gx: SCN::from(UCN::from_bytes(&vec![
|
pub fn default(&'static self) -> ECPoint {
|
||||||
0x18, 0x8d, 0xa8, 0x0e, 0xb0, 0x30, 0x90, 0xf6,
|
let x = SCN::from(UCN::from_bytes(&self.gx));
|
||||||
0x7c, 0xbf, 0x20, 0xeb, 0x43, 0xa1, 0x88, 0x00,
|
let y = SCN::from(UCN::from_bytes(&self.gy));
|
||||||
0xf4, 0xff, 0x0a, 0xfd, 0x82, 0xff, 0x10, 0x12])),
|
ECPoint::new(self, x, y)
|
||||||
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]))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new elliptic curve structure that represents NIST's
|
pub const NIST_P192: EllipticCurve = EllipticCurve {
|
||||||
/// p224 curve.
|
name: "secp192r1",
|
||||||
pub fn p224() -> EllipticCurve {
|
p: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
EllipticCurve {
|
|
||||||
p: UCN::from_bytes(&vec![
|
|
||||||
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, 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, 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, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc]),
|
0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
b: UCN::from_bytes(&vec![
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
0x5a, 0xc6, 0x35, 0xd8, 0xaa, 0x3a, 0x93, 0xe7,
|
0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
0xb3, 0xeb, 0xbd, 0x55, 0x76, 0x98, 0x86, 0xbc,
|
0xff, 0xff ],
|
||||||
0x65, 0x1d, 0x06, 0xb0, 0xcc, 0x53, 0xb0, 0xf6,
|
n: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x3b, 0xce, 0x3c, 0x3e, 0x27, 0xd2, 0x60, 0x4b]),
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
Gx: SCN::from(UCN::from_bytes(&vec![
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x6b, 0x17, 0xd1, 0xf2, 0xe1, 0x2c, 0x42, 0x47,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0xf8, 0xbc, 0xe6, 0xe5, 0x63, 0xa4, 0x40, 0xf2,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x77, 0x03, 0x7d, 0x81, 0x2d, 0xeb, 0x33, 0xa0,
|
0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
0xf4, 0xa1, 0x39, 0x45, 0xd8, 0x98, 0xc2, 0x96])),
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x99, 0xde,
|
||||||
Gy: SCN::from(UCN::from_bytes(&vec![
|
0xf8, 0x36, 0x14, 0x6b, 0xc9, 0xb1, 0xb4, 0xd2,
|
||||||
0x4f, 0xe3, 0x42, 0xe2, 0xfe, 0x1a, 0x7f, 0x9b,
|
0x28, 0x31 ],
|
||||||
0x8e, 0xe7, 0xeb, 0x4a, 0x7c, 0x0f, 0x9e, 0x16,
|
seed: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x2b, 0xce, 0x33, 0x57, 0x6b, 0x31, 0x5e, 0xce,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0xcb, 0xb6, 0x40, 0x68, 0x37, 0xbf, 0x51, 0xf5]))
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 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
|
pub const NIST_P224: EllipticCurve = EllipticCurve {
|
||||||
/// p256 curve.
|
name: "secp224r1",
|
||||||
pub fn p384() -> EllipticCurve {
|
p: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
EllipticCurve {
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
p: UCN::from_bytes(&vec![
|
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, 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, 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, 0xff,
|
||||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe,
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff,
|
||||||
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, 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, 0xff, 0xff, 0xff, 0xff,
|
b: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0xc7, 0x63, 0x4d, 0x81, 0xf4, 0x37, 0x2d, 0xdf,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x58, 0x1a, 0x0d, 0xb2, 0x48, 0xb0, 0xa7, 0x7a,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0xec, 0xec, 0x19, 0x6a, 0xcc, 0xc5, 0x29, 0x73]),
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
SEED: UCN::from_bytes(&vec![
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb4, 0x05,
|
||||||
0xa3, 0x35, 0x92, 0x6a, 0xa3, 0x19, 0xa2, 0x7a,
|
0x0a, 0x85, 0x0c, 0x04, 0xb3, 0xab, 0xf5, 0x41,
|
||||||
0x1d, 0x00, 0x89, 0x6a, 0x67, 0x73, 0xa4, 0x82,
|
0x32, 0x56, 0x50, 0x44, 0xb0, 0xb7, 0xd7, 0xbf,
|
||||||
0x7a, 0xcd, 0xac, 0x73]),
|
0xd8, 0xba, 0x27, 0x0b, 0x39, 0x43, 0x23, 0x55,
|
||||||
c: UCN::from_bytes(&vec![
|
0xff, 0xb4],
|
||||||
0x79, 0xd1, 0xe6, 0x55, 0xf8, 0x68, 0xf0, 0x2f,
|
gx: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0xff, 0x48, 0xdc, 0xde, 0xe1, 0x41, 0x51, 0xdd,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0xb8, 0x06, 0x43, 0xc1, 0x40, 0x6d, 0x0c, 0xa1,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x0d, 0xfe, 0x6f, 0xc5, 0x20, 0x09, 0x54, 0x0a,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x49, 0x5e, 0x80, 0x42, 0xea, 0x5f, 0x74, 0x4f,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb7, 0x0e,
|
||||||
0x6e, 0x18, 0x46, 0x67, 0xcc, 0x72, 0x24, 0x83]),
|
0x0c, 0xbd, 0x6b, 0xb4, 0xbf, 0x7f, 0x32, 0x13,
|
||||||
a: UCN::from_bytes(&vec![
|
0x90, 0xb9, 0x4a, 0x03, 0xc1, 0xd3, 0x56, 0xc2,
|
||||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
0x11, 0x22, 0x34, 0x32, 0x80, 0xd6, 0x11, 0x5c,
|
||||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
0x1d, 0x21],
|
||||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
gy: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xfc]),
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
b: UCN::from_bytes(&vec![
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbd, 0x37,
|
||||||
0xb3, 0x31, 0x2f, 0xa7, 0xe2, 0x3e, 0xe7, 0xe4,
|
0x63, 0x88, 0xb5, 0xf7, 0x23, 0xfb, 0x4c, 0x22,
|
||||||
0x98, 0x8e, 0x05, 0x6b, 0xe3, 0xf8, 0x2d, 0x19,
|
0xdf, 0xe6, 0xcd, 0x43, 0x75, 0xa0, 0x5a, 0x07,
|
||||||
0x18, 0x1d, 0x9c, 0x6e, 0xfe, 0x81, 0x41, 0x12,
|
0x47, 0x64, 0x44, 0xd5, 0x81, 0x99, 0x85, 0x00,
|
||||||
0x03, 0x14, 0x08, 0x8f, 0x50, 0x13, 0x87, 0x5a,
|
0x7e, 0x34]
|
||||||
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]))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Create a new elliptic curve structure that represents NIST's
|
pub const NIST_P256: EllipticCurve = EllipticCurve {
|
||||||
/// p256 curve.
|
name: "secp256r1",
|
||||||
pub fn p521() -> EllipticCurve {
|
p: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
EllipticCurve {
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
p: UCN::from_bytes(&vec![
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
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,
|
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, 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![
|
n: [ 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
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,
|
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,
|
0x96, 0x6b, 0x7f, 0xcc, 0x01, 0x48, 0xf7, 0x09,
|
||||||
0xa5, 0xd0, 0x3b, 0xb5, 0xc9, 0xb8, 0x89, 0x9c,
|
0xa5, 0xd0, 0x3b, 0xb5, 0xc9, 0xb8, 0x89, 0x9c,
|
||||||
0x47, 0xae, 0xbb, 0x6f, 0xb7, 0x1e, 0x91, 0x38,
|
0x47, 0xae, 0xbb, 0x6f, 0xb7, 0x1e, 0x91, 0x38,
|
||||||
0x64, 0x09]),
|
0x64, 0x09 ],
|
||||||
SEED: UCN::from_bytes(&vec![
|
seed: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0xd0, 0x9e, 0x88, 0x00, 0x29, 0x1c, 0xb8, 0x53,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x96, 0xcc, 0x67, 0x17, 0x39, 0x32, 0x84, 0xaa,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0xa0, 0xda, 0x64, 0xba]),
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
c: UCN::from_bytes(&vec![
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0xb4, 0x8b, 0xfa, 0x5f, 0x42, 0x0a, 0x34, 0x94,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, 0x9e,
|
||||||
0x95, 0x39, 0xd2, 0xbd, 0xfc, 0x26, 0x4e, 0xee,
|
0x88, 0x00, 0x29, 0x1c, 0xb8, 0x53, 0x96, 0xcc,
|
||||||
0xeb, 0x07, 0x76, 0x88, 0xe4, 0x4f, 0xbf, 0x0a,
|
0x67, 0x17, 0x39, 0x32, 0x84, 0xaa, 0xa0, 0xda,
|
||||||
0xd8, 0xf6, 0xd0, 0xed, 0xb3, 0x7b, 0xd6, 0xb5,
|
0x64, 0xba ],
|
||||||
0x33, 0x28, 0x10, 0x00, 0x51, 0x8e, 0x19, 0xf1,
|
c: [ 0x00, 0xb4, 0x8b, 0xfa, 0x5f, 0x42, 0x0a, 0x34,
|
||||||
0xb9, 0xff, 0xbe, 0x0f, 0xe9, 0xed, 0x8a, 0x3c,
|
0x94, 0x95, 0x39, 0xd2, 0xbd, 0xfc, 0x26, 0x4e,
|
||||||
0x22, 0x00, 0xb8, 0xf8, 0x75, 0xe5, 0x23, 0x86,
|
0xee, 0xeb, 0x07, 0x76, 0x88, 0xe4, 0x4f, 0xbf,
|
||||||
0x8c, 0x70, 0xc1, 0xe5, 0xbf, 0x55, 0xba, 0xd6,
|
0x0a, 0xd8, 0xf6, 0xd0, 0xed, 0xb3, 0x7b, 0xd6,
|
||||||
0x37]),
|
0xb5, 0x33, 0x28, 0x10, 0x00, 0x51, 0x8e, 0x19,
|
||||||
a: UCN::from_bytes(&vec![
|
0xf1, 0xb9, 0xff, 0xbe, 0x0f, 0xe9, 0xed, 0x8a,
|
||||||
0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
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,
|
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, 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]),
|
0xff, 0xfc ],
|
||||||
b: UCN::from_bytes(&vec![
|
b: [ 0x00, 0x51, 0x95, 0x3e, 0xb9, 0x61, 0x8e, 0x1c,
|
||||||
0x51, 0x95, 0x3e, 0xb9, 0x61, 0x8e, 0x1c, 0x9a,
|
0x9a, 0x1f, 0x92, 0x9a, 0x21, 0xa0, 0xb6, 0x85,
|
||||||
0x1f, 0x92, 0x9a, 0x21, 0xa0, 0xb6, 0x85, 0x40,
|
0x40, 0xee, 0xa2, 0xda, 0x72, 0x5b, 0x99, 0xb3,
|
||||||
0xee, 0xa2, 0xda, 0x72, 0x5b, 0x99, 0xb3, 0x15,
|
0x15, 0xf3, 0xb8, 0xb4, 0x89, 0x91, 0x8e, 0xf1,
|
||||||
0xf3, 0xb8, 0xb4, 0x89, 0x91, 0x8e, 0xf1, 0x09,
|
0x09, 0xe1, 0x56, 0x19, 0x39, 0x51, 0xec, 0x7e,
|
||||||
0xe1, 0x56, 0x19, 0x39, 0x51, 0xec, 0x7e, 0x93,
|
0x93, 0x7b, 0x16, 0x52, 0xc0, 0xbd, 0x3b, 0xb1,
|
||||||
0x7b, 0x16, 0x52, 0xc0, 0xbd, 0x3b, 0xb1, 0xbf,
|
0xbf, 0x07, 0x35, 0x73, 0xdf, 0x88, 0x3d, 0x2c,
|
||||||
0x07, 0x35, 0x73, 0xdf, 0x88, 0x3d, 0x2c, 0x34,
|
0x34, 0xf1, 0xef, 0x45, 0x1f, 0xd4, 0x6b, 0x50,
|
||||||
0xf1, 0xef, 0x45, 0x1f, 0xd4, 0x6b, 0x50, 0x3f,
|
0x3f, 0x00 ],
|
||||||
0x00]),
|
gx: [ 0x00, 0xc6, 0x85, 0x8e, 0x06, 0xb7, 0x04, 0x04,
|
||||||
Gx: SCN::from(UCN::from_bytes(&vec![
|
0xe9, 0xcd, 0x9e, 0x3e, 0xcb, 0x66, 0x23, 0x95,
|
||||||
0xc6, 0x85, 0x8e, 0x06, 0xb7, 0x04, 0x04, 0xe9,
|
0xb4, 0x42, 0x9c, 0x64, 0x81, 0x39, 0x05, 0x3f,
|
||||||
0xcd, 0x9e, 0x3e, 0xcb, 0x66, 0x23, 0x95, 0xb4,
|
0xb5, 0x21, 0xf8, 0x28, 0xaf, 0x60, 0x6b, 0x4d,
|
||||||
0x42, 0x9c, 0x64, 0x81, 0x39, 0x05, 0x3f, 0xb5,
|
0x3d, 0xba, 0xa1, 0x4b, 0x5e, 0x77, 0xef, 0xe7,
|
||||||
0x21, 0xf8, 0x28, 0xaf, 0x60, 0x6b, 0x4d, 0x3d,
|
0x59, 0x28, 0xfe, 0x1d, 0xc1, 0x27, 0xa2, 0xff,
|
||||||
0xba, 0xa1, 0x4b, 0x5e, 0x77, 0xef, 0xe7, 0x59,
|
0xa8, 0xde, 0x33, 0x48, 0xb3, 0xc1, 0x85, 0x6a,
|
||||||
0x28, 0xfe, 0x1d, 0xc1, 0x27, 0xa2, 0xff, 0xa8,
|
0x42, 0x9b, 0xf9, 0x7e, 0x7e, 0x31, 0xc2, 0xe5,
|
||||||
0xde, 0x33, 0x48, 0xb3, 0xc1, 0x85, 0x6a, 0x42,
|
0xbd, 0x66 ],
|
||||||
0x9b, 0xf9, 0x7e, 0x7e, 0x31, 0xc2, 0xe5, 0xbd,
|
gy: [ 0x00, 0x18, 0x39, 0x29, 0x6a, 0x78, 0x9a, 0x3b,
|
||||||
0x66])),
|
0xc0, 0x04, 0x5c, 0x8a, 0x5f, 0xb4, 0x2c, 0x7d,
|
||||||
Gy: SCN::from(UCN::from_bytes(&vec![
|
0x1b, 0xd9, 0x98, 0xf5, 0x44, 0x49, 0x57, 0x9b,
|
||||||
0x18, 0x39, 0x29, 0x6a, 0x78, 0x9a, 0x3b, 0xc0,
|
0x44, 0x68, 0x17, 0xaf, 0xbd, 0x17, 0x27, 0x3e,
|
||||||
0x04, 0x5c, 0x8a, 0x5f, 0xb4, 0x2c, 0x7d, 0x1b,
|
0x66, 0x2c, 0x97, 0xee, 0x72, 0x99, 0x5e, 0xf4,
|
||||||
0xd9, 0x98, 0xf5, 0x44, 0x49, 0x57, 0x9b, 0x44,
|
0x26, 0x40, 0xc5, 0x50, 0xb9, 0x01, 0x3f, 0xad,
|
||||||
0x68, 0x17, 0xaf, 0xbd, 0x17, 0x27, 0x3e, 0x66,
|
0x07, 0x61, 0x35, 0x3c, 0x70, 0x86, 0xa2, 0x72,
|
||||||
0x2c, 0x97, 0xee, 0x72, 0x99, 0x5e, 0xf4, 0x26,
|
0xc2, 0x40, 0x88, 0xbe, 0x94, 0x76, 0x9f, 0xd1,
|
||||||
0x40, 0xc5, 0x50, 0xb9, 0x01, 0x3f, 0xad, 0x07,
|
0x66, 0x50 ]
|
||||||
0x61, 0x35, 0x3c, 0x70, 0x86, 0xa2, 0x72, 0xc2,
|
};
|
||||||
0x40, 0x88, 0xbe, 0x94, 0x76, 0x9f, 0xd1, 0x66,
|
|
||||||
0x50]))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,86 +1,187 @@
|
|||||||
use cryptonum::{SCN,UCN};
|
use cryptonum::{SCN,UCN};
|
||||||
use dsa::rfc6979::*;
|
//use dsa::rfc6979::*;
|
||||||
use ecdsa::curves::EllipticCurve;
|
use ecdsa::curves::*;
|
||||||
use ecdsa::math::ECCPoint;
|
use ecdsa::point::ECPoint;
|
||||||
use ecdsa::private::ECDSAPrivate;
|
//use ecdsa::private::ECDSAPrivate;
|
||||||
use ecdsa::public::ECDSAPublic;
|
//use ecdsa::public::ECDSAPublic;
|
||||||
use sha1::Sha1;
|
//use sha1::Sha1;
|
||||||
use sha2::{Sha224,Sha256,Sha384,Sha512};
|
//use sha2::{Sha224,Sha256,Sha384,Sha512};
|
||||||
use testing::run_test;
|
use testing::run_test;
|
||||||
|
|
||||||
fn get_curve(cbytes: &[u8]) -> EllipticCurve {
|
fn get_curve(cbytes: &[u8]) -> &'static EllipticCurve {
|
||||||
match usize::from(UCN::from_bytes(cbytes)) {
|
match usize::from(UCN::from_bytes(cbytes)) {
|
||||||
0x192 => EllipticCurve::p192(),
|
0x192 => &NIST_P192,
|
||||||
0x224 => EllipticCurve::p224(),
|
0x224 => &NIST_P224,
|
||||||
0x256 => EllipticCurve::p256(),
|
0x256 => &NIST_P256,
|
||||||
0x384 => EllipticCurve::p384(),
|
0x384 => &NIST_P384,
|
||||||
0x521 => EllipticCurve::p521(),
|
0x521 => &NIST_P521,
|
||||||
_ => panic!("Unacceptable curve identifier")
|
x => panic!("Unacceptable curve identifier {}", x)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn verification_tests()
|
fn point_negate()
|
||||||
{
|
{
|
||||||
run_test("tests/ecdsa/signature.test", 8, |case| {
|
run_test("tests/ecdsa/ec_negate.test", 5, |case| {
|
||||||
let (neg0, cbytes) = case.get("c").unwrap();
|
let (neg0, abytes) = case.get("a").unwrap();
|
||||||
let (negx, xbytes) = case.get("x").unwrap();
|
let (neg1, bbytes) = case.get("b").unwrap();
|
||||||
let (negy, ybytes) = case.get("y").unwrap();
|
let (neg2, cbytes) = case.get("c").unwrap();
|
||||||
let (neg1, hbytes) = case.get("h").unwrap();
|
let (neg3, xbytes) = case.get("x").unwrap();
|
||||||
let (neg2, msg) = case.get("m").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 (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);
|
assert!(!neg0 && !neg1 && !neg2 && !neg3 && !neg4 && !neg5 && !neg6);
|
||||||
let curve = get_curve(cbytes);
|
let curve = get_curve(&cbytes);
|
||||||
let ux = UCN::from_bytes(xbytes);
|
let x = SCN::from(UCN::from_bytes(xbytes));
|
||||||
let uy = UCN::from_bytes(ybytes);
|
let y = SCN::from(UCN::from_bytes(ybytes));
|
||||||
let x = SCN{ negative: *negx, value: ux };
|
let p1 = ECPoint::new(curve, x, y);
|
||||||
let y = SCN{ negative: *negy, value: uy };
|
let q = SCN::from(UCN::from_bytes(qbytes));
|
||||||
let point = ECCPoint::new(&curve, x, y);
|
let r = SCN::from(UCN::from_bytes(rbytes));
|
||||||
let public = ECDSAPublic::new(&curve, &point);
|
let p2 = ECPoint::new(curve, q, r);
|
||||||
let r = UCN::from_bytes(rbytes);
|
let a = SCN::from(UCN::from_bytes(abytes));
|
||||||
let s = UCN::from_bytes(sbytes);
|
let b = SCN::from(UCN::from_bytes(bbytes));
|
||||||
println!("r: {:X}", r);
|
let result = ECPoint::new(curve, a, b);
|
||||||
let sig = DSASignature{ r: r, s: s };
|
assert_eq!(result, p1.add(&p2));
|
||||||
|
|
||||||
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]
|
#[test]
|
||||||
fn signing_tests()
|
fn point_scale()
|
||||||
{
|
{
|
||||||
run_test("tests/ecdsa/signature.test", 8, |case| {
|
run_test("tests/ecdsa/ec_mul.test", 6, |case| {
|
||||||
let (neg0, cbytes) = case.get("c").unwrap();
|
let (neg0, abytes) = case.get("a").unwrap();
|
||||||
let (neg1, dbytes) = case.get("d").unwrap();
|
let (neg1, bbytes) = case.get("b").unwrap();
|
||||||
let (neg2, hbytes) = case.get("h").unwrap();
|
let (neg2, kbytes) = case.get("k").unwrap();
|
||||||
let (neg3, msg) = case.get("m").unwrap();
|
let (neg3, cbytes) = case.get("c").unwrap();
|
||||||
let (neg4, rbytes) = case.get("r").unwrap();
|
let (neg4, xbytes) = case.get("x").unwrap();
|
||||||
let (neg5, sbytes) = case.get("s").unwrap();
|
let (neg5, ybytes) = case.get("y").unwrap();
|
||||||
|
|
||||||
assert!(!neg0 & !neg1 & !neg2 & !neg3 & !neg4 & !neg5);
|
assert!(!neg0 && !neg1 && !neg2 && !neg3 && !neg4 && !neg5);
|
||||||
let curve = get_curve(cbytes);
|
let curve = get_curve(&cbytes);
|
||||||
let d = UCN::from_bytes(dbytes);
|
let x = SCN::from(UCN::from_bytes(xbytes));
|
||||||
let private = ECDSAPrivate::new(&curve, &d);
|
let y = SCN::from(UCN::from_bytes(ybytes));
|
||||||
let r = UCN::from_bytes(rbytes);
|
let base = ECPoint::new(curve, x, y);
|
||||||
let s = UCN::from_bytes(sbytes);
|
let k = UCN::from_bytes(kbytes);
|
||||||
let sig = DSASignature{ r: r, s: s };
|
let a = SCN::from(UCN::from_bytes(abytes));
|
||||||
|
let b = SCN::from(UCN::from_bytes(bbytes));
|
||||||
match usize::from(UCN::from_bytes(hbytes)) {
|
let result = ECPoint::new(curve, a, b);
|
||||||
0x1 => assert_eq!(sig, private.sign::<Sha1>(msg)),
|
assert_eq!(result, base.scale(&k));
|
||||||
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)
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//#[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)
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
//}
|
||||||
|
|||||||
@@ -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 * λ
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
115
src/ecdsa/mod.rs
115
src/ecdsa/mod.rs
@@ -1,60 +1,61 @@
|
|||||||
mod curves;
|
mod curves;
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod gold_tests;
|
mod gold_tests;
|
||||||
mod math;
|
mod point;
|
||||||
mod private;
|
//mod private;
|
||||||
mod public;
|
//mod public;
|
||||||
|
//
|
||||||
pub use self::private::ECDSAPrivate;
|
//pub use self::private::ECDSAPrivate;
|
||||||
pub use self::public::ECDSAPublic;
|
//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 cryptonum::UCN;
|
||||||
use self::curves::EllipticCurve;
|
//use rand::{Rng,OsRng};
|
||||||
use self::math::ECCPoint;
|
//use self::curves::EllipticCurve;
|
||||||
|
//use self::math::ECCPoint;
|
||||||
#[derive(Clone,Debug,PartialEq)]
|
//
|
||||||
pub struct ECDSAKeyPair {
|
//#[derive(Clone,Debug,PartialEq)]
|
||||||
pub private: ECDSAPrivate,
|
//pub struct ECDSAKeyPair {
|
||||||
pub public: ECDSAPublic
|
// pub private: ECDSAPrivate,
|
||||||
}
|
// pub public: ECDSAPublic
|
||||||
|
//}
|
||||||
impl ECDSAKeyPair {
|
//
|
||||||
pub fn generate(params: &EllipticCurve)
|
//impl ECDSAKeyPair {
|
||||||
-> ECDSAKeyPair
|
// pub fn generate(params: &'static EllipticCurve)
|
||||||
{
|
// -> ECDSAKeyPair
|
||||||
let mut rng = OsRng::new().unwrap();
|
// {
|
||||||
ECDSAKeyPair::generate_w_rng(&mut rng, params)
|
// 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
|
// pub fn generate_w_rng<G: Rng>(rng: &mut G, params: &'static EllipticCurve)
|
||||||
{
|
// -> ECDSAKeyPair
|
||||||
let one = UCN::from(1u64);
|
// {
|
||||||
#[allow(non_snake_case)]
|
// let one = UCN::from(1u64);
|
||||||
let N = params.n.bits();
|
// #[allow(non_snake_case)]
|
||||||
let bits_to_generate = N + 64;
|
// let N = params.n.bits();
|
||||||
let bytes_to_generate = (bits_to_generate + 7) / 8;
|
// let bits_to_generate = N + 64;
|
||||||
let bits: Vec<u8> = rng.gen_iter().take(bytes_to_generate).collect();
|
// let bytes_to_generate = (bits_to_generate + 7) / 8;
|
||||||
let bits_generated = bytes_to_generate * 8;
|
// let bits: Vec<u8> = rng.gen_iter().take(bytes_to_generate).collect();
|
||||||
let mut c = UCN::from_bytes(&bits);
|
// let bits_generated = bytes_to_generate * 8;
|
||||||
c >>= bits_generated - bits_to_generate;
|
// let mut c = UCN::from_bytes(&bits);
|
||||||
let nm1 = ¶ms.n - &one;
|
// c >>= bits_generated - bits_to_generate;
|
||||||
let d = (c % &nm1) + &one;
|
// let nm1 = ¶ms.n - &one;
|
||||||
#[allow(non_snake_case)]
|
// let d = (c % &nm1) + &one;
|
||||||
let Q = ECCPoint::default(params).scale(&d);
|
// #[allow(non_snake_case)]
|
||||||
ECDSAKeyPair {
|
// let Q = ECCPoint::default(params).scale(&d);
|
||||||
private: ECDSAPrivate {
|
// ECDSAKeyPair {
|
||||||
curve: params.clone(),
|
// private: ECDSAPrivate {
|
||||||
d: d
|
// curve: params,
|
||||||
},
|
// d: d
|
||||||
public: ECDSAPublic {
|
// },
|
||||||
curve: params.clone(),
|
// public: ECDSAPublic {
|
||||||
Q: Q
|
// curve: params,
|
||||||
}
|
// Q: Q
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//
|
||||||
|
|||||||
227
src/ecdsa/point.rs
Normal file
227
src/ecdsa/point.rs
Normal 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 * λ
|
||||||
|
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);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
@@ -8,14 +8,16 @@ use hmac::Hmac;
|
|||||||
|
|
||||||
#[derive(Clone,Debug,PartialEq)]
|
#[derive(Clone,Debug,PartialEq)]
|
||||||
pub struct ECDSAPrivate {
|
pub struct ECDSAPrivate {
|
||||||
pub(crate) curve: EllipticCurve,
|
pub(crate) curve: &'static EllipticCurve,
|
||||||
pub(crate) d: UCN
|
pub(crate) d: UCN
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ECDSAPrivate {
|
impl ECDSAPrivate {
|
||||||
pub fn new(c: &EllipticCurve, d: &UCN) -> ECDSAPrivate {
|
pub fn new(c: &'static EllipticCurve, d: &UCN)
|
||||||
|
-> ECDSAPrivate
|
||||||
|
{
|
||||||
ECDSAPrivate {
|
ECDSAPrivate {
|
||||||
curve: c.clone(),
|
curve: c,
|
||||||
d: d.clone()
|
d: d.clone()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -64,10 +66,10 @@ impl ECDSAPrivate {
|
|||||||
//
|
//
|
||||||
// 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).
|
||||||
let g = ECCPoint::default(&self.curve);
|
let g = ECCPoint::default(self.curve);
|
||||||
let kg = g.scale(&k);
|
let kg = g.scale(&k);
|
||||||
let ni = SCN::from(self.curve.n.clone());
|
let ni = SCN::from(self.curve.n.clone());
|
||||||
let r = &kg.x % ∋
|
let r = &kg.get_x() % ∋
|
||||||
if r.is_zero() {
|
if r.is_zero() {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -77,7 +79,7 @@ impl ECDSAPrivate {
|
|||||||
//
|
//
|
||||||
// The pair (r, s) is the signature.
|
// The pair (r, s) is the signature.
|
||||||
let kinv = SCN::from(k.modinv(&ni.value));
|
let kinv = SCN::from(k.modinv(&ni.value));
|
||||||
let s = ((SCN::from(h.clone()) + (&kg.x * &r)) * &kinv) % ∋
|
let s = ((SCN::from(h.clone()) + (&kg.get_x() * &r)) * &kinv) % ∋
|
||||||
if s.is_zero() {
|
if s.is_zero() {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,14 +8,16 @@ use hmac::Hmac;
|
|||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
#[derive(Clone,Debug,PartialEq)]
|
#[derive(Clone,Debug,PartialEq)]
|
||||||
pub struct ECDSAPublic {
|
pub struct ECDSAPublic {
|
||||||
pub(crate) curve: EllipticCurve,
|
pub(crate) curve: &'static EllipticCurve,
|
||||||
pub(crate) Q: ECCPoint
|
pub(crate) Q: ECCPoint
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ECDSAPublic {
|
impl ECDSAPublic {
|
||||||
pub fn new(curve: &EllipticCurve, point: &ECCPoint) -> ECDSAPublic {
|
pub fn new(curve: &'static EllipticCurve, point: &ECCPoint)
|
||||||
|
-> ECDSAPublic
|
||||||
|
{
|
||||||
ECDSAPublic {
|
ECDSAPublic {
|
||||||
curve: curve.clone(),
|
curve: curve,
|
||||||
Q: point.clone()
|
Q: point.clone()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -49,11 +51,12 @@ impl ECDSAPublic {
|
|||||||
let u2 = (&sig.r * &c) % n;
|
let u2 = (&sig.r * &c) % n;
|
||||||
let x = point_add_two_muls(&u1, &ECCPoint::default(&self.curve),
|
let x = point_add_two_muls(&u1, &ECCPoint::default(&self.curve),
|
||||||
&u2, &self.Q);
|
&u2, &self.Q);
|
||||||
|
let xx = x.get_x();
|
||||||
|
|
||||||
if x.x.is_negative() {
|
if xx.is_negative() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
(x.x.value % n) == sig.r
|
(xx.value % n) == sig.r
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,10 @@ import java.lang.Math;
|
|||||||
import java.lang.Thread;
|
import java.lang.Thread;
|
||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
import java.security.SecureRandom;
|
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.nist.NISTNamedCurves;
|
||||||
import org.bouncycastle.asn1.x9.X9ECParameters;
|
import org.bouncycastle.asn1.x9.X9ECParameters;
|
||||||
import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
|
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.params.ECPublicKeyParameters;
|
||||||
import org.bouncycastle.crypto.signers.ECDSASigner;
|
import org.bouncycastle.crypto.signers.ECDSASigner;
|
||||||
import org.bouncycastle.crypto.signers.HMacDSAKCalculator;
|
import org.bouncycastle.crypto.signers.HMacDSAKCalculator;
|
||||||
|
import org.bouncycastle.math.ec.ECAlgorithms;
|
||||||
|
import org.bouncycastle.math.ec.ECPoint;
|
||||||
|
|
||||||
class Generator {
|
class Generator {
|
||||||
private FileWriter out;
|
final static int COUNT = 500;
|
||||||
private SecureRandom rng;
|
|
||||||
|
|
||||||
final static int NUM_THREADS = 4;
|
public static void main(String[] args)
|
||||||
|
|
||||||
public Generator(SecureRandom r, FileWriter o) {
|
|
||||||
rng = r;
|
|
||||||
out = o;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void runTests(String curveName, int count)
|
|
||||||
throws IOException, InterruptedException
|
throws IOException, InterruptedException
|
||||||
{
|
{
|
||||||
Thread threads[] = new Thread[NUM_THREADS];
|
new Generator().run();
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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) {
|
for(Thread thread: threads) {
|
||||||
thread.join();
|
thread.join();
|
||||||
}
|
}
|
||||||
System.out.println(" done.");
|
System.out.println(" done.");
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void output(AsymmetricCipherKeyPair kp,
|
public class OutFiles {
|
||||||
int digestsize,
|
public FileWriter negate;
|
||||||
byte[] message,
|
public FileWriter dble;
|
||||||
BigInteger[] rs)
|
public FileWriter add;
|
||||||
throws IOException
|
public FileWriter mul;
|
||||||
|
public FileWriter add2mul;
|
||||||
|
public FileWriter sig;
|
||||||
|
|
||||||
|
public OutFiles()
|
||||||
{
|
{
|
||||||
ECPublicKeyParameters pub = (ECPublicKeyParameters)kp.getPublic();
|
try {
|
||||||
ECPrivateKeyParameters priv = (ECPrivateKeyParameters)kp.getPrivate();
|
negate = new FileWriter("ec_negate.test", false);
|
||||||
out.write("c: " + pub.getParameters().getCurve().getFieldSize() + "\n");
|
dble = new FileWriter("ec_dble.test", false);
|
||||||
out.write("x: " + pub.getQ().getAffineXCoord().toBigInteger().toString(16) + "\n");
|
add = new FileWriter("ec_add.test", false);
|
||||||
out.write("y: " + pub.getQ().getAffineYCoord().toBigInteger().toString(16) + "\n");
|
mul = new FileWriter("ec_mul.test", false);
|
||||||
out.write("d: " + priv.getD().toString(16) + "\n");
|
add2mul = new FileWriter("ec_add2mul.test", false);
|
||||||
out.write("h: " + digestsize + "\n");
|
sig = new FileWriter("signature.test", false);
|
||||||
out.write("m: " + asHex(message) + "\n");
|
} catch(IOException e) {
|
||||||
out.write("r: " + rs[0].toString(16) + "\n");
|
System.out.println("Blech: " + e);
|
||||||
out.write("s: " + rs[1].toString(16) + "\n");
|
}
|
||||||
out.flush();
|
}
|
||||||
System.out.print(".");
|
|
||||||
|
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();
|
System.out.flush();
|
||||||
}
|
}
|
||||||
|
} catch(IOException e) {
|
||||||
private Digest appropriateDigest(int nsize)
|
System.out.println("Argh: " + e);
|
||||||
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!");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private int randomDigestSize()
|
public class Runner implements Runnable {
|
||||||
throws IOException
|
private OutFiles outfiles;
|
||||||
{
|
private SecureRandom rng;
|
||||||
switch(getRandomChoice(5)) {
|
private ECDomainParameters ecparams;
|
||||||
case 0: return 1;
|
private BigInteger two;
|
||||||
case 1: return 224;
|
|
||||||
case 2: return 256;
|
public Runner(OutFiles outfiles, ECDomainParameters params) {
|
||||||
case 3: return 384;
|
this.outfiles = outfiles;
|
||||||
case 4: return 512;
|
this.ecparams = params;
|
||||||
default:
|
this.rng = new SecureRandom();
|
||||||
throw new IOException("The world broke.");
|
this.two = BigInteger.valueOf(2);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private int getRandomChoice(int modulus) {
|
public void run() {
|
||||||
byte randoms[] = new byte[2];
|
for(int i = 0; i < COUNT; i++) { generateNegateTests(); }
|
||||||
rng.nextBytes(randoms);
|
for(int i = 0; i < COUNT; i++) { generateDoubleTests(); }
|
||||||
int random = ((int)randoms[0] << 8) + ((int)randoms[1]);
|
for(int i = 0; i < COUNT; i++) { generateAddTests(); }
|
||||||
return (Math.abs(random) % modulus);
|
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) {
|
public void generateNegateTests() {
|
||||||
String result = "";
|
ECPoint p = getPoint();
|
||||||
|
ECPoint n = p.negate().normalize();
|
||||||
|
HashMap<String,String> m = new HashMap<String,String>();
|
||||||
|
|
||||||
for(byte value : data) {
|
m.put("c", Integer.toString(ecparams.getN().bitLength()));
|
||||||
result = result + String.format("%02x", value);
|
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)
|
public void generateAddTests() {
|
||||||
throws IOException, InterruptedException
|
ECPoint p1 = getPoint();
|
||||||
{
|
ECPoint p2 = getPoint();
|
||||||
SecureRandom rng = new SecureRandom();
|
ECPoint q = p1.add(p2).normalize();
|
||||||
FileWriter outfile = new FileWriter("signature.test", false);
|
HashMap<String,String> m = new HashMap<String,String>();
|
||||||
Generator gen = new Generator(rng, outfile);
|
|
||||||
|
|
||||||
gen.runTests("P-192", 500);
|
m.put("c", Integer.toString(ecparams.getN().bitLength()));
|
||||||
gen.runTests("P-224", 500);
|
m.put("x", p1.getAffineXCoord().toBigInteger().toString(16));
|
||||||
gen.runTests("P-256", 500);
|
m.put("y", p1.getAffineYCoord().toBigInteger().toString(16));
|
||||||
gen.runTests("P-384", 500);
|
m.put("q", p2.getAffineXCoord().toBigInteger().toString(16));
|
||||||
gen.runTests("P-521", 500);
|
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 {
|
public void generateMulTests() {
|
||||||
private ECDomainParameters params;
|
ECPoint p = getPoint();
|
||||||
private int count;
|
BigInteger k = getConstant();
|
||||||
private Generator parent;
|
ECPoint q = p.multiply(k).normalize();
|
||||||
|
HashMap<String,String> m = new HashMap<String,String>();
|
||||||
|
|
||||||
public Runner(ECDomainParameters params, int count, Generator parent)
|
m.put("c", Integer.toString(ecparams.getN().bitLength()));
|
||||||
{
|
m.put("x", p.getAffineXCoord().toBigInteger().toString(16));
|
||||||
this.params = params;
|
m.put("y", p.getAffineYCoord().toBigInteger().toString(16));
|
||||||
this.count = count;
|
m.put("k", k.toString(16));
|
||||||
this.parent = parent;
|
m.put("a", q.getAffineXCoord().toBigInteger().toString(16));
|
||||||
|
m.put("b", q.getAffineYCoord().toBigInteger().toString(16));
|
||||||
|
outfiles.dump(outfiles.mul, m);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void run()
|
public void generateAdd2MulTests() {
|
||||||
{
|
ECPoint p = getPoint();
|
||||||
for(int i = 0; i < count; i++) {
|
BigInteger a = getConstant();
|
||||||
runTest();
|
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()
|
public void generateSignatureTests() {
|
||||||
{
|
AsymmetricCipherKeyPair kp = getKeyPair();
|
||||||
ECKeyGenerationParameters params =
|
ECPublicKeyParameters pub = (ECPublicKeyParameters)kp.getPublic();
|
||||||
new ECKeyGenerationParameters(this.params, this.parent.rng);
|
ECPrivateKeyParameters priv = (ECPrivateKeyParameters)kp.getPrivate();
|
||||||
ECKeyPairGenerator keygen = new ECKeyPairGenerator();
|
byte message[] = getMessage();
|
||||||
keygen.init(params);
|
int digestsize = getDigestSize();
|
||||||
return keygen.generateKeyPair();
|
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()
|
private byte[] runHash(byte[] msg, int size) {
|
||||||
{
|
Digest digestfn = getHash(size);
|
||||||
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);
|
|
||||||
digestfn.update(msg, 0, msg.length);
|
digestfn.update(msg, 0, msg.length);
|
||||||
byte result[] = new byte[digestfn.getDigestSize()];
|
byte result[] = new byte[digestfn.getDigestSize()];
|
||||||
digestfn.doFinal(result, 0);
|
digestfn.doFinal(result, 0);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void runTest()
|
private AsymmetricCipherKeyPair getKeyPair() {
|
||||||
{
|
ECKeyGenerationParameters params =
|
||||||
try {
|
new ECKeyGenerationParameters(ecparams, rng);
|
||||||
AsymmetricCipherKeyPair kp = getKeyPair();
|
ECKeyPairGenerator keygen = new ECKeyPairGenerator();
|
||||||
ECPublicKeyParameters pub = (ECPublicKeyParameters)kp.getPublic();
|
keygen.init(params);
|
||||||
ECPrivateKeyParameters priv = (ECPrivateKeyParameters)kp.getPrivate();
|
return keygen.generateKeyPair();
|
||||||
|
}
|
||||||
|
|
||||||
byte message[] = getMessage();
|
private byte[] getMessage() {
|
||||||
int digestsize = randomDigestSize();
|
int msgsize = rng.nextInt(1024);
|
||||||
byte hash[] = runHash(message, digestsize);
|
byte message[] = new byte[msgsize];
|
||||||
|
rng.nextBytes(message);
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
Digest msgdigest = appropriateDigest(digestsize);
|
private ECPoint getPoint() {
|
||||||
HMacDSAKCalculator kgen = new HMacDSAKCalculator(msgdigest);
|
BigInteger k = getConstant();
|
||||||
ECDSASigner signer = new ECDSASigner(kgen);
|
return ecparams.getG().multiply(k).normalize();
|
||||||
signer.init(true, priv);
|
}
|
||||||
BigInteger rs[] = signer.generateSignature(hash);
|
|
||||||
parent.output(kp, digestsize, message, rs);
|
private BigInteger getConstant() {
|
||||||
} catch(IOException exc) {
|
BigInteger n = ecparams.getN();
|
||||||
System.out.println("EXCEPTION!");
|
int nBitLength = n.bitLength();
|
||||||
run();
|
|
||||||
|
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
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
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
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
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
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
Reference in New Issue
Block a user