mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-20 02:42:27 +00:00
core: reuse the gas calculation bigints in bigmodexp precompile
This commit is contained in:
parent
81e26d5a48
commit
3c139b8a68
1 changed files with 22 additions and 24 deletions
|
|
@ -147,7 +147,11 @@ func (c *dataCopy) Run(in []byte) ([]byte, error) {
|
|||
}
|
||||
|
||||
// bigModExp implements a native big integer exponential modular operation.
|
||||
type bigModExp struct{}
|
||||
type bigModExp struct {
|
||||
baseLen *big.Int
|
||||
expLen *big.Int
|
||||
modLen *big.Int
|
||||
}
|
||||
|
||||
var (
|
||||
big1 = big.NewInt(1)
|
||||
|
|
@ -165,11 +169,10 @@ var (
|
|||
|
||||
// RequiredGas returns the gas required to execute the pre-compiled contract.
|
||||
func (c *bigModExp) RequiredGas(input []byte) uint64 {
|
||||
var (
|
||||
baseLen = new(big.Int).SetBytes(getData(input, 0, 32))
|
||||
expLen = new(big.Int).SetBytes(getData(input, 32, 32))
|
||||
modLen = new(big.Int).SetBytes(getData(input, 64, 32))
|
||||
)
|
||||
c.baseLen = new(big.Int).SetBytes(getData(input, 0, 32))
|
||||
c.expLen = new(big.Int).SetBytes(getData(input, 32, 32))
|
||||
c.modLen = new(big.Int).SetBytes(getData(input, 64, 32))
|
||||
|
||||
if len(input) > 96 {
|
||||
input = input[96:]
|
||||
} else {
|
||||
|
|
@ -177,13 +180,13 @@ func (c *bigModExp) RequiredGas(input []byte) uint64 {
|
|||
}
|
||||
// Retrieve the head 32 bytes of exp for the adjusted exponent length
|
||||
var expHead *big.Int
|
||||
if big.NewInt(int64(len(input))).Cmp(baseLen) <= 0 {
|
||||
if big.NewInt(int64(len(input))).Cmp(c.baseLen) <= 0 {
|
||||
expHead = new(big.Int)
|
||||
} else {
|
||||
if expLen.Cmp(big32) > 0 {
|
||||
expHead = new(big.Int).SetBytes(getData(input, baseLen.Uint64(), 32))
|
||||
if c.expLen.Cmp(big32) > 0 {
|
||||
expHead = new(big.Int).SetBytes(getData(input, c.baseLen.Uint64(), 32))
|
||||
} else {
|
||||
expHead = new(big.Int).SetBytes(getData(input, baseLen.Uint64(), expLen.Uint64()))
|
||||
expHead = new(big.Int).SetBytes(getData(input, c.baseLen.Uint64(), c.expLen.Uint64()))
|
||||
}
|
||||
}
|
||||
// Calculate the adjusted exponent length
|
||||
|
|
@ -192,14 +195,14 @@ func (c *bigModExp) RequiredGas(input []byte) uint64 {
|
|||
msb = bitlen - 1
|
||||
}
|
||||
adjExpLen := new(big.Int)
|
||||
if expLen.Cmp(big32) > 0 {
|
||||
adjExpLen.Sub(expLen, big32)
|
||||
if c.expLen.Cmp(big32) > 0 {
|
||||
adjExpLen.Sub(c.expLen, big32)
|
||||
adjExpLen.Mul(big8, adjExpLen)
|
||||
}
|
||||
adjExpLen.Add(adjExpLen, big.NewInt(int64(msb)))
|
||||
|
||||
// Calculate the gas cost of the operation
|
||||
gas := new(big.Int).Set(math.BigMax(modLen, baseLen))
|
||||
gas := new(big.Int).Set(math.BigMax(c.modLen, c.baseLen))
|
||||
switch {
|
||||
case gas.Cmp(big64) <= 0:
|
||||
gas.Mul(gas, gas)
|
||||
|
|
@ -224,31 +227,26 @@ func (c *bigModExp) RequiredGas(input []byte) uint64 {
|
|||
}
|
||||
|
||||
func (c *bigModExp) Run(input []byte) ([]byte, error) {
|
||||
var (
|
||||
baseLen = new(big.Int).SetBytes(getData(input, 0, 32)).Uint64()
|
||||
expLen = new(big.Int).SetBytes(getData(input, 32, 32)).Uint64()
|
||||
modLen = new(big.Int).SetBytes(getData(input, 64, 32)).Uint64()
|
||||
)
|
||||
if len(input) > 96 {
|
||||
input = input[96:]
|
||||
} else {
|
||||
input = input[:0]
|
||||
}
|
||||
// Handle a special case when both the base and mod length is zero
|
||||
if baseLen == 0 && modLen == 0 {
|
||||
if c.baseLen.Uint64() == 0 && c.modLen.Uint64() == 0 {
|
||||
return []byte{}, nil
|
||||
}
|
||||
// Retrieve the operands and execute the exponentiation
|
||||
var (
|
||||
base = new(big.Int).SetBytes(getData(input, 0, baseLen))
|
||||
exp = new(big.Int).SetBytes(getData(input, baseLen, expLen))
|
||||
mod = new(big.Int).SetBytes(getData(input, baseLen+expLen, modLen))
|
||||
base = new(big.Int).SetBytes(getData(input, 0, c.baseLen.Uint64()))
|
||||
exp = new(big.Int).SetBytes(getData(input, c.baseLen.Uint64(), c.expLen.Uint64()))
|
||||
mod = new(big.Int).SetBytes(getData(input, c.baseLen.Uint64()+c.expLen.Uint64(), c.modLen.Uint64()))
|
||||
)
|
||||
if mod.BitLen() == 0 {
|
||||
// Modulo 0 is undefined, return zero
|
||||
return common.LeftPadBytes([]byte{}, int(modLen)), nil
|
||||
return common.LeftPadBytes([]byte{}, int(c.modLen.Int64())), nil
|
||||
}
|
||||
return common.LeftPadBytes(base.Exp(base, exp, mod).Bytes(), int(modLen)), nil
|
||||
return common.LeftPadBytes(base.Exp(base, exp, mod).Bytes(), int(c.modLen.Int64())), nil
|
||||
}
|
||||
|
||||
// newCurvePoint unmarshals a binary blob into a bn256 elliptic curve point,
|
||||
|
|
|
|||
Loading…
Reference in a new issue