diff --git a/itests/contracts/bls12/AllBLS12Tests.hex b/itests/contracts/bls12/AllBLS12Tests.hex new file mode 100644 index 00000000000..e9f13a2c6c2 --- /dev/null +++ b/itests/contracts/bls12/AllBLS12Tests.hex @@ -0,0 +1 @@ +6080604052348015600e575f5ffd5b50610fb48061001c5f395ff3fe608060405234801561000f575f5ffd5b5060043610610029575f3560e01c806323d746281461002d575b5f5ffd5b610035610037565b005b5f610060600f604051806101a00160405280610180815260200161065e6101809139602061023b565b90506100b88160405180604001604052806020815260200160018152506040518060400160405280601481526020017f70616972696e67206528302c47322920213d2031000000000000000000000000815250610335565b5f6100e1600f604051806101a001604052806101808152602001610c5e6101809139602061023b565b90506101398160405180604001604052806020815260200160018152506040518060400160405280601481526020017f70616972696e6720652847312c302920213d2031000000000000000000000000815250610335565b5f610162600f604051806101a001604052806101808152602001610dde6101809139602061023b565b905061019c816040518060400160405280602081526020015f815250604051806060016040528060218152602001610f5e60219139610335565b5f6101c5600f604051806104a0016040528061048081526020016107de6104809139602061023b565b905061021c816040518060400160405280602081526020015f8152506040518060400160405280602081526020017f70616972696e672070726f647563742066616c73652065787065637465642030815250610335565b610235600f60405180602001604052805f81525061038e565b50505050565b60605f5f8573ffffffffffffffffffffffffffffffffffffffff1685604051610264919061048d565b5f60405180830381855afa9150503d805f811461029c576040519150601f19603f3d011682016040523d82523d5f602084013e6102a1565b606091505b5091509150816102e6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016102dd906104fd565b60405180910390fd5b83815114610329576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161032090610565565b60405180910390fd5b80925050509392505050565b81805190602001208380519060200120148190610388576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161037f91906105d5565b60405180910390fd5b50505050565b5f8273ffffffffffffffffffffffffffffffffffffffff16826040516103b4919061048d565b5f60405180830381855afa9150503d805f81146103ec576040519150601f19603f3d011682016040523d82523d5f602084013e6103f1565b606091505b505090508015610436576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161042d9061063f565b60405180910390fd5b505050565b5f81519050919050565b5f81905092915050565b8281835e5f83830152505050565b5f6104678261043b565b6104718185610445565b935061048181856020860161044f565b80840191505092915050565b5f610498828461045d565b915081905092915050565b5f82825260208201905092915050565b7f707265636f6d70696c65207265766572746564000000000000000000000000005f82015250565b5f6104e76013836104a3565b91506104f2826104b3565b602082019050919050565b5f6020820190508181035f830152610514816104db565b9050919050565b7f756e65787065637465642072657475726e206c656e67746800000000000000005f82015250565b5f61054f6018836104a3565b915061055a8261051b565b602082019050919050565b5f6020820190508181035f83015261057c81610543565b9050919050565b5f81519050919050565b5f601f19601f8301169050919050565b5f6105a782610583565b6105b181856104a3565b93506105c181856020860161044f565b6105ca8161058d565b840191505092915050565b5f6020820190508181035f8301526105ed818461059d565b905092915050565b7f65787065637465642072657665727400000000000000000000000000000000005f82015250565b5f610629600f836104a3565b9150610634826105f5565b602082019050919050565b5f6020820190508181035f8301526106568161061d565b905091905056fe000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e100000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e100000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e100000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be70616972696e67206e6f6e2d646567656e65726163792065787065637465642030a2646970667358221220e64b247f9cea2a6fc12282266cb05b7e775729169560b9014923d3c544d1f8f064736f6c634300081e0033 \ No newline at end of file diff --git a/itests/contracts/bls12/AllBLS12Tests.sol b/itests/contracts/bls12/AllBLS12Tests.sol new file mode 100644 index 00000000000..dc4ebed53e8 --- /dev/null +++ b/itests/contracts/bls12/AllBLS12Tests.sol @@ -0,0 +1,41 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.20; + +import "./G1AddTest.sol"; +import "./G1MsmTest.sol"; +import "./G2AddTest.sol"; +import "./G2MsmTest.sol"; +import "./MapFpToG1Test.sol"; +import "./MapFp2ToG2Test.sol"; +import "./PairingTest.sol"; + +contract AllBLS12Tests { + G1AddTest private g1Add; + G1MsmTest private g1Msm; + G2AddTest private g2Add; + G2MsmTest private g2Msm; + MapFpToG1Test private mapFpToG1; + MapFp2ToG2Test private mapFp2ToG2; + PairingTest private pairing; + + constructor() { + g1Add = new G1AddTest(); + g1Msm = new G1MsmTest(); + g2Add = new G2AddTest(); + g2Msm = new G2MsmTest(); + mapFpToG1 = new MapFpToG1Test(); + mapFp2ToG2 = new MapFp2ToG2Test(); + pairing = new PairingTest(); + } + + function runTests() public view { + g1Add.runTests(); + g1Msm.runTests(); + g2Add.runTests(); + g2Msm.runTests(); + mapFpToG1.runTests(); + mapFp2ToG2.runTests(); + pairing.runTests(); + } +} + diff --git a/itests/contracts/bls12/G1AddTest.hex b/itests/contracts/bls12/G1AddTest.hex new file mode 100644 index 00000000000..b58b63ec8b4 --- /dev/null +++ b/itests/contracts/bls12/G1AddTest.hex @@ -0,0 +1 @@ +6080604052348015600e575f5ffd5b506111568061001c5f395ff3fe608060405234801561000f575f5ffd5b5060043610610029575f3560e01c806323d746281461002d575b5f5ffd5b610035610037565b005b5f610060600b6040518061012001604052806101008152602001610e216101009139608061052e565b90506100ba816040518060a00160405280608081526020016110a1608091396040518060400160405280601281526020017f673161646420616464206d69736d617463680000000000000000000000000000815250610628565b5f6100e3600b6040518061012001604052806101008152602001610d216101009139608061052e565b905061013d816040518060a0016040528060808152602001611021608091396040518060400160405280601a81526020017f673161646420646f75626c696e67206731206d69736d61746368000000000000815250610628565b5f610166600b6040518061012001604052806101008152602001610c216101009139608061052e565b90506101c0816040518060a0016040528060808152602001610fa1608091396040518060400160405280601a81526020017f673161646420646f75626c696e67207031206d69736d61746368000000000000815250610628565b5f610254600b6040518060a0016040528060808152602001610aa160809139608067ffffffffffffffff8111156101fa576101f961072e565b5b6040519080825280601f01601f19166020018201604052801561022c5781602001600182028036833780820191505090505b5060405160200161023e9291906107ad565b604051602081830303815290604052608061052e565b90506102ae816040518060a0016040528060808152602001610aa1608091396040518060400160405280601c81526020017f6731616464206964656e746974792067312b30206d69736d6174636800000000815250610628565b5f610342600b6040518060a0016040528060808152602001610f2160809139608067ffffffffffffffff8111156102e8576102e761072e565b5b6040519080825280601f01601f19166020018201604052801561031a5781602001600182028036833780820191505090505b5060405160200161032c9291906107ad565b604051602081830303815290604052608061052e565b905061039c816040518060a0016040528060808152602001610f21608091396040518060400160405280601c81526020017f6731616464206964656e746974792070312b30206d69736d6174636800000000815250610628565b5f6103c5600b60405180610120016040528061010081526020016109a16101009139608061052e565b905061045481608067ffffffffffffffff8111156103e6576103e561072e565b5b6040519080825280601f01601f1916602001820160405280156104185781602001600182028036833780820191505090505b506040518060400160405280601081526020017f67316164642067312d673120213d203000000000000000000000000000000000815250610628565b5f61047d600b6040518061012001604052806101008152602001610b216101009139608061052e565b905061050c81608067ffffffffffffffff81111561049e5761049d61072e565b5b6040519080825280601f01601f1916602001820160405280156104d05781602001600182028036833780820191505090505b506040518060400160405280601081526020017f67316164642070312d703120213d203000000000000000000000000000000000815250610628565b610525600b60405180602001604052805f815250610681565b50505050505050565b60605f5f8573ffffffffffffffffffffffffffffffffffffffff168560405161055791906107d0565b5f60405180830381855afa9150503d805f811461058f576040519150601f19603f3d011682016040523d82523d5f602084013e610594565b606091505b5091509150816105d9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105d090610840565b60405180910390fd5b8381511461061c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610613906108a8565b60405180910390fd5b80925050509392505050565b8180519060200120838051906020012014819061067b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106729190610918565b60405180910390fd5b50505050565b5f8273ffffffffffffffffffffffffffffffffffffffff16826040516106a791906107d0565b5f60405180830381855afa9150503d805f81146106df576040519150601f19603f3d011682016040523d82523d5f602084013e6106e4565b606091505b505090508015610729576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161072090610982565b60405180910390fd5b505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b5f81519050919050565b5f81905092915050565b8281835e5f83830152505050565b5f6107878261075b565b6107918185610765565b93506107a181856020860161076f565b80840191505092915050565b5f6107b8828561077d565b91506107c4828461077d565b91508190509392505050565b5f6107db828461077d565b915081905092915050565b5f82825260208201905092915050565b7f707265636f6d70696c65207265766572746564000000000000000000000000005f82015250565b5f61082a6013836107e6565b9150610835826107f6565b602082019050919050565b5f6020820190508181035f8301526108578161081e565b9050919050565b7f756e65787065637465642072657475726e206c656e67746800000000000000005f82015250565b5f6108926018836107e6565b915061089d8261085e565b602082019050919050565b5f6020820190508181035f8301526108bf81610886565b9050919050565b5f81519050919050565b5f601f19601f8301169050919050565b5f6108ea826108c6565b6108f481856107e6565b935061090481856020860161076f565b61090d816108d0565b840191505092915050565b5f6020820190508181035f83015261093081846108e0565b905092915050565b7f65787065637465642072657665727400000000000000000000000000000000005f82015250565b5f61096c600f836107e6565b915061097782610938565b602082019050919050565b5f6020820190508181035f83015261099981610960565b905091905056fe0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e10000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb00000000000000000000000000000000114d1d6855d545a8aa7d76c8cf2e21f267816aef1db507c96655b9d5caac42364e6f38ba0ecb751bad54dcd6b939c2ca0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e100000000000000000000000000000000112b98340eee2777cc3c14163dea3ec97977ac3dc5c70da32e6e87578f44912e902ccef9efe28d4a78b8999dfbca942600000000000000000000000000000000186b28d92356c4dfec4b5201ad099dbdede3781f8998ddf929b4cd7756192185ca7b8f4ef7088f813270ac3d48868a2100000000000000000000000000000000112b98340eee2777cc3c14163dea3ec97977ac3dc5c70da32e6e87578f44912e902ccef9efe28d4a78b8999dfbca9426000000000000000000000000000000000195e911162921ba5ed055b496420f197693d36569ec34c63d7c0529a097d49e543070afba4b707e878e53c2b779208a00000000000000000000000000000000112b98340eee2777cc3c14163dea3ec97977ac3dc5c70da32e6e87578f44912e902ccef9efe28d4a78b8999dfbca942600000000000000000000000000000000186b28d92356c4dfec4b5201ad099dbdede3781f8998ddf929b4cd7756192185ca7b8f4ef7088f813270ac3d48868a2100000000000000000000000000000000112b98340eee2777cc3c14163dea3ec97977ac3dc5c70da32e6e87578f44912e902ccef9efe28d4a78b8999dfbca942600000000000000000000000000000000186b28d92356c4dfec4b5201ad099dbdede3781f8998ddf929b4cd7756192185ca7b8f4ef7088f813270ac3d48868a210000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e10000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e10000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e100000000000000000000000000000000112b98340eee2777cc3c14163dea3ec97977ac3dc5c70da32e6e87578f44912e902ccef9efe28d4a78b8999dfbca942600000000000000000000000000000000186b28d92356c4dfec4b5201ad099dbdede3781f8998ddf929b4cd7756192185ca7b8f4ef7088f813270ac3d48868a2100000000000000000000000000000000112b98340eee2777cc3c14163dea3ec97977ac3dc5c70da32e6e87578f44912e902ccef9efe28d4a78b8999dfbca942600000000000000000000000000000000186b28d92356c4dfec4b5201ad099dbdede3781f8998ddf929b4cd7756192185ca7b8f4ef7088f813270ac3d48868a210000000000000000000000000000000015222cddbabdd764c4bee0b3720322a65ff4712c86fc4b1588d0c209210a0884fa9468e855d261c483091b2bf7de6a630000000000000000000000000000000009f9edb99bc3b75d7489735c98b16ab78b9386c5f7a1f76c7e96ac6eb5bbde30dbca31a74ec6e0f0b12229eecea33c39000000000000000000000000000000000572cbea904d67468808c8eb50a9450c9721db309128012543902d0ac358a62ae28f75bb8f1c7c42c39a8c5529bf0f4e00000000000000000000000000000000166a9d8cabc673a322fda673779d8e3822ba3ecb8670e461f73bb9021d5fd76a4c56d9d4cd16bd1bba86881979749d28000000000000000000000000000000000a40300ce2dec9888b60690e9a41d3004fda4886854573974fab73b046d3147ba5b7a5bde85279ffede1b45b3918d82d0000000000000000000000000000000006d3d887e9f53b9ec4eb6cedf5607226754b07c01ace7834f57f3e7315faefb739e59018e22c492006190fba4a870025a26469706673582212202ce0e4ad7fc735a1b0efefb566665d6d0354c3829e3b9299ce0db34d808e52c764736f6c634300081e0033 \ No newline at end of file diff --git a/itests/contracts/bls12/G1AddTest.sol b/itests/contracts/bls12/G1AddTest.sol new file mode 100644 index 00000000000..fb2d9df9266 --- /dev/null +++ b/itests/contracts/bls12/G1AddTest.sol @@ -0,0 +1,69 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.20; + +contract G1AddTest { + function callOk(address pc, bytes memory input, uint256 expectedLen) internal view returns (bytes memory) { + (bool ok, bytes memory out) = pc.staticcall(input); + require(ok, "precompile reverted"); + require(out.length == expectedLen, "unexpected return length"); + return out; + } + + function expectRevert(address pc, bytes memory input) internal view { + (bool ok, ) = pc.staticcall(input); + require(!ok, "expected revert"); + } + + function expectEq(bytes memory a, bytes memory b, string memory what) internal pure { + require(keccak256(a) == keccak256(b), what); + } + + address constant PRECOMPILE = 0x000000000000000000000000000000000000000b; // BLS12_G1ADD + uint256 constant OUT_LEN = 128; + + // Vector: g1 + p1 + bytes constant INPUT_ADD_G1_P1 = hex"0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e100000000000000000000000000000000112b98340eee2777cc3c14163dea3ec97977ac3dc5c70da32e6e87578f44912e902ccef9efe28d4a78b8999dfbca942600000000000000000000000000000000186b28d92356c4dfec4b5201ad099dbdede3781f8998ddf929b4cd7756192185ca7b8f4ef7088f813270ac3d48868a21"; + bytes constant EXPECT_ADD_G1_P1 = hex"000000000000000000000000000000000a40300ce2dec9888b60690e9a41d3004fda4886854573974fab73b046d3147ba5b7a5bde85279ffede1b45b3918d82d0000000000000000000000000000000006d3d887e9f53b9ec4eb6cedf5607226754b07c01ace7834f57f3e7315faefb739e59018e22c492006190fba4a870025"; + // Vector: g1 + g1 = 2*g1 + bytes constant INPUT_G1_PLUS_G1 = hex"0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e10000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e1"; + bytes constant EXPECT_G1_PLUS_G1 = hex"000000000000000000000000000000000572cbea904d67468808c8eb50a9450c9721db309128012543902d0ac358a62ae28f75bb8f1c7c42c39a8c5529bf0f4e00000000000000000000000000000000166a9d8cabc673a322fda673779d8e3822ba3ecb8670e461f73bb9021d5fd76a4c56d9d4cd16bd1bba86881979749d28"; + // Vector: p1 + p1 = 2*p1 + bytes constant INPUT_P1_PLUS_P1 = hex"00000000000000000000000000000000112b98340eee2777cc3c14163dea3ec97977ac3dc5c70da32e6e87578f44912e902ccef9efe28d4a78b8999dfbca942600000000000000000000000000000000186b28d92356c4dfec4b5201ad099dbdede3781f8998ddf929b4cd7756192185ca7b8f4ef7088f813270ac3d48868a2100000000000000000000000000000000112b98340eee2777cc3c14163dea3ec97977ac3dc5c70da32e6e87578f44912e902ccef9efe28d4a78b8999dfbca942600000000000000000000000000000000186b28d92356c4dfec4b5201ad099dbdede3781f8998ddf929b4cd7756192185ca7b8f4ef7088f813270ac3d48868a21"; + bytes constant EXPECT_P1_PLUS_P1 = hex"0000000000000000000000000000000015222cddbabdd764c4bee0b3720322a65ff4712c86fc4b1588d0c209210a0884fa9468e855d261c483091b2bf7de6a630000000000000000000000000000000009f9edb99bc3b75d7489735c98b16ab78b9386c5f7a1f76c7e96ac6eb5bbde30dbca31a74ec6e0f0b12229eecea33c39"; + // Encoded canonical points (128 bytes each) for identity tests + bytes constant G1_ENC = hex"0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e1"; + bytes constant P1_ENC = hex"00000000000000000000000000000000112b98340eee2777cc3c14163dea3ec97977ac3dc5c70da32e6e87578f44912e902ccef9efe28d4a78b8999dfbca942600000000000000000000000000000000186b28d92356c4dfec4b5201ad099dbdede3781f8998ddf929b4cd7756192185ca7b8f4ef7088f813270ac3d48868a21"; + // Subtraction (add inverse) vectors -> infinity + bytes constant INPUT_G1_MINUS_G1 = hex"0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e10000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb00000000000000000000000000000000114d1d6855d545a8aa7d76c8cf2e21f267816aef1db507c96655b9d5caac42364e6f38ba0ecb751bad54dcd6b939c2ca"; + bytes constant INPUT_P1_MINUS_P1 = hex"00000000000000000000000000000000112b98340eee2777cc3c14163dea3ec97977ac3dc5c70da32e6e87578f44912e902ccef9efe28d4a78b8999dfbca942600000000000000000000000000000000186b28d92356c4dfec4b5201ad099dbdede3781f8998ddf929b4cd7756192185ca7b8f4ef7088f813270ac3d48868a2100000000000000000000000000000000112b98340eee2777cc3c14163dea3ec97977ac3dc5c70da32e6e87578f44912e902ccef9efe28d4a78b8999dfbca9426000000000000000000000000000000000195e911162921ba5ed055b496420f197693d36569ec34c63d7c0529a097d49e543070afba4b707e878e53c2b779208a"; + + function runTests() public view { + // Positive: addition + bytes memory out1 = callOk(PRECOMPILE, INPUT_ADD_G1_P1, OUT_LEN); + expectEq(out1, EXPECT_ADD_G1_P1, "g1add add mismatch"); + + // Additional positives + bytes memory out2 = callOk(PRECOMPILE, INPUT_G1_PLUS_G1, OUT_LEN); + expectEq(out2, EXPECT_G1_PLUS_G1, "g1add doubling g1 mismatch"); + + bytes memory out3 = callOk(PRECOMPILE, INPUT_P1_PLUS_P1, OUT_LEN); + expectEq(out3, EXPECT_P1_PLUS_P1, "g1add doubling p1 mismatch"); + + // Identity: g1 + 0 = g1; p1 + 0 = p1 + bytes memory out4 = callOk(PRECOMPILE, bytes.concat(G1_ENC, new bytes(OUT_LEN)), OUT_LEN); + expectEq(out4, G1_ENC, "g1add identity g1+0 mismatch"); + + bytes memory out5 = callOk(PRECOMPILE, bytes.concat(P1_ENC, new bytes(OUT_LEN)), OUT_LEN); + expectEq(out5, P1_ENC, "g1add identity p1+0 mismatch"); + + // Subtraction to infinity + bytes memory out6 = callOk(PRECOMPILE, INPUT_G1_MINUS_G1, OUT_LEN); + expectEq(out6, new bytes(OUT_LEN), "g1add g1-g1 != 0"); + + bytes memory out7 = callOk(PRECOMPILE, INPUT_P1_MINUS_P1, OUT_LEN); + expectEq(out7, new bytes(OUT_LEN), "g1add p1-p1 != 0"); + + // Negative: incorrect input size should revert + expectRevert(PRECOMPILE, hex""); + } +} diff --git a/itests/contracts/bls12/G1MsmTest.hex b/itests/contracts/bls12/G1MsmTest.hex new file mode 100644 index 00000000000..416a04aae7d --- /dev/null +++ b/itests/contracts/bls12/G1MsmTest.hex @@ -0,0 +1 @@ +6080604052348015600e575f5ffd5b5061137c8061001c5f395ff3fe608060405234801561000f575f5ffd5b5060043610610029575f3560e01c806323d746281461002d575b5f5ffd5b610035610037565b005b5f61005d600c6040518060c0016040528060a0815260200161122760a0913960806103c2565b90506100b7816040518060a00160405280608081526020016112c7608091396040518060400160405280601181526020017f67316d736d203278206d69736d617463680000000000000000000000000000008152506104bc565b5f6100dd600c6040518060c0016040528060a08152602001610f0760a0913960806103c2565b9050610137816040518060a0016040528060808152602001610d45608091396040518060400160405280601181526020017f67316d736d203178206d69736d617463680000000000000000000000000000008152506104bc565b5f61015d600c6040518060c0016040528060a0815260200161104760a0913960806103c2565b90506101b7816040518060a00160405280608081526020016107e5608091396040518060400160405280600f81526020017f67316d736d20307820213d20696e6600000000000000000000000000000000008152506104bc565b5f6101dd600c6040518060c0016040528060a08152602001610fa760a0913960806103c2565b9050610237816040518060a00160405280608081526020016107e5608091396040518060400160405280601281526020017f67316d736d20782a696e6620213d20696e6600000000000000000000000000008152506104bc565b5f61025d600c6040518060c0016040528060a08152602001610e4560a0913960806103c2565b905061029a816040518060a001604052806080815260200161086560809139604051806060016040528060228152602001610ee5602291396104bc565b5f6102c3600c60405180610480016040528061046081526020016108e5610460913960806103c2565b905061031d816040518060a0016040528060808152602001610dc5608091396040518060400160405280601781526020017f67316d736d206d756c7469706c65206d69736d617463680000000000000000008152506104bc565b5f610346600c60405180610160016040528061014081526020016110e7610140913960806103c2565b90506103a0816040518060a00160405280608081526020016112c7608091396040518060400160405280601681526020017f67316d736d203267312b696e66206d69736d61746368000000000000000000008152506104bc565b6103b9600c60405180602001604052805f815250610515565b50505050505050565b60605f5f8573ffffffffffffffffffffffffffffffffffffffff16856040516103eb9190610614565b5f60405180830381855afa9150503d805f8114610423576040519150601f19603f3d011682016040523d82523d5f602084013e610428565b606091505b50915091508161046d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161046490610684565b60405180910390fd5b838151146104b0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104a7906106ec565b60405180910390fd5b80925050509392505050565b8180519060200120838051906020012014819061050f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610506919061075c565b60405180910390fd5b50505050565b5f8273ffffffffffffffffffffffffffffffffffffffff168260405161053b9190610614565b5f60405180830381855afa9150503d805f8114610573576040519150601f19603f3d011682016040523d82523d5f602084013e610578565b606091505b5050905080156105bd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105b4906107c6565b60405180910390fd5b505050565b5f81519050919050565b5f81905092915050565b8281835e5f83830152505050565b5f6105ee826105c2565b6105f881856105cc565b93506106088185602086016105d6565b80840191505092915050565b5f61061f82846105e4565b915081905092915050565b5f82825260208201905092915050565b7f707265636f6d70696c65207265766572746564000000000000000000000000005f82015250565b5f61066e60138361062a565b91506106798261063a565b602082019050919050565b5f6020820190508181035f83015261069b81610662565b9050919050565b7f756e65787065637465642072657475726e206c656e67746800000000000000005f82015250565b5f6106d660188361062a565b91506106e1826106a2565b602082019050919050565b5f6020820190508181035f830152610703816106ca565b9050919050565b5f81519050919050565b5f601f19601f8301169050919050565b5f61072e8261070a565b610738818561062a565b93506107488185602086016105d6565b61075181610714565b840191505092915050565b5f6020820190508181035f8301526107748184610724565b905092915050565b7f65787065637465642072657665727400000000000000000000000000000000005f82015250565b5f6107b0600f8361062a565b91506107bb8261077c565b602082019050919050565b5f6020820190508181035f8301526107dd816107a4565b905091905056fe00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006ee9c9331228753bcb148d0ca8623447701bb0aa6eafb0340aa7f81543923474e00f2a225de65c62dd1d8303270220c0000000000000000000000000000000018dd7be47eb4e80985d7a0d2cc96c8b004250b36a5c3ec0217705d453d3ecc6d0d3d1588722da51b40728baba1e938040000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e1263dbd792f5b1be47ed85f8938c0f29586af0d3ac7b977f21c278fe1462040e300000000000000000000000000000000112b98340eee2777cc3c14163dea3ec97977ac3dc5c70da32e6e87578f44912e902ccef9efe28d4a78b8999dfbca942600000000000000000000000000000000186b28d92356c4dfec4b5201ad099dbdede3781f8998ddf929b4cd7756192185ca7b8f4ef7088f813270ac3d48868a2147b8192d77bf871b62e87859d653922725724a5c031afeabc60bcef5ff66513800000000000000000000000000000000184bb665c37ff561a89ec2122dd343f20e0f4cbcaec84e3c3052ea81d1834e192c426074b02ed3dca4e7676ce4ce48ba0000000000000000000000000000000004407b8d35af4dacc809927071fc0405218f1401a6d15af775810e4e460064bcc9468beeba82fdc751be70476c888bf3328388aff0d4a5b7dc9205abd374e7e98f3cd9f3418edb4eafda5fb16473d21600000000000000000000000000000000009769f3ab59bfd551d53a5f846b9984c59b97d6842b20a2c565baa167945e3d026a3755b6345df8ec7e6acb6868ae6d000000000000000000000000000000001532c00cf61aa3d0ce3e5aa20c3b531a2abd2c770a790a2613818303c6b830ffc0ecf6c357af3317b9575c567f11cd2c263dbd792f5b1be47ed85f8938c0f29586af0d3ac7b977f21c278fe1462040e2000000000000000000000000000000001974dbb8e6b5d20b84df7e625e2fbfecb2cdb5f77d5eae5fb2955e5ce7313cae8364bc2fff520a6c25619739c6bdcb6a0000000000000000000000000000000015f9897e11c6441eaa676de141c8d83c37aab8667173cbe1dfd6de74d11861b961dccebcd9d289ac633455dfcc7013a347b8192d77bf871b62e87859d653922725724a5c031afeabc60bcef5ff665131000000000000000000000000000000000a7a047c4a8397b3446450642c2ac64d7239b61872c9ae7a59707a8f4f950f101e766afe58223b3bff3a19a7f754027c000000000000000000000000000000001383aebba1e4327ccff7cf9912bda0dbc77de048b71ef8c8a81111d71dc33c5e3aa6edee9cf6f5fe525d50cc50b77cc9328388aff0d4a5b7dc9205abd374e7e98f3cd9f3418edb4eafda5fb16473d211000000000000000000000000000000000e7a16a975904f131682edbb03d9560d3e48214c9986bd50417a77108d13dc957500edf96462a3d01e62dc6cd468ef11000000000000000000000000000000000ae89e677711d05c30a48d6d75e76ca9fb70fe06c6dd6ff988683d89ccde29ac7d46c53bb97a59b1901abf1db66052db55b53c4669f19f0fc7431929bc0363d7d8fb432435fcde2635fdba334424e9f50000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e100000000000000000000000000000000053fbdb09b6b5faa08bfe7b7069454247ad4d8bd57e90e2d2ebaa04003dcf110aa83072c07f480ab2107cca2ccff6091000000000000000000000000000000001654537b7c96fe64d13906066679c3d45808cb666452b55d1b909c230cc4b423c3f932c58754b9b762dc49fcc825522c00000000000000000000000000000000112b98340eee2777cc3c14163dea3ec97977ac3dc5c70da32e6e87578f44912e902ccef9efe28d4a78b8999dfbca942600000000000000000000000000000000186b28d92356c4dfec4b5201ad099dbdede3781f8998ddf929b4cd7756192185ca7b8f4ef7088f813270ac3d48868a219a2b64cc58f8992cb21237914262ca9ada6cb13dc7b7d3f11c278fe0462040e467316d736d20756e6e6f726d616c697a6564207363616c6172206d69736d617463680000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e10000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000110000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e10000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e10000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000572cbea904d67468808c8eb50a9450c9721db309128012543902d0ac358a62ae28f75bb8f1c7c42c39a8c5529bf0f4e00000000000000000000000000000000166a9d8cabc673a322fda673779d8e3822ba3ecb8670e461f73bb9021d5fd76a4c56d9d4cd16bd1bba86881979749d28a26469706673582212206042625b125d28998f0f0c280fa3f805fa529d55fada73a7eac45816ccba44e264736f6c634300081e0033 \ No newline at end of file diff --git a/itests/contracts/bls12/G1MsmTest.sol b/itests/contracts/bls12/G1MsmTest.sol new file mode 100644 index 00000000000..71434dcc31d --- /dev/null +++ b/itests/contracts/bls12/G1MsmTest.sol @@ -0,0 +1,72 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.20; + +contract G1MsmTest { + function callOk(address pc, bytes memory input, uint256 expectedLen) internal view returns (bytes memory) { + (bool ok, bytes memory out) = pc.staticcall(input); + require(ok, "precompile reverted"); + require(out.length == expectedLen, "unexpected return length"); + return out; + } + + function expectRevert(address pc, bytes memory input) internal view { + (bool ok, ) = pc.staticcall(input); + require(!ok, "expected revert"); + } + + function expectEq(bytes memory a, bytes memory b, string memory what) internal pure { + require(keccak256(a) == keccak256(b), what); + } + + address constant PRECOMPILE = 0x000000000000000000000000000000000000000C; // BLS12_G1MSM + uint256 constant OUT_LEN = 128; + + // Vector: (g1, 2) -> 2*g1 + bytes constant INPUT_G1_2X = hex"0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e10000000000000000000000000000000000000000000000000000000000000002"; + bytes constant EXPECT_G1_2X = hex"000000000000000000000000000000000572cbea904d67468808c8eb50a9450c9721db309128012543902d0ac358a62ae28f75bb8f1c7c42c39a8c5529bf0f4e00000000000000000000000000000000166a9d8cabc673a322fda673779d8e3822ba3ecb8670e461f73bb9021d5fd76a4c56d9d4cd16bd1bba86881979749d28"; + // Vector: 1*g1 = g1 + bytes constant INPUT_G1_1X = hex"0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e10000000000000000000000000000000000000000000000000000000000000001"; + bytes constant EXPECT_G1_1X = hex"0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e1"; + // Vector: 0*g1 = inf + bytes constant INPUT_G1_0X = hex"0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e10000000000000000000000000000000000000000000000000000000000000000"; + bytes constant EXPECT_INF_G1 = hex"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + // Vector: x*inf = inf (any non-zero scalar) + bytes constant INPUT_X_INF = hex"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011"; + // Vector: random p1 with unnormalized scalar + bytes constant INPUT_P1_UNNORM = hex"00000000000000000000000000000000112b98340eee2777cc3c14163dea3ec97977ac3dc5c70da32e6e87578f44912e902ccef9efe28d4a78b8999dfbca942600000000000000000000000000000000186b28d92356c4dfec4b5201ad099dbdede3781f8998ddf929b4cd7756192185ca7b8f4ef7088f813270ac3d48868a219a2b64cc58f8992cb21237914262ca9ada6cb13dc7b7d3f11c278fe0462040e4"; + bytes constant EXPECT_P1_UNNORM = hex"0000000000000000000000000000000006ee9c9331228753bcb148d0ca8623447701bb0aa6eafb0340aa7f81543923474e00f2a225de65c62dd1d8303270220c0000000000000000000000000000000018dd7be47eb4e80985d7a0d2cc96c8b004250b36a5c3ec0217705d453d3ecc6d0d3d1588722da51b40728baba1e93804"; + // Multi-pair MSM (from Rust tests) -> expected point + bytes constant INPUT_MULTI = hex"0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e1263dbd792f5b1be47ed85f8938c0f29586af0d3ac7b977f21c278fe1462040e300000000000000000000000000000000112b98340eee2777cc3c14163dea3ec97977ac3dc5c70da32e6e87578f44912e902ccef9efe28d4a78b8999dfbca942600000000000000000000000000000000186b28d92356c4dfec4b5201ad099dbdede3781f8998ddf929b4cd7756192185ca7b8f4ef7088f813270ac3d48868a2147b8192d77bf871b62e87859d653922725724a5c031afeabc60bcef5ff66513800000000000000000000000000000000184bb665c37ff561a89ec2122dd343f20e0f4cbcaec84e3c3052ea81d1834e192c426074b02ed3dca4e7676ce4ce48ba0000000000000000000000000000000004407b8d35af4dacc809927071fc0405218f1401a6d15af775810e4e460064bcc9468beeba82fdc751be70476c888bf3328388aff0d4a5b7dc9205abd374e7e98f3cd9f3418edb4eafda5fb16473d21600000000000000000000000000000000009769f3ab59bfd551d53a5f846b9984c59b97d6842b20a2c565baa167945e3d026a3755b6345df8ec7e6acb6868ae6d000000000000000000000000000000001532c00cf61aa3d0ce3e5aa20c3b531a2abd2c770a790a2613818303c6b830ffc0ecf6c357af3317b9575c567f11cd2c263dbd792f5b1be47ed85f8938c0f29586af0d3ac7b977f21c278fe1462040e2000000000000000000000000000000001974dbb8e6b5d20b84df7e625e2fbfecb2cdb5f77d5eae5fb2955e5ce7313cae8364bc2fff520a6c25619739c6bdcb6a0000000000000000000000000000000015f9897e11c6441eaa676de141c8d83c37aab8667173cbe1dfd6de74d11861b961dccebcd9d289ac633455dfcc7013a347b8192d77bf871b62e87859d653922725724a5c031afeabc60bcef5ff665131000000000000000000000000000000000a7a047c4a8397b3446450642c2ac64d7239b61872c9ae7a59707a8f4f950f101e766afe58223b3bff3a19a7f754027c000000000000000000000000000000001383aebba1e4327ccff7cf9912bda0dbc77de048b71ef8c8a81111d71dc33c5e3aa6edee9cf6f5fe525d50cc50b77cc9328388aff0d4a5b7dc9205abd374e7e98f3cd9f3418edb4eafda5fb16473d211000000000000000000000000000000000e7a16a975904f131682edbb03d9560d3e48214c9986bd50417a77108d13dc957500edf96462a3d01e62dc6cd468ef11000000000000000000000000000000000ae89e677711d05c30a48d6d75e76ca9fb70fe06c6dd6ff988683d89ccde29ac7d46c53bb97a59b1901abf1db66052db55b53c4669f19f0fc7431929bc0363d7d8fb432435fcde2635fdba334424e9f5"; + bytes constant EXPECT_MULTI = hex"00000000000000000000000000000000053fbdb09b6b5faa08bfe7b7069454247ad4d8bd57e90e2d2ebaa04003dcf110aa83072c07f480ab2107cca2ccff6091000000000000000000000000000000001654537b7c96fe64d13906066679c3d45808cb666452b55d1b909c230cc4b423c3f932c58754b9b762dc49fcc825522c"; + // 2g1 + inf -> 2*g1 + bytes constant INPUT_2G1_PLUS_INF = hex"0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e1000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002"; + bytes constant EXPECT_2G1_PLUS_INF = hex"000000000000000000000000000000000572cbea904d67468808c8eb50a9450c9721db309128012543902d0ac358a62ae28f75bb8f1c7c42c39a8c5529bf0f4e00000000000000000000000000000000166a9d8cabc673a322fda673779d8e3822ba3ecb8670e461f73bb9021d5fd76a4c56d9d4cd16bd1bba86881979749d28"; + + function runTests() public view { + // Positive: MSM with single pair equals scalar mul + bytes memory out1 = callOk(PRECOMPILE, INPUT_G1_2X, OUT_LEN); + expectEq(out1, EXPECT_G1_2X, "g1msm 2x mismatch"); + + // Additional positives + bytes memory out2 = callOk(PRECOMPILE, INPUT_G1_1X, OUT_LEN); + expectEq(out2, EXPECT_G1_1X, "g1msm 1x mismatch"); + + bytes memory out3 = callOk(PRECOMPILE, INPUT_G1_0X, OUT_LEN); + expectEq(out3, EXPECT_INF_G1, "g1msm 0x != inf"); + + bytes memory out4 = callOk(PRECOMPILE, INPUT_X_INF, OUT_LEN); + expectEq(out4, EXPECT_INF_G1, "g1msm x*inf != inf"); + + bytes memory out5 = callOk(PRECOMPILE, INPUT_P1_UNNORM, OUT_LEN); + expectEq(out5, EXPECT_P1_UNNORM, "g1msm unnormalized scalar mismatch"); + + bytes memory out6 = callOk(PRECOMPILE, INPUT_MULTI, OUT_LEN); + expectEq(out6, EXPECT_MULTI, "g1msm multiple mismatch"); + + bytes memory out7 = callOk(PRECOMPILE, INPUT_2G1_PLUS_INF, OUT_LEN); + expectEq(out7, EXPECT_2G1_PLUS_INF, "g1msm 2g1+inf mismatch"); + + // Negative: empty input should revert + expectRevert(PRECOMPILE, hex""); + } +} diff --git a/itests/contracts/bls12/G2AddTest.hex b/itests/contracts/bls12/G2AddTest.hex new file mode 100644 index 00000000000..48890f3e527 --- /dev/null +++ b/itests/contracts/bls12/G2AddTest.hex @@ -0,0 +1 @@ +6080604052348015600e575f5ffd5b506118f68061001c5f395ff3fe608060405234801561000f575f5ffd5b5060043610610029575f3560e01c806323d746281461002d575b5f5ffd5b610035610037565b005b5f610061600d60405180610220016040528061020081526020016113c1610200913961010061054e565b90506100be8160405180610120016040528061010081526020016109c161010091396040518060400160405280601281526020017f673261646420616464206d69736d617463680000000000000000000000000000815250610648565b5f6100e8600d6040518061022001604052806102008152602001610bc1610200913961010061054e565b90506101458160405180610120016040528061010081526020016115c161010091396040518060400160405280601a81526020017f673261646420646f75626c696e67206732206d69736d61746368000000000000815250610648565b5f61016f600d60405180610220016040528061020081526020016111c1610200913961010061054e565b90506101cc8160405180610120016040528061010081526020016117c161010091396040518060400160405280601a81526020017f673261646420646f75626c696e67207032206d69736d61746368000000000000815250610648565b5f610265600d6040518061012001604052806101008152602001610ac1610100913961010067ffffffffffffffff81111561020a5761020961074e565b5b6040519080825280601f01601f19166020018201604052801561023c5781602001600182028036833780820191505090505b5060405160200161024e9291906107cd565b60405160208183030381529060405261010061054e565b90506102c2816040518061012001604052806101008152602001610ac161010091396040518060400160405280601c81526020017f6732616464206964656e746974792067322b30206d69736d6174636800000000815250610648565b5f61035b600d60405180610120016040528061010081526020016116c1610100913961010067ffffffffffffffff811115610300576102ff61074e565b5b6040519080825280601f01601f1916602001820160405280156103325781602001600182028036833780820191505090505b506040516020016103449291906107cd565b60405160208183030381529060405261010061054e565b90506103b88160405180610120016040528061010081526020016116c161010091396040518060400160405280601c81526020017f6732616464206964656e746974792070322b30206d69736d6174636800000000815250610648565b5f6103e2600d6040518061022001604052806102008152602001610fc1610200913961010061054e565b90506104728161010067ffffffffffffffff8111156104045761040361074e565b5b6040519080825280601f01601f1916602001820160405280156104365781602001600182028036833780820191505090505b506040518060400160405280601081526020017f67326164642067322d673220213d203000000000000000000000000000000000815250610648565b5f61049c600d6040518061022001604052806102008152602001610dc1610200913961010061054e565b905061052c8161010067ffffffffffffffff8111156104be576104bd61074e565b5b6040519080825280601f01601f1916602001820160405280156104f05781602001600182028036833780820191505090505b506040518060400160405280601081526020017f67326164642070322d703220213d203000000000000000000000000000000000815250610648565b610545600d60405180602001604052805f8152506106a1565b50505050505050565b60605f5f8573ffffffffffffffffffffffffffffffffffffffff168560405161057791906107f0565b5f60405180830381855afa9150503d805f81146105af576040519150601f19603f3d011682016040523d82523d5f602084013e6105b4565b606091505b5091509150816105f9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105f090610860565b60405180910390fd5b8381511461063c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610633906108c8565b60405180910390fd5b80925050509392505050565b8180519060200120838051906020012014819061069b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106929190610938565b60405180910390fd5b50505050565b5f8273ffffffffffffffffffffffffffffffffffffffff16826040516106c791906107f0565b5f60405180830381855afa9150503d805f81146106ff576040519150601f19603f3d011682016040523d82523d5f602084013e610704565b606091505b505090508015610749576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610740906109a2565b60405180910390fd5b505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b5f81519050919050565b5f81905092915050565b8281835e5f83830152505050565b5f6107a78261077b565b6107b18185610785565b93506107c181856020860161078f565b80840191505092915050565b5f6107d8828561079d565b91506107e4828461079d565b91508190509392505050565b5f6107fb828461079d565b915081905092915050565b5f82825260208201905092915050565b7f707265636f6d70696c65207265766572746564000000000000000000000000005f82015250565b5f61084a601383610806565b915061085582610816565b602082019050919050565b5f6020820190508181035f8301526108778161083e565b9050919050565b7f756e65787065637465642072657475726e206c656e67746800000000000000005f82015250565b5f6108b2601883610806565b91506108bd8261087e565b602082019050919050565b5f6020820190508181035f8301526108df816108a6565b9050919050565b5f81519050919050565b5f601f19601f8301169050919050565b5f61090a826108e6565b6109148185610806565b935061092481856020860161078f565b61092d816108f0565b840191505092915050565b5f6020820190508181035f8301526109508184610900565b905092915050565b7f65787065637465642072657665727400000000000000000000000000000000005f82015250565b5f61098c600f83610806565b915061099782610958565b602082019050919050565b5f6020820190508181035f8301526109b981610980565b905091905056fe000000000000000000000000000000000b54a8a7b08bd6827ed9a797de216b8c9057b3a9ca93e2f88e7f04f19accc42da90d883632b9ca4dc38d013f71ede4db00000000000000000000000000000000077eba4eecf0bd764dce8ed5f45040dd8f3b3427cb35230509482c14651713282946306247866dfe39a8e33016fcbe520000000000000000000000000000000014e60a76a29ef85cbd69f251b9f29147b67cfe3ed2823d3f9776b3a0efd2731941d47436dc6d2b58d9e65f8438bad073000000000000000000000000000000001586c3c910d95754fef7a732df78e279c3d37431c6a2b77e67a00c7c130a8fcd4d19f159cbeb997a178108fffffcbd2000000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be00000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be00000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be00000000000000000000000000000000103121a2ceaae586d240843a398967325f8eb5a93e8fea99b62b9f88d8556c80dd726a4b30e84a36eeabaf3592937f2700000000000000000000000000000000086b990f3da2aeac0a36143b7d7c824428215140db1bb859338764cb58458f081d92664f9053b50b3fbd2e4723121b68000000000000000000000000000000000f9e7ba9a86a8f7624aa2b42dcc8772e1af4ae115685e60abc2c9b90242167acef3d0be4050bf935eed7c3b6fc7ba77e000000000000000000000000000000000d22c3652d0dc6f0fc9316e14268477c2049ef772e852108d269d9c38dba1d4802e8dae479818184c08f9a569d87845100000000000000000000000000000000103121a2ceaae586d240843a398967325f8eb5a93e8fea99b62b9f88d8556c80dd726a4b30e84a36eeabaf3592937f2700000000000000000000000000000000086b990f3da2aeac0a36143b7d7c824428215140db1bb859338764cb58458f081d92664f9053b50b3fbd2e4723121b68000000000000000000000000000000000a6296409115572426717c73668335a949829d739cff2cb4ab043710d28f8e772f6ef41aac4806c9cb273c490384032d000000000000000000000000000000000cde4e850c721fa94e8890d500e3655b442d5c0dc4fff1b694c6f8dd68f6d8dc1bc3251a37d27e7af96f65a96278265a00000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be00000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000d1b3cc2c7027888be51d9ef691d77bcb679afda66c73f17f9ee3837a55024f78c71363275a75d75d86bab79f74782aa0000000000000000000000000000000013fa4d4a0ad8b1ce186ed5061789213d993923066dddaf1040bc3ff59f825c78df74f2d75467e25e0f55f8a00fa030ed00000000000000000000000000000000103121a2ceaae586d240843a398967325f8eb5a93e8fea99b62b9f88d8556c80dd726a4b30e84a36eeabaf3592937f2700000000000000000000000000000000086b990f3da2aeac0a36143b7d7c824428215140db1bb859338764cb58458f081d92664f9053b50b3fbd2e4723121b68000000000000000000000000000000000f9e7ba9a86a8f7624aa2b42dcc8772e1af4ae115685e60abc2c9b90242167acef3d0be4050bf935eed7c3b6fc7ba77e000000000000000000000000000000000d22c3652d0dc6f0fc9316e14268477c2049ef772e852108d269d9c38dba1d4802e8dae479818184c08f9a569d87845100000000000000000000000000000000103121a2ceaae586d240843a398967325f8eb5a93e8fea99b62b9f88d8556c80dd726a4b30e84a36eeabaf3592937f2700000000000000000000000000000000086b990f3da2aeac0a36143b7d7c824428215140db1bb859338764cb58458f081d92664f9053b50b3fbd2e4723121b68000000000000000000000000000000000f9e7ba9a86a8f7624aa2b42dcc8772e1af4ae115685e60abc2c9b90242167acef3d0be4050bf935eed7c3b6fc7ba77e000000000000000000000000000000000d22c3652d0dc6f0fc9316e14268477c2049ef772e852108d269d9c38dba1d4802e8dae479818184c08f9a569d87845100000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be00000000000000000000000000000000103121a2ceaae586d240843a398967325f8eb5a93e8fea99b62b9f88d8556c80dd726a4b30e84a36eeabaf3592937f2700000000000000000000000000000000086b990f3da2aeac0a36143b7d7c824428215140db1bb859338764cb58458f081d92664f9053b50b3fbd2e4723121b68000000000000000000000000000000000f9e7ba9a86a8f7624aa2b42dcc8772e1af4ae115685e60abc2c9b90242167acef3d0be4050bf935eed7c3b6fc7ba77e000000000000000000000000000000000d22c3652d0dc6f0fc9316e14268477c2049ef772e852108d269d9c38dba1d4802e8dae479818184c08f9a569d878451000000000000000000000000000000001638533957d540a9d2370f17cc7ed5863bc0b995b8825e0ee1ea1e1e4d00dbae81f14b0bf3611b78c952aacab827a053000000000000000000000000000000000a4edef9c1ed7f729f520e47730a124fd70662a904ba1074728114d1031e1572c6c886f6b57ec72a6178288c47c33577000000000000000000000000000000000468fb440d82b0630aeb8dca2b5256789a66da69bf91009cbfe6bd221e47aa8ae88dece9764bf3bd999d95d71e4c9899000000000000000000000000000000000f6d4552fa65dd2638b361543f887136a43253d9c66c411697003f7a13c308f5422e1aa0a59c8967acdefd8b6e36ccf300000000000000000000000000000000103121a2ceaae586d240843a398967325f8eb5a93e8fea99b62b9f88d8556c80dd726a4b30e84a36eeabaf3592937f2700000000000000000000000000000000086b990f3da2aeac0a36143b7d7c824428215140db1bb859338764cb58458f081d92664f9053b50b3fbd2e4723121b68000000000000000000000000000000000f9e7ba9a86a8f7624aa2b42dcc8772e1af4ae115685e60abc2c9b90242167acef3d0be4050bf935eed7c3b6fc7ba77e000000000000000000000000000000000d22c3652d0dc6f0fc9316e14268477c2049ef772e852108d269d9c38dba1d4802e8dae479818184c08f9a569d878451000000000000000000000000000000000b76fcbb604082a4f2d19858a7befd6053fa181c5119a612dfec83832537f644e02454f2b70d40985ebb08042d1620d40000000000000000000000000000000019a4a02c0ae51365d964c73be7babb719db1c69e0ddbf9a8a335b5bed3b0a4b070d2d5df01d2da4a3f1e56aae2ec106d000000000000000000000000000000000d18322f821ac72d3ca92f92b000483cf5b7d9e5d06873a44071c4e7e81efd904f210208fe0b9b4824f01c65bc7e62080000000000000000000000000000000004e563d53609a2d1e216aaaee5fbc14ef460160db8d1fdc5e1bd4e8b54cd2f39abf6f925969fa405efb9e700b01c7085a26469706673582212206996fb987bae213f419276ef6bf5bc4056df93d5923486406955b746c8f6c14964736f6c634300081e0033 \ No newline at end of file diff --git a/itests/contracts/bls12/G2AddTest.sol b/itests/contracts/bls12/G2AddTest.sol new file mode 100644 index 00000000000..9f2934bb56b --- /dev/null +++ b/itests/contracts/bls12/G2AddTest.sol @@ -0,0 +1,69 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.20; + +contract G2AddTest { + function callOk(address pc, bytes memory input, uint256 expectedLen) internal view returns (bytes memory) { + (bool ok, bytes memory out) = pc.staticcall(input); + require(ok, "precompile reverted"); + require(out.length == expectedLen, "unexpected return length"); + return out; + } + + function expectRevert(address pc, bytes memory input) internal view { + (bool ok, ) = pc.staticcall(input); + require(!ok, "expected revert"); + } + + function expectEq(bytes memory a, bytes memory b, string memory what) internal pure { + require(keccak256(a) == keccak256(b), what); + } + + address constant PRECOMPILE = 0x000000000000000000000000000000000000000d; // BLS12_G2ADD + uint256 constant OUT_LEN = 256; + + // Vector: g2 + p2 + bytes constant INPUT_ADD_G2_P2 = hex"00000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be00000000000000000000000000000000103121a2ceaae586d240843a398967325f8eb5a93e8fea99b62b9f88d8556c80dd726a4b30e84a36eeabaf3592937f2700000000000000000000000000000000086b990f3da2aeac0a36143b7d7c824428215140db1bb859338764cb58458f081d92664f9053b50b3fbd2e4723121b68000000000000000000000000000000000f9e7ba9a86a8f7624aa2b42dcc8772e1af4ae115685e60abc2c9b90242167acef3d0be4050bf935eed7c3b6fc7ba77e000000000000000000000000000000000d22c3652d0dc6f0fc9316e14268477c2049ef772e852108d269d9c38dba1d4802e8dae479818184c08f9a569d878451"; + bytes constant EXPECT_ADD_G2_P2 = hex"000000000000000000000000000000000b54a8a7b08bd6827ed9a797de216b8c9057b3a9ca93e2f88e7f04f19accc42da90d883632b9ca4dc38d013f71ede4db00000000000000000000000000000000077eba4eecf0bd764dce8ed5f45040dd8f3b3427cb35230509482c14651713282946306247866dfe39a8e33016fcbe520000000000000000000000000000000014e60a76a29ef85cbd69f251b9f29147b67cfe3ed2823d3f9776b3a0efd2731941d47436dc6d2b58d9e65f8438bad073000000000000000000000000000000001586c3c910d95754fef7a732df78e279c3d37431c6a2b77e67a00c7c130a8fcd4d19f159cbeb997a178108fffffcbd20"; + // Vector: g2 + g2 = 2*g2 + bytes constant INPUT_G2_PLUS_G2 = hex"00000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be00000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be"; + bytes constant EXPECT_G2_PLUS_G2 = hex"000000000000000000000000000000001638533957d540a9d2370f17cc7ed5863bc0b995b8825e0ee1ea1e1e4d00dbae81f14b0bf3611b78c952aacab827a053000000000000000000000000000000000a4edef9c1ed7f729f520e47730a124fd70662a904ba1074728114d1031e1572c6c886f6b57ec72a6178288c47c33577000000000000000000000000000000000468fb440d82b0630aeb8dca2b5256789a66da69bf91009cbfe6bd221e47aa8ae88dece9764bf3bd999d95d71e4c9899000000000000000000000000000000000f6d4552fa65dd2638b361543f887136a43253d9c66c411697003f7a13c308f5422e1aa0a59c8967acdefd8b6e36ccf3"; + // Vector: p2 + p2 = 2*p2 + bytes constant INPUT_P2_PLUS_P2 = hex"00000000000000000000000000000000103121a2ceaae586d240843a398967325f8eb5a93e8fea99b62b9f88d8556c80dd726a4b30e84a36eeabaf3592937f2700000000000000000000000000000000086b990f3da2aeac0a36143b7d7c824428215140db1bb859338764cb58458f081d92664f9053b50b3fbd2e4723121b68000000000000000000000000000000000f9e7ba9a86a8f7624aa2b42dcc8772e1af4ae115685e60abc2c9b90242167acef3d0be4050bf935eed7c3b6fc7ba77e000000000000000000000000000000000d22c3652d0dc6f0fc9316e14268477c2049ef772e852108d269d9c38dba1d4802e8dae479818184c08f9a569d87845100000000000000000000000000000000103121a2ceaae586d240843a398967325f8eb5a93e8fea99b62b9f88d8556c80dd726a4b30e84a36eeabaf3592937f2700000000000000000000000000000000086b990f3da2aeac0a36143b7d7c824428215140db1bb859338764cb58458f081d92664f9053b50b3fbd2e4723121b68000000000000000000000000000000000f9e7ba9a86a8f7624aa2b42dcc8772e1af4ae115685e60abc2c9b90242167acef3d0be4050bf935eed7c3b6fc7ba77e000000000000000000000000000000000d22c3652d0dc6f0fc9316e14268477c2049ef772e852108d269d9c38dba1d4802e8dae479818184c08f9a569d878451"; + bytes constant EXPECT_P2_PLUS_P2 = hex"000000000000000000000000000000000b76fcbb604082a4f2d19858a7befd6053fa181c5119a612dfec83832537f644e02454f2b70d40985ebb08042d1620d40000000000000000000000000000000019a4a02c0ae51365d964c73be7babb719db1c69e0ddbf9a8a335b5bed3b0a4b070d2d5df01d2da4a3f1e56aae2ec106d000000000000000000000000000000000d18322f821ac72d3ca92f92b000483cf5b7d9e5d06873a44071c4e7e81efd904f210208fe0b9b4824f01c65bc7e62080000000000000000000000000000000004e563d53609a2d1e216aaaee5fbc14ef460160db8d1fdc5e1bd4e8b54cd2f39abf6f925969fa405efb9e700b01c7085"; + // Encoded canonical points (256 bytes each) for identity tests + bytes constant G2_ENC = hex"00000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be"; + bytes constant P2_ENC = hex"00000000000000000000000000000000103121a2ceaae586d240843a398967325f8eb5a93e8fea99b62b9f88d8556c80dd726a4b30e84a36eeabaf3592937f2700000000000000000000000000000000086b990f3da2aeac0a36143b7d7c824428215140db1bb859338764cb58458f081d92664f9053b50b3fbd2e4723121b68000000000000000000000000000000000f9e7ba9a86a8f7624aa2b42dcc8772e1af4ae115685e60abc2c9b90242167acef3d0be4050bf935eed7c3b6fc7ba77e000000000000000000000000000000000d22c3652d0dc6f0fc9316e14268477c2049ef772e852108d269d9c38dba1d4802e8dae479818184c08f9a569d878451"; + // Subtraction (add inverse) vectors -> infinity + bytes constant INPUT_G2_MINUS_G2 = hex"00000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be00000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000d1b3cc2c7027888be51d9ef691d77bcb679afda66c73f17f9ee3837a55024f78c71363275a75d75d86bab79f74782aa0000000000000000000000000000000013fa4d4a0ad8b1ce186ed5061789213d993923066dddaf1040bc3ff59f825c78df74f2d75467e25e0f55f8a00fa030ed"; + bytes constant INPUT_P2_MINUS_P2 = hex"00000000000000000000000000000000103121a2ceaae586d240843a398967325f8eb5a93e8fea99b62b9f88d8556c80dd726a4b30e84a36eeabaf3592937f2700000000000000000000000000000000086b990f3da2aeac0a36143b7d7c824428215140db1bb859338764cb58458f081d92664f9053b50b3fbd2e4723121b68000000000000000000000000000000000f9e7ba9a86a8f7624aa2b42dcc8772e1af4ae115685e60abc2c9b90242167acef3d0be4050bf935eed7c3b6fc7ba77e000000000000000000000000000000000d22c3652d0dc6f0fc9316e14268477c2049ef772e852108d269d9c38dba1d4802e8dae479818184c08f9a569d87845100000000000000000000000000000000103121a2ceaae586d240843a398967325f8eb5a93e8fea99b62b9f88d8556c80dd726a4b30e84a36eeabaf3592937f2700000000000000000000000000000000086b990f3da2aeac0a36143b7d7c824428215140db1bb859338764cb58458f081d92664f9053b50b3fbd2e4723121b68000000000000000000000000000000000a6296409115572426717c73668335a949829d739cff2cb4ab043710d28f8e772f6ef41aac4806c9cb273c490384032d000000000000000000000000000000000cde4e850c721fa94e8890d500e3655b442d5c0dc4fff1b694c6f8dd68f6d8dc1bc3251a37d27e7af96f65a96278265a"; + + function runTests() public view { + // Positive: addition + bytes memory out1 = callOk(PRECOMPILE, INPUT_ADD_G2_P2, OUT_LEN); + expectEq(out1, EXPECT_ADD_G2_P2, "g2add add mismatch"); + + // Additional positives + bytes memory out2 = callOk(PRECOMPILE, INPUT_G2_PLUS_G2, OUT_LEN); + expectEq(out2, EXPECT_G2_PLUS_G2, "g2add doubling g2 mismatch"); + + bytes memory out3 = callOk(PRECOMPILE, INPUT_P2_PLUS_P2, OUT_LEN); + expectEq(out3, EXPECT_P2_PLUS_P2, "g2add doubling p2 mismatch"); + + // Identity: g2 + 0 = g2; p2 + 0 = p2 + bytes memory out4 = callOk(PRECOMPILE, bytes.concat(G2_ENC, new bytes(OUT_LEN)), OUT_LEN); + expectEq(out4, G2_ENC, "g2add identity g2+0 mismatch"); + + bytes memory out5 = callOk(PRECOMPILE, bytes.concat(P2_ENC, new bytes(OUT_LEN)), OUT_LEN); + expectEq(out5, P2_ENC, "g2add identity p2+0 mismatch"); + + // Subtraction to infinity + bytes memory out6 = callOk(PRECOMPILE, INPUT_G2_MINUS_G2, OUT_LEN); + expectEq(out6, new bytes(OUT_LEN), "g2add g2-g2 != 0"); + + bytes memory out7 = callOk(PRECOMPILE, INPUT_P2_MINUS_P2, OUT_LEN); + expectEq(out7, new bytes(OUT_LEN), "g2add p2-p2 != 0"); + + // Negative: incorrect input size should revert + expectRevert(PRECOMPILE, hex""); + } +} diff --git a/itests/contracts/bls12/G2MsmTest.hex b/itests/contracts/bls12/G2MsmTest.hex new file mode 100644 index 00000000000..5510c5821a8 --- /dev/null +++ b/itests/contracts/bls12/G2MsmTest.hex @@ -0,0 +1 @@ +6080604052348015600e575f5ffd5b506111128061001c5f395ff3fe608060405234801561000f575f5ffd5b5060043610610029575f3560e01c806323d746281461002d575b5f5ffd5b610035610037565b005b5f610061600e6040518061014001604052806101208152602001610e9d61012091396101006102fa565b90506100be816040518061012001604052806101008152602001610a5d61010091396040518060400160405280601181526020017f67326d736d203278206d69736d617463680000000000000000000000000000008152506103f4565b5f6100e8600e604051806101400160405280610120815260200161093d61012091396101006102fa565b905061014581604051806101200160405280610100815260200161071d61010091396040518060400160405280601181526020017f67326d736d203178206d69736d617463680000000000000000000000000000008152506103f4565b5f61016f600e6040518061014001604052806101208152602001610fbd61012091396101006102fa565b90506101cc816040518061012001604052806101008152602001610d9d61010091396040518060400160405280600f81526020017f67326d736d20307820213d20696e6600000000000000000000000000000000008152506103f4565b5f6101f6600e604051806101400160405280610120815260200161081d61012091396101006102fa565b9050610253816040518061012001604052806101008152602001610d9d61010091396040518060400160405280601281526020017f67326d736d20782a696e6620213d20696e6600000000000000000000000000008152506103f4565b5f61027d600e6040518061026001604052806102408152602001610b5d61024091396101006102fa565b90506102da816040518061012001604052806101008152602001610a5d61010091396040518060400160405280601681526020017f67326d736d203267322b696e66206d69736d61746368000000000000000000008152506103f4565b6102f3600e60405180602001604052805f81525061044d565b5050505050565b60605f5f8573ffffffffffffffffffffffffffffffffffffffff1685604051610323919061054c565b5f60405180830381855afa9150503d805f811461035b576040519150601f19603f3d011682016040523d82523d5f602084013e610360565b606091505b5091509150816103a5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161039c906105bc565b60405180910390fd5b838151146103e8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103df90610624565b60405180910390fd5b80925050509392505050565b81805190602001208380519060200120148190610447576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161043e9190610694565b60405180910390fd5b50505050565b5f8273ffffffffffffffffffffffffffffffffffffffff1682604051610473919061054c565b5f60405180830381855afa9150503d805f81146104ab576040519150601f19603f3d011682016040523d82523d5f602084013e6104b0565b606091505b5050905080156104f5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104ec906106fe565b60405180910390fd5b505050565b5f81519050919050565b5f81905092915050565b8281835e5f83830152505050565b5f610526826104fa565b6105308185610504565b935061054081856020860161050e565b80840191505092915050565b5f610557828461051c565b915081905092915050565b5f82825260208201905092915050565b7f707265636f6d70696c65207265766572746564000000000000000000000000005f82015250565b5f6105a6601383610562565b91506105b182610572565b602082019050919050565b5f6020820190508181035f8301526105d38161059a565b9050919050565b7f756e65787065637465642072657475726e206c656e67746800000000000000005f82015250565b5f61060e601883610562565b9150610619826105da565b602082019050919050565b5f6020820190508181035f83015261063b81610602565b9050919050565b5f81519050919050565b5f601f19601f8301169050919050565b5f61066682610642565b6106708185610562565b935061068081856020860161050e565b6106898161064c565b840191505092915050565b5f6020820190508181035f8301526106ac818461065c565b905092915050565b7f65787065637465642072657665727400000000000000000000000000000000005f82015250565b5f6106e8600f83610562565b91506106f3826106b4565b602082019050919050565b5f6020820190508181035f830152610715816106dc565b905091905056fe00000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001100000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000001638533957d540a9d2370f17cc7ed5863bc0b995b8825e0ee1ea1e1e4d00dbae81f14b0bf3611b78c952aacab827a053000000000000000000000000000000000a4edef9c1ed7f729f520e47730a124fd70662a904ba1074728114d1031e1572c6c886f6b57ec72a6178288c47c33577000000000000000000000000000000000468fb440d82b0630aeb8dca2b5256789a66da69bf91009cbfe6bd221e47aa8ae88dece9764bf3bd999d95d71e4c9899000000000000000000000000000000000f6d4552fa65dd2638b361543f887136a43253d9c66c411697003f7a13c308f5422e1aa0a59c8967acdefd8b6e36ccf300000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be0000000000000000000000000000000000000000000000000000000000000000a2646970667358221220345b46560fc9fb73d2bc1f44b5b8cc351de388ad826fcc7989c1e11e605cb05064736f6c634300081e0033 \ No newline at end of file diff --git a/itests/contracts/bls12/G2MsmTest.sol b/itests/contracts/bls12/G2MsmTest.sol new file mode 100644 index 00000000000..e4ebae09398 --- /dev/null +++ b/itests/contracts/bls12/G2MsmTest.sol @@ -0,0 +1,60 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.20; + +contract G2MsmTest { + function callOk(address pc, bytes memory input, uint256 expectedLen) internal view returns (bytes memory) { + (bool ok, bytes memory out) = pc.staticcall(input); + require(ok, "precompile reverted"); + require(out.length == expectedLen, "unexpected return length"); + return out; + } + + function expectRevert(address pc, bytes memory input) internal view { + (bool ok, ) = pc.staticcall(input); + require(!ok, "expected revert"); + } + + function expectEq(bytes memory a, bytes memory b, string memory what) internal pure { + require(keccak256(a) == keccak256(b), what); + } + + address constant PRECOMPILE = 0x000000000000000000000000000000000000000E; // BLS12_G2MSM + uint256 constant OUT_LEN = 256; + + // Vector: (g2, 2) -> 2*g2 + bytes constant INPUT_G2_2X = hex"00000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be0000000000000000000000000000000000000000000000000000000000000002"; + bytes constant EXPECT_G2_2X = hex"000000000000000000000000000000001638533957d540a9d2370f17cc7ed5863bc0b995b8825e0ee1ea1e1e4d00dbae81f14b0bf3611b78c952aacab827a053000000000000000000000000000000000a4edef9c1ed7f729f520e47730a124fd70662a904ba1074728114d1031e1572c6c886f6b57ec72a6178288c47c33577000000000000000000000000000000000468fb440d82b0630aeb8dca2b5256789a66da69bf91009cbfe6bd221e47aa8ae88dece9764bf3bd999d95d71e4c9899000000000000000000000000000000000f6d4552fa65dd2638b361543f887136a43253d9c66c411697003f7a13c308f5422e1aa0a59c8967acdefd8b6e36ccf3"; + // Vector: 1*g2 = g2 + bytes constant INPUT_G2_1X = hex"00000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be0000000000000000000000000000000000000000000000000000000000000001"; + bytes constant EXPECT_G2_1X = hex"00000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be"; + // Vector: 0*g2 = inf + bytes constant INPUT_G2_0X = hex"00000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be0000000000000000000000000000000000000000000000000000000000000000"; + bytes constant EXPECT_INF_G2 = hex"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + // Vector: x*inf = inf + bytes constant INPUT_X_INF = hex"000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011"; + // 2g2 + inf -> 2*g2 + bytes constant INPUT_2G2_PLUS_INF = hex"00000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002"; + bytes constant EXPECT_2G2_PLUS_INF = hex"000000000000000000000000000000001638533957d540a9d2370f17cc7ed5863bc0b995b8825e0ee1ea1e1e4d00dbae81f14b0bf3611b78c952aacab827a053000000000000000000000000000000000a4edef9c1ed7f729f520e47730a124fd70662a904ba1074728114d1031e1572c6c886f6b57ec72a6178288c47c33577000000000000000000000000000000000468fb440d82b0630aeb8dca2b5256789a66da69bf91009cbfe6bd221e47aa8ae88dece9764bf3bd999d95d71e4c9899000000000000000000000000000000000f6d4552fa65dd2638b361543f887136a43253d9c66c411697003f7a13c308f5422e1aa0a59c8967acdefd8b6e36ccf3"; + + function runTests() public view { + // Positive: MSM with single pair equals scalar mul + bytes memory out1 = callOk(PRECOMPILE, INPUT_G2_2X, OUT_LEN); + expectEq(out1, EXPECT_G2_2X, "g2msm 2x mismatch"); + + // Additional positives + bytes memory out2 = callOk(PRECOMPILE, INPUT_G2_1X, OUT_LEN); + expectEq(out2, EXPECT_G2_1X, "g2msm 1x mismatch"); + + bytes memory out3 = callOk(PRECOMPILE, INPUT_G2_0X, OUT_LEN); + expectEq(out3, EXPECT_INF_G2, "g2msm 0x != inf"); + + bytes memory out4 = callOk(PRECOMPILE, INPUT_X_INF, OUT_LEN); + expectEq(out4, EXPECT_INF_G2, "g2msm x*inf != inf"); + + bytes memory out5 = callOk(PRECOMPILE, INPUT_2G2_PLUS_INF, OUT_LEN); + expectEq(out5, EXPECT_2G2_PLUS_INF, "g2msm 2g2+inf mismatch"); + + // Negative: empty input should revert + expectRevert(PRECOMPILE, hex""); + } +} diff --git a/itests/contracts/bls12/MapFp2ToG2Test.hex b/itests/contracts/bls12/MapFp2ToG2Test.hex new file mode 100644 index 00000000000..e035ef897d0 --- /dev/null +++ b/itests/contracts/bls12/MapFp2ToG2Test.hex @@ -0,0 +1 @@ +6080604052348015600e575f5ffd5b50610ec38061001c5f395ff3fe608060405234801561000f575f5ffd5b5060043610610029575f3560e01c806323d746281461002d575b5f5ffd5b610035610037565b005b5f61005e60116040518060a001604052806080815260200161098e608091396101006102eb565b90506100bb81604051806101200160405280610100815260200161078e61010091396040518060400160405280601681526020017f6d61705f6670325f746f5f6732206d69736d61746368000000000000000000008152506103e5565b5f6100e260116040518060a0016040528060808152602001610e0e608091396101006102eb565b905061013f816040518061012001604052806101008152602001610d0e61010091396040518060400160405280601981526020017f6d61705f6670325f746f5f6732202332206d69736d61746368000000000000008152506103e5565b5f61016660116040518060a0016040528060808152602001610c8e608091396101006102eb565b90506101c381604051806101200160405280610100815260200161088e61010091396040518060400160405280601981526020017f6d61705f6670325f746f5f6732202333206d69736d61746368000000000000008152506103e5565b5f6101ea60116040518060a0016040528060808152602001610b0e608091396101006102eb565b9050610247816040518061012001604052806101008152602001610b8e61010091396040518060400160405280601981526020017f6d61705f6670325f746f5f6732202334206d69736d61746368000000000000008152506103e5565b5f61026e60116040518060a001604052806080815260200161070e608091396101006102eb565b90506102cb816040518061012001604052806101008152602001610a0e61010091396040518060400160405280601981526020017f6d61705f6670325f746f5f6732202335206d69736d61746368000000000000008152506103e5565b6102e4601160405180602001604052805f81525061043e565b5050505050565b60605f5f8573ffffffffffffffffffffffffffffffffffffffff1685604051610314919061053d565b5f60405180830381855afa9150503d805f811461034c576040519150601f19603f3d011682016040523d82523d5f602084013e610351565b606091505b509150915081610396576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161038d906105ad565b60405180910390fd5b838151146103d9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103d090610615565b60405180910390fd5b80925050509392505050565b81805190602001208380519060200120148190610438576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161042f9190610685565b60405180910390fd5b50505050565b5f8273ffffffffffffffffffffffffffffffffffffffff1682604051610464919061053d565b5f60405180830381855afa9150503d805f811461049c576040519150601f19603f3d011682016040523d82523d5f602084013e6104a1565b606091505b5050905080156104e6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104dd906106ef565b60405180910390fd5b505050565b5f81519050919050565b5f81905092915050565b8281835e5f83830152505050565b5f610517826104eb565b61052181856104f5565b93506105318185602086016104ff565b80840191505092915050565b5f610548828461050d565b915081905092915050565b5f82825260208201905092915050565b7f707265636f6d70696c65207265766572746564000000000000000000000000005f82015250565b5f610597601383610553565b91506105a282610563565b602082019050919050565b5f6020820190508181035f8301526105c48161058b565b9050919050565b7f756e65787065637465642072657475726e206c656e67746800000000000000005f82015250565b5f6105ff601883610553565b915061060a826105cb565b602082019050919050565b5f6020820190508181035f83015261062c816105f3565b9050919050565b5f81519050919050565b5f601f19601f8301169050919050565b5f61065782610633565b6106618185610553565b93506106718185602086016104ff565b61067a8161063d565b840191505092915050565b5f6020820190508181035f83015261069d818461064d565b905092915050565b7f65787065637465642072657665727400000000000000000000000000000000005f82015250565b5f6106d9600f83610553565b91506106e4826106a5565b602082019050919050565b5f6020820190508181035f830152610706816106cd565b905091905056fe0000000000000000000000000000000003f80ce4ff0ca2f576d797a3660e3f65b274285c054feccc3215c879e2c0589d376e83ede13f93c32f05da0f68fd6a1000000000000000000000000000000000006488a837c5413746d868d1efb7232724da10eca410b07d8b505b9363bdccf0a1fc0029bad07d65b15ccfe6dd25e20d0000000000000000000000000000000000e7f4568a82b4b7dc1f14c6aaa055edf51502319c723c4dc2688c7fe5944c213f510328082396515734b6612c4e7bb700000000000000000000000000000000126b855e9e69b1f691f816e48ac6977664d24d99f8724868a184186469ddfd4617367e94527d4b74fc86413483afb35b000000000000000000000000000000000caead0fd7b6176c01436833c79d305c78be307da5f6af6c133c47311def6ff1e0babf57a0fb5539fce7ee12407b0a42000000000000000000000000000000001498aadcf7ae2b345243e281ae076df6de84455d766ab6fcdaad71fab60abb2e8b980a440043cd305db09d283c895e3d00000000000000000000000000000000038af300ef34c7759a6caaa4e69363cafeed218a1f207e93b2c70d91a1263d375d6730bd6b6509dcac3ba5b567e85bf3000000000000000000000000000000000da75be60fb6aa0e9e3143e40c42796edf15685cafe0279afd2a67c3dff1c82341f17effd402e4f1af240ea90f4b659b0000000000000000000000000000000019b148cbdf163cf0894f29660d2e7bfb2b68e37d54cc83fd4e6e62c020eaa48709302ef8e746736c0e19342cc1ce3df4000000000000000000000000000000000492f4fed741b073e5a82580f7c663f9b79e036b70ab3e51162359cec4e77c78086fe879b65ca7a47d34374c8315ac5e0000000000000000000000000000000007355d25caf6e7f2f0cb2812ca0e513bd026ed09dda65b177500fa31714e09ea0ded3a078b526bed3307f804d4b93b040000000000000000000000000000000002829ce3c021339ccb5caf3e187f6370e1e2a311dec9b75363117063ab2015603ff52c3d3b98f19c2f65575e99e8b78c000000000000000000000000000000000ea4e7c33d43e17cc516a72f76437c4bf81d8f4eac69ac355d3bf9b71b8138d55dc10fd458be115afa798b55dac34be1000000000000000000000000000000001565c2f625032d232f13121d3cfb476f45275c303a037faa255f9da62000c2c864ea881e2bcddd111edc4a3c0da3e88d00000000000000000000000000000000043b6f5fe4e52c839148dc66f2b3751e69a0f6ebb3d056d6465d50d4108543ecd956e10fa1640dfd9bc0030cc2558d28000000000000000000000000000000000f8991d2a1ad662e7b6f58ab787947f1fa607fce12dde171bc17903b012091b657e15333e11701edcf5b63ba2a5612470000000000000000000000000000000008d4a0997b9d52fecf99427abb721f0fa779479963315fe21c6445250de7183e3f63bfdf86570da8929489e421d4ee950000000000000000000000000000000016cb4ccad91ec95aab070f22043916cd6a59c4ca94097f7f510043d48515526dc8eaaea27e586f09151ae613688d5a89000000000000000000000000000000000c5ae723be00e6c3f0efe184fdc0702b64588fe77dda152ab13099a3bacd3876767fa7bbad6d6fd90b3642e902b208f90000000000000000000000000000000012c8c05c1d5fc7bfa847f4d7d81e294e66b9a78bc9953990c358945e1f042eedafce608b67fdd3ab0cb2e6e263b9b1ad0000000000000000000000000000000004e77ddb3ede41b5ec4396b7421dd916efc68a358a0d7425bddd253547f2fb4830522358491827265dfc5bcc1928a5690000000000000000000000000000000011c624c56dbe154d759d021eec60fab3d8b852395a89de497e48504366feedd4662d023af447d66926a28076813dd6460000000000000000000000000000000018c16fe362b7dbdfa102e42bdfd3e2f4e6191d479437a59db4eb716986bf08ee1f42634db66bde97d6c16bbfd342b3b8000000000000000000000000000000000e37812ce1b146d998d5f92bdd5ada2a31bfd63dfe18311aa91637b5f279dd045763166aa1615e46a50d8d8f475f184e00000000000000000000000000000000108ed59fd9fae381abfd1d6bce2fd2fa220990f0f837fa30e0f27914ed6e1454db0d1ee957b219f61da6ff8be0d6441f000000000000000000000000000000000296238ea82c6d4adb3c838ee3cb2346049c90b96d602d7bb1b469b905c9228be25c627bffee872def773d5b2a2eb57d00000000000000000000000000000000033f90f6057aadacae7963b0a0b379dd46750c1c94a6357c99b65f63b79e321ff50fe3053330911c56b6ceea08fee65600000000000000000000000000000000153606c417e59fb331b7ae6bce4fbf7c5190c33ce9402b5ebe2b70e44fca614f3f1382a3625ed5493843d0b0a652fc3f00000000000000000000000000000000138879a9559e24cecee8697b8b4ad32cced053138ab913b99872772dc753a2967ed50aabc907937aefb2439ba06cc50c000000000000000000000000000000000a1ae7999ea9bab1dcc9ef8887a6cb6e8f1e22566015428d220b7eec90ffa70ad1f624018a9ad11e78d588bd3617f9f2a26469706673582212205eacd67643ad311fdc5bbeda349963a0ed34e89050220bf0d8802a2a90ce24e964736f6c634300081e0033 \ No newline at end of file diff --git a/itests/contracts/bls12/MapFp2ToG2Test.sol b/itests/contracts/bls12/MapFp2ToG2Test.sol new file mode 100644 index 00000000000..24718abfc14 --- /dev/null +++ b/itests/contracts/bls12/MapFp2ToG2Test.sol @@ -0,0 +1,56 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.20; + +contract MapFp2ToG2Test { + function callOk(address pc, bytes memory input, uint256 expectedLen) internal view returns (bytes memory) { + (bool ok, bytes memory out) = pc.staticcall(input); + require(ok, "precompile reverted"); + require(out.length == expectedLen, "unexpected return length"); + return out; + } + + function expectRevert(address pc, bytes memory input) internal view { + (bool ok, ) = pc.staticcall(input); + require(!ok, "expected revert"); + } + + function expectEq(bytes memory a, bytes memory b, string memory what) internal pure { + require(keccak256(a) == keccak256(b), what); + } + + address constant PRECOMPILE = 0x0000000000000000000000000000000000000011; // MAP_FP2_TO_G2 + uint256 constant OUT_LEN = 256; + + // Vector 1 from Rust tests + bytes constant INPUT1 = hex"0000000000000000000000000000000007355d25caf6e7f2f0cb2812ca0e513bd026ed09dda65b177500fa31714e09ea0ded3a078b526bed3307f804d4b93b040000000000000000000000000000000002829ce3c021339ccb5caf3e187f6370e1e2a311dec9b75363117063ab2015603ff52c3d3b98f19c2f65575e99e8b78c"; + bytes constant EXPECT1 = hex"0000000000000000000000000000000000e7f4568a82b4b7dc1f14c6aaa055edf51502319c723c4dc2688c7fe5944c213f510328082396515734b6612c4e7bb700000000000000000000000000000000126b855e9e69b1f691f816e48ac6977664d24d99f8724868a184186469ddfd4617367e94527d4b74fc86413483afb35b000000000000000000000000000000000caead0fd7b6176c01436833c79d305c78be307da5f6af6c133c47311def6ff1e0babf57a0fb5539fce7ee12407b0a42000000000000000000000000000000001498aadcf7ae2b345243e281ae076df6de84455d766ab6fcdaad71fab60abb2e8b980a440043cd305db09d283c895e3d"; + bytes constant INPUT2 = hex"00000000000000000000000000000000138879a9559e24cecee8697b8b4ad32cced053138ab913b99872772dc753a2967ed50aabc907937aefb2439ba06cc50c000000000000000000000000000000000a1ae7999ea9bab1dcc9ef8887a6cb6e8f1e22566015428d220b7eec90ffa70ad1f624018a9ad11e78d588bd3617f9f2"; + bytes constant EXPECT2 = hex"00000000000000000000000000000000108ed59fd9fae381abfd1d6bce2fd2fa220990f0f837fa30e0f27914ed6e1454db0d1ee957b219f61da6ff8be0d6441f000000000000000000000000000000000296238ea82c6d4adb3c838ee3cb2346049c90b96d602d7bb1b469b905c9228be25c627bffee872def773d5b2a2eb57d00000000000000000000000000000000033f90f6057aadacae7963b0a0b379dd46750c1c94a6357c99b65f63b79e321ff50fe3053330911c56b6ceea08fee65600000000000000000000000000000000153606c417e59fb331b7ae6bce4fbf7c5190c33ce9402b5ebe2b70e44fca614f3f1382a3625ed5493843d0b0a652fc3f"; + bytes constant INPUT3 = hex"0000000000000000000000000000000018c16fe362b7dbdfa102e42bdfd3e2f4e6191d479437a59db4eb716986bf08ee1f42634db66bde97d6c16bbfd342b3b8000000000000000000000000000000000e37812ce1b146d998d5f92bdd5ada2a31bfd63dfe18311aa91637b5f279dd045763166aa1615e46a50d8d8f475f184e"; + bytes constant EXPECT3 = hex"00000000000000000000000000000000038af300ef34c7759a6caaa4e69363cafeed218a1f207e93b2c70d91a1263d375d6730bd6b6509dcac3ba5b567e85bf3000000000000000000000000000000000da75be60fb6aa0e9e3143e40c42796edf15685cafe0279afd2a67c3dff1c82341f17effd402e4f1af240ea90f4b659b0000000000000000000000000000000019b148cbdf163cf0894f29660d2e7bfb2b68e37d54cc83fd4e6e62c020eaa48709302ef8e746736c0e19342cc1ce3df4000000000000000000000000000000000492f4fed741b073e5a82580f7c663f9b79e036b70ab3e51162359cec4e77c78086fe879b65ca7a47d34374c8315ac5e"; + bytes constant INPUT4 = hex"0000000000000000000000000000000008d4a0997b9d52fecf99427abb721f0fa779479963315fe21c6445250de7183e3f63bfdf86570da8929489e421d4ee950000000000000000000000000000000016cb4ccad91ec95aab070f22043916cd6a59c4ca94097f7f510043d48515526dc8eaaea27e586f09151ae613688d5a89"; + bytes constant EXPECT4 = hex"000000000000000000000000000000000c5ae723be00e6c3f0efe184fdc0702b64588fe77dda152ab13099a3bacd3876767fa7bbad6d6fd90b3642e902b208f90000000000000000000000000000000012c8c05c1d5fc7bfa847f4d7d81e294e66b9a78bc9953990c358945e1f042eedafce608b67fdd3ab0cb2e6e263b9b1ad0000000000000000000000000000000004e77ddb3ede41b5ec4396b7421dd916efc68a358a0d7425bddd253547f2fb4830522358491827265dfc5bcc1928a5690000000000000000000000000000000011c624c56dbe154d759d021eec60fab3d8b852395a89de497e48504366feedd4662d023af447d66926a28076813dd646"; + bytes constant INPUT5 = hex"0000000000000000000000000000000003f80ce4ff0ca2f576d797a3660e3f65b274285c054feccc3215c879e2c0589d376e83ede13f93c32f05da0f68fd6a1000000000000000000000000000000000006488a837c5413746d868d1efb7232724da10eca410b07d8b505b9363bdccf0a1fc0029bad07d65b15ccfe6dd25e20d"; + bytes constant EXPECT5 = hex"000000000000000000000000000000000ea4e7c33d43e17cc516a72f76437c4bf81d8f4eac69ac355d3bf9b71b8138d55dc10fd458be115afa798b55dac34be1000000000000000000000000000000001565c2f625032d232f13121d3cfb476f45275c303a037faa255f9da62000c2c864ea881e2bcddd111edc4a3c0da3e88d00000000000000000000000000000000043b6f5fe4e52c839148dc66f2b3751e69a0f6ebb3d056d6465d50d4108543ecd956e10fa1640dfd9bc0030cc2558d28000000000000000000000000000000000f8991d2a1ad662e7b6f58ab787947f1fa607fce12dde171bc17903b012091b657e15333e11701edcf5b63ba2a561247"; + + function runTests() public view { + // Positive + bytes memory out1 = callOk(PRECOMPILE, INPUT1, OUT_LEN); + expectEq(out1, EXPECT1, "map_fp2_to_g2 mismatch"); + + bytes memory out2 = callOk(PRECOMPILE, INPUT2, OUT_LEN); + expectEq(out2, EXPECT2, "map_fp2_to_g2 #2 mismatch"); + + bytes memory out3 = callOk(PRECOMPILE, INPUT3, OUT_LEN); + expectEq(out3, EXPECT3, "map_fp2_to_g2 #3 mismatch"); + + bytes memory out4 = callOk(PRECOMPILE, INPUT4, OUT_LEN); + expectEq(out4, EXPECT4, "map_fp2_to_g2 #4 mismatch"); + + bytes memory out5 = callOk(PRECOMPILE, INPUT5, OUT_LEN); + expectEq(out5, EXPECT5, "map_fp2_to_g2 #5 mismatch"); + + // Negative: wrong length + expectRevert(PRECOMPILE, hex""); + } +} diff --git a/itests/contracts/bls12/MapFpToG1Test.hex b/itests/contracts/bls12/MapFpToG1Test.hex new file mode 100644 index 00000000000..78959eb8bdb --- /dev/null +++ b/itests/contracts/bls12/MapFpToG1Test.hex @@ -0,0 +1 @@ +6080604052348015600e575f5ffd5b50610aef8061001c5f395ff3fe608060405234801561000f575f5ffd5b5060043610610029575f3560e01c806323d746281461002d575b5f5ffd5b610035610037565b005b5f61005d601060405180606001604052806040815260200161093a6040913960806102d7565b90506100b7816040518060a0016040528060808152602001610a3a608091396040518060400160405280601581526020017f6d61705f66705f746f5f6731206d69736d6174636800000000000000000000008152506103d1565b5f6100dd60106040518060600160405280604081526020016107ba6040913960806102d7565b9050610137816040518060a001604052806080815260200161073a608091396040518060400160405280601881526020017f6d61705f66705f746f5f6731202332206d69736d6174636800000000000000008152506103d1565b5f61015d60106040518060600160405280604081526020016106fa6040913960806102d7565b90506101b7816040518060a00160405280608081526020016108ba608091396040518060400160405280601881526020017f6d61705f66705f746f5f6731202333206d69736d6174636800000000000000008152506103d1565b5f6101dd60106040518060600160405280604081526020016109fa6040913960806102d7565b9050610237816040518060a001604052806080815260200161083a608091396040518060400160405280601881526020017f6d61705f66705f746f5f6731202334206d69736d6174636800000000000000008152506103d1565b5f61025d60106040518060600160405280604081526020016107fa6040913960806102d7565b90506102b7816040518060a001604052806080815260200161097a608091396040518060400160405280601881526020017f6d61705f66705f746f5f6731202335206d69736d6174636800000000000000008152506103d1565b6102d0601060405180602001604052805f81525061042a565b5050505050565b60605f5f8573ffffffffffffffffffffffffffffffffffffffff16856040516103009190610529565b5f60405180830381855afa9150503d805f8114610338576040519150601f19603f3d011682016040523d82523d5f602084013e61033d565b606091505b509150915081610382576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161037990610599565b60405180910390fd5b838151146103c5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103bc90610601565b60405180910390fd5b80925050509392505050565b81805190602001208380519060200120148190610424576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161041b9190610671565b60405180910390fd5b50505050565b5f8273ffffffffffffffffffffffffffffffffffffffff16826040516104509190610529565b5f60405180830381855afa9150503d805f8114610488576040519150601f19603f3d011682016040523d82523d5f602084013e61048d565b606091505b5050905080156104d2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104c9906106db565b60405180910390fd5b505050565b5f81519050919050565b5f81905092915050565b8281835e5f83830152505050565b5f610503826104d7565b61050d81856104e1565b935061051d8185602086016104eb565b80840191505092915050565b5f61053482846104f9565b915081905092915050565b5f82825260208201905092915050565b7f707265636f6d70696c65207265766572746564000000000000000000000000005f82015250565b5f61058360138361053f565b915061058e8261054f565b602082019050919050565b5f6020820190508181035f8301526105b081610577565b9050919050565b7f756e65787065637465642072657475726e206c656e67746800000000000000005f82015250565b5f6105eb60188361053f565b91506105f6826105b7565b602082019050919050565b5f6020820190508181035f830152610618816105df565b9050919050565b5f81519050919050565b5f601f19601f8301169050919050565b5f6106438261061f565b61064d818561053f565b935061065d8185602086016104eb565b61066681610629565b840191505092915050565b5f6020820190508181035f8301526106898184610639565b905092915050565b7f65787065637465642072657665727400000000000000000000000000000000005f82015250565b5f6106c5600f8361053f565b91506106d082610691565b602082019050919050565b5f6020820190508181035f8301526106f2816106b9565b905091905056fe0000000000000000000000000000000004090815ad598a06897dd89bcda860f25837d54e897298ce31e6947378134d3761dc59a572154963e8c954919ecfa82d00000000000000000000000000000000009769f3ab59bfd551d53a5f846b9984c59b97d6842b20a2c565baa167945e3d026a3755b6345df8ec7e6acb6868ae6d000000000000000000000000000000001532c00cf61aa3d0ce3e5aa20c3b531a2abd2c770a790a2613818303c6b830ffc0ecf6c357af3317b9575c567f11cd2c00000000000000000000000000000000147e1ed29f06e4c5079b9d14fc89d2820d32419b990c1c7bb7dbea2a36a045124b31ffbde7c99329c05c559af1c6cc82000000000000000000000000000000000dd824886d2123a96447f6c56e3a3fa992fbfefdba17b6673f9f630ff19e4d326529db37e1c1be43f905bf9202e0278d000000000000000000000000000000000a7a047c4a8397b3446450642c2ac64d7239b61872c9ae7a59707a8f4f950f101e766afe58223b3bff3a19a7f754027c000000000000000000000000000000001383aebba1e4327ccff7cf9912bda0dbc77de048b71ef8c8a81111d71dc33c5e3aa6edee9cf6f5fe525d50cc50b77cc9000000000000000000000000000000001974dbb8e6b5d20b84df7e625e2fbfecb2cdb5f77d5eae5fb2955e5ce7313cae8364bc2fff520a6c25619739c6bdcb6a0000000000000000000000000000000015f9897e11c6441eaa676de141c8d83c37aab8667173cbe1dfd6de74d11861b961dccebcd9d289ac633455dfcc7013a300000000000000000000000000000000156c8a6a2c184569d69a76be144b5cdc5141d2d2ca4fe341f011e25e3969c55ad9e9b9ce2eb833c81a908e5fa4ac5f03000000000000000000000000000000000e7a16a975904f131682edbb03d9560d3e48214c9986bd50417a77108d13dc957500edf96462a3d01e62dc6cd468ef11000000000000000000000000000000000ae89e677711d05c30a48d6d75e76ca9fb70fe06c6dd6ff988683d89ccde29ac7d46c53bb97a59b1901abf1db66052db0000000000000000000000000000000008dccd088ca55b8bfbc96fb50bb25c592faa867a8bb78d4e94a8cc2c92306190244532e91feba2b7fed977e3c3bb5a1f00000000000000000000000000000000184bb665c37ff561a89ec2122dd343f20e0f4cbcaec84e3c3052ea81d1834e192c426074b02ed3dca4e7676ce4ce48ba0000000000000000000000000000000004407b8d35af4dacc809927071fc0405218f1401a6d15af775810e4e460064bcc9468beeba82fdc751be70476c888bf3a2646970667358221220e7868d01a23513cf94f2ae00dfc156943da9ea999fb7bb88b533a59cff0f29b464736f6c634300081e0033 \ No newline at end of file diff --git a/itests/contracts/bls12/MapFpToG1Test.sol b/itests/contracts/bls12/MapFpToG1Test.sol new file mode 100644 index 00000000000..7011ff47fde --- /dev/null +++ b/itests/contracts/bls12/MapFpToG1Test.sol @@ -0,0 +1,56 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.20; + +contract MapFpToG1Test { + function callOk(address pc, bytes memory input, uint256 expectedLen) internal view returns (bytes memory) { + (bool ok, bytes memory out) = pc.staticcall(input); + require(ok, "precompile reverted"); + require(out.length == expectedLen, "unexpected return length"); + return out; + } + + function expectRevert(address pc, bytes memory input) internal view { + (bool ok, ) = pc.staticcall(input); + require(!ok, "expected revert"); + } + + function expectEq(bytes memory a, bytes memory b, string memory what) internal pure { + require(keccak256(a) == keccak256(b), what); + } + + address constant PRECOMPILE = 0x0000000000000000000000000000000000000010; // MAP_FP_TO_G1 + uint256 constant OUT_LEN = 128; + + // Vector 1 from Rust tests + bytes constant INPUT1 = hex"00000000000000000000000000000000156c8a6a2c184569d69a76be144b5cdc5141d2d2ca4fe341f011e25e3969c55ad9e9b9ce2eb833c81a908e5fa4ac5f03"; + bytes constant EXPECT1 = hex"00000000000000000000000000000000184bb665c37ff561a89ec2122dd343f20e0f4cbcaec84e3c3052ea81d1834e192c426074b02ed3dca4e7676ce4ce48ba0000000000000000000000000000000004407b8d35af4dacc809927071fc0405218f1401a6d15af775810e4e460064bcc9468beeba82fdc751be70476c888bf3"; + bytes constant INPUT2 = hex"00000000000000000000000000000000147e1ed29f06e4c5079b9d14fc89d2820d32419b990c1c7bb7dbea2a36a045124b31ffbde7c99329c05c559af1c6cc82"; + bytes constant EXPECT2 = hex"00000000000000000000000000000000009769f3ab59bfd551d53a5f846b9984c59b97d6842b20a2c565baa167945e3d026a3755b6345df8ec7e6acb6868ae6d000000000000000000000000000000001532c00cf61aa3d0ce3e5aa20c3b531a2abd2c770a790a2613818303c6b830ffc0ecf6c357af3317b9575c567f11cd2c"; + bytes constant INPUT3 = hex"0000000000000000000000000000000004090815ad598a06897dd89bcda860f25837d54e897298ce31e6947378134d3761dc59a572154963e8c954919ecfa82d"; + bytes constant EXPECT3 = hex"000000000000000000000000000000001974dbb8e6b5d20b84df7e625e2fbfecb2cdb5f77d5eae5fb2955e5ce7313cae8364bc2fff520a6c25619739c6bdcb6a0000000000000000000000000000000015f9897e11c6441eaa676de141c8d83c37aab8667173cbe1dfd6de74d11861b961dccebcd9d289ac633455dfcc7013a3"; + bytes constant INPUT4 = hex"0000000000000000000000000000000008dccd088ca55b8bfbc96fb50bb25c592faa867a8bb78d4e94a8cc2c92306190244532e91feba2b7fed977e3c3bb5a1f"; + bytes constant EXPECT4 = hex"000000000000000000000000000000000a7a047c4a8397b3446450642c2ac64d7239b61872c9ae7a59707a8f4f950f101e766afe58223b3bff3a19a7f754027c000000000000000000000000000000001383aebba1e4327ccff7cf9912bda0dbc77de048b71ef8c8a81111d71dc33c5e3aa6edee9cf6f5fe525d50cc50b77cc9"; + bytes constant INPUT5 = hex"000000000000000000000000000000000dd824886d2123a96447f6c56e3a3fa992fbfefdba17b6673f9f630ff19e4d326529db37e1c1be43f905bf9202e0278d"; + bytes constant EXPECT5 = hex"000000000000000000000000000000000e7a16a975904f131682edbb03d9560d3e48214c9986bd50417a77108d13dc957500edf96462a3d01e62dc6cd468ef11000000000000000000000000000000000ae89e677711d05c30a48d6d75e76ca9fb70fe06c6dd6ff988683d89ccde29ac7d46c53bb97a59b1901abf1db66052db"; + + function runTests() public view { + // Positive + bytes memory out1 = callOk(PRECOMPILE, INPUT1, OUT_LEN); + expectEq(out1, EXPECT1, "map_fp_to_g1 mismatch"); + + bytes memory out2 = callOk(PRECOMPILE, INPUT2, OUT_LEN); + expectEq(out2, EXPECT2, "map_fp_to_g1 #2 mismatch"); + + bytes memory out3 = callOk(PRECOMPILE, INPUT3, OUT_LEN); + expectEq(out3, EXPECT3, "map_fp_to_g1 #3 mismatch"); + + bytes memory out4 = callOk(PRECOMPILE, INPUT4, OUT_LEN); + expectEq(out4, EXPECT4, "map_fp_to_g1 #4 mismatch"); + + bytes memory out5 = callOk(PRECOMPILE, INPUT5, OUT_LEN); + expectEq(out5, EXPECT5, "map_fp_to_g1 #5 mismatch"); + + // Negative: wrong length + expectRevert(PRECOMPILE, hex""); + } +} diff --git a/itests/contracts/bls12/PairingTest.hex b/itests/contracts/bls12/PairingTest.hex new file mode 100644 index 00000000000..e9f13a2c6c2 --- /dev/null +++ b/itests/contracts/bls12/PairingTest.hex @@ -0,0 +1 @@ +6080604052348015600e575f5ffd5b50610fb48061001c5f395ff3fe608060405234801561000f575f5ffd5b5060043610610029575f3560e01c806323d746281461002d575b5f5ffd5b610035610037565b005b5f610060600f604051806101a00160405280610180815260200161065e6101809139602061023b565b90506100b88160405180604001604052806020815260200160018152506040518060400160405280601481526020017f70616972696e67206528302c47322920213d2031000000000000000000000000815250610335565b5f6100e1600f604051806101a001604052806101808152602001610c5e6101809139602061023b565b90506101398160405180604001604052806020815260200160018152506040518060400160405280601481526020017f70616972696e6720652847312c302920213d2031000000000000000000000000815250610335565b5f610162600f604051806101a001604052806101808152602001610dde6101809139602061023b565b905061019c816040518060400160405280602081526020015f815250604051806060016040528060218152602001610f5e60219139610335565b5f6101c5600f604051806104a0016040528061048081526020016107de6104809139602061023b565b905061021c816040518060400160405280602081526020015f8152506040518060400160405280602081526020017f70616972696e672070726f647563742066616c73652065787065637465642030815250610335565b610235600f60405180602001604052805f81525061038e565b50505050565b60605f5f8573ffffffffffffffffffffffffffffffffffffffff1685604051610264919061048d565b5f60405180830381855afa9150503d805f811461029c576040519150601f19603f3d011682016040523d82523d5f602084013e6102a1565b606091505b5091509150816102e6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016102dd906104fd565b60405180910390fd5b83815114610329576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161032090610565565b60405180910390fd5b80925050509392505050565b81805190602001208380519060200120148190610388576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161037f91906105d5565b60405180910390fd5b50505050565b5f8273ffffffffffffffffffffffffffffffffffffffff16826040516103b4919061048d565b5f60405180830381855afa9150503d805f81146103ec576040519150601f19603f3d011682016040523d82523d5f602084013e6103f1565b606091505b505090508015610436576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161042d9061063f565b60405180910390fd5b505050565b5f81519050919050565b5f81905092915050565b8281835e5f83830152505050565b5f6104678261043b565b6104718185610445565b935061048181856020860161044f565b80840191505092915050565b5f610498828461045d565b915081905092915050565b5f82825260208201905092915050565b7f707265636f6d70696c65207265766572746564000000000000000000000000005f82015250565b5f6104e76013836104a3565b91506104f2826104b3565b602082019050919050565b5f6020820190508181035f830152610514816104db565b9050919050565b7f756e65787065637465642072657475726e206c656e67746800000000000000005f82015250565b5f61054f6018836104a3565b915061055a8261051b565b602082019050919050565b5f6020820190508181035f83015261057c81610543565b9050919050565b5f81519050919050565b5f601f19601f8301169050919050565b5f6105a782610583565b6105b181856104a3565b93506105c181856020860161044f565b6105ca8161058d565b840191505092915050565b5f6020820190508181035f8301526105ed818461059d565b905092915050565b7f65787065637465642072657665727400000000000000000000000000000000005f82015250565b5f610629600f836104a3565b9150610634826105f5565b602082019050919050565b5f6020820190508181035f8301526106568161061d565b905091905056fe000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e100000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e100000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e100000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be70616972696e67206e6f6e2d646567656e65726163792065787065637465642030a2646970667358221220e64b247f9cea2a6fc12282266cb05b7e775729169560b9014923d3c544d1f8f064736f6c634300081e0033 \ No newline at end of file diff --git a/itests/contracts/bls12/PairingTest.sol b/itests/contracts/bls12/PairingTest.sol new file mode 100644 index 00000000000..03312ba44dc --- /dev/null +++ b/itests/contracts/bls12/PairingTest.sol @@ -0,0 +1,53 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.20; + +contract PairingTest { + function callOk(address pc, bytes memory input, uint256 expectedLen) internal view returns (bytes memory) { + (bool ok, bytes memory out) = pc.staticcall(input); + require(ok, "precompile reverted"); + require(out.length == expectedLen, "unexpected return length"); + return out; + } + + function expectRevert(address pc, bytes memory input) internal view { + (bool ok, ) = pc.staticcall(input); + require(!ok, "expected revert"); + } + + function expectEq(bytes memory a, bytes memory b, string memory what) internal pure { + require(keccak256(a) == keccak256(b), what); + } + + address constant PRECOMPILE = 0x000000000000000000000000000000000000000F; // BLS12_PAIRING_CHECK + uint256 constant OUT_LEN = 32; + + // Vector: e(0, G2) -> 1 (last byte = 0x01) + bytes constant INPUT_E_0_G2 = hex"000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be"; + bytes constant EXPECT_TRUE = hex"0000000000000000000000000000000000000000000000000000000000000001"; + bytes constant EXPECT_FALSE = hex"0000000000000000000000000000000000000000000000000000000000000000"; + // Vector: e(G1, 0) -> 1 + bytes constant INPUT_E_G1_0 = hex"0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + // Vector: non-degeneracy -> expect 0 + bytes constant INPUT_NON_DEGENERATE = hex"0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e100000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be"; + // Vector: e(G1,G2)*e(0,0)*e(G1,G2) -> 0 + bytes constant INPUT_PRODUCT_FALSE = hex"0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e100000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e100000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be"; + + function runTests() public view { + // Positive: pairing should return true (1) + bytes memory out1 = callOk(PRECOMPILE, INPUT_E_0_G2, OUT_LEN); + expectEq(out1, EXPECT_TRUE, "pairing e(0,G2) != 1"); + + bytes memory out2 = callOk(PRECOMPILE, INPUT_E_G1_0, OUT_LEN); + expectEq(out2, EXPECT_TRUE, "pairing e(G1,0) != 1"); + + // False (0) cases + bytes memory out3 = callOk(PRECOMPILE, INPUT_NON_DEGENERATE, OUT_LEN); + expectEq(out3, EXPECT_FALSE, "pairing non-degeneracy expected 0"); + + bytes memory out4 = callOk(PRECOMPILE, INPUT_PRODUCT_FALSE, OUT_LEN); + expectEq(out4, EXPECT_FALSE, "pairing product false expected 0"); + + // Negative: empty input should revert (length must be multiple of 384 and non-zero) + expectRevert(PRECOMPILE, hex""); + } +} diff --git a/itests/contracts/bls12/compile.sh b/itests/contracts/bls12/compile.sh new file mode 100755 index 00000000000..d46ec7ad0c4 --- /dev/null +++ b/itests/contracts/bls12/compile.sh @@ -0,0 +1,10 @@ +#!/bin/bash +set -eu +set -o pipefail + +#use the solc compiler https://docs.soliditylang.org/en/v0.8.17/installing-solidity.html +# to compile all of the .sol files to their corresponding evm binary files stored as .hex +# solc outputs to stdout a format that we just want to grab the last line of and then remove the trailing newline on that line + +find . -maxdepth 1 -name \*.sol -print0 | + xargs -0 -I{} bash -euc -o pipefail 'solc --bin {} |tail -n1 | tr -d "\n" > $(echo {} | sed -e s/.sol$/.hex/)' diff --git a/itests/fevm_test.go b/itests/fevm_test.go index 820148404ee..33cf18538f6 100644 --- a/itests/fevm_test.go +++ b/itests/fevm_test.go @@ -1853,3 +1853,28 @@ func TestTstore(t *testing.T) { _, _, err = client.EVM().InvokeContractByFuncName(ctx, fromAddr, contractAddr, "testNestedContracts(address)", inputDataContract) require.NoError(t, err) } + +func TestFEVMTestBLS(t *testing.T) { + ctx, cancel, client := kit.SetupFEVMTest(t) + defer cancel() + + tests := []string{ + "G1AddTest", + "G1MsmTest", + "G2AddTest", + "G2MsmTest", + "MapFpToG1Test", + "MapFp2ToG2Test", + "PairingTest", + } + + for _, name := range tests { + name := name + t.Run(name, func(t *testing.T) { + filename := fmt.Sprintf("contracts/bls12/%s.hex", name) + fromAddr, contractAddr := client.EVM().DeployContractFromFilename(ctx, filename) + _, _, err := client.EVM().InvokeContractByFuncName(ctx, fromAddr, contractAddr, "runTests()", []byte{}) + require.NoError(t, err) + }) + } +}