Skip to content

Commit 3076891

Browse files
authored
EIP-7883: ModExp gas cost increase (#4071)
* Increase minimal price from 200 to 500 * Increase cost when exponent is larger than 32 bytes * Multiplication complexity is doubled if base or modulus is bigger than 32 bytes * Add 7883 to common * Update implementation to allow 2565 and pre-2565 gas algorithm
1 parent 504212e commit 3076891

File tree

3 files changed

+24
-9
lines changed

3 files changed

+24
-9
lines changed

packages/common/src/eips.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -478,4 +478,12 @@ export const eipsDict: EIPsDict = {
478478
7864: {
479479
minimumHardfork: Hardfork.London,
480480
},
481+
/**
482+
* Description : EIP-7883: ModExp Gas Cost Increase
483+
* URL : hhttps://eips.ethereum.org/EIPS/eip-7883
484+
* Status : Draft
485+
*/
486+
7883: {
487+
minimumHardfork: Hardfork.Chainstart,
488+
},
481489
}

packages/common/src/hardforks.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ export const hardforksDict: HardforksDict = {
166166
* Status : Final
167167
*/
168168
osaka: {
169-
eips: [663, 3540, 3670, 4200, 4750, 5450, 6206, 7069, 7480, 7620, 7692, 7698],
169+
eips: [663, 3540, 3670, 4200, 4750, 5450, 6206, 7069, 7480, 7620, 7692, 7698, 7883],
170170
},
171171
/**
172172
* Description: Next feature hardfork after osaka, internally used for verkle testing/implementation (incomplete/experimental)

packages/evm/src/precompiles/05-modexp.ts

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,9 @@ import type { PrecompileInput } from './types.ts'
2424

2525
const BIGINT_4 = BigInt(4)
2626
const BIGINT_16 = BigInt(16)
27-
const BIGINT_200 = BigInt(200)
2827
const BIGINT_480 = BigInt(480)
28+
const BIGINT_200 = BigInt(200)
29+
const BIGINT_500 = BigInt(500)
2930
const BIGINT_1024 = BigInt(1024)
3031
const BIGINT_3072 = BigInt(3072)
3132
const BIGINT_199680 = BigInt(199680)
@@ -56,7 +57,7 @@ function multiplicationComplexityEIP2565(x: bigint): bigint {
5657
return words * words
5758
}
5859

59-
function getAdjustedExponentLength(data: Uint8Array): bigint {
60+
function getAdjustedExponentLength(data: Uint8Array, opts: PrecompileInput): bigint {
6061
let expBytesStart
6162
try {
6263
const baseLen = bytesToBigInt(data.subarray(0, 32))
@@ -83,8 +84,8 @@ function getAdjustedExponentLength(data: Uint8Array): bigint {
8384
if (expLenMinus32OrZero < BIGINT_0) {
8485
expLenMinus32OrZero = BIGINT_0
8586
}
86-
const eightTimesExpLenMinus32OrZero = expLenMinus32OrZero * BIGINT_8
87-
let adjustedExpLen = eightTimesExpLenMinus32OrZero
87+
let adjustedExpLen =
88+
expLenMinus32OrZero * (opts.common.isActivatedEIP(7883) === true ? BIGINT_16 : BIGINT_8)
8889
if (bitLen > 0) {
8990
adjustedExpLen += BigInt(bitLen)
9091
}
@@ -108,7 +109,7 @@ export function precompile05(opts: PrecompileInput): ExecResult {
108109
const pName = getPrecompileName('05')
109110
const data = opts.data.length < 96 ? setLengthRight(opts.data, 96) : opts.data
110111

111-
let adjustedELen = getAdjustedExponentLength(data)
112+
let adjustedELen = getAdjustedExponentLength(data, opts)
112113
if (adjustedELen < BIGINT_1) {
113114
adjustedELen = BIGINT_1
114115
}
@@ -131,13 +132,19 @@ export function precompile05(opts: PrecompileInput): ExecResult {
131132
const mStart = eEnd
132133
const mEnd = mStart + mLen
133134

134-
if (!opts.common.isActivatedEIP(2565)) {
135-
gasUsed = (adjustedELen * multiplicationComplexity(maxLen)) / Gquaddivisor
136-
} else {
135+
if (opts.common.isActivatedEIP(7883)) {
136+
const wordsSquared = multiplicationComplexityEIP2565(maxLen)
137+
gasUsed = (adjustedELen * (maxLen > 32 ? 2n * wordsSquared : wordsSquared)) / Gquaddivisor
138+
if (gasUsed < BIGINT_500) {
139+
gasUsed = BIGINT_500
140+
}
141+
} else if (opts.common.isActivatedEIP(2565)) {
137142
gasUsed = (adjustedELen * multiplicationComplexityEIP2565(maxLen)) / Gquaddivisor
138143
if (gasUsed < BIGINT_200) {
139144
gasUsed = BIGINT_200
140145
}
146+
} else {
147+
gasUsed = (adjustedELen * multiplicationComplexity(maxLen)) / Gquaddivisor
141148
}
142149
if (!gasLimitCheck(opts, gasUsed, pName)) {
143150
return OOGResult(opts.gasLimit)

0 commit comments

Comments
 (0)