Skip to content

Commit

Permalink
add dev test & helper contracts
Browse files Browse the repository at this point in the history
  • Loading branch information
pLabarta committed Feb 24, 2025
1 parent 2fa9d81 commit b75e635
Show file tree
Hide file tree
Showing 2 changed files with 142 additions and 0 deletions.
87 changes: 87 additions & 0 deletions test/contracts/src/BLS12381.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract BLS12381Helper2 {
// Define the addresses for the BLS12-381 precompiles
address constant BLS12_G1ADD = 0x000000000000000000000000000000000000000b; // Replace with actual address
address constant BLS12_G1MULTIEXP = 0x000000000000000000000000000000000000000C; // Replace with actual address
address constant BLS12_G2ADD = 0x000000000000000000000000000000000000000d; // Replace with actual address
address constant BLS12_G2MULTIEXP = 0x000000000000000000000000000000000000000E; // Replace with actual address

function testAll() public returns (bool) {
// Hardcoded inputs and expected outputs for each precompile test vector
// Test vectors from https://github.com/ethereum/EIPs/tree/master/assets/eip-2537
// Only the first case was tested for each precompile
bytes memory g1AddInput = hex"0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e100000000000000000000000000000000112b98340eee2777cc3c14163dea3ec97977ac3dc5c70da32e6e87578f44912e902ccef9efe28d4a78b8999dfbca942600000000000000000000000000000000186b28d92356c4dfec4b5201ad099dbdede3781f8998ddf929b4cd7756192185ca7b8f4ef7088f813270ac3d48868a21";
bytes memory g1AddExpected = hex"000000000000000000000000000000000a40300ce2dec9888b60690e9a41d3004fda4886854573974fab73b046d3147ba5b7a5bde85279ffede1b45b3918d82d0000000000000000000000000000000006d3d887e9f53b9ec4eb6cedf5607226754b07c01ace7834f57f3e7315faefb739e59018e22c492006190fba4a870025";

bytes memory g1MultiExpInput = hex"0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e10000000000000000000000000000000000000000000000000000000000000002";
bytes memory g1MultiExpExpected = hex"000000000000000000000000000000000572cbea904d67468808c8eb50a9450c9721db309128012543902d0ac358a62ae28f75bb8f1c7c42c39a8c5529bf0f4e00000000000000000000000000000000166a9d8cabc673a322fda673779d8e3822ba3ecb8670e461f73bb9021d5fd76a4c56d9d4cd16bd1bba86881979749d28";

bytes memory g2AddInput = hex"00000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be00000000000000000000000000000000103121a2ceaae586d240843a398967325f8eb5a93e8fea99b62b9f88d8556c80dd726a4b30e84a36eeabaf3592937f2700000000000000000000000000000000086b990f3da2aeac0a36143b7d7c824428215140db1bb859338764cb58458f081d92664f9053b50b3fbd2e4723121b68000000000000000000000000000000000f9e7ba9a86a8f7624aa2b42dcc8772e1af4ae115685e60abc2c9b90242167acef3d0be4050bf935eed7c3b6fc7ba77e000000000000000000000000000000000d22c3652d0dc6f0fc9316e14268477c2049ef772e852108d269d9c38dba1d4802e8dae479818184c08f9a569d878451";
bytes memory g2AddExpected = hex"000000000000000000000000000000000b54a8a7b08bd6827ed9a797de216b8c9057b3a9ca93e2f88e7f04f19accc42da90d883632b9ca4dc38d013f71ede4db00000000000000000000000000000000077eba4eecf0bd764dce8ed5f45040dd8f3b3427cb35230509482c14651713282946306247866dfe39a8e33016fcbe520000000000000000000000000000000014e60a76a29ef85cbd69f251b9f29147b67cfe3ed2823d3f9776b3a0efd2731941d47436dc6d2b58d9e65f8438bad073000000000000000000000000000000001586c3c910d95754fef7a732df78e279c3d37431c6a2b77e67a00c7c130a8fcd4d19f159cbeb997a178108fffffcbd20";

bytes memory g2MultiExpInput = hex"00000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be0000000000000000000000000000000000000000000000000000000000000002";
bytes memory g2MultiExpExpected = hex"000000000000000000000000000000001638533957d540a9d2370f17cc7ed5863bc0b995b8825e0ee1ea1e1e4d00dbae81f14b0bf3611b78c952aacab827a053000000000000000000000000000000000a4edef9c1ed7f729f520e47730a124fd70662a904ba1074728114d1031e1572c6c886f6b57ec72a6178288c47c33577000000000000000000000000000000000468fb440d82b0630aeb8dca2b5256789a66da69bf91009cbfe6bd221e47aa8ae88dece9764bf3bd999d95d71e4c9899000000000000000000000000000000000f6d4552fa65dd2638b361543f887136a43253d9c66c411697003f7a13c308f5422e1aa0a59c8967acdefd8b6e36ccf3";

// Test G1ADD
(bool success, bytes memory result) = BLS12_G1ADD.call(g1AddInput);
require(success, "G1ADD precompile failed");
require(keccak256(result) == keccak256(g1AddExpected), "G1ADD precompile output mismatch");

// Test G1MULTIEXP
(success, result) = BLS12_G1MULTIEXP.call(g1MultiExpInput);
require(success, "G1MULTIEXP precompile failed");
require(keccak256(result) == keccak256(g1MultiExpExpected), "G1MULTIEXP precompile output mismatch");

// Test G2ADD
(success, result) = BLS12_G2ADD.call(g2AddInput);
require(success, "G2ADD precompile failed");
require(keccak256(result) == keccak256(g2AddExpected), "G2ADD precompile output mismatch");

// Test G2MULTIEXP
(success, result) = BLS12_G2MULTIEXP.call(g2MultiExpInput);
require(success, "G2MULTIEXP precompile failed");
require(keccak256(result) == keccak256(g2MultiExpExpected), "G2MULTIEXP precompile output mismatch");

return true;
}
}

