Skip to content

Commit b3cc636

Browse files
authored
test(eip7883): add implementation coverage test cases for ModExp gas calculation (#2119)
Add targeted test cases to improve coverage of implementation-specific variations in EIP-7883 ModExp gas calculation across different Ethereum clients: - IC1: Tests bit shift vs multiplication at 33-byte boundary (go-ethereum vs nethermind) - IC3/IC4: Tests ceiling division at 7 and 9 bytes for edge cases - IC5: Tests bit counting variations in middle of exponent - IC6: Tests native library optimization boundaries (Besu) - IC7: Tests vector optimization 128-bit boundary (Nethermind) - IC9: Tests zero modulus handling variations - IC10: Tests power-of-2 boundary with high bit set These cases target critical divergence points identified through analysis of gas calculation implementations in go-ethereum, nethermind, besu, revm, and erigon.
1 parent b3cade1 commit b3cc636

File tree

1 file changed

+31
-6
lines changed

1 file changed

+31
-6
lines changed

tests/osaka/eip7883_modexp_gas_increase/test_modexp_thresholds.py

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,23 @@ def create_modexp_variable_gas_test_cases():
342342
("01" * 16, "80" + "00" * 31, "02" * 16, "01" * 16, "E2"),
343343
("01" * 16, "00" * 31 + "80", "02" * 16, "01" * 16, "E3"),
344344
("01" * 16, "7F" + "FF" * 31, "02" * 16, "01" * 16, "E4"),
345+
# Implementation coverage cases
346+
# IC1: Bit shift vs multiplication at 33-byte boundary
347+
("FF" * 33, "01", "FF" * 33, "00" * 33, "IC1"),
348+
# IC3: Ceiling division at 7 bytes
349+
("01" * 7, "01", "02" * 7, "01" * 7, "IC3"),
350+
# IC4: Ceiling division at 9 bytes
351+
("01" * 9, "01", "02" * 9, "01" * 9, "IC4"),
352+
# IC5: Bit counting in middle of exponent
353+
("01", "00" * 15 + "80" + "00" * 16, "02", "01", "IC5"),
354+
# IC6: Native library even byte optimization
355+
("01" * 31 + "00", "01", "01" * 31 + "00", "00" * 32, "IC6"),
356+
# IC7: Vector optimization 128-bit boundary
357+
("00" * 15 + "01" * 17, "01", "00" * 15 + "01" * 17, "00" * 32, "IC7"),
358+
# IC9: Zero modulus with large inputs
359+
("FF" * 32, "FF" * 32, "", "", "IC9"),
360+
# IC10: Power-of-2 boundary with high bit
361+
("01" * 32, "80" + "00" * 31, "02" * 32, "01" * 32, "IC10"),
345362
]
346363

