mirror of
https://github.com/saymrwulf/risc0-curve25519-dalek-source.git
synced 2026-09-10 21:00:41 +00:00
Rename field types based on radix.
`FieldElement32` -> `FieldElement2625` `FieldElement64` -> `FieldElement51` `Scalar32` -> `Scalar29` `Scalar64` -> `Scalar52` This naming is more accurate and would let us add an ADX backend later.
This commit is contained in:
parent
4814242d00
commit
94cb3e7842
14 changed files with 514 additions and 514 deletions
4
build.rs
4
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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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<CachedPoint> = NafLookupTable8([
|
||||
CachedPoint(FieldElement32x4([
|
||||
CachedPoint(FieldElement2625x4([
|
||||
u32x8::new(
|
||||
3571425,
|
||||
10045002,
|
||||
|
|
@ -148,7 +148,7 @@ pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8<CachedPoint> = Naf
|
|||
4846528,
|
||||
),
|
||||
])),
|
||||
CachedPoint(FieldElement32x4([
|
||||
CachedPoint(FieldElement2625x4([
|
||||
u32x8::new(
|
||||
47099681,
|
||||
31447946,
|
||||
|
|
@ -200,7 +200,7 @@ pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8<CachedPoint> = Naf
|
|||
31366585,
|
||||
),
|
||||
])),
|
||||
CachedPoint(FieldElement32x4([
|
||||
CachedPoint(FieldElement2625x4([
|
||||
u32x8::new(
|
||||
18147205,
|
||||
62587998,
|
||||
|
|
@ -252,7 +252,7 @@ pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8<CachedPoint> = Naf
|
|||
31948344,
|
||||
),
|
||||
])),
|
||||
CachedPoint(FieldElement32x4([
|
||||
CachedPoint(FieldElement2625x4([
|
||||
u32x8::new(
|
||||
10625852,
|
||||
15193821,
|
||||
|
|
@ -304,7 +304,7 @@ pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8<CachedPoint> = Naf
|
|||
11531760,
|
||||
),
|
||||
])),
|
||||
CachedPoint(FieldElement32x4([
|
||||
CachedPoint(FieldElement2625x4([
|
||||
u32x8::new(
|
||||
22176662,
|
||||
3984313,
|
||||
|
|
@ -356,7 +356,7 @@ pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8<CachedPoint> = Naf
|
|||
9686767,
|
||||
),
|
||||
])),
|
||||
CachedPoint(FieldElement32x4([
|
||||
CachedPoint(FieldElement2625x4([
|
||||
u32x8::new(
|
||||
21157200,
|
||||
39156966,
|
||||
|
|
@ -408,7 +408,7 @@ pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8<CachedPoint> = Naf
|
|||
17395963,
|
||||
),
|
||||
])),
|
||||
CachedPoint(FieldElement32x4([
|
||||
CachedPoint(FieldElement2625x4([
|
||||
u32x8::new(
|
||||
63153652,
|
||||
32195955,
|
||||
|
|
@ -460,7 +460,7 @@ pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8<CachedPoint> = Naf
|
|||
10289708,
|
||||
),
|
||||
])),
|
||||
CachedPoint(FieldElement32x4([
|
||||
CachedPoint(FieldElement2625x4([
|
||||
u32x8::new(
|
||||
1401265,
|
||||
58846825,
|
||||
|
|
@ -512,7 +512,7 @@ pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8<CachedPoint> = Naf
|
|||
11976112,
|
||||
),
|
||||
])),
|
||||
CachedPoint(FieldElement32x4([
|
||||
CachedPoint(FieldElement2625x4([
|
||||
u32x8::new(
|
||||
39849808,
|
||||
44781685,
|
||||
|
|
@ -564,7 +564,7 @@ pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8<CachedPoint> = Naf
|
|||
27313245,
|
||||
),
|
||||
])),
|
||||
CachedPoint(FieldElement32x4([
|
||||
CachedPoint(FieldElement2625x4([
|
||||
u32x8::new(
|
||||
58237774,
|
||||
15917425,
|
||||
|
|
@ -616,7 +616,7 @@ pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8<CachedPoint> = Naf
|
|||
22487864,
|
||||
),
|
||||
])),
|
||||
CachedPoint(FieldElement32x4([
|
||||
CachedPoint(FieldElement2625x4([
|
||||
u32x8::new(
|
||||
12671134,
|
||||
56419053,
|
||||
|
|
@ -668,7 +668,7 @@ pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8<CachedPoint> = Naf
|
|||
2606889,
|
||||
),
|
||||
])),
|
||||
CachedPoint(FieldElement32x4([
|
||||
CachedPoint(FieldElement2625x4([
|
||||
u32x8::new(
|
||||
55082775,
|
||||
45300503,
|
||||
|
|
@ -720,7 +720,7 @@ pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8<CachedPoint> = Naf
|
|||
5956424,
|
||||
),
|
||||
])),
|
||||
CachedPoint(FieldElement32x4([
|
||||
CachedPoint(FieldElement2625x4([
|
||||
u32x8::new(
|
||||
8211442,
|
||||
8014184,
|
||||
|
|
@ -772,7 +772,7 @@ pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8<CachedPoint> = Naf
|
|||
1824195,
|
||||
),
|
||||
])),
|
||||
CachedPoint(FieldElement32x4([
|
||||
CachedPoint(FieldElement2625x4([
|
||||
u32x8::new(
|
||||
59402443,
|
||||
17056879,
|
||||
|
|
@ -824,7 +824,7 @@ pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8<CachedPoint> = Naf
|
|||
11687259,
|
||||
),
|
||||
])),
|
||||
CachedPoint(FieldElement32x4([
|
||||
CachedPoint(FieldElement2625x4([
|
||||
u32x8::new(
|
||||
12521903,
|
||||
26014045,
|
||||
|
|
@ -876,7 +876,7 @@ pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8<CachedPoint> = Naf
|
|||
32973409,
|
||||
),
|
||||
])),
|
||||
CachedPoint(FieldElement32x4([
|
||||
CachedPoint(FieldElement2625x4([
|
||||
u32x8::new(
|
||||
30654745,
|
||||
51286025,
|
||||
|
|
@ -928,7 +928,7 @@ pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8<CachedPoint> = Naf
|
|||
32228854,
|
||||
),
|
||||
])),
|
||||
CachedPoint(FieldElement32x4([
|
||||
CachedPoint(FieldElement2625x4([
|
||||
u32x8::new(
|
||||
49518649,
|
||||
59119280,
|
||||
|
|
@ -980,7 +980,7 @@ pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8<CachedPoint> = Naf
|
|||
27003505,
|
||||
),
|
||||
])),
|
||||
CachedPoint(FieldElement32x4([
|
||||
CachedPoint(FieldElement2625x4([
|
||||
u32x8::new(
|
||||
28286608,
|
||||
10767548,
|
||||
|
|
@ -1032,7 +1032,7 @@ pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8<CachedPoint> = Naf
|
|||
18292949,
|
||||
),
|
||||
])),
|
||||
CachedPoint(FieldElement32x4([
|
||||
CachedPoint(FieldElement2625x4([
|
||||
u32x8::new(
|
||||
13869851,
|
||||
31448904,
|
||||
|
|
@ -1084,7 +1084,7 @@ pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8<CachedPoint> = Naf
|
|||
17277037,
|
||||
),
|
||||
])),
|
||||
CachedPoint(FieldElement32x4([
|
||||
CachedPoint(FieldElement2625x4([
|
||||
u32x8::new(
|
||||
43287109,
|
||||
27900723,
|
||||
|
|
@ -1136,7 +1136,7 @@ pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8<CachedPoint> = Naf
|
|||
30748046,
|
||||
),
|
||||
])),
|
||||
CachedPoint(FieldElement32x4([
|
||||
CachedPoint(FieldElement2625x4([
|
||||
u32x8::new(
|
||||
16441817,
|
||||
36111849,
|
||||
|
|
@ -1188,7 +1188,7 @@ pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8<CachedPoint> = Naf
|
|||
10930179,
|
||||
),
|
||||
])),
|
||||
CachedPoint(FieldElement32x4([
|
||||
CachedPoint(FieldElement2625x4([
|
||||
u32x8::new(
|
||||
28319289,
|
||||
40734650,
|
||||
|
|
@ -1240,7 +1240,7 @@ pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8<CachedPoint> = Naf
|
|||
10938429,
|
||||
),
|
||||
])),
|
||||
CachedPoint(FieldElement32x4([
|
||||
CachedPoint(FieldElement2625x4([
|
||||
u32x8::new(
|
||||
8373273,
|
||||
49064494,
|
||||
|
|
@ -1292,7 +1292,7 @@ pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8<CachedPoint> = Naf
|
|||
15812027,
|
||||
),
|
||||
])),
|
||||
CachedPoint(FieldElement32x4([
|
||||
CachedPoint(FieldElement2625x4([
|
||||
u32x8::new(
|
||||
30741269,
|
||||
38648744,
|
||||
|
|
@ -1344,7 +1344,7 @@ pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8<CachedPoint> = Naf
|
|||
10839820,
|
||||
),
|
||||
])),
|
||||
CachedPoint(FieldElement32x4([
|
||||
CachedPoint(FieldElement2625x4([
|
||||
u32x8::new(
|
||||
18672548,
|
||||
57660959,
|
||||
|
|
@ -1396,7 +1396,7 @@ pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8<CachedPoint> = Naf
|
|||
30432268,
|
||||
),
|
||||
])),
|
||||
CachedPoint(FieldElement32x4([
|
||||
CachedPoint(FieldElement2625x4([
|
||||
u32x8::new(
|
||||
12179834,
|
||||
41005450,
|
||||
|
|
@ -1448,7 +1448,7 @@ pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8<CachedPoint> = Naf
|
|||
24862543,
|
||||
),
|
||||
])),
|
||||
CachedPoint(FieldElement32x4([
|
||||
CachedPoint(FieldElement2625x4([
|
||||
u32x8::new(
|
||||
59523541,
|
||||
62195428,
|
||||
|
|
@ -1500,7 +1500,7 @@ pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8<CachedPoint> = Naf
|
|||
27449522,
|
||||
),
|
||||
])),
|
||||
CachedPoint(FieldElement32x4([
|
||||
CachedPoint(FieldElement2625x4([
|
||||
u32x8::new(
|
||||
19770733,
|
||||
26478685,
|
||||
|
|
@ -1552,7 +1552,7 @@ pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8<CachedPoint> = Naf
|
|||
1776722,
|
||||
),
|
||||
])),
|
||||
CachedPoint(FieldElement32x4([
|
||||
CachedPoint(FieldElement2625x4([
|
||||
u32x8::new(
|
||||
36719806,
|
||||
20827965,
|
||||
|
|
@ -1604,7 +1604,7 @@ pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8<CachedPoint> = Naf
|
|||
29334408,
|
||||
),
|
||||
])),
|
||||
CachedPoint(FieldElement32x4([
|
||||
CachedPoint(FieldElement2625x4([
|
||||
u32x8::new(
|
||||
42307254,
|
||||
57217102,
|
||||
|
|
@ -1656,7 +1656,7 @@ pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8<CachedPoint> = Naf
|
|||
11292096,
|
||||
),
|
||||
])),
|
||||
CachedPoint(FieldElement32x4([
|
||||
CachedPoint(FieldElement2625x4([
|
||||
u32x8::new(
|
||||
7071115,
|
||||
46444090,
|
||||
|
|
@ -1708,7 +1708,7 @@ pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8<CachedPoint> = Naf
|
|||
26285185,
|
||||
),
|
||||
])),
|
||||
CachedPoint(FieldElement32x4([
|
||||
CachedPoint(FieldElement2625x4([
|
||||
u32x8::new(
|
||||
963440,
|
||||
63742255,
|
||||
|
|
@ -1760,7 +1760,7 @@ pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8<CachedPoint> = Naf
|
|||
4928058,
|
||||
),
|
||||
])),
|
||||
CachedPoint(FieldElement32x4([
|
||||
CachedPoint(FieldElement2625x4([
|
||||
u32x8::new(
|
||||
63655588,
|
||||
17883670,
|
||||
|
|
@ -1812,7 +1812,7 @@ pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8<CachedPoint> = Naf
|
|||
32462955,
|
||||
),
|
||||
])),
|
||||
CachedPoint(FieldElement32x4([
|
||||
CachedPoint(FieldElement2625x4([
|
||||
u32x8::new(
|
||||
39158670,
|
||||
15322548,
|
||||
|
|
@ -1864,7 +1864,7 @@ pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8<CachedPoint> = Naf
|
|||
20307815,
|
||||
),
|
||||
])),
|
||||
CachedPoint(FieldElement32x4([
|
||||
CachedPoint(FieldElement2625x4([
|
||||
u32x8::new(
|
||||
2863373,
|
||||
40876242,
|
||||
|
|
@ -1916,7 +1916,7 @@ pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8<CachedPoint> = Naf
|
|||
21388876,
|
||||
),
|
||||
])),
|
||||
CachedPoint(FieldElement32x4([
|
||||
CachedPoint(FieldElement2625x4([
|
||||
u32x8::new(
|
||||
59276548,
|
||||
49972346,
|
||||
|
|
@ -1968,7 +1968,7 @@ pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8<CachedPoint> = Naf
|
|||
27257051,
|
||||
),
|
||||
])),
|
||||
CachedPoint(FieldElement32x4([
|
||||
CachedPoint(FieldElement2625x4([
|
||||
u32x8::new(
|
||||
52951491,
|
||||
66542164,
|
||||
|
|
@ -2020,7 +2020,7 @@ pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8<CachedPoint> = Naf
|
|||
26001714,
|
||||
),
|
||||
])),
|
||||
CachedPoint(FieldElement32x4([
|
||||
CachedPoint(FieldElement2625x4([
|
||||
u32x8::new(
|
||||
66783087,
|
||||
5234346,
|
||||
|
|
@ -2072,7 +2072,7 @@ pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8<CachedPoint> = Naf
|
|||
10065424,
|
||||
),
|
||||
])),
|
||||
CachedPoint(FieldElement32x4([
|
||||
CachedPoint(FieldElement2625x4([
|
||||
u32x8::new(
|
||||
42822326,
|
||||
57678669,
|
||||
|
|
@ -2124,7 +2124,7 @@ pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8<CachedPoint> = Naf
|
|||
4170709,
|
||||
),
|
||||
])),
|
||||
CachedPoint(FieldElement32x4([
|
||||
CachedPoint(FieldElement2625x4([
|
||||
u32x8::new(
|
||||
26535281,
|
||||
60238317,
|
||||
|
|
@ -2176,7 +2176,7 @@ pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8<CachedPoint> = Naf
|
|||
33286062,
|
||||
),
|
||||
])),
|
||||
CachedPoint(FieldElement32x4([
|
||||
CachedPoint(FieldElement2625x4([
|
||||
u32x8::new(
|
||||
54863941,
|
||||
67016431,
|
||||
|
|
@ -2228,7 +2228,7 @@ pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8<CachedPoint> = Naf
|
|||
347423,
|
||||
),
|
||||
])),
|
||||
CachedPoint(FieldElement32x4([
|
||||
CachedPoint(FieldElement2625x4([
|
||||
u32x8::new(
|
||||
41391822,
|
||||
34336880,
|
||||
|
|
@ -2280,7 +2280,7 @@ pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8<CachedPoint> = Naf
|
|||
4942942,
|
||||
),
|
||||
])),
|
||||
CachedPoint(FieldElement32x4([
|
||||
CachedPoint(FieldElement2625x4([
|
||||
u32x8::new(
|
||||
31956192,
|
||||
59570132,
|
||||
|
|
@ -2332,7 +2332,7 @@ pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8<CachedPoint> = Naf
|
|||
32932252,
|
||||
),
|
||||
])),
|
||||
CachedPoint(FieldElement32x4([
|
||||
CachedPoint(FieldElement2625x4([
|
||||
u32x8::new(
|
||||
29885826,
|
||||
51028067,
|
||||
|
|
@ -2384,7 +2384,7 @@ pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8<CachedPoint> = Naf
|
|||
9101885,
|
||||
),
|
||||
])),
|
||||
CachedPoint(FieldElement32x4([
|
||||
CachedPoint(FieldElement2625x4([
|
||||
u32x8::new(
|
||||
43331297,
|
||||
18431341,
|
||||
|
|
@ -2436,7 +2436,7 @@ pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8<CachedPoint> = Naf
|
|||
201203,
|
||||
),
|
||||
])),
|
||||
CachedPoint(FieldElement32x4([
|
||||
CachedPoint(FieldElement2625x4([
|
||||
u32x8::new(
|
||||
20548943,
|
||||
14334571,
|
||||
|
|
@ -2488,7 +2488,7 @@ pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8<CachedPoint> = Naf
|
|||
25177079,
|
||||
),
|
||||
])),
|
||||
CachedPoint(FieldElement32x4([
|
||||
CachedPoint(FieldElement2625x4([
|
||||
u32x8::new(
|
||||
41186817,
|
||||
46681702,
|
||||
|
|
@ -2540,7 +2540,7 @@ pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8<CachedPoint> = Naf
|
|||
7976478,
|
||||
),
|
||||
])),
|
||||
CachedPoint(FieldElement32x4([
|
||||
CachedPoint(FieldElement2625x4([
|
||||
u32x8::new(
|
||||
46509314,
|
||||
55327128,
|
||||
|
|
@ -2592,7 +2592,7 @@ pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8<CachedPoint> = Naf
|
|||
22687008,
|
||||
),
|
||||
])),
|
||||
CachedPoint(FieldElement32x4([
|
||||
CachedPoint(FieldElement2625x4([
|
||||
u32x8::new(
|
||||
15091184,
|
||||
32550863,
|
||||
|
|
@ -2644,7 +2644,7 @@ pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8<CachedPoint> = Naf
|
|||
542137,
|
||||
),
|
||||
])),
|
||||
CachedPoint(FieldElement32x4([
|
||||
CachedPoint(FieldElement2625x4([
|
||||
u32x8::new(
|
||||
62776018,
|
||||
32835413,
|
||||
|
|
@ -2696,7 +2696,7 @@ pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8<CachedPoint> = Naf
|
|||
21024049,
|
||||
),
|
||||
])),
|
||||
CachedPoint(FieldElement32x4([
|
||||
CachedPoint(FieldElement2625x4([
|
||||
u32x8::new(
|
||||
60835961,
|
||||
48209103,
|
||||
|
|
@ -2748,7 +2748,7 @@ pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8<CachedPoint> = Naf
|
|||
20924342,
|
||||
),
|
||||
])),
|
||||
CachedPoint(FieldElement32x4([
|
||||
CachedPoint(FieldElement2625x4([
|
||||
u32x8::new(
|
||||
18135013,
|
||||
20358426,
|
||||
|
|
@ -2800,7 +2800,7 @@ pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8<CachedPoint> = Naf
|
|||
14572399,
|
||||
),
|
||||
])),
|
||||
CachedPoint(FieldElement32x4([
|
||||
CachedPoint(FieldElement2625x4([
|
||||
u32x8::new(
|
||||
10785787,
|
||||
46564798,
|
||||
|
|
@ -2852,7 +2852,7 @@ pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8<CachedPoint> = Naf
|
|||
24110612,
|
||||
),
|
||||
])),
|
||||
CachedPoint(FieldElement32x4([
|
||||
CachedPoint(FieldElement2625x4([
|
||||
u32x8::new(
|
||||
39907267,
|
||||
45940262,
|
||||
|
|
@ -2904,7 +2904,7 @@ pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8<CachedPoint> = Naf
|
|||
29853825,
|
||||
),
|
||||
])),
|
||||
CachedPoint(FieldElement32x4([
|
||||
CachedPoint(FieldElement2625x4([
|
||||
u32x8::new(
|
||||
66303987,
|
||||
36060363,
|
||||
|
|
@ -2956,7 +2956,7 @@ pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8<CachedPoint> = Naf
|
|||
23261841,
|
||||
),
|
||||
])),
|
||||
CachedPoint(FieldElement32x4([
|
||||
CachedPoint(FieldElement2625x4([
|
||||
u32x8::new(
|
||||
51218008,
|
||||
5070126,
|
||||
|
|
@ -3008,7 +3008,7 @@ pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8<CachedPoint> = Naf
|
|||
18326047,
|
||||
),
|
||||
])),
|
||||
CachedPoint(FieldElement32x4([
|
||||
CachedPoint(FieldElement2625x4([
|
||||
u32x8::new(
|
||||
64176557,
|
||||
3912400,
|
||||
|
|
@ -3060,7 +3060,7 @@ pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8<CachedPoint> = Naf
|
|||
12655016,
|
||||
),
|
||||
])),
|
||||
CachedPoint(FieldElement32x4([
|
||||
CachedPoint(FieldElement2625x4([
|
||||
u32x8::new(
|
||||
38372660,
|
||||
57101970,
|
||||
|
|
@ -3112,7 +3112,7 @@ pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8<CachedPoint> = Naf
|
|||
13421882,
|
||||
),
|
||||
])),
|
||||
CachedPoint(FieldElement32x4([
|
||||
CachedPoint(FieldElement2625x4([
|
||||
u32x8::new(
|
||||
22917795,
|
||||
22088359,
|
||||
|
|
@ -3164,7 +3164,7 @@ pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8<CachedPoint> = Naf
|
|||
13175986,
|
||||
),
|
||||
])),
|
||||
CachedPoint(FieldElement32x4([
|
||||
CachedPoint(FieldElement2625x4([
|
||||
u32x8::new(
|
||||
16185025,
|
||||
61537525,
|
||||
|
|
@ -3216,7 +3216,7 @@ pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8<CachedPoint> = Naf
|
|||
21409233,
|
||||
),
|
||||
])),
|
||||
CachedPoint(FieldElement32x4([
|
||||
CachedPoint(FieldElement2625x4([
|
||||
u32x8::new(
|
||||
59411973,
|
||||
57437124,
|
||||
|
|
@ -3268,7 +3268,7 @@ pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8<CachedPoint> = Naf
|
|||
4211851,
|
||||
),
|
||||
])),
|
||||
CachedPoint(FieldElement32x4([
|
||||
CachedPoint(FieldElement2625x4([
|
||||
u32x8::new(
|
||||
6757410,
|
||||
65455566,
|
||||
|
|
@ -3320,7 +3320,7 @@ pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8<CachedPoint> = Naf
|
|||
10524446,
|
||||
),
|
||||
])),
|
||||
CachedPoint(FieldElement32x4([
|
||||
CachedPoint(FieldElement2625x4([
|
||||
u32x8::new(
|
||||
1497507,
|
||||
33054449,
|
||||
|
|
@ -3372,7 +3372,7 @@ pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8<CachedPoint> = Naf
|
|||
29687002,
|
||||
),
|
||||
])),
|
||||
CachedPoint(FieldElement32x4([
|
||||
CachedPoint(FieldElement2625x4([
|
||||
u32x8::new(
|
||||
35889734,
|
||||
23047226,
|
||||
|
|
|
|||
|
|
@ -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<edwards::EdwardsPoint> 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<ExtendedPoint> 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<ExtendedPoint> 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);
|
||||
|
|
|
|||
|
|
@ -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<FieldElement32x4> for FieldElement32x4 {
|
||||
type Output = FieldElement32x4;
|
||||
/// Add two `FieldElement32x4`s, without performing a reduction.
|
||||
impl Add<FieldElement2625x4> 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<FieldElement32x4> 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();
|
||||
|
||||
|
|
|
|||
|
|
@ -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])
|
||||
},
|
||||
];
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<usize> for Scalar32 {
|
||||
impl Index<usize> for Scalar29 {
|
||||
type Output = u32;
|
||||
fn index(&self, _index: usize) -> &u32 {
|
||||
&(self.0[_index])
|
||||
}
|
||||
}
|
||||
|
||||
impl IndexMut<usize> for Scalar32 {
|
||||
impl IndexMut<usize> 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]);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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]),
|
||||
}
|
||||
];
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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<usize> for Scalar64 {
|
||||
impl Index<usize> for Scalar52 {
|
||||
type Output = u64;
|
||||
fn index(&self, _index: usize) -> &u64 {
|
||||
&(self.0[_index])
|
||||
}
|
||||
}
|
||||
|
||||
impl IndexMut<usize> for Scalar64 {
|
||||
impl IndexMut<usize> 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]);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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 {}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in a new issue