From bcdf30a5f379b5443986ba564e04b45db9212409 Mon Sep 17 00:00:00 2001 From: Vincent Hanquez Date: Mon, 9 Sep 2024 11:33:28 +0800 Subject: [PATCH] elligator --- src/curve25519/fe/fe64/mod.rs | 32 +++++ src/curve25519/fe/mod.rs | 57 ++++++++ src/curve25519/ge.rs | 142 ++++++++++++++++++- src/ed25519.rs | 247 +++++++++++++++++++++++++++++++++- src/lib.rs | 2 +- 5 files changed, 475 insertions(+), 5 deletions(-) diff --git a/src/curve25519/fe/fe64/mod.rs b/src/curve25519/fe/fe64/mod.rs index 03ddbf0..697bef2 100644 --- a/src/curve25519/fe/fe64/mod.rs +++ b/src/curve25519/fe/fe64/mod.rs @@ -51,6 +51,15 @@ impl Fe { 0x2B8324804FC1D, ]); + /// Field element constant for -1. + pub(crate) const M1: Fe = Fe([ + 2251799813685228, + 2251799813685247, + 2251799813685247, + 2251799813685247, + 2251799813685247, + ]); + /// Field element constant for D pub const D: Fe = Fe([ 0x34DCA135978A3, @@ -68,6 +77,18 @@ impl Fe { 0x6738CC7407977, 0x2406D9DC56DFF, ]); + + /// Field element for Montgomery curve value 486662 + pub(crate) const MONTGOMERY_A: Fe = Fe([486662, 0, 0, 0, 0]); + + /// Field element for Montgomery curve value -486662 + pub(crate) const MONTGOMERY_A_NEG: Fe = Fe([ + 2251799813198567, + 2251799813685247, + 2251799813685247, + 2251799813685247, + 2251799813685247, + ]); } #[inline] @@ -394,6 +415,11 @@ impl Fe { CtEqual::ct_ne(&self.to_bytes(), &[0; 32]).into() } + /// Check that the field element is 'negative' + pub fn is_negative_ct(&self) -> Choice { + (self.to_packed()[0] & 1).ct_ne(0) + } + /// Check that the field element is 'negative' pub fn is_negative(&self) -> bool { (self.to_packed()[0] & 1) != 0 @@ -406,6 +432,12 @@ impl Fe { pub(crate) fn maybe_set(&mut self, rhs: &Fe, do_swap: Choice) { ct_array64_maybe_set(&mut self.0, &rhs.0, do_swap); } + + pub(crate) fn choice(self, other: Self, choice: Choice) -> Self { + let mut ret = self.0.clone(); + ct_array64_maybe_set(&mut ret, &other.0, choice); + Self(ret) + } } #[cfg(test)] diff --git a/src/curve25519/fe/mod.rs b/src/curve25519/fe/mod.rs index eeadc6c..1ac07f2 100644 --- a/src/curve25519/fe/mod.rs +++ b/src/curve25519/fe/mod.rs @@ -24,7 +24,37 @@ pub use fe32::*; #[cfg(not(any(any(target_arch = "arm"), feature = "force-32bits")))] pub use fe64::*; +use crate::constant_time::{Choice, CtEqual}; + impl Fe { + /// Raise a field element to (p-5) / 8 = 2^252-3 + pub fn pow_252_3(&self) -> Fe { + let z1 = self; + let z2 = z1.square(); + let z8 = z2.square_repeatdly(2); + let z9 = z1 * &z8; + let z11 = &z2 * &z9; + let z22 = z11.square(); + let z_5_0 = &z9 * &z22; + let z_10_5 = z_5_0.square_repeatdly(5); + let z_10_0 = &z_10_5 * &z_5_0; + let z_20_10 = z_10_0.square_repeatdly(10); + let z_20_0 = &z_20_10 * &z_10_0; + let z_40_20 = z_20_0.square_repeatdly(20); + let z_40_0 = &z_40_20 * &z_20_0; + let z_50_10 = z_40_0.square_repeatdly(10); + let z_50_0 = &z_50_10 * &z_10_0; + let z_100_50 = z_50_0.square_repeatdly(50); + let z_100_0 = &z_100_50 * &z_50_0; + let z_200_100 = z_100_0.square_repeatdly(100); + let z_200_0 = &z_200_100 * &z_100_0; + let z_250_50 = z_200_0.square_repeatdly(50); + let z_250_0 = &z_250_50 * &z_50_0; + let z_250_2 = z_250_0.square_repeatdly(2); + let z_252_0 = &z_250_2 * &z1; + z_252_0 + } + /// Raise a field element to 2^255-23 pub fn pow25523(&self) -> Fe { let z2 = self.square(); @@ -83,6 +113,33 @@ impl Fe { z_255_21 } + + pub(crate) fn sqrt_ratio_i(u: &Self, v: &Self) -> (Choice, Fe) { + let v3 = &v.square() * &v; + let v7 = &v3.square() * &v; + let mut r = &(u * &v3) * &(u * &v7).pow_252_3(); + let check = v * &r.square(); + + let i = &Fe::SQRTM1; + + let correct_sign_sqrt = check.ct_eq(u); + let flipped_sign_sqrt = check.ct_eq(&(-u)); + let flipped_sign_sqrt_i = check.ct_eq(&(&(-u) * i)); + + let r_prime = &Fe::SQRTM1 * &r; + Fe::maybe_set(&mut r, &r_prime, flipped_sign_sqrt | flipped_sign_sqrt_i); + + // Choose the nonnegative square root. + let r_is_negative = r.is_negative_ct(); + let mut r_neg = r.clone(); + r_neg.negate_mut(); + + Fe::maybe_set(&mut r, &r_neg, r_is_negative); + + let was_nonzero_square = correct_sign_sqrt | flipped_sign_sqrt; + + (was_nonzero_square, r) + } } #[cfg(test)] diff --git a/src/curve25519/ge.rs b/src/curve25519/ge.rs index 18139f5..cc06cc6 100644 --- a/src/curve25519/ge.rs +++ b/src/curve25519/ge.rs @@ -68,7 +68,46 @@ impl GeAffine { } pub fn from_bytes(s: &[u8; 32]) -> Option { - // See RFC8032 5.3.1 decoding process + // See RFC8032 5.1.3 decoding process + // + // y (255 bits) | sign(x) (1 bit) = s + // let u = y^2 - 1 + // v = d * y^2 + 1 + // x = u * v^3 * (u * v^7)^((p-5)/8) + + // recover x_sign from the bytes by reading the 255 bits + let x_0 = s[31] >> 7; + // recover y by clearing the highest bit (side effect of from_bytes) + let y = Fe::from_bytes(s); + + // recover x + let y2 = y.square(); + let u = &y2 - &Fe::ONE; + let v = &(&y2 * &Fe::D) + &Fe::ONE; + + let (is_valid_y_coord, mut x) = Fe::sqrt_ratio_i(&u, &v); + + if is_valid_y_coord.is_false() { + return None; + } + + let sign_bit = x_0.ct_eq(1); + + let mut x_neg = x.clone(); + x_neg.negate_mut(); + + x.maybe_set(&x_neg, sign_bit); + + let Self { x: x2, y: y2 } = Self::from_bytes2(s).unwrap(); + + //assert_eq!(y.to_bytes(), y2.to_bytes(), "y mismatch"); + //assert_eq!(x.to_bytes(), x2.to_bytes(), "x mismatch"); + + Some(Self { x: x2, y: y2 }) + } + + pub fn from_bytes2(s: &[u8; 32]) -> Option { + // See RFC8032 5.1.3 decoding process // // y (255 bits) | sign(x) (1 bit) = s // let u = y^2 - 1 @@ -374,6 +413,84 @@ impl Ge { h } + + fn mul_cofactor(self) -> Self { + let mut r: Self; + let mut s = self.to_partial(); + for _ in 0..2 { + r = s.double_full(); + s = r.to_partial(); + } + s.double_full() + } + + fn from_raw_hash(hash: &[u8; 32]) -> Option { + let fe = Fe::from_bytes(hash); + std::println!("fe {:x?}", fe.to_bytes()); + let m1 = elligator_encode(&fe); + std::println!("m1 {:x?}", m1.0); + let e = m1.to_edwards(0); + std::println!("e: {:x?}", e.clone().map(|x| x.to_bytes())); + e.map(|p| p.mul_cofactor()) + } + + pub fn from_hash [u8; 64]>(bytes: &[u8], hash: H) -> Option { + use core::convert::TryFrom; + let h = hash(bytes); + let h32 = <&[u8; 32]>::try_from(&h[0..32]).unwrap(); + Self::from_raw_hash(h32) + } +} + +pub struct MontgomeryPoint([u8; 32]); + +impl MontgomeryPoint { + fn to_edwards(&self, sign: u8) -> Option { + let u = Fe::from_bytes(&self.0); + if u == Fe::M1 { + return None; + } + let y = &(&u - &Fe::ONE) * &(&u + &Fe::ONE).invert(); + + let mut y_bytes = y.to_bytes(); + println!("y_bytes[31] {:b}", &y_bytes[31]); + y_bytes[31] ^= sign << 7; + println!("y_bytes[31] {:b}", &y_bytes[31]); + println!("y_bytes {:x?}", &y_bytes); + + Ge::from_bytes(&y_bytes) + } +} + +/// Get the Elligator2 mapping to a MontgomeryPoint +/// +/// +fn elligator_encode(r_0: &Fe) -> MontgomeryPoint { + let r_0_sq = r_0.square(); + let r_0_sq_2 = &r_0_sq + &r_0_sq; + let d_1 = &Fe::ONE + &r_0_sq_2; + + let d = &Fe::MONTGOMERY_A_NEG * &(d_1.invert()); /* A/(1+2r^2) */ + std::println!("d {:x?}", d.to_bytes()); + + let d_sq = &d.square(); + let au = &Fe::MONTGOMERY_A * &d; + + let inner = &(d_sq + &au) + &Fe::ONE; + let eps = &d * &inner; /* eps = d^3 + Ad^2 + d */ + + std::println!("eps {:x?}", eps.to_bytes()); + + let (eps_is_sq, _eps) = Fe::sqrt_ratio_i(&eps, &Fe::ONE); + + let a_or_zero = Fe::choice(Fe::MONTGOMERY_A, Fe::ZERO, eps_is_sq); /* 0, or A if nonsquare*/ + let mut u = &d + &a_or_zero; + let mut u_neg = u.clone(); + u_neg.negate_mut(); + + Fe::maybe_set(&mut u, &u_neg, eps_is_sq.negate()); /* d, or -d-A if nonsquare */ + + MontgomeryPoint(u.to_bytes()) } impl Add<&GeCached> for &Ge { @@ -530,3 +647,26 @@ impl GePrecomp { t } } + +#[cfg(test)] +mod tests { + use super::Ge; + use crate::hashing::sha512; + + #[test] + fn elligator() { + let input = [ + 0x21, 0x4f, 0x30, 0x6e, 0x15, 0x76, 0xf5, 0xa7, 0x57, 0x76, 0x36, 0xfe, 0x30, 0x3c, + 0xa2, 0xc6, 0x25, 0xb5, 0x33, 0x31, 0x9f, 0x52, 0x44, 0x2b, 0x22, 0xa9, 0xfa, 0x3b, + 0x7e, 0xde, 0x80, 0x9f, + ]; + let output = [ + 0xc9, 0x5b, 0xec, 0xf0, 0xf9, 0x35, 0x95, 0x17, 0x46, 0x33, 0xb9, 0xd4, 0xd6, 0xbb, + 0xbe, 0xb8, 0x8e, 0x16, 0xfa, 0x25, 0x71, 0x76, 0xf8, 0x77, 0xce, 0x42, 0x6e, 0x14, + 0x24, 0x62, 0x60, 0xd2, + ]; + let point = Ge::from_hash(&input, |v| sha512(v)).unwrap(); + let output_got = point.to_bytes(); + assert_eq!(output, output_got); + } +} diff --git a/src/ed25519.rs b/src/ed25519.rs index 78b34ff..e021c7b 100644 --- a/src/ed25519.rs +++ b/src/ed25519.rs @@ -200,11 +200,13 @@ pub fn verify( return false; } }; + println!("verify ge {:x?}", a.to_bytes()); let signature_scalar = match Scalar::from_bytes_canonical(signature_right) { None => return false, Some(s) => s, }; + println!("signature scal {:x?}", signature_scalar.to_bytes()); // reject all-0 public keys let mut d = 0; @@ -334,11 +336,24 @@ mod tests { assert_eq!(edx_ss, cv_ss); } - fn do_sign_verify_case(seed: [u8; 32], message: &[u8], expected_signature: [u8; 64]) { + fn do_sign_verify_case( + seed: [u8; 32], + expected_public: [u8; 32], + message: &[u8], + expected_signature: [u8; 64], + ) { let (secret_key, public_key) = keypair(&seed); let mut actual_signature = signature(message, &secret_key); - assert_eq!(expected_signature.to_vec(), actual_signature.to_vec()); - assert!(verify(message, &public_key, &actual_signature)); + assert_eq!(&expected_public, &public_key, "public key mismatch"); + assert_eq!( + expected_signature.to_vec(), + actual_signature.to_vec(), + "signature mismatch" + ); + assert!( + verify(message, &public_key, &actual_signature), + "verify of signature failed" + ); for &(index, flip) in [(0, 1), (31, 0x80), (20, 0xff)].iter() { actual_signature[index] ^= flip; @@ -351,8 +366,233 @@ mod tests { assert!(!verify(message, &public_key_corrupt, &actual_signature,)); } + pub struct TestVector { + id: usize, + secret: [u8; 32], + public: [u8; 32], + msg: &'static [u8], + signature: [u8; 64], + } + + const TEST_VECTORS: &[TestVector] = &[ + TestVector { + id: 1, + secret: [ + 0x9d, 0x61, 0xb1, 0x9d, 0xef, 0xfd, 0x5a, 0x60, 0xba, 0x84, 0x4a, 0xf4, 0x92, 0xec, + 0x2c, 0xc4, 0x44, 0x49, 0xc5, 0x69, 0x7b, 0x32, 0x69, 0x19, 0x70, 0x3b, 0xac, 0x03, + 0x1c, 0xae, 0x7f, 0x60, + ], + public: [ + 0xd7, 0x5a, 0x98, 0x01, 0x82, 0xb1, 0x0a, 0xb7, 0xd5, 0x4b, 0xfe, 0xd3, 0xc9, 0x64, + 0x07, 0x3a, 0x0e, 0xe1, 0x72, 0xf3, 0xda, 0xa6, 0x23, 0x25, 0xaf, 0x02, 0x1a, 0x68, + 0xf7, 0x07, 0x51, 0x1a, + ], + msg: &[], + signature: [ + 0xe5, 0x56, 0x43, 0x00, 0xc3, 0x60, 0xac, 0x72, 0x90, 0x86, 0xe2, 0xcc, 0x80, 0x6e, + 0x82, 0x8a, 0x84, 0x87, 0x7f, 0x1e, 0xb8, 0xe5, 0xd9, 0x74, 0xd8, 0x73, 0xe0, 0x65, + 0x22, 0x49, 0x01, 0x55, 0x5f, 0xb8, 0x82, 0x15, 0x90, 0xa3, 0x3b, 0xac, 0xc6, 0x1e, + 0x39, 0x70, 0x1c, 0xf9, 0xb4, 0x6b, 0xd2, 0x5b, 0xf5, 0xf0, 0x59, 0x5b, 0xbe, 0x24, + 0x65, 0x51, 0x41, 0x43, 0x8e, 0x7a, 0x10, 0x0b, + ], + }, + TestVector { + id: 2, + secret: [ + 0x4c, 0xcd, 0x08, 0x9b, 0x28, 0xff, 0x96, 0xda, 0x9d, 0xb6, 0xc3, 0x46, 0xec, 0x11, + 0x4e, 0x0f, 0x5b, 0x8a, 0x31, 0x9f, 0x35, 0xab, 0xa6, 0x24, 0xda, 0x8c, 0xf6, 0xed, + 0x4f, 0xb8, 0xa6, 0xfb, + ], + public: [ + 0x3d, 0x40, 0x17, 0xc3, 0xe8, 0x43, 0x89, 0x5a, 0x92, 0xb7, 0x0a, 0xa7, 0x4d, 0x1b, + 0x7e, 0xbc, 0x9c, 0x98, 0x2c, 0xcf, 0x2e, 0xc4, 0x96, 0x8c, 0xc0, 0xcd, 0x55, 0xf1, + 0x2a, 0xf4, 0x66, 0x0c, + ], + msg: &[0x72], + signature: [ + 0x92, 0xa0, 0x09, 0xa9, 0xf0, 0xd4, 0xca, 0xb8, 0x72, 0x0e, 0x82, 0x0b, 0x5f, 0x64, + 0x25, 0x40, 0xa2, 0xb2, 0x7b, 0x54, 0x16, 0x50, 0x3f, 0x8f, 0xb3, 0x76, 0x22, 0x23, + 0xeb, 0xdb, 0x69, 0xda, 0x08, 0x5a, 0xc1, 0xe4, 0x3e, 0x15, 0x99, 0x6e, 0x45, 0x8f, + 0x36, 0x13, 0xd0, 0xf1, 0x1d, 0x8c, 0x38, 0x7b, 0x2e, 0xae, 0xb4, 0x30, 0x2a, 0xee, + 0xb0, 0x0d, 0x29, 0x16, 0x12, 0xbb, 0x0c, 0x00, + ], + }, + TestVector { + id: 3, + secret: [ + 0xc5, 0xaa, 0x8d, 0xf4, 0x3f, 0x9f, 0x83, 0x7b, 0xed, 0xb7, 0x44, 0x2f, 0x31, 0xdc, + 0xb7, 0xb1, 0x66, 0xd3, 0x85, 0x35, 0x07, 0x6f, 0x09, 0x4b, 0x85, 0xce, 0x3a, 0x2e, + 0x0b, 0x44, 0x58, 0xf7, + ], + public: [ + 0xfc, 0x51, 0xcd, 0x8e, 0x62, 0x18, 0xa1, 0xa3, 0x8d, 0xa4, 0x7e, 0xd0, 0x02, 0x30, + 0xf0, 0x58, 0x08, 0x16, 0xed, 0x13, 0xba, 0x33, 0x03, 0xac, 0x5d, 0xeb, 0x91, 0x15, + 0x48, 0x90, 0x80, 0x25, + ], + msg: &[0xaf, 0x82], + signature: [ + 0x62, 0x91, 0xd6, 0x57, 0xde, 0xec, 0x24, 0x02, 0x48, 0x27, 0xe6, 0x9c, 0x3a, 0xbe, + 0x01, 0xa3, 0x0c, 0xe5, 0x48, 0xa2, 0x84, 0x74, 0x3a, 0x44, 0x5e, 0x36, 0x80, 0xd7, + 0xdb, 0x5a, 0xc3, 0xac, 0x18, 0xff, 0x9b, 0x53, 0x8d, 0x16, 0xf2, 0x90, 0xae, 0x67, + 0xf7, 0x60, 0x98, 0x4d, 0xc6, 0x59, 0x4a, 0x7c, 0x15, 0xe9, 0x71, 0x6e, 0xd2, 0x8d, + 0xc0, 0x27, 0xbe, 0xce, 0xea, 0x1e, 0xc4, 0x0a, + ], + }, + TestVector { + id: 4, + secret: [ + 0x0d, 0x4a, 0x05, 0xb0, 0x73, 0x52, 0xa5, 0x43, 0x6e, 0x18, 0x03, 0x56, 0xda, 0x0a, + 0xe6, 0xef, 0xa0, 0x34, 0x5f, 0xf7, 0xfb, 0x15, 0x72, 0x57, 0x57, 0x72, 0xe8, 0x00, + 0x5e, 0xd9, 0x78, 0xe9, + ], + public: [ + 0xe6, 0x1a, 0x18, 0x5b, 0xce, 0xf2, 0x61, 0x3a, 0x6c, 0x7c, 0xb7, 0x97, 0x63, 0xce, + 0x94, 0x5d, 0x3b, 0x24, 0x5d, 0x76, 0x11, 0x4d, 0xd4, 0x40, 0xbc, 0xf5, 0xf2, 0xdc, + 0x1a, 0xa5, 0x70, 0x57, + ], + msg: &[0xcb, 0xc7, 0x7b], + signature: [ + 0xd9, 0x86, 0x8d, 0x52, 0xc2, 0xbe, 0xbc, 0xe5, 0xf3, 0xfa, 0x5a, 0x79, 0x89, 0x19, + 0x70, 0xf3, 0x09, 0xcb, 0x65, 0x91, 0xe3, 0xe1, 0x70, 0x2a, 0x70, 0x27, 0x6f, 0xa9, + 0x7c, 0x24, 0xb3, 0xa8, 0xe5, 0x86, 0x06, 0xc3, 0x8c, 0x97, 0x58, 0x52, 0x9d, 0xa5, + 0x0e, 0xe3, 0x1b, 0x82, 0x19, 0xcb, 0xa4, 0x52, 0x71, 0xc6, 0x89, 0xaf, 0xa6, 0x0b, + 0x0e, 0xa2, 0x6c, 0x99, 0xdb, 0x19, 0xb0, 0x0c, + ], + }, + TestVector { + id: 5, + secret: [ + 0x6d, 0xf9, 0x34, 0x0c, 0x13, 0x8c, 0xc1, 0x88, 0xb5, 0xfe, 0x44, 0x64, 0xeb, 0xaa, + 0x3f, 0x7f, 0xc2, 0x06, 0xa2, 0xd5, 0x5c, 0x34, 0x34, 0x70, 0x7e, 0x74, 0xc9, 0xfc, + 0x04, 0xe2, 0x0e, 0xbb, + ], + public: [ + 0xc0, 0xda, 0xc1, 0x02, 0xc4, 0x53, 0x31, 0x86, 0xe2, 0x5d, 0xc4, 0x31, 0x28, 0x47, + 0x23, 0x53, 0xea, 0xab, 0xdb, 0x87, 0x8b, 0x15, 0x2a, 0xeb, 0x8e, 0x00, 0x1f, 0x92, + 0xd9, 0x02, 0x33, 0xa7, + ], + msg: &[0x5f, 0x4c, 0x89, 0x89], + signature: [ + 0x12, 0x4f, 0x6f, 0xc6, 0xb0, 0xd1, 0x00, 0x84, 0x27, 0x69, 0xe7, 0x1b, 0xd5, 0x30, + 0x66, 0x4d, 0x88, 0x8d, 0xf8, 0x50, 0x7d, 0xf6, 0xc5, 0x6d, 0xed, 0xfd, 0xb5, 0x09, + 0xae, 0xb9, 0x34, 0x16, 0xe2, 0x6b, 0x91, 0x8d, 0x38, 0xaa, 0x06, 0x30, 0x5d, 0xf3, + 0x09, 0x56, 0x97, 0xc1, 0x8b, 0x2a, 0xa8, 0x32, 0xea, 0xa5, 0x2e, 0xdc, 0x0a, 0xe4, + 0x9f, 0xba, 0xe5, 0xa8, 0x5e, 0x15, 0x0c, 0x07, + ], + }, + TestVector { + id: 6, + secret: [ + 0xb7, 0x80, 0x38, 0x1a, 0x65, 0xed, 0xf8, 0xb7, 0x8f, 0x69, 0x45, 0xe8, 0xdb, 0xec, + 0x79, 0x41, 0xac, 0x04, 0x9f, 0xd4, 0xc6, 0x10, 0x40, 0xcf, 0x0c, 0x32, 0x43, 0x57, + 0x97, 0x5a, 0x29, 0x3c, + ], + public: [ + 0xe2, 0x53, 0xaf, 0x07, 0x66, 0x80, 0x4b, 0x86, 0x9b, 0xb1, 0x59, 0x5b, 0xe9, 0x76, + 0x5b, 0x53, 0x48, 0x86, 0xbb, 0xaa, 0xb8, 0x30, 0x5b, 0xf5, 0x0d, 0xbc, 0x7f, 0x89, + 0x9b, 0xfb, 0x5f, 0x01, + ], + msg: &[0x18, 0xb6, 0xbe, 0xc0, 0x97], + signature: [ + 0xb2, 0xfc, 0x46, 0xad, 0x47, 0xaf, 0x46, 0x44, 0x78, 0xc1, 0x99, 0xe1, 0xf8, 0xbe, + 0x16, 0x9f, 0x1b, 0xe6, 0x32, 0x7c, 0x7f, 0x9a, 0x0a, 0x66, 0x89, 0x37, 0x1c, 0xa9, + 0x4c, 0xaf, 0x04, 0x06, 0x4a, 0x01, 0xb2, 0x2a, 0xff, 0x15, 0x20, 0xab, 0xd5, 0x89, + 0x51, 0x34, 0x16, 0x03, 0xfa, 0xed, 0x76, 0x8c, 0xf7, 0x8c, 0xe9, 0x7a, 0xe7, 0xb0, + 0x38, 0xab, 0xfe, 0x45, 0x6a, 0xa1, 0x7c, 0x09, + ], + }, + TestVector { + id: 7, + secret: [ + 0x78, 0xae, 0x9e, 0xff, 0xe6, 0xf2, 0x45, 0xe9, 0x24, 0xa7, 0xbe, 0x63, 0x04, 0x11, + 0x46, 0xeb, 0xc6, 0x70, 0xdb, 0xd3, 0x06, 0x0c, 0xba, 0x67, 0xfb, 0xc6, 0x21, 0x6f, + 0xeb, 0xc4, 0x45, 0x46, + ], + public: [ + 0xfb, 0xcf, 0xbf, 0xa4, 0x05, 0x05, 0xd7, 0xf2, 0xbe, 0x44, 0x4a, 0x33, 0xd1, 0x85, + 0xcc, 0x54, 0xe1, 0x6d, 0x61, 0x52, 0x60, 0xe1, 0x64, 0x0b, 0x2b, 0x50, 0x87, 0xb8, + 0x3e, 0xe3, 0x64, 0x3d, + ], + msg: &[0x89, 0x01, 0x0d, 0x85, 0x59, 0x72], + signature: [ + 0x6e, 0xd6, 0x29, 0xfc, 0x1d, 0x9c, 0xe9, 0xe1, 0x46, 0x87, 0x55, 0xff, 0x63, 0x6d, + 0x5a, 0x3f, 0x40, 0xa5, 0xd9, 0xc9, 0x1a, 0xfd, 0x93, 0xb7, 0x9d, 0x24, 0x18, 0x30, + 0xf7, 0xe5, 0xfa, 0x29, 0x85, 0x4b, 0x8f, 0x20, 0xcc, 0x6e, 0xec, 0xbb, 0x24, 0x8d, + 0xbd, 0x8d, 0x16, 0xd1, 0x4e, 0x99, 0x75, 0x21, 0x94, 0xe4, 0x90, 0x4d, 0x09, 0xc7, + 0x4d, 0x63, 0x95, 0x18, 0x83, 0x9d, 0x23, 0x00, + ], + }, + TestVector { + id: 8, + secret: [ + 0x69, 0x18, 0x65, 0xbf, 0xc8, 0x2a, 0x1e, 0x4b, 0x57, 0x4e, 0xec, 0xde, 0x4c, 0x75, + 0x19, 0x09, 0x3f, 0xaf, 0x0c, 0xf8, 0x67, 0x38, 0x02, 0x34, 0xe3, 0x66, 0x46, 0x45, + 0xc6, 0x1c, 0x5f, 0x79, + ], + public: [ + 0x98, 0xa5, 0xe3, 0xa3, 0x6e, 0x67, 0xaa, 0xba, 0x89, 0x88, 0x8b, 0xf0, 0x93, 0xde, + 0x1a, 0xd9, 0x63, 0xe7, 0x74, 0x01, 0x3b, 0x39, 0x02, 0xbf, 0xab, 0x35, 0x6d, 0x8b, + 0x90, 0x17, 0x8a, 0x63, + ], + msg: &[0xb4, 0xa8, 0xf3, 0x81, 0xe7, 0x0e, 0x7a], + signature: [ + 0x6e, 0x0a, 0xf2, 0xfe, 0x55, 0xae, 0x37, 0x7a, 0x6b, 0x7a, 0x72, 0x78, 0xed, 0xfb, + 0x41, 0x9b, 0xd3, 0x21, 0xe0, 0x6d, 0x0d, 0xf5, 0xe2, 0x70, 0x37, 0xdb, 0x88, 0x12, + 0xe7, 0xe3, 0x52, 0x98, 0x10, 0xfa, 0x55, 0x52, 0xf6, 0xc0, 0x02, 0x09, 0x85, 0xca, + 0x17, 0xa0, 0xe0, 0x2e, 0x03, 0x6d, 0x7b, 0x22, 0x2a, 0x24, 0xf9, 0x9b, 0x77, 0xb7, + 0x5f, 0xdd, 0x16, 0xcb, 0x05, 0x56, 0x81, 0x07, + ], + }, + TestVector { + id: 9, + secret: [ + 0x3b, 0x26, 0x51, 0x6f, 0xb3, 0xdc, 0x88, 0xeb, 0x18, 0x1b, 0x9e, 0xd7, 0x3f, 0x0b, + 0xcd, 0x52, 0xbc, 0xd6, 0xb4, 0xc7, 0x88, 0xe4, 0xbc, 0xaf, 0x46, 0x05, 0x7f, 0xd0, + 0x78, 0xbe, 0xe0, 0x73, + ], + public: [ + 0xf8, 0x1f, 0xb5, 0x4a, 0x82, 0x5f, 0xce, 0xd9, 0x5e, 0xb0, 0x33, 0xaf, 0xcd, 0x64, + 0x31, 0x40, 0x75, 0xab, 0xfb, 0x0a, 0xbd, 0x20, 0xa9, 0x70, 0x89, 0x25, 0x03, 0x43, + 0x6f, 0x34, 0xb8, 0x63, + ], + msg: &[0x42, 0x84, 0xab, 0xc5, 0x1b, 0xb6, 0x72, 0x35], + signature: [ + 0xd6, 0xad, 0xde, 0xc5, 0xaf, 0xb0, 0x52, 0x8a, 0xc1, 0x7b, 0xb1, 0x78, 0xd3, 0xe7, + 0xf2, 0x88, 0x7f, 0x9a, 0xdb, 0xb1, 0xad, 0x16, 0xe1, 0x10, 0x54, 0x5e, 0xf3, 0xbc, + 0x57, 0xf9, 0xde, 0x23, 0x14, 0xa5, 0xc8, 0x38, 0x8f, 0x72, 0x3b, 0x89, 0x07, 0xbe, + 0x0f, 0x3a, 0xc9, 0x0c, 0x62, 0x59, 0xbb, 0xe8, 0x85, 0xec, 0xc1, 0x76, 0x45, 0xdf, + 0x3d, 0xb7, 0xd4, 0x88, 0xf8, 0x05, 0xfa, 0x08, + ], + }, + TestVector { + id: 10, + secret: [ + 0xed, 0xc6, 0xf5, 0xfb, 0xdd, 0x1c, 0xee, 0x4d, 0x10, 0x1c, 0x06, 0x35, 0x30, 0xa3, + 0x04, 0x90, 0xb2, 0x21, 0xbe, 0x68, 0xc0, 0x36, 0xf5, 0xb0, 0x7d, 0x0f, 0x95, 0x3b, + 0x74, 0x5d, 0xf1, 0x92, + ], + public: [ + 0xc1, 0xa4, 0x9c, 0x66, 0xe6, 0x17, 0xf9, 0xef, 0x5e, 0xc6, 0x6b, 0xc4, 0xc6, 0x56, + 0x4c, 0xa3, 0x3d, 0xe2, 0xa5, 0xfb, 0x5e, 0x14, 0x64, 0x06, 0x2e, 0x6d, 0x6c, 0x62, + 0x19, 0x15, 0x5e, 0xfd, + ], + msg: &[0x67, 0x2b, 0xf8, 0x96, 0x5d, 0x04, 0xbc, 0x51, 0x46], + signature: [ + 0x2c, 0x76, 0xa0, 0x4a, 0xf2, 0x39, 0x1c, 0x14, 0x70, 0x82, 0xe3, 0x3f, 0xaa, 0xcd, + 0xbe, 0x56, 0x64, 0x2a, 0x1e, 0x13, 0x4b, 0xd3, 0x88, 0x62, 0x0b, 0x85, 0x2b, 0x90, + 0x1a, 0x6b, 0xc1, 0x6f, 0xf6, 0xc9, 0xcc, 0x94, 0x04, 0xc4, 0x1d, 0xea, 0x12, 0xed, + 0x28, 0x1d, 0xa0, 0x67, 0xa1, 0x51, 0x38, 0x66, 0xf9, 0xd9, 0x64, 0xf8, 0xbd, 0xd2, + 0x49, 0x53, 0x85, 0x6c, 0x50, 0x04, 0x29, 0x01, + ], + }, + ]; + #[test] fn sign_verify_cases() { + for vec in TEST_VECTORS { + do_sign_verify_case(vec.secret, vec.public, vec.msg, vec.signature) + } + /* do_sign_verify_case( [ 0x2d, 0x20, 0x86, 0x83, 0x2c, 0xc2, 0xfe, 0x3f, 0xd1, 0x8c, 0xb5, 0x1d, 0x6c, 0x5e, @@ -407,5 +647,6 @@ mod tests { 0x64, 0x10, 0x16, 0xf7, 0xa9, 0x0b, 0xe2, 0x0c, ], ); + */ } } diff --git a/src/lib.rs b/src/lib.rs index 78868dd..5a533ef 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -44,7 +44,7 @@ extern crate test; #[cfg(not(feature = "std"))] extern crate alloc; -#[cfg(test)] +// #[cfg(test)] #[macro_use] extern crate std;