Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 53 additions & 0 deletions ed448-goldilocks/src/curve/twedwards.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,56 @@ pub(crate) mod affine;
pub(crate) mod extended;
pub(crate) mod extensible;
pub(crate) mod projective;

use crate::field::FieldElement;

pub(crate) struct IsogenyMap {
pub(crate) X: FieldElement,
pub(crate) Y: FieldElement,
pub(crate) T: FieldElement,
pub(crate) Z: FieldElement,
}

impl IsogenyMap {
// (1.) https://eprint.iacr.org/2014/027.pdf
pub(crate) fn map(&self, scale: impl FnOnce(FieldElement) -> FieldElement) -> Self {
// x = 2xy / (y^2 - a*x^2)
// y = (y^2 + a*x^2) / (2 - y^2 - a*x^2)

// Derive algorithm for projective form:

// x = X / Z
// y = Y / Z
// xy = T / Z
// x^2 = X^2 / Z^2
// y^2 = y^2 / Z^2

// x = 2xy / (y^2 - a*x^2)
// x = (2T/Z) / (Y^2/Z^2 + a*X^2/Z^2)
// x = 2TZ / (Y^2 - a*X^2)

// y = (y^2 + a*x^2) / (2 - y^2 - a*x^2)
// y = (Y^2/Z^2 + a*X^2/Z^2) / (2 - Y^2/Z^2 - a*X^2/Z^2)
// y = (Y^2 + a*X^2) / (2*Z^2 - Y^2 - a*X^2)

let xx = self.X.square();
let yy = self.Y.square();
let axx = scale(xx);
let yy_plus_axx = yy + axx;

// Compute x
let x_numerator = (self.T * self.Z).double();
let x_denom = yy - axx;

// Compute y
let y_numerator = yy_plus_axx;
let y_denom = self.Z.square().double() - yy_plus_axx;

let X = x_numerator * y_denom;
let Y = y_numerator * x_denom;
let T = x_numerator * y_numerator;
let Z = x_denom * y_denom;

Self { X, Y, T, Z }
}
}
44 changes: 11 additions & 33 deletions ed448-goldilocks/src/curve/twedwards/extended.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
#![allow(non_snake_case)]
#![allow(dead_code)]

use crate::curve::twedwards::affine::AffinePoint;
use crate::curve::twedwards::extensible::ExtensiblePoint;
use super::IsogenyMap;
use super::affine::AffinePoint;
use super::extensible::ExtensiblePoint;
use crate::edwards::EdwardsPoint as EdwardsExtendedPoint;
use crate::field::FieldElement;
use subtle::{Choice, ConditionallySelectable, ConstantTimeEq};
Expand Down Expand Up @@ -105,39 +106,16 @@ impl ExtendedPoint {
}

/// Uses a 2-isogeny to map the point to the Ed448-Goldilocks
// (2. Algorithm 2) https://eprint.iacr.org/2008/522.pdf
pub fn to_untwisted(self) -> EdwardsExtendedPoint {
// x = 2xy / (y^2 + a*x^2)
// y = (y^2 - a*x^2) / (2 - y^2 - a*x^2)

// Convert to affine now, then derive extended version later
let affine = self.to_affine();
let x = affine.x;
let y = affine.y;

let yy = y.square();
let xx = x.square();
let axx = -xx;
let yy_plus_axx = yy + axx;

// Compute x
let x_numerator = (x * y).double();
let x_denom = yy - axx;

// Compute y
let y_numerator = yy_plus_axx;
let y_denom = FieldElement::TWO - yy_plus_axx;

let common_denom = (x_denom * y_denom).invert();
let new_x = x_numerator * y_denom * common_denom;
let new_y = y_numerator * x_denom * common_denom;

EdwardsExtendedPoint {
X: new_x,
Y: new_y,
Z: FieldElement::ONE,
T: new_x * new_y,
let IsogenyMap { X, Y, T, Z } = IsogenyMap {
X: self.X,
Y: self.Y,
T: self.T,
Z: self.Z,
}
.map(|f| -f);

EdwardsExtendedPoint { X, Y, Z, T }
}

/// Checks if the point is on the curve
Expand Down
30 changes: 9 additions & 21 deletions ed448-goldilocks/src/edwards/extended.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ 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::field::FieldElement;
use crate::*;
Expand Down Expand Up @@ -669,29 +670,16 @@ impl EdwardsPoint {
AffinePoint { x, y }
}

// Copied from https://github.com/otrv4/libgoldilocks/blob/d07cb5b423995bae1155702aa949846c95d855c1/src/goldilocks.c#L980-L994.
pub(crate) fn to_twisted(self) -> TwistedExtendedPoint {
let c = self.X.square();
let a = self.Y.square();
let d = c + a;
let t = self.Y + self.X;
let b = t.square();
let b = b - d;
let t = a - c;
let x = self.Z.square();
let z = x.double();
let a = z - d;
let new_x = a * b;
let new_z = t * a;
let new_y = t * d;
let new_t = b * d;

TwistedExtendedPoint {
X: new_x,
Y: new_y,
Z: new_z,
T: new_t,
let IsogenyMap { X, Y, T, Z } = IsogenyMap {
X: self.X,
Y: self.Y,
T: self.T,
Z: self.Z,
}
.map(|f| f);

TwistedExtendedPoint { X, Y, Z, T }
}

/// Compute the negation of this point's `x`-coordinate.
Expand Down