// 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); } }