contract BLS12381Helper1 {
// Define the addresses for the BLS12-381 precompiles
address constant BLS12_PAIRING = 0x000000000000000000000000000000000000000F; // Replace with actual address
address constant BLS12_MAP_FP_TO_G1 = 0x0000000000000000000000000000000000000010; // Replace with actual address
address constant BLS12_MAP_FP2_TO_G2 =0x0000000000000000000000000000000000000011; // Replace with actual address

function testAll() public returns (bool) {
// Hardcoded inputs and expected outputs for each precompile test vector
// Test vectors from https://github.com/ethereum/EIPs/tree/master/assets/eip-2537
// Only the first case was tested for each precompile
bytes memory pairingInput = hex"0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be";
bytes memory pairingExpected = hex"0000000000000000000000000000000000000000000000000000000000000001";

bytes memory mapFpToG1Input = hex"00000000000000000000000000000000156c8a6a2c184569d69a76be144b5cdc5141d2d2ca4fe341f011e25e3969c55ad9e9b9ce2eb833c81a908e5fa4ac5f03";
bytes memory mapFpToG1Expected = hex"00000000000000000000000000000000184bb665c37ff561a89ec2122dd343f20e0f4cbcaec84e3c3052ea81d1834e192c426074b02ed3dca4e7676ce4ce48ba0000000000000000000000000000000004407b8d35af4dacc809927071fc0405218f1401a6d15af775810e4e460064bcc9468beeba82fdc751be70476c888bf3";

bytes memory mapFp2ToG2Input = hex"0000000000000000000000000000000007355d25caf6e7f2f0cb2812ca0e513bd026ed09dda65b177500fa31714e09ea0ded3a078b526bed3307f804d4b93b040000000000000000000000000000000002829ce3c021339ccb5caf3e187f6370e1e2a311dec9b75363117063ab2015603ff52c3d3b98f19c2f65575e99e8b78c";
bytes memory mapFp2ToG2Expected = hex"0000000000000000000000000000000000e7f4568a82b4b7dc1f14c6aaa055edf51502319c723c4dc2688c7fe5944c213f510328082396515734b6612c4e7bb700000000000000000000000000000000126b855e9e69b1f691f816e48ac6977664d24d99f8724868a184186469ddfd4617367e94527d4b74fc86413483afb35b000000000000000000000000000000000caead0fd7b6176c01436833c79d305c78be307da5f6af6c133c47311def6ff1e0babf57a0fb5539fce7ee12407b0a42000000000000000000000000000000001498aadcf7ae2b345243e281ae076df6de84455d766ab6fcdaad71fab60abb2e8b980a440043cd305db09d283c895e3d";

// Test PAIRING
(bool success, bytes memory result) = BLS12_PAIRING.call(pairingInput);
require(success, "PAIRING precompile failed");
require(keccak256(result) == keccak256(pairingExpected), "PAIRING precompile output mismatch");

// Test MAP_FP_TO_G1
(success, result) = BLS12_MAP_FP_TO_G1.call(mapFpToG1Input);
require(success, "MAP_FP_TO_G1 precompile failed");
require(keccak256(result) == keccak256(mapFpToG1Expected), "MAP_FP_TO_G1 precompile output mismatch");

// // // Test MAP_FP2_TO_G2
(success, result) = BLS12_MAP_FP2_TO_G2.call(mapFp2ToG2Input);
require(success, "MAP_FP2_TO_G2 precompile failed");
require(keccak256(result) == keccak256(mapFp2ToG2Expected), "MAP_FP2_TO_G2 precompile output mismatch");

return true;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import "@moonbeam-network/api-augment";

import { beforeAll, deployCreateCompiledContract, describeSuite, expect } from "@moonwall/cli";
import { encodeFunctionData } from "viem";

describeSuite({
id: "D012999",
title: "Precompiles - BLS123_81",
foundationMethods: "dev",
testCases: ({ context, it, log }) => {
let helper1Address;
let helper1Abi;

let helper2Address;
let helper2Abi;

beforeAll(async () => {
const { contractAddress, abi } = await deployCreateCompiledContract(context, "BLS12381Helper1");
helper1Address = contractAddress;
helper1Abi = abi;

const { contractAddress: contractAddress2, abi: abi2 } = await deployCreateCompiledContract(context, "BLS12381Helper2");
helper2Address = contractAddress2;
helper2Abi = abi2;
});

it({
id: "T01",
title: "Test all precompiles with test vectors",
test: async () => {

// BLS12381.sol contains the test vectors for the precompiles
// and splits them into two contracts to avoid hitting the gas limit

const tx = await context.viem().sendTransaction({
to: helper1Address,
data: encodeFunctionData({abi: helper1Abi, functionName: "testAll", args: []}),
});
await context.createBlock();

const receipt = await context.viem().getTransactionReceipt({ hash: tx});
expect(receipt.status).toBe("success");

const tx2 = await context.viem().sendTransaction({
to: helper2Address,
data: encodeFunctionData({abi: helper2Abi, functionName: "testAll", args: []}),
});
await context.createBlock();

const receipt2 = await context.viem().getTransactionReceipt({ hash: tx2});
expect(receipt2.status).toBe("success");
},
});

}});

0 comments on commit b75e635

Please sign in to comment.