Skip to main content

ed448_goldilocks/curve/scalar_mul/window/
wnaf.rs

1use crate::curve::twedwards::extended::ExtendedPoint;
2use crate::curve::twedwards::projective::ProjectiveNielsPoint;
3use subtle::{ConditionallySelectable, ConstantTimeEq};
4
5pub struct LookupTable([ProjectiveNielsPoint; 8]);
6
7/// Precomputes odd multiples of the point passed in
8impl From<&ExtendedPoint> for LookupTable {
9    fn from(P: &ExtendedPoint) -> LookupTable {
10        let mut table = [P.to_projective_niels(); 8];
11
12        for i in 1..8 {
13            table[i] = P
14                .add_projective_niels(&table[i - 1])
15                .to_extended()
16                .to_projective_niels();
17        }
18
19        LookupTable(table)
20    }
21}
22
23impl LookupTable {
24    /// Selects a projective niels point from a lookup table in constant time
25    pub fn select(&self, index: u32) -> ProjectiveNielsPoint {
26        let mut result = ProjectiveNielsPoint::IDENTITY;
27
28        for i in 1..9 {
29            let swap = index.ct_eq(&(i as u32));
30            result.conditional_assign(&self.0[i - 1], swap);
31        }
32        result
33    }
34}
35
36// XXX: Add back tests to ensure that select works correctly
37
38#[test]
39fn test_lookup() {
40    let p = ExtendedPoint::GENERATOR;
41    let points = LookupTable::from(&p);
42
43    let mut expected_point = ExtendedPoint::IDENTITY;
44    for i in 0..8 {
45        let selected_point = points.select(i);
46        assert_eq!(selected_point.to_extensible(), expected_point);
47
48        expected_point = expected_point.add_extended(&p).to_extended();
49    }
50}