diff --git a/build.rs b/build.rs index 284bce7..c6a25eb 100644 --- a/build.rs +++ b/build.rs @@ -81,10 +81,10 @@ fn main() { format!( "\n #[cfg(feature = \"u32_backend\")] -use backend::u32::field::FieldElement32; +use backend::u32::field::FieldElement2625; #[cfg(feature = \"u64_backend\")] -use backend::u64::field::FieldElement64; +use backend::u64::field::FieldElement51; use edwards::EdwardsBasepointTable; diff --git a/docs/avx2-notes.md b/docs/avx2-notes.md index d902650..a382a34 100644 --- a/docs/avx2-notes.md +++ b/docs/avx2-notes.md @@ -444,7 +444,7 @@ There are several directions for future improvement: particularly NEON. The current point arithmetic code is written in terms of field element vectors, which are in turn implemented using platform SIMD vectors. It should be possible to write an alternate - implementation of the `FieldElement32x4` using NEON without changing + implementation of the `FieldElement2625x4` using NEON without changing the point arithmetic. NEON has 128-bit vectors rather than 256-bit vectors, but this may still be worthwhile compared to a serial implementation. diff --git a/src/backend/avx2/constants.rs b/src/backend/avx2/constants.rs index 76a644a..2433497 100644 --- a/src/backend/avx2/constants.rs +++ b/src/backend/avx2/constants.rs @@ -13,11 +13,11 @@ use packed_simd::u32x8; use backend::avx2::edwards::{CachedPoint, ExtendedPoint}; -use backend::avx2::field::FieldElement32x4; +use backend::avx2::field::FieldElement2625x4; use scalar_mul::window::NafLookupTable8; /// The identity element as an `ExtendedPoint`. -pub(crate) static EXTENDEDPOINT_IDENTITY: ExtendedPoint = ExtendedPoint(FieldElement32x4([ +pub(crate) static EXTENDEDPOINT_IDENTITY: ExtendedPoint = ExtendedPoint(FieldElement2625x4([ u32x8::new(0, 1, 0, 0, 1, 0, 0, 0), u32x8::splat(0), u32x8::splat(0), @@ -26,7 +26,7 @@ pub(crate) static EXTENDEDPOINT_IDENTITY: ExtendedPoint = ExtendedPoint(FieldEle ])); /// The identity element as a `CachedPoint`. -pub(crate) static CACHEDPOINT_IDENTITY: CachedPoint = CachedPoint(FieldElement32x4([ +pub(crate) static CACHEDPOINT_IDENTITY: CachedPoint = CachedPoint(FieldElement2625x4([ u32x8::new(121647, 121666, 0, 0, 243332, 67108845, 0, 33554431), u32x8::new(67108864, 0, 33554431, 0, 0, 67108863, 0, 33554431), u32x8::new(67108863, 0, 33554431, 0, 0, 67108863, 0, 33554431), @@ -96,7 +96,7 @@ pub(crate) static P_TIMES_16_HI: u32x8 = u32x8::new( /// Odd multiples of the Ed25519 basepoint: pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8 = NafLookupTable8([ - CachedPoint(FieldElement32x4([ + CachedPoint(FieldElement2625x4([ u32x8::new( 3571425, 10045002, @@ -148,7 +148,7 @@ pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8 = Naf 4846528, ), ])), - CachedPoint(FieldElement32x4([ + CachedPoint(FieldElement2625x4([ u32x8::new( 47099681, 31447946, @@ -200,7 +200,7 @@ pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8 = Naf 31366585, ), ])), - CachedPoint(FieldElement32x4([ + CachedPoint(FieldElement2625x4([ u32x8::new( 18147205, 62587998, @@ -252,7 +252,7 @@ pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8 = Naf 31948344, ), ])), - CachedPoint(FieldElement32x4([ + CachedPoint(FieldElement2625x4([ u32x8::new( 10625852, 15193821, @@ -304,7 +304,7 @@ pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8 = Naf 11531760, ), ])), - CachedPoint(FieldElement32x4([ + CachedPoint(FieldElement2625x4([ u32x8::new( 22176662, 3984313, @@ -356,7 +356,7 @@ pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8 = Naf 9686767, ), ])), - CachedPoint(FieldElement32x4([ + CachedPoint(FieldElement2625x4([ u32x8::new( 21157200, 39156966, @@ -408,7 +408,7 @@ pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8 = Naf 17395963, ), ])), - CachedPoint(FieldElement32x4([ + CachedPoint(FieldElement2625x4([ u32x8::new( 63153652, 32195955, @@ -460,7 +460,7 @@ pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8 = Naf 10289708, ), ])), - CachedPoint(FieldElement32x4([ + CachedPoint(FieldElement2625x4([ u32x8::new( 1401265, 58846825, @@ -512,7 +512,7 @@ pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8 = Naf 11976112, ), ])), - CachedPoint(FieldElement32x4([ + CachedPoint(FieldElement2625x4([ u32x8::new( 39849808, 44781685, @@ -564,7 +564,7 @@ pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8 = Naf 27313245, ), ])), - CachedPoint(FieldElement32x4([ + CachedPoint(FieldElement2625x4([ u32x8::new( 58237774, 15917425, @@ -616,7 +616,7 @@ pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8 = Naf 22487864, ), ])), - CachedPoint(FieldElement32x4([ + CachedPoint(FieldElement2625x4([ u32x8::new( 12671134, 56419053, @@ -668,7 +668,7 @@ pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8 = Naf 2606889, ), ])), - CachedPoint(FieldElement32x4([ + CachedPoint(FieldElement2625x4([ u32x8::new( 55082775, 45300503, @@ -720,7 +720,7 @@ pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8 = Naf 5956424, ), ])), - CachedPoint(FieldElement32x4([ + CachedPoint(FieldElement2625x4([ u32x8::new( 8211442, 8014184, @@ -772,7 +772,7 @@ pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8 = Naf 1824195, ), ])), - CachedPoint(FieldElement32x4([ + CachedPoint(FieldElement2625x4([ u32x8::new( 59402443, 17056879, @@ -824,7 +824,7 @@ pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8 = Naf 11687259, ), ])), - CachedPoint(FieldElement32x4([ + CachedPoint(FieldElement2625x4([ u32x8::new( 12521903, 26014045, @@ -876,7 +876,7 @@ pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8 = Naf 32973409, ), ])), - CachedPoint(FieldElement32x4([ + CachedPoint(FieldElement2625x4([ u32x8::new( 30654745, 51286025, @@ -928,7 +928,7 @@ pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8 = Naf 32228854, ), ])), - CachedPoint(FieldElement32x4([ + CachedPoint(FieldElement2625x4([ u32x8::new( 49518649, 59119280, @@ -980,7 +980,7 @@ pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8 = Naf 27003505, ), ])), - CachedPoint(FieldElement32x4([ + CachedPoint(FieldElement2625x4([ u32x8::new( 28286608, 10767548, @@ -1032,7 +1032,7 @@ pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8 = Naf 18292949, ), ])), - CachedPoint(FieldElement32x4([ + CachedPoint(FieldElement2625x4([ u32x8::new( 13869851, 31448904, @@ -1084,7 +1084,7 @@ pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8 = Naf 17277037, ), ])), - CachedPoint(FieldElement32x4([ + CachedPoint(FieldElement2625x4([ u32x8::new( 43287109, 27900723, @@ -1136,7 +1136,7 @@ pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8 = Naf 30748046, ), ])), - CachedPoint(FieldElement32x4([ + CachedPoint(FieldElement2625x4([ u32x8::new( 16441817, 36111849, @@ -1188,7 +1188,7 @@ pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8 = Naf 10930179, ), ])), - CachedPoint(FieldElement32x4([ + CachedPoint(FieldElement2625x4([ u32x8::new( 28319289, 40734650, @@ -1240,7 +1240,7 @@ pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8 = Naf 10938429, ), ])), - CachedPoint(FieldElement32x4([ + CachedPoint(FieldElement2625x4([ u32x8::new( 8373273, 49064494, @@ -1292,7 +1292,7 @@ pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8 = Naf 15812027, ), ])), - CachedPoint(FieldElement32x4([ + CachedPoint(FieldElement2625x4([ u32x8::new( 30741269, 38648744, @@ -1344,7 +1344,7 @@ pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8 = Naf 10839820, ), ])), - CachedPoint(FieldElement32x4([ + CachedPoint(FieldElement2625x4([ u32x8::new( 18672548, 57660959, @@ -1396,7 +1396,7 @@ pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8 = Naf 30432268, ), ])), - CachedPoint(FieldElement32x4([ + CachedPoint(FieldElement2625x4([ u32x8::new( 12179834, 41005450, @@ -1448,7 +1448,7 @@ pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8 = Naf 24862543, ), ])), - CachedPoint(FieldElement32x4([ + CachedPoint(FieldElement2625x4([ u32x8::new( 59523541, 62195428, @@ -1500,7 +1500,7 @@ pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8 = Naf 27449522, ), ])), - CachedPoint(FieldElement32x4([ + CachedPoint(FieldElement2625x4([ u32x8::new( 19770733, 26478685, @@ -1552,7 +1552,7 @@ pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8 = Naf 1776722, ), ])), - CachedPoint(FieldElement32x4([ + CachedPoint(FieldElement2625x4([ u32x8::new( 36719806, 20827965, @@ -1604,7 +1604,7 @@ pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8 = Naf 29334408, ), ])), - CachedPoint(FieldElement32x4([ + CachedPoint(FieldElement2625x4([ u32x8::new( 42307254, 57217102, @@ -1656,7 +1656,7 @@ pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8 = Naf 11292096, ), ])), - CachedPoint(FieldElement32x4([ + CachedPoint(FieldElement2625x4([ u32x8::new( 7071115, 46444090, @@ -1708,7 +1708,7 @@ pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8 = Naf 26285185, ), ])), - CachedPoint(FieldElement32x4([ + CachedPoint(FieldElement2625x4([ u32x8::new( 963440, 63742255, @@ -1760,7 +1760,7 @@ pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8 = Naf 4928058, ), ])), - CachedPoint(FieldElement32x4([ + CachedPoint(FieldElement2625x4([ u32x8::new( 63655588, 17883670, @@ -1812,7 +1812,7 @@ pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8 = Naf 32462955, ), ])), - CachedPoint(FieldElement32x4([ + CachedPoint(FieldElement2625x4([ u32x8::new( 39158670, 15322548, @@ -1864,7 +1864,7 @@ pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8 = Naf 20307815, ), ])), - CachedPoint(FieldElement32x4([ + CachedPoint(FieldElement2625x4([ u32x8::new( 2863373, 40876242, @@ -1916,7 +1916,7 @@ pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8 = Naf 21388876, ), ])), - CachedPoint(FieldElement32x4([ + CachedPoint(FieldElement2625x4([ u32x8::new( 59276548, 49972346, @@ -1968,7 +1968,7 @@ pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8 = Naf 27257051, ), ])), - CachedPoint(FieldElement32x4([ + CachedPoint(FieldElement2625x4([ u32x8::new( 52951491, 66542164, @@ -2020,7 +2020,7 @@ pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8 = Naf 26001714, ), ])), - CachedPoint(FieldElement32x4([ + CachedPoint(FieldElement2625x4([ u32x8::new( 66783087, 5234346, @@ -2072,7 +2072,7 @@ pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8 = Naf 10065424, ), ])), - CachedPoint(FieldElement32x4([ + CachedPoint(FieldElement2625x4([ u32x8::new( 42822326, 57678669, @@ -2124,7 +2124,7 @@ pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8 = Naf 4170709, ), ])), - CachedPoint(FieldElement32x4([ + CachedPoint(FieldElement2625x4([ u32x8::new( 26535281, 60238317, @@ -2176,7 +2176,7 @@ pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8 = Naf 33286062, ), ])), - CachedPoint(FieldElement32x4([ + CachedPoint(FieldElement2625x4([ u32x8::new( 54863941, 67016431, @@ -2228,7 +2228,7 @@ pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8 = Naf 347423, ), ])), - CachedPoint(FieldElement32x4([ + CachedPoint(FieldElement2625x4([ u32x8::new( 41391822, 34336880, @@ -2280,7 +2280,7 @@ pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8 = Naf 4942942, ), ])), - CachedPoint(FieldElement32x4([ + CachedPoint(FieldElement2625x4([ u32x8::new( 31956192, 59570132, @@ -2332,7 +2332,7 @@ pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8 = Naf 32932252, ), ])), - CachedPoint(FieldElement32x4([ + CachedPoint(FieldElement2625x4([ u32x8::new( 29885826, 51028067, @@ -2384,7 +2384,7 @@ pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8 = Naf 9101885, ), ])), - CachedPoint(FieldElement32x4([ + CachedPoint(FieldElement2625x4([ u32x8::new( 43331297, 18431341, @@ -2436,7 +2436,7 @@ pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8 = Naf 201203, ), ])), - CachedPoint(FieldElement32x4([ + CachedPoint(FieldElement2625x4([ u32x8::new( 20548943, 14334571, @@ -2488,7 +2488,7 @@ pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8 = Naf 25177079, ), ])), - CachedPoint(FieldElement32x4([ + CachedPoint(FieldElement2625x4([ u32x8::new( 41186817, 46681702, @@ -2540,7 +2540,7 @@ pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8 = Naf 7976478, ), ])), - CachedPoint(FieldElement32x4([ + CachedPoint(FieldElement2625x4([ u32x8::new( 46509314, 55327128, @@ -2592,7 +2592,7 @@ pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8 = Naf 22687008, ), ])), - CachedPoint(FieldElement32x4([ + CachedPoint(FieldElement2625x4([ u32x8::new( 15091184, 32550863, @@ -2644,7 +2644,7 @@ pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8 = Naf 542137, ), ])), - CachedPoint(FieldElement32x4([ + CachedPoint(FieldElement2625x4([ u32x8::new( 62776018, 32835413, @@ -2696,7 +2696,7 @@ pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8 = Naf 21024049, ), ])), - CachedPoint(FieldElement32x4([ + CachedPoint(FieldElement2625x4([ u32x8::new( 60835961, 48209103, @@ -2748,7 +2748,7 @@ pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8 = Naf 20924342, ), ])), - CachedPoint(FieldElement32x4([ + CachedPoint(FieldElement2625x4([ u32x8::new( 18135013, 20358426, @@ -2800,7 +2800,7 @@ pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8 = Naf 14572399, ), ])), - CachedPoint(FieldElement32x4([ + CachedPoint(FieldElement2625x4([ u32x8::new( 10785787, 46564798, @@ -2852,7 +2852,7 @@ pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8 = Naf 24110612, ), ])), - CachedPoint(FieldElement32x4([ + CachedPoint(FieldElement2625x4([ u32x8::new( 39907267, 45940262, @@ -2904,7 +2904,7 @@ pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8 = Naf 29853825, ), ])), - CachedPoint(FieldElement32x4([ + CachedPoint(FieldElement2625x4([ u32x8::new( 66303987, 36060363, @@ -2956,7 +2956,7 @@ pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8 = Naf 23261841, ), ])), - CachedPoint(FieldElement32x4([ + CachedPoint(FieldElement2625x4([ u32x8::new( 51218008, 5070126, @@ -3008,7 +3008,7 @@ pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8 = Naf 18326047, ), ])), - CachedPoint(FieldElement32x4([ + CachedPoint(FieldElement2625x4([ u32x8::new( 64176557, 3912400, @@ -3060,7 +3060,7 @@ pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8 = Naf 12655016, ), ])), - CachedPoint(FieldElement32x4([ + CachedPoint(FieldElement2625x4([ u32x8::new( 38372660, 57101970, @@ -3112,7 +3112,7 @@ pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8 = Naf 13421882, ), ])), - CachedPoint(FieldElement32x4([ + CachedPoint(FieldElement2625x4([ u32x8::new( 22917795, 22088359, @@ -3164,7 +3164,7 @@ pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8 = Naf 13175986, ), ])), - CachedPoint(FieldElement32x4([ + CachedPoint(FieldElement2625x4([ u32x8::new( 16185025, 61537525, @@ -3216,7 +3216,7 @@ pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8 = Naf 21409233, ), ])), - CachedPoint(FieldElement32x4([ + CachedPoint(FieldElement2625x4([ u32x8::new( 59411973, 57437124, @@ -3268,7 +3268,7 @@ pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8 = Naf 4211851, ), ])), - CachedPoint(FieldElement32x4([ + CachedPoint(FieldElement2625x4([ u32x8::new( 6757410, 65455566, @@ -3320,7 +3320,7 @@ pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8 = Naf 10524446, ), ])), - CachedPoint(FieldElement32x4([ + CachedPoint(FieldElement2625x4([ u32x8::new( 1497507, 33054449, @@ -3372,7 +3372,7 @@ pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8 = Naf 29687002, ), ])), - CachedPoint(FieldElement32x4([ + CachedPoint(FieldElement2625x4([ u32x8::new( 35889734, 23047226, diff --git a/src/backend/avx2/edwards.rs b/src/backend/avx2/edwards.rs index 18ecfde..e076238 100644 --- a/src/backend/avx2/edwards.rs +++ b/src/backend/avx2/edwards.rs @@ -45,7 +45,7 @@ use scalar_mul::window::{LookupTable, NafLookupTable5, NafLookupTable8}; use traits::Identity; -use backend::avx2::field::{FieldElement32x4, Lanes, Shuffle}; +use backend::avx2::field::{FieldElement2625x4, Lanes, Shuffle}; use backend::avx2::constants; /// A point on Curve25519, using parallel Edwards formulas for curve @@ -56,11 +56,11 @@ use backend::avx2::constants; /// The coefficients of an `ExtendedPoint` are bounded with /// \\( b < 0.007 \\). #[derive(Copy, Clone, Debug)] -pub struct ExtendedPoint(pub(super) FieldElement32x4); +pub struct ExtendedPoint(pub(super) FieldElement2625x4); impl From for ExtendedPoint { fn from(P: edwards::EdwardsPoint) -> ExtendedPoint { - ExtendedPoint(FieldElement32x4::new(&P.X, &P.Y, &P.Z, &P.T)) + ExtendedPoint(FieldElement2625x4::new(&P.X, &P.Y, &P.Z, &P.T)) } } @@ -78,7 +78,7 @@ impl From for edwards::EdwardsPoint { impl ConditionallySelectable for ExtendedPoint { fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self { - ExtendedPoint(FieldElement32x4::conditional_select(&a.0, &b.0, choice)) + ExtendedPoint(FieldElement2625x4::conditional_select(&a.0, &b.0, choice)) } fn conditional_assign(&mut self, other: &Self, choice: Choice) { @@ -133,7 +133,7 @@ impl ExtendedPoint { // ======================= // S5 S6 S8 S9 - let zero = FieldElement32x4::zero(); + let zero = FieldElement2625x4::zero(); let S_1 = tmp1.shuffle(Shuffle::AAAA); let S_2 = tmp1.shuffle(Shuffle::BBBB); @@ -181,7 +181,7 @@ impl ExtendedPoint { /// As long as the `CachedPoint` is not repeatedly negated, its /// coefficients will be bounded with \\( b < 1.0 \\). #[derive(Copy, Clone, Debug)] -pub struct CachedPoint(pub(super) FieldElement32x4); +pub struct CachedPoint(pub(super) FieldElement2625x4); impl From for CachedPoint { fn from(P: ExtendedPoint) -> CachedPoint { @@ -215,7 +215,7 @@ impl Identity for CachedPoint { impl ConditionallySelectable for CachedPoint { fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self { - CachedPoint(FieldElement32x4::conditional_select(&a.0, &b.0, choice)) + CachedPoint(FieldElement2625x4::conditional_select(&a.0, &b.0, choice)) } fn conditional_assign(&mut self, other: &Self, choice: Choice) { @@ -329,7 +329,7 @@ mod test { use super::*; fn serial_add(P: edwards::EdwardsPoint, Q: edwards::EdwardsPoint) -> edwards::EdwardsPoint { - use backend::u64::field::FieldElement64; + use backend::u64::field::FieldElement51; let (X1, Y1, Z1, T1) = (P.X, P.Y, P.Z, P.T); let (X2, Y2, Z2, T2) = (Q.X, Q.Y, Q.Z, Q.T); @@ -360,10 +360,10 @@ mod test { print_var!(S7); println!(""); - let S8 = &S4 * &FieldElement64([ 121666,0,0,0,0]); // R5 - let S9 = &S5 * &FieldElement64([ 121666,0,0,0,0]); // R6 - let S10 = &S6 * &FieldElement64([2*121666,0,0,0,0]); // R8 - let S11 = &S7 * &(-&FieldElement64([2*121665,0,0,0,0])); // R7 + let S8 = &S4 * &FieldElement51([ 121666,0,0,0,0]); // R5 + let S9 = &S5 * &FieldElement51([ 121666,0,0,0,0]); // R6 + let S10 = &S6 * &FieldElement51([2*121666,0,0,0,0]); // R8 + let S11 = &S7 * &(-&FieldElement51([2*121665,0,0,0,0])); // R7 print_var!(S8); print_var!(S9); print_var!(S10); diff --git a/src/backend/avx2/field.rs b/src/backend/avx2/field.rs index 27ba558..9364e45 100644 --- a/src/backend/avx2/field.rs +++ b/src/backend/avx2/field.rs @@ -11,14 +11,14 @@ //! An implementation of 4-way vectorized 32bit field arithmetic using //! AVX2. //! -//! The `FieldElement32x4` struct provides a vector of four field +//! The `FieldElement2625x4` struct provides a vector of four field //! elements, implemented using AVX2 operations. Its API is designed //! to abstract away the platform-dependent details, so that point //! arithmetic can be implemented only in terms of a vector of field //! elements. //! //! At this level, the API is optimized for speed and not safety. The -//! `FieldElement32x4` does not always perform reductions. The pre- +//! `FieldElement2625x4` does not always perform reductions. The pre- //! and post-conditions on the bounds of the coefficients are //! documented for each method, but it is the caller's responsibility //! to ensure that there are no overflows. @@ -43,7 +43,7 @@ use core::ops::{Add, Mul, Neg}; use packed_simd::{i32x8, u32x8, u64x4, IntoBits}; use backend::avx2::constants::{P_TIMES_16_HI, P_TIMES_16_LO, P_TIMES_2_HI, P_TIMES_2_LO}; -use backend::u64::field::FieldElement64; +use backend::u64::field::FieldElement51; /// Unpack 32-bit lanes into 64-bit lanes: /// ``` @@ -97,11 +97,11 @@ fn repack_pair(x: u32x8, y: u32x8) -> u32x8 { } /// The `Lanes` enum represents a subset of the lanes `A,B,C,D` of a -/// `FieldElement32x4`. +/// `FieldElement2625x4`. /// /// It's used to specify blend operations without /// having to know details about the data layout of the -/// `FieldElement32x4`. +/// `FieldElement2625x4`. #[derive(Copy, Clone, Debug)] pub enum Lanes { C, @@ -114,7 +114,7 @@ pub enum Lanes { ABCD, } -/// The `Shuffle` enum represents a shuffle of a `FieldElement32x4`. +/// The `Shuffle` enum represents a shuffle of a `FieldElement2625x4`. /// /// The enum variants are named by what they do to a vector \\( /// (A,B,C,D) \\); for instance, `Shuffle::BADC` turns \\( (A, B, C, @@ -135,26 +135,26 @@ pub enum Shuffle { /// A vector of four field elements. /// -/// Each operation on a `FieldElement32x4` has documented effects on +/// Each operation on a `FieldElement2625x4` has documented effects on /// the bounds of the coefficients. This API is designed for speed /// and not safety; it is the caller's responsibility to ensure that /// the post-conditions of one operation are compatible with the /// pre-conditions of the next. #[derive(Clone, Copy, Debug)] -pub struct FieldElement32x4(pub(crate) [u32x8; 5]); +pub struct FieldElement2625x4(pub(crate) [u32x8; 5]); use subtle::Choice; use subtle::ConditionallySelectable; -impl ConditionallySelectable for FieldElement32x4 { +impl ConditionallySelectable for FieldElement2625x4 { fn conditional_select( - a: &FieldElement32x4, - b: &FieldElement32x4, + a: &FieldElement2625x4, + b: &FieldElement2625x4, choice: Choice, - ) -> FieldElement32x4 { + ) -> FieldElement2625x4 { let mask = (-(choice.unwrap_u8() as i32)) as u32; let mask_vec = u32x8::splat(mask); - FieldElement32x4([ + FieldElement2625x4([ a.0[0] ^ (mask_vec & (a.0[0] ^ b.0[0])), a.0[1] ^ (mask_vec & (a.0[1] ^ b.0[1])), a.0[2] ^ (mask_vec & (a.0[2] ^ b.0[2])), @@ -165,7 +165,7 @@ impl ConditionallySelectable for FieldElement32x4 { fn conditional_assign( &mut self, - other: &FieldElement32x4, + other: &FieldElement2625x4, choice: Choice, ) { let mask = (-(choice.unwrap_u8() as i32)) as u32; @@ -178,11 +178,11 @@ impl ConditionallySelectable for FieldElement32x4 { } } -impl FieldElement32x4 { +impl FieldElement2625x4 { /// Split this vector into an array of four (serial) field /// elements. - pub fn split(&self) -> [FieldElement64; 4] { - let mut out = [FieldElement64::zero(); 4]; + pub fn split(&self) -> [FieldElement51; 4] { + let mut out = [FieldElement51::zero(); 4]; for i in 0..5 { let a_2i = self.0[i].extract(0) as u64; // let b_2i = self.0[i].extract(1) as u64; // @@ -208,7 +208,7 @@ impl FieldElement32x4 { /// that when this function is inlined, LLVM is able to lower the /// shuffle using an immediate. #[inline] - pub fn shuffle(&self, control: Shuffle) -> FieldElement32x4 { + pub fn shuffle(&self, control: Shuffle) -> FieldElement2625x4 { #[inline(always)] fn shuffle_lanes(x: u32x8, control: Shuffle) -> u32x8 { unsafe { @@ -233,7 +233,7 @@ impl FieldElement32x4 { } } - FieldElement32x4([ + FieldElement2625x4([ shuffle_lanes(self.0[0], control), shuffle_lanes(self.0[1], control), shuffle_lanes(self.0[2], control), @@ -248,7 +248,7 @@ impl FieldElement32x4 { /// that this function can be inlined and LLVM can lower it to a /// blend instruction using an immediate. #[inline] - pub fn blend(&self, other: FieldElement32x4, control: Lanes) -> FieldElement32x4 { + pub fn blend(&self, other: FieldElement2625x4, control: Lanes) -> FieldElement2625x4 { #[inline(always)] fn blend_lanes(x: u32x8, y: u32x8, control: Lanes) -> u32x8 { unsafe { @@ -310,7 +310,7 @@ impl FieldElement32x4 { } } - FieldElement32x4([ + FieldElement2625x4([ blend_lanes(self.0[0], other.0[0], control), blend_lanes(self.0[1], other.0[1], control), blend_lanes(self.0[2], other.0[2], control), @@ -320,26 +320,26 @@ impl FieldElement32x4 { } /// Construct a vector of zeros. - pub fn zero() -> FieldElement32x4 { - FieldElement32x4([u32x8::splat(0); 5]) + pub fn zero() -> FieldElement2625x4 { + FieldElement2625x4([u32x8::splat(0); 5]) } /// Convenience wrapper around `new(x,x,x,x)`. - pub fn splat(x: &FieldElement64) -> FieldElement32x4 { - FieldElement32x4::new(x, x, x, x) + pub fn splat(x: &FieldElement51) -> FieldElement2625x4 { + FieldElement2625x4::new(x, x, x, x) } - /// Create a `FieldElement32x4` from four `FieldElement64`s. + /// Create a `FieldElement2625x4` from four `FieldElement51`s. /// /// # Postconditions /// - /// The resulting `FieldElement32x4` is bounded with \\( b < 0.0002 \\). + /// The resulting `FieldElement2625x4` is bounded with \\( b < 0.0002 \\). pub fn new( - x0: &FieldElement64, - x1: &FieldElement64, - x2: &FieldElement64, - x3: &FieldElement64, - ) -> FieldElement32x4 { + x0: &FieldElement51, + x1: &FieldElement51, + x2: &FieldElement51, + x3: &FieldElement51, + ) -> FieldElement2625x4 { let mut buf = [u32x8::splat(0); 5]; let low_26_bits = (1 << 26) - 1; for i in 0..5 { @@ -355,10 +355,10 @@ impl FieldElement32x4 { buf[i] = u32x8::new(a_2i, b_2i, a_2i_1, b_2i_1, c_2i, d_2i, c_2i_1, d_2i_1); } - // We don't know that the original `FieldElement64`s were + // We don't know that the original `FieldElement51`s were // fully reduced, so the odd limbs may exceed 2^25. // Reduce them to be sure. - FieldElement32x4(buf).reduce() + FieldElement2625x4(buf).reduce() } /// Given \\((A,B,C,D)\\), compute \\((-A,-B,-C,-D)\\), without @@ -372,11 +372,11 @@ impl FieldElement32x4 { /// /// The coefficients of the result are bounded with \\( b < 1 \\). #[inline] - pub fn negate_lazy(&self) -> FieldElement32x4 { + pub fn negate_lazy(&self) -> FieldElement2625x4 { // The limbs of self are bounded with b < 0.999, while the // smallest limb of 2*p is 67108845 > 2^{26+0.9999}, so // underflows are not possible. - FieldElement32x4([ + FieldElement2625x4([ P_TIMES_2_LO - self.0[0], P_TIMES_2_HI - self.0[1], P_TIMES_2_HI - self.0[2], @@ -395,7 +395,7 @@ impl FieldElement32x4 { /// /// The coefficients of the result are bounded with \\( b < 1.6 \\). #[inline] - pub fn diff_sum(&self) -> FieldElement32x4 { + pub fn diff_sum(&self) -> FieldElement2625x4 { // tmp1 = (B, A, D, C) let tmp1 = self.shuffle(Shuffle::BADC); // tmp2 = (-A, B, -C, D) @@ -410,7 +410,7 @@ impl FieldElement32x4 { /// /// The coefficients of the result are bounded with \\( b < 0.0002 \\). #[inline] - pub fn reduce(&self) -> FieldElement32x4 { + pub fn reduce(&self) -> FieldElement2625x4 { let shifts = i32x8::new(26, 26, 25, 25, 26, 26, 25, 25); let masks = u32x8::new( (1 << 26) - 1, @@ -509,16 +509,16 @@ impl FieldElement32x4 { // c_odd < 2^25 + 2^11.25 < 25.0001 < 2^{25+b} // // where b = 0.0002. - FieldElement32x4(v) + FieldElement2625x4(v) } - /// Given an array of wide coefficients, reduce them to a `FieldElement32x4`. + /// Given an array of wide coefficients, reduce them to a `FieldElement2625x4`. /// /// # Postconditions /// /// The coefficients of the result are bounded with \\( b < 0.007 \\). #[inline] - fn reduce64(mut z: [u64x4; 10]) -> FieldElement32x4 { + fn reduce64(mut z: [u64x4; 10]) -> FieldElement2625x4 { // These aren't const because splat isn't a const fn let LOW_25_BITS: u64x4 = u64x4::splat((1 << 25) - 1); let LOW_26_BITS: u64x4 = u64x4::splat((1 << 26) - 1); @@ -578,7 +578,7 @@ impl FieldElement32x4 { // b = 0 for other z[i]. // // So the packed result is bounded with b = 0.007. - FieldElement32x4([ + FieldElement2625x4([ repack_pair(z[0].into_bits(), z[1].into_bits()), repack_pair(z[2].into_bits(), z[3].into_bits()), repack_pair(z[4].into_bits(), z[5].into_bits()), @@ -596,7 +596,7 @@ impl FieldElement32x4 { /// # Postconditions /// /// The coefficients of the result are bounded with \\( b < 0.007 \\). - pub fn square_and_negate_D(&self) -> FieldElement32x4 { + pub fn square_and_negate_D(&self) -> FieldElement2625x4 { #[inline(always)] fn m(x: u32x8, y: u32x8) -> u64x4 { use core::arch::x86_64::_mm256_mul_epu32; @@ -681,12 +681,12 @@ impl FieldElement32x4 { z8 = negate_D(z8, even_p37); z9 = negate_D(z9, odd__p37); - FieldElement32x4::reduce64([z0, z1, z2, z3, z4, z5, z6, z7, z8, z9]) + FieldElement2625x4::reduce64([z0, z1, z2, z3, z4, z5, z6, z7, z8, z9]) } } -impl Neg for FieldElement32x4 { - type Output = FieldElement32x4; +impl Neg for FieldElement2625x4 { + type Output = FieldElement2625x4; /// Negate this field element, performing a reduction. /// @@ -701,8 +701,8 @@ impl Neg for FieldElement32x4 { /// /// The coefficients of the result are bounded with \\( b < 0.0002 \\). #[inline] - fn neg(self) -> FieldElement32x4 { - FieldElement32x4([ + fn neg(self) -> FieldElement2625x4 { + FieldElement2625x4([ P_TIMES_16_LO - self.0[0], P_TIMES_16_HI - self.0[1], P_TIMES_16_HI - self.0[2], @@ -712,12 +712,12 @@ impl Neg for FieldElement32x4 { } } -impl Add for FieldElement32x4 { - type Output = FieldElement32x4; - /// Add two `FieldElement32x4`s, without performing a reduction. +impl Add for FieldElement2625x4 { + type Output = FieldElement2625x4; + /// Add two `FieldElement2625x4`s, without performing a reduction. #[inline] - fn add(self, rhs: FieldElement32x4) -> FieldElement32x4 { - FieldElement32x4([ + fn add(self, rhs: FieldElement2625x4) -> FieldElement2625x4 { + FieldElement2625x4([ self.0[0] + rhs.0[0], self.0[1] + rhs.0[1], self.0[2] + rhs.0[2], @@ -727,15 +727,15 @@ impl Add for FieldElement32x4 { } } -impl Mul<(u32, u32, u32, u32)> for FieldElement32x4 { - type Output = FieldElement32x4; +impl Mul<(u32, u32, u32, u32)> for FieldElement2625x4 { + type Output = FieldElement2625x4; /// Perform a multiplication by a vector of small constants. /// /// # Postconditions /// /// The coefficients of the result are bounded with \\( b < 0.007 \\). #[inline] - fn mul(self, scalars: (u32, u32, u32, u32)) -> FieldElement32x4 { + fn mul(self, scalars: (u32, u32, u32, u32)) -> FieldElement2625x4 { unsafe { use core::arch::x86_64::_mm256_mul_epu32; @@ -747,7 +747,7 @@ impl Mul<(u32, u32, u32, u32)> for FieldElement32x4 { let (b6, b7) = unpack_pair(self.0[3]); let (b8, b9) = unpack_pair(self.0[4]); - FieldElement32x4::reduce64([ + FieldElement2625x4::reduce64([ _mm256_mul_epu32(b0.into_bits(), consts.into_bits()).into_bits(), _mm256_mul_epu32(b1.into_bits(), consts.into_bits()).into_bits(), _mm256_mul_epu32(b2.into_bits(), consts.into_bits()).into_bits(), @@ -763,8 +763,8 @@ impl Mul<(u32, u32, u32, u32)> for FieldElement32x4 { } } -impl<'a, 'b> Mul<&'b FieldElement32x4> for &'a FieldElement32x4 { - type Output = FieldElement32x4; +impl<'a, 'b> Mul<&'b FieldElement2625x4> for &'a FieldElement2625x4 { + type Output = FieldElement2625x4; /// Multiply `self` by `rhs`. /// /// # Preconditions @@ -777,7 +777,7 @@ impl<'a, 'b> Mul<&'b FieldElement32x4> for &'a FieldElement32x4 { /// /// The coefficients of the result are bounded with \\( b < 0.007 \\). /// - fn mul(self, rhs: &'b FieldElement32x4) -> FieldElement32x4 { + fn mul(self, rhs: &'b FieldElement2625x4) -> FieldElement2625x4 { #[inline(always)] fn m(x: u32x8, y: u32x8) -> u64x4 { use core::arch::x86_64::_mm256_mul_epu32; @@ -869,7 +869,7 @@ impl<'a, 'b> Mul<&'b FieldElement32x4> for &'a FieldElement32x4 { // multiplications by 19 into a u32. The tighter bound on b_y // means we could get a tighter bound on the outputs, or a // looser bound on b_x. - FieldElement32x4::reduce64([z0, z1, z2, z3, z4, z5, z6, z7, z8, z9]) + FieldElement2625x4::reduce64([z0, z1, z2, z3, z4, z5, z6, z7, z8, z9]) } } @@ -880,25 +880,25 @@ mod test { #[test] fn scale_by_curve_constants() { - let mut x = FieldElement32x4::splat(&FieldElement64::one()); + let mut x = FieldElement2625x4::splat(&FieldElement51::one()); x = x * (121666, 121666, 2*121666, 2*121665); let xs = x.split(); - assert_eq!(xs[0], FieldElement64([121666, 0, 0, 0, 0])); - assert_eq!(xs[1], FieldElement64([121666, 0, 0, 0, 0])); - assert_eq!(xs[2], FieldElement64([2 * 121666, 0, 0, 0, 0])); - assert_eq!(xs[3], FieldElement64([2 * 121665, 0, 0, 0, 0])); + assert_eq!(xs[0], FieldElement51([121666, 0, 0, 0, 0])); + assert_eq!(xs[1], FieldElement51([121666, 0, 0, 0, 0])); + assert_eq!(xs[2], FieldElement51([2 * 121666, 0, 0, 0, 0])); + assert_eq!(xs[3], FieldElement51([2 * 121665, 0, 0, 0, 0])); } #[test] fn diff_sum_vs_serial() { - let x0 = FieldElement64([10000, 10001, 10002, 10003, 10004]); - let x1 = FieldElement64([10100, 10101, 10102, 10103, 10104]); - let x2 = FieldElement64([10200, 10201, 10202, 10203, 10204]); - let x3 = FieldElement64([10300, 10301, 10302, 10303, 10304]); + let x0 = FieldElement51([10000, 10001, 10002, 10003, 10004]); + let x1 = FieldElement51([10100, 10101, 10102, 10103, 10104]); + let x2 = FieldElement51([10200, 10201, 10202, 10203, 10204]); + let x3 = FieldElement51([10300, 10301, 10302, 10303, 10304]); - let vec = FieldElement32x4::new(&x0, &x1, &x2, &x3).diff_sum(); + let vec = FieldElement2625x4::new(&x0, &x1, &x2, &x3).diff_sum(); let result = vec.split(); @@ -910,12 +910,12 @@ mod test { #[test] fn square_vs_serial() { - let x0 = FieldElement64([10000, 10001, 10002, 10003, 10004]); - let x1 = FieldElement64([10100, 10101, 10102, 10103, 10104]); - let x2 = FieldElement64([10200, 10201, 10202, 10203, 10204]); - let x3 = FieldElement64([10300, 10301, 10302, 10303, 10304]); + let x0 = FieldElement51([10000, 10001, 10002, 10003, 10004]); + let x1 = FieldElement51([10100, 10101, 10102, 10103, 10104]); + let x2 = FieldElement51([10200, 10201, 10202, 10203, 10204]); + let x3 = FieldElement51([10300, 10301, 10302, 10303, 10304]); - let vec = FieldElement32x4::new(&x0, &x1, &x2, &x3); + let vec = FieldElement2625x4::new(&x0, &x1, &x2, &x3); let result = vec.square_and_negate_D().split(); @@ -927,12 +927,12 @@ mod test { #[test] fn multiply_vs_serial() { - let x0 = FieldElement64([10000, 10001, 10002, 10003, 10004]); - let x1 = FieldElement64([10100, 10101, 10102, 10103, 10104]); - let x2 = FieldElement64([10200, 10201, 10202, 10203, 10204]); - let x3 = FieldElement64([10300, 10301, 10302, 10303, 10304]); + let x0 = FieldElement51([10000, 10001, 10002, 10003, 10004]); + let x1 = FieldElement51([10100, 10101, 10102, 10103, 10104]); + let x2 = FieldElement51([10200, 10201, 10202, 10203, 10204]); + let x3 = FieldElement51([10300, 10301, 10302, 10303, 10304]); - let vec = FieldElement32x4::new(&x0, &x1, &x2, &x3); + let vec = FieldElement2625x4::new(&x0, &x1, &x2, &x3); let vecprime = vec.clone(); let result = (&vec * &vecprime).split(); @@ -945,12 +945,12 @@ mod test { #[test] fn test_unpack_repack_pair() { - let x0 = FieldElement64([10000 + (10001 << 26), 0, 0, 0, 0]); - let x1 = FieldElement64([10100 + (10101 << 26), 0, 0, 0, 0]); - let x2 = FieldElement64([10200 + (10201 << 26), 0, 0, 0, 0]); - let x3 = FieldElement64([10300 + (10301 << 26), 0, 0, 0, 0]); + let x0 = FieldElement51([10000 + (10001 << 26), 0, 0, 0, 0]); + let x1 = FieldElement51([10100 + (10101 << 26), 0, 0, 0, 0]); + let x2 = FieldElement51([10200 + (10201 << 26), 0, 0, 0, 0]); + let x3 = FieldElement51([10300 + (10301 << 26), 0, 0, 0, 0]); - let vec = FieldElement32x4::new(&x0, &x1, &x2, &x3); + let vec = FieldElement2625x4::new(&x0, &x1, &x2, &x3); let src = vec.0[0]; @@ -969,12 +969,12 @@ mod test { #[test] fn new_split_roundtrips() { - let x0 = FieldElement64::from_bytes(&[0x10; 32]); - let x1 = FieldElement64::from_bytes(&[0x11; 32]); - let x2 = FieldElement64::from_bytes(&[0x12; 32]); - let x3 = FieldElement64::from_bytes(&[0x13; 32]); + let x0 = FieldElement51::from_bytes(&[0x10; 32]); + let x1 = FieldElement51::from_bytes(&[0x11; 32]); + let x2 = FieldElement51::from_bytes(&[0x12; 32]); + let x3 = FieldElement51::from_bytes(&[0x13; 32]); - let vec = FieldElement32x4::new(&x0, &x1, &x2, &x3); + let vec = FieldElement2625x4::new(&x0, &x1, &x2, &x3); let splits = vec.split(); diff --git a/src/backend/u32/constants.rs b/src/backend/u32/constants.rs index e0e0525..22def0a 100644 --- a/src/backend/u32/constants.rs +++ b/src/backend/u32/constants.rs @@ -12,48 +12,48 @@ //! and useful field elements like `sqrt(-1)`), as well as //! lookup tables of pre-computed points. -use backend::u32::field::FieldElement32; -use backend::u32::scalar::Scalar32; +use backend::u32::field::FieldElement2625; +use backend::u32::scalar::Scalar29; use edwards::EdwardsPoint; /// Edwards `d` value, equal to `-121665/121666 mod p`. -pub(crate) const EDWARDS_D: FieldElement32 = FieldElement32([ +pub(crate) const EDWARDS_D: FieldElement2625 = FieldElement2625([ 56195235, 13857412, 51736253, 6949390, 114729, 24766616, 60832955, 30306712, 48412415, 21499315, ]); /// Edwards `2*d` value, equal to `2*(-121665/121666) mod p`. -pub(crate) const EDWARDS_D2: FieldElement32 = FieldElement32([ +pub(crate) const EDWARDS_D2: FieldElement2625 = FieldElement2625([ 45281625, 27714825, 36363642, 13898781, 229458, 15978800, 54557047, 27058993, 29715967, 9444199, ]); /// `= sqrt(a*d - 1)`, where `a = -1 (mod p)`, `d` are the Edwards curve parameters. -pub(crate) const SQRT_AD_MINUS_ONE: FieldElement32 = FieldElement32([ +pub(crate) const SQRT_AD_MINUS_ONE: FieldElement2625 = FieldElement2625([ 24849947, 33400850, 43495378, 6347714, 46036536, 32887293, 41837720, 18186727, 66238516, 14525638, ]); /// `= 1/sqrt(a-d)`, where `a = -1 (mod p)`, `d` are the Edwards curve parameters. -pub(crate) const INVSQRT_A_MINUS_D: FieldElement32 = FieldElement32([ +pub(crate) const INVSQRT_A_MINUS_D: FieldElement2625 = FieldElement2625([ 6111466, 4156064, 39310137, 12243467, 41204824, 120896, 20826367, 26493656, 6093567, 31568420, ]); /// Precomputed value of one of the square roots of -1 (mod p) -pub(crate) const SQRT_M1: FieldElement32 = FieldElement32([ +pub(crate) const SQRT_M1: FieldElement2625 = FieldElement2625([ 34513072, 25610706, 9377949, 3500415, 12389472, 33281959, 41962654, 31548777, 326685, 11406482, ]); /// `APLUS2_OVER_FOUR` is (A+2)/4. (This is used internally within the Montgomery ladder.) -pub(crate) const APLUS2_OVER_FOUR: FieldElement32 = FieldElement32([ +pub(crate) const APLUS2_OVER_FOUR: FieldElement2625 = FieldElement2625([ 121666, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]); /// `L` is the order of base point, i.e. 2^252 + /// 27742317777372353535851937790883648493 -pub(crate) const L: Scalar32 = Scalar32([ 0x1cf5d3ed, 0x009318d2, 0x1de73596, 0x1df3bd45, +pub(crate) const L: Scalar29 = Scalar29([ 0x1cf5d3ed, 0x009318d2, 0x1de73596, 0x1df3bd45, 0x0000014d, 0x00000000, 0x00000000, 0x00000000, 0x00100000 ]); @@ -61,12 +61,12 @@ pub(crate) const L: Scalar32 = Scalar32([ 0x1cf5d3ed, 0x009318d2, 0x1de73596, 0x pub(crate) const LFACTOR: u32 = 0x12547e1b; /// `R` = R % L where R = 2^261 -pub(crate) const R: Scalar32 = Scalar32([ 0x114df9ed, 0x1a617303, 0x0f7c098c, 0x16793167, +pub(crate) const R: Scalar29 = Scalar29([ 0x114df9ed, 0x1a617303, 0x0f7c098c, 0x16793167, 0x1ffd656e, 0x1fffffff, 0x1fffffff, 0x1fffffff, 0x000fffff ]); /// `RR` = (R^2) % L where R = 2^261 -pub(crate) const RR: Scalar32 = Scalar32([ 0x0b5f9d12, 0x1e141b17, 0x158d7f3d, 0x143f3757, +pub(crate) const RR: Scalar29 = Scalar29([ 0x0b5f9d12, 0x1e141b17, 0x158d7f3d, 0x143f3757, 0x1972d781, 0x042feb7c, 0x1ceec73d, 0x1e184d1e, 0x0005046d ]); @@ -76,10 +76,10 @@ pub(crate) const RR: Scalar32 = Scalar32([ 0x0b5f9d12, 0x1e141b17, 0x158d7f3d, 0 /// `ED25519_BASEPOINT_TABLE`, which should be used for scalar /// multiplication (it's much faster). pub const ED25519_BASEPOINT_POINT: EdwardsPoint = EdwardsPoint{ - X: FieldElement32([52811034, 25909283, 16144682, 17082669, 27570973, 30858332, 40966398, 8378388, 20764389, 8758491]), - Y: FieldElement32([40265304, 26843545, 13421772, 20132659, 26843545, 6710886, 53687091, 13421772, 40265318, 26843545]), - Z: FieldElement32([1, 0, 0, 0, 0, 0, 0, 0, 0, 0]), - T: FieldElement32([28827043, 27438313, 39759291, 244362, 8635006, 11264893, 19351346, 13413597, 16611511, 27139452]), + X: FieldElement2625([52811034, 25909283, 16144682, 17082669, 27570973, 30858332, 40966398, 8378388, 20764389, 8758491]), + Y: FieldElement2625([40265304, 26843545, 13421772, 20132659, 26843545, 6710886, 53687091, 13421772, 40265318, 26843545]), + Z: FieldElement2625([1, 0, 0, 0, 0, 0, 0, 0, 0, 0]), + T: FieldElement2625([28827043, 27438313, 39759291, 244362, 8635006, 11264893, 19351346, 13413597, 16611511, 27139452]), }; /// The 8-torsion subgroup \\(\mathcal E [8]\\). @@ -99,51 +99,51 @@ pub const EIGHT_TORSION: [EdwardsPoint; 8] = EIGHT_TORSION_INNER_DOC_HIDDEN; #[doc(hidden)] pub const EIGHT_TORSION_INNER_DOC_HIDDEN: [EdwardsPoint; 8] = [ EdwardsPoint{ - X: FieldElement32([0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), - Y: FieldElement32([1, 0, 0, 0, 0, 0, 0, 0, 0, 0]), - Z: FieldElement32([1, 0, 0, 0, 0, 0, 0, 0, 0, 0]), - T: FieldElement32([0, 0, 0, 0, 0, 0, 0, 0, 0, 0]) + X: FieldElement2625([0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), + Y: FieldElement2625([1, 0, 0, 0, 0, 0, 0, 0, 0, 0]), + Z: FieldElement2625([1, 0, 0, 0, 0, 0, 0, 0, 0, 0]), + T: FieldElement2625([0, 0, 0, 0, 0, 0, 0, 0, 0, 0]) }, EdwardsPoint{ - X: FieldElement32([21352778, 5345713, 4660180, 25206575, 24143089, 14568123, 30185756, 21306662, 33579924, 8345318]), - Y: FieldElement32([6952903, 1265500, 60246523, 7057497, 4037696, 5447722, 35427965, 15325401, 19365852, 31985330]), - Z: FieldElement32([1, 0, 0, 0, 0, 0, 0, 0, 0, 0]), - T: FieldElement32([41846657, 21581751, 11716001, 27684820, 48915701, 16297738, 20670665, 24995334, 3541542, 28543251]) + X: FieldElement2625([21352778, 5345713, 4660180, 25206575, 24143089, 14568123, 30185756, 21306662, 33579924, 8345318]), + Y: FieldElement2625([6952903, 1265500, 60246523, 7057497, 4037696, 5447722, 35427965, 15325401, 19365852, 31985330]), + Z: FieldElement2625([1, 0, 0, 0, 0, 0, 0, 0, 0, 0]), + T: FieldElement2625([41846657, 21581751, 11716001, 27684820, 48915701, 16297738, 20670665, 24995334, 3541542, 28543251]) }, EdwardsPoint{ - X: FieldElement32([32595773, 7943725, 57730914, 30054016, 54719391, 272472, 25146209, 2005654, 66782178, 22147949]), - Y: FieldElement32([0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), - Z: FieldElement32([1, 0, 0, 0, 0, 0, 0, 0, 0, 0]), - T: FieldElement32([0, 0, 0, 0, 0, 0, 0, 0, 0, 0]) + X: FieldElement2625([32595773, 7943725, 57730914, 30054016, 54719391, 272472, 25146209, 2005654, 66782178, 22147949]), + Y: FieldElement2625([0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), + Z: FieldElement2625([1, 0, 0, 0, 0, 0, 0, 0, 0, 0]), + T: FieldElement2625([0, 0, 0, 0, 0, 0, 0, 0, 0, 0]) }, EdwardsPoint{ - X: FieldElement32([21352778, 5345713, 4660180, 25206575, 24143089, 14568123, 30185756, 21306662, 33579924, 8345318]), - Y: FieldElement32([60155942, 32288931, 6862340, 26496934, 63071167, 28106709, 31680898, 18229030, 47743011, 1569101]), - Z: FieldElement32([1, 0, 0, 0, 0, 0, 0, 0, 0, 0]), - T: FieldElement32([25262188, 11972680, 55392862, 5869611, 18193162, 17256693, 46438198, 8559097, 63567321, 5011180]) + X: FieldElement2625([21352778, 5345713, 4660180, 25206575, 24143089, 14568123, 30185756, 21306662, 33579924, 8345318]), + Y: FieldElement2625([60155942, 32288931, 6862340, 26496934, 63071167, 28106709, 31680898, 18229030, 47743011, 1569101]), + Z: FieldElement2625([1, 0, 0, 0, 0, 0, 0, 0, 0, 0]), + T: FieldElement2625([25262188, 11972680, 55392862, 5869611, 18193162, 17256693, 46438198, 8559097, 63567321, 5011180]) }, EdwardsPoint{ - X: FieldElement32([0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), - Y: FieldElement32([67108844, 33554431, 67108863, 33554431, 67108863, 33554431, 67108863, 33554431, 67108863, 33554431]), - Z: FieldElement32([1, 0, 0, 0, 0, 0, 0, 0, 0, 0]), - T: FieldElement32([0, 0, 0, 0, 0, 0, 0, 0, 0, 0]) + X: FieldElement2625([0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), + Y: FieldElement2625([67108844, 33554431, 67108863, 33554431, 67108863, 33554431, 67108863, 33554431, 67108863, 33554431]), + Z: FieldElement2625([1, 0, 0, 0, 0, 0, 0, 0, 0, 0]), + T: FieldElement2625([0, 0, 0, 0, 0, 0, 0, 0, 0, 0]) }, EdwardsPoint{ - X: FieldElement32([45756067, 28208718, 62448683, 8347856, 42965774, 18986308, 36923107, 12247769, 33528939, 25209113]), - Y: FieldElement32([60155942, 32288931, 6862340, 26496934, 63071167, 28106709, 31680898, 18229030, 47743011, 1569101]), - Z: FieldElement32([1, 0, 0, 0, 0, 0, 0, 0, 0, 0]), - T: FieldElement32([41846657, 21581751, 11716001, 27684820, 48915701, 16297738, 20670665, 24995334, 3541542, 28543251]) + X: FieldElement2625([45756067, 28208718, 62448683, 8347856, 42965774, 18986308, 36923107, 12247769, 33528939, 25209113]), + Y: FieldElement2625([60155942, 32288931, 6862340, 26496934, 63071167, 28106709, 31680898, 18229030, 47743011, 1569101]), + Z: FieldElement2625([1, 0, 0, 0, 0, 0, 0, 0, 0, 0]), + T: FieldElement2625([41846657, 21581751, 11716001, 27684820, 48915701, 16297738, 20670665, 24995334, 3541542, 28543251]) }, EdwardsPoint{ - X: FieldElement32([34513072, 25610706, 9377949, 3500415, 12389472, 33281959, 41962654, 31548777, 326685, 11406482]), - Y: FieldElement32([0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), - Z: FieldElement32([1, 0, 0, 0, 0, 0, 0, 0, 0, 0]), - T: FieldElement32([0, 0, 0, 0, 0, 0, 0, 0, 0, 0]) + X: FieldElement2625([34513072, 25610706, 9377949, 3500415, 12389472, 33281959, 41962654, 31548777, 326685, 11406482]), + Y: FieldElement2625([0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), + Z: FieldElement2625([1, 0, 0, 0, 0, 0, 0, 0, 0, 0]), + T: FieldElement2625([0, 0, 0, 0, 0, 0, 0, 0, 0, 0]) }, EdwardsPoint{ - X: FieldElement32([45756067, 28208718, 62448683, 8347856, 42965774, 18986308, 36923107, 12247769, 33528939, 25209113]), - Y: FieldElement32([6952903, 1265500, 60246523, 7057497, 4037696, 5447722, 35427965, 15325401, 19365852, 31985330]), - Z: FieldElement32([1, 0, 0, 0, 0, 0, 0, 0, 0, 0]), - T: FieldElement32([25262188, 11972680, 55392862, 5869611, 18193162, 17256693, 46438198, 8559097, 63567321, 5011180]) + X: FieldElement2625([45756067, 28208718, 62448683, 8347856, 42965774, 18986308, 36923107, 12247769, 33528939, 25209113]), + Y: FieldElement2625([6952903, 1265500, 60246523, 7057497, 4037696, 5447722, 35427965, 15325401, 19365852, 31985330]), + Z: FieldElement2625([1, 0, 0, 0, 0, 0, 0, 0, 0, 0]), + T: FieldElement2625([25262188, 11972680, 55392862, 5869611, 18193162, 17256693, 46438198, 8559097, 63567321, 5011180]) }, ]; diff --git a/src/backend/u32/field.rs b/src/backend/u32/field.rs index 5f2fe1d..8a7ca72 100644 --- a/src/backend/u32/field.rs +++ b/src/backend/u32/field.rs @@ -24,7 +24,7 @@ use core::ops::{Sub, SubAssign}; use subtle::Choice; use subtle::ConditionallySelectable; -/// A `FieldElement32` represents an element of the field +/// A `FieldElement2625` represents an element of the field /// \\( \mathbb Z / (2\^{255} - 19)\\). /// /// In the 32-bit implementation, a `FieldElement` is represented in @@ -41,44 +41,44 @@ use subtle::ConditionallySelectable; /// # Note /// /// The `curve25519_dalek::field` module provides a type alias -/// `curve25519_dalek::field::FieldElement` to either `FieldElement64` -/// or `FieldElement32`. +/// `curve25519_dalek::field::FieldElement` to either `FieldElement51` +/// or `FieldElement2625`. /// -/// The backend-specific type `FieldElement32` should not be used +/// The backend-specific type `FieldElement2625` should not be used /// outside of the `curve25519_dalek::field` module. #[derive(Copy, Clone)] -pub struct FieldElement32(pub (crate) [u32; 10]); +pub struct FieldElement2625(pub (crate) [u32; 10]); -impl Debug for FieldElement32 { +impl Debug for FieldElement2625 { fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - write!(f, "FieldElement32({:?})", &self.0[..]) + write!(f, "FieldElement2625({:?})", &self.0[..]) } } -impl<'b> AddAssign<&'b FieldElement32> for FieldElement32 { - fn add_assign(&mut self, _rhs: &'b FieldElement32) { +impl<'b> AddAssign<&'b FieldElement2625> for FieldElement2625 { + fn add_assign(&mut self, _rhs: &'b FieldElement2625) { for i in 0..10 { self.0[i] += _rhs.0[i]; } } } -impl<'a, 'b> Add<&'b FieldElement32> for &'a FieldElement32 { - type Output = FieldElement32; - fn add(self, _rhs: &'b FieldElement32) -> FieldElement32 { +impl<'a, 'b> Add<&'b FieldElement2625> for &'a FieldElement2625 { + type Output = FieldElement2625; + fn add(self, _rhs: &'b FieldElement2625) -> FieldElement2625 { let mut output = *self; output += _rhs; output } } -impl<'b> SubAssign<&'b FieldElement32> for FieldElement32 { - fn sub_assign(&mut self, _rhs: &'b FieldElement32) { - // See comment in FieldElement64::Sub +impl<'b> SubAssign<&'b FieldElement2625> for FieldElement2625 { + fn sub_assign(&mut self, _rhs: &'b FieldElement2625) { + // See comment in FieldElement51::Sub // // Compute a - b as ((a + 2^4 * p) - b) to avoid underflow. let b = &_rhs.0; - self.0 = FieldElement32::reduce([ + self.0 = FieldElement2625::reduce([ ((self.0[0] + (0x3ffffed << 4)) - b[0]) as u64, ((self.0[1] + (0x1ffffff << 4)) - b[1]) as u64, ((self.0[2] + (0x3ffffff << 4)) - b[2]) as u64, @@ -93,25 +93,25 @@ impl<'b> SubAssign<&'b FieldElement32> for FieldElement32 { } } -impl<'a, 'b> Sub<&'b FieldElement32> for &'a FieldElement32 { - type Output = FieldElement32; - fn sub(self, _rhs: &'b FieldElement32) -> FieldElement32 { +impl<'a, 'b> Sub<&'b FieldElement2625> for &'a FieldElement2625 { + type Output = FieldElement2625; + fn sub(self, _rhs: &'b FieldElement2625) -> FieldElement2625 { let mut output = *self; output -= _rhs; output } } -impl<'b> MulAssign<&'b FieldElement32> for FieldElement32 { - fn mul_assign(&mut self, _rhs: &'b FieldElement32) { - let result = (self as &FieldElement32) * _rhs; +impl<'b> MulAssign<&'b FieldElement2625> for FieldElement2625 { + fn mul_assign(&mut self, _rhs: &'b FieldElement2625) { + let result = (self as &FieldElement2625) * _rhs; self.0 = result.0; } } -impl<'a, 'b> Mul<&'b FieldElement32> for &'a FieldElement32 { - type Output = FieldElement32; - fn mul(self, _rhs: &'b FieldElement32) -> FieldElement32 { +impl<'a, 'b> Mul<&'b FieldElement2625> for &'a FieldElement2625 { + type Output = FieldElement2625; + fn mul(self, _rhs: &'b FieldElement2625) -> FieldElement2625 { /// Helper function to multiply two 32-bit integers with 64 bits /// of output. #[inline(always)] @@ -206,26 +206,26 @@ impl<'a, 'b> Mul<&'b FieldElement32> for &'a FieldElement32 { // // So z[0] fits into a u64 if 51 + 2*b + lg(249) < 64 // if b < 2.5. - FieldElement32::reduce([z0, z1, z2, z3, z4, z5, z6, z7, z8, z9]) + FieldElement2625::reduce([z0, z1, z2, z3, z4, z5, z6, z7, z8, z9]) } } -impl<'a> Neg for &'a FieldElement32 { - type Output = FieldElement32; - fn neg(self) -> FieldElement32 { +impl<'a> Neg for &'a FieldElement2625 { + type Output = FieldElement2625; + fn neg(self) -> FieldElement2625 { let mut output = *self; output.negate(); output } } -impl ConditionallySelectable for FieldElement32 { +impl ConditionallySelectable for FieldElement2625 { fn conditional_select( - a: &FieldElement32, - b: &FieldElement32, + a: &FieldElement2625, + b: &FieldElement2625, choice: Choice, - ) -> FieldElement32 { - FieldElement32([ + ) -> FieldElement2625 { + FieldElement2625([ u32::conditional_select(&a.0[0], &b.0[0], choice), u32::conditional_select(&a.0[1], &b.0[1], choice), u32::conditional_select(&a.0[2], &b.0[2], choice), @@ -239,7 +239,7 @@ impl ConditionallySelectable for FieldElement32 { ]) } - fn conditional_assign(&mut self, other: &FieldElement32, choice: Choice) { + fn conditional_assign(&mut self, other: &FieldElement2625, choice: Choice) { self.0[0].conditional_assign(&other.0[0], choice); self.0[1].conditional_assign(&other.0[1], choice); self.0[2].conditional_assign(&other.0[2], choice); @@ -252,7 +252,7 @@ impl ConditionallySelectable for FieldElement32 { self.0[9].conditional_assign(&other.0[9], choice); } - fn conditional_swap(a: &mut FieldElement32, b: &mut FieldElement32, choice: Choice) { + fn conditional_swap(a: &mut FieldElement2625, b: &mut FieldElement2625, choice: Choice) { u32::conditional_swap(&mut a.0[0], &mut b.0[0], choice); u32::conditional_swap(&mut a.0[1], &mut b.0[1], choice); u32::conditional_swap(&mut a.0[2], &mut b.0[2], choice); @@ -266,11 +266,11 @@ impl ConditionallySelectable for FieldElement32 { } } -impl FieldElement32 { +impl FieldElement2625 { /// Invert the sign of this field element pub fn negate(&mut self) { // Compute -b as ((2^4 * p) - b) to avoid underflow. - let neg = FieldElement32::reduce([ + let neg = FieldElement2625::reduce([ ((0x3ffffed << 4) - self.0[0]) as u64, ((0x1ffffff << 4) - self.0[1]) as u64, ((0x3ffffff << 4) - self.0[2]) as u64, @@ -286,25 +286,25 @@ impl FieldElement32 { } /// Construct zero. - pub fn zero() -> FieldElement32 { - FieldElement32([ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]) + pub fn zero() -> FieldElement2625 { + FieldElement2625([ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]) } /// Construct one. - pub fn one() -> FieldElement32 { - FieldElement32([ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]) + pub fn one() -> FieldElement2625 { + FieldElement2625([ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]) } /// Construct -1. - pub fn minus_one() -> FieldElement32 { - FieldElement32([ + pub fn minus_one() -> FieldElement2625 { + FieldElement2625([ 0x3ffffec, 0x1ffffff, 0x3ffffff, 0x1ffffff, 0x3ffffff, 0x1ffffff, 0x3ffffff, 0x1ffffff, 0x3ffffff, 0x1ffffff, ]) } /// Given `k > 0`, return `self^(2^k)`. - pub fn pow2k(&self, k: u32) -> FieldElement32 { + pub fn pow2k(&self, k: u32) -> FieldElement2625 { debug_assert!( k > 0 ); let mut z = self.square(); for _ in 1..k { @@ -314,12 +314,12 @@ impl FieldElement32 { } /// Given unreduced coefficients `z[0], ..., z[9]` of any size, - /// carry and reduce them mod p to obtain a `FieldElement32` + /// carry and reduce them mod p to obtain a `FieldElement2625` /// whose coefficients have excess `b < 0.007`. /// /// In other words, each coefficient of the result is bounded by /// either `2^(25 + 0.007)` or `2^(26 + 0.007)`, as appropriate. - fn reduce(mut z: [u64; 10]) -> FieldElement32 { + fn reduce(mut z: [u64; 10]) -> FieldElement2625 { const LOW_25_BITS: u64 = (1 << 25) - 1; const LOW_26_BITS: u64 = (1 << 26) - 1; @@ -361,13 +361,13 @@ impl FieldElement32 { // < 2^25.007 (good enough) // and we're done. - FieldElement32([ + FieldElement2625([ z[0] as u32, z[1] as u32, z[2] as u32, z[3] as u32, z[4] as u32, z[5] as u32, z[6] as u32, z[7] as u32, z[8] as u32, z[9] as u32, ]) } - /// Load a `FieldElement64` from the low 255 bits of a 256-bit + /// Load a `FieldElement51` from the low 255 bits of a 256-bit /// input. /// /// # Warning @@ -378,7 +378,7 @@ impl FieldElement32 { /// encoding of every field element should decode, re-encode to /// the canonical encoding, and check that the input was /// canonical. - pub fn from_bytes(data: &[u8; 32]) -> FieldElement32 { //FeFromBytes + pub fn from_bytes(data: &[u8; 32]) -> FieldElement2625 { //FeFromBytes #[inline] fn load3(b: &[u8]) -> u64 { (b[0] as u64) | ((b[1] as u64) << 8) | ((b[2] as u64) << 16) @@ -402,16 +402,16 @@ impl FieldElement32 { h[8] = load3(&data[26..]) << 4; h[9] = (load3(&data[29..]) & LOW_23_BITS) << 2; - FieldElement32::reduce(h) + FieldElement2625::reduce(h) } - /// Serialize this `FieldElement64` to a 32-byte array. The + /// Serialize this `FieldElement51` to a 32-byte array. The /// encoding is canonical. pub fn to_bytes(&self) -> [u8; 32] { let inp = &self.0; // Reduce the value represented by `in` to the range [0,2*p) - let mut h: [u32; 10] = FieldElement32::reduce([ + let mut h: [u32; 10] = FieldElement2625::reduce([ // XXX this cast is annoying inp[0] as u64, inp[1] as u64, inp[2] as u64, inp[3] as u64, inp[4] as u64, inp[5] as u64, inp[6] as u64, inp[7] as u64, inp[8] as u64, inp[9] as u64, @@ -554,16 +554,16 @@ impl FieldElement32 { } /// Compute `self^2`. - pub fn square(&self) -> FieldElement32 { - FieldElement32::reduce(self.square_inner()) + pub fn square(&self) -> FieldElement2625 { + FieldElement2625::reduce(self.square_inner()) } /// Compute `2*self^2`. - pub fn square2(&self) -> FieldElement32 { + pub fn square2(&self) -> FieldElement2625 { let mut coeffs = self.square_inner(); for i in 0..self.0.len() { coeffs[i] += coeffs[i]; } - FieldElement32::reduce(coeffs) + FieldElement2625::reduce(coeffs) } } diff --git a/src/backend/u32/scalar.rs b/src/backend/u32/scalar.rs index 6c3bb51..8dce8a3 100644 --- a/src/backend/u32/scalar.rs +++ b/src/backend/u32/scalar.rs @@ -15,24 +15,24 @@ use core::ops::{Index, IndexMut}; use constants; -/// The `Scalar32` struct represents an element in ℤ/lℤ as 9 29-bit limbs +/// The `Scalar29` struct represents an element in ℤ/lℤ as 9 29-bit limbs #[derive(Copy,Clone)] -pub struct Scalar32(pub [u32; 9]); +pub struct Scalar29(pub [u32; 9]); -impl Debug for Scalar32 { +impl Debug for Scalar29 { fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - write!(f, "Scalar32: {:?}", &self.0[..]) + write!(f, "Scalar29: {:?}", &self.0[..]) } } -impl Index for Scalar32 { +impl Index for Scalar29 { type Output = u32; fn index(&self, _index: usize) -> &u32 { &(self.0[_index]) } } -impl IndexMut for Scalar32 { +impl IndexMut for Scalar29 { fn index_mut(&mut self, _index: usize) -> &mut u32 { &mut (self.0[_index]) } @@ -44,14 +44,14 @@ fn m(x: u32, y: u32) -> u64 { (x as u64) * (y as u64) } -impl Scalar32 { +impl Scalar29 { /// Return the zero scalar. - pub fn zero() -> Scalar32 { - Scalar32([0,0,0,0,0,0,0,0,0]) + pub fn zero() -> Scalar29 { + Scalar29([0,0,0,0,0,0,0,0,0]) } /// Unpack a 32 byte / 256 bit scalar into 9 29-bit limbs. - pub fn from_bytes(bytes: &[u8; 32]) -> Scalar32 { + pub fn from_bytes(bytes: &[u8; 32]) -> Scalar29 { let mut words = [0u32; 8]; for i in 0..8 { for j in 0..4 { @@ -61,7 +61,7 @@ impl Scalar32 { let mask = (1u32 << 29) - 1; let top_mask = (1u32 << 24) - 1; - let mut s = Scalar32::zero(); + let mut s = Scalar29::zero(); s[ 0] = words[0] & mask; s[ 1] = ((words[0] >> 29) | (words[1] << 3)) & mask; @@ -77,7 +77,7 @@ impl Scalar32 { } /// Reduce a 64 byte / 512 bit scalar mod l. - pub fn from_bytes_wide(bytes: &[u8; 64]) -> Scalar32 { + pub fn from_bytes_wide(bytes: &[u8; 64]) -> Scalar29 { let mut words = [0u32; 16]; for i in 0..16 { for j in 0..4 { @@ -86,8 +86,8 @@ impl Scalar32 { } let mask = (1u32 << 29) - 1; - let mut lo = Scalar32::zero(); - let mut hi = Scalar32::zero(); + let mut lo = Scalar29::zero(); + let mut hi = Scalar29::zero(); lo[0] = words[ 0] & mask; lo[1] = ((words[ 0] >> 29) | (words[ 1] << 3)) & mask; @@ -108,13 +108,13 @@ impl Scalar32 { hi[7] = ((words[14] >> 16) | (words[15] << 16)) & mask; hi[8] = words[15] >> 13 ; - lo = Scalar32::montgomery_mul(&lo, &constants::R); // (lo * R) / R = lo - hi = Scalar32::montgomery_mul(&hi, &constants::RR); // (hi * R^2) / R = hi * R + lo = Scalar29::montgomery_mul(&lo, &constants::R); // (lo * R) / R = lo + hi = Scalar29::montgomery_mul(&hi, &constants::RR); // (hi * R^2) / R = hi * R - Scalar32::add(&hi, &lo) // (hi * R) + lo + Scalar29::add(&hi, &lo) // (hi * R) + lo } - /// Pack the limbs of this `Scalar32` into 32 bytes. + /// Pack the limbs of this `Scalar29` into 32 bytes. pub fn to_bytes(&self) -> [u8; 32] { let mut s = [0u8; 32]; @@ -155,8 +155,8 @@ impl Scalar32 { } /// Compute `a + b` (mod l). - pub fn add(a: &Scalar32, b: &Scalar32) -> Scalar32 { - let mut sum = Scalar32::zero(); + pub fn add(a: &Scalar29, b: &Scalar29) -> Scalar29 { + let mut sum = Scalar29::zero(); let mask = (1u32 << 29) - 1; // a + b @@ -167,12 +167,12 @@ impl Scalar32 { } // subtract l if the sum is >= l - Scalar32::sub(&sum, &constants::L) + Scalar29::sub(&sum, &constants::L) } /// Compute `a - b` (mod l). - pub fn sub(a: &Scalar32, b: &Scalar32) -> Scalar32 { - let mut difference = Scalar32::zero(); + pub fn sub(a: &Scalar29, b: &Scalar29) -> Scalar29 { + let mut difference = Scalar29::zero(); let mask = (1u32 << 29) - 1; // a - b @@ -197,7 +197,7 @@ impl Scalar32 { /// /// This is implemented with a one-level refined Karatsuba decomposition #[inline(always)] - pub (crate) fn mul_internal(a: &Scalar32, b: &Scalar32) -> [u64; 17] { + pub (crate) fn mul_internal(a: &Scalar29, b: &Scalar29) -> [u64; 17] { let mut z = [0u64; 17]; z[0] = m(a[0],b[0]); // c00 @@ -254,7 +254,7 @@ impl Scalar32 { /// Compute `a^2`. #[inline(always)] - fn square_internal(a: &Scalar32) -> [u64; 17] { + fn square_internal(a: &Scalar29) -> [u64; 17] { let aa = [ a[0]*2, a[1]*2, @@ -289,7 +289,7 @@ impl Scalar32 { /// Compute `limbs/R` (mod l), where R is the Montgomery modulus 2^261 #[inline(always)] - pub (crate) fn montgomery_reduce(limbs: &[u64; 17]) -> Scalar32 { + pub (crate) fn montgomery_reduce(limbs: &[u64; 17]) -> Scalar29 { #[inline(always)] fn part1(sum: u64) -> (u64, u32) { @@ -329,49 +329,49 @@ impl Scalar32 { let r8 = carry as u32; // result may be >= l, so attempt to subtract l - Scalar32::sub(&Scalar32([r0,r1,r2,r3,r4,r5,r6,r7,r8]), l) + Scalar29::sub(&Scalar29([r0,r1,r2,r3,r4,r5,r6,r7,r8]), l) } /// Compute `a * b` (mod l). #[inline(never)] - pub fn mul(a: &Scalar32, b: &Scalar32) -> Scalar32 { - let ab = Scalar32::montgomery_reduce(&Scalar32::mul_internal(a, b)); - Scalar32::montgomery_reduce(&Scalar32::mul_internal(&ab, &constants::RR)) + pub fn mul(a: &Scalar29, b: &Scalar29) -> Scalar29 { + let ab = Scalar29::montgomery_reduce(&Scalar29::mul_internal(a, b)); + Scalar29::montgomery_reduce(&Scalar29::mul_internal(&ab, &constants::RR)) } /// Compute `a^2` (mod l). #[inline(never)] #[allow(dead_code)] // XXX we don't expose square() via the Scalar API - pub fn square(&self) -> Scalar32 { - let aa = Scalar32::montgomery_reduce(&Scalar32::square_internal(self)); - Scalar32::montgomery_reduce(&Scalar32::mul_internal(&aa, &constants::RR)) + pub fn square(&self) -> Scalar29 { + let aa = Scalar29::montgomery_reduce(&Scalar29::square_internal(self)); + Scalar29::montgomery_reduce(&Scalar29::mul_internal(&aa, &constants::RR)) } /// Compute `(a * b) / R` (mod l), where R is the Montgomery modulus 2^261 #[inline(never)] - pub fn montgomery_mul(a: &Scalar32, b: &Scalar32) -> Scalar32 { - Scalar32::montgomery_reduce(&Scalar32::mul_internal(a, b)) + pub fn montgomery_mul(a: &Scalar29, b: &Scalar29) -> Scalar29 { + Scalar29::montgomery_reduce(&Scalar29::mul_internal(a, b)) } /// Compute `(a^2) / R` (mod l) in Montgomery form, where R is the Montgomery modulus 2^261 #[inline(never)] - pub fn montgomery_square(&self) -> Scalar32 { - Scalar32::montgomery_reduce(&Scalar32::square_internal(self)) + pub fn montgomery_square(&self) -> Scalar29 { + Scalar29::montgomery_reduce(&Scalar29::square_internal(self)) } - /// Puts a Scalar32 in to Montgomery form, i.e. computes `a*R (mod l)` + /// Puts a Scalar29 in to Montgomery form, i.e. computes `a*R (mod l)` #[inline(never)] - pub fn to_montgomery(&self) -> Scalar32 { - Scalar32::montgomery_mul(self, &constants::RR) + pub fn to_montgomery(&self) -> Scalar29 { + Scalar29::montgomery_mul(self, &constants::RR) } - /// Takes a Scalar32 out of Montgomery form, i.e. computes `a/R (mod l)` - pub fn from_montgomery(&self) -> Scalar32 { + /// Takes a Scalar29 out of Montgomery form, i.e. computes `a/R (mod l)` + pub fn from_montgomery(&self) -> Scalar29 { let mut limbs = [0u64; 17]; for i in 0..9 { limbs[i] = self[i] as u64; } - Scalar32::montgomery_reduce(&limbs) + Scalar29::montgomery_reduce(&limbs) } } @@ -385,69 +385,69 @@ mod test { /// x = 2^253-1 = 14474011154664524427946373126085988481658748083205070504932198000989141204991 /// x = 7237005577332262213973186563042994240801631723825162898930247062703686954002 mod l /// x = 5147078182513738803124273553712992179887200054963030844803268920753008712037*R mod l in Montgomery form - pub static X: Scalar32 = Scalar32( + pub static X: Scalar29 = Scalar29( [0x1fffffff, 0x1fffffff, 0x1fffffff, 0x1fffffff, 0x1fffffff, 0x1fffffff, 0x1fffffff, 0x1fffffff, 0x001fffff]); /// x^2 = 3078544782642840487852506753550082162405942681916160040940637093560259278169 mod l - pub static XX: Scalar32 = Scalar32( + pub static XX: Scalar29 = Scalar29( [0x00217559, 0x000b3401, 0x103ff43b, 0x1462a62c, 0x1d6f9f38, 0x18e7a42f, 0x09a3dcee, 0x008dbe18, 0x0006ce65]); /// x^2 = 2912514428060642753613814151688322857484807845836623976981729207238463947987*R mod l in Montgomery form - pub static XX_MONT: Scalar32 = Scalar32( + pub static XX_MONT: Scalar29 = Scalar29( [0x152b4d2e, 0x0571d53b, 0x1da6d964, 0x188663b6, 0x1d1b5f92, 0x19d50e3f, 0x12306c29, 0x0c6f26fe, 0x00030edb]); /// y = 6145104759870991071742105800796537629880401874866217824609283457819451087098 - pub static Y: Scalar32 = Scalar32( + pub static Y: Scalar29 = Scalar29( [0x1e1458fa, 0x165ba838, 0x1d787b36, 0x0e577f3a, 0x1d2baf06, 0x1d689a19, 0x1fff3047, 0x117704ab, 0x000d9601]); /// x*y = 36752150652102274958925982391442301741 - pub static XY: Scalar32 = Scalar32( + pub static XY: Scalar29 = Scalar29( [0x0ba7632d, 0x017736bb, 0x15c76138, 0x0c69daa1, 0x000001ba, 0x00000000, 0x00000000, 0x00000000, 0x00000000]); /// x*y = 3783114862749659543382438697751927473898937741870308063443170013240655651591*R mod l in Montgomery form - pub static XY_MONT: Scalar32 = Scalar32( + pub static XY_MONT: Scalar29 = Scalar29( [0x077b51e1, 0x1c64e119, 0x02a19ef5, 0x18d2129e, 0x00de0430, 0x045a7bc8, 0x04cfc7c9, 0x1c002681, 0x000bdc1c]); /// a = 2351415481556538453565687241199399922945659411799870114962672658845158063753 - pub static A: Scalar32 = Scalar32( + pub static A: Scalar29 = Scalar29( [0x07b3be89, 0x02291b60, 0x14a99f03, 0x07dc3787, 0x0a782aae, 0x16262525, 0x0cfdb93f, 0x13f5718d, 0x000532da]); /// b = 4885590095775723760407499321843594317911456947580037491039278279440296187236 - pub static B: Scalar32 = Scalar32( + pub static B: Scalar29 = Scalar29( [0x15421564, 0x1e69fd72, 0x093d9692, 0x161785be, 0x1587d69f, 0x09d9dada, 0x130246c0, 0x0c0a8e72, 0x000acd25]); /// a+b = 0 /// a-b = 4702830963113076907131374482398799845891318823599740229925345317690316127506 - pub static AB: Scalar32 = Scalar32( + pub static AB: Scalar29 = Scalar29( [0x0f677d12, 0x045236c0, 0x09533e06, 0x0fb86f0f, 0x14f0555c, 0x0c4c4a4a, 0x19fb727f, 0x07eae31a, 0x000a65b5]); // c = (2^512 - 1) % l = 1627715501170711445284395025044413883736156588369414752970002579683115011840 - pub static C: Scalar32 = Scalar32( + pub static C: Scalar29 = Scalar29( [0x049c0f00, 0x00308f1a, 0x0164d1e9, 0x1c374ed1, 0x1be65d00, 0x19e90bfa, 0x08f73bb1, 0x036f8613, 0x00039941]); #[test] fn mul_max() { - let res = Scalar32::mul(&X, &X); + let res = Scalar29::mul(&X, &X); for i in 0..9 { assert!(res[i] == XX[i]); } @@ -463,7 +463,7 @@ mod test { #[test] fn montgomery_mul_max() { - let res = Scalar32::montgomery_mul(&X, &X); + let res = Scalar29::montgomery_mul(&X, &X); for i in 0..9 { assert!(res[i] == XX_MONT[i]); } @@ -479,7 +479,7 @@ mod test { #[test] fn mul() { - let res = Scalar32::mul(&X, &Y); + let res = Scalar29::mul(&X, &Y); for i in 0..9 { assert!(res[i] == XY[i]); } @@ -487,7 +487,7 @@ mod test { #[test] fn montgomery_mul() { - let res = Scalar32::montgomery_mul(&X, &Y); + let res = Scalar29::montgomery_mul(&X, &Y); for i in 0..9 { assert!(res[i] == XY_MONT[i]); } @@ -495,8 +495,8 @@ mod test { #[test] fn add() { - let res = Scalar32::add(&A, &B); - let zero = Scalar32::zero(); + let res = Scalar29::add(&A, &B); + let zero = Scalar29::zero(); for i in 0..9 { assert!(res[i] == zero[i]); } @@ -504,7 +504,7 @@ mod test { #[test] fn sub() { - let res = Scalar32::sub(&A, &B); + let res = Scalar29::sub(&A, &B); for i in 0..9 { assert!(res[i] == AB[i]); } @@ -513,7 +513,7 @@ mod test { #[test] fn from_bytes_wide() { let bignum = [255u8; 64]; // 2^512 - 1 - let reduced = Scalar32::from_bytes_wide(&bignum); + let reduced = Scalar29::from_bytes_wide(&bignum); for i in 0..9 { assert!(reduced[i] == C[i]); } diff --git a/src/backend/u64/constants.rs b/src/backend/u64/constants.rs index 0ac7fe3..11c86b2 100644 --- a/src/backend/u64/constants.rs +++ b/src/backend/u64/constants.rs @@ -10,43 +10,43 @@ //! This module contains backend-specific constant values, such as the 64-bit limbs of curve constants. -use backend::u64::field::FieldElement64; -use backend::u64::scalar::Scalar64; +use backend::u64::field::FieldElement51; +use backend::u64::scalar::Scalar52; use edwards::EdwardsPoint; /// Edwards `d` value, equal to `-121665/121666 mod p`. -pub(crate) const EDWARDS_D: FieldElement64 = FieldElement64([929955233495203, 466365720129213, 1662059464998953, 2033849074728123, 1442794654840575]); +pub(crate) const EDWARDS_D: FieldElement51 = FieldElement51([929955233495203, 466365720129213, 1662059464998953, 2033849074728123, 1442794654840575]); /// Edwards `2*d` value, equal to `2*(-121665/121666) mod p`. -pub(crate) const EDWARDS_D2: FieldElement64 = FieldElement64([1859910466990425, 932731440258426, 1072319116312658, 1815898335770999, 633789495995903]); +pub(crate) const EDWARDS_D2: FieldElement51 = FieldElement51([1859910466990425, 932731440258426, 1072319116312658, 1815898335770999, 633789495995903]); /// `= sqrt(a*d - 1)`, where `a = -1 (mod p)`, `d` are the Edwards curve parameters. -pub(crate) const SQRT_AD_MINUS_ONE: FieldElement64 = FieldElement64([ +pub(crate) const SQRT_AD_MINUS_ONE: FieldElement51 = FieldElement51([ 2241493124984347, 425987919032274, 2207028919301688, 1220490630685848, 974799131293748 ]); /// `= 1/sqrt(a-d)`, where `a = -1 (mod p)`, `d` are the Edwards curve parameters. -pub(crate) const INVSQRT_A_MINUS_D: FieldElement64 = FieldElement64([ +pub(crate) const INVSQRT_A_MINUS_D: FieldElement51 = FieldElement51([ 278908739862762, 821645201101625, 8113234426968, 1777959178193151, 2118520810568447 ]); /// Precomputed value of one of the square roots of -1 (mod p) -pub(crate) const SQRT_M1: FieldElement64 = FieldElement64([1718705420411056, 234908883556509, 2233514472574048, 2117202627021982, 765476049583133]); +pub(crate) const SQRT_M1: FieldElement51 = FieldElement51([1718705420411056, 234908883556509, 2233514472574048, 2117202627021982, 765476049583133]); /// `APLUS2_OVER_FOUR` is (A+2)/4. (This is used internally within the Montgomery ladder.) -pub(crate) const APLUS2_OVER_FOUR: FieldElement64 = FieldElement64([121666, 0, 0, 0, 0]); +pub(crate) const APLUS2_OVER_FOUR: FieldElement51 = FieldElement51([121666, 0, 0, 0, 0]); /// `L` is the order of base point, i.e. 2^252 + 27742317777372353535851937790883648493 -pub(crate) const L: Scalar64 = Scalar64([ 0x0002631a5cf5d3ed, 0x000dea2f79cd6581, 0x000000000014def9, 0x0000000000000000, 0x0000100000000000 ]); +pub(crate) const L: Scalar52 = Scalar52([ 0x0002631a5cf5d3ed, 0x000dea2f79cd6581, 0x000000000014def9, 0x0000000000000000, 0x0000100000000000 ]); /// `L` * `LFACTOR` = -1 (mod 2^52) pub(crate) const LFACTOR: u64 = 0x51da312547e1b; /// `R` = R % L where R = 2^260 -pub(crate) const R: Scalar64 = Scalar64([ 0x000f48bd6721e6ed, 0x0003bab5ac67e45a, 0x000fffffeb35e51b, 0x000fffffffffffff, 0x00000fffffffffff ]); +pub(crate) const R: Scalar52 = Scalar52([ 0x000f48bd6721e6ed, 0x0003bab5ac67e45a, 0x000fffffeb35e51b, 0x000fffffffffffff, 0x00000fffffffffff ]); /// `RR` = (R^2) % L where R = 2^260 -pub(crate) const RR: Scalar64 = Scalar64([ 0x0009d265e952d13b, 0x000d63c715bea69f, 0x0005be65cb687604, 0x0003dceec73d217f, 0x000009411b7c309a ]); +pub(crate) const RR: Scalar52 = Scalar52([ 0x0009d265e952d13b, 0x000d63c715bea69f, 0x0005be65cb687604, 0x0003dceec73d217f, 0x000009411b7c309a ]); /// The Ed25519 basepoint, as an `EdwardsPoint`. /// @@ -54,10 +54,10 @@ pub(crate) const RR: Scalar64 = Scalar64([ 0x0009d265e952d13b, 0x000d63c715bea69 /// `ED25519_BASEPOINT_TABLE`, which should be used for scalar /// multiplication (it's much faster). pub const ED25519_BASEPOINT_POINT: EdwardsPoint = EdwardsPoint{ - X: FieldElement64([1738742601995546, 1146398526822698, 2070867633025821, 562264141797630, 587772402128613]), - Y: FieldElement64([1801439850948184, 1351079888211148, 450359962737049, 900719925474099, 1801439850948198]), - Z: FieldElement64([1, 0, 0, 0, 0]), - T: FieldElement64([1841354044333475, 16398895984059, 755974180946558, 900171276175154, 1821297809914039]), + X: FieldElement51([1738742601995546, 1146398526822698, 2070867633025821, 562264141797630, 587772402128613]), + Y: FieldElement51([1801439850948184, 1351079888211148, 450359962737049, 900719925474099, 1801439850948198]), + Z: FieldElement51([1, 0, 0, 0, 0]), + T: FieldElement51([1841354044333475, 16398895984059, 755974180946558, 900171276175154, 1821297809914039]), }; /// The 8-torsion subgroup \\(\mathcal E [8]\\). @@ -74,58 +74,58 @@ pub const EIGHT_TORSION: [EdwardsPoint; 8] = EIGHT_TORSION_INNER_DOC_HIDDEN; #[doc(hidden)] pub const EIGHT_TORSION_INNER_DOC_HIDDEN: [EdwardsPoint; 8] = [ EdwardsPoint { - X: FieldElement64([0, 0, 0, 0, 0]), - Y: FieldElement64([1, 0, 0, 0, 0]), - Z: FieldElement64([1, 0, 0, 0, 0]), - T: FieldElement64([0, 0, 0, 0, 0]), + X: FieldElement51([0, 0, 0, 0, 0]), + Y: FieldElement51([1, 0, 0, 0, 0]), + Z: FieldElement51([1, 0, 0, 0, 0]), + T: FieldElement51([0, 0, 0, 0, 0]), } , EdwardsPoint { - X: FieldElement64([358744748052810, 1691584618240980, 977650209285361, 1429865912637724, 560044844278676]), - Y: FieldElement64([84926274344903, 473620666599931, 365590438845504, 1028470286882429, 2146499180330972]), - Z: FieldElement64([1, 0, 0, 0, 0]), - T: FieldElement64([1448326834587521, 1857896831960481, 1093722731865333, 1677408490711241, 1915505153018406]), + X: FieldElement51([358744748052810, 1691584618240980, 977650209285361, 1429865912637724, 560044844278676]), + Y: FieldElement51([84926274344903, 473620666599931, 365590438845504, 1028470286882429, 2146499180330972]), + Z: FieldElement51([1, 0, 0, 0, 0]), + T: FieldElement51([1448326834587521, 1857896831960481, 1093722731865333, 1677408490711241, 1915505153018406]), } , EdwardsPoint { - X: FieldElement64([533094393274173, 2016890930128738, 18285341111199, 134597186663265, 1486323764102114]), - Y: FieldElement64([0, 0, 0, 0, 0]), - Z: FieldElement64([1, 0, 0, 0, 0]), - T: FieldElement64([0, 0, 0, 0, 0]), + X: FieldElement51([533094393274173, 2016890930128738, 18285341111199, 134597186663265, 1486323764102114]), + Y: FieldElement51([0, 0, 0, 0, 0]), + Z: FieldElement51([1, 0, 0, 0, 0]), + T: FieldElement51([0, 0, 0, 0, 0]), } , EdwardsPoint { - X: FieldElement64([358744748052810, 1691584618240980, 977650209285361, 1429865912637724, 560044844278676]), - Y: FieldElement64([2166873539340326, 1778179147085316, 1886209374839743, 1223329526802818, 105300633354275]), - Z: FieldElement64([1, 0, 0, 0, 0]), - T: FieldElement64([803472979097708, 393902981724766, 1158077081819914, 574391322974006, 336294660666841]), + X: FieldElement51([358744748052810, 1691584618240980, 977650209285361, 1429865912637724, 560044844278676]), + Y: FieldElement51([2166873539340326, 1778179147085316, 1886209374839743, 1223329526802818, 105300633354275]), + Z: FieldElement51([1, 0, 0, 0, 0]), + T: FieldElement51([803472979097708, 393902981724766, 1158077081819914, 574391322974006, 336294660666841]), } , EdwardsPoint { - X: FieldElement64([0, 0, 0, 0, 0]), - Y: FieldElement64([2251799813685228, 2251799813685247, 2251799813685247, 2251799813685247, 2251799813685247]), - Z: FieldElement64([1, 0, 0, 0, 0]), - T: FieldElement64([0, 0, 0, 0, 0]), + X: FieldElement51([0, 0, 0, 0, 0]), + Y: FieldElement51([2251799813685228, 2251799813685247, 2251799813685247, 2251799813685247, 2251799813685247]), + Z: FieldElement51([1, 0, 0, 0, 0]), + T: FieldElement51([0, 0, 0, 0, 0]), } , EdwardsPoint { - X: FieldElement64([1893055065632419, 560215195444267, 1274149604399886, 821933901047523, 1691754969406571]), - Y: FieldElement64([2166873539340326, 1778179147085316, 1886209374839743, 1223329526802818, 105300633354275]), - Z: FieldElement64([1, 0, 0, 0, 0]), - T: FieldElement64([1448326834587521, 1857896831960481, 1093722731865333, 1677408490711241, 1915505153018406]), + X: FieldElement51([1893055065632419, 560215195444267, 1274149604399886, 821933901047523, 1691754969406571]), + Y: FieldElement51([2166873539340326, 1778179147085316, 1886209374839743, 1223329526802818, 105300633354275]), + Z: FieldElement51([1, 0, 0, 0, 0]), + T: FieldElement51([1448326834587521, 1857896831960481, 1093722731865333, 1677408490711241, 1915505153018406]), } , EdwardsPoint { - X: FieldElement64([1718705420411056, 234908883556509, 2233514472574048, 2117202627021982, 765476049583133]), - Y: FieldElement64([0, 0, 0, 0, 0]), - Z: FieldElement64([1, 0, 0, 0, 0]), - T: FieldElement64([0, 0, 0, 0, 0]), + X: FieldElement51([1718705420411056, 234908883556509, 2233514472574048, 2117202627021982, 765476049583133]), + Y: FieldElement51([0, 0, 0, 0, 0]), + Z: FieldElement51([1, 0, 0, 0, 0]), + T: FieldElement51([0, 0, 0, 0, 0]), } , EdwardsPoint { - X: FieldElement64([1893055065632419, 560215195444267, 1274149604399886, 821933901047523, 1691754969406571]), - Y: FieldElement64([84926274344903, 473620666599931, 365590438845504, 1028470286882429, 2146499180330972]), - Z: FieldElement64([1, 0, 0, 0, 0]), - T: FieldElement64([803472979097708, 393902981724766, 1158077081819914, 574391322974006, 336294660666841]), + X: FieldElement51([1893055065632419, 560215195444267, 1274149604399886, 821933901047523, 1691754969406571]), + Y: FieldElement51([84926274344903, 473620666599931, 365590438845504, 1028470286882429, 2146499180330972]), + Z: FieldElement51([1, 0, 0, 0, 0]), + T: FieldElement51([803472979097708, 393902981724766, 1158077081819914, 574391322974006, 336294660666841]), } ]; diff --git a/src/backend/u64/field.rs b/src/backend/u64/field.rs index ffe1a48..bdf440c 100644 --- a/src/backend/u64/field.rs +++ b/src/backend/u64/field.rs @@ -20,7 +20,7 @@ use core::ops::{Sub, SubAssign}; use subtle::Choice; use subtle::ConditionallySelectable; -/// A `FieldElement64` represents an element of the field +/// A `FieldElement51` represents an element of the field /// \\( \mathbb Z / (2\^{255} - 19)\\). /// /// In the 64-bit implementation, a `FieldElement` is represented in @@ -30,57 +30,57 @@ use subtle::ConditionallySelectable; /// # Note /// /// The `curve25519_dalek::field` module provides a type alias -/// `curve25519_dalek::field::FieldElement` to either `FieldElement64` -/// or `FieldElement32`. +/// `curve25519_dalek::field::FieldElement` to either `FieldElement51` +/// or `FieldElement2625`. /// -/// The backend-specific type `FieldElement64` should not be used +/// The backend-specific type `FieldElement51` should not be used /// outside of the `curve25519_dalek::field` module. #[derive(Copy, Clone)] -pub struct FieldElement64(pub (crate) [u64; 5]); +pub struct FieldElement51(pub (crate) [u64; 5]); -impl Debug for FieldElement64 { +impl Debug for FieldElement51 { fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - write!(f, "FieldElement64({:?})", &self.0[..]) + write!(f, "FieldElement51({:?})", &self.0[..]) } } -impl<'b> AddAssign<&'b FieldElement64> for FieldElement64 { - fn add_assign(&mut self, _rhs: &'b FieldElement64) { +impl<'b> AddAssign<&'b FieldElement51> for FieldElement51 { + fn add_assign(&mut self, _rhs: &'b FieldElement51) { for i in 0..5 { self.0[i] += _rhs.0[i]; } } } -impl<'a, 'b> Add<&'b FieldElement64> for &'a FieldElement64 { - type Output = FieldElement64; - fn add(self, _rhs: &'b FieldElement64) -> FieldElement64 { +impl<'a, 'b> Add<&'b FieldElement51> for &'a FieldElement51 { + type Output = FieldElement51; + fn add(self, _rhs: &'b FieldElement51) -> FieldElement51 { let mut output = *self; output += _rhs; output } } -impl<'b> SubAssign<&'b FieldElement64> for FieldElement64 { - fn sub_assign(&mut self, _rhs: &'b FieldElement64) { - let result = (self as &FieldElement64) - _rhs; +impl<'b> SubAssign<&'b FieldElement51> for FieldElement51 { + fn sub_assign(&mut self, _rhs: &'b FieldElement51) { + let result = (self as &FieldElement51) - _rhs; self.0 = result.0; } } -impl<'a, 'b> Sub<&'b FieldElement64> for &'a FieldElement64 { - type Output = FieldElement64; - fn sub(self, _rhs: &'b FieldElement64) -> FieldElement64 { +impl<'a, 'b> Sub<&'b FieldElement51> for &'a FieldElement51 { + type Output = FieldElement51; + fn sub(self, _rhs: &'b FieldElement51) -> FieldElement51 { // To avoid underflow, first add a multiple of p. // Choose 16*p = p << 4 to be larger than 54-bit _rhs. // // If we could statically track the bitlengths of the limbs - // of every FieldElement64, we could choose a multiple of p + // of every FieldElement51, we could choose a multiple of p // just bigger than _rhs and avoid having to do a reduction. // // Since we don't yet have type-level integers to do this, we // have to add an explicit reduction call here. - FieldElement64::reduce([ + FieldElement51::reduce([ (self.0[0] + 36028797018963664u64) - _rhs.0[0], (self.0[1] + 36028797018963952u64) - _rhs.0[1], (self.0[2] + 36028797018963952u64) - _rhs.0[2], @@ -90,16 +90,16 @@ impl<'a, 'b> Sub<&'b FieldElement64> for &'a FieldElement64 { } } -impl<'b> MulAssign<&'b FieldElement64> for FieldElement64 { - fn mul_assign(&mut self, _rhs: &'b FieldElement64) { - let result = (self as &FieldElement64) * _rhs; +impl<'b> MulAssign<&'b FieldElement51> for FieldElement51 { + fn mul_assign(&mut self, _rhs: &'b FieldElement51) { + let result = (self as &FieldElement51) * _rhs; self.0 = result.0; } } -impl<'a, 'b> Mul<&'b FieldElement64> for &'a FieldElement64 { - type Output = FieldElement64; - fn mul(self, _rhs: &'b FieldElement64) -> FieldElement64 { +impl<'a, 'b> Mul<&'b FieldElement51> for &'a FieldElement51 { + type Output = FieldElement51; + fn mul(self, _rhs: &'b FieldElement51) -> FieldElement51 { /// Helper function to multiply two 64-bit integers with 128 /// bits of output. #[inline(always)] @@ -196,26 +196,26 @@ impl<'a, 'b> Mul<&'b FieldElement64> for &'a FieldElement64 { out[0] &= LOW_51_BIT_MASK; // Now out[i] < 2^(51 + epsilon) for all i. - FieldElement64(out) + FieldElement51(out) } } -impl<'a> Neg for &'a FieldElement64 { - type Output = FieldElement64; - fn neg(self) -> FieldElement64 { +impl<'a> Neg for &'a FieldElement51 { + type Output = FieldElement51; + fn neg(self) -> FieldElement51 { let mut output = *self; output.negate(); output } } -impl ConditionallySelectable for FieldElement64 { +impl ConditionallySelectable for FieldElement51 { fn conditional_select( - a: &FieldElement64, - b: &FieldElement64, + a: &FieldElement51, + b: &FieldElement51, choice: Choice, - ) -> FieldElement64 { - FieldElement64([ + ) -> FieldElement51 { + FieldElement51([ u64::conditional_select(&a.0[0], &b.0[0], choice), u64::conditional_select(&a.0[1], &b.0[1], choice), u64::conditional_select(&a.0[2], &b.0[2], choice), @@ -224,7 +224,7 @@ impl ConditionallySelectable for FieldElement64 { ]) } - fn conditional_swap(a: &mut FieldElement64, b: &mut FieldElement64, choice: Choice) { + fn conditional_swap(a: &mut FieldElement51, b: &mut FieldElement51, choice: Choice) { u64::conditional_swap(&mut a.0[0], &mut b.0[0], choice); u64::conditional_swap(&mut a.0[1], &mut b.0[1], choice); u64::conditional_swap(&mut a.0[2], &mut b.0[2], choice); @@ -232,7 +232,7 @@ impl ConditionallySelectable for FieldElement64 { u64::conditional_swap(&mut a.0[4], &mut b.0[4], choice); } - fn conditional_assign(&mut self, other: &FieldElement64, choice: Choice) { + fn conditional_assign(&mut self, other: &FieldElement51, choice: Choice) { self.0[0].conditional_assign(&other.0[0], choice); self.0[1].conditional_assign(&other.0[1], choice); self.0[2].conditional_assign(&other.0[2], choice); @@ -241,11 +241,11 @@ impl ConditionallySelectable for FieldElement64 { } } -impl FieldElement64 { +impl FieldElement51 { /// Invert the sign of this field element pub fn negate(&mut self) { // See commentary in the Sub impl - let neg = FieldElement64::reduce([ + let neg = FieldElement51::reduce([ 36028797018963664u64 - self.0[0], 36028797018963952u64 - self.0[1], 36028797018963952u64 - self.0[2], @@ -256,23 +256,23 @@ impl FieldElement64 { } /// Construct zero. - pub fn zero() -> FieldElement64 { - FieldElement64([ 0, 0, 0, 0, 0 ]) + pub fn zero() -> FieldElement51 { + FieldElement51([ 0, 0, 0, 0, 0 ]) } /// Construct one. - pub fn one() -> FieldElement64 { - FieldElement64([ 1, 0, 0, 0, 0 ]) + pub fn one() -> FieldElement51 { + FieldElement51([ 1, 0, 0, 0, 0 ]) } /// Construct -1. - pub fn minus_one() -> FieldElement64 { - FieldElement64([2251799813685228, 2251799813685247, 2251799813685247, 2251799813685247, 2251799813685247]) + pub fn minus_one() -> FieldElement51 { + FieldElement51([2251799813685228, 2251799813685247, 2251799813685247, 2251799813685247, 2251799813685247]) } /// Given 64-bit input limbs, reduce to enforce the bound 2^(51 + epsilon). #[inline(always)] - fn reduce(mut limbs: [u64; 5]) -> FieldElement64 { + fn reduce(mut limbs: [u64; 5]) -> FieldElement51 { const LOW_51_BIT_MASK: u64 = (1u64 << 51) - 1; // Since the input limbs are bounded by 2^64, the biggest @@ -304,10 +304,10 @@ impl FieldElement64 { limbs[3] += c2; limbs[4] += c3; - FieldElement64(limbs) + FieldElement51(limbs) } - /// Load a `FieldElement64` from the low 255 bits of a 256-bit + /// Load a `FieldElement51` from the low 255 bits of a 256-bit /// input. /// /// # Warning @@ -319,7 +319,7 @@ impl FieldElement64 { /// the canonical encoding, and check that the input was /// canonical. /// - pub fn from_bytes(bytes: &[u8; 32]) -> FieldElement64 { + pub fn from_bytes(bytes: &[u8; 32]) -> FieldElement51 { let load8 = |input: &[u8]| -> u64 { (input[0] as u64) | ((input[1] as u64) << 8) @@ -332,7 +332,7 @@ impl FieldElement64 { }; let low_51_bit_mask = (1u64 << 51) - 1; - FieldElement64( + FieldElement51( // load bits [ 0, 64), no shift [ load8(&bytes[ 0..]) & low_51_bit_mask // load bits [ 48,112), shift to [ 51,112) @@ -346,7 +346,7 @@ impl FieldElement64 { ]) } - /// Serialize this `FieldElement64` to a 32-byte array. The + /// Serialize this `FieldElement51` to a 32-byte array. The /// encoding is canonical. pub fn to_bytes(&self) -> [u8; 32] { // Let h = limbs[0] + limbs[1]*2^51 + ... + limbs[4]*2^204. @@ -365,7 +365,7 @@ impl FieldElement64 { // Therefore q can be computed as the carry bit of h + 19. // First, reduce the limbs to ensure h < 2*p. - let mut limbs = FieldElement64::reduce(self.0).0; + let mut limbs = FieldElement51::reduce(self.0).0; let mut q = (limbs[0] + 19) >> 51; q = (limbs[1] + q) >> 51; @@ -433,7 +433,7 @@ impl FieldElement64 { } /// Given `k > 0`, return `self^(2^k)`. - pub fn pow2k(&self, mut k: u32) -> FieldElement64 { + pub fn pow2k(&self, mut k: u32) -> FieldElement51 { debug_assert!( k > 0 ); @@ -535,16 +535,16 @@ impl FieldElement64 { } } - FieldElement64(a) + FieldElement51(a) } /// Returns the square of this field element. - pub fn square(&self) -> FieldElement64 { + pub fn square(&self) -> FieldElement51 { self.pow2k(1) } /// Returns 2 times the square of this field element. - pub fn square2(&self) -> FieldElement64 { + pub fn square2(&self) -> FieldElement51 { let mut square = self.pow2k(1); for i in 0..5 { square.0[i] *= 2; diff --git a/src/backend/u64/scalar.rs b/src/backend/u64/scalar.rs index e14440b..e9031b0 100644 --- a/src/backend/u64/scalar.rs +++ b/src/backend/u64/scalar.rs @@ -16,25 +16,25 @@ use core::ops::{Index, IndexMut}; use constants; -/// The `Scalar64` struct represents an element in +/// The `Scalar52` struct represents an element in /// \\(\mathbb Z / \ell \mathbb Z\\) as 5 \\(52\\)-bit limbs. #[derive(Copy,Clone)] -pub struct Scalar64(pub [u64; 5]); +pub struct Scalar52(pub [u64; 5]); -impl Debug for Scalar64 { +impl Debug for Scalar52 { fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - write!(f, "Scalar64: {:?}", &self.0[..]) + write!(f, "Scalar52: {:?}", &self.0[..]) } } -impl Index for Scalar64 { +impl Index for Scalar52 { type Output = u64; fn index(&self, _index: usize) -> &u64 { &(self.0[_index]) } } -impl IndexMut for Scalar64 { +impl IndexMut for Scalar52 { fn index_mut(&mut self, _index: usize) -> &mut u64 { &mut (self.0[_index]) } @@ -46,14 +46,14 @@ fn m(x: u64, y: u64) -> u128 { (x as u128) * (y as u128) } -impl Scalar64 { +impl Scalar52 { /// Return the zero scalar - pub fn zero() -> Scalar64 { - Scalar64([0,0,0,0,0]) + pub fn zero() -> Scalar52 { + Scalar52([0,0,0,0,0]) } /// Unpack a 32 byte / 256 bit scalar into 5 52-bit limbs. - pub fn from_bytes(bytes: &[u8; 32]) -> Scalar64 { + pub fn from_bytes(bytes: &[u8; 32]) -> Scalar52 { let mut words = [0u64; 4]; for i in 0..4 { for j in 0..8 { @@ -63,7 +63,7 @@ impl Scalar64 { let mask = (1u64 << 52) - 1; let top_mask = (1u64 << 48) - 1; - let mut s = Scalar64::zero(); + let mut s = Scalar52::zero(); s[ 0] = words[0] & mask; s[ 1] = ((words[0] >> 52) | (words[1] << 12)) & mask; @@ -75,7 +75,7 @@ impl Scalar64 { } /// Reduce a 64 byte / 512 bit scalar mod l - pub fn from_bytes_wide(bytes: &[u8; 64]) -> Scalar64 { + pub fn from_bytes_wide(bytes: &[u8; 64]) -> Scalar52 { let mut words = [0u64; 8]; for i in 0..8 { for j in 0..8 { @@ -84,8 +84,8 @@ impl Scalar64 { } let mask = (1u64 << 52) - 1; - let mut lo = Scalar64::zero(); - let mut hi = Scalar64::zero(); + let mut lo = Scalar52::zero(); + let mut hi = Scalar52::zero(); lo[0] = words[ 0] & mask; lo[1] = ((words[ 0] >> 52) | (words[ 1] << 12)) & mask; @@ -98,13 +98,13 @@ impl Scalar64 { hi[3] = ((words[ 6] >> 32) | (words[ 7] << 32)) & mask; hi[4] = words[ 7] >> 20 ; - lo = Scalar64::montgomery_mul(&lo, &constants::R); // (lo * R) / R = lo - hi = Scalar64::montgomery_mul(&hi, &constants::RR); // (hi * R^2) / R = hi * R + lo = Scalar52::montgomery_mul(&lo, &constants::R); // (lo * R) / R = lo + hi = Scalar52::montgomery_mul(&hi, &constants::RR); // (hi * R^2) / R = hi * R - Scalar64::add(&hi, &lo) + Scalar52::add(&hi, &lo) } - /// Pack the limbs of this `Scalar64` into 32 bytes + /// Pack the limbs of this `Scalar52` into 32 bytes pub fn to_bytes(&self) -> [u8; 32] { let mut s = [0u8; 32]; @@ -145,8 +145,8 @@ impl Scalar64 { } /// Compute `a + b` (mod l) - pub fn add(a: &Scalar64, b: &Scalar64) -> Scalar64 { - let mut sum = Scalar64::zero(); + pub fn add(a: &Scalar52, b: &Scalar52) -> Scalar52 { + let mut sum = Scalar52::zero(); let mask = (1u64 << 52) - 1; // a + b @@ -157,12 +157,12 @@ impl Scalar64 { } // subtract l if the sum is >= l - Scalar64::sub(&sum, &constants::L) + Scalar52::sub(&sum, &constants::L) } /// Compute `a - b` (mod l) - pub fn sub(a: &Scalar64, b: &Scalar64) -> Scalar64 { - let mut difference = Scalar64::zero(); + pub fn sub(a: &Scalar52, b: &Scalar52) -> Scalar52 { + let mut difference = Scalar52::zero(); let mask = (1u64 << 52) - 1; // a - b @@ -185,7 +185,7 @@ impl Scalar64 { /// Compute `a * b` #[inline(always)] - pub (crate) fn mul_internal(a: &Scalar64, b: &Scalar64) -> [u128; 9] { + pub (crate) fn mul_internal(a: &Scalar52, b: &Scalar52) -> [u128; 9] { let mut z = [0u128; 9]; z[0] = m(a[0],b[0]); @@ -203,7 +203,7 @@ impl Scalar64 { /// Compute `a^2` #[inline(always)] - fn square_internal(a: &Scalar64) -> [u128; 9] { + fn square_internal(a: &Scalar52) -> [u128; 9] { let aa = [ a[0]*2, a[1]*2, @@ -226,7 +226,7 @@ impl Scalar64 { /// Compute `limbs/R` (mod l), where R is the Montgomery modulus 2^260 #[inline(always)] - pub (crate) fn montgomery_reduce(limbs: &[u128; 9]) -> Scalar64 { + pub (crate) fn montgomery_reduce(limbs: &[u128; 9]) -> Scalar52 { #[inline(always)] fn part1(sum: u128) -> (u128, u64) { @@ -258,50 +258,50 @@ impl Scalar64 { let r4 = carry as u64; // result may be >= l, so attempt to subtract l - Scalar64::sub(&Scalar64([r0,r1,r2,r3,r4]), l) + Scalar52::sub(&Scalar52([r0,r1,r2,r3,r4]), l) } /// Compute `a * b` (mod l) #[inline(never)] - pub fn mul(a: &Scalar64, b: &Scalar64) -> Scalar64 { - let ab = Scalar64::montgomery_reduce(&Scalar64::mul_internal(a, b)); - Scalar64::montgomery_reduce(&Scalar64::mul_internal(&ab, &constants::RR)) + pub fn mul(a: &Scalar52, b: &Scalar52) -> Scalar52 { + let ab = Scalar52::montgomery_reduce(&Scalar52::mul_internal(a, b)); + Scalar52::montgomery_reduce(&Scalar52::mul_internal(&ab, &constants::RR)) } /// Compute `a^2` (mod l) #[inline(never)] #[allow(dead_code)] // XXX we don't expose square() via the Scalar API - pub fn square(&self) -> Scalar64 { - let aa = Scalar64::montgomery_reduce(&Scalar64::square_internal(self)); - Scalar64::montgomery_reduce(&Scalar64::mul_internal(&aa, &constants::RR)) + pub fn square(&self) -> Scalar52 { + let aa = Scalar52::montgomery_reduce(&Scalar52::square_internal(self)); + Scalar52::montgomery_reduce(&Scalar52::mul_internal(&aa, &constants::RR)) } /// Compute `(a * b) / R` (mod l), where R is the Montgomery modulus 2^260 #[inline(never)] - pub fn montgomery_mul(a: &Scalar64, b: &Scalar64) -> Scalar64 { - Scalar64::montgomery_reduce(&Scalar64::mul_internal(a, b)) + pub fn montgomery_mul(a: &Scalar52, b: &Scalar52) -> Scalar52 { + Scalar52::montgomery_reduce(&Scalar52::mul_internal(a, b)) } /// Compute `(a^2) / R` (mod l) in Montgomery form, where R is the Montgomery modulus 2^260 #[inline(never)] - pub fn montgomery_square(&self) -> Scalar64 { - Scalar64::montgomery_reduce(&Scalar64::square_internal(self)) + pub fn montgomery_square(&self) -> Scalar52 { + Scalar52::montgomery_reduce(&Scalar52::square_internal(self)) } - /// Puts a Scalar64 in to Montgomery form, i.e. computes `a*R (mod l)` + /// Puts a Scalar52 in to Montgomery form, i.e. computes `a*R (mod l)` #[inline(never)] - pub fn to_montgomery(&self) -> Scalar64 { - Scalar64::montgomery_mul(self, &constants::RR) + pub fn to_montgomery(&self) -> Scalar52 { + Scalar52::montgomery_mul(self, &constants::RR) } - /// Takes a Scalar64 out of Montgomery form, i.e. computes `a/R (mod l)` + /// Takes a Scalar52 out of Montgomery form, i.e. computes `a/R (mod l)` #[inline(never)] - pub fn from_montgomery(&self) -> Scalar64 { + pub fn from_montgomery(&self) -> Scalar52 { let mut limbs = [0u128; 9]; for i in 0..5 { limbs[i] = self[i] as u128; } - Scalar64::montgomery_reduce(&limbs) + Scalar52::montgomery_reduce(&limbs) } } @@ -316,59 +316,59 @@ mod test { /// x = 14474011154664524427946373126085988481658748083205070504932198000989141204991 /// x = 7237005577332262213973186563042994240801631723825162898930247062703686954002 mod l /// x = 3057150787695215392275360544382990118917283750546154083604586903220563173085*R mod l in Montgomery form - pub static X: Scalar64 = Scalar64( + pub static X: Scalar52 = Scalar52( [0x000fffffffffffff, 0x000fffffffffffff, 0x000fffffffffffff, 0x000fffffffffffff, 0x00001fffffffffff]); /// x^2 = 3078544782642840487852506753550082162405942681916160040940637093560259278169 mod l - pub static XX: Scalar64 = Scalar64( + pub static XX: Scalar52 = Scalar52( [0x0001668020217559, 0x000531640ffd0ec0, 0x00085fd6f9f38a31, 0x000c268f73bb1cf4, 0x000006ce65046df0]); /// x^2 = 4413052134910308800482070043710297189082115023966588301924965890668401540959*R mod l in Montgomery form - pub static XX_MONT: Scalar64 = Scalar64( + pub static XX_MONT: Scalar52 = Scalar52( [0x000c754eea569a5c, 0x00063b6ed36cb215, 0x0008ffa36bf25886, 0x000e9183614e7543, 0x0000061db6c6f26f]); /// y = 6145104759870991071742105800796537629880401874866217824609283457819451087098 - pub static Y: Scalar64 = Scalar64( + pub static Y: Scalar52 = Scalar52( [0x000b75071e1458fa, 0x000bf9d75e1ecdac, 0x000433d2baf0672b, 0x0005fffcc11fad13, 0x00000d96018bb825]); /// x*y = 36752150652102274958925982391442301741 mod l - pub static XY: Scalar64 = Scalar64( + pub static XY: Scalar52 = Scalar52( [0x000ee6d76ba7632d, 0x000ed50d71d84e02, 0x00000000001ba634, 0x0000000000000000, 0x0000000000000000]); /// x*y = 658448296334113745583381664921721413881518248721417041768778176391714104386*R mod l in Montgomery form - pub static XY_MONT: Scalar64 = Scalar64( + pub static XY_MONT: Scalar52 = Scalar52( [0x0006d52bf200cfd5, 0x00033fb1d7021570, 0x000f201bc07139d8, 0x0001267e3e49169e, 0x000007b839c00268]); /// a = 2351415481556538453565687241199399922945659411799870114962672658845158063753 - pub static A: Scalar64 = Scalar64( + pub static A: Scalar52 = Scalar52( [0x0005236c07b3be89, 0x0001bc3d2a67c0c4, 0x000a4aa782aae3ee, 0x0006b3f6e4fec4c4, 0x00000532da9fab8c]); /// b = 4885590095775723760407499321843594317911456947580037491039278279440296187236 - pub static B: Scalar64 = Scalar64( + pub static B: Scalar52 = Scalar52( [0x000d3fae55421564, 0x000c2df24f65a4bc, 0x0005b5587d69fb0b, 0x00094c091b013b3b, 0x00000acd25605473]); /// a+b = 0 /// a-b = 4702830963113076907131374482398799845891318823599740229925345317690316127506 - pub static AB: Scalar64 = Scalar64( + pub static AB: Scalar52 = Scalar52( [0x000a46d80f677d12, 0x0003787a54cf8188, 0x0004954f0555c7dc, 0x000d67edc9fd8989, 0x00000a65b53f5718]); // c = (2^512 - 1) % l = 1627715501170711445284395025044413883736156588369414752970002579683115011840 - pub static C: Scalar64 = Scalar64( + pub static C: Scalar52 = Scalar52( [0x000611e3449c0f00, 0x000a768859347a40, 0x0007f5be65d00e1b, 0x0009a3dceec73d21, 0x00000399411b7c30]); #[test] fn mul_max() { - let res = Scalar64::mul(&X, &X); + let res = Scalar52::mul(&X, &X); for i in 0..5 { assert!(res[i] == XX[i]); } @@ -384,7 +384,7 @@ mod test { #[test] fn montgomery_mul_max() { - let res = Scalar64::montgomery_mul(&X, &X); + let res = Scalar52::montgomery_mul(&X, &X); for i in 0..5 { assert!(res[i] == XX_MONT[i]); } @@ -400,7 +400,7 @@ mod test { #[test] fn mul() { - let res = Scalar64::mul(&X, &Y); + let res = Scalar52::mul(&X, &Y); for i in 0..5 { assert!(res[i] == XY[i]); } @@ -408,7 +408,7 @@ mod test { #[test] fn montgomery_mul() { - let res = Scalar64::montgomery_mul(&X, &Y); + let res = Scalar52::montgomery_mul(&X, &Y); for i in 0..5 { assert!(res[i] == XY_MONT[i]); } @@ -416,8 +416,8 @@ mod test { #[test] fn add() { - let res = Scalar64::add(&A, &B); - let zero = Scalar64::zero(); + let res = Scalar52::add(&A, &B); + let zero = Scalar52::zero(); for i in 0..5 { assert!(res[i] == zero[i]); } @@ -425,7 +425,7 @@ mod test { #[test] fn sub() { - let res = Scalar64::sub(&A, &B); + let res = Scalar52::sub(&A, &B); for i in 0..5 { assert!(res[i] == AB[i]); } @@ -434,7 +434,7 @@ mod test { #[test] fn from_bytes_wide() { let bignum = [255u8; 64]; // 2^512 - 1 - let reduced = Scalar64::from_bytes_wide(&bignum); + let reduced = Scalar52::from_bytes_wide(&bignum); println!("{:?}", reduced); for i in 0..5 { assert!(reduced[i] == C[i]); diff --git a/src/constants.rs b/src/constants.rs index 51833ac..83d7ec8 100644 --- a/src/constants.rs +++ b/src/constants.rs @@ -151,9 +151,9 @@ mod test { #[test] #[cfg(feature = "u32_backend")] fn test_d_vs_ratio() { - use backend::u32::field::FieldElement32; - let a = -&FieldElement32([121665,0,0,0,0,0,0,0,0,0]); - let b = FieldElement32([121666,0,0,0,0,0,0,0,0,0]); + use backend::u32::field::FieldElement2625; + let a = -&FieldElement2625([121665,0,0,0,0,0,0,0,0,0]); + let b = FieldElement2625([121666,0,0,0,0,0,0,0,0,0]); let d = &a * &b.invert(); let d2 = &d + &d; assert_eq!(d, constants::EDWARDS_D); @@ -164,9 +164,9 @@ mod test { #[test] #[cfg(feature = "u64_backend")] fn test_d_vs_ratio() { - use backend::u64::field::FieldElement64; - let a = -&FieldElement64([121665,0,0,0,0]); - let b = FieldElement64([121666,0,0,0,0]); + use backend::u64::field::FieldElement51; + let a = -&FieldElement51([121665,0,0,0,0]); + let b = FieldElement51([121666,0,0,0,0]); let d = &a * &b.invert(); let d2 = &d + &d; assert_eq!(d, constants::EDWARDS_D); diff --git a/src/field.rs b/src/field.rs index 4448695..1587cea 100644 --- a/src/field.rs +++ b/src/field.rs @@ -12,8 +12,8 @@ //! //! The `curve25519_dalek::field` module provides a type alias //! `curve25519_dalek::field::FieldElement` to a field element type -//! defined in the `backend` module; either `FieldElement64` or -//! `FieldElement32`. +//! defined in the `backend` module; either `FieldElement51` or +//! `FieldElement2625`. //! //! Field operations defined in terms of machine //! operations, such as field multiplication or squaring, are defined in @@ -40,7 +40,7 @@ pub use backend::u64::field::*; /// The `FieldElement` type is an alias for one of the platform-specific /// implementations. #[cfg(feature = "u64_backend")] -pub type FieldElement = backend::u64::field::FieldElement64; +pub type FieldElement = backend::u64::field::FieldElement51; #[cfg(feature = "u32_backend")] pub use backend::u32::field::*; @@ -50,7 +50,7 @@ pub use backend::u32::field::*; /// The `FieldElement` type is an alias for one of the platform-specific /// implementations. #[cfg(feature = "u32_backend")] -pub type FieldElement = backend::u32::field::FieldElement32; +pub type FieldElement = backend::u32::field::FieldElement2625; impl Eq for FieldElement {} diff --git a/src/scalar.rs b/src/scalar.rs index 2e4d256..c8d5aa9 100644 --- a/src/scalar.rs +++ b/src/scalar.rs @@ -168,14 +168,14 @@ use constants; /// This is a type alias for one of the scalar types in the `backend` /// module. #[cfg(feature = "u64_backend")] -type UnpackedScalar = backend::u64::scalar::Scalar64; +type UnpackedScalar = backend::u64::scalar::Scalar52; /// An `UnpackedScalar` represents an element of the field GF(l), optimized for speed. /// /// This is a type alias for one of the scalar types in the `backend` /// module. #[cfg(feature = "u32_backend")] -type UnpackedScalar = backend::u32::scalar::Scalar32; +type UnpackedScalar = backend::u32::scalar::Scalar29; /// The `Scalar` struct holds an integer \\(s < 2\^{255} \\) which