Skip to content

Commit

Permalink
Set Bn256PairingMaxInputSizeGranite
Browse files Browse the repository at this point in the history
  • Loading branch information
ImTei committed Aug 7, 2024
1 parent 4499000 commit 04a678f
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 1 deletion.
41 changes: 41 additions & 0 deletions core/vm/contracts.go
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,22 @@ var PrecompiledContractsFjord = map[libcommon.Address]PrecompiledContract{
libcommon.BytesToAddress([]byte{0x01, 0x00}): &p256Verify{},
}

// PrecompiledContractsGranite contains the default set of pre-compiled Ethereum
// contracts used in the Granite release.
var PrecompiledContractsGranite = map[libcommon.Address]PrecompiledContract{
libcommon.BytesToAddress([]byte{1}): &ecrecover{},
libcommon.BytesToAddress([]byte{2}): &sha256hash{},
libcommon.BytesToAddress([]byte{3}): &ripemd160hash{},
libcommon.BytesToAddress([]byte{4}): &dataCopy{},
libcommon.BytesToAddress([]byte{5}): &bigModExp{eip2565: true},
libcommon.BytesToAddress([]byte{6}): &bn256AddIstanbul{},
libcommon.BytesToAddress([]byte{7}): &bn256ScalarMulIstanbul{},
libcommon.BytesToAddress([]byte{8}): &bn256PairingGranite{},
libcommon.BytesToAddress([]byte{9}): &blake2F{},
libcommon.BytesToAddress([]byte{0x0a}): &pointEvaluation{},
libcommon.BytesToAddress([]byte{0x01, 0x00}): &p256Verify{},
}

var PrecompiledContractsNapoli = map[libcommon.Address]PrecompiledContract{
libcommon.BytesToAddress([]byte{0x01}): &ecrecover{},
libcommon.BytesToAddress([]byte{0x02}): &sha256hash{},
Expand Down Expand Up @@ -167,6 +183,7 @@ var PrecompiledContractsPrague = map[libcommon.Address]PrecompiledContract{
}

var (
PrecompiledAddressesGranite []libcommon.Address
PrecompiledAddressesFjord []libcommon.Address
PrecompiledAddressesPrague []libcommon.Address
PrecompiledAddressesNapoli []libcommon.Address
Expand Down Expand Up @@ -196,6 +213,9 @@ func init() {
for k := range PrecompiledContractsFjord {
PrecompiledAddressesFjord = append(PrecompiledAddressesFjord, k)
}
for k := range PrecompiledContractsGranite {
PrecompiledAddressesGranite = append(PrecompiledAddressesGranite, k)
}
for k := range PrecompiledContractsNapoli {
PrecompiledAddressesNapoli = append(PrecompiledAddressesNapoli, k)
}
Expand All @@ -207,6 +227,8 @@ func init() {
// ActivePrecompiles returns the precompiles enabled with the current configuration.
func ActivePrecompiles(rules *chain.Rules) []libcommon.Address {
switch {
case rules.IsOptimismGranite:
return PrecompiledAddressesGranite
case rules.IsOptimismFjord:
return PrecompiledAddressesFjord
case rules.IsPrague:
Expand Down Expand Up @@ -595,6 +617,9 @@ var (

// errBadPairingInput is returned if the bn256 pairing input is invalid.
errBadPairingInput = errors.New("bad elliptic curve pairing size")

// errBadPairingInputSize is returned if the bn256 pairing input size is invalid.
errBadPairingInputSize = errors.New("bad elliptic curve pairing input size")
)

// runBn256Pairing implements the Bn256Pairing precompile, referenced by both
Expand Down Expand Up @@ -628,6 +653,22 @@ func runBn256Pairing(input []byte) ([]byte, error) {
return false32Byte, nil
}

// bn256PairingGranite implements a pairing pre-compile for the bn256 curve
// conforming to Granite consensus rules.
type bn256PairingGranite struct{}

// RequiredGas returns the gas required to execute the pre-compiled contract.
func (c *bn256PairingGranite) RequiredGas(input []byte) uint64 {
return new(bn256PairingIstanbul).RequiredGas(input)
}

func (c *bn256PairingGranite) Run(input []byte) ([]byte, error) {
if len(input) > int(params.Bn256PairingMaxInputSizeGranite) {
return nil, errBadPairingInputSize
}
return runBn256Pairing(input)
}

// bn256PairingIstanbul implements a pairing pre-compile for the bn256 curve
// conforming to Istanbul consensus rules.
type bn256PairingIstanbul struct{}
Expand Down
12 changes: 11 additions & 1 deletion core/vm/contracts_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import (
libcommon "github.com/ledgerwatch/erigon-lib/common"

"github.com/ledgerwatch/erigon/common"
"github.com/ledgerwatch/erigon/params"
)

// precompiledTest defines the input/output pairs for precompiled contract tests.
Expand Down Expand Up @@ -56,7 +57,7 @@ var allPrecompiles = map[libcommon.Address]PrecompiledContract{
libcommon.BytesToAddress([]byte{0xf5}): &bigModExp{eip2565: true},
libcommon.BytesToAddress([]byte{6}): &bn256AddIstanbul{},
libcommon.BytesToAddress([]byte{7}): &bn256ScalarMulIstanbul{},
libcommon.BytesToAddress([]byte{8}): &bn256PairingIstanbul{},
libcommon.BytesToAddress([]byte{8}): &bn256PairingGranite{},
libcommon.BytesToAddress([]byte{9}): &blake2F{},
libcommon.BytesToAddress([]byte{10}): &bls12381G1Add{},
libcommon.BytesToAddress([]byte{11}): &bls12381G1Mul{},
Expand Down Expand Up @@ -420,3 +421,12 @@ func TestPrecompiledP256Verify(t *testing.T) {
// test case from OP Stack Fjord geth
testJson("p256Verify2", "100", t)
}

func TestPrecompileBn256PairingTooLargeInput(t *testing.T) {
big := make([]byte, params.Bn256PairingMaxInputSizeGranite+1)
testPrecompiledFailure("08", precompiledFailureTest{
Input: common.Bytes2Hex(big),
ExpectedError: "bad elliptic curve pairing input size",
Name: "bn256Pairing_input_too_big",
}, t)
}
2 changes: 2 additions & 0 deletions core/vm/evm.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ var emptyCodeHash = crypto.Keccak256Hash(nil)
func (evm *EVM) precompile(addr libcommon.Address) (PrecompiledContract, bool) {
var precompiles map[libcommon.Address]PrecompiledContract
switch {
case evm.chainRules.IsOptimismGranite:
precompiles = PrecompiledContractsGranite
case evm.chainRules.IsOptimismFjord:
precompiles = PrecompiledContractsFjord
case evm.chainRules.IsPrague:
Expand Down
2 changes: 2 additions & 0 deletions params/protocol_params.go
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,8 @@ const (
Bn256PairingPerPointGasByzantium uint64 = 80000 // Byzantium per-point price for an elliptic curve pairing check
Bn256PairingPerPointGasIstanbul uint64 = 34000 // Per-point price for an elliptic curve pairing check

Bn256PairingMaxInputSizeGranite uint64 = 112687 // Maximum input size for an elliptic curve pairing check

Bls12381G1AddGas uint64 = 500 // Price for BLS12-381 elliptic curve G1 point addition
Bls12381G1MulGas uint64 = 12000 // Price for BLS12-381 elliptic curve G1 point scalar multiplication
Bls12381G2AddGas uint64 = 800 // Price for BLS12-381 elliptic curve G2 point addition
Expand Down

0 comments on commit 04a678f

Please sign in to comment.