core/vm: fix 7823 in case of base length == 0 and mod length == 0. Augment size cap check to catch case where base/exp/mod len > 2**64 (although this is unlikely to happen in practice)

This commit is contained in:
Jared Wasinger 2025-08-07 20:10:03 +09:00
parent e7189b5987
commit ae8d4d4629

View file

@ -500,23 +500,31 @@ func (c *bigModExp) RequiredGas(input []byte) uint64 {
func (c *bigModExp) Run(input []byte) ([]byte, error) { func (c *bigModExp) Run(input []byte) ([]byte, error) {
var ( var (
baseLen = new(big.Int).SetBytes(getData(input, 0, 32)).Uint64() baseLenBig = new(big.Int).SetBytes(getData(input, 0, 32))
expLen = new(big.Int).SetBytes(getData(input, 32, 32)).Uint64() expLenBig = new(big.Int).SetBytes(getData(input, 32, 32))
modLen = new(big.Int).SetBytes(getData(input, 64, 32)).Uint64() modLenBig = new(big.Int).SetBytes(getData(input, 64, 32))
baseLen = baseLenBig.Uint64()
expLen = expLenBig.Uint64()
modLen = modLenBig.Uint64()
) )
if len(input) > 96 { if len(input) > 96 {
input = input[96:] input = input[96:]
} else { } else {
input = input[:0] input = input[:0]
} }
inputLensHighBitsSet := baseLenBig.Rsh(baseLenBig, 64).Cmp(common.Big0) != 0 ||
expLenBig.Rsh(expLenBig, 64).Cmp(common.Big0) != 0 ||
modLenBig.Rsh(modLenBig, 64).Cmp(common.Big0) != 0
// enforce size cap for inputs
if c.eip7823 && (max(baseLen, expLen, modLen) > 1024 || inputLensHighBitsSet) {
return nil, errors.New("one or more of base/exponent/modulus length exceeded 1024 bytes")
}
// Handle a special case when both the base and mod length is zero // Handle a special case when both the base and mod length is zero
if baseLen == 0 && modLen == 0 { if baseLen == 0 && modLen == 0 {
return []byte{}, nil return []byte{}, nil
} }
// enforce size cap for inputs
if c.eip7823 && max(baseLen, expLen, modLen) > 1024 {
return nil, errors.New("one or more of base/exponent/modulus length exceeded 1024 bytes")
}
// Retrieve the operands and execute the exponentiation // Retrieve the operands and execute the exponentiation
var ( var (
base = new(big.Int).SetBytes(getData(input, 0, baseLen)) base = new(big.Int).SetBytes(getData(input, 0, baseLen))