diff --git a/core/vm/contracts_test.go b/core/vm/contracts_test.go index 0d1f760936..3f2d416879 100644 --- a/core/vm/contracts_test.go +++ b/core/vm/contracts_test.go @@ -65,8 +65,8 @@ var allPrecompiles = map[common.Address]PrecompiledContract{ common.BytesToAddress([]byte{16}): &bls12381Pairing{}, common.BytesToAddress([]byte{17}): &bls12381MapG1{}, common.BytesToAddress([]byte{18}): &bls12381MapG2{}, - common.BytesToAddress([]byte{0x50}): &MinaPoseidon{}, - common.BytesToAddress([]byte{0x51}): &MinaSigner{}, + common.BytesToAddress([]byte{0x50}): &MinaPoseidon{}, + common.BytesToAddress([]byte{0x51}): &MinaSigner{}, } // EIP-152 test vectors @@ -314,6 +314,7 @@ func TestPrecompiledBLS12381Pairing(t *testing.T) { testJson("blsPairing", "1 func TestPrecompiledBLS12381MapG1(t *testing.T) { testJson("blsMapG1", "11", t) } func TestPrecompiledBLS12381MapG2(t *testing.T) { testJson("blsMapG2", "12", t) } func TestPrecompiledMinaPoseidon(t *testing.T) { testJson("minaPoseidon", "50", t) } +func TestPrecompiledMinaSigner(t *testing.T) { testJson("minaSigner", "51", t) } func BenchmarkPrecompiledBLS12381G1Add(b *testing.B) { benchJson("blsG1Add", "0a", b) } func BenchmarkPrecompiledBLS12381G1Mul(b *testing.B) { benchJson("blsG1Mul", "0b", b) } @@ -325,6 +326,7 @@ func BenchmarkPrecompiledBLS12381Pairing(b *testing.B) { benchJson("blsPairin func BenchmarkPrecompiledBLS12381MapG1(b *testing.B) { benchJson("blsMapG1", "11", b) } func BenchmarkPrecompiledBLS12381MapG2(b *testing.B) { benchJson("blsMapG2", "12", b) } func BenchmarkPrecompiledMinaPoseidon(b *testing.B) { benchJson("minaPoseidon", "50", b) } +func BenchmarkPrecompiledMinaSigner(b *testing.B) { benchJson("minaSigner", "51", b) } // Failure tests func TestPrecompiledBLS12381G1AddFail(t *testing.T) { testJsonFail("blsG1Add", "0a", t) } @@ -337,6 +339,7 @@ func TestPrecompiledBLS12381PairingFail(t *testing.T) { testJsonFail("blsPair func TestPrecompiledBLS12381MapG1Fail(t *testing.T) { testJsonFail("blsMapG1", "11", t) } func TestPrecompiledBLS12381MapG2Fail(t *testing.T) { testJsonFail("blsMapG2", "12", t) } func TestPrecompiledMinaPoseidonFail(t *testing.T) { testJsonFail("minaPoseidon", "50", t) } +func TestPrecompiledMinaSignerFail(t *testing.T) { testJsonFail("minaSigner", "51", t) } func loadJson(name string) ([]precompiledTest, error) { data, err := os.ReadFile(fmt.Sprintf("testdata/precompiles/%v.json", name)) diff --git a/core/vm/mina_contracts.go b/core/vm/mina_contracts.go index 7154337f67..d762c61d56 100644 --- a/core/vm/mina_contracts.go +++ b/core/vm/mina_contracts.go @@ -57,6 +57,11 @@ func packErr(message string) []byte { return append(revertSelector, bytes...) } +var ( + errMinaInvalidSignature = errors.New("invalid function signature") + errMinaCallingRustLibFailed = errors.New("calling rust library failed") +) + type MinaPoseidon struct{} func (c *MinaPoseidon) RequiredGas(input []byte) uint64 { @@ -66,14 +71,9 @@ func (c *MinaPoseidon) RequiredGas(input []byte) uint64 { // 0x1f831f84 var poseidonHashSignature = crypto.Keccak256([]byte("poseidonHash(uint8,bytes32[])"))[:4] -var ( - errMinaPoseidonInvalidSignature = errors.New("invalid function signature") - errMinaPoseidonCallingRustLibFailed = errors.New("calling rust library failed") -) - func (c *MinaPoseidon) Run(input []byte) ([]byte, error) { if len(input) < 4 || !bytes.Equal(input[:4], poseidonHashSignature) { - return packErr("Invalid signature"), errMinaPoseidonInvalidSignature + return packErr("Invalid signature"), errMinaInvalidSignature } calldata := input[4:] @@ -105,7 +105,7 @@ func (c *MinaPoseidon) Run(input []byte) ([]byte, error) { C.uintptr_t(len(fields)), (*C.uint8_t)(&output_buffer[0]), ) { - return packErr("Calling Poseidon hash failed"), errMinaPoseidonCallingRustLibFailed + return packErr("Calling Poseidon hash failed"), errMinaCallingRustLibFailed } return output_buffer[:], nil @@ -122,7 +122,7 @@ var verifySignature = crypto.Keccak256([]byte("verify(uint8,bytes32,bytes32,byte func (c *MinaSigner) Run(input []byte) ([]byte, error) { if len(input) < 4 || !bytes.Equal(input[:4], verifySignature) { - return packErr("Invalid signature"), ErrExecutionReverted + return packErr("Invalid signature"), errMinaInvalidSignature } calldata := input[4:] @@ -147,23 +147,26 @@ func (c *MinaSigner) Run(input []byte) ([]byte, error) { signatureS := unpacked[4].([32]uint8) fields := unpacked[5].([][32]uint8) - if len(fields) == 0 { - return packErr("Unable to verify for 0 fields"), ErrExecutionReverted - } - output_buffer := false + var fields_ptr *C.uint8_t + if len(fields) == 0 { + fields_ptr = (*C.uint8_t)(nil) + } else { + fields_ptr = (*C.uint8_t)(&fields[0][0]) + } + if !C.verify( C.uint8_t(networkId), (*C.uint8_t)(&pubKeyX[0]), (*C.uint8_t)(&pubKeyY[0]), (*C.uint8_t)(&signatureRX[0]), (*C.uint8_t)(&signatureS[0]), - (*C.uint8_t)(&fields[0][0]), + fields_ptr, C.uintptr_t(len(fields)), (*C.bool)(&output_buffer), ) { - return packErr("Calling verify failed"), ErrExecutionReverted + return packErr("Calling verify failed"), errMinaCallingRustLibFailed } return abi.Arguments{{Type: sol_bool}}.Pack(output_buffer) diff --git a/core/vm/testdata/precompiles/fail-minaSigner.json b/core/vm/testdata/precompiles/fail-minaSigner.json new file mode 100644 index 0000000000..f6f0bcfd99 --- /dev/null +++ b/core/vm/testdata/precompiles/fail-minaSigner.json @@ -0,0 +1,22 @@ +[ + { + "Input": "aabbccdd", + "ExpectedError": "invalid function signature", + "Name": "mina_signer_invalid_signature" + }, + { + "Input": "462e39d6", + "ExpectedError": "abi: attempting to unmarshall an empty string while arguments are expected", + "Name": "mina_signer_invalid_calldata 1" + }, + { + "Input": "462e39d6aabbccdd", + "ExpectedError": "abi: cannot marshal in to go type: length insufficient 4 require 32", + "Name": "mina_signer_invalid_calldata 2" + }, + { + "Input": "462e39d60000000000000000000000000000000000000000000000000000000000000001ffb2abc6b0af14d8174f994590e37255f187c474ee385af4a399ad272e1eb60cf553e6e81fec4abc17cc21965c1991de96378b28754ab52dc758afe60afa1f0241197af9c449fcfe22fd770592997f157ef7c26eb33657897d077c71fdbb7f30bf2dc3c90732e136a85253dbb6db0c18823a5c573e70fa02c22eba7e04538c0100000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "ExpectedError": "calling rust library failed", + "Name": "mina_poseidon_invalid_field" + } +] diff --git a/core/vm/testdata/precompiles/minaSigner.json b/core/vm/testdata/precompiles/minaSigner.json new file mode 100644 index 0000000000..bcb134de67 --- /dev/null +++ b/core/vm/testdata/precompiles/minaSigner.json @@ -0,0 +1,44 @@ +[ + { + "Input": "462e39d60000000000000000000000000000000000000000000000000000000000000001ffb2abc6b0af14d8174f994590e37255f187c474ee385af4a399ad272e1eb60cf553e6e81fec4abc17cc21965c1991de96378b28754ab52dc758afe60afa1f0241197af9c449fcfe22fd770592997f157ef7c26eb33657897d077c71fdbb7f30bf2dc3c90732e136a85253dbb6db0c18823a5c573e70fa02c22eba7e04538c0100000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000147e64adc9759307d1472d1fe8b9340d67d56b79cea7cfafb04b5647229968809", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Name": "vector 1", + "Gas": 1000, + "NoBenchmark": false + }, + { + "Input": "462e39d60000000000000000000000000000000000000000000000000000000000000001b4286e40a0cfd61dd7457433adfd13d229f8ea277faef68ad6a2ab15a1bf910fd090cf75ab20da968fc2642f5b1545b819c563d14106a943fcce4bab0b2458177e7f89d308cd9fe434621eef98ad4e3fa42461ab4acf39d6051a862793c88c239940148992baff75f41e1c4a1cc13596cfdbc71bc9043cc8deb4f731df3ba13a00000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000041b856ed3cd4b1c194835c47d194ed90dc8cc18eb61825efc53ce72fe8451d006488f11b7917a37b2dc8d54c4aa8bb09ebcedeca1d9aa4bb790dd5710eedf061e5c2e11fac12b2dff35c8bda983880c18084f74b2bd150a6eaf88d9ea9492bd063ae94f5a90f0ccc35b40b91cc1770e97ff951679c9a497334521ea0ea48be32f", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Name": "vector 2", + "Gas": 1000, + "NoBenchmark": false + }, + { + "Input": "462e39d60000000000000000000000000000000000000000000000000000000000000001bf2e7149abba9571f50fcb32c3486af9517dfcc8474909adc3b6cbd2245cf61cbb42e2b30e3e3b8c3cde48299bbd20195cc207e95fba1bb2d68fe79f8ff78931749b0b525a821c5d6393edace3c82a908e91c878a4264eea6710d6924b217a3c7a1df4449137deb4d21b766333358957676cb3dcad1a5a940a7d3eaf33cf1f1600000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000003a359b9b2c05816f11df3b83c11f67c7111bfc82297afcf1d419964a2afc06f3bba9bab58485eebaed5a8192c373a3967a46b70d5a9d141bb3d1ac61422045622af9f76a9f9237d3adb7fd7c4fd3bd3620060578395180c41079292e2b2e10621", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Name": "vector 3", + "Gas": 1000, + "NoBenchmark": false + }, + { + "Input": "462e39d60000000000000000000000000000000000000000000000000000000000000001bf2e7149abba9571f50fcb32c3486af9517dfcc8474909adc3b6cbd2245cf61cbb42e2b30e3e3b8c3cde48299bbd20195cc207e95fba1bb2d68fe79f8ff78931749b0b525a821c5d6393edace3c82a908e91c878a4264eea6710d6924b217a3c7a1df4449137deb4d21b766333358957676cb3dcad1a5a940a7d3eaf33cf1f1600000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000002a359b9b2c05816f11df3b83c11f67c7111bfc82297afcf1d419964a2afc06f3bba9bab58485eebaed5a8192c373a3967a46b70d5a9d141bb3d1ac61422045622", + "Expected": "0000000000000000000000000000000000000000000000000000000000000000", + "Name": "vector 4", + "Gas": 1000, + "NoBenchmark": false + }, + { + "Input": "462e39d60000000000000000000000000000000000000000000000000000000000000001b4286e40a0cfd61dd7457433adfd13d229f8ea277faef68ad6a2ab15a1bf910fbb42e2b30e3e3b8c3cde48299bbd20195cc207e95fba1bb2d68fe79f8ff78931749b0b525a821c5d6393edace3c82a908e91c878a4264eea6710d6924b217a3c7a1df4449137deb4d21b766333358957676cb3dcad1a5a940a7d3eaf33cf1f1600000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000003a359b9b2c05816f11df3b83c11f67c7111bfc82297afcf1d419964a2afc06f3bba9bab58485eebaed5a8192c373a3967a46b70d5a9d141bb3d1ac61422045622af9f76a9f9237d3adb7fd7c4fd3bd3620060578395180c41079292e2b2e10621", + "Expected": "0000000000000000000000000000000000000000000000000000000000000000", + "Name": "vector 5", + "Gas": 1000, + "NoBenchmark": false + }, + { + "Input": "462e39d60000000000000000000000000000000000000000000000000000000000000001bf2e7149abba9571f50fcb32c3486af9517dfcc8474909adc3b6cbd2245cf61cbb42e2b30e3e3b8c3cde48299bbd20195cc207e95fba1bb2d68fe79f8ff78931749b0b525a821c5d6393edace3c82a908e91c878a4264eea6710d6924b217a3cbf2dc3c90732e136a85253dbb6db0c18823a5c573e70fa02c22eba7e04538c0100000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000003a359b9b2c05816f11df3b83c11f67c7111bfc82297afcf1d419964a2afc06f3bba9bab58485eebaed5a8192c373a3967a46b70d5a9d141bb3d1ac61422045622af9f76a9f9237d3adb7fd7c4fd3bd3620060578395180c41079292e2b2e10621", + "Expected": "0000000000000000000000000000000000000000000000000000000000000000", + "Name": "vector 6", + "Gas": 1000, + "NoBenchmark": false + } +]