diff --git a/src/constants.rs b/src/constants.rs index bfc103d..04aa289 100644 --- a/src/constants.rs +++ b/src/constants.rs @@ -26,15 +26,19 @@ use curve::CompressedEdwardsY; use curve::EdwardsBasepointTable; use scalar::Scalar; +#[cfg(feature="radix_25_5")] pub const d: FieldElement = FieldElement([ -10913610, 13857413, -15372611, 6949391, 114729, -8787816, -6275908, -3247719, -18696448, -12055116, ]); +#[cfg(feature="radix_25_5")] pub const d2: FieldElement = FieldElement([ -21827239, -5839606, -30745221, 13898782, 229458, 15978800, -12551817, -6495438, 29715968, 9444199, ]); +#[cfg(feature="radix_25_5")] pub const d4: FieldElement = FieldElement([ 23454405, -11679213, 5618422, -5756869, 458917, -1596832, -25103633, -12990876, -7676928, -14666033 ]); +#[cfg(feature="radix_25_5")] pub const a_minus_d: FieldElement = FieldElement([ 10913609, -13857413, 15372611, -6949391, -114729, 8787816, 6275908, 3247719, 18696448, 12055116, ]); @@ -47,21 +51,25 @@ pub const HALF_P_MINUS_1_BYTES: [u8; 32] = 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f]; /// Precomputed value of one of the square roots of -1 (mod p) +#[cfg(feature="radix_25_5")] pub const SQRT_M1: FieldElement = FieldElement([ -32595792, -7943725, 9377950, 3500415, 12389472, -272473, -25146209, -2005654, 326686, 11406482, ]); /// Precomputed value of the other square root of -1 (mod p), /// i.e., MSQRT_M1 = -SQRT_M1. +#[cfg(feature="radix_25_5")] pub const MSQRT_M1: FieldElement = FieldElement([ 32595792, 7943725, -9377950, -3500415, -12389472, 272473, 25146209, 2005654, -326686, -11406482, ]); /// Precomputed value of 1/2 (mod p). +#[cfg(feature="radix_25_5")] pub const HALF: FieldElement = FieldElement([ 10, 0, 0, 0, 0, 0, 0, 0, 0, -16777216, ]); /// In Montgomery form y² = x³+Ax²+x, Curve25519 has A=486662. +#[cfg(feature="radix_25_5")] pub const A: FieldElement = FieldElement([ 486662, 0, 0, 0, 0, 0, 0, 0, 0, 0, ]); @@ -69,21 +77,25 @@ pub const A: FieldElement = FieldElement([ // XXX I think that this was used in Adam's code for his elligator // implementation, but that should maybe be using sqrt(-486664) // instead...? - hdevalence +#[cfg(feature="radix_25_5")] pub const SQRT_MINUS_A: FieldElement = FieldElement([ // sqrtMinusA 12222970, 8312128, 11511410, -9067497, 15300785, 241793, -25456130, -14121551, 12187136, -3972024, ]); /// SQRT_MINUS_APLUS2 is sqrt(-486664) +#[cfg(feature="radix_25_5")] pub const SQRT_MINUS_APLUS2: FieldElement = FieldElement([ -12222970, -8312128, -11511410, 9067497, -15300785, -241793, 25456130, 14121551, -12187136, 3972024]); /// SQRT_MINUS_HALF is sqrt(-1/2) +#[cfg(feature="radix_25_5")] pub const SQRT_MINUS_HALF: FieldElement = FieldElement([ // sqrtMinusHalf -17256545, 3971863, 28865457, -1750208, 27359696, -16640980, 12573105, 1002827, -163343, 11073975, ]); /// HALF_Q_MINUS_1_BYTES is (2^255-20)/2 expressed in little endian form. +#[cfg(feature="radix_25_5")] pub const HALF_Q_MINUS_1_BYTES: [u8; 32] = [ // halfQMinus1Bytes 0xf6, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, @@ -101,6 +113,7 @@ pub const BASE_CMPRSSD: CompressedEdwardsY = 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66]); /// Basepoint has y = 4/5. +#[cfg(feature="radix_25_5")] 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]), @@ -128,6 +141,7 @@ pub const lminus1: Scalar = Scalar([ 0xec, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0 /// /// Thus Ɛ[4] is the points indexed by 0,2,4,6 and Ɛ[2] is the points /// indexed by 0,4. +#[cfg(feature="radix_25_5")] pub const EIGHT_TORSION: [ExtendedPoint; 8] = [ ExtendedPoint{ X: FieldElement([0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), @@ -179,6 +193,7 @@ pub const EIGHT_TORSION: [ExtendedPoint; 8] = [ }, ]; +#[cfg(feature="radix_25_5")] pub const bi: [AffineNielsPoint; 8] = [ AffineNielsPoint{ y_plus_x: FieldElement([25967493, -14356035, 29566456, 3660896, -12694345, 4014787, 27544626, -11754271, -6079156, 2047605]), @@ -226,6 +241,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`. +#[cfg(feature="radix_25_5")] pub const ED25519_BASEPOINT_TABLE: EdwardsBasepointTable = EdwardsBasepointTable([ [ AffineNielsPoint{ diff --git a/src/field.rs b/src/field.rs index e9baaaa..f5511a1 100644 --- a/src/field.rs +++ b/src/field.rs @@ -747,6 +747,7 @@ impl FieldElement { FieldElement::combine_coeffs(&[h0, h1, h2, h3, h4, h5, h6, h7, h8, h9]) } + #[cfg(feature="radix_25_5")] fn square_inner(&self) -> [i64;10] { let f0 = self[0] as i64; let f1 = self[1] as i64; @@ -789,6 +790,8 @@ impl FieldElement { /// Calculates h = f*f. Can overlap h with f. /// + /// XXX limbs: better to talk about headroom? + /// /// # Preconditions /// /// * |f[i]| bounded by 1.1*2^26, 1.1*2^25, 1.1*2^26, 1.1*2^25, etc. @@ -796,12 +799,15 @@ impl FieldElement { /// # Postconditions /// /// * |h[i]| bounded by 1.1*2^25, 1.1*2^24, 1.1*2^25, 1.1*2^24, etc. + #[cfg(feature="radix_25_5")] pub fn square(&self) -> FieldElement { FieldElement::combine_coeffs(&self.square_inner()) } /// Square this field element and multiply the result by 2. /// + /// XXX explain why square2 exists vs square (overflow) + /// /// # Preconditions /// /// * |f[i]| bounded by 1.65*2^26, 1.65*2^25, 1.65*2^26, 1.65*2^25, etc. @@ -814,9 +820,10 @@ impl FieldElement { /// /// See fe_mul.c in ref10 implementation for discussion of implementation /// strategy. + #[cfg(feature="radix_25_5")] pub fn square2(&self) -> FieldElement { let mut coeffs = self.square_inner(); - for i in 0..10 { + for i in 0..self.0.len() { coeffs[i] += coeffs[i]; } FieldElement::combine_coeffs(&coeffs) @@ -1138,10 +1145,6 @@ mod test { 8, 208, 170, 251, 97, 127, 70, 210, 58, 23, 166, 87, 240, 169, 184, 178]; - static B_LIMBS_RADIX_25_5: FieldElement = FieldElement( - [-5652623, 8034020, 8266223, -13556020, -5672552, - -5582839, -12603138, 15161929, -16418207, 13296296]); - #[test] fn from_bytes_highbit_is_ignored() { let mut cleared_bytes = B_BYTES.clone(); @@ -1151,6 +1154,12 @@ mod test { assert_eq!(without_highbit_set, with_highbit_set); } + #[cfg(feature="radix_25_5")] + static B_LIMBS_RADIX_25_5: FieldElement = FieldElement( + [-5652623, 8034020, 8266223, -13556020, -5672552, + -5582839, -12603138, 15161929, -16418207, 13296296]); + + #[cfg(feature="radix_25_5")] #[test] fn from_bytes_vs_radix_25_5_limb_constants() { let test_elt = FieldElement::from_bytes(&B_BYTES); @@ -1159,6 +1168,7 @@ mod test { } } + #[cfg(feature="radix_25_5")] #[test] fn radix_25_5_limb_constants_to_bytes_vs_byte_constants() { let test_bytes = B_LIMBS_RADIX_25_5.to_bytes(); @@ -1171,8 +1181,8 @@ mod test { #[test] fn conditional_negate() { - 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 mut x = one; x.conditional_negate(1u8); assert_eq!(x, minus_one);