Skip to content

core/vm: implement EIP 7823 - Set upper bounds for MODEXP #31818

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jun 4, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 34 additions & 5 deletions core/vm/contracts.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ var PrecompiledContractsByzantium = PrecompiledContracts{
common.BytesToAddress([]byte{0x2}): &sha256hash{},
common.BytesToAddress([]byte{0x3}): &ripemd160hash{},
common.BytesToAddress([]byte{0x4}): &dataCopy{},
common.BytesToAddress([]byte{0x5}): &bigModExp{eip2565: false},
common.BytesToAddress([]byte{0x5}): &bigModExp{eip2565: false, eip7823: false},
common.BytesToAddress([]byte{0x6}): &bn256AddByzantium{},
common.BytesToAddress([]byte{0x7}): &bn256ScalarMulByzantium{},
common.BytesToAddress([]byte{0x8}): &bn256PairingByzantium{},
Expand All @@ -79,7 +79,7 @@ var PrecompiledContractsIstanbul = PrecompiledContracts{
common.BytesToAddress([]byte{0x2}): &sha256hash{},
common.BytesToAddress([]byte{0x3}): &ripemd160hash{},
common.BytesToAddress([]byte{0x4}): &dataCopy{},
common.BytesToAddress([]byte{0x5}): &bigModExp{eip2565: false},
common.BytesToAddress([]byte{0x5}): &bigModExp{eip2565: false, eip7823: false},
common.BytesToAddress([]byte{0x6}): &bn256AddIstanbul{},
common.BytesToAddress([]byte{0x7}): &bn256ScalarMulIstanbul{},
common.BytesToAddress([]byte{0x8}): &bn256PairingIstanbul{},
Expand All @@ -93,7 +93,7 @@ var PrecompiledContractsBerlin = PrecompiledContracts{
common.BytesToAddress([]byte{0x2}): &sha256hash{},
common.BytesToAddress([]byte{0x3}): &ripemd160hash{},
common.BytesToAddress([]byte{0x4}): &dataCopy{},
common.BytesToAddress([]byte{0x5}): &bigModExp{eip2565: true},
common.BytesToAddress([]byte{0x5}): &bigModExp{eip2565: true, eip7823: false},
common.BytesToAddress([]byte{0x6}): &bn256AddIstanbul{},
common.BytesToAddress([]byte{0x7}): &bn256ScalarMulIstanbul{},
common.BytesToAddress([]byte{0x8}): &bn256PairingIstanbul{},
Expand All @@ -107,7 +107,7 @@ var PrecompiledContractsCancun = PrecompiledContracts{
common.BytesToAddress([]byte{0x2}): &sha256hash{},
common.BytesToAddress([]byte{0x3}): &ripemd160hash{},
common.BytesToAddress([]byte{0x4}): &dataCopy{},
common.BytesToAddress([]byte{0x5}): &bigModExp{eip2565: true},
common.BytesToAddress([]byte{0x5}): &bigModExp{eip2565: true, eip7823: false},
common.BytesToAddress([]byte{0x6}): &bn256AddIstanbul{},
common.BytesToAddress([]byte{0x7}): &bn256ScalarMulIstanbul{},
common.BytesToAddress([]byte{0x8}): &bn256PairingIstanbul{},
Expand All @@ -122,7 +122,7 @@ var PrecompiledContractsPrague = PrecompiledContracts{
common.BytesToAddress([]byte{0x02}): &sha256hash{},
common.BytesToAddress([]byte{0x03}): &ripemd160hash{},
common.BytesToAddress([]byte{0x04}): &dataCopy{},
common.BytesToAddress([]byte{0x05}): &bigModExp{eip2565: true},
common.BytesToAddress([]byte{0x05}): &bigModExp{eip2565: true, eip7823: false},
common.BytesToAddress([]byte{0x06}): &bn256AddIstanbul{},
common.BytesToAddress([]byte{0x07}): &bn256ScalarMulIstanbul{},
common.BytesToAddress([]byte{0x08}): &bn256PairingIstanbul{},
Expand All @@ -141,6 +141,28 @@ var PrecompiledContractsBLS = PrecompiledContractsPrague

var PrecompiledContractsVerkle = PrecompiledContractsPrague

// PrecompiledContractsOsaka contains the set of pre-compiled Ethereum
// contracts used in the Osaka release.
var PrecompiledContractsOsaka = PrecompiledContracts{
common.BytesToAddress([]byte{0x01}): &ecrecover{},
common.BytesToAddress([]byte{0x02}): &sha256hash{},
common.BytesToAddress([]byte{0x03}): &ripemd160hash{},
common.BytesToAddress([]byte{0x04}): &dataCopy{},
common.BytesToAddress([]byte{0x05}): &bigModExp{eip2565: true, eip7823: true},
common.BytesToAddress([]byte{0x06}): &bn256AddIstanbul{},
common.BytesToAddress([]byte{0x07}): &bn256ScalarMulIstanbul{},
common.BytesToAddress([]byte{0x08}): &bn256PairingIstanbul{},
common.BytesToAddress([]byte{0x09}): &blake2F{},
common.BytesToAddress([]byte{0x0a}): &kzgPointEvaluation{},
common.BytesToAddress([]byte{0x0b}): &bls12381G1Add{},
common.BytesToAddress([]byte{0x0c}): &bls12381G1MultiExp{},
common.BytesToAddress([]byte{0x0d}): &bls12381G2Add{},
common.BytesToAddress([]byte{0x0e}): &bls12381G2MultiExp{},
common.BytesToAddress([]byte{0x0f}): &bls12381Pairing{},
common.BytesToAddress([]byte{0x10}): &bls12381MapG1{},
common.BytesToAddress([]byte{0x11}): &bls12381MapG2{},
}

var (
PrecompiledAddressesPrague []common.Address
PrecompiledAddressesCancun []common.Address
Expand Down Expand Up @@ -175,6 +197,8 @@ func activePrecompiledContracts(rules params.Rules) PrecompiledContracts {
switch {
case rules.IsVerkle:
return PrecompiledContractsVerkle
case rules.IsOsaka:
return PrecompiledContractsOsaka
case rules.IsPrague:
return PrecompiledContractsPrague
case rules.IsCancun:
Expand Down Expand Up @@ -317,6 +341,7 @@ func (c *dataCopy) Run(in []byte) ([]byte, error) {
// bigModExp implements a native big integer exponential modular operation.
type bigModExp struct {
eip2565 bool
eip7823 bool
}

var (
Expand Down Expand Up @@ -456,6 +481,10 @@ func (c *bigModExp) Run(input []byte) ([]byte, error) {
if baseLen == 0 && modLen == 0 {
return []byte{}, nil
}
// enforce size cap for inputs
if c.eip7823 && max(baseLen, expLen, modLen) > 1024 {
return nil, fmt.Errorf("one or more of base/exponent/modulus length exceeded 1024 bytes")
}
// Retrieve the operands and execute the exponentiation
var (
base = new(big.Int).SetBytes(getData(input, 0, baseLen))
Expand Down