ghost-exodus-draft/src/MathTester.sol
Uncle Fatso c66175a577
Shamir-Straus trick for pair and quartet
Signed-off-by: Uncle Fatso <uncle.fatso@ghostchain.io>
2025-10-18 15:48:45 +03:00

153 lines
4.8 KiB
Solidity

// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.0;
import {EllipticCurve} from "./libraries/ECMath.sol";
import {EllipticCurveProjective} from "./libraries/ECMathProjective.sol";
contract MathTester {
// Constants are taken from https://en.bitcoin.it/wiki/Secp256k1
uint256 public constant A = 0;
uint256 public constant B = 7;
uint256 public constant P = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F;
uint256 public constant N = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141;
function addJacobian(
uint256 x1,
uint256 y1,
uint256 x2,
uint256 y2
) public pure returns (uint256, uint256, uint256) {
return EllipticCurve.jacAdd(x1, y1, 1, x2, y2, 1, P);
}
function addProjective(
uint256 x1,
uint256 y1,
uint256 x2,
uint256 y2
) public pure returns (uint256, uint256, uint256) {
return EllipticCurveProjective.projectiveAdd(x1, y1, 1, x2, y2, 1);
}
function doubleJacobian(uint256 x1, uint256 y1) public pure returns (uint256, uint256, uint256) {
return EllipticCurve.jacDouble(x1, y1, 1, A, P);
}
function doubleProjective(uint256 x1, uint256 y1) public pure returns (uint256, uint256, uint256) {
return EllipticCurveProjective.projectiveDouble(x1, y1, 1);
}
function addProjectiveMixed(
uint256 x1,
uint256 y1,
uint256 x2,
uint256 y2
) public pure returns (uint256, uint256, uint256) {
return EllipticCurveProjective.projectiveAddMixed(x1, y1, 1, x2, y2);
}
function mulEcTriplet(
uint256 x1,
uint256 y1,
uint256 k1,
uint256 x2,
uint256 y2,
uint256 k2,
uint256 x3,
uint256 y3,
uint256 k3
) public pure returns(uint256, uint256) {
(x1, y1) = EllipticCurve.ecMul(k1, x1, y1, A, P);
(x2, y2) = EllipticCurve.ecMul(k2, x2, y2, A, P);
(x3, y3) = EllipticCurve.ecMul(k3, x3, y3, A, P);
(x1, y1) = EllipticCurve.ecAdd(x1, y1, x2, y2, A, P);
(x1, y1) = EllipticCurve.ecAdd(x1, y1, x3, y3, A, P);
return (x1, y1);
}
function mulProjectiveTriplet(
uint256 x1,
uint256 y1,
uint256 k1,
uint256 x2,
uint256 y2,
uint256 k2,
uint256 x3,
uint256 y3,
uint256 k3
) public pure returns(uint256, uint256, uint256) {
return EllipticCurveProjective.mulAddProjectiveTriplet(x1, y1, k1, x2, y2, k2, x3, y3, k3);
}
function mulEcPair(
uint256 x1,
uint256 y1,
uint256 k1,
uint256 x2,
uint256 y2,
uint256 k2
) public pure returns(uint256, uint256) {
(x1, y1) = EllipticCurve.ecMul(k1, x1, y1, A, P);
(x2, y2) = EllipticCurve.ecMul(k2, x2, y2, A, P);
(x1, y1) = EllipticCurve.ecAdd(x1, y1, x2, y2, A, P);
return (x1, y1);
}
function mulProjectivePair(
uint256 x1,
uint256 y1,
uint256 k1,
uint256 x2,
uint256 y2,
uint256 k2
) public pure returns(uint256, uint256, uint256) {
return EllipticCurveProjective.mulAddProjectivePair(x1, y1, k1, x2, y2, k2);
}
function mulEcQuartet(
uint256 x1, uint256 y1, uint256 k1,
uint256 x2, uint256 y2, uint256 k2,
uint256 x3, uint256 y3, uint256 k3,
uint256 x4, uint256 y4, uint256 k4
) public pure returns(uint256, uint256) {
(x1, y1) = EllipticCurve.ecMul(k1, x1, y1, A, P);
(x2, y2) = EllipticCurve.ecMul(k2, x2, y2, A, P);
(x3, y3) = EllipticCurve.ecMul(k3, x3, y3, A, P);
(x4, y4) = EllipticCurve.ecMul(k4, x4, y4, A, P);
(x1, y1) = EllipticCurve.ecAdd(x1, y1, x2, y2, A, P);
(x3, y3) = EllipticCurve.ecAdd(x3, y3, x4, y4, A, P);
(x1, y1) = EllipticCurve.ecAdd(x1, y1, x3, y3, A, P);
return (x1, y1);
}
function mulProjectiveQuartet(
uint256 x1, uint256 y1, uint256 k1,
uint256 x2, uint256 y2, uint256 k2,
uint256 x3, uint256 y3, uint256 k3,
uint256 x4, uint256 y4, uint256 k4
) public pure returns (uint256, uint256, uint256) {
return EllipticCurveProjective.mulAddProjectiveQuartet(
x1, y1, k1,
x2, y2, k2,
x3, y3, k3,
x4, y4, k4
);
}
function toAffineJacobian(uint256 x, uint256 y, uint256 z) public pure returns (uint256, uint256) {
return EllipticCurve.toAffine(x, y, z, P);
}
function toAffineProjective(uint256 x, uint256 y, uint256 z) public pure returns (uint256, uint256) {
return EllipticCurveProjective.toAffine(x, y, z);
}
function isOnCurve(uint256 x, uint256 y) public pure returns (bool) {
return EllipticCurveProjective.isOnCurve(x, y);
}
}