From 9956fdfc99643cd19a36b1775a74614401177a90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ula=C5=9F=20Erdo=C4=9Fan?= Date: Mon, 8 May 2023 04:11:54 +0300 Subject: [PATCH 01/15] crypto/secp2561r1: add secp256r1 curve verifiers (cherry picked from commit fb89b61cdc2ccf6bda9f77f72315e01fa4ffb7d7) --- crypto/secp256r1/publickey.go | 21 +++++++++++++++++++ crypto/secp256r1/verifier.go | 39 +++++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+) create mode 100644 crypto/secp256r1/publickey.go create mode 100644 crypto/secp256r1/verifier.go diff --git a/crypto/secp256r1/publickey.go b/crypto/secp256r1/publickey.go new file mode 100644 index 0000000000..c92afaa1e0 --- /dev/null +++ b/crypto/secp256r1/publickey.go @@ -0,0 +1,21 @@ +package secp256r1 + +import ( + "crypto/ecdsa" + "crypto/elliptic" + "math/big" +) + +// Generates approptiate public key format from given coordinates +func newPublicKey(x, y *big.Int) *ecdsa.PublicKey { + // Check if the given coordinates are valid + if x == nil || y == nil || !elliptic.P256().IsOnCurve(x, y) { + return nil + } + + return &ecdsa.PublicKey{ + Curve: elliptic.P256(), + X: x, + Y: y, + } +} diff --git a/crypto/secp256r1/verifier.go b/crypto/secp256r1/verifier.go new file mode 100644 index 0000000000..67a0dd787d --- /dev/null +++ b/crypto/secp256r1/verifier.go @@ -0,0 +1,39 @@ +package secp256r1 + +import ( + "crypto/ecdsa" + "crypto/elliptic" + "errors" + "math/big" + + "github.com/ethereum/go-ethereum/common" +) + +var ( + secp256k1halfN = new(big.Int).Div(elliptic.P256().Params().N, big.NewInt(2)) +) + +// Verifies the given signature (r, s) for the given hash and public key (x, y). +func Verify(hash []byte, r, s, x, y *big.Int) ([]byte, error) { + // Create the public key format + publicKey := newPublicKey(x, y) + if publicKey == nil { + return nil, errors.New("invalid public key coordinates") + } + + if checkMalleability(s) { + return nil, errors.New("malleability issue") + } + + // Verify the signature with the public key and return 1 if it's valid, 0 otherwise + if ok := ecdsa.Verify(publicKey, hash, r, s); ok { + return common.LeftPadBytes(common.Big1.Bytes(), 32), nil + } + + return common.LeftPadBytes(common.Big0.Bytes(), 32), nil +} + +// Check the malleability issue +func checkMalleability(s *big.Int) bool { + return s.Cmp(secp256k1halfN) <= 0 +} From cdb96096d890880aac45eaaf7ad96e72f284cbde Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ula=C5=9F=20Erdo=C4=9Fan?= Date: Mon, 8 May 2023 04:12:57 +0300 Subject: [PATCH 02/15] core/vm: implement secp256r1 verifier precompiled (cherry picked from commit a8c0a2e05c7b6cafa16d296f91da8cb651bf9d46) --- core/vm/contracts.go | 55 ++++++++++++++++++---- core/vm/contracts_test.go | 13 +++++ core/vm/testdata/precompiles/ecverify.json | 9 ++++ 3 files changed, 68 insertions(+), 9 deletions(-) create mode 100644 core/vm/testdata/precompiles/ecverify.json diff --git a/core/vm/contracts.go b/core/vm/contracts.go index ba7539737c..d5375be753 100644 --- a/core/vm/contracts.go +++ b/core/vm/contracts.go @@ -28,6 +28,7 @@ import ( "github.com/ethereum/go-ethereum/crypto/blake2b" "github.com/ethereum/go-ethereum/crypto/bls12381" "github.com/ethereum/go-ethereum/crypto/bn256" + "github.com/ethereum/go-ethereum/crypto/secp256r1" "github.com/ethereum/go-ethereum/params" "golang.org/x/crypto/ripemd160" ) @@ -79,15 +80,15 @@ var PrecompiledContractsIstanbul = map[common.Address]PrecompiledContract{ // PrecompiledContractsBerlin contains the default set of pre-compiled Ethereum // contracts used in the Berlin release. var PrecompiledContractsBerlin = map[common.Address]PrecompiledContract{ - common.BytesToAddress([]byte{1}): &ecrecover{}, - common.BytesToAddress([]byte{2}): &sha256hash{}, - common.BytesToAddress([]byte{3}): &ripemd160hash{}, - common.BytesToAddress([]byte{4}): &dataCopy{}, - common.BytesToAddress([]byte{5}): &bigModExp{eip2565: true}, - common.BytesToAddress([]byte{6}): &bn256AddIstanbul{}, - common.BytesToAddress([]byte{7}): &bn256ScalarMulIstanbul{}, - common.BytesToAddress([]byte{8}): &bn256PairingIstanbul{}, - common.BytesToAddress([]byte{9}): &blake2F{}, + common.BytesToAddress([]byte{1}): &ecrecover{}, + common.BytesToAddress([]byte{2}): &sha256hash{}, + common.BytesToAddress([]byte{3}): &ripemd160hash{}, + common.BytesToAddress([]byte{4}): &dataCopy{}, + common.BytesToAddress([]byte{5}): &bigModExp{eip2565: true}, + common.BytesToAddress([]byte{6}): &bn256AddIstanbul{}, + common.BytesToAddress([]byte{7}): &bn256ScalarMulIstanbul{}, + common.BytesToAddress([]byte{8}): &bn256PairingIstanbul{}, + common.BytesToAddress([]byte{9}): &blake2F{}, } // PrecompiledContractsBLS contains the set of pre-compiled Ethereum @@ -104,6 +105,12 @@ var PrecompiledContractsBLS = map[common.Address]PrecompiledContract{ common.BytesToAddress([]byte{18}): &bls12381MapG2{}, } +// PrecompiledContractsEcverify contains the precompiled Ethereum +// contract specified in EIP-N. This is exported for testing purposes. +var PrecompiledContractsEcverify = map[common.Address]PrecompiledContract{ + common.BytesToAddress([]byte{19}): &ecverify{}, +} + var ( PrecompiledAddressesBerlin []common.Address PrecompiledAddressesIstanbul []common.Address @@ -1107,3 +1114,33 @@ func (c *bls12381MapG2) Run(input []byte) ([]byte, error) { // Encode the G2 point to 256 bytes return g.EncodePoint(r), nil } + +// ECVERIFY (secp256r1 signature verification) +// implemented as a native contract +type ecverify struct{} + +// RequiredGas returns the gas required to execute the precompiled contract +func (c *ecverify) RequiredGas(input []byte) uint64 { + return params.EcverifyGas +} + +// Run executes the precompiled contract, returning the output and the used gas +func (c *ecverify) Run(input []byte) ([]byte, error) { + // Required input length is 160 bytes + const ecverifyInputLength = 160 + + // "input" is (hash, r, s, x, y), each 32 bytes + input = common.RightPadBytes(input, ecverifyInputLength) + + // Extract the hash, r, s, x, y from the input + hash := input[0:32] + r, s := new(big.Int).SetBytes(input[32:64]), new(big.Int).SetBytes(input[64:96]) + x, y := new(big.Int).SetBytes(input[96:128]), new(big.Int).SetBytes(input[128:160]) + + // Verify the secp256r1 signature + if result, err := secp256r1.Verify(hash, r, s, x, y); err != nil { + return nil, err + } else { + return result, nil + } +} diff --git a/core/vm/contracts_test.go b/core/vm/contracts_test.go index 53f8de5945..3e8f5c71eb 100644 --- a/core/vm/contracts_test.go +++ b/core/vm/contracts_test.go @@ -65,6 +65,7 @@ var allPrecompiles = map[common.Address]PrecompiledContract{ common.BytesToAddress([]byte{16}): &bls12381Pairing{}, common.BytesToAddress([]byte{17}): &bls12381MapG1{}, common.BytesToAddress([]byte{18}): &bls12381MapG2{}, + common.BytesToAddress([]byte{19}): &ecverify{}, } // EIP-152 test vectors @@ -411,3 +412,15 @@ func BenchmarkPrecompiledBLS12381G2MultiExpWorstCase(b *testing.B) { } benchmarkPrecompiled("0f", testcase, b) } + +// Benchmarks the sample inputs from the ECVERIFY precompile. +func BenchmarkPrecompiledEcverify(bench *testing.B) { + t := precompiledTest{ + Input: "2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b98243744ca2b25ce52b927841120de9d5e5a454acabea2ebacaa1f76850934cb0c7c818200fa5e4b4607eeea9593071a6097b132d77c10661c441b5a66eb36856e1251c078c2c1367932e25bf657f6b2e378a26a27e238196295e1c59e2225d372fe603c229d85ea9eb0b090274c59a0600becd11d0df3f91fe44677977119c4ff03", + Expected: "0000000000000000000000000000000000000000000000000000000000000001", + Name: "ecverify", + } + benchmarkPrecompiled("13", t, bench) +} + +func TestPrecompiledEcverify(t *testing.T) { testJson("ecverify", "13", t) } diff --git a/core/vm/testdata/precompiles/ecverify.json b/core/vm/testdata/precompiles/ecverify.json new file mode 100644 index 0000000000..15ad1fbb34 --- /dev/null +++ b/core/vm/testdata/precompiles/ecverify.json @@ -0,0 +1,9 @@ +[ + { + "Input": "2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b98243744ca2b25ce52b927841120de9d5e5a454acabea2ebacaa1f76850934cb0c7c818200fa5e4b4607eeea9593071a6097b132d77c10661c441b5a66eb36856e1251c078c2c1367932e25bf657f6b2e378a26a27e238196295e1c59e2225d372fe603c229d85ea9eb0b090274c59a0600becd11d0df3f91fe44677977119c4ff03", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "CallEcverify", + "NoBenchmark": false + } + ] \ No newline at end of file From 56f193346e1b004f848d85aa728cbd5eac9b0114 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ula=C5=9F=20Erdo=C4=9Fan?= Date: Mon, 8 May 2023 04:13:19 +0300 Subject: [PATCH 03/15] params: add new precompiled gas price (cherry picked from commit c0554c0764a2c021689e8d73b36987b67c954f0c) --- params/protocol_params.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/params/protocol_params.go b/params/protocol_params.go index 1de8e88bd7..685bce776f 100644 --- a/params/protocol_params.go +++ b/params/protocol_params.go @@ -160,6 +160,8 @@ const ( Bls12381MapG1Gas uint64 = 5500 // Gas price for BLS12-381 mapping field element to G1 operation Bls12381MapG2Gas uint64 = 110000 // Gas price for BLS12-381 mapping field element to G2 operation + EcverifyGas uint64 = 3450 // secp256r1 elliptic curve signature verifier gas price + // The Refund Quotient is the cap on how much of the used gas can be refunded. Before EIP-3529, // up to half the consumed gas could be refunded. Redefined as 1/5th in EIP-3529 RefundQuotient uint64 = 2 From ae2d3da5c1da25a207741233980e7d38517a10a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ula=C5=9F=20Erdo=C4=9Fan?= Date: Tue, 16 May 2023 18:05:43 +0300 Subject: [PATCH 04/15] core/vm, params: rename precompiled to p256verify (cherry picked from commit 6c7028a9043f65f0a3596be4a429be4e03d0eb89) --- core/vm/contracts.go | 38 +++++++++---------- core/vm/contracts_test.go | 10 ++--- .../{ecverify.json => p256Verify.json} | 2 +- params/protocol_params.go | 2 +- 4 files changed, 26 insertions(+), 26 deletions(-) rename core/vm/testdata/precompiles/{ecverify.json => p256Verify.json} (93%) diff --git a/core/vm/contracts.go b/core/vm/contracts.go index d5375be753..f07969c435 100644 --- a/core/vm/contracts.go +++ b/core/vm/contracts.go @@ -80,15 +80,15 @@ var PrecompiledContractsIstanbul = map[common.Address]PrecompiledContract{ // PrecompiledContractsBerlin contains the default set of pre-compiled Ethereum // contracts used in the Berlin release. var PrecompiledContractsBerlin = map[common.Address]PrecompiledContract{ - common.BytesToAddress([]byte{1}): &ecrecover{}, - common.BytesToAddress([]byte{2}): &sha256hash{}, - common.BytesToAddress([]byte{3}): &ripemd160hash{}, - common.BytesToAddress([]byte{4}): &dataCopy{}, - common.BytesToAddress([]byte{5}): &bigModExp{eip2565: true}, - common.BytesToAddress([]byte{6}): &bn256AddIstanbul{}, - common.BytesToAddress([]byte{7}): &bn256ScalarMulIstanbul{}, - common.BytesToAddress([]byte{8}): &bn256PairingIstanbul{}, - common.BytesToAddress([]byte{9}): &blake2F{}, + common.BytesToAddress([]byte{1}): &ecrecover{}, + common.BytesToAddress([]byte{2}): &sha256hash{}, + common.BytesToAddress([]byte{3}): &ripemd160hash{}, + common.BytesToAddress([]byte{4}): &dataCopy{}, + common.BytesToAddress([]byte{5}): &bigModExp{eip2565: true}, + common.BytesToAddress([]byte{6}): &bn256AddIstanbul{}, + common.BytesToAddress([]byte{7}): &bn256ScalarMulIstanbul{}, + common.BytesToAddress([]byte{8}): &bn256PairingIstanbul{}, + common.BytesToAddress([]byte{9}): &blake2F{}, } // PrecompiledContractsBLS contains the set of pre-compiled Ethereum @@ -105,10 +105,10 @@ var PrecompiledContractsBLS = map[common.Address]PrecompiledContract{ common.BytesToAddress([]byte{18}): &bls12381MapG2{}, } -// PrecompiledContractsEcverify contains the precompiled Ethereum +// PrecompiledContractsP256Verify contains the precompiled Ethereum // contract specified in EIP-N. This is exported for testing purposes. -var PrecompiledContractsEcverify = map[common.Address]PrecompiledContract{ - common.BytesToAddress([]byte{19}): &ecverify{}, +var PrecompiledContractsP256Verify = map[common.Address]PrecompiledContract{ + common.BytesToAddress([]byte{19}): &p256Verify{}, } var ( @@ -1115,22 +1115,22 @@ func (c *bls12381MapG2) Run(input []byte) ([]byte, error) { return g.EncodePoint(r), nil } -// ECVERIFY (secp256r1 signature verification) +// P256VERIFY (secp256r1 signature verification) // implemented as a native contract -type ecverify struct{} +type p256Verify struct{} // RequiredGas returns the gas required to execute the precompiled contract -func (c *ecverify) RequiredGas(input []byte) uint64 { - return params.EcverifyGas +func (c *p256Verify) RequiredGas(input []byte) uint64 { + return params.P256VerifyGas } // Run executes the precompiled contract, returning the output and the used gas -func (c *ecverify) Run(input []byte) ([]byte, error) { +func (c *p256Verify) Run(input []byte) ([]byte, error) { // Required input length is 160 bytes - const ecverifyInputLength = 160 + const p256VerifyInputLength = 160 // "input" is (hash, r, s, x, y), each 32 bytes - input = common.RightPadBytes(input, ecverifyInputLength) + input = common.RightPadBytes(input, p256VerifyInputLength) // Extract the hash, r, s, x, y from the input hash := input[0:32] diff --git a/core/vm/contracts_test.go b/core/vm/contracts_test.go index 3e8f5c71eb..b025742238 100644 --- a/core/vm/contracts_test.go +++ b/core/vm/contracts_test.go @@ -65,7 +65,7 @@ var allPrecompiles = map[common.Address]PrecompiledContract{ common.BytesToAddress([]byte{16}): &bls12381Pairing{}, common.BytesToAddress([]byte{17}): &bls12381MapG1{}, common.BytesToAddress([]byte{18}): &bls12381MapG2{}, - common.BytesToAddress([]byte{19}): &ecverify{}, + common.BytesToAddress([]byte{19}): &p256Verify{}, } // EIP-152 test vectors @@ -413,14 +413,14 @@ func BenchmarkPrecompiledBLS12381G2MultiExpWorstCase(b *testing.B) { benchmarkPrecompiled("0f", testcase, b) } -// Benchmarks the sample inputs from the ECVERIFY precompile. -func BenchmarkPrecompiledEcverify(bench *testing.B) { +// Benchmarks the sample inputs from the P256VERIFY precompile. +func BenchmarkPrecompiledP256Verify(bench *testing.B) { t := precompiledTest{ Input: "2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b98243744ca2b25ce52b927841120de9d5e5a454acabea2ebacaa1f76850934cb0c7c818200fa5e4b4607eeea9593071a6097b132d77c10661c441b5a66eb36856e1251c078c2c1367932e25bf657f6b2e378a26a27e238196295e1c59e2225d372fe603c229d85ea9eb0b090274c59a0600becd11d0df3f91fe44677977119c4ff03", Expected: "0000000000000000000000000000000000000000000000000000000000000001", - Name: "ecverify", + Name: "p256Verify", } benchmarkPrecompiled("13", t, bench) } -func TestPrecompiledEcverify(t *testing.T) { testJson("ecverify", "13", t) } +func TestPrecompiledP256Verify(t *testing.T) { testJson("p256Verify", "13", t) } diff --git a/core/vm/testdata/precompiles/ecverify.json b/core/vm/testdata/precompiles/p256Verify.json similarity index 93% rename from core/vm/testdata/precompiles/ecverify.json rename to core/vm/testdata/precompiles/p256Verify.json index 15ad1fbb34..c98054d4c2 100644 --- a/core/vm/testdata/precompiles/ecverify.json +++ b/core/vm/testdata/precompiles/p256Verify.json @@ -3,7 +3,7 @@ "Input": "2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b98243744ca2b25ce52b927841120de9d5e5a454acabea2ebacaa1f76850934cb0c7c818200fa5e4b4607eeea9593071a6097b132d77c10661c441b5a66eb36856e1251c078c2c1367932e25bf657f6b2e378a26a27e238196295e1c59e2225d372fe603c229d85ea9eb0b090274c59a0600becd11d0df3f91fe44677977119c4ff03", "Expected": "0000000000000000000000000000000000000000000000000000000000000001", "Gas": 3450, - "Name": "CallEcverify", + "Name": "CallP256Verify", "NoBenchmark": false } ] \ No newline at end of file diff --git a/params/protocol_params.go b/params/protocol_params.go index 685bce776f..10f7aaf81a 100644 --- a/params/protocol_params.go +++ b/params/protocol_params.go @@ -160,7 +160,7 @@ const ( Bls12381MapG1Gas uint64 = 5500 // Gas price for BLS12-381 mapping field element to G1 operation Bls12381MapG2Gas uint64 = 110000 // Gas price for BLS12-381 mapping field element to G2 operation - EcverifyGas uint64 = 3450 // secp256r1 elliptic curve signature verifier gas price + P256VerifyGas uint64 = 3450 // secp256r1 elliptic curve signature verifier gas price // The Refund Quotient is the cap on how much of the used gas can be refunded. Before EIP-3529, // up to half the consumed gas could be refunded. Redefined as 1/5th in EIP-3529 From 83a20d36eca3432dee1420b67db834454ad0ca45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ula=C5=9F=20Erdo=C4=9Fan?= Date: Mon, 22 May 2023 17:57:24 +0200 Subject: [PATCH 05/15] core/vm: simplify the return values format (cherry picked from commit d245194e7724c2a7d153945cc86c9aa8d0b522b3) --- core/vm/contracts.go | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/core/vm/contracts.go b/core/vm/contracts.go index f07969c435..4245a54528 100644 --- a/core/vm/contracts.go +++ b/core/vm/contracts.go @@ -1138,9 +1138,5 @@ func (c *p256Verify) Run(input []byte) ([]byte, error) { x, y := new(big.Int).SetBytes(input[96:128]), new(big.Int).SetBytes(input[128:160]) // Verify the secp256r1 signature - if result, err := secp256r1.Verify(hash, r, s, x, y); err != nil { - return nil, err - } else { - return result, nil - } + return secp256r1.Verify(hash, r, s, x, y) } From fc057aaabb9b1e9faed73ced441caecc28ee6cfe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ula=C5=9F=20Erdo=C4=9Fan?= Date: Mon, 22 May 2023 22:38:41 +0200 Subject: [PATCH 06/15] crypto/secp25r1: fix reverse malleability issue (cherry picked from commit 066a31f6345c8a04a4ebf84efd8c80d87107e6d5) --- crypto/secp256r1/verifier.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crypto/secp256r1/verifier.go b/crypto/secp256r1/verifier.go index 67a0dd787d..9db2d5b930 100644 --- a/crypto/secp256r1/verifier.go +++ b/crypto/secp256r1/verifier.go @@ -35,5 +35,5 @@ func Verify(hash []byte, r, s, x, y *big.Int) ([]byte, error) { // Check the malleability issue func checkMalleability(s *big.Int) bool { - return s.Cmp(secp256k1halfN) <= 0 + return s.Cmp(secp256k1halfN) > 0 } From 40e6de0bf2f5fc3e0c055b3d19f94e933399a7f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ula=C5=9F=20Erdo=C4=9Fan?= Date: Mon, 22 May 2023 22:39:55 +0200 Subject: [PATCH 07/15] core/vm: fix testdata non-malleable for p256Verify (cherry picked from commit ec17e788ade3f43ded67c014f019770634f32a7c) --- core/vm/contracts_test.go | 2 +- core/vm/testdata/precompiles/p256Verify.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/core/vm/contracts_test.go b/core/vm/contracts_test.go index b025742238..24ddae0715 100644 --- a/core/vm/contracts_test.go +++ b/core/vm/contracts_test.go @@ -416,7 +416,7 @@ func BenchmarkPrecompiledBLS12381G2MultiExpWorstCase(b *testing.B) { // Benchmarks the sample inputs from the P256VERIFY precompile. func BenchmarkPrecompiledP256Verify(bench *testing.B) { t := precompiledTest{ - Input: "2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b98243744ca2b25ce52b927841120de9d5e5a454acabea2ebacaa1f76850934cb0c7c818200fa5e4b4607eeea9593071a6097b132d77c10661c441b5a66eb36856e1251c078c2c1367932e25bf657f6b2e378a26a27e238196295e1c59e2225d372fe603c229d85ea9eb0b090274c59a0600becd11d0df3f91fe44677977119c4ff03", + Input: "4cee90eb86eaa050036147a12d49004b6b9c72bd725d39d4785011fe190f0b4da73bd4903f0ce3b639bbbf6e8e80d16931ff4bcf5993d58468e8fb19086e8cac36dbcd03009df8c59286b162af3bd7fcc0450c9aa81be5d10d312af6c66b1d604aebd3099c618202fcfe16ae7770b0c49ab5eadf74b754204a3bb6060e44eff37618b065f9832de4ca6ca971a7a1adc826d0f7c00181a5fb2ddf79ae00b4e10e", Expected: "0000000000000000000000000000000000000000000000000000000000000001", Name: "p256Verify", } diff --git a/core/vm/testdata/precompiles/p256Verify.json b/core/vm/testdata/precompiles/p256Verify.json index c98054d4c2..fbcac41e9f 100644 --- a/core/vm/testdata/precompiles/p256Verify.json +++ b/core/vm/testdata/precompiles/p256Verify.json @@ -1,6 +1,6 @@ [ { - "Input": "2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b98243744ca2b25ce52b927841120de9d5e5a454acabea2ebacaa1f76850934cb0c7c818200fa5e4b4607eeea9593071a6097b132d77c10661c441b5a66eb36856e1251c078c2c1367932e25bf657f6b2e378a26a27e238196295e1c59e2225d372fe603c229d85ea9eb0b090274c59a0600becd11d0df3f91fe44677977119c4ff03", + "Input": "4cee90eb86eaa050036147a12d49004b6b9c72bd725d39d4785011fe190f0b4da73bd4903f0ce3b639bbbf6e8e80d16931ff4bcf5993d58468e8fb19086e8cac36dbcd03009df8c59286b162af3bd7fcc0450c9aa81be5d10d312af6c66b1d604aebd3099c618202fcfe16ae7770b0c49ab5eadf74b754204a3bb6060e44eff37618b065f9832de4ca6ca971a7a1adc826d0f7c00181a5fb2ddf79ae00b4e10e", "Expected": "0000000000000000000000000000000000000000000000000000000000000001", "Gas": 3450, "Name": "CallP256Verify", From b5559e30186326ed614adcb843532793d4a74450 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ula=C5=9F=20Erdo=C4=9Fan?= Date: Thu, 22 Jun 2023 15:40:47 +0300 Subject: [PATCH 08/15] core/vm: update the eip number (cherry picked from commit f5b6d7e9954cae87348e21525210affda09297c1) --- core/vm/contracts.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/vm/contracts.go b/core/vm/contracts.go index 4245a54528..d9e427d5e3 100644 --- a/core/vm/contracts.go +++ b/core/vm/contracts.go @@ -106,7 +106,7 @@ var PrecompiledContractsBLS = map[common.Address]PrecompiledContract{ } // PrecompiledContractsP256Verify contains the precompiled Ethereum -// contract specified in EIP-N. This is exported for testing purposes. +// contract specified in EIP-7212. This is exported for testing purposes. var PrecompiledContractsP256Verify = map[common.Address]PrecompiledContract{ common.BytesToAddress([]byte{19}): &p256Verify{}, } From 0d115db16865edb6903d7bf11126ab64256f366c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ula=C5=9F=20Erdo=C4=9Fan?= Date: Fri, 23 Jun 2023 01:13:27 +0300 Subject: [PATCH 09/15] core, crypto/secp256r1: fix error reverts tx error (cherry picked from commit 2820903f591365b17a4c3bdb36bd49ee2d84054c) --- core/vm/contracts.go | 8 +++++++- crypto/secp256r1/verifier.go | 20 +++++++++++--------- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/core/vm/contracts.go b/core/vm/contracts.go index d9e427d5e3..db73bcebbc 100644 --- a/core/vm/contracts.go +++ b/core/vm/contracts.go @@ -1138,5 +1138,11 @@ func (c *p256Verify) Run(input []byte) ([]byte, error) { x, y := new(big.Int).SetBytes(input[96:128]), new(big.Int).SetBytes(input[128:160]) // Verify the secp256r1 signature - return secp256r1.Verify(hash, r, s, x, y) + if secp256r1.Verify(hash, r, s, x, y) { + // Signature is valid + return common.LeftPadBytes(common.Big1.Bytes(), 32), nil + } else { + // Signature is invalid + return nil, nil + } } diff --git a/crypto/secp256r1/verifier.go b/crypto/secp256r1/verifier.go index 9db2d5b930..e45d49e352 100644 --- a/crypto/secp256r1/verifier.go +++ b/crypto/secp256r1/verifier.go @@ -3,34 +3,36 @@ package secp256r1 import ( "crypto/ecdsa" "crypto/elliptic" - "errors" "math/big" - - "github.com/ethereum/go-ethereum/common" ) var ( + // Half of the order of the subgroup in the elliptic curve secp256k1halfN = new(big.Int).Div(elliptic.P256().Params().N, big.NewInt(2)) ) // Verifies the given signature (r, s) for the given hash and public key (x, y). -func Verify(hash []byte, r, s, x, y *big.Int) ([]byte, error) { +func Verify(hash []byte, r, s, x, y *big.Int) bool { // Create the public key format publicKey := newPublicKey(x, y) + + // Check if they are invalid public key coordinates if publicKey == nil { - return nil, errors.New("invalid public key coordinates") + return false } + // Check the malleability issue if checkMalleability(s) { - return nil, errors.New("malleability issue") + return false } - // Verify the signature with the public key and return 1 if it's valid, 0 otherwise + // Verify the signature with the public key, + // then return true if it's valid, false otherwise if ok := ecdsa.Verify(publicKey, hash, r, s); ok { - return common.LeftPadBytes(common.Big1.Bytes(), 32), nil + return true } - return common.LeftPadBytes(common.Big0.Bytes(), 32), nil + return false } // Check the malleability issue From d64d8e73c11b6ccfa8175e0fae6407d6587fd1ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ula=C5=9F=20Erdo=C4=9Fan?= Date: Fri, 11 Aug 2023 00:36:35 +0300 Subject: [PATCH 10/15] crypto/secp256r1: refactor by simplfying return (cherry picked from commit 1be1875156e2a5a417801deb59546b167e5456c6) --- crypto/secp256r1/verifier.go | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/crypto/secp256r1/verifier.go b/crypto/secp256r1/verifier.go index e45d49e352..a9e833cd65 100644 --- a/crypto/secp256r1/verifier.go +++ b/crypto/secp256r1/verifier.go @@ -28,11 +28,7 @@ func Verify(hash []byte, r, s, x, y *big.Int) bool { // Verify the signature with the public key, // then return true if it's valid, false otherwise - if ok := ecdsa.Verify(publicKey, hash, r, s); ok { - return true - } - - return false + return ecdsa.Verify(publicKey, hash, r, s) } // Check the malleability issue From 2bbf30ff90ff1b94db6986aaf957c80c1e1ed9dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ula=C5=9F=20Erdo=C4=9Fan?= Date: Sun, 24 Sep 2023 04:42:41 +0300 Subject: [PATCH 11/15] core/vm: force the input length of p256verify (cherry picked from commit 21f4932c9bbb8664cf7b3e3c3602b6a48c747893) --- core/vm/contracts.go | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/core/vm/contracts.go b/core/vm/contracts.go index db73bcebbc..4d1047d948 100644 --- a/core/vm/contracts.go +++ b/core/vm/contracts.go @@ -1124,13 +1124,15 @@ func (c *p256Verify) RequiredGas(input []byte) uint64 { return params.P256VerifyGas } -// Run executes the precompiled contract, returning the output and the used gas +// Run executes the precompiled contract with given 160 bytes of param, returning the output and the used gas func (c *p256Verify) Run(input []byte) ([]byte, error) { // Required input length is 160 bytes const p256VerifyInputLength = 160 - - // "input" is (hash, r, s, x, y), each 32 bytes - input = common.RightPadBytes(input, p256VerifyInputLength) + // Check the input length + if len(input) != p256VerifyInputLength { + // Input length is invalid + return nil, nil + } // Extract the hash, r, s, x, y from the input hash := input[0:32] From ab2f20e8ddd540ebccce2fa2473447f54d62183d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ula=C5=9F=20Erdo=C4=9Fan?= Date: Sun, 24 Sep 2023 04:54:00 +0300 Subject: [PATCH 12/15] crypto/secp256r1: reject the reference pubKey coordinates (cherry picked from commit 98f10b0d5e358075d03b76834cd30c97f4fbdfe1) --- crypto/secp256r1/publickey.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/crypto/secp256r1/publickey.go b/crypto/secp256r1/publickey.go index c92afaa1e0..9b84044efa 100644 --- a/crypto/secp256r1/publickey.go +++ b/crypto/secp256r1/publickey.go @@ -13,6 +13,11 @@ func newPublicKey(x, y *big.Int) *ecdsa.PublicKey { return nil } + // Check if the given coordinates are the reference point (infinity) + if x.Sign() == 0 && y.Sign() == 0 { + return nil + } + return &ecdsa.PublicKey{ Curve: elliptic.P256(), X: x, From 738107b6c85b50619e37aa058e6be93cee4ad62f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ula=C5=9F=20Erdo=C4=9Fan?= Date: Sat, 7 Oct 2023 16:08:05 +0300 Subject: [PATCH 13/15] crypto/secp256r1: remove malleability check due to spec (cherry picked from commit cec0b058115282168c5afc5197de3f6b5479dc4a) --- crypto/secp256r1/verifier.go | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/crypto/secp256r1/verifier.go b/crypto/secp256r1/verifier.go index a9e833cd65..ccc0786610 100644 --- a/crypto/secp256r1/verifier.go +++ b/crypto/secp256r1/verifier.go @@ -2,15 +2,9 @@ package secp256r1 import ( "crypto/ecdsa" - "crypto/elliptic" "math/big" ) -var ( - // Half of the order of the subgroup in the elliptic curve - secp256k1halfN = new(big.Int).Div(elliptic.P256().Params().N, big.NewInt(2)) -) - // Verifies the given signature (r, s) for the given hash and public key (x, y). func Verify(hash []byte, r, s, x, y *big.Int) bool { // Create the public key format @@ -21,17 +15,7 @@ func Verify(hash []byte, r, s, x, y *big.Int) bool { return false } - // Check the malleability issue - if checkMalleability(s) { - return false - } - // Verify the signature with the public key, // then return true if it's valid, false otherwise return ecdsa.Verify(publicKey, hash, r, s) } - -// Check the malleability issue -func checkMalleability(s *big.Int) bool { - return s.Cmp(secp256k1halfN) > 0 -} From 05a19f2a360055c489af4eb22e46d6b641d52f8e Mon Sep 17 00:00:00 2001 From: Anshal Shukla Date: Thu, 30 Nov 2023 12:56:21 +0530 Subject: [PATCH 14/15] fix test, add napoli block --- core/vm/contracts.go | 11 +++++++++-- core/vm/contracts_test.go | 6 +++++- core/vm/testdata/precompiles/p256Verify.json | 2 +- params/config.go | 14 +++++++++++--- 4 files changed, 26 insertions(+), 7 deletions(-) diff --git a/core/vm/contracts.go b/core/vm/contracts.go index 4d1047d948..5d1728d1fd 100644 --- a/core/vm/contracts.go +++ b/core/vm/contracts.go @@ -105,13 +105,14 @@ var PrecompiledContractsBLS = map[common.Address]PrecompiledContract{ common.BytesToAddress([]byte{18}): &bls12381MapG2{}, } -// PrecompiledContractsP256Verify contains the precompiled Ethereum +// PrecompiledContractsNapoli contains the precompiled Ethereum // contract specified in EIP-7212. This is exported for testing purposes. -var PrecompiledContractsP256Verify = map[common.Address]PrecompiledContract{ +var PrecompiledContractsNapoli = map[common.Address]PrecompiledContract{ common.BytesToAddress([]byte{19}): &p256Verify{}, } var ( + PrecompiledAddressesNapoli []common.Address PrecompiledAddressesBerlin []common.Address PrecompiledAddressesIstanbul []common.Address PrecompiledAddressesByzantium []common.Address @@ -134,11 +135,17 @@ func init() { for k := range PrecompiledContractsBerlin { PrecompiledAddressesBerlin = append(PrecompiledAddressesBerlin, k) } + + for k := range PrecompiledContractsNapoli { + PrecompiledAddressesNapoli = append(PrecompiledAddressesNapoli, k) + } } // ActivePrecompiles returns the precompiles enabled with the current configuration. func ActivePrecompiles(rules params.Rules) []common.Address { switch { + case rules.IsNapoli: + return PrecompiledAddressesNapoli case rules.IsBerlin: return PrecompiledAddressesBerlin case rules.IsIstanbul: diff --git a/core/vm/contracts_test.go b/core/vm/contracts_test.go index 24ddae0715..c55f58eb51 100644 --- a/core/vm/contracts_test.go +++ b/core/vm/contracts_test.go @@ -423,4 +423,8 @@ func BenchmarkPrecompiledP256Verify(bench *testing.B) { benchmarkPrecompiled("13", t, bench) } -func TestPrecompiledP256Verify(t *testing.T) { testJson("p256Verify", "13", t) } +func TestPrecompiledP256Verify(t *testing.T) { + t.Parallel() + + testJson("p256Verify", "13", t) +} diff --git a/core/vm/testdata/precompiles/p256Verify.json b/core/vm/testdata/precompiles/p256Verify.json index fbcac41e9f..c01387dda7 100644 --- a/core/vm/testdata/precompiles/p256Verify.json +++ b/core/vm/testdata/precompiles/p256Verify.json @@ -6,4 +6,4 @@ "Name": "CallP256Verify", "NoBenchmark": false } - ] \ No newline at end of file +] \ No newline at end of file diff --git a/params/config.go b/params/config.go index e3740068c6..278374356b 100644 --- a/params/config.go +++ b/params/config.go @@ -649,6 +649,7 @@ type ChainConfig struct { ShanghaiBlock *big.Int `json:"shanghaiBlock,omitempty"` // Shanghai switch Block (nil = no fork, 0 = already on shanghai) CancunBlock *big.Int `json:"cancunBlock,omitempty"` // Cancun switch Block (nil = no fork, 0 = already on cancun) PragueBlock *big.Int `json:"pragueBlock,omitempty"` // Prague switch Block (nil = no fork, 0 = already on prague) + NapoliBlock *big.Int `json:"napoliBlock,omitempty"` // Napoli switch Block (nil = no fork, 0 = already on Napoli) // TerminalTotalDifficulty is the amount of total difficulty reached by // the network that triggers the consensus upgrade. @@ -971,21 +972,26 @@ func (c *ChainConfig) IsTerminalPoWBlock(parentTotalDiff *big.Int, totalDiff *bi return parentTotalDiff.Cmp(c.TerminalTotalDifficulty) < 0 && totalDiff.Cmp(c.TerminalTotalDifficulty) >= 0 } -// IsShanghai returns whether time is either equal to the Shanghai fork time or greater. +// IsShanghai returns whether num is either equal to the Shanghai fork block or greater. func (c *ChainConfig) IsShanghai(num *big.Int) bool { return isBlockForked(c.ShanghaiBlock, num) } -// IsCancun returns whether num is either equal to the Cancun fork time or greater. +// IsCancun returns whether num is either equal to the Cancun fork block or greater. func (c *ChainConfig) IsCancun(num *big.Int) bool { return isBlockForked(c.CancunBlock, num) } -// IsPrague returns whether num is either equal to the Prague fork time or greater. +// IsPrague returns whether num is either equal to the Prague fork block or greater. func (c *ChainConfig) IsPrague(num *big.Int) bool { return isBlockForked(c.PragueBlock, num) } +// IsNapoli returns whether num is either equal to the Napoli fork block or greater. +func (c *ChainConfig) IsNapoli(num *big.Int) bool { + return isBlockForked(c.NapoliBlock, num) +} + // CheckCompatible checks whether scheduled fork transitions have been imported // with a mismatching chain configuration. func (c *ChainConfig) CheckCompatible(newcfg *ChainConfig, height uint64, time uint64) *ConfigCompatError { @@ -1327,6 +1333,7 @@ type Rules struct { IsByzantium, IsConstantinople, IsPetersburg, IsIstanbul bool IsBerlin, IsLondon bool IsMerge, IsShanghai, IsCancun, IsPrague bool + IsNapoli bool } // Rules ensures c's ChainID is not nil. @@ -1352,5 +1359,6 @@ func (c *ChainConfig) Rules(num *big.Int, isMerge bool, timestamp uint64) Rules IsShanghai: c.IsShanghai(num), IsCancun: c.IsCancun(num), IsPrague: c.IsPrague(num), + IsNapoli: c.IsNapoli(num), } } From 1e5211c1c7d9968655cc3287cfab9868f5922121 Mon Sep 17 00:00:00 2001 From: Anshal Shukla Date: Fri, 12 Jan 2024 20:45:10 +0530 Subject: [PATCH 15/15] add test cases --- core/vm/contracts.go | 34 +++++++------------- core/vm/contracts_test.go | 6 ++-- core/vm/testdata/precompiles/p256Verify.json | 28 ++++++++++++++++ params/config.go | 9 +----- 4 files changed, 43 insertions(+), 34 deletions(-) diff --git a/core/vm/contracts.go b/core/vm/contracts.go index 70eb0748ad..9e907f97b2 100644 --- a/core/vm/contracts.go +++ b/core/vm/contracts.go @@ -96,16 +96,17 @@ var PrecompiledContractsBerlin = map[common.Address]PrecompiledContract{ // PrecompiledContractsCancun contains the default set of pre-compiled Ethereum // contracts used in the Cancun release. var PrecompiledContractsCancun = map[common.Address]PrecompiledContract{ - common.BytesToAddress([]byte{1}): &ecrecover{}, - common.BytesToAddress([]byte{2}): &sha256hash{}, - common.BytesToAddress([]byte{3}): &ripemd160hash{}, - common.BytesToAddress([]byte{4}): &dataCopy{}, - common.BytesToAddress([]byte{5}): &bigModExp{eip2565: true}, - common.BytesToAddress([]byte{6}): &bn256AddIstanbul{}, - common.BytesToAddress([]byte{7}): &bn256ScalarMulIstanbul{}, - common.BytesToAddress([]byte{8}): &bn256PairingIstanbul{}, - common.BytesToAddress([]byte{9}): &blake2F{}, - common.BytesToAddress([]byte{0x0a}): &kzgPointEvaluation{}, + common.BytesToAddress([]byte{1}): &ecrecover{}, + common.BytesToAddress([]byte{2}): &sha256hash{}, + common.BytesToAddress([]byte{3}): &ripemd160hash{}, + common.BytesToAddress([]byte{4}): &dataCopy{}, + common.BytesToAddress([]byte{5}): &bigModExp{eip2565: true}, + common.BytesToAddress([]byte{6}): &bn256AddIstanbul{}, + common.BytesToAddress([]byte{7}): &bn256ScalarMulIstanbul{}, + common.BytesToAddress([]byte{8}): &bn256PairingIstanbul{}, + common.BytesToAddress([]byte{9}): &blake2F{}, + common.BytesToAddress([]byte{0x0a}): &kzgPointEvaluation{}, + common.BytesToAddress([]byte{0x01, 0x00}): &p256Verify{}, } // PrecompiledContractsBLS contains the set of pre-compiled Ethereum @@ -122,14 +123,7 @@ var PrecompiledContractsBLS = map[common.Address]PrecompiledContract{ common.BytesToAddress([]byte{18}): &bls12381MapG2{}, } -// PrecompiledContractsNapoli contains the precompiled Ethereum -// contract specified in EIP-7212. This is exported for testing purposes. -var PrecompiledContractsNapoli = map[common.Address]PrecompiledContract{ - common.BytesToAddress([]byte{19}): &p256Verify{}, -} - var ( - PrecompiledAddressesNapoli []common.Address PrecompiledAddressesCancun []common.Address PrecompiledAddressesBerlin []common.Address PrecompiledAddressesIstanbul []common.Address @@ -156,17 +150,11 @@ func init() { for k := range PrecompiledContractsCancun { PrecompiledAddressesCancun = append(PrecompiledAddressesCancun, k) } - - for k := range PrecompiledContractsNapoli { - PrecompiledAddressesNapoli = append(PrecompiledAddressesNapoli, k) - } } // ActivePrecompiles returns the precompiles enabled with the current configuration. func ActivePrecompiles(rules params.Rules) []common.Address { switch { - case rules.IsNapoli: - return PrecompiledAddressesNapoli case rules.IsCancun: return PrecompiledAddressesCancun case rules.IsBerlin: diff --git a/core/vm/contracts_test.go b/core/vm/contracts_test.go index f791cebc73..021dfe48eb 100644 --- a/core/vm/contracts_test.go +++ b/core/vm/contracts_test.go @@ -67,7 +67,7 @@ var allPrecompiles = map[common.Address]PrecompiledContract{ common.BytesToAddress([]byte{0x0f, 0x10}): &bls12381Pairing{}, common.BytesToAddress([]byte{0x0f, 0x11}): &bls12381MapG1{}, common.BytesToAddress([]byte{0x0f, 0x12}): &bls12381MapG2{}, - common.BytesToAddress([]byte{19}): &p256Verify{}, + common.BytesToAddress([]byte{0x01, 0x00}): &p256Verify{}, } // EIP-152 test vectors @@ -424,11 +424,11 @@ func BenchmarkPrecompiledP256Verify(bench *testing.B) { Expected: "0000000000000000000000000000000000000000000000000000000000000001", Name: "p256Verify", } - benchmarkPrecompiled("13", t, bench) + benchmarkPrecompiled("100", t, bench) } func TestPrecompiledP256Verify(t *testing.T) { t.Parallel() - testJson("p256Verify", "13", t) + testJson("p256Verify", "100", t) } diff --git a/core/vm/testdata/precompiles/p256Verify.json b/core/vm/testdata/precompiles/p256Verify.json index c01387dda7..54723147a5 100644 --- a/core/vm/testdata/precompiles/p256Verify.json +++ b/core/vm/testdata/precompiles/p256Verify.json @@ -5,5 +5,33 @@ "Gas": 3450, "Name": "CallP256Verify", "NoBenchmark": false + }, + { + "Input": "b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9414de3726ee4d237b410c1d85ebcb05553dc578561d9f7942b7250795beb9b9027b657067322fc00ab35263fde0acabf998cd9fcf1282df9555f85dba7bdbbe2dc90f74c9e210bc3e0c60aeaa03729c9e6acde4a048ee58fd2e466c1e7b0374e606b8c22ad2985df7d792ff344f03ce94a079da801006b13640bc5af7932a7b9", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "CallP256Verify", + "NoBenchmark": false + }, + { + "Input": "b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9b35d6a4f7f6fc5620c97d4287696f5174b3d37fa537b74b5fc26997ba79c725d62fe5e5fe6da76eec924e822c5ef853ede6c17069a9e9133a38f87d61599f68e7d5f3c812a255436846ee84a262b79ec4d0783afccf2433deabdca9ecf62bef5ff24e90988c7f139d378549c3a8bc6c94e6a1c911c1e02e6f48ed65aaf3d296e", + "Expected": "0000000000000000000000000000000000000000000000000000000000000001", + "Gas": 3450, + "Name": "CallP256Verify", + "NoBenchmark": false + }, + { + "Input": "b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9c29c3df6ce3431b6f030b1b68b1589508ad9d1a149830489c638653aa4b08af93f6e86a9a7643403b6f5c593410d9f7234a8cd27309bce90447073ce17476850615ff147863bc8652be1e369444f90bbc5f9df05a26362e609f73ab1f1839fe3cd34fd2ae672c110671d49115825fc56b5148321aabe5ba39f2b46f71149cff9", + "Expected": "", + "Gas": 3450, + "Name": "CallP256Verify", + "NoBenchmark": false + }, + { + "Input": "b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9", + "Expected": "", + "Gas": 3450, + "Name": "CallP256Verify", + "NoBenchmark": false } ] \ No newline at end of file diff --git a/params/config.go b/params/config.go index 3184c4416d..ea00979850 100644 --- a/params/config.go +++ b/params/config.go @@ -518,7 +518,6 @@ type ChainConfig struct { CancunBlock *big.Int `json:"cancunBlock,omitempty"` // Cancun switch Block (nil = no fork, 0 = already on cancun) PragueBlock *big.Int `json:"pragueBlock,omitempty"` // Prague switch Block (nil = no fork, 0 = already on prague) VerkleBlock *big.Int `json:"verkleBlock,omitempty"` // Verkle switch Block (nil = no fork, 0 = already on verkle) - NapoliBlock *big.Int `json:"napoliBlock,omitempty"` // Napoli switch Block (nil = no fork, 0 = already on Napoli) // TerminalTotalDifficulty is the amount of total difficulty reached by // the network that triggers the consensus upgrade. @@ -858,11 +857,6 @@ func (c *ChainConfig) IsPrague(num *big.Int) bool { return isBlockForked(c.PragueBlock, num) } -// IsNapoli returns whether num is either equal to the Napoli fork block or greater. -func (c *ChainConfig) IsNapoli(num *big.Int) bool { - return isBlockForked(c.NapoliBlock, num) -} - // CheckCompatible checks whether scheduled fork transitions have been imported // with a mismatching chain configuration. func (c *ChainConfig) CheckCompatible(newcfg *ChainConfig, height uint64, time uint64) *ConfigCompatError { @@ -1151,7 +1145,7 @@ type Rules struct { IsByzantium, IsConstantinople, IsPetersburg, IsIstanbul bool IsBerlin, IsLondon bool IsMerge, IsShanghai, IsCancun, IsPrague bool - IsVerkle, IsNapoli bool + IsVerkle bool } // Rules ensures c's ChainID is not nil. @@ -1177,6 +1171,5 @@ func (c *ChainConfig) Rules(num *big.Int, isMerge bool, timestamp uint64) Rules IsShanghai: c.IsShanghai(num), IsCancun: c.IsCancun(num), IsPrague: c.IsPrague(num), - IsNapoli: c.IsNapoli(num), } }