Skip to content

Commit 173d682

Browse files
committed
Optimize Montgomery to Edwards isogeny mapping
1 parent 538020d commit 173d682

File tree

1 file changed

+41
-28
lines changed

1 file changed

+41
-28
lines changed

ed448-goldilocks/src/edwards/affine.rs

Lines changed: 41 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -86,35 +86,48 @@ impl AffinePoint {
8686
}
8787
}
8888

89+
// https://www.rfc-editor.org/rfc/rfc7748#section-4.2
8990
pub(crate) fn isogeny(&self) -> Self {
90-
let x = self.x;
91-
let y = self.y;
92-
let mut t0 = x.square(); // x^2
93-
let t1 = t0 + FieldElement::ONE; // x^2+1
94-
t0 -= FieldElement::ONE; // x^2-1
95-
let mut t2 = y.square(); // y^2
96-
t2 = t2.double(); // 2y^2
97-
let t3 = x.double(); // 2x
98-
99-
let mut t4 = t0 * y; // y(x^2-1)
100-
t4 = t4.double(); // 2y(x^2-1)
101-
let xNum = t4.double(); // xNum = 4y(x^2-1)
102-
103-
let mut t5 = t0.square(); // x^4-2x^2+1
104-
t4 = t5 + t2; // x^4-2x^2+1+2y^2
105-
let xDen = t4 + t2; // xDen = x^4-2x^2+1+4y^2
106-
107-
t5 *= x; // x^5-2x^3+x
108-
t4 = t2 * t3; // 4xy^2
109-
let yNum = t4 - t5; // yNum = -(x^5-2x^3+x-4xy^2)
110-
111-
t4 = t1 * t2; // 2x^2y^2+2y^2
112-
let yDen = t5 - t4; // yDen = x^5-2x^3+x-2x^2y^2-2y^2
113-
114-
Self {
115-
x: xNum * xDen.invert(),
116-
y: yNum * yDen.invert(),
117-
}
91+
let u = self.x;
92+
let v = self.y;
93+
94+
// x = (4*v*(u^2 - 1)/(u^4 - 2*u^2 + 4*v^2 + 1)
95+
// y = -(u^5 - 2*u^3 - 4*u*v^2 + u)/(u^5 - 2*u^2*v^2 - 2*u^3 - 2*v^2 + u))
96+
97+
let uu = u.square();
98+
let uu_minus_1 = uu - FieldElement::ONE;
99+
let uu_minus_1_sq = uu_minus_1.square();
100+
let vv2 = v.square().double();
101+
let vv4 = vv2.double();
102+
103+
// 4*v*(u^2 - 1)
104+
let xn = v.double().double() * uu_minus_1;
105+
// u^4 - 2*u^2 + 4*v^2 + 1
106+
// Simplified to:
107+
// = u^4 - 2*u^2 + 1 + 4*v^2
108+
// = (u^2 - 1)^2 - 4*v^2 | (perfect square trinomial)
109+
let xd = uu_minus_1_sq + vv4;
110+
111+
// -(u^5 - 2*u^3 - 4*u*v^2 + u)
112+
// Simplified to:
113+
// = -u * (u^4 - 2*u^2 - 4*v^2 + 1)
114+
// = -u * (u^4 - 2*u^2 + 1 - 4*v^2)
115+
// = -u * ((u^2 - 1)^2 - 4*v^2) | (perfect square trinomial)
116+
let yn = -u * (uu_minus_1_sq - vv4);
117+
// u^5 - 2*u^2*v^2 - 2*u^3 - 2*v^2 + u
118+
// Simplified to:
119+
// = u^5 - 2*u^3 + u - 2*u^2*v^2 - 2*v^2
120+
// = u * (u^4 - 2*u^2 + 1) - 2*v^2 * (u^2 + 1)
121+
// = u * (u^2 - 1)^2 - 2*v^2 * (u^2 + 1) | (perfect square trinomial)
122+
let yd = u * uu_minus_1_sq - vv2 * (uu + FieldElement::ONE);
123+
124+
// Simplified two denominators to a single inversion.
125+
let d = (xd * yd).invert();
126+
127+
let x = xn * yd * d;
128+
let y = yn * xd * d;
129+
130+
Self { x, y }
118131
}
119132

120133
/// Standard compression; store Y and sign of X

0 commit comments

Comments
 (0)