153 lines
4.8 KiB
Solidity
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);
|
|
}
|
|
}
|