diff --git a/src/constants.rs b/src/constants.rs index 112d060..6072293 100644 --- a/src/constants.rs +++ b/src/constants.rs @@ -23,6 +23,7 @@ use field::FieldElement; use curve::ExtendedPoint; use curve::AffineNielsPoint; use curve::CompressedEdwardsY; +use curve::BasepointTable; use scalar::Scalar; pub const d: FieldElement = FieldElement([ @@ -100,7 +101,7 @@ pub const BASE_CMPRSSD: CompressedEdwardsY = 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66]); /// Basepoint has y = 4/5. -pub const BASEPOINT: ExtendedPoint = ExtendedPoint{ +pub const ED25519_BASEPOINT: ExtendedPoint = ExtendedPoint{ X: FieldElement([-14297830, -7645148, 16144683, -16471763, 27570974, -2696100, -26142465, 8378389, 20764389, 8758491]), Y: FieldElement([-26843541, -6710886, 13421773, -13421773, 26843546, 6710886, -13421773, 13421773, -26843546, -6710886]), Z: FieldElement([1, 0, 0, 0, 0, 0, 0, 0, 0, 0]), @@ -225,7 +226,7 @@ pub const bi: [AffineNielsPoint; 8] = [ /// /// The table is defined so `constants::base[i][j-1] = j*(16^2i)*B`, /// for `0 ≤ i < 32`, `1 ≤ j < 9`. -pub const base: [[AffineNielsPoint; 8]; 32] = [ +pub const ED25519_BASEPOINT_TABLE: BasepointTable = BasepointTable([ [ AffineNielsPoint{ y_plus_x: FieldElement([25967493, -14356035, 29566456, 3660896, -12694345, 4014787, 27544626, -11754271, -6079156, 2047605]), @@ -1569,7 +1570,7 @@ pub const base: [[AffineNielsPoint; 8]; 32] = [ y_minus_x: FieldElement([29701166, -14373934, -10878120, 9279288, -17568, 13127210, 21382910, 11042292, 25838796, 4642684]), xy2d: FieldElement([-20430234, 14955537, -24126347, 8124619, -5369288, -5990470, 30468147, -13900640, 18423289, 4177476]), }, -]]; +]]); #[cfg(test)] mod test { @@ -1670,23 +1671,4 @@ mod test { let a_minus_d = &a - &constants::d; assert_eq!(a_minus_d, constants::a_minus_d); } - - /// Test the values in the lookup table of precomputed multiples - /// of the basepoint. - #[test] - fn test_precomputed_basepoint_multiples() { - let bp = constants::BASE_CMPRSSD.decompress().unwrap(); - let mut P = bp; - for i in 0..32 { - // P = (16^2)^i * B - let mut jP = P.to_affine_niels(); - for j in 1..9 { - // constants::base[i][j-1] is supposed to be - // j * (16^2)^i * B - assert_eq!(constants::base[i][j-1], jP); - jP = (&P + &jP).to_extended().to_affine_niels(); - } - P = P.mult_by_pow_2(8); - } - } } diff --git a/src/curve.rs b/src/curve.rs index 11a37a8..804d180 100644 --- a/src/curve.rs +++ b/src/curve.rs @@ -912,52 +912,11 @@ pub trait BasepointMult { impl BasepointMult for ExtendedPoint { fn basepoint() -> ExtendedPoint { - constants::BASEPOINT + constants::ED25519_BASEPOINT } - /// Construct an `ExtendedPoint` from a `Scalar`, `scalar`, by - /// computing the multiple `aB` of the basepoint `B`. - /// - /// Precondition: the scalar must be reduced. - /// - /// The computation proceeds as follows, as described on page 13 - /// of the Ed25519 paper. Write the scalar `a` in radix 16 with - /// coefficients in [-8,8), i.e., - /// - /// a = a_0 + a_1*16^1 + ... + a_63*16^63, - /// - /// with -8 ≤ a_i < 8. Then - /// - /// a*B = a_0*B + a_1*16^1*B + ... + a_63*16^63*B. - /// - /// Grouping even and odd coefficients gives - /// - /// a*B = a_0*16^0*B + a_2*16^2*B + ... + a_62*16^62*B - /// + a_1*16^1*B + a_3*16^3*B + ... + a_63*16^63*B - /// = (a_0*16^0*B + a_2*16^2*B + ... + a_62*16^62*B) - /// + 16*(a_1*16^0*B + a_3*16^2*B + ... + a_63*16^62*B). - /// - /// We then use the `select_precomputed_point` function, which - /// takes `-8 ≤ x < 8` and `[16^2i * B, ..., 8 * 16^2i * B]`, - /// and returns `x * 16^2i * B` in constant time. - fn basepoint_mult(scalar: &Scalar) -> ExtendedPoint { //GeScalarMultBase - let e = scalar.to_radix_16(); - let mut h = ExtendedPoint::identity(); - let mut t: CompletedPoint; - - for i in (0..64).filter(|x| x % 2 == 1) { - t = &h + &select_precomputed_point(e[i], &constants::base[i/2]); - h = t.to_extended(); - } - - h = h.mult_by_pow_2(4); - - for i in (0..64).filter(|x| x % 2 == 0) { - t = &h + &select_precomputed_point(e[i], &constants::base[i/2]); - h = t.to_extended(); - } - - h + fn basepoint_mult(scalar: &Scalar) -> ExtendedPoint { + constants::ED25519_BASEPOINT_TABLE.basepoint_mult(scalar) } } @@ -1222,7 +1181,7 @@ mod test { /// Test Montgomery conversion against the X25519 basepoint. #[test] fn basepoint_to_montgomery() { - assert_eq!(constants::BASEPOINT.compress_montgomery().unwrap(), + assert_eq!(constants::ED25519_BASEPOINT.compress_montgomery().unwrap(), BASE_CMPRSSD_MONTY); } @@ -1275,10 +1234,10 @@ mod test { .decompress().unwrap(); // Test projective coordinates exactly since we know they should // only differ by a flipped sign. - assert_eq!(minus_basepoint.X, -(&constants::BASEPOINT.X)); - assert_eq!(minus_basepoint.Y, constants::BASEPOINT.Y); - assert_eq!(minus_basepoint.Z, constants::BASEPOINT.Z); - assert_eq!(minus_basepoint.T, -(&constants::BASEPOINT.T)); + assert_eq!(minus_basepoint.X, -(&constants::ED25519_BASEPOINT.X)); + assert_eq!(minus_basepoint.Y, constants::ED25519_BASEPOINT.Y); + assert_eq!(minus_basepoint.Z, constants::ED25519_BASEPOINT.Z); + assert_eq!(minus_basepoint.T, -(&constants::ED25519_BASEPOINT.T)); } /// Test that computing 1*basepoint gives the correct basepoint. @@ -1293,7 +1252,7 @@ mod test { /// using basepoint + basepoint versus the 2*basepoint constant. #[test] fn basepoint_plus_basepoint_vs_basepoint2() { - let bp = constants::BASEPOINT; + let bp = constants::ED25519_BASEPOINT; let bp_added = &bp + &bp; assert_eq!(bp_added.compress_edwards(), BASE2_CMPRSSD); } @@ -1302,7 +1261,7 @@ mod test { /// using the basepoint, basepoint2 constants #[test] fn basepoint_plus_basepoint_projective_niels_vs_basepoint2() { - let bp = constants::BASEPOINT; + let bp = constants::ED25519_BASEPOINT; let bp_added = (&bp + &bp.to_projective_niels()).to_extended(); assert_eq!(bp_added.compress_edwards(), BASE2_CMPRSSD); } @@ -1311,7 +1270,7 @@ mod test { /// using the basepoint, basepoint2 constants #[test] fn basepoint_plus_basepoint_affine_niels_vs_basepoint2() { - let bp = constants::BASEPOINT; + let bp = constants::ED25519_BASEPOINT; let bp_affine_niels = bp.to_affine_niels(); let bp_added = (&bp + &bp_affine_niels).to_extended(); assert_eq!(bp_added.compress_edwards(), BASE2_CMPRSSD); @@ -1360,16 +1319,17 @@ mod test { /// Test precomputed basepoint mult #[test] fn test_precomputed_basepoint_mult() { - let table = BasepointTable::create(&constants::BASEPOINT); + let table = BasepointTable::create(&constants::ED25519_BASEPOINT); let aB_1 = ExtendedPoint::basepoint_mult(&A_SCALAR); let aB_2 = table.basepoint_mult(&A_SCALAR); - assert_eq!(aB_1.compress(), aB_2.compress()); + assert_eq!(aB_1.compress_edwards(), + aB_2.compress_edwards()); } /// Test scalar_mult versus a known scalar multiple from ed25519.py #[test] fn scalar_mult_vs_ed25519py() { - let aB = constants::BASEPOINT.scalar_mult(&A_SCALAR); + let aB = constants::ED25519_BASEPOINT.scalar_mult(&A_SCALAR); assert_eq!(aB.compress_edwards(), A_TIMES_BASEPOINT); } @@ -1384,7 +1344,7 @@ mod test { /// Test basepoint.double() versus the 2*basepoint constant. #[test] fn basepoint_double_vs_basepoint2() { - assert_eq!(constants::BASEPOINT.double().compress_edwards(), + assert_eq!(constants::ED25519_BASEPOINT.double().compress_edwards(), BASE2_CMPRSSD); } @@ -1399,14 +1359,15 @@ mod test { /// Check that converting to projective and then back to extended round-trips. #[test] fn basepoint_projective_extended_round_trip() { - assert_eq!(constants::BASEPOINT.to_projective().to_extended().compress_edwards(), + assert_eq!(constants::ED25519_BASEPOINT + .to_projective().to_extended().compress_edwards(), constants::BASE_CMPRSSD); } /// Test computing 16*basepoint vs mult_by_pow_2(4) #[test] fn basepoint16_vs_mult_by_pow_2_4() { - let bp16 = constants::BASEPOINT.mult_by_pow_2(4); + let bp16 = constants::ED25519_BASEPOINT.mult_by_pow_2(4); assert_eq!(bp16.compress_edwards(), BASE16_CMPRSSD); } @@ -1415,7 +1376,7 @@ mod test { fn conditional_assign_for_affine_niels_point() { let id = AffineNielsPoint::identity(); let mut p1 = AffineNielsPoint::identity(); - let bp = constants::BASEPOINT.to_affine_niels(); + let bp = constants::ED25519_BASEPOINT.to_affine_niels(); p1.conditional_assign(&bp, 0); assert_eq!(p1, id); @@ -1426,7 +1387,7 @@ mod test { #[test] fn is_small_order() { // The basepoint has large prime order - assert!(constants::BASEPOINT.is_small_order() == false); + assert!(constants::ED25519_BASEPOINT.is_small_order() == false); // constants::EIGHT_TORSION has all points of small order. for torsion_point in &constants::EIGHT_TORSION { assert!(torsion_point.is_small_order() == true); @@ -1441,8 +1402,8 @@ mod test { #[test] fn is_identity() { - assert!(ExtendedPoint::identity().is_identity() == true); - assert!( constants::BASEPOINT.is_identity() == false); + assert!( ExtendedPoint::identity().is_identity() == true); + assert!(constants::ED25519_BASEPOINT.is_identity() == false); } } @@ -1464,13 +1425,13 @@ mod bench { #[bench] fn scalar_mult(b: &mut Bencher) { - let bp = constants::BASEPOINT; + let bp = constants::ED25519_BASEPOINT; b.iter(|| bp.scalar_mult(&A_SCALAR)); } #[bench] fn bench_select_precomputed_point(b: &mut Bencher) { - b.iter(|| select_precomputed_point(0, &constants::base[12])); + b.iter(|| select_precomputed_point(0, &constants::ED25519_BASEPOINT_TABLE.0[0])); } #[bench] @@ -1481,53 +1442,53 @@ mod bench { #[bench] fn add_extended_and_cached_output_completed(b: &mut Bencher) { - let p1 = constants::BASEPOINT; - let p2 = constants::BASEPOINT.to_projective_niels(); + let p1 = constants::ED25519_BASEPOINT; + let p2 = constants::ED25519_BASEPOINT.to_projective_niels(); b.iter(|| &p1 + &p2); } #[bench] fn add_extended_and_cached_output_extended(b: &mut Bencher) { - let p1 = constants::BASEPOINT; - let p2 = constants::BASEPOINT.to_projective_niels(); + let p1 = constants::ED25519_BASEPOINT; + let p2 = constants::ED25519_BASEPOINT.to_projective_niels(); b.iter(|| (&p1 + &p2).to_extended()); } #[bench] fn add_extended_and_precomputed_output_completed(b: &mut Bencher) { - let p1 = constants::BASEPOINT; - let p2 = select_precomputed_point(6, &constants::base[27]); + let p1 = constants::ED25519_BASEPOINT; + let p2 = constants::ED25519_BASEPOINT.to_affine_niels(); b.iter(|| &p1 + &p2); } #[bench] fn add_extended_and_precomputed_output_extended(b: &mut Bencher) { - let p1 = constants::BASEPOINT; - let p2 = select_precomputed_point(6, &constants::base[27]); + let p1 = constants::ED25519_BASEPOINT; + let p2 = constants::ED25519_BASEPOINT.to_affine_niels(); b.iter(|| (&p1 + &p2).to_extended()); } #[bench] fn projective_double_output_completed(b: &mut Bencher) { - let p1 = constants::BASEPOINT.to_projective(); + let p1 = constants::ED25519_BASEPOINT.to_projective(); b.iter(|| p1.double() ); } #[bench] fn extended_double_output_extended(b: &mut Bencher) { - let p1 = constants::BASEPOINT; + let p1 = constants::ED25519_BASEPOINT; b.iter(|| p1.double() ); } #[bench] fn mult_by_cofactor(b: &mut Bencher) { - let p1 = constants::BASEPOINT; + let p1 = constants::ED25519_BASEPOINT; b.iter(|| p1.mult_by_cofactor() ); }