update elliptic curve libraries

Signed-off-by: Uncle Fatso <uncle.fatso@ghostchain.io>
This commit is contained in:
Uncle Fatso 2025-10-28 20:03:26 +03:00
parent c66175a577
commit 3c5963eab9
Signed by: f4ts0
GPG Key ID: 565F4F2860226EBB
2 changed files with 55 additions and 29 deletions

View File

@ -10,6 +10,9 @@ pragma solidity ^0.8.0;
** @author Witnet Foundation
*/
library EllipticCurve {
// Pre-computed constant for 2 ** 128 - 1
uint256 private constant U128_MAX = 340282366920938463463374607431768211455;
// Pre-computed constant for 2 ** 255
uint256 private constant U255_MAX_PLUS_1 =
57896044618658097711785492504343953926634992332820282019728792003956564819968;

View File

@ -14,8 +14,6 @@ library EllipticCurveProjective {
uint256 public constant P = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F;
uint256 public constant N = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141;
uint256 private constant B3 = 21;
function findMaxBitLength(
uint256 k1,
uint256 k2,
@ -72,9 +70,41 @@ library EllipticCurveProjective {
}
}
function mulAddProjectiveSingle(
uint256 x1, uint256 y1, uint256 k1
) internal pure returns (uint256 x2, uint256 y2, uint256 z2) {
// We implement the Straus-Shamir trick described in
// Trading Inversions for Multiplications in Elliptic Curve Cryptography.
// (https://eprint.iacr.org/2003/257.pdf Page 7).
// TODO: handle edge case k1 == 0
uint256 bits = findMaxBitLength(k1, 0, 0, 0);
x2 = 0;
y2 = 1;
z2 = 0;
for (; bits > 0;) {
unchecked { --bits; }
(x2, y2, z2) = projectiveDouble(x2, y2, z2);
uint8 mask;
assembly {
mask := and(shr(bits, k1), 1)
}
if (mask != 0) {
(x2, y2, z2) = projectiveAddMixed(
x2, y2, z2, x1, y1
);
}
}
}
function mulAddProjectivePair(
uint256 x1, uint256 y1, uint256 k1,
uint256 x2, uint256 y2, uint256 k2
uint256 x1, uint256 y1, uint256 z1, uint256 k1,
uint256 x2, uint256 y2, uint256 z2, uint256 k2
) internal pure returns (uint256 x3, uint256 y3, uint256 z3) {
// We implement the Straus-Shamir trick described in
// Trading Inversions for Multiplications in Elliptic Curve Cryptography.
@ -86,10 +116,10 @@ library EllipticCurveProjective {
uint256[4] memory precomputedYs;
uint256[4] memory precomputedZs;
precomputedXs[1] = x2; precomputedYs[1] = y2; precomputedZs[1] = 1; // 01: P2
precomputedXs[2] = x1; precomputedYs[2] = y1; precomputedZs[2] = 1; // 10: P1
precomputedXs[1] = x2; precomputedYs[1] = y2; precomputedZs[1] = z2; // 01: P2
precomputedXs[2] = x1; precomputedYs[2] = y1; precomputedZs[2] = z1; // 10: P1
(x3, y3, z3) = projectiveAddMixed(x1, y1, 1, x2, y2); // 11: P1+P2
(x3, y3, z3) = projectiveAdd(x1, y1, z1, x2, y2, z2); // 11: P1+P2
precomputedXs[3] = x3;
precomputedYs[3] = y3;
precomputedZs[3] = z3;
@ -111,18 +141,10 @@ library EllipticCurveProjective {
)
}
if (mask == 0) {
continue;
}
if (mask == 3) {
if (mask != 0) {
(x3, y3, z3) = projectiveAdd(
x3, y3, z3, precomputedXs[mask], precomputedYs[mask], precomputedZs[mask]
);
} else {
(x3, y3, z3) = projectiveAddMixed(
x3, y3, z3, precomputedXs[mask], precomputedYs[mask]
);
}
}
}
@ -204,7 +226,7 @@ library EllipticCurveProjective {
uint256 x2, uint256 y2, uint256 k2,
uint256 x3, uint256 y3, uint256 k3,
uint256 x4, uint256 y4, uint256 k4
) internal pure returns (uint256 x5, uint256 y5, uint256 z5) {
) internal pure returns (uint256, uint256, uint256) {
// We implement the Straus-Shamir trick described in
// Trading Inversions for Multiplications in Elliptic Curve Cryptography.
// (https://eprint.iacr.org/2003/257.pdf Page 7).
@ -267,14 +289,14 @@ library EllipticCurveProjective {
y4
); // 1111: P4+P3+P2+P1
x5 = 0;
y5 = 1;
z5 = 0;
x1 = 0;
y1 = 1;
uint256 z1 = 0;
for (; bits > 0;) {
unchecked { --bits; }
(x5, y5, z5) = projectiveDouble(x5, y5, z5);
(x1, y1, z1) = projectiveDouble(x1, y1, z1);
uint8 mask;
uint16 bitmask;
@ -300,15 +322,16 @@ library EllipticCurveProjective {
}
if (bitmask == 1) {
(x5, y5, z5) = projectiveAddMixed(
x5, y5, z5, precomputedXs[mask], precomputedYs[mask]
(x1, y1, z1) = projectiveAddMixed(
x1, y1, z1, precomputedXs[mask], precomputedYs[mask]
);
} else {
(x5, y5, z5) = projectiveAdd(
x5, y5, z5, precomputedXs[mask], precomputedYs[mask], precomputedZs[mask]
(x1, y1, z1) = projectiveAdd(
x1, y1, z1, precomputedXs[mask], precomputedYs[mask], precomputedZs[mask]
);
}
}
return (x1, y1, z1);
}
function projectiveAddMixed(
@ -335,10 +358,10 @@ library EllipticCurveProjective {
Y3 = mulmod(X2, Z1, P); // 8. Y3 X2 · Z1 => (X2·Z1)
Y3 = addmod(Y3, X1, P); // 9. Y3 Y3 + X1 => (X2·Z1 + X1)
t0 = mulmod(3, t0, P); // 10. t0 X3 + t0 => (3·(X1·X2))
uint256 t2 = mulmod(B3, Z1, P); // 11. t2 b3 · Z1 => (b3·Z1)
uint256 t2 = mulmod(21, Z1, P); // 11. t2 b3 · Z1 => (b3·Z1)
Z3 = addmod(t1, t2, P); // 12. Z3 t1 + t2 => (Y1·Y2 + b·3·Z1)
t1 = addmod(t1, P - t2, P); // 13. t1 t1 t2 => (Y1·Y2 - b·3·Z1)
Y3 = mulmod(B3, Y3, P); // 14. Y3 b3 · Y3 => 3·b·(X2·Z1 + X1)
Y3 = mulmod(21, Y3, P); // 14. Y3 b3 · Y3 => 3·b·(X2·Z1 + X1)
X3 = mulmod(t4, Y3, P); // 15. X3 t4 · Y3 => (Y2·Z1 + Y1)·b·3·(X2·Z1 + X1)
t2 = mulmod(t3, t1, P); // 16. t2 t3 · t1 => ((X2·Y1 + X1·Y2)·(Y1·Y2 - b3·Z1))
X3 = addmod(t2, P - X3, P); // 17. X3 t2 X3 => ((X2·Y1 + X1·Y2)·(Y1·Y2 - b3·Z1) - 3·B·(Y2·Z1 + Y1)·(X2·Z1 + X1))
@ -385,10 +408,10 @@ library EllipticCurveProjective {
Y3 = addmod(X3, P - Y3, P); // 18. Y3 X3 - Y3 => ((X1 + Z1)·(X2 + Z2) - X1·X2 - Z1·Z2)
X3 = addmod(t0, t0, P); // 19. X3 t0 + t0 => (2·X1·X2)
t0 = addmod(X3, t0, P); // 20. t0 X3 + t0 => (3·X1·X2)
t2 = mulmod(B3, t2, P); // 21. t2 B3 · t2 => 3b · Z1·Z2
t2 = mulmod(21, t2, P); // 21. t2 B3 · t2 => 3b · Z1·Z2
Z3 = addmod(t1, t2, P); // 22. Z3 t1 + t2 => Y1·Y2 + 3·b·Z1·Z2
t1 = addmod(t1, P - t2, P); // 23. t1 t1 - t2 => Y1·Y2 - 3·b·Z1·Z2
Y3 = mulmod(B3, Y3, P); // 24. Y3 B3 · Y3 => 3b · ((X1+Z1)(X2+Z2) - X1·X2 - Z1·Z2)
Y3 = mulmod(21, Y3, P); // 24. Y3 B3 · Y3 => 3b · ((X1+Z1)(X2+Z2) - X1·X2 - Z1·Z2)
X3 = mulmod(t4, Y3, P); // 25. X3 t4 · Y3 => 3b·((Y1+Z1)(Y2+Z2)-Y1·Y2-Z1·Z2) · ((X1+Z1)(X2+Z2)-X1·X2-Z1·Z2)
t2 = mulmod(t3, t1, P); // 26. t2 t3 · t1 => ((X1+Y1)(X2+Y2)-X1·X2-Y1·Y2) · (Y1·Y2 - 3·b·Z1·Z2)
X3 = addmod(t2, P - X3, P); // 27. X3 t2 - X3 => (X1Y2+X2Y1)(Y1·Y2-3·b·Z1·Z2) - 3b(Y1·Z2+Y2·Z1)(X1·Z2+X2·Z1)