From ef3af5910ffa79ea9b9724d1eb5c7e9d83b10dca Mon Sep 17 00:00:00 2001 From: daxpedda Date: Sat, 26 Jul 2025 23:57:33 +0200 Subject: [PATCH] Reduce unnecessary conversions to `ExtensiblePoint` and back --- .../src/curve/scalar_mul/double_and_add.rs | 7 +- .../src/curve/scalar_mul/variable_base.rs | 13 +- .../src/curve/scalar_mul/window/wnaf.rs | 16 +- ed448-goldilocks/src/curve/twedwards.rs | 15 +- .../src/curve/twedwards/affine.rs | 11 +- .../src/curve/twedwards/extended.rs | 154 ++++++++++++++---- .../src/curve/twedwards/extensible.rs | 124 +++----------- .../src/curve/twedwards/projective.rs | 21 +-- ed448-goldilocks/src/decaf/ops.rs | 6 +- ed448-goldilocks/src/decaf/points.rs | 22 +-- ed448-goldilocks/src/edwards/extended.rs | 18 +- 11 files changed, 210 insertions(+), 197 deletions(-) diff --git a/ed448-goldilocks/src/curve/scalar_mul/double_and_add.rs b/ed448-goldilocks/src/curve/scalar_mul/double_and_add.rs index aac590611..917ba16d5 100644 --- a/ed448-goldilocks/src/curve/scalar_mul/double_and_add.rs +++ b/ed448-goldilocks/src/curve/scalar_mul/double_and_add.rs @@ -1,9 +1,10 @@ use crate::curve::twedwards::extended::ExtendedPoint; +use crate::curve::twedwards::extensible::ExtensiblePoint; use subtle::{Choice, ConditionallySelectable}; /// Traditional double and add algorithm -pub(crate) fn double_and_add(point: &ExtendedPoint, s_bits: [bool; 448]) -> ExtendedPoint { - let mut result = ExtendedPoint::IDENTITY; +pub(crate) fn double_and_add(point: &ExtendedPoint, s_bits: [bool; 448]) -> ExtensiblePoint { + let mut result = ExtensiblePoint::IDENTITY; // NB, we reverse here, so we are going from MSB to LSB // XXX: Would be great if subtle had a From for Choice. But maybe that is not it's purpose? @@ -12,7 +13,7 @@ pub(crate) fn double_and_add(point: &ExtendedPoint, s_bits: [bool; 448]) -> Exte let mut p = ExtendedPoint::IDENTITY; p.conditional_assign(point, Choice::from(bit as u8)); - result = result.add(&p); + result = result.to_extended().add_extended(&p); } result diff --git a/ed448-goldilocks/src/curve/scalar_mul/variable_base.rs b/ed448-goldilocks/src/curve/scalar_mul/variable_base.rs index bdbca2b79..8379bcbe6 100644 --- a/ed448-goldilocks/src/curve/scalar_mul/variable_base.rs +++ b/ed448-goldilocks/src/curve/scalar_mul/variable_base.rs @@ -5,7 +5,7 @@ use crate::EdwardsScalar; use crate::curve::twedwards::{extended::ExtendedPoint, extensible::ExtensiblePoint}; use subtle::{Choice, ConditionallyNegatable}; -pub fn variable_base(point: &ExtendedPoint, s: &EdwardsScalar) -> ExtendedPoint { +pub fn variable_base(point: &ExtendedPoint, s: &EdwardsScalar) -> ExtensiblePoint { let mut result = ExtensiblePoint::IDENTITY; // Recode Scalar @@ -28,10 +28,10 @@ pub fn variable_base(point: &ExtendedPoint, s: &EdwardsScalar) -> ExtendedPoint let mut neg_P = lookup.select(abs_value); neg_P.conditional_negate(Choice::from((sign) as u8)); - result = result.add_projective_niels(&neg_P); + result = result.to_extended().add_projective_niels(&neg_P); } - result.to_extended() + result } #[cfg(test)] @@ -57,7 +57,7 @@ mod test { // Lets see if this is conserved over the isogenies let edwards_point = twisted_point.to_untwisted(); let got_untwisted_point = edwards_point.scalar_mul(&scalar); - let expected_untwisted_point = got.to_untwisted(); + let expected_untwisted_point = got.to_extended().to_untwisted(); assert_eq!(got_untwisted_point, expected_untwisted_point); } @@ -69,9 +69,8 @@ mod test { let exp = variable_base(&x, &EdwardsScalar::from(1u8)); assert!(x == exp); // Test that 2 * (P + P) = 4 * P - let x_ext = x.to_extensible(); - let expected_two_x = x_ext.add_extensible(&x_ext).double(); + let expected_two_x = x.add_extended(&x).double(); let got = variable_base(&x, &EdwardsScalar::from(4u8)); - assert!(expected_two_x.to_extended() == got); + assert!(expected_two_x == got); } } diff --git a/ed448-goldilocks/src/curve/scalar_mul/window/wnaf.rs b/ed448-goldilocks/src/curve/scalar_mul/window/wnaf.rs index 07c98b863..5f846880e 100644 --- a/ed448-goldilocks/src/curve/scalar_mul/window/wnaf.rs +++ b/ed448-goldilocks/src/curve/scalar_mul/window/wnaf.rs @@ -6,13 +6,14 @@ pub struct LookupTable([ProjectiveNielsPoint; 8]); /// Precomputes odd multiples of the point passed in impl From<&ExtendedPoint> for LookupTable { - fn from(point: &ExtendedPoint) -> LookupTable { - let P = point.to_extensible(); - + fn from(P: &ExtendedPoint) -> LookupTable { let mut table = [P.to_projective_niels(); 8]; for i in 1..8 { - table[i] = P.add_projective_niels(&table[i - 1]).to_projective_niels(); + table[i] = P + .add_projective_niels(&table[i - 1]) + .to_extended() + .to_projective_niels(); } LookupTable(table) @@ -42,11 +43,8 @@ fn test_lookup() { let mut expected_point = ExtendedPoint::IDENTITY; for i in 0..8 { let selected_point = points.select(i); - assert_eq!(selected_point.to_extended(), expected_point); + assert_eq!(selected_point.to_extensible(), expected_point); - expected_point = expected_point - .to_extensible() - .add_extended(&p) - .to_extended(); + expected_point = expected_point.add_extended(&p).to_extended(); } } diff --git a/ed448-goldilocks/src/curve/twedwards.rs b/ed448-goldilocks/src/curve/twedwards.rs index aa2a94c2a..579d20433 100644 --- a/ed448-goldilocks/src/curve/twedwards.rs +++ b/ed448-goldilocks/src/curve/twedwards.rs @@ -12,13 +12,21 @@ use crate::field::FieldElement; pub(crate) struct IsogenyMap { pub(crate) X: FieldElement, pub(crate) Y: FieldElement, + pub(crate) Z: FieldElement, pub(crate) T: FieldElement, +} + +pub(crate) struct IsogenyMapResult { + pub(crate) X: FieldElement, + pub(crate) Y: FieldElement, pub(crate) Z: FieldElement, + pub(crate) T1: FieldElement, + pub(crate) T2: FieldElement, } impl IsogenyMap { // (1.) https://eprint.iacr.org/2014/027.pdf - pub(crate) fn map(&self, scale: impl FnOnce(FieldElement) -> FieldElement) -> Self { + pub(crate) fn map(&self, scale: impl FnOnce(FieldElement) -> FieldElement) -> IsogenyMapResult { // x = 2xy / (y^2 - a*x^2) // y = (y^2 + a*x^2) / (2 - y^2 - a*x^2) @@ -53,9 +61,10 @@ impl IsogenyMap { let X = x_numerator * y_denom; let Y = y_numerator * x_denom; - let T = x_numerator * y_numerator; let Z = x_denom * y_denom; + let T1 = x_numerator; + let T2 = y_numerator; - Self { X, Y, T, Z } + IsogenyMapResult { X, Y, Z, T1, T2 } } } diff --git a/ed448-goldilocks/src/curve/twedwards/affine.rs b/ed448-goldilocks/src/curve/twedwards/affine.rs index 055e49014..578e00c2c 100644 --- a/ed448-goldilocks/src/curve/twedwards/affine.rs +++ b/ed448-goldilocks/src/curve/twedwards/affine.rs @@ -121,13 +121,14 @@ impl AffineNielsPoint { && (self.td == other.td) } - /// Converts an AffineNielsPoint to an ExtendedPoint - pub(crate) fn to_extended(self) -> ExtendedPoint { - ExtendedPoint { + /// Converts an AffineNielsPoint to an ExtensiblePoint + pub(crate) fn to_extensible(self) -> ExtensiblePoint { + ExtensiblePoint { X: self.y_plus_x - self.y_minus_x, Y: self.y_minus_x + self.y_plus_x, Z: FieldElement::ONE, - T: self.y_plus_x * self.y_minus_x, + T1: self.y_plus_x, + T2: self.y_minus_x, } } } @@ -140,7 +141,7 @@ mod tests { #[test] fn test_negation() { use crate::TWISTED_EDWARDS_BASE_POINT; - let a = TWISTED_EDWARDS_BASE_POINT.to_affine(); + let a = TWISTED_EDWARDS_BASE_POINT.to_extensible().to_affine(); assert!(a.is_on_curve()); let neg_a = a.negate(); diff --git a/ed448-goldilocks/src/curve/twedwards/extended.rs b/ed448-goldilocks/src/curve/twedwards/extended.rs index 189005f72..979d2cd8a 100644 --- a/ed448-goldilocks/src/curve/twedwards/extended.rs +++ b/ed448-goldilocks/src/curve/twedwards/extended.rs @@ -2,8 +2,9 @@ #![allow(dead_code)] use super::IsogenyMap; -use super::affine::AffinePoint; use super::extensible::ExtensiblePoint; +use super::projective::ProjectiveNielsPoint; +use super::{IsogenyMapResult, affine::AffineNielsPoint}; use crate::edwards::EdwardsPoint as EdwardsExtendedPoint; use crate::field::FieldElement; use subtle::{Choice, ConditionallySelectable, ConstantTimeEq}; @@ -44,6 +45,11 @@ impl PartialEq for ExtendedPoint { self.ct_eq(other).into() } } +impl PartialEq for ExtendedPoint { + fn eq(&self, other: &ExtensiblePoint) -> bool { + self.to_extensible().ct_eq(other).into() + } +} impl Eq for ExtendedPoint {} impl Default for ExtendedPoint { @@ -70,14 +76,90 @@ impl ExtendedPoint { T: FieldElement::ZERO, }; - /// Doubles an extended point - pub(crate) fn double(&self) -> ExtendedPoint { - self.to_extensible().double().to_extended() + /// Adds an extensible point to an extended point + /// Returns an extensible point + /// (3.1) https://iacr.org/archive/asiacrypt2008/53500329/53500329.pdf + pub fn add_extended(&self, other: &ExtendedPoint) -> ExtensiblePoint { + let A = self.X * other.X; + let B = self.Y * other.Y; + let C = self.T * other.T * FieldElement::TWISTED_D; + let D = self.Z * other.Z; + let E = (self.X + self.Y) * (other.X + other.Y) - A - B; + let F = D - C; + let G = D + C; + let H = B + A; + ExtensiblePoint { + X: E * F, + Y: G * H, + T1: E, + T2: H, + Z: F * G, + } } - /// Adds an extended point to itself - pub(crate) fn add(&self, other: &ExtendedPoint) -> ExtendedPoint { - self.to_extensible().add_extended(other).to_extended() + /// Subtracts an extensible point from an extended point + /// Returns an extensible point + /// This is a direct modification of the addition formula to the negation of `other` + pub fn sub_extended(&self, other: &ExtendedPoint) -> ExtensiblePoint { + let A = self.X * other.X; + let B = self.Y * other.Y; + let C = self.T * other.T * FieldElement::TWISTED_D; + let D = self.Z * other.Z; + let E = (self.X + self.Y) * (other.Y - other.X) + A - B; + let F = D + C; + let G = D - C; + let H = B - A; + ExtensiblePoint { + X: E * F, + Y: G * H, + T1: E, + T2: H, + Z: F * G, + } + } + + /// Adds an extensible point to an AffineNiels point + /// Returns an Extensible point + pub fn add_affine_niels(&self, other: AffineNielsPoint) -> ExtensiblePoint { + let A = other.y_minus_x * (self.Y - self.X); + let B = other.y_plus_x * (self.X + self.Y); + let C = other.td * self.T; + let D = B + A; + let E = B - A; + let F = self.Z - C; + let G = self.Z + C; + ExtensiblePoint { + X: E * F, + Y: G * D, + Z: F * G, + T1: E, + T2: D, + } + } + + /// Adds an extensible point to a ProjectiveNiels point + /// Returns an extensible point + /// (3.1)[Last set of formulas] https://iacr.org/archive/asiacrypt2008/53500329/53500329.pdf + /// This differs from the formula above by a factor of 2. Saving 1 Double + /// Cost 8M + pub fn add_projective_niels(&self, other: &ProjectiveNielsPoint) -> ExtensiblePoint { + // This is the only step which makes it different than adding an AffineNielsPoint + let Z = self.Z * other.Z; + + let A = (self.Y - self.X) * other.Y_minus_X; + let B = (self.Y + self.X) * other.Y_plus_X; + let C = other.Td * self.T; + let D = B + A; + let E = B - A; + let F = Z - C; + let G = Z + C; + ExtensiblePoint { + X: E * F, + Y: G * D, + Z: F * G, + T1: E, + T2: D, + } } /// Converts an ExtendedPoint to an ExtensiblePoint @@ -91,31 +173,32 @@ impl ExtendedPoint { } } - /// Converts an extended point to Affine co-ordinates - pub(crate) fn to_affine(self) -> AffinePoint { - // Points to consider: - // - All points where Z=0, translate to (0,0) - // - The identity point has z=1, so it is not a problem - - let INV_Z = self.Z.invert(); - - let x = self.X * INV_Z; - let y = self.Y * INV_Z; - - AffinePoint { x, y } - } - /// Uses a 2-isogeny to map the point to the Ed448-Goldilocks pub fn to_untwisted(self) -> EdwardsExtendedPoint { - let IsogenyMap { X, Y, T, Z } = IsogenyMap { + let IsogenyMapResult { X, Y, Z, T1, T2 } = IsogenyMap { X: self.X, Y: self.Y, - T: self.T, Z: self.Z, + T: self.T, } .map(|f| -f); - EdwardsExtendedPoint { X, Y, Z, T } + EdwardsExtendedPoint { + X, + Y, + Z, + T: T1 * T2, + } + } + + /// Converts an Extensible point to a ProjectiveNiels Point + pub fn to_projective_niels(self) -> ProjectiveNielsPoint { + ProjectiveNielsPoint { + Y_plus_X: self.X + self.Y, + Y_minus_X: self.Y - self.X, + Z: self.Z.double(), + Td: self.T * FieldElement::TWO_TIMES_TWISTED_D, + } } /// Checks if the point is on the curve @@ -159,6 +242,7 @@ impl ExtendedPoint { #[cfg(test)] mod tests { use super::*; + use crate::curve::twedwards::affine::AffinePoint; use crate::{GOLDILOCKS_BASE_POINT, TWISTED_EDWARDS_BASE_POINT}; fn hex_to_field(hex: &'static str) -> FieldElement { @@ -177,8 +261,8 @@ mod tests { let y = hex_to_field( "ae05e9634ad7048db359d6205086c2b0036ed7a035884dd7b7e36d728ad8c4b80d6565833a2a3098bbbcb2bed1cda06bdaeafbcdea9386ed", ); - let a = AffinePoint { x, y }.to_extended(); - let twist_a = a.to_untwisted().to_twisted(); + let a = AffinePoint { x, y }.to_extensible(); + let twist_a = a.to_extended().to_untwisted().to_twisted(); assert_eq!(twist_a, a.double().double()) } @@ -201,28 +285,28 @@ mod tests { #[test] fn test_point_add() { let a = TWISTED_EDWARDS_BASE_POINT; - let b = a.double(); + let b = a.to_extensible().double().to_extended(); // A + B = B + A = C - let c_1 = a.to_extensible().add_extended(&b).to_extended(); - let c_2 = b.to_extensible().add_extended(&a).to_extended(); + let c_1 = a.add_extended(&b).to_extended(); + let c_2 = b.add_extended(&a).to_extended(); assert!(c_1 == c_2); // Adding identity point should not change result - let c = c_1.to_extensible().add_extended(&ExtendedPoint::IDENTITY); - assert!(c.to_extended() == c_1); + let c = c_1.add_extended(&ExtendedPoint::IDENTITY); + assert!(c == c_1); } #[test] fn test_point_sub() { let a = TWISTED_EDWARDS_BASE_POINT; - let b = a.double(); + let b = a.to_extensible().double().to_extended(); // A - B = C - let c_1 = a.to_extensible().sub_extended(&b).to_extended(); + let c_1 = a.sub_extended(&b).to_extended(); // -B + A = C - let c_2 = b.negate().to_extensible().add_extended(&a).to_extended(); + let c_2 = b.negate().add_extended(&a).to_extended(); assert!(c_1 == c_2); } @@ -231,6 +315,6 @@ mod tests { let a = TWISTED_EDWARDS_BASE_POINT; let neg_a = a.negate(); - assert!(a.to_extensible().add_extended(&neg_a) == ExtensiblePoint::IDENTITY); + assert!(a.add_extended(&neg_a) == ExtensiblePoint::IDENTITY); } } diff --git a/ed448-goldilocks/src/curve/twedwards/extensible.rs b/ed448-goldilocks/src/curve/twedwards/extensible.rs index ff3dc2d07..cca9d04b9 100644 --- a/ed448-goldilocks/src/curve/twedwards/extensible.rs +++ b/ed448-goldilocks/src/curve/twedwards/extensible.rs @@ -1,9 +1,8 @@ #![allow(non_snake_case)] #![allow(dead_code)] -use crate::curve::twedwards::{ - affine::AffineNielsPoint, extended::ExtendedPoint, projective::ProjectiveNielsPoint, -}; +use super::affine::AffinePoint; +use super::extended::ExtendedPoint; use crate::field::FieldElement; use subtle::{Choice, ConstantTimeEq}; @@ -12,6 +11,7 @@ use subtle::{Choice, ConstantTimeEq}; // Where x = X/Z , y = Y/Z , T1 * T2 = T // XXX: I think we have too many point representations, // But let's not remove any yet +#[derive(Copy, Clone, Debug)] pub struct ExtensiblePoint { pub(crate) X: FieldElement, pub(crate) Y: FieldElement, @@ -36,6 +36,11 @@ impl PartialEq for ExtensiblePoint { self.ct_eq(other).into() } } +impl PartialEq for ExtensiblePoint { + fn eq(&self, other: &ExtendedPoint) -> bool { + self.ct_eq(&other.to_extensible()).into() + } +} impl Eq for ExtensiblePoint {} impl ExtensiblePoint { @@ -67,99 +72,8 @@ impl ExtensiblePoint { } } - /// Adds two extensible points together by converting the other point to a ExtendedPoint - pub fn add_extensible(&self, other: &ExtensiblePoint) -> ExtensiblePoint { - self.add_extended(&other.to_extended()) - } - - /// Adds an extensible point to an extended point - /// Returns an extensible point - /// (3.1) https://iacr.org/archive/asiacrypt2008/53500329/53500329.pdf - pub fn add_extended(&self, other: &ExtendedPoint) -> ExtensiblePoint { - let A = self.X * other.X; - let B = self.Y * other.Y; - let C = self.T1 * self.T2 * other.T * FieldElement::TWISTED_D; - let D = self.Z * other.Z; - let E = (self.X + self.Y) * (other.X + other.Y) - A - B; - let F = D - C; - let G = D + C; - let H = B + A; - ExtensiblePoint { - X: E * F, - Y: G * H, - T1: E, - T2: H, - Z: F * G, - } - } - - /// Subtracts an extensible point from an extended point - /// Returns an extensible point - /// This is a direct modification of the addition formula to the negation of `other` - pub fn sub_extended(&self, other: &ExtendedPoint) -> ExtensiblePoint { - let A = self.X * other.X; - let B = self.Y * other.Y; - let C = self.T1 * self.T2 * other.T * FieldElement::TWISTED_D; - let D = self.Z * other.Z; - let E = (self.X + self.Y) * (other.Y - other.X) + A - B; - let F = D + C; - let G = D - C; - let H = B - A; - ExtensiblePoint { - X: E * F, - Y: G * H, - T1: E, - T2: H, - Z: F * G, - } - } - - /// Adds an extensible point to an AffineNiels point - /// Returns an Extensible point - pub fn add_affine_niels(&self, other: AffineNielsPoint) -> ExtensiblePoint { - let A = other.y_minus_x * (self.Y - self.X); - let B = other.y_plus_x * (self.X + self.Y); - let C = other.td * self.T1 * self.T2; - let D = B + A; - let E = B - A; - let F = self.Z - C; - let G = self.Z + C; - ExtensiblePoint { - X: E * F, - Y: G * D, - Z: F * G, - T1: E, - T2: D, - } - } - - /// Adds an extensible point to a ProjectiveNiels point - /// Returns an extensible point - /// (3.1)[Last set of formulas] https://iacr.org/archive/asiacrypt2008/53500329/53500329.pdf - /// This differs from the formula above by a factor of 2. Saving 1 Double - /// Cost 8M - pub fn add_projective_niels(&self, other: &ProjectiveNielsPoint) -> ExtensiblePoint { - // This is the only step which makes it different than adding an AffineNielsPoint - let Z = self.Z * other.Z; - - let A = (self.Y - self.X) * other.Y_minus_X; - let B = (self.Y + self.X) * other.Y_plus_X; - let C = other.Td * self.T1 * self.T2; - let D = B + A; - let E = B - A; - let F = Z - C; - let G = Z + C; - ExtensiblePoint { - X: E * F, - Y: G * D, - Z: F * G, - T1: E, - T2: D, - } - } - /// Converts an extensible point to an extended point - pub fn to_extended(&self) -> ExtendedPoint { + pub fn to_extended(self) -> ExtendedPoint { ExtendedPoint { X: self.X, Y: self.Y, @@ -168,13 +82,17 @@ impl ExtensiblePoint { } } - /// Converts an Extensible point to a ProjectiveNiels Point - pub fn to_projective_niels(&self) -> ProjectiveNielsPoint { - ProjectiveNielsPoint { - Y_plus_X: self.X + self.Y, - Y_minus_X: self.Y - self.X, - Z: self.Z + self.Z, - Td: self.T1 * self.T2 * FieldElement::TWO_TIMES_TWISTED_D, - } + /// Converts an extended point to Affine co-ordinates + pub(crate) fn to_affine(self) -> AffinePoint { + // Points to consider: + // - All points where Z=0, translate to (0,0) + // - The identity point has z=1, so it is not a problem + + let INV_Z = self.Z.invert(); + + let x = self.X * INV_Z; + let y = self.Y * INV_Z; + + AffinePoint { x, y } } } diff --git a/ed448-goldilocks/src/curve/twedwards/projective.rs b/ed448-goldilocks/src/curve/twedwards/projective.rs index 166bda78f..d2b97d89a 100644 --- a/ed448-goldilocks/src/curve/twedwards/projective.rs +++ b/ed448-goldilocks/src/curve/twedwards/projective.rs @@ -1,6 +1,6 @@ #![allow(non_snake_case)] -use crate::curve::twedwards::extended::ExtendedPoint; +use super::extensible::ExtensiblePoint; use crate::field::FieldElement; use subtle::{Choice, ConditionallyNegatable, ConditionallySelectable}; @@ -22,7 +22,7 @@ pub struct ProjectiveNielsPoint { impl PartialEq for ProjectiveNielsPoint { fn eq(&self, other: &ProjectiveNielsPoint) -> bool { - self.to_extended().eq(&other.to_extended()) + self.to_extensible().eq(&other.to_extensible()) } } impl Eq for ProjectiveNielsPoint {} @@ -52,21 +52,22 @@ impl ProjectiveNielsPoint { Z: FieldElement::TWO, }; - pub fn to_extended(self) -> ExtendedPoint { + pub fn to_extensible(self) -> ExtensiblePoint { let A = self.Y_plus_X - self.Y_minus_X; let B = self.Y_plus_X + self.Y_minus_X; - ExtendedPoint { + ExtensiblePoint { X: self.Z * A, Y: self.Z * B, Z: self.Z.square(), - T: B * A, + T1: B, + T2: A, } } } #[cfg(test)] mod tests { use super::*; - use crate::curve::twedwards::extensible::ExtensiblePoint; + use crate::curve::twedwards::extended::ExtendedPoint; #[test] fn identity() { @@ -75,11 +76,11 @@ mod tests { // and then both sides are converted to twisted-curve form. assert_eq!( ProjectiveNielsPoint::IDENTITY, - ExtensiblePoint::IDENTITY.to_projective_niels(), + ExtendedPoint::IDENTITY.to_projective_niels(), ); // Here only the left-side identity point is converted. assert_eq!( - ProjectiveNielsPoint::IDENTITY.to_extended(), + ProjectiveNielsPoint::IDENTITY.to_extensible(), ExtendedPoint::IDENTITY, ); } @@ -88,10 +89,10 @@ mod tests { fn test_conditional_negate() { let bp = ExtendedPoint::GENERATOR; - let mut bp_neg = bp.to_extensible().to_projective_niels(); + let mut bp_neg = bp.to_projective_niels(); bp_neg.conditional_negate(1.into()); - let expect_identity = bp_neg.to_extended().add(&bp); + let expect_identity = bp_neg.to_extensible().to_extended().add_extended(&bp); assert_eq!(ExtendedPoint::IDENTITY, expect_identity); } } diff --git a/ed448-goldilocks/src/decaf/ops.rs b/ed448-goldilocks/src/decaf/ops.rs index 97f82f2a2..1ba168537 100644 --- a/ed448-goldilocks/src/decaf/ops.rs +++ b/ed448-goldilocks/src/decaf/ops.rs @@ -14,7 +14,7 @@ impl Mul<&DecafScalar> for &DecafPoint { fn mul(self, scalar: &DecafScalar) -> DecafPoint { // XXX: We can do better than double and add - DecafPoint(double_and_add(&self.0, scalar.bits())) + DecafPoint(double_and_add(&self.0, scalar.bits()).to_extended()) } } @@ -37,7 +37,7 @@ impl Add<&DecafPoint> for &DecafPoint { type Output = DecafPoint; fn add(self, other: &DecafPoint) -> DecafPoint { - DecafPoint(self.0.to_extensible().add_extended(&other.0).to_extended()) + DecafPoint(self.0.add_extended(&other.0).to_extended()) } } @@ -101,7 +101,7 @@ impl Sub<&DecafPoint> for &DecafPoint { type Output = DecafPoint; fn sub(self, other: &DecafPoint) -> DecafPoint { - DecafPoint(self.0.to_extensible().sub_extended(&other.0).to_extended()) + DecafPoint(self.0.sub_extended(&other.0).to_extended()) } } diff --git a/ed448-goldilocks/src/decaf/points.rs b/ed448-goldilocks/src/decaf/points.rs index e075604a4..47ef0942a 100644 --- a/ed448-goldilocks/src/decaf/points.rs +++ b/ed448-goldilocks/src/decaf/points.rs @@ -200,7 +200,7 @@ impl Group for DecafPoint { } fn double(&self) -> Self { - Self(self.0.double()) + Self(self.0.to_extensible().double().to_extended()) } } @@ -248,19 +248,19 @@ impl CurveGroup for DecafPoint { type AffineRepr = DecafAffinePoint; fn to_affine(&self) -> Self::AffineRepr { - DecafAffinePoint(self.0.to_affine()) + DecafAffinePoint(self.0.to_extensible().to_affine()) } } impl From for DecafPoint { fn from(point: EdwardsPoint) -> Self { - Self(point.to_twisted()) + Self(point.to_twisted().to_extended()) } } impl From<&EdwardsPoint> for DecafPoint { fn from(point: &EdwardsPoint) -> Self { - Self(point.to_twisted()) + Self(point.to_twisted().to_extended()) } } @@ -290,13 +290,13 @@ impl From<&DecafAffinePoint> for DecafPoint { impl From for DecafAffinePoint { fn from(point: DecafPoint) -> Self { - DecafAffinePoint(point.0.to_affine()) + DecafAffinePoint(point.0.to_extensible().to_affine()) } } impl From<&DecafPoint> for DecafAffinePoint { fn from(point: &DecafPoint) -> Self { - DecafAffinePoint(point.0.to_affine()) + DecafAffinePoint(point.0.to_extensible().to_affine()) } } @@ -315,12 +315,12 @@ impl DecafPoint { /// Add two points pub fn add(&self, other: &DecafPoint) -> DecafPoint { - DecafPoint(self.0.to_extensible().add_extended(&other.0).to_extended()) + DecafPoint(self.0.add_extended(&other.0).to_extended()) } /// Subtract two points pub fn sub(&self, other: &DecafPoint) -> DecafPoint { - DecafPoint(self.0.to_extensible().sub_extended(&other.0).to_extended()) + DecafPoint(self.0.sub_extended(&other.0).to_extended()) } /// Compress this point @@ -377,7 +377,7 @@ impl DecafPoint { let u1 = FieldElement::from_bytes(&hi); let q0 = u0.map_to_curve_decaf448(); let q1 = u1.map_to_curve_decaf448(); - Self(q0.add(&q1)) + Self(q0.add_extended(&q1).to_extended()) } } @@ -608,8 +608,8 @@ mod test { let P = TWISTED_EDWARDS_BASE_POINT; - let P2 = P.double(); - let P3 = P2.to_extensible().add_extended(&P).to_extended(); + let P2 = P.to_extensible().double().to_extended(); + let P3 = P2.add_extended(&P).to_extended(); // Encode and decode to make them Decaf points let Decaf_P = DecafPoint(P).compress().decompress().unwrap(); diff --git a/ed448-goldilocks/src/edwards/extended.rs b/ed448-goldilocks/src/edwards/extended.rs index 3634e06ef..f914abf43 100644 --- a/ed448-goldilocks/src/edwards/extended.rs +++ b/ed448-goldilocks/src/edwards/extended.rs @@ -4,8 +4,8 @@ use core::iter::Sum; use core::ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub, SubAssign}; use crate::curve::scalar_mul::variable_base; -use crate::curve::twedwards::IsogenyMap; -use crate::curve::twedwards::extended::ExtendedPoint as TwistedExtendedPoint; +use crate::curve::twedwards::extensible::ExtensiblePoint as TwistedExtensiblePoint; +use crate::curve::twedwards::{IsogenyMap, IsogenyMapResult}; use crate::edwards::affine::PointBytes; use crate::field::{ConstMontyType, FieldElement}; use crate::*; @@ -337,7 +337,9 @@ impl EdwardsPoint { let scalar_div_four = scalar.div_by_2().div_by_2(); // Use isogeny and dual isogeny to compute phi^-1((s/4) * phi(P)) - variable_base(&self.to_twisted(), &scalar_div_four).to_untwisted() + variable_base(&self.to_twisted().to_extended(), &scalar_div_four) + .to_extended() + .to_untwisted() } /// Add two points @@ -405,16 +407,16 @@ impl EdwardsPoint { AffinePoint { x, y } } - pub(crate) fn to_twisted(self) -> TwistedExtendedPoint { - let IsogenyMap { X, Y, T, Z } = IsogenyMap { + pub(crate) fn to_twisted(self) -> TwistedExtensiblePoint { + let IsogenyMapResult { X, Y, Z, T1, T2 } = IsogenyMap { X: self.X, Y: self.Y, - T: self.T, Z: self.Z, + T: self.T, } .map(|f| f); - TwistedExtendedPoint { X, Y, Z, T } + TwistedExtensiblePoint { X, Y, Z, T1, T2 } } /// Compute the negation of this point's `x`-coordinate. @@ -833,7 +835,7 @@ mod tests { "ae05e9634ad7048db359d6205086c2b0036ed7a035884dd7b7e36d728ad8c4b80d6565833a2a3098bbbcb2bed1cda06bdaeafbcdea9386ed", ); let a = AffinePoint { x, y }.to_edwards(); - let twist_a = a.to_twisted().to_untwisted(); + let twist_a = a.to_twisted().to_extended().to_untwisted(); assert!(twist_a == a.double().double()) }