347364
# Gas calculation parameters:
@@ -378,16 +395,16 @@ def create_modexp_variable_gas_test_cases():
378395
# │ S0 │ S │ = │ A │ True │ 500 │ Small, equal, zero exp, clamped │
379396
# │ S1 │ S │ = │ B │ True │ 500 │ Small, equal, small exp, clamped │
380397
# │ S2 │ S │ = │ B │ False │ 4080 │ Small, equal, large exp, unclamped │
381-
# │ S3 │ S │ = │ C │ False │ 2032 │ Small, equal, large exp + zero low256 │
398+
# │ S3 │ S │ = │ C │ False │ 2048 │ Small, equal, large exp + zero low256 │
382399
# │ S4 │ S │ = │ D │ False │ 2048 │ Small, equal, large exp + non-zero low256 │
383400
# │ S5 │ S │ > │ A │ True │ 500 │ Small, base > mod, zero exp, clamped │
384401
# │ S6 │ S │ < │ B │ True │ 500 │ Small, base < mod, small exp, clamped │
385402
# │ L0 │ L │ = │ A │ True │ 500 │ Large, equal, zero exp, clamped │
386403
# │ L1 │ L │ = │ B │ False │ 12750 │ Large, equal, large exp, unclamped │
387-
# │ L2 │ L │ = │ C │ False │ 6350 │ Large, equal, large exp + zero low256 │
404+
# │ L2 │ L │ = │ C │ False │ 6400 │ Large, equal, large exp + zero low256 │
388405
# │ L3 │ L │ = │ D │ False │ 6400 │ Large, equal, large exp + non-zero low256 │
389406
# │ L4 │ L │ > │ B │ True │ 500 │ Large, base > mod, small exp, clamped │
390-
# │ L5 │ L │ < │ C │ False │ 9144 │ Large, base < mod, large exp + zero low256 │
407+
# │ L5 │ L │ < │ C │ False │ 9216 │ Large, base < mod, large exp + zero low256 │
391408
# │ B1 │ L │ < │ B │ True │ 500 │ Cross 32-byte boundary (31/33) │
392409
# │ B2 │ L │ > │ B │ True │ 500 │ Cross 32-byte boundary (33/31) │
393410
# │ B4 │ L │ = │ B │ True │ 500 │ Just over 32-byte boundary │
@@ -404,15 +421,23 @@ def create_modexp_variable_gas_test_cases():
404421
# │ M3 │ L │ < │ D │ False │ 98176 │ Small base, max exponent/mod │
405422
# │ T2 │ S │ = │ B │ True │ 500 │ Tiny maximum values │
406423
# │ P2 │ S │ = │ B │ False │ 4080 │ High bit in exponent │
407-
# │ P3 │ L │ = │ D │ False │ 1550 │ Specific bit pattern in large exponent │
408-
# │ A1 │ L │ < │ C │ False │ 65408 │ Asymmetric: tiny base, large exp/mod │
424+
# │ P3 │ L │ = │ D │ False │ 1150 │ Specific bit pattern in large exponent │
425+
# │ A1 │ L │ < │ C │ False │ 65536 │ Asymmetric: tiny base, large exp/mod │
409426
# │ A2 │ L │ > │ B │ True │ 500 │ Asymmetric: large base, tiny exp/mod │
410-
# │ A3 │ L │ > │ C │ False │ 65408 │ Asymmetric: large base/exp, tiny modulus │
427+
# │ A3 │ L │ > │ C │ False │ 65536 │ Asymmetric: large base/exp, tiny modulus │
411428
# │ W2 │ S │ = │ B │ True │ 500 │ Exactly 8-byte words │
412429
# │ E1 │ S │ = │ D │ True │ 500 │ Exponent exactly 33 bytes │
413430
# │ E2 │ S │ = │ B │ False │ 4080 │ High bit in exponent first byte │
414431
# │ E3 │ S │ = │ B │ True │ 500 │ High bit in exponent last byte │
415432
# │ E4 │ S │ = │ B │ False │ 4064 │ Maximum 32-byte exponent │
433+
# │ IC1 │ L │ = │ B │ True │ 500 │ Bit shift vs multiplication @ 33 bytes │
434+
# │ IC3 │ S │ = │ B │ True │ 500 │ Ceiling division at 7 bytes │
435+
# │ IC4 │ S │ = │ B │ True │ 500 │ Ceiling division at 9 bytes │
436+
# │ IC5 │ S │ = │ B │ False │ 2160 │ Bit counting in middle of exponent │
437+
# │ IC6 │ L │ = │ B │ True │ 500 │ Native library even byte optimization │
438+
# │ IC7 │ L │ = │ B │ True │ 500 │ Vector optimization 128-bit boundary │
439+
# │ IC9 │ S │ = │ B │ N/A │ N/A │ Zero modulus handling │
440+
# │ IC10│ S │ = │ B │ False │ 4080 │ Power-of-2 boundary with high bit │
416441
# └─────┴──────┴─────┴──────┴───────┴─────────┴───────────────────────────────────────────────┘
417442
for base, exponent, modulus, expected_result, test_id in test_cases:
418443
yield pytest.param(

0 commit comments

Comments
 (0)