diff --git a/src/ethereum_test_benchmark/benchmark_code_generator.py b/src/ethereum_test_benchmark/benchmark_code_generator.py index 311b4132c3b..203338edccd 100644 --- a/src/ethereum_test_benchmark/benchmark_code_generator.py +++ b/src/ethereum_test_benchmark/benchmark_code_generator.py @@ -3,6 +3,7 @@ optimized bytecode patterns. """ +from ethereum_test_base_types import Address from ethereum_test_forks import Fork from ethereum_test_specs.benchmark import BenchmarkCodeGenerator from ethereum_test_types import Alloc, Transaction @@ -13,18 +14,20 @@ class JumpLoopGenerator(BenchmarkCodeGenerator): """Generates bytecode that loops execution using JUMP operations.""" - def deploy_contracts(self, pre: Alloc, fork: Fork) -> None: + def deploy_contracts(self, pre: Alloc, fork: Fork) -> Address: """Deploy the looping contract.""" # Benchmark Test Structure: - # setup + JUMPDEST + attack + attack + ... + - # attack + JUMP(setup_length) - code = self.generate_repeated_code(self.attack_block, self.setup, fork) + # setup + JUMPDEST + + # attack + attack + ... + attack + + # cleanup + JUMP(setup_length) + code = self.generate_repeated_code(self.attack_block, self.setup, self.cleanup, fork) self._contract_address = pre.deploy_contract(code=code) + return self._contract_address def generate_transaction(self, pre: Alloc, gas_limit: int, fork: Fork) -> Transaction: """Generate transaction that executes the looping contract.""" if not hasattr(self, "_contract_address"): - raise ValueError("deploy_contracts must be called before generate_transaction") + self.deploy_contracts(pre, fork) return Transaction( to=self._contract_address, @@ -39,7 +42,7 @@ class ExtCallGenerator(BenchmarkCodeGenerator): maximum allowed code size. """ - def deploy_contracts(self, pre: Alloc, fork: Fork) -> None: + def deploy_contracts(self, pre: Alloc, fork: Fork) -> Address: """Deploy both target and caller contracts.""" # Benchmark Test Structure: # There are two contracts: @@ -53,7 +56,7 @@ def deploy_contracts(self, pre: Alloc, fork: Fork) -> None: # Deploy target contract that contains the actual attack block self._target_contract_address = pre.deploy_contract( - code=self.attack_block * max_iterations + code=self.setup + self.attack_block * max_iterations ) # Create caller contract that repeatedly calls the target contract @@ -65,13 +68,14 @@ def deploy_contracts(self, pre: Alloc, fork: Fork) -> None: # JUMP(setup_length) code_sequence = Op.POP(Op.STATICCALL(Op.GAS, self._target_contract_address, 0, 0, 0, 0)) - caller_code = self.generate_repeated_code(code_sequence, Bytecode(), fork) + caller_code = self.generate_repeated_code(code_sequence, Bytecode(), self.cleanup, fork) self._contract_address = pre.deploy_contract(code=caller_code) + return self._contract_address def generate_transaction(self, pre: Alloc, gas_limit: int, fork: Fork) -> Transaction: """Generate transaction that executes the caller contract.""" if not hasattr(self, "_contract_address"): - raise ValueError("deploy_contracts must be called before generate_transaction") + self.deploy_contracts(pre, fork) return Transaction( to=self._contract_address, diff --git a/src/ethereum_test_specs/benchmark.py b/src/ethereum_test_specs/benchmark.py index c6fdd1b644b..f6a439899e5 100644 --- a/src/ethereum_test_specs/benchmark.py +++ b/src/ethereum_test_specs/benchmark.py @@ -9,7 +9,7 @@ from pydantic import ConfigDict, Field from ethereum_clis import TransitionTool -from ethereum_test_base_types import HexNumber +from ethereum_test_base_types import Address, HexNumber from ethereum_test_exceptions import BlockException, TransactionException from ethereum_test_execution import ( BaseExecute, @@ -40,9 +40,10 @@ class BenchmarkCodeGenerator(ABC): attack_block: Bytecode setup: Bytecode = field(default_factory=Bytecode) + cleanup: Bytecode = field(default_factory=Bytecode) @abstractmethod - def deploy_contracts(self, pre: Alloc, fork: Fork) -> None: + def deploy_contracts(self, pre: Alloc, fork: Fork) -> Address: """Deploy any contracts needed for the benchmark.""" ... @@ -52,7 +53,7 @@ def generate_transaction(self, pre: Alloc, gas_limit: int, fork: Fork) -> Transa ... def generate_repeated_code( - self, repeated_code: Bytecode, setup: Bytecode, fork: Fork + self, repeated_code: Bytecode, setup: Bytecode, cleanup: Bytecode, fork: Fork ) -> Bytecode: """ Calculate the maximum number of iterations that @@ -61,11 +62,11 @@ def generate_repeated_code( assert len(repeated_code) > 0, "repeated_code cannot be empty" max_code_size = fork.max_code_size() - overhead = len(setup) + len(Op.JUMPDEST) + len(Op.JUMP(len(setup))) + overhead = len(setup) + len(Op.JUMPDEST) + len(cleanup) + len(Op.JUMP(len(setup))) available_space = max_code_size - overhead max_iterations = available_space // len(repeated_code) - code = setup + Op.JUMPDEST + repeated_code * max_iterations + Op.JUMP(len(setup)) + code = setup + Op.JUMPDEST + repeated_code * max_iterations + cleanup + Op.JUMP(len(setup)) self._validate_code_size(code, fork) return code diff --git a/tests/benchmark/test_worst_blocks.py b/tests/benchmark/test_worst_blocks.py index 6d95ef657b0..d90eb9fbf5e 100644 --- a/tests/benchmark/test_worst_blocks.py +++ b/tests/benchmark/test_worst_blocks.py @@ -2,6 +2,7 @@ Tests that benchmark EVMs in worst-case block scenarios. """ +import math import random import pytest @@ -12,11 +13,10 @@ AccessList, Address, Alloc, + BenchmarkTestFiller, Block, - BlockchainTestFiller, Environment, Hash, - StateTestFiller, Transaction, ) @@ -111,7 +111,7 @@ def ether_transfer_case( ["a_to_a", "a_to_b", "diff_acc_to_b", "a_to_diff_acc", "diff_acc_to_diff_acc"], ) def test_block_full_of_ether_transfers( - blockchain_test: BlockchainTestFiller, + benchmark_test: BenchmarkTestFiller, pre: Alloc, env: Environment, case_id: str, @@ -155,8 +155,7 @@ def test_block_full_of_ether_transfers( else {receiver: Account(balance=balance) for receiver, balance in balances.items()} ) - blockchain_test( - genesis_environment=env, + benchmark_test( pre=pre, post=post_state, blocks=[Block(txs=txs)], @@ -176,18 +175,14 @@ def total_cost_standard_per_token(): return 4 -@pytest.mark.parametrize("zero_byte", [True, False]) -def test_block_full_data( - state_test: StateTestFiller, - pre: Alloc, - zero_byte: bool, - intrinsic_cost: int, +def calldata_generator( + gas_amount: int, + zero_byte: int, total_cost_floor_per_token: int, - gas_benchmark_value: int, + total_cost_standard_per_token: int, ): - """Test a block with empty payload.""" - # Gas cost calculation based on EIP-7683: - # (https://eips.ethereum.org/EIPS/eip-7683) + """Calculate the calldata based on the gas amount and zero byte.""" + # Gas cost calculation based on EIP-7683: (https://eips.ethereum.org/EIPS/eip-7683) # # tx.gasUsed = 21000 + max( # STANDARD_TOKEN_COST * tokens_in_calldata @@ -212,121 +207,163 @@ def test_block_full_data( # # So we calculate how many bytes we can fit into calldata based on # available gas. - - gas_available = gas_benchmark_value - intrinsic_cost - - # Calculate the token_in_calldata - max_tokens_in_calldata = gas_available // total_cost_floor_per_token - # Calculate the number of bytes that can be stored in the calldata + max_tokens_in_calldata = gas_amount // total_cost_floor_per_token num_of_bytes = max_tokens_in_calldata if zero_byte else max_tokens_in_calldata // 4 byte_data = b"\x00" if zero_byte else b"\xff" + return byte_data * num_of_bytes - tx = Transaction( - to=pre.fund_eoa(), - data=byte_data * num_of_bytes, - gas_limit=gas_benchmark_value, - sender=pre.fund_eoa(), - ) - state_test( +@pytest.mark.parametrize("zero_byte", [True, False]) +def test_block_full_data( + benchmark_test: BenchmarkTestFiller, + pre: Alloc, + zero_byte: bool, + intrinsic_cost: int, + total_cost_floor_per_token: int, + gas_benchmark_value: int, + tx_gas_limit_cap: int, + total_cost_standard_per_token: int, + fork: Fork, +): + """Test a block with empty payload.""" + iteration_count = math.ceil(gas_benchmark_value / tx_gas_limit_cap) + + gas_remaining = gas_benchmark_value + total_gas_used = 0 + txs = [] + for _ in range(iteration_count): + gas_available = min(tx_gas_limit_cap, gas_remaining) - intrinsic_cost + data = calldata_generator( + gas_available, + zero_byte, + total_cost_floor_per_token, + total_cost_standard_per_token, + ) + + total_gas_used += fork.transaction_intrinsic_cost_calculator()(calldata=data) + gas_remaining -= gas_available + intrinsic_cost + + txs.append( + Transaction( + to=pre.fund_eoa(), + data=data, + gas_limit=gas_available + intrinsic_cost, + sender=pre.fund_eoa(), + ) + ) + + benchmark_test( pre=pre, post={}, - tx=tx, + blocks=[Block(txs=txs)], + expected_benchmark_gas_used=total_gas_used, ) def test_block_full_access_list_and_data( - state_test: StateTestFiller, + benchmark_test: BenchmarkTestFiller, pre: Alloc, intrinsic_cost: int, total_cost_standard_per_token: int, fork: Fork, gas_benchmark_value: int, + tx_gas_limit_cap: int, ): """ Test a block with access lists (60% gas) and calldata (40% gas) using random mixed bytes. """ - attack_gas_limit = gas_benchmark_value - gas_available = attack_gas_limit - intrinsic_cost - - # Split available gas: 60% for access lists, 40% for calldata - gas_for_access_list = int(gas_available * 0.6) - gas_for_calldata = int(gas_available * 0.4) - - # Access list gas costs from fork's gas_costs - gas_costs = fork.gas_costs() - gas_per_address = gas_costs.G_ACCESS_LIST_ADDRESS - gas_per_storage_key = gas_costs.G_ACCESS_LIST_STORAGE - - # Calculate number of storage keys we can fit - gas_after_address = gas_for_access_list - gas_per_address - num_storage_keys = gas_after_address // gas_per_storage_key - - # Create access list with 1 address and many storage keys - access_address = Address("0x1234567890123456789012345678901234567890") - storage_keys = [] - for i in range(num_storage_keys): - # Generate random-looking storage keys - storage_keys.append(Hash(i)) - - access_list = [ - AccessList( - address=access_address, - storage_keys=storage_keys, + iteration_count = math.ceil(gas_benchmark_value / tx_gas_limit_cap) + + gas_remaining = gas_benchmark_value + total_gas_used = 0 + + txs = [] + for _ in range(iteration_count): + gas_available = min(tx_gas_limit_cap, gas_remaining) - intrinsic_cost + + # Split available gas: 60% for access lists, 40% for calldata + gas_for_access_list = int(gas_available * 0.6) + gas_for_calldata = int(gas_available * 0.4) + + # Access list gas costs from fork's gas_costs + gas_costs = fork.gas_costs() + gas_per_address = gas_costs.G_ACCESS_LIST_ADDRESS + gas_per_storage_key = gas_costs.G_ACCESS_LIST_STORAGE + + # Calculate number of storage keys we can fit + gas_after_address = gas_for_access_list - gas_per_address + num_storage_keys = gas_after_address // gas_per_storage_key + + # Create access list with 1 address and many storage keys + access_address = Address("0x1234567890123456789012345678901234567890") + storage_keys = [] + for i in range(num_storage_keys): + # Generate random-looking storage keys + storage_keys.append(Hash(i)) + + access_list = [ + AccessList( + address=access_address, + storage_keys=storage_keys, + ) + ] + + # Calculate calldata with 29% of gas for zero bytes and 71% for + # non-zero bytes + # Token accounting: tokens_in_calldata = zero_bytes + 4 * + # non_zero_bytes + # We want to split the gas budget: + # - 29% of gas_for_calldata for zero bytes + # - 71% of gas_for_calldata for non-zero bytes + + max_tokens_in_calldata = gas_for_calldata // total_cost_standard_per_token + + # Calculate how many tokens to allocate to each type + tokens_for_zero_bytes = int(max_tokens_in_calldata * 0.29) + tokens_for_non_zero_bytes = max_tokens_in_calldata - tokens_for_zero_bytes + + # Convert tokens to actual byte counts + # Zero bytes: 1 token per byte + # Non-zero bytes: 4 tokens per byte + num_zero_bytes = tokens_for_zero_bytes # 1 token = 1 zero byte + num_non_zero_bytes = tokens_for_non_zero_bytes // 4 # 4 tokens = 1 non-zero byte + + # Create calldata with mixed bytes + calldata = bytearray() + + # Add zero bytes + calldata.extend(b"\x00" * num_zero_bytes) + + # Add non-zero bytes (random values from 0x01 to 0xff) + rng = random.Random(42) # For reproducibility + for _ in range(num_non_zero_bytes): + calldata.append(rng.randint(1, 255)) + + # Shuffle the bytes to mix zero and non-zero bytes + calldata_list = list(calldata) + rng.shuffle(calldata_list) + shuffled_calldata = bytes(calldata_list) + + txs.append( + Transaction( + to=pre.fund_eoa(amount=0), + data=shuffled_calldata, + gas_limit=gas_available + intrinsic_cost, + sender=pre.fund_eoa(), + access_list=access_list, + ) ) - ] - - # Calculate calldata with 29% of gas for zero bytes and 71% for non-zero - # bytes - # Token accounting: tokens_in_calldata = zero_bytes + 4 * non_zero_bytes - # We want to split the gas budget: - # - 29% of gas_for_calldata for zero bytes - # - 71% of gas_for_calldata for non-zero bytes - - max_tokens_in_calldata = gas_for_calldata // total_cost_standard_per_token - - # Calculate how many tokens to allocate to each type - tokens_for_zero_bytes = int(max_tokens_in_calldata * 0.29) - tokens_for_non_zero_bytes = max_tokens_in_calldata - tokens_for_zero_bytes - - # Convert tokens to actual byte counts - # Zero bytes: 1 token per byte - # Non-zero bytes: 4 tokens per byte - num_zero_bytes = tokens_for_zero_bytes # 1 token = 1 zero byte - # 4 tokens = 1 non-zero byte - num_non_zero_bytes = tokens_for_non_zero_bytes // 4 - - # Create calldata with mixed bytes - calldata = bytearray() - - # Add zero bytes - calldata.extend(b"\x00" * num_zero_bytes) - - # Add non-zero bytes (random values from 0x01 to 0xff) - rng = random.Random(42) # For reproducibility - for _ in range(num_non_zero_bytes): - calldata.append(rng.randint(1, 255)) - - # Shuffle the bytes to mix zero and non-zero bytes - calldata_list = list(calldata) - rng.shuffle(calldata_list) - shuffled_calldata = bytes(calldata_list) - - tx = Transaction( - to=pre.fund_eoa(amount=0), - data=shuffled_calldata, - gas_limit=attack_gas_limit, - sender=pre.fund_eoa(), - access_list=access_list, - ) - state_test( - pre=pre, - post={}, - tx=tx, - expected_benchmark_gas_used=fork.transaction_intrinsic_cost_calculator()( + gas_remaining -= gas_for_access_list + intrinsic_cost + total_gas_used += fork.transaction_intrinsic_cost_calculator()( calldata=shuffled_calldata, access_list=access_list, - ), + ) + + benchmark_test( + pre=pre, + post={}, + blocks=[Block(txs=txs)], + expected_benchmark_gas_used=total_gas_used, ) diff --git a/tests/benchmark/test_worst_bytecode.py b/tests/benchmark/test_worst_bytecode.py index 14227394040..2852d925808 100644 --- a/tests/benchmark/test_worst_bytecode.py +++ b/tests/benchmark/test_worst_bytecode.py @@ -6,16 +6,18 @@ import pytest +from ethereum_test_benchmark.benchmark_code_generator import JumpLoopGenerator from ethereum_test_forks import Fork from ethereum_test_tools import ( Account, Alloc, + BenchmarkTestFiller, Block, BlockchainTestFiller, Bytecode, + Bytes, Environment, Hash, - StateTestFiller, Transaction, While, compute_create2_address, @@ -23,8 +25,6 @@ from ethereum_test_types.helpers import compute_create_address from ethereum_test_vm import Opcodes as Op -from .helpers import code_loop_precompile_call - REFERENCE_SPEC_GIT_PATH = "TODO" REFERENCE_SPEC_VERSION = "TODO" @@ -245,7 +245,7 @@ def test_worst_bytecode_single_opcode( ids=lambda x: x.hex(), ) def test_worst_initcode_jumpdest_analysis( - state_test: StateTestFiller, + benchmark_test: BenchmarkTestFiller, pre: Alloc, fork: Fork, pattern: Bytecode, @@ -261,7 +261,6 @@ def test_worst_initcode_jumpdest_analysis( is modified by mixing-in the returned create address between CREATE invocations to prevent caching. """ - max_code_size = fork.max_code_size() initcode_size = fork.max_initcode_size() # Expand the initcode pattern to the transaction data so it can be used in @@ -291,32 +290,20 @@ def test_worst_initcode_jumpdest_analysis( # Make sure the last opcode in the initcode is JUMPDEST. code_prepare_initcode += Op.MSTORE(initcode_size - 32, Op.PUSH32[bytes(Op.JUMPDEST) * 32]) - code_invoke_create = ( + attack_block = ( Op.PUSH1[len(initcode_prefix)] + Op.MSTORE + Op.CREATE(value=Op.PUSH0, offset=Op.PUSH0, size=Op.MSIZE) ) - initial_random = Op.PUSH0 - code_prefix = code_prepare_initcode + initial_random - code_loop_header = Op.JUMPDEST - code_loop_footer = Op.JUMP(len(code_prefix)) - code_loop_body_len = ( - max_code_size - len(code_prefix) - len(code_loop_header) - len(code_loop_footer) - ) - - code_loop_body = (code_loop_body_len // len(code_invoke_create)) * bytes(code_invoke_create) - code = code_prefix + code_loop_header + code_loop_body + code_loop_footer - assert (max_code_size - len(code_invoke_create)) < len(code) <= max_code_size + setup = code_prepare_initcode + Op.PUSH0 - tx = Transaction( - to=pre.deploy_contract(code=code), - data=tx_data, - gas_limit=gas_benchmark_value, - sender=pre.fund_eoa(), - ) + tx = JumpLoopGenerator( + setup=setup, attack_block=attack_block, cleanup=Bytecode() + ).generate_transaction(pre, gas_benchmark_value, fork) + tx.data = Bytes(tx_data) - state_test( + benchmark_test( pre=pre, post={}, tx=tx, @@ -349,14 +336,13 @@ def test_worst_initcode_jumpdest_analysis( ], ) def test_worst_create( - state_test: StateTestFiller, + benchmark_test: BenchmarkTestFiller, pre: Alloc, fork: Fork, opcode: Op, max_code_size_ratio: float, non_zero_data: bool, value: int, - gas_benchmark_value: int, ): """ Test the CREATE and CREATE2 performance with different configurations. @@ -394,7 +380,7 @@ def test_worst_create( # ... # JUMP(#) # ``` - code_prefix = ( + setup = ( Op.PUSH3(code_size) + Op.PUSH1(value) + Op.EXTCODECOPY( @@ -405,7 +391,7 @@ def test_worst_create( if opcode == Op.CREATE2: # For CREATE2, we provide an initial salt. - code_prefix = code_prefix + Op.PUSH1(42) + setup += Op.PUSH1(42) attack_block = ( # For CREATE: @@ -420,16 +406,18 @@ def test_worst_create( # - DUP3 is targeting the EXTCODESIZE value pushed in code_prefix. else Op.DUP3 + Op.PUSH0 + Op.DUP4 + Op.CREATE2 ) - code = code_loop_precompile_call(code_prefix, attack_block, fork) + + code = JumpLoopGenerator(setup=setup, attack_block=attack_block).generate_repeated_code( + attack_block, Bytecode(), Bytecode(), fork + ) tx = Transaction( # Set enough balance in the pre-alloc for `value > 0` configurations. to=pre.deploy_contract(code=code, balance=1_000_000_000 if value > 0 else 0), - gas_limit=gas_benchmark_value, sender=pre.fund_eoa(), ) - state_test( + benchmark_test( pre=pre, post={}, tx=tx, @@ -444,7 +432,7 @@ def test_worst_create( ], ) def test_worst_creates_collisions( - state_test: StateTestFiller, + benchmark_test: BenchmarkTestFiller, pre: Alloc, fork: Fork, opcode: Op, @@ -475,14 +463,12 @@ def test_worst_creates_collisions( # The CALL to the proxy contract needs at a minimum gas corresponding to # the CREATE(2) plus extra required PUSH0s for arguments. min_gas_required = gas_costs.G_CREATE + gas_costs.G_BASE * (3 if opcode == Op.CREATE else 4) - code_prefix = Op.PUSH20(proxy_contract) + Op.PUSH3(min_gas_required) + setup = Op.PUSH20(proxy_contract) + Op.PUSH3(min_gas_required) attack_block = Op.POP( # DUP7 refers to the PUSH3 above. # DUP7 refers to the proxy contract address. Op.CALL(gas=Op.DUP7, address=Op.DUP7) ) - code = code_loop_precompile_call(code_prefix, attack_block, fork) - tx_target = pre.deploy_contract(code=code) # (**) We deploy the contract that CREATE(2) will attempt to create so any # attempt will fail. @@ -496,14 +482,8 @@ def test_worst_creates_collisions( addr = compute_create_address(address=proxy_contract, nonce=nonce) pre.deploy_contract(address=addr, code=Op.INVALID) - tx = Transaction( - to=tx_target, - gas_limit=gas_benchmark_value, - sender=pre.fund_eoa(), - ) - - state_test( + benchmark_test( pre=pre, post={}, - tx=tx, + code_generator=JumpLoopGenerator(setup=setup, attack_block=attack_block), ) diff --git a/tests/benchmark/test_worst_compute.py b/tests/benchmark/test_worst_compute.py index 504b2310510..d46ac444e56 100644 --- a/tests/benchmark/test_worst_compute.py +++ b/tests/benchmark/test_worst_compute.py @@ -11,18 +11,16 @@ import pytest from py_ecc.bn128 import G1, G2, multiply -from ethereum_test_base_types.base_types import Bytes -from ethereum_test_benchmark.benchmark_code_generator import JumpLoopGenerator +from ethereum_test_base_types.base_types import Bytes, HexNumber +from ethereum_test_benchmark import ExtCallGenerator, JumpLoopGenerator from ethereum_test_forks import Fork from ethereum_test_tools import ( Address, Alloc, BenchmarkTestFiller, Block, - BlockchainTestFiller, Bytecode, Environment, - StateTestFiller, Transaction, add_kzg_version, ) @@ -38,7 +36,6 @@ from ..osaka.eip7951_p256verify_precompiles.spec import FieldElement from ..prague.eip2537_bls_12_381_precompiles import spec as bls12381_spec from ..prague.eip2537_bls_12_381_precompiles.spec import BytesConcatenation -from .helpers import code_loop_precompile_call REFERENCE_SPEC_GIT_PATH = "TODO" REFERENCE_SPEC_VERSION = "TODO" @@ -82,60 +79,33 @@ def make_dup(index: int) -> Opcode: ], ) def test_worst_zero_param( - state_test: StateTestFiller, + benchmark_test: BenchmarkTestFiller, pre: Alloc, opcode: Op, - fork: Fork, - gas_benchmark_value: int, ): """Test running a block with as many zero-parameter opcodes as possible.""" - opcode_sequence = opcode * fork.max_stack_height() - target_contract_address = pre.deploy_contract(code=opcode_sequence) - - calldata = Bytecode() - attack_block = Op.POP(Op.STATICCALL(Op.GAS, target_contract_address, 0, 0, 0, 0)) - code = code_loop_precompile_call(calldata, attack_block, fork) - code_address = pre.deploy_contract(code=code) - - tx = Transaction( - to=code_address, - gas_limit=gas_benchmark_value, - sender=pre.fund_eoa(), - ) - - state_test( + benchmark_test( pre=pre, post={}, - tx=tx, + code_generator=ExtCallGenerator(setup=Bytecode(), attack_block=opcode), ) @pytest.mark.parametrize("calldata_length", [0, 1_000, 10_000]) def test_worst_calldatasize( - state_test: StateTestFiller, + benchmark_test: BenchmarkTestFiller, pre: Alloc, fork: Fork, calldata_length: int, gas_benchmark_value: int, ): """Test running a block with as many CALLDATASIZE as possible.""" - max_code_size = fork.max_code_size() + tx = JumpLoopGenerator( + setup=Bytecode(), attack_block=Op.POP(Op.CALLDATASIZE) + ).generate_transaction(pre, gas_benchmark_value, fork) + tx.data = Bytes(b"\x00" * calldata_length) - code_prefix = Op.JUMPDEST - iter_loop = Op.POP(Op.CALLDATASIZE) - code_suffix = Op.PUSH0 + Op.JUMP - code_iter_len = (max_code_size - len(code_prefix) - len(code_suffix)) // len(iter_loop) - code = code_prefix + iter_loop * code_iter_len + code_suffix - assert len(code) <= max_code_size - - tx = Transaction( - to=pre.deploy_contract(code=bytes(code)), - gas_limit=gas_benchmark_value, - sender=pre.fund_eoa(), - data=b"\x00" * calldata_length, - ) - - state_test( + benchmark_test( pre=pre, post={}, tx=tx, @@ -145,12 +115,11 @@ def test_worst_calldatasize( @pytest.mark.parametrize("non_zero_value", [True, False]) @pytest.mark.parametrize("from_origin", [True, False]) def test_worst_callvalue( - state_test: StateTestFiller, + benchmark_test: BenchmarkTestFiller, pre: Alloc, fork: Fork, non_zero_value: bool, from_origin: bool, - gas_benchmark_value: int, ): """ Test running a block with as many CALLVALUE opcodes as possible. @@ -159,15 +128,9 @@ def test_worst_callvalue( value. The `from_origin` parameter controls whether the call frame is the immediate from the transaction or a previous CALL. """ - max_code_size = fork.max_code_size() - - code_prefix = Op.JUMPDEST - iter_loop = Op.POP(Op.CALLVALUE) - code_suffix = Op.PUSH0 + Op.JUMP - code_iter_len = (max_code_size - len(code_prefix) - len(code_suffix)) // len(iter_loop) - code = code_prefix + iter_loop * code_iter_len + code_suffix - assert len(code) <= max_code_size - code_address = pre.deploy_contract(code=bytes(code)) + code_address = JumpLoopGenerator( + setup=Bytecode(), attack_block=Op.POP(Op.CALLVALUE), cleanup=Bytecode() + ).deploy_contracts(pre, fork) if from_origin: tx_to = code_address @@ -181,12 +144,11 @@ def test_worst_callvalue( tx = Transaction( to=tx_to, - gas_limit=gas_benchmark_value, value=1 if non_zero_value and from_origin else 0, sender=pre.fund_eoa(), ) - state_test( + benchmark_test( pre=pre, post={}, tx=tx, @@ -211,12 +173,10 @@ class ReturnDataStyle(Enum): ) @pytest.mark.parametrize("returned_size", [1, 0]) def test_worst_returndatasize_nonzero( - state_test: StateTestFiller, + benchmark_test: BenchmarkTestFiller, pre: Alloc, - fork: Fork, returned_size: int, return_data_style: ReturnDataStyle, - gas_benchmark_value: int, ): """ Test running a block which execute as many RETURNDATASIZE opcodes which @@ -226,11 +186,9 @@ def test_worst_returndatasize_nonzero( buffer. The `return_data_style` indicates how returned data is produced for the opcode caller. """ - max_code_size = fork.max_code_size() - - dummy_contract_call = Bytecode() + setup = Bytecode() if return_data_style != ReturnDataStyle.IDENTITY: - dummy_contract_call = Op.STATICCALL( + setup += Op.STATICCALL( address=pre.deploy_contract( code=Op.REVERT(0, returned_size) if return_data_style == ReturnDataStyle.REVERT @@ -238,68 +196,36 @@ def test_worst_returndatasize_nonzero( ) ) else: - dummy_contract_call = Op.MSTORE8(0, 1) + Op.STATICCALL( + setup += Op.MSTORE8(0, 1) + Op.STATICCALL( address=0x04, # Identity precompile args_size=returned_size, ) - code_prefix = dummy_contract_call + Op.JUMPDEST - iter_loop = Op.POP(Op.RETURNDATASIZE) - code_suffix = Op.JUMP(len(code_prefix) - 1) - code_iter_len = (max_code_size - len(code_prefix) - len(code_suffix)) // len(iter_loop) - code = code_prefix + iter_loop * code_iter_len + code_suffix - assert len(code) <= max_code_size - - tx = Transaction( - to=pre.deploy_contract(code=bytes(code)), - gas_limit=gas_benchmark_value, - sender=pre.fund_eoa(), - ) - - state_test( + benchmark_test( pre=pre, post={}, - tx=tx, + code_generator=JumpLoopGenerator(setup=setup, attack_block=Op.POP(Op.RETURNDATASIZE)), ) def test_worst_returndatasize_zero( - state_test: StateTestFiller, + benchmark_test: BenchmarkTestFiller, pre: Alloc, - fork: Fork, - gas_benchmark_value: int, ): """ - Test running a block with as many RETURNDATASIZE opcodes as possible with a - zero buffer. + Test running a block with as many RETURNDATASIZE opcodes as possible with + a zero buffer. """ - max_code_size = fork.max_code_size() - - dummy_contract_call = Bytecode() - - code_prefix = dummy_contract_call + Op.JUMPDEST - iter_loop = Op.POP(Op.RETURNDATASIZE) - code_suffix = Op.JUMP(len(code_prefix) - 1) - code_iter_len = (max_code_size - len(code_prefix) - len(code_suffix)) // len(iter_loop) - code = code_prefix + iter_loop * code_iter_len + code_suffix - assert len(code) <= max_code_size - - tx = Transaction( - to=pre.deploy_contract(code=bytes(code)), - gas_limit=gas_benchmark_value, - sender=pre.fund_eoa(), - ) - - state_test( + benchmark_test( pre=pre, post={}, - tx=tx, + code_generator=ExtCallGenerator(setup=Bytecode(), attack_block=Op.RETURNDATASIZE), ) @pytest.mark.parametrize("mem_size", [0, 1, 1_000, 100_000, 1_000_000]) def test_worst_msize( - state_test: StateTestFiller, + benchmark_test: BenchmarkTestFiller, pre: Alloc, fork: Fork, mem_size: int, @@ -310,26 +236,15 @@ def test_worst_msize( The `mem_size` parameter indicates by how much the memory is expanded. """ - max_stack_height = fork.max_stack_height() - - code_sequence = Op.MLOAD(Op.CALLVALUE) + Op.POP + Op.MSIZE * max_stack_height - target_address = pre.deploy_contract(code=code_sequence) - - calldata = Bytecode() - attack_block = Op.POP(Op.STATICCALL(Op.GAS, target_address, 0, 0, 0, 0)) - code = code_loop_precompile_call(calldata, attack_block, fork) - assert len(code) <= fork.max_code_size() - - code_address = pre.deploy_contract(code=code) - - tx = Transaction( - to=code_address, - gas_limit=gas_benchmark_value, - sender=pre.fund_eoa(), - value=mem_size, + generator = ExtCallGenerator( + setup=Op.MLOAD(Op.CALLVALUE) + Op.POP, + attack_block=Op.MSIZE, ) + generator.deploy_contracts(pre, fork) + tx = generator.generate_transaction(pre, gas_benchmark_value, fork) + tx.value = HexNumber(mem_size) - state_test( + benchmark_test( pre=pre, post={}, tx=tx, @@ -337,7 +252,7 @@ def test_worst_msize( def test_worst_keccak( - state_test: StateTestFiller, + benchmark_test: BenchmarkTestFiller, pre: Alloc, fork: Fork, gas_benchmark_value: int, @@ -350,11 +265,10 @@ def test_worst_keccak( gsc = fork.gas_costs() mem_exp_gas_calculator = fork.memory_expansion_gas_calculator() - max_code_size = fork.max_code_size() - - # Discover the optimal input size to maximize keccak-permutations, not - # keccak calls. The complication of the discovery arises from the non- - # linear gas cost of memory expansion. + # Discover the optimal input size to maximize keccak-permutations, + # not to maximize keccak calls. + # The complication of the discovery arises from + # the non-linear gas cost of memory expansion. max_keccak_perm_per_block = 0 optimal_input_length = 0 for i in range(1, 1_000_000, 32): @@ -385,32 +299,20 @@ def test_worst_keccak( # The loop structure is: JUMPDEST + [attack iteration] + PUSH0 + JUMP # # Now calculate available gas for [attack iteration]: - # Numerator = max_code_size-3. The -3 is for the JUMPDEST, PUSH0 and JUMP - # Denominator = (PUSHN + PUSH1 + KECCAK256 + POP) + PUSH1_DATA + PUSHN_DATA - # + # Numerator = max_code_size-3. (JUMPDEST, PUSH0 and JUMP) + # Denominator = (PUSHN + PUSH1 + KECCAK256 + POP) + PUSH1_DATA + + # PUSHN_DATA # TODO: the testing framework uses PUSH1(0) instead of PUSH0 which is - # suboptimal for the attack, whenever this is fixed adjust accordingly. - start_code = Op.JUMPDEST + Op.PUSH20[optimal_input_length] - loop_code = Op.POP(Op.SHA3(Op.PUSH0, Op.DUP1)) - end_code = Op.POP + Op.JUMP(Op.PUSH0) - max_iters_loop = (max_code_size - (len(start_code) + len(end_code))) // len(loop_code) - code = start_code + (loop_code * max_iters_loop) + end_code - if len(code) > max_code_size: - # Must never happen, but keep it as a sanity check. - raise ValueError(f"Code size {len(code)} exceeds maximum code size {max_code_size}") - - code_address = pre.deploy_contract(code=bytes(code)) - - tx = Transaction( - to=code_address, - gas_limit=gas_benchmark_value, - sender=pre.fund_eoa(), - ) - - state_test( + # suboptimal for the + # attack, whenever this is fixed adjust accordingly. + benchmark_test( pre=pre, post={}, - tx=tx, + code_generator=JumpLoopGenerator( + setup=Op.PUSH20[optimal_input_length], + attack_block=Op.POP(Op.SHA3(Op.PUSH0, Op.DUP1)), + cleanup=Bytecode(), + ), ) @@ -423,7 +325,7 @@ def test_worst_keccak( ], ) def test_worst_precompile_only_data_input( - state_test: StateTestFiller, + benchmark_test: BenchmarkTestFiller, pre: Alloc, fork: Fork, address: Address, @@ -478,856 +380,362 @@ def test_worst_precompile_only_data_input( max_work = total_work optimal_input_length = input_length - calldata = Op.CODECOPY(0, 0, optimal_input_length) attack_block = Op.POP(Op.STATICCALL(Op.GAS, address, 0, optimal_input_length, 0, 0)) - code = code_loop_precompile_call(calldata, attack_block, fork) - - code_address = pre.deploy_contract(code=code) - tx = Transaction( - to=code_address, - gas_limit=gas_benchmark_value, - sender=pre.fund_eoa(), - ) - - state_test( + benchmark_test( pre=pre, post={}, - tx=tx, - ) - - -@pytest.mark.parametrize( - ["mod_exp_input"], - [ - pytest.param( - ModExpInput( - base=8 * "ff", - exponent=112 * "ff", - modulus=7 * "ff" + "00", - ), - id="mod_even_8b_exp_896", - ), - pytest.param( - ModExpInput( - base=16 * "ff", - exponent=40 * "ff", - modulus=15 * "ff" + "00", - ), - id="mod_even_16b_exp_320", - ), - pytest.param( - ModExpInput( - base=24 * "ff", - exponent=21 * "ff", - modulus=23 * "ff" + "00", - ), - id="mod_even_24b_exp_168", - ), - pytest.param( - ModExpInput( - base=32 * "ff", - exponent=5 * "ff", - modulus=31 * "ff" + "00", - ), - id="mod_even_32b_exp_40", - ), - pytest.param( - ModExpInput( - base=32 * "ff", - exponent=12 * "ff", - modulus=31 * "ff" + "00", - ), - id="mod_even_32b_exp_96", - ), - pytest.param( - ModExpInput( - base=32 * "ff", - exponent=32 * "ff", - modulus=31 * "ff" + "00", - ), - id="mod_even_32b_exp_256", - ), - pytest.param( - ModExpInput( - base=64 * "ff", - exponent=64 * "ff", - modulus=63 * "ff" + "00", - ), - id="mod_even_64b_exp_512", - ), - pytest.param( - ModExpInput( - base=128 * "ff", - exponent=128 * "ff", - modulus=127 * "ff" + "00", - ), - id="mod_even_128b_exp_1024", - ), - pytest.param( - ModExpInput( - base=256 * "ff", - exponent=128 * "ff", - modulus=255 * "ff" + "00", - ), - id="mod_even_256b_exp_1024", - ), - pytest.param( - ModExpInput( - base=512 * "ff", - exponent=128 * "ff", - modulus=511 * "ff" + "00", - ), - id="mod_even_512b_exp_1024", - ), - pytest.param( - ModExpInput( - base=1024 * "ff", - exponent=128 * "ff", - modulus=1023 * "ff" + "00", - ), - id="mod_even_1024b_exp_1024", - ), - pytest.param( - ModExpInput( - base=32 * "ff", - exponent=12 * "ff", - modulus=31 * "ff" + "01", - ), - id="mod_odd_32b_exp_96", - ), - pytest.param( - ModExpInput( - base=32 * "ff", - exponent=32 * "ff", - modulus=31 * "ff" + "01", - ), - id="mod_odd_32b_exp_256", - ), - pytest.param( - ModExpInput( - base=64 * "ff", - exponent=64 * "ff", - modulus=63 * "ff" + "01", - ), - id="mod_odd_64b_exp_512", - ), - pytest.param( - ModExpInput( - base=128 * "ff", - exponent=128 * "ff", - modulus=127 * "ff" + "01", - ), - id="mod_odd_128b_exp_1024", - ), - pytest.param( - ModExpInput( - base=256 * "ff", - exponent=128 * "ff", - modulus=255 * "ff" + "01", - ), - id="mod_odd_256b_exp_1024", - ), - pytest.param( - ModExpInput( - base=512 * "ff", - exponent=128 * "ff", - modulus=511 * "ff" + "01", - ), - id="mod_odd_512b_exp_1024", - ), - pytest.param( - ModExpInput( - base=1024 * "ff", - exponent=128 * "ff", - modulus=1023 * "ff" + "01", - ), - id="mod_odd_1024b_exp_1024", - ), - pytest.param( - ModExpInput( - base=32 * "ff", - exponent=8 * "12345670", - modulus=31 * "ff" + "01", - ), - id="mod_odd_32b_exp_cover_windows", - ), - # Ported from - # https://github.com/NethermindEth/nethermind/blob/ceb8d57b8530ce8181d7427c115ca593386909d6/tools/EngineRequestsGenerator/TestCases/Modexp.cs#L38 - pytest.param( - ModExpInput( - base=192 * "FF", - exponent="03", - modulus=6 * ("00" + 31 * "FF"), - ), - id="mod_min_gas_base_heavy", - ), - # Ported from - # https://github.com/NethermindEth/nethermind/blob/ceb8d57b8530ce8181d7427c115ca593386909d6/tools/EngineRequestsGenerator/TestCases/Modexp.cs#L40 - pytest.param( - ModExpInput( - base=8 * "FF", - exponent="07" + 75 * "FF", - modulus=7 * "FF", - ), - id="mod_min_gas_exp_heavy", - ), - # Ported from - # https://github.com/NethermindEth/nethermind/blob/ceb8d57b8530ce8181d7427c115ca593386909d6/tools/EngineRequestsGenerator/TestCases/Modexp.cs#L42 - pytest.param( - ModExpInput( - base=40 * "FF", - exponent="01" + 3 * "FF", - modulus="00" + 38 * "FF", - ), - id="mod_min_gas_balanced", - ), - # Ported from - # https://github.com/NethermindEth/nethermind/blob/ceb8d57b8530ce8181d7427c115ca593386909d6/tools/EngineRequestsGenerator/TestCases/Modexp.cs#L44 - pytest.param( - ModExpInput( - base=32 * "FF", - exponent=5 * "FF", - modulus=("00" + 31 * "FF"), - ), - id="mod_exp_208_gas_balanced", - ), - # Ported from - # https://github.com/NethermindEth/nethermind/blob/ceb8d57b8530ce8181d7427c115ca593386909d6/tools/EngineRequestsGenerator/TestCases/Modexp.cs#L46 - pytest.param( - ModExpInput( - base=8 * "FF", - exponent=81 * "FF", - modulus=7 * "FF", - ), - id="mod_exp_215_gas_exp_heavy", - ), - # Ported from - # https://github.com/NethermindEth/nethermind/blob/ceb8d57b8530ce8181d7427c115ca593386909d6/tools/EngineRequestsGenerator/TestCases/Modexp.cs#L48 - pytest.param( - ModExpInput( - base=8 * "FF", - exponent=112 * "FF", - modulus=7 * "FF", - ), - id="mod_exp_298_gas_exp_heavy", - ), - # Ported from - # https://github.com/NethermindEth/nethermind/blob/ceb8d57b8530ce8181d7427c115ca593386909d6/tools/EngineRequestsGenerator/TestCases/Modexp.cs#L50 - pytest.param( - ModExpInput( - base=16 * "FF", - exponent=40 * "FF", - modulus=15 * "FF", - ), - id="mod_pawel_2", - ), - # Ported from - # https://github.com/NethermindEth/nethermind/blob/ceb8d57b8530ce8181d7427c115ca593386909d6/tools/EngineRequestsGenerator/TestCases/Modexp.cs#L52 - pytest.param( - ModExpInput( - base=24 * "FF", - exponent=21 * "FF", - modulus=23 * "FF", - ), - id="mod_pawel_3", - ), - # Ported from - # https://github.com/NethermindEth/nethermind/blob/ceb8d57b8530ce8181d7427c115ca593386909d6/tools/EngineRequestsGenerator/TestCases/Modexp.cs#L54 - pytest.param( - ModExpInput( - base=32 * "FF", - exponent=12 * "FF", - modulus="00" + 31 * "FF", - ), - id="mod_pawel_4", - ), - # Ported from - # https://github.com/NethermindEth/nethermind/blob/ceb8d57b8530ce8181d7427c115ca593386909d6/tools/EngineRequestsGenerator/TestCases/Modexp.cs#L56 - pytest.param( - ModExpInput( - base=280 * "FF", - exponent="03", - modulus=8 * ("00" + 31 * "FF") + 23 * "FF", - ), - id="mod_408_gas_base_heavy", - ), - # Ported from - # https://github.com/NethermindEth/nethermind/blob/ceb8d57b8530ce8181d7427c115ca593386909d6/tools/EngineRequestsGenerator/TestCases/Modexp.cs#L58 - pytest.param( - ModExpInput( - base=16 * "FF", - exponent="15" + 37 * "FF", - modulus=15 * "FF", - ), - id="mod_400_gas_exp_heavy", - ), - # Ported from - # https://github.com/NethermindEth/nethermind/blob/ceb8d57b8530ce8181d7427c115ca593386909d6/tools/EngineRequestsGenerator/TestCases/Modexp.cs#L60 - pytest.param( - ModExpInput( - base=48 * "FF", - exponent="07" + 4 * "FF", - modulus="00" + 46 * "FF", - ), - id="mod_408_gas_balanced", - ), - # Ported from - # https://github.com/NethermindEth/nethermind/blob/ceb8d57b8530ce8181d7427c115ca593386909d6/tools/EngineRequestsGenerator/TestCases/Modexp.cs#L62 - pytest.param( - ModExpInput( - base=344 * "FF", - exponent="03", - modulus=10 * ("00" + 31 * "FF") + 23 * "FF", - ), - id="mod_616_gas_base_heavy", - ), - # Ported from - # https://github.com/NethermindEth/nethermind/blob/ceb8d57b8530ce8181d7427c115ca593386909d6/tools/EngineRequestsGenerator/TestCases/Modexp.cs#L64 - pytest.param( - ModExpInput( - base=16 * "FF", - exponent="07" + 56 * "FF", - modulus=15 * "FF", - ), - id="mod_600_gas_exp_heavy", - ), - # Ported from - # https://github.com/NethermindEth/nethermind/blob/ceb8d57b8530ce8181d7427c115ca593386909d6/tools/EngineRequestsGenerator/TestCases/Modexp.cs#L66 - pytest.param( - ModExpInput( - base=48 * "FF", - exponent="07" + 6 * "FF", - modulus="00" + 46 * "FF", - ), - id="mod_600_gas_balanced", - ), - # Ported from - # https://github.com/NethermindEth/nethermind/blob/ceb8d57b8530ce8181d7427c115ca593386909d6/tools/EngineRequestsGenerator/TestCases/Modexp.cs#L68 - pytest.param( - ModExpInput( - base=392 * "FF", - exponent="03", - modulus=12 * ("00" + 31 * "FF") + 7 * "FF", - ), - id="mod_800_gas_base_heavy", - ), - # Ported from - # https://github.com/NethermindEth/nethermind/blob/ceb8d57b8530ce8181d7427c115ca593386909d6/tools/EngineRequestsGenerator/TestCases/Modexp.cs#L70 - pytest.param( - ModExpInput( - base=16 * "FF", - exponent="01" + 75 * "FF", - modulus=15 * "FF", - ), - id="mod_800_gas_exp_heavy", - ), - # Ported from - # https://github.com/NethermindEth/nethermind/blob/ceb8d57b8530ce8181d7427c115ca593386909d6/tools/EngineRequestsGenerator/TestCases/Modexp.cs#L72 - pytest.param( - ModExpInput( - base=56 * "FF", - exponent=6 * "FF", - modulus="00" + 54 * "FF", - ), - id="mod_767_gas_balanced", - ), - # Ported from - # https://github.com/NethermindEth/nethermind/blob/ceb8d57b8530ce8181d7427c115ca593386909d6/tools/EngineRequestsGenerator/TestCases/Modexp.cs#L74 - pytest.param( - ModExpInput( - base=16 * "FF", - exponent=80 * "FF", - modulus=15 * "FF", - ), - id="mod_852_gas_exp_heavy", - ), - # Ported from - # https://github.com/NethermindEth/nethermind/blob/ceb8d57b8530ce8181d7427c115ca593386909d6/tools/EngineRequestsGenerator/TestCases/Modexp.cs#L76 - pytest.param( - ModExpInput( - base=408 * "FF", - exponent="03", - modulus=12 * ("00" + 31 * "FF") + 23 * "FF", - ), - id="mod_867_gas_base_heavy", - ), - # Ported from - # https://github.com/NethermindEth/nethermind/blob/ceb8d57b8530ce8181d7427c115ca593386909d6/tools/EngineRequestsGenerator/TestCases/Modexp.cs#L78 - pytest.param( - ModExpInput( - base=56 * "FF", - exponent="2b" + 7 * "FF", - modulus="00" + 54 * "FF", - ), - id="mod_996_gas_balanced", - ), - # Ported from - # https://github.com/NethermindEth/nethermind/blob/ceb8d57b8530ce8181d7427c115ca593386909d6/tools/EngineRequestsGenerator/TestCases/Modexp.cs#L80 - pytest.param( - ModExpInput( - base=448 * "FF", - exponent="03", - modulus=14 * ("00" + 31 * "FF"), - ), - id="mod_1045_gas_base_heavy", - ), - # Ported from - # https://github.com/NethermindEth/nethermind/blob/ceb8d57b8530ce8181d7427c115ca593386909d6/tools/EngineRequestsGenerator/TestCases/Modexp.cs#L82 - pytest.param( - ModExpInput( - base=32 * "FF", - exponent=16 * "FF", - modulus="00" + 31 * "FF", - ), - id="mod_677_gas_base_heavy", - ), - # Ported from - # https://github.com/NethermindEth/nethermind/blob/ceb8d57b8530ce8181d7427c115ca593386909d6/tools/EngineRequestsGenerator/TestCases/Modexp.cs#L84 - pytest.param( - ModExpInput( - base=24 * "FF", - exponent=32 * "FF", - modulus=23 * "FF", - ), - id="mod_765_gas_exp_heavy", - ), - # Ported from - # https://github.com/NethermindEth/nethermind/blob/ceb8d57b8530ce8181d7427c115ca593386909d6/tools/EngineRequestsGenerator/TestCases/Modexp.cs#L86 - pytest.param( - ModExpInput( - base=32 * "FF", - exponent=32 * "FF", - modulus="00" + 31 * "FF", - ), - id="mod_1360_gas_balanced", - ), - pytest.param( - ModExpInput( - base=8 * "FF", - exponent=81 * "FF", - modulus=7 * "FF", - ), - id="mod_8_exp_648", - ), - pytest.param( - ModExpInput( - base=8 * "FF", - exponent="FF" + 111 * "FF", - modulus=7 * "FF", - ), - id="mod_8_exp_896", - ), - pytest.param( - ModExpInput( - base=32 * "FF", - exponent=4 * "FF", - modulus="00" + 31 * "FF", - ), - id="mod_32_exp_32", - ), - pytest.param( - ModExpInput( - base=32 * "FF", - exponent="0D" + 4 * "FF", - modulus="00" + 31 * "FF", - ), - id="mod_32_exp_36", - ), - pytest.param( - ModExpInput( - base=32 * "FF", - exponent=5 * "FF", - modulus="00" + 31 * "FF", - ), - id="mod_32_exp_40", - ), - pytest.param( - ModExpInput( - base=32 * "FF", - exponent=8 * "FF", - modulus="00" + 31 * "FF", - ), - id="mod_32_exp_64", - ), - pytest.param( - ModExpInput( - base=32 * "FF", - exponent="01" + 8 * "FF", - modulus="00" + 31 * "FF", - ), - id="mod_32_exp_65", - ), - pytest.param( - ModExpInput( - base=32 * "FF", - exponent=16 * "FF", - modulus="00" + 31 * "FF", - ), - id="mod_32_exp_128", - ), - pytest.param( - ModExpInput( - base=256 * "FF", - exponent="03" + 0 * "FF", - modulus=8 * ("00" + 31 * "FF"), - ), - id="mod_256_exp_2", - ), - pytest.param( - ModExpInput( - base=264 * "FF", - exponent="03" + 0 * "FF", - modulus=8 * ("00" + 31 * "FF") + 7 * "FF", - ), - id="mod_264_exp_2", - ), - pytest.param( - ModExpInput( - base=1024 * "FF", - exponent="03", - modulus=32 * ("00" + 31 * "FF"), - ), - id="mod_1024_exp_2", + code_generator=JumpLoopGenerator( + setup=Op.CODECOPY(0, 0, optimal_input_length), attack_block=attack_block + ), + ) + + +def create_modexp_test_cases(): + """Create test cases for the MODEXP precompile.""" + test_cases = [ + # (base, exponent, modulus, test_id) + (8 * "ff", 112 * "ff", 7 * "ff" + "00", "mod_even_8b_exp_896"), + (16 * "ff", 40 * "ff", 15 * "ff" + "00", "mod_even_16b_exp_320"), + (24 * "ff", 21 * "ff", 23 * "ff" + "00", "mod_even_24b_exp_168"), + (32 * "ff", 5 * "ff", 31 * "ff" + "00", "mod_even_32b_exp_40"), + (32 * "ff", 12 * "ff", 31 * "ff" + "00", "mod_even_32b_exp_96"), + (32 * "ff", 32 * "ff", 31 * "ff" + "00", "mod_even_32b_exp_256"), + (64 * "ff", 64 * "ff", 63 * "ff" + "00", "mod_even_64b_exp_512"), + (128 * "ff", 128 * "ff", 127 * "ff" + "00", "mod_even_128b_exp_1024"), + (256 * "ff", 128 * "ff", 255 * "ff" + "00", "mod_even_256b_exp_1024"), + (512 * "ff", 128 * "ff", 511 * "ff" + "00", "mod_even_512b_exp_1024"), + (1024 * "ff", 128 * "ff", 1023 * "ff" + "00", "mod_even_1024b_exp_1024"), + (32 * "ff", 12 * "ff", 31 * "ff" + "01", "mod_odd_32b_exp_96"), + (32 * "ff", 32 * "ff", 31 * "ff" + "01", "mod_odd_32b_exp_256"), + (64 * "ff", 64 * "ff", 63 * "ff" + "01", "mod_odd_64b_exp_512"), + (128 * "ff", 128 * "ff", 127 * "ff" + "01", "mod_odd_128b_exp_1024"), + (256 * "ff", 128 * "ff", 255 * "ff" + "01", "mod_odd_256b_exp_1024"), + (512 * "ff", 128 * "ff", 511 * "ff" + "01", "mod_odd_512b_exp_1024"), + (1024 * "ff", 128 * "ff", 1023 * "ff" + "01", "mod_odd_1024b_exp_1024"), + (32 * "ff", 8 * "12345670", 31 * "ff" + "01", "mod_odd_32b_exp_cover_windows"), + # Ported from https://github.com/NethermindEth/nethermind/blob/ceb8d57b8530ce8181d7427c115ca593386909d6/tools/EngineRequestsGenerator/TestCases/Modexp.cs#L38 + (192 * "FF", "03", 6 * ("00" + 31 * "FF"), "mod_min_gas_base_heavy"), + # Ported from https://github.com/NethermindEth/nethermind/blob/ceb8d57b8530ce8181d7427c115ca593386909d6/tools/EngineRequestsGenerator/TestCases/Modexp.cs#L40 + (8 * "FF", "07" + 75 * "FF", 7 * "FF", "mod_min_gas_exp_heavy"), + # Ported from https://github.com/NethermindEth/nethermind/blob/ceb8d57b8530ce8181d7427c115ca593386909d6/tools/EngineRequestsGenerator/TestCases/Modexp.cs#L42 + (40 * "FF", "01" + 3 * "FF", "00" + 38 * "FF", "mod_min_gas_balanced"), + # Ported from https://github.com/NethermindEth/nethermind/blob/ceb8d57b8530ce8181d7427c115ca593386909d6/tools/EngineRequestsGenerator/TestCases/Modexp.cs#L44 + (32 * "FF", 5 * "FF", ("00" + 31 * "FF"), "mod_exp_208_gas_balanced"), + # Ported from https://github.com/NethermindEth/nethermind/blob/ceb8d57b8530ce8181d7427c115ca593386909d6/tools/EngineRequestsGenerator/TestCases/Modexp.cs#L46 + (8 * "FF", 81 * "FF", 7 * "FF", "mod_exp_215_gas_exp_heavy"), + # Ported from https://github.com/NethermindEth/nethermind/blob/ceb8d57b8530ce8181d7427c115ca593386909d6/tools/EngineRequestsGenerator/TestCases/Modexp.cs#L48 + (8 * "FF", 112 * "FF", 7 * "FF", "mod_exp_298_gas_exp_heavy"), + # Ported from https://github.com/NethermindEth/nethermind/blob/ceb8d57b8530ce8181d7427c115ca593386909d6/tools/EngineRequestsGenerator/TestCases/Modexp.cs#L50 + (16 * "FF", 40 * "FF", 15 * "FF", "mod_pawel_2"), + # Ported from https://github.com/NethermindEth/nethermind/blob/ceb8d57b8530ce8181d7427c115ca593386909d6/tools/EngineRequestsGenerator/TestCases/Modexp.cs#L52 + (24 * "FF", 21 * "FF", 23 * "FF", "mod_pawel_3"), + # Ported from https://github.com/NethermindEth/nethermind/blob/ceb8d57b8530ce8181d7427c115ca593386909d6/tools/EngineRequestsGenerator/TestCases/Modexp.cs#L54 + (32 * "FF", 12 * "FF", "00" + 31 * "FF", "mod_pawel_4"), + # Ported from https://github.com/NethermindEth/nethermind/blob/ceb8d57b8530ce8181d7427c115ca593386909d6/tools/EngineRequestsGenerator/TestCases/Modexp.cs#L56 + (280 * "FF", "03", 8 * ("00" + 31 * "FF") + 23 * "FF", "mod_408_gas_base_heavy"), + # Ported from https://github.com/NethermindEth/nethermind/blob/ceb8d57b8530ce8181d7427c115ca593386909d6/tools/EngineRequestsGenerator/TestCases/Modexp.cs#L58 + (16 * "FF", "15" + 37 * "FF", 15 * "FF", "mod_400_gas_exp_heavy"), + # Ported from https://github.com/NethermindEth/nethermind/blob/ceb8d57b8530ce8181d7427c115ca593386909d6/tools/EngineRequestsGenerator/TestCases/Modexp.cs#L60 + (48 * "FF", "07" + 4 * "FF", "00" + 46 * "FF", "mod_408_gas_balanced"), + # Ported from https://github.com/NethermindEth/nethermind/blob/ceb8d57b8530ce8181d7427c115ca593386909d6/tools/EngineRequestsGenerator/TestCases/Modexp.cs#L62 + (344 * "FF", "03", 10 * ("00" + 31 * "FF") + 23 * "FF", "mod_616_gas_base_heavy"), + # Ported from https://github.com/NethermindEth/nethermind/blob/ceb8d57b8530ce8181d7427c115ca593386909d6/tools/EngineRequestsGenerator/TestCases/Modexp.cs#L64 + (16 * "FF", "07" + 56 * "FF", 15 * "FF", "mod_600_gas_exp_heavy"), + # Ported from https://github.com/NethermindEth/nethermind/blob/ceb8d57b8530ce8181d7427c115ca593386909d6/tools/EngineRequestsGenerator/TestCases/Modexp.cs#L66 + (48 * "FF", "07" + 6 * "FF", "00" + 46 * "FF", "mod_600_gas_balanced"), + # Ported from https://github.com/NethermindEth/nethermind/blob/ceb8d57b8530ce8181d7427c115ca593386909d6/tools/EngineRequestsGenerator/TestCases/Modexp.cs#L68 + (392 * "FF", "03", 12 * ("00" + 31 * "FF") + 7 * "FF", "mod_800_gas_base_heavy"), + # Ported from https://github.com/NethermindEth/nethermind/blob/ceb8d57b8530ce8181d7427c115ca593386909d6/tools/EngineRequestsGenerator/TestCases/Modexp.cs#L70 + (16 * "FF", "01" + 75 * "FF", 15 * "FF", "mod_800_gas_exp_heavy"), + # Ported from https://github.com/NethermindEth/nethermind/blob/ceb8d57b8530ce8181d7427c115ca593386909d6/tools/EngineRequestsGenerator/TestCases/Modexp.cs#L72 + (56 * "FF", 6 * "FF", "00" + 54 * "FF", "mod_767_gas_balanced"), + # Ported from https://github.com/NethermindEth/nethermind/blob/ceb8d57b8530ce8181d7427c115ca593386909d6/tools/EngineRequestsGenerator/TestCases/Modexp.cs#L74 + (16 * "FF", 80 * "FF", 15 * "FF", "mod_852_gas_exp_heavy"), + # Ported from https://github.com/NethermindEth/nethermind/blob/ceb8d57b8530ce8181d7427c115ca593386909d6/tools/EngineRequestsGenerator/TestCases/Modexp.cs#L76 + (408 * "FF", "03", 12 * ("00" + 31 * "FF") + 23 * "FF", "mod_867_gas_base_heavy"), + # Ported from https://github.com/NethermindEth/nethermind/blob/ceb8d57b8530ce8181d7427c115ca593386909d6/tools/EngineRequestsGenerator/TestCases/Modexp.cs#L78 + (56 * "FF", "2b" + 7 * "FF", "00" + 54 * "FF", "mod_996_gas_balanced"), + # Ported from https://github.com/NethermindEth/nethermind/blob/ceb8d57b8530ce8181d7427c115ca593386909d6/tools/EngineRequestsGenerator/TestCases/Modexp.cs#L80 + (448 * "FF", "03", 14 * ("00" + 31 * "FF"), "mod_1045_gas_base_heavy"), + # Ported from https://github.com/NethermindEth/nethermind/blob/ceb8d57b8530ce8181d7427c115ca593386909d6/tools/EngineRequestsGenerator/TestCases/Modexp.cs#L82 + (32 * "FF", 16 * "FF", "00" + 31 * "FF", "mod_677_gas_base_heavy"), + # Ported from https://github.com/NethermindEth/nethermind/blob/ceb8d57b8530ce8181d7427c115ca593386909d6/tools/EngineRequestsGenerator/TestCases/Modexp.cs#L84 + (24 * "FF", 32 * "FF", 23 * "FF", "mod_765_gas_exp_heavy"), + # Ported from https://github.com/NethermindEth/nethermind/blob/ceb8d57b8530ce8181d7427c115ca593386909d6/tools/EngineRequestsGenerator/TestCases/Modexp.cs#L86 + (32 * "FF", 32 * "FF", "00" + 31 * "FF", "mod_1360_gas_balanced"), + (8 * "FF", 81 * "FF", 7 * "FF", "mod_8_exp_648"), + (8 * "FF", "FF" + 111 * "FF", 7 * "FF", "mod_8_exp_896"), + (32 * "FF", 4 * "FF", "00" + 31 * "FF", "mod_32_exp_32"), + (32 * "FF", "0D" + 4 * "FF", "00" + 31 * "FF", "mod_32_exp_36"), + (32 * "FF", 5 * "FF", "00" + 31 * "FF", "mod_32_exp_40"), + (32 * "FF", 8 * "FF", "00" + 31 * "FF", "mod_32_exp_64"), + (32 * "FF", "01" + 8 * "FF", "00" + 31 * "FF", "mod_32_exp_65"), + (32 * "FF", 16 * "FF", "00" + 31 * "FF", "mod_32_exp_128"), + (256 * "FF", "03" + 0 * "FF", 8 * ("00" + 31 * "FF"), "mod_256_exp_2"), + (264 * "FF", "03" + 0 * "FF", 8 * ("00" + 31 * "FF") + 7 * "FF", "mod_264_exp_2"), + (1024 * "FF", "03", 32 * ("00" + 31 * "FF"), "mod_1024_exp_2"), + # Ported from https://github.com/NethermindEth/nethermind/blob/ceb8d57b8530ce8181d7427c115ca593386909d6/tools/EngineRequestsGenerator/TestCases/ModexpVulnerability.cs#L122 + ( + "03", + "fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2e", + "fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f", + "mod_vul_example_1", ), - # Ported from - # https://github.com/NethermindEth/nethermind/blob/ceb8d57b8530ce8181d7427c115ca593386909d6/tools/EngineRequestsGenerator/TestCases/ModexpVulnerability.cs#L122 - pytest.param( - ModExpInput( - base="03", - exponent="fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2e", - modulus="fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f", - ), - id="mod_vul_example_1", + # Ported from https://github.com/NethermindEth/nethermind/blob/ceb8d57b8530ce8181d7427c115ca593386909d6/tools/EngineRequestsGenerator/TestCases/ModexpVulnerability.cs#L124 + ( + "", + "fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2e", + "fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f", + "mod_vul_example_2", ), - # Ported from - # https://github.com/NethermindEth/nethermind/blob/ceb8d57b8530ce8181d7427c115ca593386909d6/tools/EngineRequestsGenerator/TestCases/ModexpVulnerability.cs#L124 - pytest.param( - ModExpInput( - base="", - exponent="fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2e", - modulus="fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f", - ), - id="mod_vul_example_2", + # Ported from https://github.com/NethermindEth/nethermind/blob/ceb8d57b8530ce8181d7427c115ca593386909d6/tools/EngineRequestsGenerator/TestCases/ModexpVulnerability.cs#L126 + ( + "e09ad9675465c53a109fac66a445c91b292d2bb2c5268addb30cd82f80fcb0033ff97c80a5fc6f39193ae969c6ede6710a6b7ac27078a06d90ef1c72e5c85fb5", + "02", + "fc9e1f6beb81516545975218075ec2af118cd8798df6e08a147c60fd6095ac2bb02c2908cf4dd7c81f11c289e4bce98f3553768f392a80ce22bf5c4f4a248c6b", + "mod_vul_nagydani_1_square", ), - # Ported from - # https://github.com/NethermindEth/nethermind/blob/ceb8d57b8530ce8181d7427c115ca593386909d6/tools/EngineRequestsGenerator/TestCases/ModexpVulnerability.cs#L126 - pytest.param( - ModExpInput( - base="e09ad9675465c53a109fac66a445c91b292d2bb2c5268addb30cd82f80fcb0033ff97c80a5fc6f39193ae969c6ede6710a6b7ac27078a06d90ef1c72e5c85fb5", - exponent="02", - modulus="fc9e1f6beb81516545975218075ec2af118cd8798df6e08a147c60fd6095ac2bb02c2908cf4dd7c81f11c289e4bce98f3553768f392a80ce22bf5c4f4a248c6b", - ), - id="mod_vul_nagydani_1_square", + # Ported from https://github.com/NethermindEth/nethermind/blob/ceb8d57b8530ce8181d7427c115ca593386909d6/tools/EngineRequestsGenerator/TestCases/ModexpVulnerability.cs#L128 + ( + "e09ad9675465c53a109fac66a445c91b292d2bb2c5268addb30cd82f80fcb0033ff97c80a5fc6f39193ae969c6ede6710a6b7ac27078a06d90ef1c72e5c85fb5", + "03", + "fc9e1f6beb81516545975218075ec2af118cd8798df6e08a147c60fd6095ac2bb02c2908cf4dd7c81f11c289e4bce98f3553768f392a80ce22bf5c4f4a248c6b", + "mod_vul_nagydani_1_qube", ), - # Ported from - # https://github.com/NethermindEth/nethermind/blob/ceb8d57b8530ce8181d7427c115ca593386909d6/tools/EngineRequestsGenerator/TestCases/ModexpVulnerability.cs#L128 - pytest.param( - ModExpInput( - base="e09ad9675465c53a109fac66a445c91b292d2bb2c5268addb30cd82f80fcb0033ff97c80a5fc6f39193ae969c6ede6710a6b7ac27078a06d90ef1c72e5c85fb5", - exponent="03", - modulus="fc9e1f6beb81516545975218075ec2af118cd8798df6e08a147c60fd6095ac2bb02c2908cf4dd7c81f11c289e4bce98f3553768f392a80ce22bf5c4f4a248c6b", - ), - id="mod_vul_nagydani_1_qube", + # Ported from https://github.com/NethermindEth/nethermind/blob/ceb8d57b8530ce8181d7427c115ca593386909d6/tools/EngineRequestsGenerator/TestCases/ModexpVulnerability.cs#L130 + ( + "e09ad9675465c53a109fac66a445c91b292d2bb2c5268addb30cd82f80fcb0033ff97c80a5fc6f39193ae969c6ede6710a6b7ac27078a06d90ef1c72e5c85fb5", + "010001", + "fc9e1f6beb81516545975218075ec2af118cd8798df6e08a147c60fd6095ac2bb02c2908cf4dd7c81f11c289e4bce98f3553768f392a80ce22bf5c4f4a248c6b", + "mod_vul_nagydani_1_pow_0x10001", ), - # Ported from - # https://github.com/NethermindEth/nethermind/blob/ceb8d57b8530ce8181d7427c115ca593386909d6/tools/EngineRequestsGenerator/TestCases/ModexpVulnerability.cs#L130 - pytest.param( - ModExpInput( - base="e09ad9675465c53a109fac66a445c91b292d2bb2c5268addb30cd82f80fcb0033ff97c80a5fc6f39193ae969c6ede6710a6b7ac27078a06d90ef1c72e5c85fb5", - exponent="010001", - modulus="fc9e1f6beb81516545975218075ec2af118cd8798df6e08a147c60fd6095ac2bb02c2908cf4dd7c81f11c289e4bce98f3553768f392a80ce22bf5c4f4a248c6b", - ), - id="mod_vul_nagydani_1_pow_0x10001", + # Ported from https://github.com/NethermindEth/nethermind/blob/ceb8d57b8530ce8181d7427c115ca593386909d6/tools/EngineRequestsGenerator/TestCases/ModexpVulnerability.cs#L132 + ( + "cad7d991a00047dd54d3399b6b0b937c718abddef7917c75b6681f40cc15e2be0003657d8d4c34167b2f0bbbca0ccaa407c2a6a07d50f1517a8f22979ce12a81dcaf707cc0cebfc0ce2ee84ee7f77c38b9281b9822a8d3de62784c089c9b18dcb9a2a5eecbede90ea788a862a9ddd9d609c2c52972d63e289e28f6a590ffbf51", + "02", + "e6d893b80aeed5e6e9ce9afa8a5d5675c93a32ac05554cb20e9951b2c140e3ef4e433068cf0fb73bc9f33af1853f64aa27a0028cbf570d7ac9048eae5dc7b28c87c31e5810f1e7fa2cda6adf9f1076dbc1ec1238560071e7efc4e9565c49be9e7656951985860a558a754594115830bcdb421f741408346dd5997bb01c287087", + "mod_vul_nagydani_2_square", ), - # Ported from - # https://github.com/NethermindEth/nethermind/blob/ceb8d57b8530ce8181d7427c115ca593386909d6/tools/EngineRequestsGenerator/TestCases/ModexpVulnerability.cs#L132 - pytest.param( - ModExpInput( - base="cad7d991a00047dd54d3399b6b0b937c718abddef7917c75b6681f40cc15e2be0003657d8d4c34167b2f0bbbca0ccaa407c2a6a07d50f1517a8f22979ce12a81dcaf707cc0cebfc0ce2ee84ee7f77c38b9281b9822a8d3de62784c089c9b18dcb9a2a5eecbede90ea788a862a9ddd9d609c2c52972d63e289e28f6a590ffbf51", - exponent="02", - modulus="e6d893b80aeed5e6e9ce9afa8a5d5675c93a32ac05554cb20e9951b2c140e3ef4e433068cf0fb73bc9f33af1853f64aa27a0028cbf570d7ac9048eae5dc7b28c87c31e5810f1e7fa2cda6adf9f1076dbc1ec1238560071e7efc4e9565c49be9e7656951985860a558a754594115830bcdb421f741408346dd5997bb01c287087", - ), - id="mod_vul_nagydani_2_square", + # Ported from https://github.com/NethermindEth/nethermind/blob/ceb8d57b8530ce8181d7427c115ca593386909d6/tools/EngineRequestsGenerator/TestCases/ModexpVulnerability.cs#L134 + ( + "cad7d991a00047dd54d3399b6b0b937c718abddef7917c75b6681f40cc15e2be0003657d8d4c34167b2f0bbbca0ccaa407c2a6a07d50f1517a8f22979ce12a81dcaf707cc0cebfc0ce2ee84ee7f77c38b9281b9822a8d3de62784c089c9b18dcb9a2a5eecbede90ea788a862a9ddd9d609c2c52972d63e289e28f6a590ffbf51", + "03", + "e6d893b80aeed5e6e9ce9afa8a5d5675c93a32ac05554cb20e9951b2c140e3ef4e433068cf0fb73bc9f33af1853f64aa27a0028cbf570d7ac9048eae5dc7b28c87c31e5810f1e7fa2cda6adf9f1076dbc1ec1238560071e7efc4e9565c49be9e7656951985860a558a754594115830bcdb421f741408346dd5997bb01c287087", + "mod_vul_nagydani_2_qube", ), - # Ported from - # https://github.com/NethermindEth/nethermind/blob/ceb8d57b8530ce8181d7427c115ca593386909d6/tools/EngineRequestsGenerator/TestCases/ModexpVulnerability.cs#L134 - pytest.param( - ModExpInput( - base="cad7d991a00047dd54d3399b6b0b937c718abddef7917c75b6681f40cc15e2be0003657d8d4c34167b2f0bbbca0ccaa407c2a6a07d50f1517a8f22979ce12a81dcaf707cc0cebfc0ce2ee84ee7f77c38b9281b9822a8d3de62784c089c9b18dcb9a2a5eecbede90ea788a862a9ddd9d609c2c52972d63e289e28f6a590ffbf51", - exponent="03", - modulus="e6d893b80aeed5e6e9ce9afa8a5d5675c93a32ac05554cb20e9951b2c140e3ef4e433068cf0fb73bc9f33af1853f64aa27a0028cbf570d7ac9048eae5dc7b28c87c31e5810f1e7fa2cda6adf9f1076dbc1ec1238560071e7efc4e9565c49be9e7656951985860a558a754594115830bcdb421f741408346dd5997bb01c287087", - ), - id="mod_vul_nagydani_2_qube", + # Ported from https://github.com/NethermindEth/nethermind/blob/ceb8d57b8530ce8181d7427c115ca593386909d6/tools/EngineRequestsGenerator/TestCases/ModexpVulnerability.cs#L136 + ( + "cad7d991a00047dd54d3399b6b0b937c718abddef7917c75b6681f40cc15e2be0003657d8d4c34167b2f0bbbca0ccaa407c2a6a07d50f1517a8f22979ce12a81dcaf707cc0cebfc0ce2ee84ee7f77c38b9281b9822a8d3de62784c089c9b18dcb9a2a5eecbede90ea788a862a9ddd9d609c2c52972d63e289e28f6a590ffbf51", + "010001", + "e6d893b80aeed5e6e9ce9afa8a5d5675c93a32ac05554cb20e9951b2c140e3ef4e433068cf0fb73bc9f33af1853f64aa27a0028cbf570d7ac9048eae5dc7b28c87c31e5810f1e7fa2cda6adf9f1076dbc1ec1238560071e7efc4e9565c49be9e7656951985860a558a754594115830bcdb421f741408346dd5997bb01c287087", + "mod_vul_nagydani_2_pow_0x10001", ), - # Ported from - # https://github.com/NethermindEth/nethermind/blob/ceb8d57b8530ce8181d7427c115ca593386909d6/tools/EngineRequestsGenerator/TestCases/ModexpVulnerability.cs#L136 - pytest.param( - ModExpInput( - base="cad7d991a00047dd54d3399b6b0b937c718abddef7917c75b6681f40cc15e2be0003657d8d4c34167b2f0bbbca0ccaa407c2a6a07d50f1517a8f22979ce12a81dcaf707cc0cebfc0ce2ee84ee7f77c38b9281b9822a8d3de62784c089c9b18dcb9a2a5eecbede90ea788a862a9ddd9d609c2c52972d63e289e28f6a590ffbf51", - exponent="010001", - modulus="e6d893b80aeed5e6e9ce9afa8a5d5675c93a32ac05554cb20e9951b2c140e3ef4e433068cf0fb73bc9f33af1853f64aa27a0028cbf570d7ac9048eae5dc7b28c87c31e5810f1e7fa2cda6adf9f1076dbc1ec1238560071e7efc4e9565c49be9e7656951985860a558a754594115830bcdb421f741408346dd5997bb01c287087", - ), - id="mod_vul_nagydani_2_pow_0x10001", + ( + "c9130579f243e12451760976261416413742bd7c91d39ae087f46794062b8c239f2a74abf3918605a0e046a7890e049475ba7fbb78f5de6490bd22a710cc04d30088179a919d86c2da62cf37f59d8f258d2310d94c24891be2d7eeafaa32a8cb4b0cfe5f475ed778f45907dc8916a73f03635f233f7a77a00a3ec9ca6761a5bbd558a2318ecd0caa1c5016691523e7e1fa267dd35e70c66e84380bdcf7c0582f540174e572c41f81e93da0b757dff0b0fe23eb03aa19af0bdec3afb474216febaacb8d0381e631802683182b0fe72c28392539850650b70509f54980241dc175191a35d967288b532a7a8223ce2440d010615f70df269501944d4ec16fe4a3cb", + "02", + "d7a85909174757835187cb52e71934e6c07ef43b4c46fc30bbcd0bc72913068267c54a4aabebb493922492820babdeb7dc9b1558fcf7bd82c37c82d3147e455b623ab0efa752fe0b3a67ca6e4d126639e645a0bf417568adbb2a6a4eef62fa1fa29b2a5a43bebea1f82193a7dd98eb483d09bb595af1fa9c97c7f41f5649d976aee3e5e59e2329b43b13bea228d4a93f16ba139ccb511de521ffe747aa2eca664f7c9e33da59075cc335afcd2bf3ae09765f01ab5a7c3e3938ec168b74724b5074247d200d9970382f683d6059b94dbc336603d1dfee714e4b447ac2fa1d99ecb4961da2854e03795ed758220312d101e1e3d87d5313a6d052aebde75110363d", + "mod_vul_nagydani_3_square", ), - # Ported from - # https://github.com/NethermindEth/nethermind/blob/ceb8d57b8530ce8181d7427c115ca593386909d6/tools/EngineRequestsGenerator/TestCases/ModexpVulnerability.cs#L138 - pytest.param( - ModExpInput( - base="c9130579f243e12451760976261416413742bd7c91d39ae087f46794062b8c239f2a74abf3918605a0e046a7890e049475ba7fbb78f5de6490bd22a710cc04d30088179a919d86c2da62cf37f59d8f258d2310d94c24891be2d7eeafaa32a8cb4b0cfe5f475ed778f45907dc8916a73f03635f233f7a77a00a3ec9ca6761a5bbd558a2318ecd0caa1c5016691523e7e1fa267dd35e70c66e84380bdcf7c0582f540174e572c41f81e93da0b757dff0b0fe23eb03aa19af0bdec3afb474216febaacb8d0381e631802683182b0fe72c28392539850650b70509f54980241dc175191a35d967288b532a7a8223ce2440d010615f70df269501944d4ec16fe4a3cb", - exponent="02", - modulus="d7a85909174757835187cb52e71934e6c07ef43b4c46fc30bbcd0bc72913068267c54a4aabebb493922492820babdeb7dc9b1558fcf7bd82c37c82d3147e455b623ab0efa752fe0b3a67ca6e4d126639e645a0bf417568adbb2a6a4eef62fa1fa29b2a5a43bebea1f82193a7dd98eb483d09bb595af1fa9c97c7f41f5649d976aee3e5e59e2329b43b13bea228d4a93f16ba139ccb511de521ffe747aa2eca664f7c9e33da59075cc335afcd2bf3ae09765f01ab5a7c3e3938ec168b74724b5074247d200d9970382f683d6059b94dbc336603d1dfee714e4b447ac2fa1d99ecb4961da2854e03795ed758220312d101e1e3d87d5313a6d052aebde75110363d", - ), - id="mod_vul_nagydani_3_square", + # Ported from https://github.com/NethermindEth/nethermind/blob/ceb8d57b8530ce8181d7427c115ca593386909d6/tools/EngineRequestsGenerator/TestCases/ModexpVulnerability.cs#L140 + ( + "c9130579f243e12451760976261416413742bd7c91d39ae087f46794062b8c239f2a74abf3918605a0e046a7890e049475ba7fbb78f5de6490bd22a710cc04d30088179a919d86c2da62cf37f59d8f258d2310d94c24891be2d7eeafaa32a8cb4b0cfe5f475ed778f45907dc8916a73f03635f233f7a77a00a3ec9ca6761a5bbd558a2318ecd0caa1c5016691523e7e1fa267dd35e70c66e84380bdcf7c0582f540174e572c41f81e93da0b757dff0b0fe23eb03aa19af0bdec3afb474216febaacb8d0381e631802683182b0fe72c28392539850650b70509f54980241dc175191a35d967288b532a7a8223ce2440d010615f70df269501944d4ec16fe4a3cb", + "03", + "d7a85909174757835187cb52e71934e6c07ef43b4c46fc30bbcd0bc72913068267c54a4aabebb493922492820babdeb7dc9b1558fcf7bd82c37c82d3147e455b623ab0efa752fe0b3a67ca6e4d126639e645a0bf417568adbb2a6a4eef62fa1fa29b2a5a43bebea1f82193a7dd98eb483d09bb595af1fa9c97c7f41f5649d976aee3e5e59e2329b43b13bea228d4a93f16ba139ccb511de521ffe747aa2eca664f7c9e33da59075cc335afcd2bf3ae09765f01ab5a7c3e3938ec168b74724b5074247d200d9970382f683d6059b94dbc336603d1dfee714e4b447ac2fa1d99ecb4961da2854e03795ed758220312d101e1e3d87d5313a6d052aebde75110363d", + "mod_vul_nagydani_3_qube", ), - # Ported from - # https://github.com/NethermindEth/nethermind/blob/ceb8d57b8530ce8181d7427c115ca593386909d6/tools/EngineRequestsGenerator/TestCases/ModexpVulnerability.cs#L140 - pytest.param( - ModExpInput( - base="c9130579f243e12451760976261416413742bd7c91d39ae087f46794062b8c239f2a74abf3918605a0e046a7890e049475ba7fbb78f5de6490bd22a710cc04d30088179a919d86c2da62cf37f59d8f258d2310d94c24891be2d7eeafaa32a8cb4b0cfe5f475ed778f45907dc8916a73f03635f233f7a77a00a3ec9ca6761a5bbd558a2318ecd0caa1c5016691523e7e1fa267dd35e70c66e84380bdcf7c0582f540174e572c41f81e93da0b757dff0b0fe23eb03aa19af0bdec3afb474216febaacb8d0381e631802683182b0fe72c28392539850650b70509f54980241dc175191a35d967288b532a7a8223ce2440d010615f70df269501944d4ec16fe4a3cb", - exponent="03", - modulus="d7a85909174757835187cb52e71934e6c07ef43b4c46fc30bbcd0bc72913068267c54a4aabebb493922492820babdeb7dc9b1558fcf7bd82c37c82d3147e455b623ab0efa752fe0b3a67ca6e4d126639e645a0bf417568adbb2a6a4eef62fa1fa29b2a5a43bebea1f82193a7dd98eb483d09bb595af1fa9c97c7f41f5649d976aee3e5e59e2329b43b13bea228d4a93f16ba139ccb511de521ffe747aa2eca664f7c9e33da59075cc335afcd2bf3ae09765f01ab5a7c3e3938ec168b74724b5074247d200d9970382f683d6059b94dbc336603d1dfee714e4b447ac2fa1d99ecb4961da2854e03795ed758220312d101e1e3d87d5313a6d052aebde75110363d", - ), - id="mod_vul_nagydani_3_qube", + # Ported from https://github.com/NethermindEth/nethermind/blob/ceb8d57b8530ce8181d7427c115ca593386909d6/tools/EngineRequestsGenerator/TestCases/ModexpVulnerability.cs#L142 + ( + "c9130579f243e12451760976261416413742bd7c91d39ae087f46794062b8c239f2a74abf3918605a0e046a7890e049475ba7fbb78f5de6490bd22a710cc04d30088179a919d86c2da62cf37f59d8f258d2310d94c24891be2d7eeafaa32a8cb4b0cfe5f475ed778f45907dc8916a73f03635f233f7a77a00a3ec9ca6761a5bbd558a2318ecd0caa1c5016691523e7e1fa267dd35e70c66e84380bdcf7c0582f540174e572c41f81e93da0b757dff0b0fe23eb03aa19af0bdec3afb474216febaacb8d0381e631802683182b0fe72c28392539850650b70509f54980241dc175191a35d967288b532a7a8223ce2440d010615f70df269501944d4ec16fe4a3cb", + "010001", + "d7a85909174757835187cb52e71934e6c07ef43b4c46fc30bbcd0bc72913068267c54a4aabebb493922492820babdeb7dc9b1558fcf7bd82c37c82d3147e455b623ab0efa752fe0b3a67ca6e4d126639e645a0bf417568adbb2a6a4eef62fa1fa29b2a5a43bebea1f82193a7dd98eb483d09bb595af1fa9c97c7f41f5649d976aee3e5e59e2329b43b13bea228d4a93f16ba139ccb511de521ffe747aa2eca664f7c9e33da59075cc335afcd2bf3ae09765f01ab5a7c3e3938ec168b74724b5074247d200d9970382f683d6059b94dbc336603d1dfee714e4b447ac2fa1d99ecb4961da2854e03795ed758220312d101e1e3d87d5313a6d052aebde75110363d", + "mod_vul_nagydani_3_pow_0x10001", ), - # Ported from - # https://github.com/NethermindEth/nethermind/blob/ceb8d57b8530ce8181d7427c115ca593386909d6/tools/EngineRequestsGenerator/TestCases/ModexpVulnerability.cs#L142 - pytest.param( - ModExpInput( - base="c9130579f243e12451760976261416413742bd7c91d39ae087f46794062b8c239f2a74abf3918605a0e046a7890e049475ba7fbb78f5de6490bd22a710cc04d30088179a919d86c2da62cf37f59d8f258d2310d94c24891be2d7eeafaa32a8cb4b0cfe5f475ed778f45907dc8916a73f03635f233f7a77a00a3ec9ca6761a5bbd558a2318ecd0caa1c5016691523e7e1fa267dd35e70c66e84380bdcf7c0582f540174e572c41f81e93da0b757dff0b0fe23eb03aa19af0bdec3afb474216febaacb8d0381e631802683182b0fe72c28392539850650b70509f54980241dc175191a35d967288b532a7a8223ce2440d010615f70df269501944d4ec16fe4a3cb", - exponent="010001", - modulus="d7a85909174757835187cb52e71934e6c07ef43b4c46fc30bbcd0bc72913068267c54a4aabebb493922492820babdeb7dc9b1558fcf7bd82c37c82d3147e455b623ab0efa752fe0b3a67ca6e4d126639e645a0bf417568adbb2a6a4eef62fa1fa29b2a5a43bebea1f82193a7dd98eb483d09bb595af1fa9c97c7f41f5649d976aee3e5e59e2329b43b13bea228d4a93f16ba139ccb511de521ffe747aa2eca664f7c9e33da59075cc335afcd2bf3ae09765f01ab5a7c3e3938ec168b74724b5074247d200d9970382f683d6059b94dbc336603d1dfee714e4b447ac2fa1d99ecb4961da2854e03795ed758220312d101e1e3d87d5313a6d052aebde75110363d", - ), - id="mod_vul_nagydani_3_pow_0x10001", + # Ported from https://github.com/NethermindEth/nethermind/blob/ceb8d57b8530ce8181d7427c115ca593386909d6/tools/EngineRequestsGenerator/TestCases/ModexpVulnerability.cs#L144 + ( + "db34d0e438249c0ed685c949cc28776a05094e1c48691dc3f2dca5fc3356d2a0663bd376e4712839917eb9a19c670407e2c377a2de385a3ff3b52104f7f1f4e0c7bf7717fb913896693dc5edbb65b760ef1b00e42e9d8f9af17352385e1cd742c9b006c0f669995cb0bb21d28c0aced2892267637b6470d8cee0ab27fc5d42658f6e88240c31d6774aa60a7ebd25cd48b56d0da11209f1928e61005c6eb709f3e8e0aaf8d9b10f7d7e296d772264dc76897ccdddadc91efa91c1903b7232a9e4c3b941917b99a3bc0c26497dedc897c25750af60237aa67934a26a2bc491db3dcc677491944bc1f51d3e5d76b8d846a62db03dedd61ff508f91a56d71028125035c3a44cbb041497c83bf3e4ae2a9613a401cc721c547a2afa3b16a2969933d3626ed6d8a7428648f74122fd3f2a02a20758f7f693892c8fd798b39abac01d18506c45e71432639e9f9505719ee822f62ccbf47f6850f096ff77b5afaf4be7d772025791717dbe5abf9b3f40cff7d7aab6f67e38f62faf510747276e20a42127e7500c444f9ed92baf65ade9e836845e39c4316d9dce5f8e2c8083e2c0acbb95296e05e51aab13b6b8f53f06c9c4276e12b0671133218cc3ea907da3bd9a367096d9202128d14846cc2e20d56fc8473ecb07cecbfb8086919f3971926e7045b853d85a69d026195c70f9f7a823536e2a8f4b3e12e94d9b53a934353451094b81", + "02", + "df3143a0057457d75e8c708b6337a6f5a4fd1a06727acf9fb93e2993c62f3378b37d56c85e7b1e00f0145ebf8e4095bd723166293c60b6ac1252291ef65823c9e040ddad14969b3b340a4ef714db093a587c37766d68b8d6b5016e741587e7e6bf7e763b44f0247e64bae30f994d248bfd20541a333e5b225ef6a61199e301738b1e688f70ec1d7fb892c183c95dc543c3e12adf8a5e8b9ca9d04f9445cced3ab256f29e998e69efaa633a7b60e1db5a867924ccab0a171d9d6e1098dfa15acde9553de599eaa56490c8f411e4985111f3d40bddfc5e301edb01547b01a886550a61158f7e2033c59707789bf7c854181d0c2e2a42a93cf09209747d7082e147eb8544de25c3eb14f2e35559ea0c0f5877f2f3fc92132c0ae9da4e45b2f6c866a224ea6d1f28c05320e287750fbc647368d41116e528014cc1852e5531d53e4af938374daba6cee4baa821ed07117253bb3601ddd00d59a3d7fb2ef1f5a2fbba7c429f0cf9a5b3462410fd833a69118f8be9c559b1000cc608fd877fb43f8e65c2d1302622b944462579056874b387208d90623fcdaf93920ca7a9e4ba64ea208758222ad868501cc2c345e2d3a5ea2a17e5069248138c8a79c0251185d29ee73e5afab5354769142d2bf0cb6712727aa6bf84a6245fcdae66e4938d84d1b9dd09a884818622080ff5f98942fb20acd7e0c916c2d5ea7ce6f7e173315384518f", + "mod_vul_nagydani_4_square", ), - # Ported from - # https://github.com/NethermindEth/nethermind/blob/ceb8d57b8530ce8181d7427c115ca593386909d6/tools/EngineRequestsGenerator/TestCases/ModexpVulnerability.cs#L144 - pytest.param( - ModExpInput( - base="db34d0e438249c0ed685c949cc28776a05094e1c48691dc3f2dca5fc3356d2a0663bd376e4712839917eb9a19c670407e2c377a2de385a3ff3b52104f7f1f4e0c7bf7717fb913896693dc5edbb65b760ef1b00e42e9d8f9af17352385e1cd742c9b006c0f669995cb0bb21d28c0aced2892267637b6470d8cee0ab27fc5d42658f6e88240c31d6774aa60a7ebd25cd48b56d0da11209f1928e61005c6eb709f3e8e0aaf8d9b10f7d7e296d772264dc76897ccdddadc91efa91c1903b7232a9e4c3b941917b99a3bc0c26497dedc897c25750af60237aa67934a26a2bc491db3dcc677491944bc1f51d3e5d76b8d846a62db03dedd61ff508f91a56d71028125035c3a44cbb041497c83bf3e4ae2a9613a401cc721c547a2afa3b16a2969933d3626ed6d8a7428648f74122fd3f2a02a20758f7f693892c8fd798b39abac01d18506c45e71432639e9f9505719ee822f62ccbf47f6850f096ff77b5afaf4be7d772025791717dbe5abf9b3f40cff7d7aab6f67e38f62faf510747276e20a42127e7500c444f9ed92baf65ade9e836845e39c4316d9dce5f8e2c8083e2c0acbb95296e05e51aab13b6b8f53f06c9c4276e12b0671133218cc3ea907da3bd9a367096d9202128d14846cc2e20d56fc8473ecb07cecbfb8086919f3971926e7045b853d85a69d026195c70f9f7a823536e2a8f4b3e12e94d9b53a934353451094b81", - exponent="02", - modulus="df3143a0057457d75e8c708b6337a6f5a4fd1a06727acf9fb93e2993c62f3378b37d56c85e7b1e00f0145ebf8e4095bd723166293c60b6ac1252291ef65823c9e040ddad14969b3b340a4ef714db093a587c37766d68b8d6b5016e741587e7e6bf7e763b44f0247e64bae30f994d248bfd20541a333e5b225ef6a61199e301738b1e688f70ec1d7fb892c183c95dc543c3e12adf8a5e8b9ca9d04f9445cced3ab256f29e998e69efaa633a7b60e1db5a867924ccab0a171d9d6e1098dfa15acde9553de599eaa56490c8f411e4985111f3d40bddfc5e301edb01547b01a886550a61158f7e2033c59707789bf7c854181d0c2e2a42a93cf09209747d7082e147eb8544de25c3eb14f2e35559ea0c0f5877f2f3fc92132c0ae9da4e45b2f6c866a224ea6d1f28c05320e287750fbc647368d41116e528014cc1852e5531d53e4af938374daba6cee4baa821ed07117253bb3601ddd00d59a3d7fb2ef1f5a2fbba7c429f0cf9a5b3462410fd833a69118f8be9c559b1000cc608fd877fb43f8e65c2d1302622b944462579056874b387208d90623fcdaf93920ca7a9e4ba64ea208758222ad868501cc2c345e2d3a5ea2a17e5069248138c8a79c0251185d29ee73e5afab5354769142d2bf0cb6712727aa6bf84a6245fcdae66e4938d84d1b9dd09a884818622080ff5f98942fb20acd7e0c916c2d5ea7ce6f7e173315384518f", - ), - id="mod_vul_nagydani_4_square", + # Ported from https://github.com/NethermindEth/nethermind/blob/ceb8d57b8530ce8181d7427c115ca593386909d6/tools/EngineRequestsGenerator/TestCases/ModexpVulnerability.cs#L146 + ( + "db34d0e438249c0ed685c949cc28776a05094e1c48691dc3f2dca5fc3356d2a0663bd376e4712839917eb9a19c670407e2c377a2de385a3ff3b52104f7f1f4e0c7bf7717fb913896693dc5edbb65b760ef1b00e42e9d8f9af17352385e1cd742c9b006c0f669995cb0bb21d28c0aced2892267637b6470d8cee0ab27fc5d42658f6e88240c31d6774aa60a7ebd25cd48b56d0da11209f1928e61005c6eb709f3e8e0aaf8d9b10f7d7e296d772264dc76897ccdddadc91efa91c1903b7232a9e4c3b941917b99a3bc0c26497dedc897c25750af60237aa67934a26a2bc491db3dcc677491944bc1f51d3e5d76b8d846a62db03dedd61ff508f91a56d71028125035c3a44cbb041497c83bf3e4ae2a9613a401cc721c547a2afa3b16a2969933d3626ed6d8a7428648f74122fd3f2a02a20758f7f693892c8fd798b39abac01d18506c45e71432639e9f9505719ee822f62ccbf47f6850f096ff77b5afaf4be7d772025791717dbe5abf9b3f40cff7d7aab6f67e38f62faf510747276e20a42127e7500c444f9ed92baf65ade9e836845e39c4316d9dce5f8e2c8083e2c0acbb95296e05e51aab13b6b8f53f06c9c4276e12b0671133218cc3ea907da3bd9a367096d9202128d14846cc2e20d56fc8473ecb07cecbfb8086919f3971926e7045b853d85a69d026195c70f9f7a823536e2a8f4b3e12e94d9b53a934353451094b81", + "03", + "df3143a0057457d75e8c708b6337a6f5a4fd1a06727acf9fb93e2993c62f3378b37d56c85e7b1e00f0145ebf8e4095bd723166293c60b6ac1252291ef65823c9e040ddad14969b3b340a4ef714db093a587c37766d68b8d6b5016e741587e7e6bf7e763b44f0247e64bae30f994d248bfd20541a333e5b225ef6a61199e301738b1e688f70ec1d7fb892c183c95dc543c3e12adf8a5e8b9ca9d04f9445cced3ab256f29e998e69efaa633a7b60e1db5a867924ccab0a171d9d6e1098dfa15acde9553de599eaa56490c8f411e4985111f3d40bddfc5e301edb01547b01a886550a61158f7e2033c59707789bf7c854181d0c2e2a42a93cf09209747d7082e147eb8544de25c3eb14f2e35559ea0c0f5877f2f3fc92132c0ae9da4e45b2f6c866a224ea6d1f28c05320e287750fbc647368d41116e528014cc1852e5531d53e4af938374daba6cee4baa821ed07117253bb3601ddd00d59a3d7fb2ef1f5a2fbba7c429f0cf9a5b3462410fd833a69118f8be9c559b1000cc608fd877fb43f8e65c2d1302622b944462579056874b387208d90623fcdaf93920ca7a9e4ba64ea208758222ad868501cc2c345e2d3a5ea2a17e5069248138c8a79c0251185d29ee73e5afab5354769142d2bf0cb6712727aa6bf84a6245fcdae66e4938d84d1b9dd09a884818622080ff5f98942fb20acd7e0c916c2d5ea7ce6f7e173315384518f", + "mod_vul_nagydani_4_qube", ), - # Ported from - # https://github.com/NethermindEth/nethermind/blob/ceb8d57b8530ce8181d7427c115ca593386909d6/tools/EngineRequestsGenerator/TestCases/ModexpVulnerability.cs#L146 - pytest.param( - ModExpInput( - base="db34d0e438249c0ed685c949cc28776a05094e1c48691dc3f2dca5fc3356d2a0663bd376e4712839917eb9a19c670407e2c377a2de385a3ff3b52104f7f1f4e0c7bf7717fb913896693dc5edbb65b760ef1b00e42e9d8f9af17352385e1cd742c9b006c0f669995cb0bb21d28c0aced2892267637b6470d8cee0ab27fc5d42658f6e88240c31d6774aa60a7ebd25cd48b56d0da11209f1928e61005c6eb709f3e8e0aaf8d9b10f7d7e296d772264dc76897ccdddadc91efa91c1903b7232a9e4c3b941917b99a3bc0c26497dedc897c25750af60237aa67934a26a2bc491db3dcc677491944bc1f51d3e5d76b8d846a62db03dedd61ff508f91a56d71028125035c3a44cbb041497c83bf3e4ae2a9613a401cc721c547a2afa3b16a2969933d3626ed6d8a7428648f74122fd3f2a02a20758f7f693892c8fd798b39abac01d18506c45e71432639e9f9505719ee822f62ccbf47f6850f096ff77b5afaf4be7d772025791717dbe5abf9b3f40cff7d7aab6f67e38f62faf510747276e20a42127e7500c444f9ed92baf65ade9e836845e39c4316d9dce5f8e2c8083e2c0acbb95296e05e51aab13b6b8f53f06c9c4276e12b0671133218cc3ea907da3bd9a367096d9202128d14846cc2e20d56fc8473ecb07cecbfb8086919f3971926e7045b853d85a69d026195c70f9f7a823536e2a8f4b3e12e94d9b53a934353451094b81", - exponent="03", - modulus="df3143a0057457d75e8c708b6337a6f5a4fd1a06727acf9fb93e2993c62f3378b37d56c85e7b1e00f0145ebf8e4095bd723166293c60b6ac1252291ef65823c9e040ddad14969b3b340a4ef714db093a587c37766d68b8d6b5016e741587e7e6bf7e763b44f0247e64bae30f994d248bfd20541a333e5b225ef6a61199e301738b1e688f70ec1d7fb892c183c95dc543c3e12adf8a5e8b9ca9d04f9445cced3ab256f29e998e69efaa633a7b60e1db5a867924ccab0a171d9d6e1098dfa15acde9553de599eaa56490c8f411e4985111f3d40bddfc5e301edb01547b01a886550a61158f7e2033c59707789bf7c854181d0c2e2a42a93cf09209747d7082e147eb8544de25c3eb14f2e35559ea0c0f5877f2f3fc92132c0ae9da4e45b2f6c866a224ea6d1f28c05320e287750fbc647368d41116e528014cc1852e5531d53e4af938374daba6cee4baa821ed07117253bb3601ddd00d59a3d7fb2ef1f5a2fbba7c429f0cf9a5b3462410fd833a69118f8be9c559b1000cc608fd877fb43f8e65c2d1302622b944462579056874b387208d90623fcdaf93920ca7a9e4ba64ea208758222ad868501cc2c345e2d3a5ea2a17e5069248138c8a79c0251185d29ee73e5afab5354769142d2bf0cb6712727aa6bf84a6245fcdae66e4938d84d1b9dd09a884818622080ff5f98942fb20acd7e0c916c2d5ea7ce6f7e173315384518f", - ), - id="mod_vul_nagydani_4_qube", + # Ported from https://github.com/NethermindEth/nethermind/blob/ceb8d57b8530ce8181d7427c115ca593386909d6/tools/EngineRequestsGenerator/TestCases/ModexpVulnerability.cs#L148 + ( + "db34d0e438249c0ed685c949cc28776a05094e1c48691dc3f2dca5fc3356d2a0663bd376e4712839917eb9a19c670407e2c377a2de385a3ff3b52104f7f1f4e0c7bf7717fb913896693dc5edbb65b760ef1b00e42e9d8f9af17352385e1cd742c9b006c0f669995cb0bb21d28c0aced2892267637b6470d8cee0ab27fc5d42658f6e88240c31d6774aa60a7ebd25cd48b56d0da11209f1928e61005c6eb709f3e8e0aaf8d9b10f7d7e296d772264dc76897ccdddadc91efa91c1903b7232a9e4c3b941917b99a3bc0c26497dedc897c25750af60237aa67934a26a2bc491db3dcc677491944bc1f51d3e5d76b8d846a62db03dedd61ff508f91a56d71028125035c3a44cbb041497c83bf3e4ae2a9613a401cc721c547a2afa3b16a2969933d3626ed6d8a7428648f74122fd3f2a02a20758f7f693892c8fd798b39abac01d18506c45e71432639e9f9505719ee822f62ccbf47f6850f096ff77b5afaf4be7d772025791717dbe5abf9b3f40cff7d7aab6f67e38f62faf510747276e20a42127e7500c444f9ed92baf65ade9e836845e39c4316d9dce5f8e2c8083e2c0acbb95296e05e51aab13b6b8f53f06c9c4276e12b0671133218cc3ea907da3bd9a367096d9202128d14846cc2e20d56fc8473ecb07cecbfb8086919f3971926e7045b853d85a69d026195c70f9f7a823536e2a8f4b3e12e94d9b53a934353451094b81", + "010001", + "df3143a0057457d75e8c708b6337a6f5a4fd1a06727acf9fb93e2993c62f3378b37d56c85e7b1e00f0145ebf8e4095bd723166293c60b6ac1252291ef65823c9e040ddad14969b3b340a4ef714db093a587c37766d68b8d6b5016e741587e7e6bf7e763b44f0247e64bae30f994d248bfd20541a333e5b225ef6a61199e301738b1e688f70ec1d7fb892c183c95dc543c3e12adf8a5e8b9ca9d04f9445cced3ab256f29e998e69efaa633a7b60e1db5a867924ccab0a171d9d6e1098dfa15acde9553de599eaa56490c8f411e4985111f3d40bddfc5e301edb01547b01a886550a61158f7e2033c59707789bf7c854181d0c2e2a42a93cf09209747d7082e147eb8544de25c3eb14f2e35559ea0c0f5877f2f3fc92132c0ae9da4e45b2f6c866a224ea6d1f28c05320e287750fbc647368d41116e528014cc1852e5531d53e4af938374daba6cee4baa821ed07117253bb3601ddd00d59a3d7fb2ef1f5a2fbba7c429f0cf9a5b3462410fd833a69118f8be9c559b1000cc608fd877fb43f8e65c2d1302622b944462579056874b387208d90623fcdaf93920ca7a9e4ba64ea208758222ad868501cc2c345e2d3a5ea2a17e5069248138c8a79c0251185d29ee73e5afab5354769142d2bf0cb6712727aa6bf84a6245fcdae66e4938d84d1b9dd09a884818622080ff5f98942fb20acd7e0c916c2d5ea7ce6f7e173315384518f", + "mod_vul_nagydani_4_pow_0x10001", ), - # Ported from - # https://github.com/NethermindEth/nethermind/blob/ceb8d57b8530ce8181d7427c115ca593386909d6/tools/EngineRequestsGenerator/TestCases/ModexpVulnerability.cs#L148 - pytest.param( - ModExpInput( - base="db34d0e438249c0ed685c949cc28776a05094e1c48691dc3f2dca5fc3356d2a0663bd376e4712839917eb9a19c670407e2c377a2de385a3ff3b52104f7f1f4e0c7bf7717fb913896693dc5edbb65b760ef1b00e42e9d8f9af17352385e1cd742c9b006c0f669995cb0bb21d28c0aced2892267637b6470d8cee0ab27fc5d42658f6e88240c31d6774aa60a7ebd25cd48b56d0da11209f1928e61005c6eb709f3e8e0aaf8d9b10f7d7e296d772264dc76897ccdddadc91efa91c1903b7232a9e4c3b941917b99a3bc0c26497dedc897c25750af60237aa67934a26a2bc491db3dcc677491944bc1f51d3e5d76b8d846a62db03dedd61ff508f91a56d71028125035c3a44cbb041497c83bf3e4ae2a9613a401cc721c547a2afa3b16a2969933d3626ed6d8a7428648f74122fd3f2a02a20758f7f693892c8fd798b39abac01d18506c45e71432639e9f9505719ee822f62ccbf47f6850f096ff77b5afaf4be7d772025791717dbe5abf9b3f40cff7d7aab6f67e38f62faf510747276e20a42127e7500c444f9ed92baf65ade9e836845e39c4316d9dce5f8e2c8083e2c0acbb95296e05e51aab13b6b8f53f06c9c4276e12b0671133218cc3ea907da3bd9a367096d9202128d14846cc2e20d56fc8473ecb07cecbfb8086919f3971926e7045b853d85a69d026195c70f9f7a823536e2a8f4b3e12e94d9b53a934353451094b81", - exponent="010001", - modulus="df3143a0057457d75e8c708b6337a6f5a4fd1a06727acf9fb93e2993c62f3378b37d56c85e7b1e00f0145ebf8e4095bd723166293c60b6ac1252291ef65823c9e040ddad14969b3b340a4ef714db093a587c37766d68b8d6b5016e741587e7e6bf7e763b44f0247e64bae30f994d248bfd20541a333e5b225ef6a61199e301738b1e688f70ec1d7fb892c183c95dc543c3e12adf8a5e8b9ca9d04f9445cced3ab256f29e998e69efaa633a7b60e1db5a867924ccab0a171d9d6e1098dfa15acde9553de599eaa56490c8f411e4985111f3d40bddfc5e301edb01547b01a886550a61158f7e2033c59707789bf7c854181d0c2e2a42a93cf09209747d7082e147eb8544de25c3eb14f2e35559ea0c0f5877f2f3fc92132c0ae9da4e45b2f6c866a224ea6d1f28c05320e287750fbc647368d41116e528014cc1852e5531d53e4af938374daba6cee4baa821ed07117253bb3601ddd00d59a3d7fb2ef1f5a2fbba7c429f0cf9a5b3462410fd833a69118f8be9c559b1000cc608fd877fb43f8e65c2d1302622b944462579056874b387208d90623fcdaf93920ca7a9e4ba64ea208758222ad868501cc2c345e2d3a5ea2a17e5069248138c8a79c0251185d29ee73e5afab5354769142d2bf0cb6712727aa6bf84a6245fcdae66e4938d84d1b9dd09a884818622080ff5f98942fb20acd7e0c916c2d5ea7ce6f7e173315384518f", - ), - id="mod_vul_nagydani_4_pow_0x10001", + # Ported from https://github.com/NethermindEth/nethermind/blob/ceb8d57b8530ce8181d7427c115ca593386909d6/tools/EngineRequestsGenerator/TestCases/ModexpVulnerability.cs#L150 + ( + "c5a1611f8be90071a43db23cc2fe01871cc4c0e8ab5743f6378e4fef77f7f6db0095c0727e20225beb665645403453e325ad5f9aeb9ba99bf3c148f63f9c07cf4fe8847ad5242d6b7d4499f93bd47056ddab8f7dee878fc2314f344dbee2a7c41a5d3db91eff372c730c2fdd3a141a4b61999e36d549b9870cf2f4e632c4d5df5f024f81c028000073a0ed8847cfb0593d36a47142f578f05ccbe28c0c06aeb1b1da027794c48db880278f79ba78ae64eedfea3c07d10e0562668d839749dc95f40467d15cf65b9cfc52c7c4bcef1cda3596dd52631aac942f146c7cebd46065131699ce8385b0db1874336747ee020a5698a3d1a1082665721e769567f579830f9d259cec1a836845109c21cf6b25da572512bf3c42fd4b96e43895589042ab60dd41f497db96aec102087fe784165bb45f942859268fd2ff6c012d9d00c02ba83eace047cc5f7b2c392c2955c58a49f0338d6fc58749c9db2155522ac17914ec216ad87f12e0ee95574613942fa615898c4d9e8a3be68cd6afa4e7a003dedbdf8edfee31162b174f965b20ae752ad89c967b3068b6f722c16b354456ba8e280f987c08e0a52d40a2e8f3a59b94d590aeef01879eb7a90b3ee7d772c839c85519cbeaddc0c193ec4874a463b53fcaea3271d80ebfb39b33489365fc039ae549a17a9ff898eea2f4cb27b8dbee4c17b998438575b2b8d107e4a0d66ba7fca85b41a58a8d51f191a35c856dfbe8aef2b00048a694bbccff832d23c8ca7a7ff0b6c0b3011d00b97c86c0628444d267c951d9e4fb8f83e154b8f74fb51aa16535e498235c5597dac9606ed0be3173a3836baa4e7d756ffe1e2879b415d3846bccd538c05b847785699aefde3e305decb600cd8fb0e7d8de5efc26971a6ad4e6d7a2d91474f1023a0ac4b78dc937da0ce607a45974d2cac1c33a2631ff7fe6144a3b2e5cf98b531a9627dea92c1dc82204d09db0439b6a11dd64b484e1263aa45fd9539b6020b55e3baece3986a8bffc1003406348f5c61265099ed43a766ee4f93f5f9c5abbc32a0fd3ac2b35b87f9ec26037d88275bd7dd0a54474995ee34ed3727f3f97c48db544b1980193a4b76a8a3ddab3591ce527f16d91882e67f0103b5cda53f7da54d489fc4ac08b6ab358a5a04aa9daa16219d50bd672a7cb804ed769d218807544e5993f1c27427104b349906a0b654df0bf69328afd3013fbe430155339c39f236df5557bf92f1ded7ff609a8502f49064ec3d1dbfb6c15d3a4c11a4f8acd12278cbf68acd5709463d12e3338a6eddb8c112f199645e23154a8e60879d2a654e3ed9296aa28f134168619691cd2c6b9e2eba4438381676173fc63c2588a3c5910dc149cf3760f0aa9fa9c3f5faa9162b0bf1aac9dd32b706a60ef53cbdb394b6b40222b5bc80eea82ba8958386672564cae3794f977871ab62337cf", + "02", + "e30049201ec12937e7ce79d0f55d9c810e20acf52212aca1d3888949e0e4830aad88d804161230eb89d4d329cc83570fe257217d2119134048dd2ed167646975fc7d77136919a049ea74cf08ddd2b896890bb24a0ba18094a22baa351bf29ad96c66bbb1a598f2ca391749620e62d61c3561a7d3653ccc8892c7b99baaf76bf836e2991cb06d6bc0514568ff0d1ec8bb4b3d6984f5eaefb17d3ea2893722375d3ddb8e389a8eef7d7d198f8e687d6a513983df906099f9a2d23f4f9dec6f8ef2f11fc0a21fac45353b94e00486f5e17d386af42502d09db33cf0cf28310e049c07e88682aeeb00cb833c5174266e62407a57583f1f88b304b7c6e0c84bbe1c0fd423072d37a5bd0aacf764229e5c7cd02473460ba3645cd8e8ae144065bf02d0dd238593d8e230354f67e0b2f23012c23274f80e3ee31e35e2606a4a3f31d94ab755e6d163cff52cbb36b6d0cc67ffc512aeed1dce4d7a0d70ce82f2baba12e8d514dc92a056f994adfb17b5b9712bd5186f27a2fda1f7039c5df2c8587fdc62f5627580c13234b55be4df3056050e2d1ef3218f0dd66cb05265fe1acfb0989d8213f2c19d1735a7cf3fa65d88dad5af52dc2bba22b7abf46c3bc77b5091baab9e8f0ddc4d5e581037de91a9f8dcbc69309be29cc815cf19a20a7585b8b3073edf51fc9baeb3e509b97fa4ecfd621e0fd57bd61cac1b895c03248ff12bdbc57509250df3517e8a3fe1d776836b34ab352b973d932ef708b14f7418f9eceb1d87667e61e3e758649cb083f01b133d37ab2f5afa96d6c84bcacf4efc3851ad308c1e7d9113624fce29fab460ab9d2a48d92cdb281103a5250ad44cb2ff6e67ac670c02fdafb3e0f1353953d6d7d5646ca1568dea55275a050ec501b7c6250444f7219f1ba7521ba3b93d089727ca5f3bbe0d6c1300b423377004954c5628fdb65770b18ced5c9b23a4a5a6d6ef25fe01b4ce278de0bcc4ed86e28a0a68818ffa40970128cf2c38740e80037984428c1bd5113f40ff47512ee6f4e4d8f9b8e8e1b3040d2928d003bd1c1329dc885302fbce9fa81c23b4dc49c7c82d29b52957847898676c89aa5d32b5b0e1c0d5a2b79a19d67562f407f19425687971a957375879d90c5f57c857136c17106c9ab1b99d80e69c8c954ed386493368884b55c939b8d64d26f643e800c56f90c01079d7c534e3b2b7ae352cefd3016da55f6a85eb803b85e2304915fd2001f77c74e28746293c46e4f5f0fd49cf988aafd0026b8e7a3bab2da5cdce1ea26c2e29ec03f4807fac432662b2d6c060be1c7be0e5489de69d0a6e03a4b9117f9244b34a0f1ecba89884f781c6320412413a00c4980287409a2a78c2cd7e65cecebbe4ec1c28cac4dd95f6998e78fc6f1392384331c9436aa10e10e2bf8ad2c4eafbcf276aa7bae64b74428911b3269c749338b0fc5075ad", + "mod_vul_nagydani_5_square", ), - # Ported from - # https://github.com/NethermindEth/nethermind/blob/ceb8d57b8530ce8181d7427c115ca593386909d6/tools/EngineRequestsGenerator/TestCases/ModexpVulnerability.cs#L150 - pytest.param( - ModExpInput( - base="c5a1611f8be90071a43db23cc2fe01871cc4c0e8ab5743f6378e4fef77f7f6db0095c0727e20225beb665645403453e325ad5f9aeb9ba99bf3c148f63f9c07cf4fe8847ad5242d6b7d4499f93bd47056ddab8f7dee878fc2314f344dbee2a7c41a5d3db91eff372c730c2fdd3a141a4b61999e36d549b9870cf2f4e632c4d5df5f024f81c028000073a0ed8847cfb0593d36a47142f578f05ccbe28c0c06aeb1b1da027794c48db880278f79ba78ae64eedfea3c07d10e0562668d839749dc95f40467d15cf65b9cfc52c7c4bcef1cda3596dd52631aac942f146c7cebd46065131699ce8385b0db1874336747ee020a5698a3d1a1082665721e769567f579830f9d259cec1a836845109c21cf6b25da572512bf3c42fd4b96e43895589042ab60dd41f497db96aec102087fe784165bb45f942859268fd2ff6c012d9d00c02ba83eace047cc5f7b2c392c2955c58a49f0338d6fc58749c9db2155522ac17914ec216ad87f12e0ee95574613942fa615898c4d9e8a3be68cd6afa4e7a003dedbdf8edfee31162b174f965b20ae752ad89c967b3068b6f722c16b354456ba8e280f987c08e0a52d40a2e8f3a59b94d590aeef01879eb7a90b3ee7d772c839c85519cbeaddc0c193ec4874a463b53fcaea3271d80ebfb39b33489365fc039ae549a17a9ff898eea2f4cb27b8dbee4c17b998438575b2b8d107e4a0d66ba7fca85b41a58a8d51f191a35c856dfbe8aef2b00048a694bbccff832d23c8ca7a7ff0b6c0b3011d00b97c86c0628444d267c951d9e4fb8f83e154b8f74fb51aa16535e498235c5597dac9606ed0be3173a3836baa4e7d756ffe1e2879b415d3846bccd538c05b847785699aefde3e305decb600cd8fb0e7d8de5efc26971a6ad4e6d7a2d91474f1023a0ac4b78dc937da0ce607a45974d2cac1c33a2631ff7fe6144a3b2e5cf98b531a9627dea92c1dc82204d09db0439b6a11dd64b484e1263aa45fd9539b6020b55e3baece3986a8bffc1003406348f5c61265099ed43a766ee4f93f5f9c5abbc32a0fd3ac2b35b87f9ec26037d88275bd7dd0a54474995ee34ed3727f3f97c48db544b1980193a4b76a8a3ddab3591ce527f16d91882e67f0103b5cda53f7da54d489fc4ac08b6ab358a5a04aa9daa16219d50bd672a7cb804ed769d218807544e5993f1c27427104b349906a0b654df0bf69328afd3013fbe430155339c39f236df5557bf92f1ded7ff609a8502f49064ec3d1dbfb6c15d3a4c11a4f8acd12278cbf68acd5709463d12e3338a6eddb8c112f199645e23154a8e60879d2a654e3ed9296aa28f134168619691cd2c6b9e2eba4438381676173fc63c2588a3c5910dc149cf3760f0aa9fa9c3f5faa9162b0bf1aac9dd32b706a60ef53cbdb394b6b40222b5bc80eea82ba8958386672564cae3794f977871ab62337cf", - exponent="02", - modulus="e30049201ec12937e7ce79d0f55d9c810e20acf52212aca1d3888949e0e4830aad88d804161230eb89d4d329cc83570fe257217d2119134048dd2ed167646975fc7d77136919a049ea74cf08ddd2b896890bb24a0ba18094a22baa351bf29ad96c66bbb1a598f2ca391749620e62d61c3561a7d3653ccc8892c7b99baaf76bf836e2991cb06d6bc0514568ff0d1ec8bb4b3d6984f5eaefb17d3ea2893722375d3ddb8e389a8eef7d7d198f8e687d6a513983df906099f9a2d23f4f9dec6f8ef2f11fc0a21fac45353b94e00486f5e17d386af42502d09db33cf0cf28310e049c07e88682aeeb00cb833c5174266e62407a57583f1f88b304b7c6e0c84bbe1c0fd423072d37a5bd0aacf764229e5c7cd02473460ba3645cd8e8ae144065bf02d0dd238593d8e230354f67e0b2f23012c23274f80e3ee31e35e2606a4a3f31d94ab755e6d163cff52cbb36b6d0cc67ffc512aeed1dce4d7a0d70ce82f2baba12e8d514dc92a056f994adfb17b5b9712bd5186f27a2fda1f7039c5df2c8587fdc62f5627580c13234b55be4df3056050e2d1ef3218f0dd66cb05265fe1acfb0989d8213f2c19d1735a7cf3fa65d88dad5af52dc2bba22b7abf46c3bc77b5091baab9e8f0ddc4d5e581037de91a9f8dcbc69309be29cc815cf19a20a7585b8b3073edf51fc9baeb3e509b97fa4ecfd621e0fd57bd61cac1b895c03248ff12bdbc57509250df3517e8a3fe1d776836b34ab352b973d932ef708b14f7418f9eceb1d87667e61e3e758649cb083f01b133d37ab2f5afa96d6c84bcacf4efc3851ad308c1e7d9113624fce29fab460ab9d2a48d92cdb281103a5250ad44cb2ff6e67ac670c02fdafb3e0f1353953d6d7d5646ca1568dea55275a050ec501b7c6250444f7219f1ba7521ba3b93d089727ca5f3bbe0d6c1300b423377004954c5628fdb65770b18ced5c9b23a4a5a6d6ef25fe01b4ce278de0bcc4ed86e28a0a68818ffa40970128cf2c38740e80037984428c1bd5113f40ff47512ee6f4e4d8f9b8e8e1b3040d2928d003bd1c1329dc885302fbce9fa81c23b4dc49c7c82d29b52957847898676c89aa5d32b5b0e1c0d5a2b79a19d67562f407f19425687971a957375879d90c5f57c857136c17106c9ab1b99d80e69c8c954ed386493368884b55c939b8d64d26f643e800c56f90c01079d7c534e3b2b7ae352cefd3016da55f6a85eb803b85e2304915fd2001f77c74e28746293c46e4f5f0fd49cf988aafd0026b8e7a3bab2da5cdce1ea26c2e29ec03f4807fac432662b2d6c060be1c7be0e5489de69d0a6e03a4b9117f9244b34a0f1ecba89884f781c6320412413a00c4980287409a2a78c2cd7e65cecebbe4ec1c28cac4dd95f6998e78fc6f1392384331c9436aa10e10e2bf8ad2c4eafbcf276aa7bae64b74428911b3269c749338b0fc5075ad", - ), - id="mod_vul_nagydani_5_square", + # Ported from https://github.com/NethermindEth/nethermind/blob/ceb8d57b8530ce8181d7427c115ca593386909d6/tools/EngineRequestsGenerator/TestCases/ModexpVulnerability.cs#L152 + ( + "c5a1611f8be90071a43db23cc2fe01871cc4c0e8ab5743f6378e4fef77f7f6db0095c0727e20225beb665645403453e325ad5f9aeb9ba99bf3c148f63f9c07cf4fe8847ad5242d6b7d4499f93bd47056ddab8f7dee878fc2314f344dbee2a7c41a5d3db91eff372c730c2fdd3a141a4b61999e36d549b9870cf2f4e632c4d5df5f024f81c028000073a0ed8847cfb0593d36a47142f578f05ccbe28c0c06aeb1b1da027794c48db880278f79ba78ae64eedfea3c07d10e0562668d839749dc95f40467d15cf65b9cfc52c7c4bcef1cda3596dd52631aac942f146c7cebd46065131699ce8385b0db1874336747ee020a5698a3d1a1082665721e769567f579830f9d259cec1a836845109c21cf6b25da572512bf3c42fd4b96e43895589042ab60dd41f497db96aec102087fe784165bb45f942859268fd2ff6c012d9d00c02ba83eace047cc5f7b2c392c2955c58a49f0338d6fc58749c9db2155522ac17914ec216ad87f12e0ee95574613942fa615898c4d9e8a3be68cd6afa4e7a003dedbdf8edfee31162b174f965b20ae752ad89c967b3068b6f722c16b354456ba8e280f987c08e0a52d40a2e8f3a59b94d590aeef01879eb7a90b3ee7d772c839c85519cbeaddc0c193ec4874a463b53fcaea3271d80ebfb39b33489365fc039ae549a17a9ff898eea2f4cb27b8dbee4c17b998438575b2b8d107e4a0d66ba7fca85b41a58a8d51f191a35c856dfbe8aef2b00048a694bbccff832d23c8ca7a7ff0b6c0b3011d00b97c86c0628444d267c951d9e4fb8f83e154b8f74fb51aa16535e498235c5597dac9606ed0be3173a3836baa4e7d756ffe1e2879b415d3846bccd538c05b847785699aefde3e305decb600cd8fb0e7d8de5efc26971a6ad4e6d7a2d91474f1023a0ac4b78dc937da0ce607a45974d2cac1c33a2631ff7fe6144a3b2e5cf98b531a9627dea92c1dc82204d09db0439b6a11dd64b484e1263aa45fd9539b6020b55e3baece3986a8bffc1003406348f5c61265099ed43a766ee4f93f5f9c5abbc32a0fd3ac2b35b87f9ec26037d88275bd7dd0a54474995ee34ed3727f3f97c48db544b1980193a4b76a8a3ddab3591ce527f16d91882e67f0103b5cda53f7da54d489fc4ac08b6ab358a5a04aa9daa16219d50bd672a7cb804ed769d218807544e5993f1c27427104b349906a0b654df0bf69328afd3013fbe430155339c39f236df5557bf92f1ded7ff609a8502f49064ec3d1dbfb6c15d3a4c11a4f8acd12278cbf68acd5709463d12e3338a6eddb8c112f199645e23154a8e60879d2a654e3ed9296aa28f134168619691cd2c6b9e2eba4438381676173fc63c2588a3c5910dc149cf3760f0aa9fa9c3f5faa9162b0bf1aac9dd32b706a60ef53cbdb394b6b40222b5bc80eea82ba8958386672564cae3794f977871ab62337cf", + "03", + "e30049201ec12937e7ce79d0f55d9c810e20acf52212aca1d3888949e0e4830aad88d804161230eb89d4d329cc83570fe257217d2119134048dd2ed167646975fc7d77136919a049ea74cf08ddd2b896890bb24a0ba18094a22baa351bf29ad96c66bbb1a598f2ca391749620e62d61c3561a7d3653ccc8892c7b99baaf76bf836e2991cb06d6bc0514568ff0d1ec8bb4b3d6984f5eaefb17d3ea2893722375d3ddb8e389a8eef7d7d198f8e687d6a513983df906099f9a2d23f4f9dec6f8ef2f11fc0a21fac45353b94e00486f5e17d386af42502d09db33cf0cf28310e049c07e88682aeeb00cb833c5174266e62407a57583f1f88b304b7c6e0c84bbe1c0fd423072d37a5bd0aacf764229e5c7cd02473460ba3645cd8e8ae144065bf02d0dd238593d8e230354f67e0b2f23012c23274f80e3ee31e35e2606a4a3f31d94ab755e6d163cff52cbb36b6d0cc67ffc512aeed1dce4d7a0d70ce82f2baba12e8d514dc92a056f994adfb17b5b9712bd5186f27a2fda1f7039c5df2c8587fdc62f5627580c13234b55be4df3056050e2d1ef3218f0dd66cb05265fe1acfb0989d8213f2c19d1735a7cf3fa65d88dad5af52dc2bba22b7abf46c3bc77b5091baab9e8f0ddc4d5e581037de91a9f8dcbc69309be29cc815cf19a20a7585b8b3073edf51fc9baeb3e509b97fa4ecfd621e0fd57bd61cac1b895c03248ff12bdbc57509250df3517e8a3fe1d776836b34ab352b973d932ef708b14f7418f9eceb1d87667e61e3e758649cb083f01b133d37ab2f5afa96d6c84bcacf4efc3851ad308c1e7d9113624fce29fab460ab9d2a48d92cdb281103a5250ad44cb2ff6e67ac670c02fdafb3e0f1353953d6d7d5646ca1568dea55275a050ec501b7c6250444f7219f1ba7521ba3b93d089727ca5f3bbe0d6c1300b423377004954c5628fdb65770b18ced5c9b23a4a5a6d6ef25fe01b4ce278de0bcc4ed86e28a0a68818ffa40970128cf2c38740e80037984428c1bd5113f40ff47512ee6f4e4d8f9b8e8e1b3040d2928d003bd1c1329dc885302fbce9fa81c23b4dc49c7c82d29b52957847898676c89aa5d32b5b0e1c0d5a2b79a19d67562f407f19425687971a957375879d90c5f57c857136c17106c9ab1b99d80e69c8c954ed386493368884b55c939b8d64d26f643e800c56f90c01079d7c534e3b2b7ae352cefd3016da55f6a85eb803b85e2304915fd2001f77c74e28746293c46e4f5f0fd49cf988aafd0026b8e7a3bab2da5cdce1ea26c2e29ec03f4807fac432662b2d6c060be1c7be0e5489de69d0a6e03a4b9117f9244b34a0f1ecba89884f781c6320412413a00c4980287409a2a78c2cd7e65cecebbe4ec1c28cac4dd95f6998e78fc6f1392384331c9436aa10e10e2bf8ad2c4eafbcf276aa7bae64b74428911b3269c749338b0fc5075ad", + "mod_vul_nagydani_5_qube", ), - # Ported from - # https://github.com/NethermindEth/nethermind/blob/ceb8d57b8530ce8181d7427c115ca593386909d6/tools/EngineRequestsGenerator/TestCases/ModexpVulnerability.cs#L152 - pytest.param( - ModExpInput( - base="c5a1611f8be90071a43db23cc2fe01871cc4c0e8ab5743f6378e4fef77f7f6db0095c0727e20225beb665645403453e325ad5f9aeb9ba99bf3c148f63f9c07cf4fe8847ad5242d6b7d4499f93bd47056ddab8f7dee878fc2314f344dbee2a7c41a5d3db91eff372c730c2fdd3a141a4b61999e36d549b9870cf2f4e632c4d5df5f024f81c028000073a0ed8847cfb0593d36a47142f578f05ccbe28c0c06aeb1b1da027794c48db880278f79ba78ae64eedfea3c07d10e0562668d839749dc95f40467d15cf65b9cfc52c7c4bcef1cda3596dd52631aac942f146c7cebd46065131699ce8385b0db1874336747ee020a5698a3d1a1082665721e769567f579830f9d259cec1a836845109c21cf6b25da572512bf3c42fd4b96e43895589042ab60dd41f497db96aec102087fe784165bb45f942859268fd2ff6c012d9d00c02ba83eace047cc5f7b2c392c2955c58a49f0338d6fc58749c9db2155522ac17914ec216ad87f12e0ee95574613942fa615898c4d9e8a3be68cd6afa4e7a003dedbdf8edfee31162b174f965b20ae752ad89c967b3068b6f722c16b354456ba8e280f987c08e0a52d40a2e8f3a59b94d590aeef01879eb7a90b3ee7d772c839c85519cbeaddc0c193ec4874a463b53fcaea3271d80ebfb39b33489365fc039ae549a17a9ff898eea2f4cb27b8dbee4c17b998438575b2b8d107e4a0d66ba7fca85b41a58a8d51f191a35c856dfbe8aef2b00048a694bbccff832d23c8ca7a7ff0b6c0b3011d00b97c86c0628444d267c951d9e4fb8f83e154b8f74fb51aa16535e498235c5597dac9606ed0be3173a3836baa4e7d756ffe1e2879b415d3846bccd538c05b847785699aefde3e305decb600cd8fb0e7d8de5efc26971a6ad4e6d7a2d91474f1023a0ac4b78dc937da0ce607a45974d2cac1c33a2631ff7fe6144a3b2e5cf98b531a9627dea92c1dc82204d09db0439b6a11dd64b484e1263aa45fd9539b6020b55e3baece3986a8bffc1003406348f5c61265099ed43a766ee4f93f5f9c5abbc32a0fd3ac2b35b87f9ec26037d88275bd7dd0a54474995ee34ed3727f3f97c48db544b1980193a4b76a8a3ddab3591ce527f16d91882e67f0103b5cda53f7da54d489fc4ac08b6ab358a5a04aa9daa16219d50bd672a7cb804ed769d218807544e5993f1c27427104b349906a0b654df0bf69328afd3013fbe430155339c39f236df5557bf92f1ded7ff609a8502f49064ec3d1dbfb6c15d3a4c11a4f8acd12278cbf68acd5709463d12e3338a6eddb8c112f199645e23154a8e60879d2a654e3ed9296aa28f134168619691cd2c6b9e2eba4438381676173fc63c2588a3c5910dc149cf3760f0aa9fa9c3f5faa9162b0bf1aac9dd32b706a60ef53cbdb394b6b40222b5bc80eea82ba8958386672564cae3794f977871ab62337cf", - exponent="03", - modulus="e30049201ec12937e7ce79d0f55d9c810e20acf52212aca1d3888949e0e4830aad88d804161230eb89d4d329cc83570fe257217d2119134048dd2ed167646975fc7d77136919a049ea74cf08ddd2b896890bb24a0ba18094a22baa351bf29ad96c66bbb1a598f2ca391749620e62d61c3561a7d3653ccc8892c7b99baaf76bf836e2991cb06d6bc0514568ff0d1ec8bb4b3d6984f5eaefb17d3ea2893722375d3ddb8e389a8eef7d7d198f8e687d6a513983df906099f9a2d23f4f9dec6f8ef2f11fc0a21fac45353b94e00486f5e17d386af42502d09db33cf0cf28310e049c07e88682aeeb00cb833c5174266e62407a57583f1f88b304b7c6e0c84bbe1c0fd423072d37a5bd0aacf764229e5c7cd02473460ba3645cd8e8ae144065bf02d0dd238593d8e230354f67e0b2f23012c23274f80e3ee31e35e2606a4a3f31d94ab755e6d163cff52cbb36b6d0cc67ffc512aeed1dce4d7a0d70ce82f2baba12e8d514dc92a056f994adfb17b5b9712bd5186f27a2fda1f7039c5df2c8587fdc62f5627580c13234b55be4df3056050e2d1ef3218f0dd66cb05265fe1acfb0989d8213f2c19d1735a7cf3fa65d88dad5af52dc2bba22b7abf46c3bc77b5091baab9e8f0ddc4d5e581037de91a9f8dcbc69309be29cc815cf19a20a7585b8b3073edf51fc9baeb3e509b97fa4ecfd621e0fd57bd61cac1b895c03248ff12bdbc57509250df3517e8a3fe1d776836b34ab352b973d932ef708b14f7418f9eceb1d87667e61e3e758649cb083f01b133d37ab2f5afa96d6c84bcacf4efc3851ad308c1e7d9113624fce29fab460ab9d2a48d92cdb281103a5250ad44cb2ff6e67ac670c02fdafb3e0f1353953d6d7d5646ca1568dea55275a050ec501b7c6250444f7219f1ba7521ba3b93d089727ca5f3bbe0d6c1300b423377004954c5628fdb65770b18ced5c9b23a4a5a6d6ef25fe01b4ce278de0bcc4ed86e28a0a68818ffa40970128cf2c38740e80037984428c1bd5113f40ff47512ee6f4e4d8f9b8e8e1b3040d2928d003bd1c1329dc885302fbce9fa81c23b4dc49c7c82d29b52957847898676c89aa5d32b5b0e1c0d5a2b79a19d67562f407f19425687971a957375879d90c5f57c857136c17106c9ab1b99d80e69c8c954ed386493368884b55c939b8d64d26f643e800c56f90c01079d7c534e3b2b7ae352cefd3016da55f6a85eb803b85e2304915fd2001f77c74e28746293c46e4f5f0fd49cf988aafd0026b8e7a3bab2da5cdce1ea26c2e29ec03f4807fac432662b2d6c060be1c7be0e5489de69d0a6e03a4b9117f9244b34a0f1ecba89884f781c6320412413a00c4980287409a2a78c2cd7e65cecebbe4ec1c28cac4dd95f6998e78fc6f1392384331c9436aa10e10e2bf8ad2c4eafbcf276aa7bae64b74428911b3269c749338b0fc5075ad", - ), - id="mod_vul_nagydani_5_qube", + # Ported from https://github.com/NethermindEth/nethermind/blob/ceb8d57b8530ce8181d7427c115ca593386909d6/tools/EngineRequestsGenerator/TestCases/ModexpVulnerability.cs#L154 + ( + "c5a1611f8be90071a43db23cc2fe01871cc4c0e8ab5743f6378e4fef77f7f6db0095c0727e20225beb665645403453e325ad5f9aeb9ba99bf3c148f63f9c07cf4fe8847ad5242d6b7d4499f93bd47056ddab8f7dee878fc2314f344dbee2a7c41a5d3db91eff372c730c2fdd3a141a4b61999e36d549b9870cf2f4e632c4d5df5f024f81c028000073a0ed8847cfb0593d36a47142f578f05ccbe28c0c06aeb1b1da027794c48db880278f79ba78ae64eedfea3c07d10e0562668d839749dc95f40467d15cf65b9cfc52c7c4bcef1cda3596dd52631aac942f146c7cebd46065131699ce8385b0db1874336747ee020a5698a3d1a1082665721e769567f579830f9d259cec1a836845109c21cf6b25da572512bf3c42fd4b96e43895589042ab60dd41f497db96aec102087fe784165bb45f942859268fd2ff6c012d9d00c02ba83eace047cc5f7b2c392c2955c58a49f0338d6fc58749c9db2155522ac17914ec216ad87f12e0ee95574613942fa615898c4d9e8a3be68cd6afa4e7a003dedbdf8edfee31162b174f965b20ae752ad89c967b3068b6f722c16b354456ba8e280f987c08e0a52d40a2e8f3a59b94d590aeef01879eb7a90b3ee7d772c839c85519cbeaddc0c193ec4874a463b53fcaea3271d80ebfb39b33489365fc039ae549a17a9ff898eea2f4cb27b8dbee4c17b998438575b2b8d107e4a0d66ba7fca85b41a58a8d51f191a35c856dfbe8aef2b00048a694bbccff832d23c8ca7a7ff0b6c0b3011d00b97c86c0628444d267c951d9e4fb8f83e154b8f74fb51aa16535e498235c5597dac9606ed0be3173a3836baa4e7d756ffe1e2879b415d3846bccd538c05b847785699aefde3e305decb600cd8fb0e7d8de5efc26971a6ad4e6d7a2d91474f1023a0ac4b78dc937da0ce607a45974d2cac1c33a2631ff7fe6144a3b2e5cf98b531a9627dea92c1dc82204d09db0439b6a11dd64b484e1263aa45fd9539b6020b55e3baece3986a8bffc1003406348f5c61265099ed43a766ee4f93f5f9c5abbc32a0fd3ac2b35b87f9ec26037d88275bd7dd0a54474995ee34ed3727f3f97c48db544b1980193a4b76a8a3ddab3591ce527f16d91882e67f0103b5cda53f7da54d489fc4ac08b6ab358a5a04aa9daa16219d50bd672a7cb804ed769d218807544e5993f1c27427104b349906a0b654df0bf69328afd3013fbe430155339c39f236df5557bf92f1ded7ff609a8502f49064ec3d1dbfb6c15d3a4c11a4f8acd12278cbf68acd5709463d12e3338a6eddb8c112f199645e23154a8e60879d2a654e3ed9296aa28f134168619691cd2c6b9e2eba4438381676173fc63c2588a3c5910dc149cf3760f0aa9fa9c3f5faa9162b0bf1aac9dd32b706a60ef53cbdb394b6b40222b5bc80eea82ba8958386672564cae3794f977871ab62337cf", + "010001", + "e30049201ec12937e7ce79d0f55d9c810e20acf52212aca1d3888949e0e4830aad88d804161230eb89d4d329cc83570fe257217d2119134048dd2ed167646975fc7d77136919a049ea74cf08ddd2b896890bb24a0ba18094a22baa351bf29ad96c66bbb1a598f2ca391749620e62d61c3561a7d3653ccc8892c7b99baaf76bf836e2991cb06d6bc0514568ff0d1ec8bb4b3d6984f5eaefb17d3ea2893722375d3ddb8e389a8eef7d7d198f8e687d6a513983df906099f9a2d23f4f9dec6f8ef2f11fc0a21fac45353b94e00486f5e17d386af42502d09db33cf0cf28310e049c07e88682aeeb00cb833c5174266e62407a57583f1f88b304b7c6e0c84bbe1c0fd423072d37a5bd0aacf764229e5c7cd02473460ba3645cd8e8ae144065bf02d0dd238593d8e230354f67e0b2f23012c23274f80e3ee31e35e2606a4a3f31d94ab755e6d163cff52cbb36b6d0cc67ffc512aeed1dce4d7a0d70ce82f2baba12e8d514dc92a056f994adfb17b5b9712bd5186f27a2fda1f7039c5df2c8587fdc62f5627580c13234b55be4df3056050e2d1ef3218f0dd66cb05265fe1acfb0989d8213f2c19d1735a7cf3fa65d88dad5af52dc2bba22b7abf46c3bc77b5091baab9e8f0ddc4d5e581037de91a9f8dcbc69309be29cc815cf19a20a7585b8b3073edf51fc9baeb3e509b97fa4ecfd621e0fd57bd61cac1b895c03248ff12bdbc57509250df3517e8a3fe1d776836b34ab352b973d932ef708b14f7418f9eceb1d87667e61e3e758649cb083f01b133d37ab2f5afa96d6c84bcacf4efc3851ad308c1e7d9113624fce29fab460ab9d2a48d92cdb281103a5250ad44cb2ff6e67ac670c02fdafb3e0f1353953d6d7d5646ca1568dea55275a050ec501b7c6250444f7219f1ba7521ba3b93d089727ca5f3bbe0d6c1300b423377004954c5628fdb65770b18ced5c9b23a4a5a6d6ef25fe01b4ce278de0bcc4ed86e28a0a68818ffa40970128cf2c38740e80037984428c1bd5113f40ff47512ee6f4e4d8f9b8e8e1b3040d2928d003bd1c1329dc885302fbce9fa81c23b4dc49c7c82d29b52957847898676c89aa5d32b5b0e1c0d5a2b79a19d67562f407f19425687971a957375879d90c5f57c857136c17106c9ab1b99d80e69c8c954ed386493368884b55c939b8d64d26f643e800c56f90c01079d7c534e3b2b7ae352cefd3016da55f6a85eb803b85e2304915fd2001f77c74e28746293c46e4f5f0fd49cf988aafd0026b8e7a3bab2da5cdce1ea26c2e29ec03f4807fac432662b2d6c060be1c7be0e5489de69d0a6e03a4b9117f9244b34a0f1ecba89884f781c6320412413a00c4980287409a2a78c2cd7e65cecebbe4ec1c28cac4dd95f6998e78fc6f1392384331c9436aa10e10e2bf8ad2c4eafbcf276aa7bae64b74428911b3269c749338b0fc5075ad", + "mod_vul_nagydani_5_pow_0x10001", ), - # Ported from - # https://github.com/NethermindEth/nethermind/blob/ceb8d57b8530ce8181d7427c115ca593386909d6/tools/EngineRequestsGenerator/TestCases/ModexpVulnerability.cs#L154 - pytest.param( - ModExpInput( - base="c5a1611f8be90071a43db23cc2fe01871cc4c0e8ab5743f6378e4fef77f7f6db0095c0727e20225beb665645403453e325ad5f9aeb9ba99bf3c148f63f9c07cf4fe8847ad5242d6b7d4499f93bd47056ddab8f7dee878fc2314f344dbee2a7c41a5d3db91eff372c730c2fdd3a141a4b61999e36d549b9870cf2f4e632c4d5df5f024f81c028000073a0ed8847cfb0593d36a47142f578f05ccbe28c0c06aeb1b1da027794c48db880278f79ba78ae64eedfea3c07d10e0562668d839749dc95f40467d15cf65b9cfc52c7c4bcef1cda3596dd52631aac942f146c7cebd46065131699ce8385b0db1874336747ee020a5698a3d1a1082665721e769567f579830f9d259cec1a836845109c21cf6b25da572512bf3c42fd4b96e43895589042ab60dd41f497db96aec102087fe784165bb45f942859268fd2ff6c012d9d00c02ba83eace047cc5f7b2c392c2955c58a49f0338d6fc58749c9db2155522ac17914ec216ad87f12e0ee95574613942fa615898c4d9e8a3be68cd6afa4e7a003dedbdf8edfee31162b174f965b20ae752ad89c967b3068b6f722c16b354456ba8e280f987c08e0a52d40a2e8f3a59b94d590aeef01879eb7a90b3ee7d772c839c85519cbeaddc0c193ec4874a463b53fcaea3271d80ebfb39b33489365fc039ae549a17a9ff898eea2f4cb27b8dbee4c17b998438575b2b8d107e4a0d66ba7fca85b41a58a8d51f191a35c856dfbe8aef2b00048a694bbccff832d23c8ca7a7ff0b6c0b3011d00b97c86c0628444d267c951d9e4fb8f83e154b8f74fb51aa16535e498235c5597dac9606ed0be3173a3836baa4e7d756ffe1e2879b415d3846bccd538c05b847785699aefde3e305decb600cd8fb0e7d8de5efc26971a6ad4e6d7a2d91474f1023a0ac4b78dc937da0ce607a45974d2cac1c33a2631ff7fe6144a3b2e5cf98b531a9627dea92c1dc82204d09db0439b6a11dd64b484e1263aa45fd9539b6020b55e3baece3986a8bffc1003406348f5c61265099ed43a766ee4f93f5f9c5abbc32a0fd3ac2b35b87f9ec26037d88275bd7dd0a54474995ee34ed3727f3f97c48db544b1980193a4b76a8a3ddab3591ce527f16d91882e67f0103b5cda53f7da54d489fc4ac08b6ab358a5a04aa9daa16219d50bd672a7cb804ed769d218807544e5993f1c27427104b349906a0b654df0bf69328afd3013fbe430155339c39f236df5557bf92f1ded7ff609a8502f49064ec3d1dbfb6c15d3a4c11a4f8acd12278cbf68acd5709463d12e3338a6eddb8c112f199645e23154a8e60879d2a654e3ed9296aa28f134168619691cd2c6b9e2eba4438381676173fc63c2588a3c5910dc149cf3760f0aa9fa9c3f5faa9162b0bf1aac9dd32b706a60ef53cbdb394b6b40222b5bc80eea82ba8958386672564cae3794f977871ab62337cf", - exponent="010001", - modulus="e30049201ec12937e7ce79d0f55d9c810e20acf52212aca1d3888949e0e4830aad88d804161230eb89d4d329cc83570fe257217d2119134048dd2ed167646975fc7d77136919a049ea74cf08ddd2b896890bb24a0ba18094a22baa351bf29ad96c66bbb1a598f2ca391749620e62d61c3561a7d3653ccc8892c7b99baaf76bf836e2991cb06d6bc0514568ff0d1ec8bb4b3d6984f5eaefb17d3ea2893722375d3ddb8e389a8eef7d7d198f8e687d6a513983df906099f9a2d23f4f9dec6f8ef2f11fc0a21fac45353b94e00486f5e17d386af42502d09db33cf0cf28310e049c07e88682aeeb00cb833c5174266e62407a57583f1f88b304b7c6e0c84bbe1c0fd423072d37a5bd0aacf764229e5c7cd02473460ba3645cd8e8ae144065bf02d0dd238593d8e230354f67e0b2f23012c23274f80e3ee31e35e2606a4a3f31d94ab755e6d163cff52cbb36b6d0cc67ffc512aeed1dce4d7a0d70ce82f2baba12e8d514dc92a056f994adfb17b5b9712bd5186f27a2fda1f7039c5df2c8587fdc62f5627580c13234b55be4df3056050e2d1ef3218f0dd66cb05265fe1acfb0989d8213f2c19d1735a7cf3fa65d88dad5af52dc2bba22b7abf46c3bc77b5091baab9e8f0ddc4d5e581037de91a9f8dcbc69309be29cc815cf19a20a7585b8b3073edf51fc9baeb3e509b97fa4ecfd621e0fd57bd61cac1b895c03248ff12bdbc57509250df3517e8a3fe1d776836b34ab352b973d932ef708b14f7418f9eceb1d87667e61e3e758649cb083f01b133d37ab2f5afa96d6c84bcacf4efc3851ad308c1e7d9113624fce29fab460ab9d2a48d92cdb281103a5250ad44cb2ff6e67ac670c02fdafb3e0f1353953d6d7d5646ca1568dea55275a050ec501b7c6250444f7219f1ba7521ba3b93d089727ca5f3bbe0d6c1300b423377004954c5628fdb65770b18ced5c9b23a4a5a6d6ef25fe01b4ce278de0bcc4ed86e28a0a68818ffa40970128cf2c38740e80037984428c1bd5113f40ff47512ee6f4e4d8f9b8e8e1b3040d2928d003bd1c1329dc885302fbce9fa81c23b4dc49c7c82d29b52957847898676c89aa5d32b5b0e1c0d5a2b79a19d67562f407f19425687971a957375879d90c5f57c857136c17106c9ab1b99d80e69c8c954ed386493368884b55c939b8d64d26f643e800c56f90c01079d7c534e3b2b7ae352cefd3016da55f6a85eb803b85e2304915fd2001f77c74e28746293c46e4f5f0fd49cf988aafd0026b8e7a3bab2da5cdce1ea26c2e29ec03f4807fac432662b2d6c060be1c7be0e5489de69d0a6e03a4b9117f9244b34a0f1ecba89884f781c6320412413a00c4980287409a2a78c2cd7e65cecebbe4ec1c28cac4dd95f6998e78fc6f1392384331c9436aa10e10e2bf8ad2c4eafbcf276aa7bae64b74428911b3269c749338b0fc5075ad", - ), - id="mod_vul_nagydani_5_pow_0x10001", + # Ported from https://github.com/NethermindEth/nethermind/blob/ceb8d57b8530ce8181d7427c115ca593386909d6/tools/EngineRequestsGenerator/TestCases/ModexpVulnerability.cs#L156 + ( + "ffffff", + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffe000007d7d7d83828282348286877d7d827d407d797d7d7d7d7d7d7d7d7d7d7d5b00000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000021000000000000000000000000000000000000000000000000000000000000000cffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff4000007d7d", + "7d83828282348286877d7d82", + "mod_vul_marius_1_even", ), - # Ported from - # https://github.com/NethermindEth/nethermind/blob/ceb8d57b8530ce8181d7427c115ca593386909d6/tools/EngineRequestsGenerator/TestCases/ModexpVulnerability.cs#L156 - pytest.param( - ModExpInput( - base="ffffff", - exponent="ffffffffffffffffffffffffffffffffffffffffffffffffffffffffe000007d7d7d83828282348286877d7d827d407d797d7d7d7d7d7d7d7d7d7d7d5b00000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000021000000000000000000000000000000000000000000000000000000000000000cffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff4000007d7d", - modulus="7d83828282348286877d7d82", - ), - id="mod_vul_marius_1_even", + # Ported from https://github.com/NethermindEth/nethermind/blob/ceb8d57b8530ce8181d7427c115ca593386909d6/tools/EngineRequestsGenerator/TestCases/ModexpVulnerability.cs#L158 + ( + "ffffffffffffffff76ffffffffffffff", + "1cffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c76ec7c7c7c7ffffffffffffffc7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7ffffffffffffc7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c76ec7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7ffff", + "ffffff3f000000000000000000000000", + "mod_vul_guido_1_even", ), - # Ported from - # https://github.com/NethermindEth/nethermind/blob/ceb8d57b8530ce8181d7427c115ca593386909d6/tools/EngineRequestsGenerator/TestCases/ModexpVulnerability.cs#L158 - pytest.param( - ModExpInput( - base="ffffffffffffffff76ffffffffffffff", - exponent="1cffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c76ec7c7c7c7ffffffffffffffc7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7ffffffffffffc7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c76ec7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7ffff", - modulus="ffffff3f000000000000000000000000", - ), - id="mod_vul_guido_1_even", + # Ported from https://github.com/NethermindEth/nethermind/blob/ceb8d57b8530ce8181d7427c115ca593386909d6/tools/EngineRequestsGenerator/TestCases/ModexpVulnerability.cs#L160 + ( + "e0060000a921212121212121ff000021", + "2b212121ffff1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f00feffff212121212121ffffffff1fe1e0e0e01e1f1f169f1f1f1f490afcefffffffffffffffff82828282828282828282828282828282828282828200ffff28ff2b212121ffff1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1fffffffffff0afceffffff7ffffffffff7c8282828282a1828282828282828282828282828200ffff28ff2b212121ffff1f1f1f1f1f1fd11f1f1f1f1f1f1f1f1f1f1fffffffffffffffff21212121212121fb2121212121ffff1f1f1f1f1f1f1f1fffaf", + "82828282828200ffff28ff2b21828200", + "mod_vul_guido_2_even", ), - # Ported from - # https://github.com/NethermindEth/nethermind/blob/ceb8d57b8530ce8181d7427c115ca593386909d6/tools/EngineRequestsGenerator/TestCases/ModexpVulnerability.cs#L160 - pytest.param( - ModExpInput( - base="e0060000a921212121212121ff000021", - exponent="2b212121ffff1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f00feffff212121212121ffffffff1fe1e0e0e01e1f1f169f1f1f1f490afcefffffffffffffffff82828282828282828282828282828282828282828200ffff28ff2b212121ffff1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1fffffffffff0afceffffff7ffffffffff7c8282828282a1828282828282828282828282828200ffff28ff2b212121ffff1f1f1f1f1f1fd11f1f1f1f1f1f1f1f1f1f1fffffffffffffffff21212121212121fb2121212121ffff1f1f1f1f1f1f1f1fffaf", - modulus="82828282828200ffff28ff2b21828200", - ), - id="mod_vul_guido_2_even", + # Ported from https://github.com/NethermindEth/nethermind/blob/ceb8d57b8530ce8181d7427c115ca593386909d6/tools/EngineRequestsGenerator/TestCases/ModexpVulnerability.cs#L162 + ( + "0193585a48e18aad777e9c1b54221a0f58140392e4f091cd5f42b2e8644a9384fbd58ae1edec2477ebf7edbf7c0a3f8bd21d1890ee87646feab3c47be716f842cc3da9b940af312dc54450a960e3fc0b86e56abddd154068e10571a96fff6259431632bc15695c6c8679057e66c2c25c127e97e64ee5de6ea1fc0a4a0e431343fed1daafa072c238a45841da86a9806680bc9f298411173210790359209cd454b5af7b4d5688b4403924e5f863d97e2c5349e1a04b54fcf385b1e9d7714bab8fbf5835f6ff9ed575e77dff7af5cbb641db5d537933bae1fa6555d6c12d6fb31ca27b57771f4aebfbe0bf95e8990c0108ffe7cbdaf370be52cf3ade594543af75ad9329d2d11a402270b5b9a6bf4b83307506e118fca4862749d04e916fc7a039f0d13f2a02e0eedb800199ec95df15b4ccd8669b52586879624d51219e72102fad810b5909b1e372ddf33888fb9beb09b416e4164966edbabd89e4a286be36277fc576ed519a15643dac602e92b63d0b9121f0491da5b16ef793a967f096d80b6c81ecaaffad7e3f06a4a5ac2796f1ed9f68e6a0fd5cf191f0c5c2eec338952ff8d31abc68bf760febeb57e088995ba1d7726a2fdd6d8ca28a181378b8b4ab699bfd4b696739bbf17a9eb2df6251143046137fdbbfacac312ebf67a67da9741b59600000000000", + "04", + "19a2917c61722b0713d3b00a2f0e1dd5aebbbe09615de424700eea3c3020fe6e9ea5de9fa1ace781df28b21f746d2ab61d0da496e08473c90ff7dfe25b43bcde76f4bafb82e0975bea75f5a0591dba80ba2fff80a07d8853bea5be13ab326ba70c57b153acc646151948d1cf061ca31b02d4719fac710e7c723ca44f5b1737824b7ccc74ba5bff980aabdbf267621cafc3d6dcc29d0ca9c16839a92ed34de136da7900aa3ee43d21aa57498981124357cf0ca9b86f9a8d3f9c604ca00c726e48f7a9945021ea6dfff92d6b2d6514693169ca133e993541bfa4c4c191de806aa80c48109bcfc9901eccfdeb2395ab75fe63c67de900829d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "mod_vul_guido_3_even", ), - # Ported from - # https://github.com/NethermindEth/nethermind/blob/ceb8d57b8530ce8181d7427c115ca593386909d6/tools/EngineRequestsGenerator/TestCases/ModexpVulnerability.cs#L162 - pytest.param( - ModExpInput( - base="0193585a48e18aad777e9c1b54221a0f58140392e4f091cd5f42b2e8644a9384fbd58ae1edec2477ebf7edbf7c0a3f8bd21d1890ee87646feab3c47be716f842cc3da9b940af312dc54450a960e3fc0b86e56abddd154068e10571a96fff6259431632bc15695c6c8679057e66c2c25c127e97e64ee5de6ea1fc0a4a0e431343fed1daafa072c238a45841da86a9806680bc9f298411173210790359209cd454b5af7b4d5688b4403924e5f863d97e2c5349e1a04b54fcf385b1e9d7714bab8fbf5835f6ff9ed575e77dff7af5cbb641db5d537933bae1fa6555d6c12d6fb31ca27b57771f4aebfbe0bf95e8990c0108ffe7cbdaf370be52cf3ade594543af75ad9329d2d11a402270b5b9a6bf4b83307506e118fca4862749d04e916fc7a039f0d13f2a02e0eedb800199ec95df15b4ccd8669b52586879624d51219e72102fad810b5909b1e372ddf33888fb9beb09b416e4164966edbabd89e4a286be36277fc576ed519a15643dac602e92b63d0b9121f0491da5b16ef793a967f096d80b6c81ecaaffad7e3f06a4a5ac2796f1ed9f68e6a0fd5cf191f0c5c2eec338952ff8d31abc68bf760febeb57e088995ba1d7726a2fdd6d8ca28a181378b8b4ab699bfd4b696739bbf17a9eb2df6251143046137fdbbfacac312ebf67a67da9741b59600000000000", - exponent="04", - modulus="19a2917c61722b0713d3b00a2f0e1dd5aebbbe09615de424700eea3c3020fe6e9ea5de9fa1ace781df28b21f746d2ab61d0da496e08473c90ff7dfe25b43bcde76f4bafb82e0975bea75f5a0591dba80ba2fff80a07d8853bea5be13ab326ba70c57b153acc646151948d1cf061ca31b02d4719fac710e7c723ca44f5b1737824b7ccc74ba5bff980aabdbf267621cafc3d6dcc29d0ca9c16839a92ed34de136da7900aa3ee43d21aa57498981124357cf0ca9b86f9a8d3f9c604ca00c726e48f7a9945021ea6dfff92d6b2d6514693169ca133e993541bfa4c4c191de806aa80c48109bcfc9901eccfdeb2395ab75fe63c67de900829d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - ), - id="mod_vul_guido_3_even", + # Ported from https://github.com/NethermindEth/nethermind/blob/ceb8d57b8530ce8181d7427c115ca593386909d6/tools/EngineRequestsGenerator/TestCases/ModexpVulnerability.cs#L166 + ( + "ffffffffffffffff", + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "ffffffffffffffff", + "mod_vul_pawel_1_exp_heavy", ), - # Ported from - # https://github.com/NethermindEth/nethermind/blob/ceb8d57b8530ce8181d7427c115ca593386909d6/tools/EngineRequestsGenerator/TestCases/ModexpVulnerability.cs#L166 - pytest.param( - ModExpInput( - base="ffffffffffffffff", - exponent="ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", - modulus="ffffffffffffffff", - ), - id="mod_vul_pawel_1_exp_heavy", + # Ported from https://github.com/NethermindEth/nethermind/blob/ceb8d57b8530ce8181d7427c115ca593386909d6/tools/EngineRequestsGenerator/TestCases/ModexpVulnerability.cs#L168 + ( + "ffffffffffffffffffffffffffffffff", + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "ffffffffffffffffffffffffffffffff", + "mod_vul_pawel_2_exp_heavy", ), - # Ported from - # https://github.com/NethermindEth/nethermind/blob/ceb8d57b8530ce8181d7427c115ca593386909d6/tools/EngineRequestsGenerator/TestCases/ModexpVulnerability.cs#L168 - pytest.param( - ModExpInput( - base="ffffffffffffffffffffffffffffffff", - exponent="ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", - modulus="ffffffffffffffffffffffffffffffff", - ), - id="mod_vul_pawel_2_exp_heavy", + # Ported from https://github.com/NethermindEth/nethermind/blob/ceb8d57b8530ce8181d7427c115ca593386909d6/tools/EngineRequestsGenerator/TestCases/ModexpVulnerability.cs#L170 + ( + "ffffffffffffffffffffffffffffffffffffffffffffffff", + "ffffffffffffffffffffffffffffffffffffffffff", + "ffffffffffffffffffffffffffffffffffffffffffffffff", + "mod_vul_pawel_3_exp_heavy", ), - # Ported from - # https://github.com/NethermindEth/nethermind/blob/ceb8d57b8530ce8181d7427c115ca593386909d6/tools/EngineRequestsGenerator/TestCases/ModexpVulnerability.cs#L170 - pytest.param( - ModExpInput( - base="ffffffffffffffffffffffffffffffffffffffffffffffff", - exponent="ffffffffffffffffffffffffffffffffffffffffff", - modulus="ffffffffffffffffffffffffffffffffffffffffffffffff", - ), - id="mod_vul_pawel_3_exp_heavy", + # Ported from https://github.com/NethermindEth/nethermind/blob/ceb8d57b8530ce8181d7427c115ca593386909d6/tools/EngineRequestsGenerator/TestCases/ModexpVulnerability.cs#L172 + ( + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "ffffffffffffffffffffffff", + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "mod_vul_pawel_4_exp_heavy", ), - pytest.param( - ModExpInput.from_bytes( - "000000000000000000000000000000000000000000000000000000000000001700000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000017bffffffffffffffffffffffffffffffffffffffffffffbffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffe" - ), - id="mod_vul_pawel_3_exp_8", + # Ported from https://github.com/NethermindEth/nethermind/blob/ceb8d57b8530ce8181d7427c115ca593386909d6/tools/EngineRequestsGenerator/TestCases/ModexpVulnerability.cs#L174 + ( + "29356abadad68ad986c416de6f620bda0e1818b589e84f853a97391694d35496", + "ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63254f", + "ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551", + "mod_vul_common_1360n1", ), - # Ported from - # https://github.com/NethermindEth/nethermind/blob/ceb8d57b8530ce8181d7427c115ca593386909d6/tools/EngineRequestsGenerator/TestCases/ModexpVulnerability.cs#L172 - pytest.param( - ModExpInput( - base="ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", - exponent="ffffffffffffffffffffffff", - modulus="ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", - ), - id="mod_vul_pawel_4_exp_heavy", + # Ported from https://github.com/NethermindEth/nethermind/blob/ceb8d57b8530ce8181d7427c115ca593386909d6/tools/EngineRequestsGenerator/TestCases/ModexpVulnerability.cs#L176 + ( + "d41afaeaea32f7409827761b68c41b6e535da4ede1f0800bfb4a6aed18394f6b", + "ffffffff00000001000000000000000000000000fffffffffffffffffffffffd", + "ffffffff00000001000000000000000000000000ffffffffffffffffffffffff", + "mod_vul_common_1360n2", ), - # Ported from - # https://github.com/NethermindEth/nethermind/blob/ceb8d57b8530ce8181d7427c115ca593386909d6/tools/EngineRequestsGenerator/TestCases/ModexpVulnerability.cs#L174 - pytest.param( - ModExpInput( - base="29356abadad68ad986c416de6f620bda0e1818b589e84f853a97391694d35496", - exponent="ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63254f", - modulus="ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551", - ), - id="mod_vul_common_1360n1", + # Ported from https://github.com/NethermindEth/nethermind/blob/ceb8d57b8530ce8181d7427c115ca593386909d6/tools/EngineRequestsGenerator/TestCases/ModexpVulnerability.cs#L178 + ( + "1a5be8fae3b3fda9ea329494ae8689c04fae4978ecccfa6a6bfb9f04b25846c0", + "30644e72e131a029b85045b68181585d2833e84879b9709143e1f593efffffff", + "30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001", + "mod_vul_common_1349n1", ), - # Ported from - # https://github.com/NethermindEth/nethermind/blob/ceb8d57b8530ce8181d7427c115ca593386909d6/tools/EngineRequestsGenerator/TestCases/ModexpVulnerability.cs#L176 - pytest.param( - ModExpInput( - base="d41afaeaea32f7409827761b68c41b6e535da4ede1f0800bfb4a6aed18394f6b", - exponent="ffffffff00000001000000000000000000000000fffffffffffffffffffffffd", - modulus="ffffffff00000001000000000000000000000000ffffffffffffffffffffffff", - ), - id="mod_vul_common_1360n2", + # Ported from https://github.com/NethermindEth/nethermind/blob/ceb8d57b8530ce8181d7427c115ca593386909d6/tools/EngineRequestsGenerator/TestCases/ModexpVulnerability.cs#L182 + ( + "0000000000000000000000000000000000000000000000000000000000000003", + "0000000001000000000000022000000000000000000000000000000000000000", + "0800000000000011000000000000000000000000000000000000000000000001", + "mod_vul_common_1152n1", ), - # Ported from - # https://github.com/NethermindEth/nethermind/blob/ceb8d57b8530ce8181d7427c115ca593386909d6/tools/EngineRequestsGenerator/TestCases/ModexpVulnerability.cs#L178 - pytest.param( - ModExpInput( - base="1a5be8fae3b3fda9ea329494ae8689c04fae4978ecccfa6a6bfb9f04b25846c0", - exponent="30644e72e131a029b85045b68181585d2833e84879b9709143e1f593efffffff", - modulus="30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001", - ), - id="mod_vul_common_1349n1", + # Ported from https://github.com/NethermindEth/nethermind/blob/ceb8d57b8530ce8181d7427c115ca593386909d6/tools/EngineRequestsGenerator/TestCases/ModexpVulnerability.cs#L184 + ( + "1fb473dd1171cf88116aa77ab3612c2c7d2cf466cc2386cc456130e2727c70b4", + "0000000000000000000000000000000000000000000000000000000001000000", + "30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001", + "mod_vul_common_200n1", ), - # Ported from - # https://github.com/NethermindEth/nethermind/blob/ceb8d57b8530ce8181d7427c115ca593386909d6/tools/EngineRequestsGenerator/TestCases/ModexpVulnerability.cs#L182 - pytest.param( - ModExpInput( - base="0000000000000000000000000000000000000000000000000000000000000003", - exponent="0000000001000000000000022000000000000000000000000000000000000000", - modulus="0800000000000011000000000000000000000000000000000000000000000001", - ), - id="mod_vul_common_1152n1", + # Ported from https://github.com/NethermindEth/nethermind/blob/ceb8d57b8530ce8181d7427c115ca593386909d6/tools/EngineRequestsGenerator/TestCases/ModexpVulnerability.cs#L186 + ( + "1951441010b2b95a6e47a6075066a50a036f5ba978c050f2821df86636c0facb", + "0000000000000000000000000000000000000000000000000000000000ffffff", + "30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001", + "mod_vul_common_200n2", ), - # Ported from - # https://github.com/NethermindEth/nethermind/blob/ceb8d57b8530ce8181d7427c115ca593386909d6/tools/EngineRequestsGenerator/TestCases/ModexpVulnerability.cs#L184 - pytest.param( - ModExpInput( - base="1fb473dd1171cf88116aa77ab3612c2c7d2cf466cc2386cc456130e2727c70b4", - exponent="0000000000000000000000000000000000000000000000000000000001000000", - modulus="30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001", - ), - id="mod_vul_common_200n1", + # Ported from https://github.com/NethermindEth/nethermind/blob/ceb8d57b8530ce8181d7427c115ca593386909d6/tools/EngineRequestsGenerator/TestCases/ModexpVulnerability.cs#L188 + ( + "288254ba43e713afbe36c9f03b54c00fae4c0a82df1cf165eb46a21c20a48ca2", + "0000000000000000000000000000000000000000000000000000000000ffffff", + "30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001", + "mod_vul_common_200n3", ), - # Ported from - # https://github.com/NethermindEth/nethermind/blob/ceb8d57b8530ce8181d7427c115ca593386909d6/tools/EngineRequestsGenerator/TestCases/ModexpVulnerability.cs#L186 - pytest.param( - ModExpInput( - base="1951441010b2b95a6e47a6075066a50a036f5ba978c050f2821df86636c0facb", - exponent="0000000000000000000000000000000000000000000000000000000000ffffff", - modulus="30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001", - ), - id="mod_vul_common_200n2", + ( + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe", + "mod_vul_zkevm_worst_case", ), - # Ported from - # https://github.com/NethermindEth/nethermind/blob/ceb8d57b8530ce8181d7427c115ca593386909d6/tools/EngineRequestsGenerator/TestCases/ModexpVulnerability.cs#L188 + ] + + special_cases = [ pytest.param( - ModExpInput( - base="288254ba43e713afbe36c9f03b54c00fae4c0a82df1cf165eb46a21c20a48ca2", - exponent="0000000000000000000000000000000000000000000000000000000000ffffff", - modulus="30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001", + ModExpInput.from_bytes( + "000000000000000000000000000000000000000000000000000000000000001700000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000017bffffffffffffffffffffffffffffffffffffffffffffbffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffe" ), - id="mod_vul_common_200n3", + id="mod_vul_pawel_3_exp_8", ), + ] + + regular_cases = [ pytest.param( ModExpInput( - base="ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", - exponent="ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", - modulus="fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe", + base=base, + exponent=exponent, + modulus=modulus, ), - id="mod_vul_zkevm_worst_case", - ), - ], + id=test_id, + ) + for base, exponent, modulus, test_id in test_cases + ] + + return regular_cases + special_cases + + +@pytest.mark.parametrize( + ["mod_exp_input"], + create_modexp_test_cases(), ) def test_worst_modexp( - state_test: StateTestFiller, + benchmark_test: BenchmarkTestFiller, pre: Alloc, fork: Fork, mod_exp_input: ModExpInput, @@ -1337,24 +745,16 @@ def test_worst_modexp( Test running a block with as many calls to the MODEXP (5) precompile as possible. All the calls have the same parametrized input. """ - # Skip the trailing zeros from the input to make EVM work even harder. - calldata = bytes(mod_exp_input).rstrip(b"\x00") - - code = code_loop_precompile_call( - Op.CALLDATACOPY(0, 0, Op.CALLDATASIZE), # Copy the input to the - # memory. - Op.POP(Op.STATICCALL(Op.GAS, 0x5, Op.PUSH0, Op.CALLDATASIZE, Op.PUSH0, Op.PUSH0)), - fork, + attack_block = Op.POP( + Op.STATICCALL(Op.GAS, 0x5, Op.PUSH0, Op.CALLDATASIZE, Op.PUSH0, Op.PUSH0) ) - tx = Transaction( - to=pre.deploy_contract(code=code), - gas_limit=gas_benchmark_value, - sender=pre.fund_eoa(), - input=calldata, - ) + tx = JumpLoopGenerator( + setup=Op.CALLDATACOPY(0, 0, Op.CALLDATASIZE), attack_block=attack_block + ).generate_transaction(pre, gas_benchmark_value, fork) + tx.data = Bytes(bytes(mod_exp_input).rstrip(b"\x00")) - state_test( + benchmark_test( pre=pre, post={}, tx=tx, @@ -1786,7 +1186,7 @@ def test_worst_modexp( ], ) def test_worst_precompile_fixed_cost( - state_test: StateTestFiller, + benchmark_test: BenchmarkTestFiller, pre: Alloc, fork: Fork, precompile_address: Address, @@ -1816,47 +1216,34 @@ def test_worst_precompile_fixed_cost( padding_length = (32 - (len(concatenated_bytes) % 32)) % 32 input_bytes = concatenated_bytes + b"\x00" * padding_length - calldata = Bytecode() + setup = Bytecode() for i in range(0, len(input_bytes), 32): chunk = input_bytes[i : i + 32] value_to_store = int.from_bytes(chunk, "big") - calldata += Op.MSTORE(i, value_to_store) + setup += Op.MSTORE(i, value_to_store) attack_block = Op.POP( Op.STATICCALL(Op.GAS, precompile_address, 0, len(concatenated_bytes), 0, 0) ) - code = code_loop_precompile_call(calldata, attack_block, fork) - code_address = pre.deploy_contract(code=bytes(code)) - - tx = Transaction( - to=code_address, - gas_limit=gas_benchmark_value, - sender=pre.fund_eoa(), - ) - state_test( + benchmark_test( pre=pre, post={}, - tx=tx, + code_generator=JumpLoopGenerator(setup=setup, attack_block=attack_block), ) def test_worst_jumps( - state_test: StateTestFiller, + benchmark_test: BenchmarkTestFiller, pre: Alloc, - gas_benchmark_value: int, ): """Test running a JUMP-intensive contract.""" - jumps_code = Op.JUMPDEST + Op.JUMP(Op.PUSH0) - jumps_address = pre.deploy_contract(jumps_code) - tx = Transaction( - to=jumps_address, - gas_limit=gas_benchmark_value, + to=pre.deploy_contract(code=(Op.JUMPDEST + Op.JUMP(Op.PUSH0))), sender=pre.fund_eoa(), ) - state_test( + benchmark_test( pre=pre, post={}, tx=tx, @@ -1864,64 +1251,37 @@ def test_worst_jumps( def test_worst_jumpi_fallthrough( - state_test: StateTestFiller, + benchmark_test: BenchmarkTestFiller, pre: Alloc, fork: Fork, - gas_benchmark_value: int, ): """Test running a JUMPI-intensive contract with fallthrough.""" - max_code_size = fork.max_code_size() - - def jumpi_seq(): - return Op.JUMPI(Op.PUSH0, Op.PUSH0) - - prefix_seq = Op.JUMPDEST - suffix_seq = Op.JUMP(Op.PUSH0) - bytes_per_seq = len(jumpi_seq()) - seqs_per_call = (max_code_size - len(prefix_seq) - len(suffix_seq)) // bytes_per_seq - - # Create and deploy the jumpi-intensive contract - jumpis_code = prefix_seq + jumpi_seq() * seqs_per_call + suffix_seq - assert len(jumpis_code) <= max_code_size - - jumpis_address = pre.deploy_contract(code=bytes(jumpis_code)) - - tx = Transaction( - to=jumpis_address, - gas_limit=gas_benchmark_value, - sender=pre.fund_eoa(), - ) - - state_test( + benchmark_test( pre=pre, post={}, - tx=tx, + code_generator=JumpLoopGenerator( + setup=Bytecode(), attack_block=Op.JUMPI(Op.PUSH0, Op.PUSH0) + ), ) def test_worst_jumpis( - state_test: StateTestFiller, + benchmark_test: BenchmarkTestFiller, pre: Alloc, - gas_benchmark_value: int, ): """Test running a JUMPI-intensive contract.""" - jumpi_code = Op.JUMPDEST + Op.JUMPI(Op.PUSH0, Op.NUMBER) - jumpi_address = pre.deploy_contract(jumpi_code) - tx = Transaction( - to=jumpi_address, - gas_limit=gas_benchmark_value, + to=pre.deploy_contract(code=(Op.JUMPDEST + Op.JUMPI(Op.PUSH0, Op.NUMBER))), sender=pre.fund_eoa(), ) - state_test( + benchmark_test( pre=pre, post={}, tx=tx, ) -@pytest.mark.slow def test_worst_jumpdests( benchmark_test: BenchmarkTestFiller, pre: Alloc, @@ -2083,7 +1443,7 @@ def test_worst_jumpdests( ids=lambda param: "" if isinstance(param, tuple) else param, ) def test_worst_binop_simple( - state_test: StateTestFiller, + benchmark_test: BenchmarkTestFiller, pre: Alloc, opcode: Op, fork: Fork, @@ -2095,25 +1455,17 @@ def test_worst_binop_simple( produces one value) as possible. The execution starts with two initial values on the stack, and the stack is balanced by the DUP2 instruction. """ - max_code_size = fork.max_code_size() - tx_data = b"".join(arg.to_bytes(32, byteorder="big") for arg in opcode_args) - code_prefix = Op.JUMPDEST + Op.CALLDATALOAD(0) + Op.CALLDATALOAD(32) - code_suffix = Op.POP + Op.POP + Op.PUSH0 + Op.JUMP - code_body_len = max_code_size - len(code_prefix) - len(code_suffix) - code_body = (Op.DUP2 + opcode) * (code_body_len // 2) - code = code_prefix + code_body + code_suffix - assert len(code) == max_code_size - 1 - - tx = Transaction( - to=pre.deploy_contract(code=code), - data=tx_data, - gas_limit=gas_benchmark_value, - sender=pre.fund_eoa(), - ) + setup = Op.CALLDATALOAD(0) + Op.CALLDATALOAD(32) + Op.DUP2 + Op.DUP2 + attack_block = Op.DUP2 + opcode + cleanup = Op.POP + Op.POP + tx = JumpLoopGenerator( + setup=setup, attack_block=attack_block, cleanup=cleanup + ).generate_transaction(pre, gas_benchmark_value, fork) + tx.data = Bytes(tx_data) - state_test( + benchmark_test( pre=pre, post={}, tx=tx, @@ -2122,35 +1474,21 @@ def test_worst_binop_simple( @pytest.mark.parametrize("opcode", [Op.ISZERO, Op.NOT]) def test_worst_unop( - state_test: StateTestFiller, + benchmark_test: BenchmarkTestFiller, pre: Alloc, opcode: Op, fork: Fork, - gas_benchmark_value: int, ): """ Test running a block with as many unary instructions (takes one arg, produces one value) as possible. """ - max_code_size = fork.max_code_size() - - code_prefix = Op.JUMPDEST + Op.PUSH0 # Start with the arg 0. - code_suffix = Op.POP + Op.PUSH0 + Op.JUMP - code_body_len = max_code_size - len(code_prefix) - len(code_suffix) - code_body = opcode * code_body_len - code = code_prefix + code_body + code_suffix - assert len(code) == max_code_size - - tx = Transaction( - to=pre.deploy_contract(code=code), - gas_limit=gas_benchmark_value, - sender=pre.fund_eoa(), - ) - - state_test( + benchmark_test( pre=pre, post={}, - tx=tx, + code_generator=JumpLoopGenerator( + setup=Op.PUSH0, attack_block=opcode, cleanup=Op.POP + Op.PUSH0 + ), ) @@ -2160,7 +1498,7 @@ def test_worst_unop( # key changes. @pytest.mark.parametrize("val_mut", [True, False]) def test_worst_tload( - state_test: StateTestFiller, + benchmark_test: BenchmarkTestFiller, fork: Fork, pre: Alloc, key_mut: bool, @@ -2168,43 +1506,31 @@ def test_worst_tload( gas_benchmark_value: int, ): """Test running a block with as many TLOAD calls as possible.""" - max_code_size = fork.max_code_size() - start_key = 41 code_key_mut = Bytecode() code_val_mut = Bytecode() + setup = Bytecode() if key_mut and val_mut: - code_prefix = Op.PUSH1(start_key) + Op.JUMPDEST - loop_iter = Op.POP(Op.TLOAD(Op.DUP1)) + setup = Op.PUSH1(start_key) + attack_block = Op.POP(Op.TLOAD(Op.DUP1)) code_key_mut = Op.POP + Op.GAS code_val_mut = Op.TSTORE(Op.DUP2, Op.GAS) if key_mut and not val_mut: - code_prefix = Op.JUMPDEST - loop_iter = Op.POP(Op.TLOAD(Op.GAS)) + attack_block = Op.POP(Op.TLOAD(Op.GAS)) if not key_mut and val_mut: - code_prefix = Op.JUMPDEST - loop_iter = Op.POP(Op.TLOAD(Op.CALLVALUE)) - code_val_mut = Op.TSTORE(Op.CALLVALUE, Op.GAS) # CALLVALUE configured - # in the tx + attack_block = Op.POP(Op.TLOAD(Op.CALLVALUE)) + code_val_mut = Op.TSTORE(Op.CALLVALUE, Op.GAS) # CALLVALUE configured in the tx if not key_mut and not val_mut: - code_prefix = Op.JUMPDEST - loop_iter = Op.POP(Op.TLOAD(Op.CALLVALUE)) - - code_suffix = code_key_mut + code_val_mut + Op.JUMP(len(code_prefix) - 1) + attack_block = Op.POP(Op.TLOAD(Op.CALLVALUE)) - code_body_len = (max_code_size - len(code_prefix) - len(code_suffix)) // len(loop_iter) - code_body = loop_iter * code_body_len - code = code_prefix + code_body + code_suffix - assert len(code) <= max_code_size + cleanup = code_key_mut + code_val_mut - tx = Transaction( - to=pre.deploy_contract(code), - gas_limit=gas_benchmark_value, - sender=pre.fund_eoa(), - value=start_key if not key_mut and val_mut else 0, - ) + tx = JumpLoopGenerator( + setup=setup, attack_block=attack_block, cleanup=cleanup + ).generate_transaction(pre, gas_benchmark_value, fork) + tx.value = HexNumber(start_key if not key_mut and val_mut else 0) - state_test( + benchmark_test( pre=pre, post={}, tx=tx, @@ -2214,49 +1540,34 @@ def test_worst_tload( @pytest.mark.parametrize("key_mut", [True, False]) @pytest.mark.parametrize("dense_val_mut", [True, False]) def test_worst_tstore( - state_test: StateTestFiller, - fork: Fork, + benchmark_test: BenchmarkTestFiller, pre: Alloc, key_mut: bool, dense_val_mut: bool, - gas_benchmark_value: int, ): """Test running a block with as many TSTORE calls as possible.""" - max_code_size = fork.max_code_size() - init_key = 42 - code_prefix = Op.PUSH1(init_key) + Op.JUMPDEST - - # If `key_mut` is True, we mutate the key on every iteration of the big - # loop. - code_key_mut = Op.POP + Op.GAS if key_mut else Bytecode() - code_suffix = code_key_mut + Op.JUMP(len(code_prefix) - 1) + setup = Op.PUSH1(init_key) - # If `dense_val_mut` is set, we use GAS as a cheap way of always storing a - # different value than the previous one. - loop_iter = Op.TSTORE(Op.DUP2, Op.GAS if dense_val_mut else Op.DUP1) - - code_body_len = (max_code_size - len(code_prefix) - len(code_suffix)) // len(loop_iter) - code_body = loop_iter * code_body_len - code = code_prefix + code_body + code_suffix - assert len(code) <= max_code_size + # If `dense_val_mut` is set, we use GAS as a cheap way of always + # storing a different value than + # the previous one. + attack_block = Op.TSTORE(Op.DUP2, Op.GAS if dense_val_mut else Op.DUP1) - tx = Transaction( - to=pre.deploy_contract(code), - gas_limit=gas_benchmark_value, - sender=pre.fund_eoa(), - ) + # If `key_mut` is True, we mutate the key on every iteration of the + # big loop. + cleanup = Op.POP + Op.GAS if key_mut else Bytecode() - state_test( + benchmark_test( pre=pre, post={}, - tx=tx, + code_generator=JumpLoopGenerator(setup=setup, attack_block=attack_block, cleanup=cleanup), ) @pytest.mark.parametrize("shift_right", [Op.SHR, Op.SAR]) def test_worst_shifts( - state_test: StateTestFiller, + benchmark_test: BenchmarkTestFiller, pre: Alloc, fork: Fork, shift_right: Op, @@ -2333,7 +1644,7 @@ def select_shift_amount(shift_fn, v): sender=pre.fund_eoa(), ) - state_test( + benchmark_test( pre=pre, post={}, tx=tx, @@ -2351,52 +1662,29 @@ def select_shift_amount(shift_fn, v): ) def test_worst_blobhash( fork: Fork, - state_test: StateTestFiller, + benchmark_test: BenchmarkTestFiller, pre: Alloc, blob_index: int, blobs_present: bool, gas_benchmark_value: int, ): """Test running a block with as many BLOBHASH instructions as possible.""" - max_code_size = fork.max_code_size() - max_stack_height = fork.max_stack_height() - - # Contract that contains a collection of BLOBHASH instructions. - opcode_sequence = Op.BLOBHASH(blob_index) * max_stack_height - assert len(opcode_sequence) <= max_code_size - - target_contract_address = pre.deploy_contract(code=opcode_sequence) - - # Contract that contains a loop of STATICCALLs to the target contract. - calldata = Bytecode() - attack_block = Op.POP(Op.STATICCALL(Op.GAS, target_contract_address, 0, 0, 0, 0)) - code = code_loop_precompile_call(calldata, attack_block, fork) - assert len(code) <= max_code_size - - code_address = pre.deploy_contract(code=code) + tx = ExtCallGenerator( + setup=Bytecode(), attack_block=Op.BLOBHASH(blob_index) + ).generate_transaction(pre, gas_benchmark_value, fork) - # Create blob transaction if blobs are present. - tx_type = TransactionType.LEGACY - blob_versioned_hashes = None - max_fee_per_blob_gas = None if blobs_present > 0: - tx_type = TransactionType.BLOB_TRANSACTION - max_fee_per_blob_gas = fork.min_base_fee_per_blob_gas() - blob_versioned_hashes = add_kzg_version( + tx.ty = HexNumber(TransactionType.BLOB_TRANSACTION) + tx.max_fee_per_blob_gas = HexNumber(fork.min_base_fee_per_blob_gas()) + tx.max_fee_per_gas = HexNumber(1000) + tx.max_priority_fee_per_gas = HexNumber(0) + tx.access_list = [] + tx.blob_versioned_hashes = add_kzg_version( [i.to_bytes() * 32 for i in range(blobs_present)], BlobsSpec.BLOB_COMMITMENT_VERSION_KZG, ) - tx = Transaction( - ty=tx_type, - to=code_address, - gas_limit=gas_benchmark_value, - max_fee_per_blob_gas=max_fee_per_blob_gas, - blob_versioned_hashes=blob_versioned_hashes, - sender=pre.fund_eoa(), - ) - - state_test( + benchmark_test( pre=pre, post={}, tx=tx, @@ -2406,7 +1694,7 @@ def test_worst_blobhash( @pytest.mark.parametrize("mod_bits", [255, 191, 127, 63]) @pytest.mark.parametrize("op", [Op.MOD, Op.SMOD]) def test_worst_mod( - state_test: StateTestFiller, + benchmark_test: BenchmarkTestFiller, pre: Alloc, fork: Fork, mod_bits: int, @@ -2428,11 +1716,11 @@ def test_worst_mod( The order of accessing the numerators is selected in a way the mod value remains in the range as long as possible. """ - max_code_size = fork.max_code_size() - - # For SMOD we negate both numerator and modulus. The underlying computation - # is the same, just the SMOD implementation will have to additionally - # handle the sign bits. The result stays negative. + # For SMOD we negate both numerator and modulus. The underlying + # computation is the same, + # just the SMOD implementation will have to additionally handle the + # sign bits. + # The result stays negative. should_negate = op == Op.SMOD num_numerators = 15 @@ -2503,32 +1791,21 @@ def test_worst_mod( seed += 1 print(f"{seed=}") - # TODO: Don't use fixed PUSH32. Let Bytecode helpers to select optimal push - # opcode. - code_constant_pool = sum((Op.PUSH32[n] for n in numerators), Bytecode()) - code_prefix = code_constant_pool + Op.JUMPDEST - code_suffix = Op.JUMP(len(code_constant_pool)) - code_body_len = max_code_size - len(code_prefix) - len(code_suffix) - code_segment = ( + # TODO: Don't use fixed PUSH32. Let Bytecode helpers to select optimal + # push opcode. + setup = sum((Op.PUSH32[n] for n in numerators), Bytecode()) + attack_block = ( Op.CALLDATALOAD(0) + sum(make_dup(len(numerators) - i) + op for i in indexes) + Op.POP ) - code = ( - code_prefix - # TODO: Add int * Bytecode support - + sum(code_segment for _ in range(code_body_len // len(code_segment))) - + code_suffix + + tx = JumpLoopGenerator(setup=setup, attack_block=attack_block).generate_transaction( + pre, gas_benchmark_value, fork ) - assert (max_code_size - len(code_segment)) < len(code) <= max_code_size input_value = initial_mod if not should_negate else neg(initial_mod) - tx = Transaction( - to=pre.deploy_contract(code=code), - data=input_value.to_bytes(32, byteorder="big"), - gas_limit=gas_benchmark_value, - sender=pre.fund_eoa(), - ) + tx.data = Bytes(input_value.to_bytes(32, byteorder="big")) - state_test( + benchmark_test( pre=pre, post={}, tx=tx, @@ -2540,50 +1817,34 @@ def test_worst_mod( @pytest.mark.parametrize("offset_initialized", [True, False]) @pytest.mark.parametrize("big_memory_expansion", [True, False]) def test_worst_memory_access( - state_test: StateTestFiller, + benchmark_test: BenchmarkTestFiller, pre: Alloc, - fork: Fork, opcode: Op, offset: int, offset_initialized: bool, big_memory_expansion: bool, - gas_benchmark_value: int, ): """ - Test running a block with as many memory access instructions as possible. + Test running a block with as many memory access instructions as + possible. """ - max_code_size = fork.max_code_size() - mem_exp_code = Op.MSTORE8(10 * 1024, 1) if big_memory_expansion else Bytecode() offset_set_code = Op.MSTORE(offset, 43) if offset_initialized else Bytecode() - code_prefix = mem_exp_code + offset_set_code + Op.PUSH1(42) + Op.PUSH1(offset) + Op.JUMPDEST + setup = mem_exp_code + offset_set_code + Op.PUSH1(42) + Op.PUSH1(offset) - code_suffix = Op.JUMP(len(code_prefix) - 1) - - loop_iter = Op.POP(Op.MLOAD(Op.DUP1)) if opcode == Op.MLOAD else opcode(Op.DUP2, Op.DUP2) - - code_body_len = (max_code_size - len(code_prefix) - len(code_suffix)) // len(loop_iter) - code_body = loop_iter * code_body_len - code = code_prefix + code_body + code_suffix - assert len(code) <= max_code_size - - tx = Transaction( - to=pre.deploy_contract(code=code), - gas_limit=gas_benchmark_value, - sender=pre.fund_eoa(), - ) + attack_block = Op.POP(Op.MLOAD(Op.DUP1)) if opcode == Op.MLOAD else opcode(Op.DUP2, Op.DUP2) - state_test( + benchmark_test( pre=pre, post={}, - tx=tx, + code_generator=JumpLoopGenerator(setup=setup, attack_block=attack_block), ) @pytest.mark.parametrize("mod_bits", [255, 191, 127, 63]) @pytest.mark.parametrize("op", [Op.ADDMOD, Op.MULMOD]) def test_worst_modarith( - state_test: StateTestFiller, + benchmark_test: BenchmarkTestFiller, pre: Alloc, fork: Fork, mod_bits: int, @@ -2682,7 +1943,7 @@ def test_worst_modarith( sender=pre.fund_eoa(), ) - state_test( + benchmark_test( pre=pre, post={}, tx=tx, @@ -2690,11 +1951,11 @@ def test_worst_modarith( def test_empty_block( - blockchain_test: BlockchainTestFiller, + benchmark_test: BenchmarkTestFiller, pre: Alloc, ): """Test running an empty block as a baseline for fixed proving costs.""" - blockchain_test( + benchmark_test( pre=pre, post={}, blocks=[Block(txs=[])], @@ -2703,7 +1964,7 @@ def test_empty_block( def test_amortized_bn128_pairings( - state_test: StateTestFiller, + benchmark_test: BenchmarkTestFiller, pre: Alloc, fork: Fork, gas_benchmark_value: int, @@ -2750,20 +2011,15 @@ def test_amortized_bn128_pairings( max_pairings = num_pairings_done optimal_per_call_num_pairings = i - calldata = Op.CALLDATACOPY(size=Op.CALLDATASIZE) + setup = Op.CALLDATACOPY(size=Op.CALLDATASIZE) attack_block = Op.POP(Op.STATICCALL(Op.GAS, 0x08, 0, Op.CALLDATASIZE, 0, 0)) - code = code_loop_precompile_call(calldata, attack_block, fork) - code_address = pre.deploy_contract(code=code) - - tx = Transaction( - to=code_address, - gas_limit=gas_benchmark_value, - data=_generate_bn128_pairs(optimal_per_call_num_pairings, 42), - sender=pre.fund_eoa(), + tx = JumpLoopGenerator(setup=setup, attack_block=attack_block).generate_transaction( + pre, gas_benchmark_value, fork ) + tx.data = _generate_bn128_pairs(optimal_per_call_num_pairings, 42) - state_test( + benchmark_test( pre=pre, post={}, tx=tx, @@ -2809,34 +2065,15 @@ def _generate_bn128_pairs(n: int, seed: int = 0): ], ) def test_worst_calldataload( - state_test: StateTestFiller, + benchmark_test: BenchmarkTestFiller, pre: Alloc, - fork: Fork, calldata: bytes, - gas_benchmark_value: int, ): """Test running a block with as many CALLDATALOAD as possible.""" - max_code_size = fork.max_code_size() - - code_prefix = Op.PUSH0 + Op.JUMPDEST - code_suffix = Op.PUSH1(1) + Op.JUMP - code_body_len = max_code_size - len(code_prefix) - len(code_suffix) - code_loop_iter = Op.CALLDATALOAD - code_body = code_loop_iter * (code_body_len // len(code_loop_iter)) - code = code_prefix + code_body + code_suffix - assert len(code) <= max_code_size - - tx = Transaction( - to=pre.deploy_contract(code=code), - data=calldata, - gas_limit=gas_benchmark_value, - sender=pre.fund_eoa(), - ) - - state_test( + benchmark_test( pre=pre, post={}, - tx=tx, + code_generator=JumpLoopGenerator(setup=Op.PUSH0, attack_block=Op.CALLDATALOAD), ) @@ -2898,36 +2135,24 @@ def test_worst_swap( ], ) def test_worst_dup( - state_test: StateTestFiller, + benchmark_test: BenchmarkTestFiller, pre: Alloc, fork: Fork, opcode: Op, - gas_benchmark_value: int, ): """Test running a block with as many DUP as possible.""" max_stack_height = fork.max_stack_height() min_stack_height = opcode.min_stack_height - code_prefix = Op.PUSH0 * min_stack_height - opcode_sequence = opcode * (max_stack_height - min_stack_height) - target_contract_address = pre.deploy_contract(code=code_prefix + opcode_sequence) + code = Op.PUSH0 * min_stack_height + opcode * (max_stack_height - min_stack_height) + target_contract_address = pre.deploy_contract(code=code) - calldata = Bytecode() attack_block = Op.POP(Op.STATICCALL(Op.GAS, target_contract_address, 0, 0, 0, 0)) - code = code_loop_precompile_call(calldata, attack_block, fork) - code_address = pre.deploy_contract(code=code) - - tx = Transaction( - to=code_address, - gas_limit=gas_benchmark_value, - sender=pre.fund_eoa(), - ) - - state_test( + benchmark_test( pre=pre, post={}, - tx=tx, + code_generator=JumpLoopGenerator(setup=Bytecode(), attack_block=attack_block), ) @@ -2970,33 +2195,17 @@ def test_worst_dup( ], ) def test_worst_push( - state_test: StateTestFiller, + benchmark_test: BenchmarkTestFiller, pre: Alloc, - fork: Fork, opcode: Op, - gas_benchmark_value: int, ): """Test running a block with as many PUSH as possible.""" - op = opcode[1] if opcode.has_data_portion() else opcode - opcode_sequence = op * fork.max_stack_height() - target_contract_address = pre.deploy_contract(code=opcode_sequence) - - calldata = Bytecode() - attack_block = Op.POP(Op.STATICCALL(Op.GAS, target_contract_address, 0, 0, 0, 0)) - - code = code_loop_precompile_call(calldata, attack_block, fork) - code_address = pre.deploy_contract(code=code) - - tx = Transaction( - to=code_address, - gas_limit=gas_benchmark_value, - sender=pre.fund_eoa(), - ) - - state_test( + benchmark_test( pre=pre, post={}, - tx=tx, + code_generator=ExtCallGenerator( + setup=Bytecode(), attack_block=opcode[1] if opcode.has_data_portion() else opcode + ), ) @@ -3015,7 +2224,7 @@ def test_worst_push( ], ) def test_worst_return_revert( - state_test: StateTestFiller, + benchmark_test: BenchmarkTestFiller, pre: Alloc, fork: Fork, opcode: Op, @@ -3044,78 +2253,45 @@ def test_worst_return_revert( code += Op.INVALID * (max_code_size - len(executable_code)) target_contract_address = pre.deploy_contract(code=code) - calldata = Bytecode() attack_block = Op.POP(Op.STATICCALL(address=target_contract_address)) - code = code_loop_precompile_call(calldata, attack_block, fork) - code_address = pre.deploy_contract(code=code) - tx = Transaction( - to=code_address, - gas_limit=gas_benchmark_value, - sender=pre.fund_eoa(), - ) - - state_test( + benchmark_test( pre=pre, post={}, - tx=tx, + code_generator=JumpLoopGenerator(setup=Bytecode(), attack_block=attack_block), ) @pytest.mark.valid_from("Osaka") def test_worst_clz_same_input( - blockchain_test: BlockchainTestFiller, + benchmark_test: BenchmarkTestFiller, pre: Alloc, fork: Fork, gas_benchmark_value: int, env: Environment, ): """Test running a block with as many CLZ with same input as possible.""" - tx_gas_limit = fork.transaction_gas_limit_cap() or env.gas_limit - magic_value = 248 # CLZ(248) = 248 - calldata = Op.PUSH1(magic_value) - attack_block = Op.CLZ - code = code_loop_precompile_call(calldata, attack_block, fork) - assert len(code) <= fork.max_code_size() - - code_address = pre.deploy_contract(code=code) - - sender = pre.fund_eoa() - tx_count = gas_benchmark_value // tx_gas_limit - remainder_gas = gas_benchmark_value % tx_gas_limit - - txs = [ - Transaction( - to=code_address, - gas_limit=tx_gas_limit if i < tx_count else remainder_gas, - nonce=i, - sender=sender, - ) - for i in range(tx_count + 1) - ] - - blockchain_test( - genesis_environment=env, + benchmark_test( pre=pre, post={}, - blocks=[Block(txs=txs)], + code_generator=JumpLoopGenerator(setup=Op.PUSH1(magic_value), attack_block=Op.CLZ), ) @pytest.mark.valid_from("Osaka") def test_worst_clz_diff_input( - blockchain_test: BlockchainTestFiller, + benchmark_test: BenchmarkTestFiller, pre: Alloc, fork: Fork, gas_benchmark_value: int, env: Environment, ): """ - Test running a block with as many CLZ with different input as possible. + Test running a block with as many CLZ with different input as + possible. """ - tx_gas_limit = fork.transaction_gas_limit_cap() or env.gas_limit max_code_size = fork.max_code_size() code_prefix = Op.JUMPDEST @@ -3135,24 +2311,13 @@ def test_worst_clz_diff_input( attack_code = code_prefix + code_seq + code_suffix assert len(attack_code) <= max_code_size - code_address = pre.deploy_contract(code=attack_code) - - sender = pre.fund_eoa() - tx_count = gas_benchmark_value // tx_gas_limit - remainder_gas = gas_benchmark_value % tx_gas_limit - txs = [ - Transaction( - to=code_address, - gas_limit=tx_gas_limit if i < tx_count else remainder_gas, - nonce=i, - sender=sender, - ) - for i in range(tx_count + 1) - ] + tx = Transaction( + to=pre.deploy_contract(code=attack_code), + sender=pre.fund_eoa(), + ) - blockchain_test( - genesis_environment=env, + benchmark_test( pre=pre, post={}, - blocks=[Block(txs=txs)], + tx=tx, ) diff --git a/tests/benchmark/test_worst_memory.py b/tests/benchmark/test_worst_memory.py index 689dcf06325..62bfa09aaab 100644 --- a/tests/benchmark/test_worst_memory.py +++ b/tests/benchmark/test_worst_memory.py @@ -2,20 +2,21 @@ Tests that benchmark EVMs in the worst-case memory opcodes. """ +from enum import auto + import pytest from ethereum_test_base_types.base_types import Bytes +from ethereum_test_benchmark.benchmark_code_generator import JumpLoopGenerator from ethereum_test_forks import Fork from ethereum_test_tools import ( Alloc, + BenchmarkTestFiller, Bytecode, - StateTestFiller, Transaction, ) from ethereum_test_vm import Opcodes as Op -from .helpers import code_loop_precompile_call - REFERENCE_SPEC_GIT_PATH = "TODO" REFERENCE_SPEC_VERSION = "TODO" @@ -23,8 +24,8 @@ class CallDataOrigin: """Enum for calldata origins.""" - TRANSACTION = 1 - CALL = 2 + TRANSACTION = auto() + CALL = auto() @pytest.mark.parametrize( @@ -58,7 +59,7 @@ class CallDataOrigin: ], ) def test_worst_calldatacopy( - state_test: StateTestFiller, + benchmark_test: BenchmarkTestFiller, pre: Alloc, fork: Fork, origin: CallDataOrigin, @@ -83,16 +84,20 @@ def test_worst_calldatacopy( # We create the contract that will be doing the CALLDATACOPY multiple # times. - # If `non_zero_data` is True, we leverage CALLDATASIZE for the copy length. - # Otherwise, since we don't send zero data explicitly via calldata, PUSH - # the target size and use DUP1 to copy it. - prefix = Bytecode() if non_zero_data or size == 0 else Op.PUSH3(size) + # + # If `non_zero_data` is True, we leverage CALLDATASIZE for the copy + # length. Otherwise, since we + # don't send zero data explicitly via calldata, PUSH the target size and + # use DUP1 to copy it. + setup = Bytecode() if non_zero_data or size == 0 else Op.PUSH3(size) src_dst = 0 if fixed_src_dst else Op.MOD(Op.GAS, 7) attack_block = Op.CALLDATACOPY( src_dst, src_dst, Op.CALLDATASIZE if non_zero_data or size == 0 else Op.DUP1 ) - code = code_loop_precompile_call(prefix, attack_block, fork) - code_address = pre.deploy_contract(code=code) + + code_address = JumpLoopGenerator(setup=setup, attack_block=attack_block).deploy_contracts( + pre, fork + ) tx_target = code_address @@ -101,15 +106,17 @@ def test_worst_calldatacopy( if origin == CallDataOrigin.CALL: # If `non_zero_data` is False we leverage just using zeroed memory. # Otherwise, we copy the calldata received from the transaction. - prefix = ( + setup = ( Op.CALLDATACOPY(Op.PUSH0, Op.PUSH0, Op.CALLDATASIZE) if non_zero_data else Bytecode() ) + Op.JUMPDEST arg_size = Op.CALLDATASIZE if non_zero_data else size - code = prefix + Op.STATICCALL( + attack_block = Op.STATICCALL( address=code_address, args_offset=Op.PUSH0, args_size=arg_size ) - code += Op.JUMP(len(prefix) - 1) - tx_target = pre.deploy_contract(code=code) + + tx_target = JumpLoopGenerator(setup=setup, attack_block=attack_block).deploy_contracts( + pre, fork + ) tx = Transaction( to=tx_target, @@ -118,7 +125,7 @@ def test_worst_calldatacopy( sender=pre.fund_eoa(), ) - state_test( + benchmark_test( pre=pre, post={}, tx=tx, @@ -143,38 +150,41 @@ def test_worst_calldatacopy( ], ) def test_worst_codecopy( - state_test: StateTestFiller, + benchmark_test: BenchmarkTestFiller, pre: Alloc, fork: Fork, max_code_size_ratio: float, fixed_src_dst: bool, - gas_benchmark_value: int, ): """Test running a block filled with CODECOPY executions.""" max_code_size = fork.max_code_size() size = int(max_code_size * max_code_size_ratio) - code_prefix = Op.PUSH32(size) + setup = Op.PUSH32(size) src_dst = 0 if fixed_src_dst else Op.MOD(Op.GAS, 7) attack_block = Op.CODECOPY(src_dst, src_dst, Op.DUP1) # DUP1 copies size. - code = code_loop_precompile_call(code_prefix, attack_block, fork) - # The code generated above is not guaranteed to be of max_code_size, so we - # pad it since a test parameter targets CODECOPYing a contract with max - # code size. Padded bytecode values are not relevant. - code = code + Op.INVALID * (max_code_size - len(code)) + code = JumpLoopGenerator(setup=setup, attack_block=attack_block).generate_repeated_code( + attack_block, Bytecode(), Bytecode(), fork + ) + + # The code generated above is not guaranteed to be of max_code_size, so + # we pad it since + # a test parameter targets CODECOPYing a contract with max code size. + # Padded bytecode values + # are not relevant. + code += Op.INVALID * (max_code_size - len(code)) assert len(code) == max_code_size, ( f"Code size {len(code)} is not equal to max code size {max_code_size}." ) tx = Transaction( to=pre.deploy_contract(code=code), - gas_limit=gas_benchmark_value, sender=pre.fund_eoa(), ) - state_test( + benchmark_test( pre=pre, post={}, tx=tx, @@ -198,20 +208,17 @@ def test_worst_codecopy( ], ) def test_worst_returndatacopy( - state_test: StateTestFiller, + benchmark_test: BenchmarkTestFiller, pre: Alloc, - fork: Fork, size: int, fixed_dst: bool, - gas_benchmark_value: int, ): """Test running a block filled with RETURNDATACOPY executions.""" - max_code_size = fork.max_code_size() - # Create the contract that will RETURN the data that will be used for - # RETURNDATACOPY. Random-ish data is injected at different points in memory - # to avoid making the content predictable. If `size` is 0, this helper - # contract won't be used. + # RETURNDATACOPY. + # Random-ish data is injected at different points in memory to avoid + # making the content + # predictable. If `size` is 0, this helper contract won't be used. code = ( Op.MSTORE8(0, Op.GAS) + Op.MSTORE8(size // 2, Op.GAS) @@ -220,14 +227,14 @@ def test_worst_returndatacopy( ) helper_contract = pre.deploy_contract(code=code) + returndata_gen = Op.STATICCALL(address=helper_contract) if size > 0 else Bytecode() + dst = 0 if fixed_dst else Op.MOD(Op.GAS, 7) + # We create the contract that will be doing the RETURNDATACOPY multiple # times. returndata_gen = Op.STATICCALL(address=helper_contract) if size > 0 else Bytecode() - dst = 0 if fixed_dst else Op.MOD(Op.GAS, 7) - attack_iter = Op.RETURNDATACOPY(dst, Op.PUSH0, Op.RETURNDATASIZE) + attack_block = Op.RETURNDATACOPY(dst, Op.PUSH0, Op.RETURNDATASIZE) - jumpdest = Op.JUMPDEST - jump_back = Op.JUMP(len(returndata_gen)) # The attack loop is constructed as: # ``` # JUMPDEST(#) @@ -238,31 +245,15 @@ def test_worst_returndatacopy( # JUMP(#) # ``` # The goal is that once per (big) loop iteration, the helper contract is - # called to generate fresh returndata to continue calling RETURNDATACOPY. - max_iters_loop = ( - max_code_size - 2 * len(returndata_gen) - len(jumpdest) - len(jump_back) - ) // len(attack_iter) - code = ( - returndata_gen - + jumpdest - + sum([attack_iter] * max_iters_loop) - + returndata_gen - + jump_back - ) - assert len(code) <= max_code_size, ( - f"Code size {len(code)} is not equal to max code size {max_code_size}." - ) - - tx = Transaction( - to=pre.deploy_contract(code=code), - gas_limit=gas_benchmark_value, - sender=pre.fund_eoa(), - ) + # called to + # generate fresh returndata to continue calling RETURNDATACOPY. - state_test( + benchmark_test( pre=pre, post={}, - tx=tx, + code_generator=JumpLoopGenerator( + setup=returndata_gen, attack_block=attack_block, cleanup=returndata_gen + ), ) @@ -283,42 +274,24 @@ def test_worst_returndatacopy( ], ) def test_worst_mcopy( - state_test: StateTestFiller, + benchmark_test: BenchmarkTestFiller, pre: Alloc, - fork: Fork, size: int, fixed_src_dst: bool, - gas_benchmark_value: int, ): """Test running a block filled with MCOPY executions.""" - max_code_size = fork.max_code_size() + src_dst = 0 if fixed_src_dst else Op.MOD(Op.GAS, 7) + attack_block = Op.MCOPY(src_dst, src_dst, size) mem_touch = ( Op.MSTORE8(0, Op.GAS) + Op.MSTORE8(size // 2, Op.GAS) + Op.MSTORE8(size - 1, Op.GAS) if size > 0 else Bytecode() ) - src_dst = 0 if fixed_src_dst else Op.MOD(Op.GAS, 7) - attack_block = Op.MCOPY(src_dst, src_dst, size) - - jumpdest = Op.JUMPDEST - jump_back = Op.JUMP(len(mem_touch)) - max_iters_loop = (max_code_size - 2 * len(mem_touch) - len(jumpdest) - len(jump_back)) // len( - attack_block - ) - code = mem_touch + jumpdest + sum([attack_block] * max_iters_loop) + mem_touch + jump_back - assert len(code) <= max_code_size, ( - f"Code size {len(code)} is not equal to max code size {max_code_size}." - ) - - tx = Transaction( - to=pre.deploy_contract(code=code), - gas_limit=gas_benchmark_value, - sender=pre.fund_eoa(), - ) - - state_test( + benchmark_test( pre=pre, post={}, - tx=tx, + code_generator=JumpLoopGenerator( + setup=mem_touch, attack_block=attack_block, cleanup=mem_touch + ), ) diff --git a/tests/benchmark/test_worst_opcode.py b/tests/benchmark/test_worst_opcode.py index 9ee805a628b..82479d4c9ec 100644 --- a/tests/benchmark/test_worst_opcode.py +++ b/tests/benchmark/test_worst_opcode.py @@ -4,18 +4,15 @@ import pytest -from ethereum_test_forks import Fork +from ethereum_test_benchmark.benchmark_code_generator import JumpLoopGenerator from ethereum_test_tools import ( Alloc, + BenchmarkTestFiller, Bytecode, - StateTestFiller, - Transaction, ) from ethereum_test_vm import Opcode from ethereum_test_vm import Opcodes as Op -from .helpers import code_loop_precompile_call - @pytest.mark.parametrize( "opcode", @@ -40,30 +37,26 @@ ) @pytest.mark.parametrize("fixed_offset", [True, False]) def test_worst_log_opcodes( - state_test: StateTestFiller, + benchmark_test: BenchmarkTestFiller, pre: Alloc, - fork: Fork, opcode: Opcode, zeros_topic: bool, size: int, fixed_offset: bool, non_zero_data: bool, - gas_benchmark_value: int, ): """Test running a block with as many LOG opcodes as possible.""" - max_code_size = fork.max_code_size() - - calldata = Bytecode() + setup = Bytecode() # For non-zero data, load into memory. if non_zero_data: - calldata += Op.CODECOPY(dest_offset=0, offset=0, size=Op.CODESIZE) + setup += Op.CODECOPY(dest_offset=0, offset=0, size=Op.CODESIZE) # Push the size value onto the stack and access it using the DUP opcode. - calldata += Op.PUSH3(size) + setup += Op.PUSH3(size) # For non-zeros topic, push a non-zero value for topic. - calldata += Op.PUSH0 if zeros_topic else Op.PUSH32(2**256 - 1) + setup += Op.PUSH0 if zeros_topic else Op.PUSH32(2**256 - 1) topic_count = len(opcode.kwargs or []) - 2 offset = Op.PUSH0 if fixed_offset else Op.MOD(Op.GAS, 7) @@ -72,21 +65,10 @@ def test_worst_log_opcodes( # 0 topics -> DUP1, 1 topic -> DUP2, N topics -> DUP(N+1) size_op = getattr(Op, f"DUP{topic_count + 2}") - code_sequence = Op.DUP1 * topic_count + size_op + offset + opcode - - code = code_loop_precompile_call(calldata, code_sequence, fork) - assert len(code) <= max_code_size - - code_address = pre.deploy_contract(code=code) - - tx = Transaction( - to=code_address, - gas_limit=gas_benchmark_value, - sender=pre.fund_eoa(), - ) + attack_block = Op.DUP1 * topic_count + size_op + offset + opcode - state_test( + benchmark_test( pre=pre, post={}, - tx=tx, + code_generator=JumpLoopGenerator(setup=setup, attack_block=attack_block), ) diff --git a/tests/benchmark/test_worst_stateful_opcodes.py b/tests/benchmark/test_worst_stateful_opcodes.py index f5cd6c0289f..eaf24cd0844 100644 --- a/tests/benchmark/test_worst_stateful_opcodes.py +++ b/tests/benchmark/test_worst_stateful_opcodes.py @@ -3,20 +3,23 @@ """ import math +from enum import auto import pytest +from ethereum_test_base_types import HexNumber +from ethereum_test_benchmark.benchmark_code_generator import ExtCallGenerator, JumpLoopGenerator from ethereum_test_forks import Fork +from ethereum_test_specs import StateTestFiller +from ethereum_test_specs.benchmark import BenchmarkTestFiller from ethereum_test_tools import ( Account, Address, Alloc, Block, - BlockchainTestFiller, Bytecode, Environment, Hash, - StateTestFiller, Transaction, While, compute_create2_address, @@ -24,8 +27,6 @@ ) from ethereum_test_vm import Opcodes as Op -from .helpers import code_loop_precompile_call - REFERENCE_SPEC_GIT_PATH = "TODO" REFERENCE_SPEC_VERSION = "TODO" @@ -44,7 +45,7 @@ ], ) def test_worst_address_state_cold( - blockchain_test: BlockchainTestFiller, + benchmark_test: BenchmarkTestFiller, pre: Alloc, fork: Fork, opcode: Op, @@ -107,11 +108,10 @@ def test_worst_address_state_cold( ) blocks.append(Block(txs=[op_tx])) - blockchain_test( + benchmark_test( pre=pre, post=post, blocks=blocks, - exclude_full_post_state_in_output=True, ) @@ -135,20 +135,15 @@ def test_worst_address_state_cold( ], ) def test_worst_address_state_warm( - state_test: StateTestFiller, + benchmark_test: BenchmarkTestFiller, pre: Alloc, - fork: Fork, opcode: Op, absent_target: bool, - gas_benchmark_value: int, ): """ - Test running a block with as many stateful opcodes doing warm access for an - account. + Test running a block with as many stateful opcodes doing warm access + for an account. """ - max_code_size = fork.max_code_size() - attack_gas_limit = gas_benchmark_value - # Setup target_addr = Address(100_000) post = {} @@ -158,45 +153,29 @@ def test_worst_address_state_warm( post[target_addr] = Account(balance=100, code=code) # Execution - prep = Op.MSTORE(0, target_addr) - jumpdest = Op.JUMPDEST - jump_back = Op.JUMP(len(prep)) - iter_block = Op.POP(opcode(address=Op.MLOAD(0))) - max_iters_loop = (max_code_size - len(prep) - len(jumpdest) - len(jump_back)) // len( - iter_block - ) - op_code = prep + jumpdest + sum([iter_block] * max_iters_loop) + jump_back - if len(op_code) > max_code_size: - # Must never happen, but keep it as a sanity check. - raise ValueError(f"Code size {len(op_code)} exceeds maximum code size {max_code_size}") - op_address = pre.deploy_contract(code=op_code) - tx = Transaction( - to=op_address, - gas_limit=attack_gas_limit, - sender=pre.fund_eoa(), - ) - - state_test( + setup = Op.MSTORE(0, target_addr) + attack_block = Op.POP(opcode(address=Op.MLOAD(0))) + benchmark_test( pre=pre, post=post, - tx=tx, + code_generator=JumpLoopGenerator(setup=setup, attack_block=attack_block), ) class StorageAction: """Enum for storage actions.""" - READ = 1 - WRITE_SAME_VALUE = 2 - WRITE_NEW_VALUE = 3 + READ = auto() + WRITE_SAME_VALUE = auto() + WRITE_NEW_VALUE = auto() class TransactionResult: """Enum for the possible transaction outcomes.""" - SUCCESS = 1 - OUT_OF_GAS = 2 - REVERT = 3 + SUCCESS = auto() + OUT_OF_GAS = auto() + REVERT = auto() @pytest.mark.parametrize( @@ -247,7 +226,7 @@ class TransactionResult: ], ) def test_worst_storage_access_cold( - blockchain_test: BlockchainTestFiller, + benchmark_test: BenchmarkTestFiller, pre: Alloc, fork: Fork, storage_action: StorageAction, @@ -261,7 +240,6 @@ def test_worst_storage_access_cold( """ gas_costs = fork.gas_costs() intrinsic_gas_cost_calc = fork.transaction_intrinsic_cost_calculator() - attack_gas_limit = gas_benchmark_value loop_cost = gas_costs.G_COLD_SLOAD # All accesses are always cold if storage_action == StorageAction.WRITE_NEW_VALUE: @@ -311,7 +289,7 @@ def test_worst_storage_access_cold( ) num_target_slots = ( - attack_gas_limit - intrinsic_gas_cost_calc() - prefix_cost - suffix_cost + gas_benchmark_value - intrinsic_gas_cost_calc() - prefix_cost - suffix_cost ) // loop_cost if tx_result == TransactionResult.OUT_OF_GAS: # Add an extra slot to make it run out-of-gas @@ -369,18 +347,17 @@ def test_worst_storage_access_cold( op_tx = Transaction( to=contract_address, - gas_limit=attack_gas_limit, + gas_limit=gas_benchmark_value, sender=pre.fund_eoa(), ) blocks.append(Block(txs=[op_tx])) - blockchain_test( + benchmark_test( pre=pre, post={}, blocks=blocks, - exclude_full_post_state_in_output=True, expected_benchmark_gas_used=( - total_gas_used if tx_result != TransactionResult.OUT_OF_GAS else attack_gas_limit + total_gas_used if tx_result != TransactionResult.OUT_OF_GAS else gas_benchmark_value ), ) @@ -394,17 +371,16 @@ def test_worst_storage_access_cold( ], ) def test_worst_storage_access_warm( - blockchain_test: BlockchainTestFiller, + benchmark_test: BenchmarkTestFiller, pre: Alloc, storage_action: StorageAction, - env: Environment, gas_benchmark_value: int, + env: Environment, ): """ - Test running a block with as many warm storage slot accesses as possible. + Test running a block with as many warm storage slot accesses as + possible. """ - attack_gas_limit = gas_benchmark_value - blocks = [] # The target storage slot for the warm access is storage slot 0. @@ -447,12 +423,12 @@ def test_worst_storage_access_warm( op_tx = Transaction( to=contract_address, - gas_limit=attack_gas_limit, + gas_limit=gas_benchmark_value, sender=pre.fund_eoa(), ) blocks.append(Block(txs=[op_tx])) - blockchain_test( + benchmark_test( pre=pre, post={}, blocks=blocks, @@ -460,9 +436,11 @@ def test_worst_storage_access_warm( def test_worst_blockhash( - blockchain_test: BlockchainTestFiller, + benchmark_test: BenchmarkTestFiller, pre: Alloc, + fork: Fork, gas_benchmark_value: int, + tx_gas_limit_cap: int, ): """ Test running a block with as many blockhash accessing oldest allowed block @@ -471,55 +449,46 @@ def test_worst_blockhash( # Create 256 dummy blocks to fill the blockhash window. blocks = [Block()] * 256 - # Always ask for the oldest allowed BLOCKHASH block. - execution_code = Op.PUSH1(1) + While( - body=Op.POP(Op.BLOCKHASH(Op.DUP1)), - ) - execution_code_address = pre.deploy_contract(code=execution_code) - op_tx = Transaction( - to=execution_code_address, - gas_limit=gas_benchmark_value, - sender=pre.fund_eoa(), + code = ExtCallGenerator(setup=Bytecode(), attack_block=Op.BLOCKHASH(1)).generate_repeated_code( + repeated_code=Op.BLOCKHASH(1), + setup=Bytecode(), + cleanup=Bytecode(), + fork=fork, ) - blocks.append(Block(txs=[op_tx])) - blockchain_test( + iteration_count = math.ceil(gas_benchmark_value / tx_gas_limit_cap) + code_address = pre.deploy_contract(code=code) + + gas_remaining = gas_benchmark_value + txs = [] + for _ in range(iteration_count): + tx_gas_limit = min(tx_gas_limit_cap, gas_remaining) + gas_remaining -= tx_gas_limit + tx = Transaction( + to=code_address, + gas_limit=HexNumber(tx_gas_limit), + sender=pre.fund_eoa(), + ) + txs.append(tx) + blocks.append(Block(txs=txs)) + + benchmark_test( pre=pre, post={}, blocks=blocks, + expected_benchmark_gas_used=gas_benchmark_value, ) def test_worst_selfbalance( - state_test: StateTestFiller, + benchmark_test: BenchmarkTestFiller, pre: Alloc, - fork: Fork, - gas_benchmark_value: int, ): """Test running a block with as many SELFBALANCE opcodes as possible.""" - max_stack_height = fork.max_stack_height() - - code_sequence = Op.SELFBALANCE * max_stack_height - target_address = pre.deploy_contract(code=code_sequence) - - calldata = Bytecode() - attack_block = Op.POP(Op.STATICCALL(Op.GAS, target_address, 0, 0, 0, 0)) - - code = code_loop_precompile_call(calldata, attack_block, fork) - assert len(code) <= fork.max_code_size() - - code_address = pre.deploy_contract(code=code) - - tx = Transaction( - to=code_address, - gas_limit=gas_benchmark_value, - sender=pre.fund_eoa(), - ) - - state_test( + benchmark_test( pre=pre, post={}, - tx=tx, + code_generator=ExtCallGenerator(setup=Bytecode(), attack_block=Op.SELFBALANCE), ) @@ -532,7 +501,7 @@ def test_worst_selfbalance( ], ) def test_worst_extcodecopy_warm( - state_test: StateTestFiller, + benchmark_test: BenchmarkTestFiller, pre: Alloc, copied_size: int, gas_benchmark_value: int, @@ -556,7 +525,7 @@ def test_worst_extcodecopy_warm( sender=pre.fund_eoa(), ) - state_test( + benchmark_test( pre=pre, post={}, tx=tx, @@ -565,7 +534,7 @@ def test_worst_extcodecopy_warm( @pytest.mark.parametrize("value_bearing", [True, False]) def test_worst_selfdestruct_existing( - blockchain_test: BlockchainTestFiller, + benchmark_test: BenchmarkTestFiller, fork: Fork, pre: Alloc, value_bearing: bool, @@ -696,14 +665,13 @@ def test_worst_selfdestruct_existing( post[deployed_contract_address] = Account(nonce=1) deployed_contract_addresses.append(deployed_contract_address) - blockchain_test( + benchmark_test( pre=pre, post=post, blocks=[ Block(txs=[contracts_deployment_tx]), Block(txs=[opcode_tx], fee_recipient=fee_recipient), ], - exclude_full_post_state_in_output=True, expected_benchmark_gas_used=expected_benchmark_gas_used, ) @@ -800,7 +768,6 @@ def test_worst_selfdestruct_created( post = {code_addr: Account(storage={0: 42})} # Check for successful # execution. state_test( - env=env, pre=pre, post=post, tx=code_tx, @@ -886,7 +853,6 @@ def test_worst_selfdestruct_initcode( post = {code_addr: Account(storage={0: 42})} # Check for successful # execution. state_test( - env=env, pre=pre, post=post, tx=code_tx,