// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.13; import {Test, stdJson, console} from "forge-std/Test.sol"; import {MathTester} from "../src/MathTester.sol"; struct Point { uint256 k; bytes32 x; bytes32 y; } contract MathTesterTest is Test { MathTester public math; Point[] public points; function setUp() public { math = new MathTester(); string memory path = "raw_vectors.json"; string memory json = vm.readFile(path); bytes memory data = vm.parseJson(json); points = abi.decode(data, (Point[])); } function test_triplet() public view { uint256 len = points.length - 2; for (uint256 i; i < len;) { (uint256 x_p, uint256 y_p, uint256 z_p) = math.mulProjectiveTriplet( uint256(points[i].x), uint256(points[i].y), uint256(points[i].k), uint256(points[i+1].x), uint256(points[i+1].y), uint256(points[i+1].k), uint256(points[i+2].x), uint256(points[i+2].y), uint256(points[i+2].k) ); (x_p, y_p) = math.toAffineProjective(x_p, y_p, z_p); (uint256 x_j, uint256 y_j) = math.mulEcTriplet( uint256(points[i].x), uint256(points[i].y), uint256(points[i].k), uint256(points[i+1].x), uint256(points[i+1].y), uint256(points[i+1].k), uint256(points[i+2].x), uint256(points[i+2].y), uint256(points[i+2].k) ); // (x_j, y_j) = math.toAffineJacobian(x_j, y_j, z_j); assertEq(x_p, x_j); assertEq(y_p, y_j); unchecked { ++i; } } } function test_addition() public view { uint256 len = points.length - 1; for (uint256 i; i < len;) { (uint256 x_p, uint256 y_p, uint256 z_p) = math.addProjective( uint256(points[i].x), uint256(points[i].y), uint256(points[i+1].x), uint256(points[i+1].y) ); (x_p, y_p) = math.toAffineProjective(x_p, y_p, z_p); (uint256 x_j, uint256 y_j, uint256 z_j) = math.addJacobian( uint256(points[i].x), uint256(points[i].y), uint256(points[i+1].x), uint256(points[i+1].y) ); (x_j, y_j) = math.toAffineJacobian(x_j, y_j, z_j); assertEq(x_p, x_j); assertEq(y_p, y_j); unchecked { ++i; } } } function test_mixedAddition() public view { uint256 len = points.length - 1; for (uint256 i; i < len;) { (uint256 x_p, uint256 y_p, uint256 z_p) = math.addProjectiveMixed( uint256(points[i].x), uint256(points[i].y), uint256(points[i+1].x), uint256(points[i+1].y) ); (x_p, y_p) = math.toAffineProjective(x_p, y_p, z_p); (uint256 x_j, uint256 y_j, uint256 z_j) = math.addJacobian( uint256(points[i].x), uint256(points[i].y), uint256(points[i+1].x), uint256(points[i+1].y) ); (x_j, y_j) = math.toAffineJacobian(x_j, y_j, z_j); assertEq(x_p, x_j); assertEq(y_p, y_j); unchecked { ++i; } } } function test_double() public view { uint256 len = points.length; for (uint256 i; i < len;) { (uint256 x_p, uint256 y_p, uint256 z_p) = math.doubleProjective( uint256(points[i].x), uint256(points[i].y) ); (x_p, y_p) = math.toAffineProjective(x_p, y_p, z_p); (uint256 x_j, uint256 y_j, uint256 z_j) = math.doubleJacobian( uint256(points[i].x), uint256(points[i].y) ); (x_j, y_j) = math.toAffineJacobian(x_j, y_j, z_j); assertEq(x_p, x_j); assertEq(y_p, y_j); unchecked { ++i; } } } }