Skip to content

Commit e4a764c

Browse files
authored
feat(tests): Test 256verify modular comparison (ethereum#2015)
* Test modular comparison * Fix lint issues, add to changelog * Add correct test case
1 parent 3287611 commit e4a764c

File tree

2 files changed

+51
-0
lines changed

2 files changed

+51
-0
lines changed

docs/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ Users can select any of the artifacts depending on their testing needs for their
129129

130130
### 🧪 Test Cases
131131

132+
-[EIP-7951](https://eips.ethereum.org/EIPS/eip-7951): Add additional test cases for modular comparison.
132133
- 🔀 Refactored `BLOBHASH` opcode context tests to use the `pre_alloc` plugin in order to avoid contract and EOA address collisions ([#1637](https://github.com/ethereum/execution-spec-tests/pull/1637)).
133134
- 🔀 Refactored `SELFDESTRUCT` opcode collision tests to use the `pre_alloc` plugin in order to avoid contract and EOA address collisions ([#1643](https://github.com/ethereum/execution-spec-tests/pull/1643)).
134135
- ✨ EIP-7594: Sanity test cases to send blob transactions and verify `engine_getBlobsVX` using the `execute` command ([#1644](https://github.com/ethereum/execution-spec-tests/pull/1644),[#1884](https://github.com/ethereum/execution-spec-tests/pull/1884)).

tests/osaka/eip7951_p256verify_precompiles/test_p256verify.py

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,3 +185,53 @@ def test_precompile_as_tx_entry_point(
185185
):
186186
"""Test P256Verify precompile entry point."""
187187
state_test(env=Environment(), pre=pre, post=post, tx=tx)
188+
189+
190+
@pytest.mark.parametrize(
191+
"input_data,expected_output",
192+
[
193+
# Test case where computed x-coordinate exceeds curve order N
194+
# This tests the modular comparison: r' ≡ r (mod N)
195+
pytest.param(
196+
Spec.H0
197+
# R: A value that when used in ECDSA verification produces an x-coordinate > N
198+
+ R(0x000000000000000000000000000000004319055358E8617B0C46353D039CDAAB)
199+
+ S(0xFFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC63254E)
200+
# X, Y: Public key coordinates that will produce x-coordinate > N during verification
201+
+ X(0x0AD99500288D466940031D72A9F5445A4D43784640855BF0A69874D2DE5FE103)
202+
+ Y(0xC5011E6EF2C42DCD50D5D3D29F99AE6EBA2C80C9244F4C5422F0979FF0C3BA5E),
203+
Spec.SUCCESS_RETURN_VALUE,
204+
id="modular_comparison_x_coordinate_exceeds_n",
205+
),
206+
pytest.param(
207+
Spec.H0
208+
+ R(Spec.N + 1) # R = N + 1 ≡ 1 (mod N)
209+
+ Spec.S0
210+
+ Spec.X0
211+
+ Spec.Y0,
212+
Spec.INVALID_RETURN_VALUE, # Should fail because R = 1 is not a valid signature
213+
id="r_equals_n_plus_one",
214+
),
215+
pytest.param(
216+
Spec.H0
217+
+ R(Spec.N + 2) # R = N + 2 ≡ 2 (mod N)
218+
+ Spec.S0
219+
+ Spec.X0
220+
+ Spec.Y0,
221+
Spec.INVALID_RETURN_VALUE, # Should fail because R = 2 is not a valid signature
222+
id="r_equals_n_plus_two",
223+
),
224+
],
225+
)
226+
@pytest.mark.parametrize("precompile_address", [Spec.P256VERIFY], ids=[""])
227+
@pytest.mark.eip_checklist("precompile/test/inputs/valid")
228+
@pytest.mark.eip_checklist("precompile/test/inputs/invalid/crypto")
229+
def test_modular_comparison(state_test: StateTestFiller, pre: Alloc, post: dict, tx: Transaction):
230+
"""
231+
Test the modular comparison condition for secp256r1 precompile.
232+
233+
This tests that when the x-coordinate of R' exceeds the curve order N,
234+
the verification should use modular arithmetic:
235+
r' ≡ r (mod N) instead of direct equality r' == r.
236+
"""
237+
state_test(env=Environment(), pre=pre, post=post, tx=tx)

0 commit comments

Comments
 (0)