Skip to content

Commit

Permalink
Include EIP-2537 precompiles into Prague (#9560)
Browse files Browse the repository at this point in the history
Include [EIP-2537](https://eips.ethereum.org/EIPS/eip-2537) into
[Prague/Electra](https://eips.ethereum.org/EIPS/eip-7600). Cherry pick
some related PRs from geth and also implement
ethereum/EIPs#3077 &
ethereum/EIPs#8291.

---------

Co-authored-by: George Carder <[email protected]>
Co-authored-by: jwasinger <[email protected]>
Co-authored-by: lonika <[email protected]>
  • Loading branch information
4 people authored Mar 18, 2024
1 parent 346c5ee commit b59247f
Show file tree
Hide file tree
Showing 18 changed files with 1,111 additions and 666 deletions.
58 changes: 36 additions & 22 deletions core/vm/contracts.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,21 +125,30 @@ var PrecompiledContractsNapoli = map[libcommon.Address]PrecompiledContract{
libcommon.BytesToAddress([]byte{0x01, 0x00}): &p256Verify{},
}

// PrecompiledContractsBLS contains the set of pre-compiled Ethereum
// contracts specified in EIP-2537. These are exported for testing purposes.
var PrecompiledContractsBLS = map[libcommon.Address]PrecompiledContract{
libcommon.BytesToAddress([]byte{0x0c}): &bls12381G1Add{},
libcommon.BytesToAddress([]byte{0x0d}): &bls12381G1Mul{},
libcommon.BytesToAddress([]byte{0x0e}): &bls12381G1MultiExp{},
libcommon.BytesToAddress([]byte{0x0f}): &bls12381G2Add{},
libcommon.BytesToAddress([]byte{0x10}): &bls12381G2Mul{},
libcommon.BytesToAddress([]byte{0x11}): &bls12381G2MultiExp{},
libcommon.BytesToAddress([]byte{0x12}): &bls12381Pairing{},
libcommon.BytesToAddress([]byte{0x13}): &bls12381MapG1{},
libcommon.BytesToAddress([]byte{0x14}): &bls12381MapG2{},
var PrecompiledContractsPrague = map[libcommon.Address]PrecompiledContract{
libcommon.BytesToAddress([]byte{0x01}): &ecrecover{},
libcommon.BytesToAddress([]byte{0x02}): &sha256hash{},
libcommon.BytesToAddress([]byte{0x03}): &ripemd160hash{},
libcommon.BytesToAddress([]byte{0x04}): &dataCopy{},
libcommon.BytesToAddress([]byte{0x05}): &bigModExp{eip2565: true},
libcommon.BytesToAddress([]byte{0x06}): &bn256AddIstanbul{},
libcommon.BytesToAddress([]byte{0x07}): &bn256ScalarMulIstanbul{},
libcommon.BytesToAddress([]byte{0x08}): &bn256PairingIstanbul{},
libcommon.BytesToAddress([]byte{0x09}): &blake2F{},
libcommon.BytesToAddress([]byte{0x0a}): &pointEvaluation{},
libcommon.BytesToAddress([]byte{0x0b}): &bls12381G1Add{},
libcommon.BytesToAddress([]byte{0x0c}): &bls12381G1Mul{},
libcommon.BytesToAddress([]byte{0x0d}): &bls12381G1MultiExp{},
libcommon.BytesToAddress([]byte{0x0e}): &bls12381G2Add{},
libcommon.BytesToAddress([]byte{0x0f}): &bls12381G2Mul{},
libcommon.BytesToAddress([]byte{0x10}): &bls12381G2MultiExp{},
libcommon.BytesToAddress([]byte{0x11}): &bls12381Pairing{},
libcommon.BytesToAddress([]byte{0x12}): &bls12381MapFpToG1{},
libcommon.BytesToAddress([]byte{0x13}): &bls12381MapFp2ToG2{},
}

var (
PrecompiledAddressesPrague []libcommon.Address
PrecompiledAddressesNapoli []libcommon.Address
PrecompiledAddressesCancun []libcommon.Address
PrecompiledAddressesBerlin []libcommon.Address
Expand Down Expand Up @@ -167,11 +176,16 @@ func init() {
for k := range PrecompiledContractsNapoli {
PrecompiledAddressesNapoli = append(PrecompiledAddressesNapoli, k)
}
for k := range PrecompiledContractsPrague {
PrecompiledAddressesPrague = append(PrecompiledAddressesPrague, k)
}
}

// ActivePrecompiles returns the precompiles enabled with the current configuration.
func ActivePrecompiles(rules *chain.Rules) []libcommon.Address {
switch {
case rules.IsPrague:
return PrecompiledAddressesPrague
case rules.IsNapoli:
return PrecompiledAddressesNapoli
case rules.IsCancun:
Expand Down Expand Up @@ -1028,15 +1042,15 @@ func decodeBLS12381FieldElement(in []byte) ([]byte, error) {
return out, nil
}

// bls12381MapG1 implements EIP-2537 MapG1 precompile.
type bls12381MapG1 struct{}
// bls12381MapFpToG1 implements EIP-2537 MapG1 precompile.
type bls12381MapFpToG1 struct{}

// RequiredGas returns the gas required to execute the pre-compiled contract.
func (c *bls12381MapG1) RequiredGas(input []byte) uint64 {
return params.Bls12381MapG1Gas
func (c *bls12381MapFpToG1) RequiredGas(input []byte) uint64 {
return params.Bls12381MapFpToG1Gas
}

func (c *bls12381MapG1) Run(input []byte) ([]byte, error) {
func (c *bls12381MapFpToG1) Run(input []byte) ([]byte, error) {
// Implements EIP-2537 Map_To_G1 precompile.
// > Field-to-curve call expects `64` bytes an an input that is interpreted as a an element of the base field.
// > Output of this call is `128` bytes and is G1 point following respective encoding rules.
Expand All @@ -1063,15 +1077,15 @@ func (c *bls12381MapG1) Run(input []byte) ([]byte, error) {
return g.EncodePoint(r), nil
}

// bls12381MapG2 implements EIP-2537 MapG2 precompile.
type bls12381MapG2 struct{}
// bls12381MapFp2ToG2 implements EIP-2537 MapG2 precompile.
type bls12381MapFp2ToG2 struct{}

// RequiredGas returns the gas required to execute the pre-compiled contract.
func (c *bls12381MapG2) RequiredGas(input []byte) uint64 {
return params.Bls12381MapG2Gas
func (c *bls12381MapFp2ToG2) RequiredGas(input []byte) uint64 {
return params.Bls12381MapFp2ToG2Gas
}

func (c *bls12381MapG2) Run(input []byte) ([]byte, error) {
func (c *bls12381MapFp2ToG2) Run(input []byte) ([]byte, error) {
// Implements EIP-2537 Map_FP2_TO_G2 precompile logic.
// > Field-to-curve call expects `128` bytes an an input that is interpreted as a an element of the quadratic extension field.
// > Output of this call is `256` bytes and is G2 point following respective encoding rules.
Expand Down
4 changes: 2 additions & 2 deletions core/vm/contracts_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,8 @@ var allPrecompiles = map[libcommon.Address]PrecompiledContract{
libcommon.BytesToAddress([]byte{14}): &bls12381G2Mul{},
libcommon.BytesToAddress([]byte{15}): &bls12381G2MultiExp{},
libcommon.BytesToAddress([]byte{16}): &bls12381Pairing{},
libcommon.BytesToAddress([]byte{17}): &bls12381MapG1{},
libcommon.BytesToAddress([]byte{18}): &bls12381MapG2{},
libcommon.BytesToAddress([]byte{17}): &bls12381MapFpToG1{},
libcommon.BytesToAddress([]byte{18}): &bls12381MapFp2ToG2{},
libcommon.BytesToAddress([]byte{20}): &pointEvaluation{},
libcommon.BytesToAddress([]byte{0x01, 0x00}): &p256Verify{},
}
Expand Down
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.IsPrague:
precompiles = PrecompiledContractsPrague
case evm.chainRules.IsNapoli:
precompiles = PrecompiledContractsNapoli
case evm.chainRules.IsCancun:
Expand Down
Loading

0 comments on commit b59247f

Please sign in to comment.