Skip to content

Commit 373eabe

Browse files
cairoethAmxxernestognw
authored
Optimizations to P256 operations (#5181)
Co-authored-by: Hadrien Croubois <[email protected]> Co-authored-by: Ernesto García <[email protected]>
1 parent 29a9539 commit 373eabe

File tree

1 file changed

+19
-18
lines changed

1 file changed

+19
-18
lines changed

contracts/utils/cryptography/P256.sol

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -125,11 +125,12 @@ library P256 {
125125
return (0, 0);
126126
}
127127

128+
uint256 p = P; // cache P on the stack
128129
uint256 rx = uint256(r);
129-
uint256 ry2 = addmod(mulmod(addmod(mulmod(rx, rx, P), A, P), rx, P), B, P); // weierstrass equation y² = x³ + a.x + b
130-
uint256 ry = Math.modExp(ry2, P1DIV4, P); // This formula for sqrt work because P ≡ 3 (mod 4)
131-
if (mulmod(ry, ry, P) != ry2) return (0, 0); // Sanity check
132-
if (ry % 2 != v % 2) ry = P - ry;
130+
uint256 ry2 = addmod(mulmod(addmod(mulmod(rx, rx, p), A, p), rx, p), B, p); // weierstrass equation y² = x³ + a.x + b
131+
uint256 ry = Math.modExp(ry2, P1DIV4, p); // This formula for sqrt work because P ≡ 3 (mod 4)
132+
if (mulmod(ry, ry, p) != ry2) return (0, 0); // Sanity check
133+
if (ry % 2 != v % 2) ry = p - ry;
133134

134135
JPoint[16] memory points = _preComputeJacobianPoints(rx, ry);
135136
uint256 w = Math.invModPrime(uint256(r), N);
@@ -170,11 +171,13 @@ library P256 {
170171
*/
171172
function _affineFromJacobian(uint256 jx, uint256 jy, uint256 jz) private view returns (uint256 ax, uint256 ay) {
172173
if (jz == 0) return (0, 0);
173-
uint256 zinv = Math.invModPrime(jz, P);
174-
uint256 zzinv = mulmod(zinv, zinv, P);
175-
uint256 zzzinv = mulmod(zzinv, zinv, P);
176-
ax = mulmod(jx, zzinv, P);
177-
ay = mulmod(jy, zzzinv, P);
174+
uint256 p = P; // cache P on the stack
175+
uint256 zinv = Math.invModPrime(jz, p);
176+
assembly ("memory-safe") {
177+
let zzinv := mulmod(zinv, zinv, p)
178+
ax := mulmod(jx, zzinv, p)
179+
ay := mulmod(jy, mulmod(zzinv, zinv, p), p)
180+
}
178181
}
179182

180183
/**
@@ -190,12 +193,11 @@ library P256 {
190193
assembly ("memory-safe") {
191194
let p := P
192195
let z1 := mload(add(p1, 0x40))
196+
let zz1 := mulmod(z1, z1, p) // zz1 = z1²
193197
let s1 := mulmod(mload(add(p1, 0x20)), mulmod(mulmod(z2, z2, p), z2, p), p) // s1 = y1*z2³
194-
let s2 := mulmod(y2, mulmod(mulmod(z1, z1, p), z1, p), p) // s2 = y2*z1³
195-
let r := addmod(s2, sub(p, s1), p) // r = s2-s1
198+
let r := addmod(mulmod(y2, mulmod(zz1, z1, p), p), sub(p, s1), p) // r = s2-s1 = y2*z1³-s1
196199
let u1 := mulmod(mload(p1), mulmod(z2, z2, p), p) // u1 = x1*z2²
197-
let u2 := mulmod(x2, mulmod(z1, z1, p), p) // u2 = x2*z1²
198-
let h := addmod(u2, sub(p, u1), p) // h = u2-u1
200+
let h := addmod(mulmod(x2, zz1, p), sub(p, u1), p) // h = u2-u1 = x2*z1²-u1
199201
let hh := mulmod(h, h, p) // h²
200202

201203
// x' = r²-h³-2*u1*h²
@@ -226,12 +228,11 @@ library P256 {
226228
let zz := mulmod(z, z, p)
227229
let s := mulmod(4, mulmod(x, yy, p), p) // s = 4*x*y²
228230
let m := addmod(mulmod(3, mulmod(x, x, p), p), mulmod(A, mulmod(zz, zz, p), p), p) // m = 3*x²+a*z⁴
229-
let t := addmod(mulmod(m, m, p), sub(p, mulmod(2, s, p)), p) // t = m²-2*s
230231

231-
// x' = t
232-
rx := t
233-
// y' = m*(s-t)-8*y⁴
234-
ry := addmod(mulmod(m, addmod(s, sub(p, t), p), p), sub(p, mulmod(8, mulmod(yy, yy, p), p)), p)
232+
// x' = t = m²-2*s
233+
rx := addmod(mulmod(m, m, p), sub(p, mulmod(2, s, p)), p)
234+
// y' = m*(s-t)-8*y⁴ = m*(s-x')-8*y⁴
235+
ry := addmod(mulmod(m, addmod(s, sub(p, rx), p), p), sub(p, mulmod(8, mulmod(yy, yy, p), p)), p)
235236
// z' = 2*y*z
236237
rz := mulmod(2, mulmod(y, z, p), p)
237238
}

0 commit comments

Comments
 (0)