update elliptic curve libraries
Signed-off-by: Uncle Fatso <uncle.fatso@ghostchain.io>
This commit is contained in:
parent
c66175a577
commit
3c5963eab9
@ -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;
|
||||
|
||||
@ -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)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user