diff --git a/ed448-goldilocks/src/curve/scalar_mul/window/wnaf.rs b/ed448-goldilocks/src/curve/scalar_mul/window/wnaf.rs index 1c804fded..07c98b863 100644 --- a/ed448-goldilocks/src/curve/scalar_mul/window/wnaf.rs +++ b/ed448-goldilocks/src/curve/scalar_mul/window/wnaf.rs @@ -22,7 +22,7 @@ impl From<&ExtendedPoint> for LookupTable { impl LookupTable { /// Selects a projective niels point from a lookup table in constant time pub fn select(&self, index: u32) -> ProjectiveNielsPoint { - let mut result = ProjectiveNielsPoint::identity(); + let mut result = ProjectiveNielsPoint::IDENTITY; for i in 1..9 { let swap = index.ct_eq(&(i as u32)); diff --git a/ed448-goldilocks/src/curve/twedwards/projective.rs b/ed448-goldilocks/src/curve/twedwards/projective.rs index d5c9cafb7..166bda78f 100644 --- a/ed448-goldilocks/src/curve/twedwards/projective.rs +++ b/ed448-goldilocks/src/curve/twedwards/projective.rs @@ -1,18 +1,18 @@ #![allow(non_snake_case)] -use crate::curve::twedwards::{extended::ExtendedPoint, extensible::ExtensiblePoint}; +use crate::curve::twedwards::extended::ExtendedPoint; use crate::field::FieldElement; use subtle::{Choice, ConditionallyNegatable, ConditionallySelectable}; impl Default for ProjectiveNielsPoint { fn default() -> ProjectiveNielsPoint { - ProjectiveNielsPoint::identity() + ProjectiveNielsPoint::IDENTITY } } // Its a variant of Niels, where a Z coordinate is added for unmixed readdition // ((y+x)/2, (y-x)/2, dxy, Z) -#[derive(Copy, Clone)] +#[derive(Copy, Clone, Debug)] pub struct ProjectiveNielsPoint { pub(crate) Y_plus_X: FieldElement, pub(crate) Y_minus_X: FieldElement, @@ -45,9 +45,12 @@ impl ConditionallyNegatable for ProjectiveNielsPoint { } impl ProjectiveNielsPoint { - pub fn identity() -> ProjectiveNielsPoint { - ExtensiblePoint::IDENTITY.to_projective_niels() - } + pub const IDENTITY: ProjectiveNielsPoint = ProjectiveNielsPoint { + Y_plus_X: FieldElement::ONE, + Y_minus_X: FieldElement::ONE, + Td: FieldElement::ZERO, + Z: FieldElement::TWO, + }; pub fn to_extended(self) -> ExtendedPoint { let A = self.Y_plus_X - self.Y_minus_X; @@ -63,6 +66,23 @@ impl ProjectiveNielsPoint { #[cfg(test)] mod tests { use super::*; + use crate::curve::twedwards::extensible::ExtensiblePoint; + + #[test] + fn identity() { + // Internally are compared by converting to `ExtendedPoint`. + // Here the right-side identity point is converted to Niel's + // and then both sides are converted to twisted-curve form. + assert_eq!( + ProjectiveNielsPoint::IDENTITY, + ExtensiblePoint::IDENTITY.to_projective_niels(), + ); + // Here only the left-side identity point is converted. + assert_eq!( + ProjectiveNielsPoint::IDENTITY.to_extended(), + ExtendedPoint::IDENTITY, + ); + } #[test] fn test_conditional_negate() { diff --git a/ed448-goldilocks/src/field/element.rs b/ed448-goldilocks/src/field/element.rs index 2a1d9d59b..7e96a5367 100644 --- a/ed448-goldilocks/src/field/element.rs +++ b/ed448-goldilocks/src/field/element.rs @@ -246,6 +246,7 @@ impl FieldElement { "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000262a8", ))); pub const ONE: Self = Self(ConstMontyType::new(&U448::ONE)); + pub const TWO: Self = Self(ConstMontyType::new(&U448::from_u64(2))); pub const TWISTED_D: Self = Self(ConstMontyType::new(&U448::from_be_hex( "fffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffffffff6755", )));