diff --git a/src/constants.rs b/src/constants.rs index 487d557..1913b8a 100644 --- a/src/constants.rs +++ b/src/constants.rs @@ -3141,14 +3141,26 @@ mod test { #[test] fn test_half() { - let one = FieldElement([1,0,0,0,0,0,0,0,0,0]); - let two = FieldElement([2,0,0,0,0,0,0,0,0,0]); + let one = FieldElement::one(); + let two = &one + &one; assert_eq!(one, &two * &constants::HALF); } - #[test] /// Test that the constant for sqrt(-486664) really is a square /// root of -486664. + #[test] + #[cfg(feature="radix_51")] + fn sqrt_minus_aplus2() { + let minus_aplus2 = -&FieldElement([486664,0,0,0,0]); + let sqrt = constants::SQRT_MINUS_APLUS2; + let sq = &sqrt * &sqrt; + assert_eq!(sq, minus_aplus2); + } + + /// Test that the constant for sqrt(-486664) really is a square + /// root of -486664. + #[test] + #[cfg(feature="radix_25_5")] fn sqrt_minus_aplus2() { let minus_aplus2 = FieldElement([-486664,0,0,0,0,0,0,0,0,0]); let sqrt = constants::SQRT_MINUS_APLUS2; @@ -3159,7 +3171,7 @@ mod test { #[test] /// Test that SQRT_M1 and MSQRT_M1 are square roots of -1 fn test_sqrt_minus_one() { - let minus_one = FieldElement([-1,0,0,0,0,0,0,0,0,0]); + let minus_one = FieldElement::minus_one(); let sqrt_m1_sq = &constants::SQRT_M1 * &constants::SQRT_M1; let msqrt_m1_sq = &constants::MSQRT_M1 * &constants::MSQRT_M1; assert_eq!(minus_one, sqrt_m1_sq); @@ -3168,8 +3180,8 @@ mod test { #[test] fn test_sqrt_constants_sign() { - let one = FieldElement([ 1,0,0,0,0,0,0,0,0,0]); - let minus_one = FieldElement([-1,0,0,0,0,0,0,0,0,0]); + let one = FieldElement::one(); + let minus_one = FieldElement::minus_one(); let (was_nonzero_square, invsqrt_m1) = minus_one.invsqrt(); assert_eq!(was_nonzero_square, 1u8); let sign_test_sqrt = &invsqrt_m1 * &constants::SQRT_M1; @@ -3180,8 +3192,9 @@ mod test { assert_eq!(sign_test_msqrt, one); } - #[test] /// Test that d = -121665/121666 + #[cfg(feature="radix_25_5")] + #[test] fn test_d_vs_ratio() { let a = FieldElement([-121665,0,0,0,0,0,0,0,0,0]); let b = FieldElement([ 121666,0,0,0,0,0,0,0,0,0]); @@ -3191,6 +3204,18 @@ mod test { assert_eq!(d2, constants::d2); } + /// Test that d = -121665/121666 + #[cfg(feature="radix_51")] + #[test] + fn test_d_vs_ratio() { + let a = -&FieldElement([121665,0,0,0,0]); + let b = FieldElement([121666,0,0,0,0]); + let d = &a * &b.invert(); + let d2 = &d + &d; + assert_eq!(d, constants::d); + assert_eq!(d2, constants::d2); + } + #[test] fn test_d4() { let mut four = FieldElement::zero(); @@ -3200,7 +3225,7 @@ mod test { #[test] fn test_a_minus_d() { - let a = FieldElement([-1,0,0,0,0,0,0,0,0,0]); + let a = FieldElement::minus_one(); let a_minus_d = &a - &constants::d; assert_eq!(a_minus_d, constants::a_minus_d); } diff --git a/src/curve.rs b/src/curve.rs index 054b164..6bb964a 100644 --- a/src/curve.rs +++ b/src/curve.rs @@ -1192,10 +1192,9 @@ mod test { /// XXX what does Signal do here? #[test] fn u_minus_one_monty() { - let mut m1 = FieldElement::zero(); - m1[0] = -1; - let m1_bytes = m1.to_bytes(); - let div_by_zero_u = CompressedMontgomeryU(m1_bytes); + let minus_one = FieldElement::minus_one(); + let minus_one_bytes = minus_one.to_bytes(); + let div_by_zero_u = CompressedMontgomeryU(minus_one_bytes); assert!(div_by_zero_u.decompress().is_none()); } diff --git a/src/field.rs b/src/field.rs index 166d604..8bd65ed 100644 --- a/src/field.rs +++ b/src/field.rs @@ -267,12 +267,20 @@ impl CTAssignable for FieldElement { /// # Preconditions /// /// * `choice` in {0,1} + #[cfg(feature="radix_25_5")] fn conditional_assign(&mut self, f: &FieldElement, choice: u8) { let mask = -(choice as Limb); for i in 0..10 { self[i] ^= mask & (self[i] ^ f[i]); } } + #[cfg(feature="radix_51")] + fn conditional_assign(&mut self, f: &FieldElement, choice: u8) { + let mask = (-(choice as i64)) as u64; + for i in 0..5 { + self.0[i] ^= mask & (self.0[i] ^ f.0[i]); + } + } } impl FieldElement { @@ -283,6 +291,7 @@ impl FieldElement { self[i] = -self[i]; } } + /// Invert the sign of this field element #[cfg(feature="radix_51")] pub fn negate(&mut self) { // XXX how many copies of p @@ -293,21 +302,23 @@ impl FieldElement { self.0[4] = constants::p.0[4] - self.0[4]; } - /// Construct the additive identity + /// Construct zero. #[cfg(feature="radix_25_5")] pub fn zero() -> FieldElement { FieldElement([ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]) } + /// Construct zero. #[cfg(feature="radix_51")] pub fn zero() -> FieldElement { FieldElement([ 0, 0, 0, 0, 0 ]) } - /// Construct the multiplicative identity + /// Construct one. #[cfg(feature="radix_25_5")] pub fn one() -> FieldElement { FieldElement([ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]) } + /// Construct one. #[cfg(feature="radix_51")] pub fn one() -> FieldElement { FieldElement([ 1, 0, 0, 0, 0 ]) @@ -318,6 +329,7 @@ impl FieldElement { pub fn minus_one() -> FieldElement { FieldElement([-1, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]) } + /// Construct -1. #[cfg(feature="radix_51")] pub fn minus_one() -> FieldElement { FieldElement([2251799813685228, 2251799813685247, 2251799813685247, 2251799813685247, 2251799813685247]) @@ -452,6 +464,7 @@ impl FieldElement { FieldElement::reduce(&h) } + /// Parse a `FieldElement` from 32 bytes. #[cfg(feature="radix_51")] pub fn from_bytes(bytes: &[u8;32]) -> FieldElement { let low_51_bit_mask = (1u64 << 51) - 1; @@ -616,6 +629,7 @@ impl FieldElement { s } + /// Serialize this `FieldElement` to bytes. #[cfg(feature="radix_51")] pub fn to_bytes(&self) -> [u8;32] { // XXX need to do reduction first @@ -835,6 +849,7 @@ impl FieldElement { FieldElement::reduce(&[h0, h1, h2, h3, h4, h5, h6, h7, h8, h9]) } + /// Compute `self * _rhs`. #[cfg(feature="radix_51")] pub fn multiply(&self, _rhs: &FieldElement) -> FieldElement { unimplemented!(); @@ -900,6 +915,7 @@ impl FieldElement { pub fn square(&self) -> FieldElement { FieldElement::reduce(&self.square_inner()) } + /// Compute `self^2`. #[cfg(feature="radix_51")] pub fn square(&self) -> FieldElement { unimplemented!(); @@ -929,6 +945,7 @@ impl FieldElement { } FieldElement::reduce(&coeffs) } + /// Compute `2 * self^2`. #[cfg(feature="radix_51")] pub fn square2(&self) -> FieldElement { unimplemented!(); @@ -1148,6 +1165,7 @@ mod test { use field::*; use subtle::CTNegatable; + /* #[test] fn print_constants() { use curve::*; @@ -1215,8 +1233,9 @@ mod test { } } - panic!(); + //panic!(); } + */ /// Random element a of GF(2^255-19), from Sage /// a = 1070314506888354081329385823235218444233221\ @@ -1263,6 +1282,7 @@ mod test { assert_eq!(asq, asq_constant_from_sage); } + /* #[test] fn from_bytes_64_on_a() { let a: [u64;5] = [838547684720132, 293808819440897, 1085520638549020, 231251532116217, 416286470530165]; @@ -1271,6 +1291,7 @@ mod test { let should_be_a_bytes = to_bytes_64(&a); assert_eq!(&A_BYTES, &should_be_a_bytes); } + */ #[test] fn a_square_vs_a_squared_constant() {