From a9bcf58160342329a80d9168ccc7732317b3b8c8 Mon Sep 17 00:00:00 2001 From: Kartik Chopra Date: Mon, 25 Nov 2024 12:15:07 -0500 Subject: [PATCH] feat: introduces BLS signature verification precompile (#52) * feat: adds BLS precompile * feat: activates cancun upgrade --- core/vm/contracts.go | 32 ++++++++++++++++++++++++++++++++ geth-poa/genesis.json | 1 + go.mod | 5 ++++- go.sum | 2 ++ params/protocol_params.go | 2 ++ 5 files changed, 41 insertions(+), 1 deletion(-) diff --git a/core/vm/contracts.go b/core/vm/contracts.go index 29fe33b60ee2..b4ec87b580b6 100644 --- a/core/vm/contracts.go +++ b/core/vm/contracts.go @@ -23,6 +23,7 @@ import ( "fmt" "math/big" + "github.com/cloudflare/circl/sign/bls" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/math" "github.com/ethereum/go-ethereum/crypto" @@ -105,6 +106,9 @@ var PrecompiledContractsCancun = map[common.Address]PrecompiledContract{ common.BytesToAddress([]byte{8}): &bn256PairingIstanbul{}, common.BytesToAddress([]byte{9}): &blake2F{}, common.BytesToAddress([]byte{0x0a}): &kzgPointEvaluation{}, + + // primev pre-compiles start at 0xf addresses + common.BytesToAddress([]byte{0xf0}): &bls12381SignatureVerification{}, } // PrecompiledContractsBLS contains the set of pre-compiled Ethereum @@ -653,6 +657,34 @@ var ( errBLS12381G2PointSubgroup = errors.New("g2 point is not on correct subgroup") ) +// bls12381SignatureVerification implements BLS signature verification precompile. +type bls12381SignatureVerification struct{} + +// RequiredGas returns the gas required to execute the pre-compiled contract. +func (c *bls12381SignatureVerification) RequiredGas(input []byte) uint64 { + return params.BlsSignVerifyGas +} + +func (c *bls12381SignatureVerification) Run(input []byte) ([]byte, error) { + // Input format: + // - pubkey (48 bytes) - G1 point + // - message (32 bytes) - Hash of the message + // - signature (96 bytes) - G2 point + if len(input) != 176 { + return nil, errBLS12381InvalidInputLength + } + + var pubKey bls.PublicKey[bls.G1] + if err := pubKey.UnmarshalBinary(input[:48]); err != nil { + return nil, err + } + + if !bls.Verify(&pubKey, input[48:80], input[80:]) { + return nil, nil + } + return input[:48], nil +} + // bls12381G1Add implements EIP-2537 G1Add precompile. type bls12381G1Add struct{} diff --git a/geth-poa/genesis.json b/geth-poa/genesis.json index 6f1e6e230831..ffe42de68b05 100644 --- a/geth-poa/genesis.json +++ b/geth-poa/genesis.json @@ -12,6 +12,7 @@ "muirGlacierBlock": 0, "berlinBlock": 0, "londonBlock": 0, + "cancunTime": 0, "arrowGlacierBlock": 0, "grayGlacierBlock": 0, "clique": { diff --git a/go.mod b/go.mod index f072bf59f60b..bb27902cce8c 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,8 @@ module github.com/ethereum/go-ethereum -go 1.20 +go 1.22.0 + +toolchain go1.23.1 require ( github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.2.0 @@ -91,6 +93,7 @@ require ( github.com/beorn7/perks v1.0.1 // indirect github.com/bits-and-blooms/bitset v1.10.0 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect + github.com/cloudflare/circl v1.5.0 // indirect github.com/cockroachdb/errors v1.8.1 // indirect github.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f // indirect github.com/cockroachdb/redact v1.0.8 // indirect diff --git a/go.sum b/go.sum index 0de564578548..1ca3a9cf3616 100644 --- a/go.sum +++ b/go.sum @@ -116,6 +116,8 @@ github.com/chzyer/readline v1.5.0/go.mod h1:x22KAscuvRqlLoK9CsoYsmxoXZMMFVyOl86c github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/chzyer/test v0.0.0-20210722231415-061457976a23/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cloudflare/circl v1.5.0 h1:hxIWksrX6XN5a1L2TI/h53AGPhNHoUBo+TD1ms9+pys= +github.com/cloudflare/circl v1.5.0/go.mod h1:uddAzsPgqdMAYatqJ0lsjX1oECcQLIlRpzZh3pJrofs= github.com/cloudflare/cloudflare-go v0.79.0 h1:ErwCYDjFCYppDJlDJ/5WhsSmzegAUe2+K9qgFyQDg3M= github.com/cloudflare/cloudflare-go v0.79.0/go.mod h1:gkHQf9xEubaQPEuerBuoinR9P8bf8a05Lq0X6WKy1Oc= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= diff --git a/params/protocol_params.go b/params/protocol_params.go index 7eb63e89ac61..693f63baeef8 100644 --- a/params/protocol_params.go +++ b/params/protocol_params.go @@ -159,6 +159,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 + BlsSignVerifyGas uint64 = 150000 // Gas price for BLS12-381 signature verification + // 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