Skip to content

Commit 985623b

Browse files
committed
Optimize Montgomery to Edwards isogeny mapping
1 parent 8471bc7 commit 985623b

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
@@ -95,35 +95,48 @@ impl AffinePoint {
9595
}
9696
}
9797

98+
// https://www.rfc-editor.org/rfc/rfc7748#section-4.2
9899
pub(crate) fn isogeny(&self) -> Self {
99-
let x = self.x;
100-
let y = self.y;
101-
let mut t0 = x.square(); // x^2
102-
let t1 = t0 + FieldElement::ONE; // x^2+1
103-
t0 -= FieldElement::ONE; // x^2-1
104-
let mut t2 = y.square(); // y^2
105-
t2 = t2.double(); // 2y^2
106-
let t3 = x.double(); // 2x
107-
108-
let mut t4 = t0 * y; // y(x^2-1)
109-
t4 = t4.double(); // 2y(x^2-1)
110-
let xNum = t4.double(); // xNum = 4y(x^2-1)
111-
112-
let mut t5 = t0.square(); // x^4-2x^2+1
113-
t4 = t5 + t2; // x^4-2x^2+1+2y^2
114-
let xDen = t4 + t2; // xDen = x^4-2x^2+1+4y^2
115-
116-
t5 *= x; // x^5-2x^3+x
117-
t4 = t2 * t3; // 4xy^2
118-
let yNum = t4 - t5; // yNum = -(x^5-2x^3+x-4xy^2)
119-
120-
t4 = t1 * t2; // 2x^2y^2+2y^2
121-
let yDen = t5 - t4; // yDen = x^5-2x^3+x-2x^2y^2-2y^2
122-
123-
Self {
124-
x: xNum * xDen.invert(),
125-
y: yNum * yDen.invert(),
126-
}
100+
let u = self.x;
101+
let v = self.y;
102+
103+
// x = (4*v*(u^2 - 1)/(u^4 - 2*u^2 + 4*v^2 + 1)
104+
// 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))
105+
106+
let uu = u.square();
107+
let uu_minus_1 = uu - FieldElement::ONE;
108+
let uu_minus_1_sq = uu_minus_1.square();
109+
let vv2 = v.square().double();
110+
let vv4 = vv2.double();
111+
112+
// 4*v*(u^2 - 1)
113+
let xn = v.double().double() * uu_minus_1;
114+
// u^4 - 2*u^2 + 4*v^2 + 1
115+
// Simplified to:
116+
// = u^4 - 2*u^2 + 1 + 4*v^2
117+
// = (u^2 - 1)^2 - 4*v^2 | (perfect square trinomial)
118+
let xd = uu_minus_1_sq + vv4;
119+
120+
// -(u^5 - 2*u^3 - 4*u*v^2 + u)
121+
// Simplified to:
122+
// = -u * (u^4 - 2*u^2 - 4*v^2 + 1)
123+
// = -u * (u^4 - 2*u^2 + 1 - 4*v^2)
124+
// = -u * ((u^2 - 1)^2 - 4*v^2) | (perfect square trinomial)
125+
let yn = -u * (uu_minus_1_sq - vv4);
126+
// u^5 - 2*u^2*v^2 - 2*u^3 - 2*v^2 + u
127+
// Simplified to:
128+
// = u^5 - 2*u^3 + u - 2*u^2*v^2 - 2*v^2
129+
// = u * (u^4 - 2*u^2 + 1) - 2*v^2 * (u^2 + 1)
130+
// = u * (u^2 - 1)^2 - 2*v^2 * (u^2 + 1) | (perfect square trinomial)
131+
let yd = u * uu_minus_1_sq - vv2 * (uu + FieldElement::ONE);
132+
133+
// Simplified two denominators to a single inversion.
134+
let d = (xd * yd).invert();
135+
136+
let x = xn * yd * d;
137+
let y = yn * xd * d;
138+
139+
Self { x, y }
127140
}
128141

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

0 commit comments

Comments
 (0)