Skip to content

Commit 1965e8d

Browse files
committed
feat(tests): bls12 g1add/g2add extra coverage 1.
1 parent 1eb0e99 commit 1965e8d

File tree

5 files changed

+333
-51
lines changed

5 files changed

+333
-51
lines changed

Diff for: tests/prague/eip2537_bls_12_381_precompiles/conftest.py

+34-7
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
"""Shared pytest definitions local to EIP-2537 tests."""
22

3-
from typing import SupportsBytes
3+
from typing import List, SupportsBytes
44

55
import pytest
66

@@ -191,11 +191,38 @@ def tx(
191191

192192

193193
# Fixed boundary G1 points
194-
G1_POINT_NEAR_P: PointG1 = BLSPointGenerator.generate_g1_point_in_subgroup_by_x(Spec.P - 100)
195-
G1_POINT_NEAR_ZERO: PointG1 = BLSPointGenerator.generate_g1_point_in_subgroup_by_x(0)
196-
G1_POINT_SMALL_X: PointG1 = BLSPointGenerator.generate_g1_point_in_subgroup_by_x(3)
194+
# G1_POINT_NEAR_P: PointG1 = BLSPointGenerator.generate_g1_point_in_subgroup_by_x(Spec.P - 100)
195+
# G1_POINT_NEAR_ZERO: PointG1 = BLSPointGenerator.generate_g1_point_in_subgroup_by_x(0)
196+
# G1_POINT_SMALL_X: PointG1 = BLSPointGenerator.generate_g1_point_in_subgroup_by_x(3)
197197

198198
# Fixed boundary G2 points
199-
G2_POINT_NEAR_P: PointG2 = BLSPointGenerator.generate_g2_point_in_subgroup_by_x((Spec.P - 100, 0))
200-
G2_POINT_NEAR_ZERO: PointG2 = BLSPointGenerator.generate_g2_point_in_subgroup_by_x((0, 0))
201-
G2_POINT_SMALL_X: PointG2 = BLSPointGenerator.generate_g2_point_in_subgroup_by_x((3, 0))
199+
# G2_POINT_NEAR_P: PointG2 = BLSPointGenerator.generate_g2_point_in_subgroup_by_x((Spec.P - 100, 0))
200+
# G2_POINT_NEAR_ZERO: PointG2 = BLSPointGenerator.generate_g2_point_in_subgroup_by_x((0, 0))
201+
# G2_POINT_SMALL_X: PointG2 = BLSPointGenerator.generate_g2_point_in_subgroup_by_x((3, 0))
202+
203+
# Points with specific x-coordinates for edge case testing
204+
# G1_EDGE_POINTS: List[PointG1] = [
205+
# G1_POINT_NEAR_ZERO,
206+
# G1_POINT_SMALL_X,
207+
# G1_POINT_NEAR_P,
208+
# BLSPointGenerator.generate_g1_point_in_subgroup_by_x(Spec.P - 1),
209+
# BLSPointGenerator.generate_g1_point_in_subgroup_by_x(1),
210+
# ]
211+
212+
# G2 points with specific x-coordinates for edge case testing
213+
# G2_EDGE_POINTS: List[PointG2] = [
214+
# G2_POINT_NEAR_ZERO,
215+
# G2_POINT_SMALL_X,
216+
# G2_POINT_NEAR_P,
217+
# BLSPointGenerator.generate_g2_point_in_subgroup_by_x((Spec.P - 1, 0)),
218+
# BLSPointGenerator.generate_g2_point_in_subgroup_by_x((1, 1)),
219+
# ]
220+
221+
222+
# Random points not in the subgroup (fast to generate)
223+
G1_NOT_IN_SUBGROUP = BLSPointGenerator.generate_random_g1_point_not_in_subgroup()
224+
G2_NOT_IN_SUBGROUP = BLSPointGenerator.generate_random_g2_point_not_in_subgroup()
225+
226+
# Random points not on the curve (fast to generate)
227+
G1_NOT_ON_CURVE = BLSPointGenerator.generate_random_g1_point_not_on_curve()
228+
G2_NOT_ON_CURVE = BLSPointGenerator.generate_random_g2_point_not_on_curve()

Diff for: tests/prague/eip2537_bls_12_381_precompiles/helpers.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,7 @@ def find_g1_point_by_x(cls, x_value: int, in_subgroup: bool, on_curve: bool = Tr
254254
Find a G1 point with x-coordinate at or near the given value,
255255
with the specified subgroup membership and curve membership.
256256
"""
257-
max_offset = 100
257+
max_offset = 5000
258258
isomorphic_b = cls.ISOMORPHIC_B_G1
259259

260260
for offset in range(max_offset + 1):
@@ -329,7 +329,7 @@ def find_g2_point_by_x(
329329
Find a G2 point with x-coordinate at or near the given value,
330330
with the specified subgroup membership and curve membership.
331331
"""
332-
max_offset = 100
332+
max_offset = 5000
333333
isomorphic_b = cls.ISOMORPHIC_B_G2
334334

335335
for offset in range(max_offset + 1):

Diff for: tests/prague/eip2537_bls_12_381_precompiles/test_bls12_g1add.py

+143-32
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
from ethereum_test_tools import Alloc, Environment, StateTestFiller, Transaction
99
from ethereum_test_tools import Opcodes as Op
1010

11-
from .conftest import G1_POINT_NEAR_P, G1_POINT_NEAR_ZERO
11+
# from .conftest import G1_POINT_NEAR_P, G1_POINT_NEAR_ZERO
1212
from .helpers import add_points_g1, vectors_from_file
1313
from .spec import PointG1, Spec, ref_spec_2537
1414

@@ -23,31 +23,48 @@
2323

2424
@pytest.mark.parametrize(
2525
"input_data,expected_output,vector_gas_value",
26+
# Test vectors from the reference spec (from the cryptography team)
2627
vectors_from_file("add_G1_bls.json")
2728
+ [
29+
# Identity (infinity) element test cases.
30+
# Checks that any point added to the identity element (INF) equals itself.
31+
pytest.param(
32+
Spec.G1 + Spec.INF_G1,
33+
Spec.G1,
34+
None,
35+
id="generator_plus_inf",
36+
),
37+
pytest.param(
38+
Spec.INF_G1 + Spec.G1,
39+
Spec.G1,
40+
None,
41+
id="inf_plus_generator",
42+
),
2843
pytest.param(
2944
Spec.INF_G1 + Spec.INF_G1,
3045
Spec.INF_G1,
3146
None,
3247
id="inf_plus_inf",
3348
),
3449
pytest.param(
35-
Spec.P1_NOT_IN_SUBGROUP + Spec.P1_NOT_IN_SUBGROUP,
36-
Spec.P1_NOT_IN_SUBGROUP_TIMES_2,
50+
Spec.INF_G1 + Spec.P1,
51+
Spec.P1,
3752
None,
38-
id="not_in_subgroup_1",
53+
id="inf_plus_point",
3954
),
55+
# Basic arithmetic properties test cases.
56+
# Checks fundamental properties of the BLS12-381 curve.
4057
pytest.param(
41-
Spec.P1_NOT_IN_SUBGROUP + Spec.P1_NOT_IN_SUBGROUP_TIMES_2,
58+
Spec.P1 + (-Spec.P1),
4259
Spec.INF_G1,
4360
None,
44-
id="not_in_subgroup_2",
61+
id="point_plus_neg_point",
4562
),
4663
pytest.param(
47-
Spec.P1 + (-Spec.P1),
64+
Spec.G1 + (-Spec.G1),
4865
Spec.INF_G1,
4966
None,
50-
id="point_plus_negative",
67+
id="generator_plus_neg_point",
5168
),
5269
pytest.param(
5370
Spec.P1 + Spec.G1,
@@ -67,43 +84,123 @@
6784
None,
6885
id="point_doubling",
6986
),
70-
# Boundary point test cases
87+
pytest.param( # (P + G) + P = P + (G + P)
88+
add_points_g1(Spec.P1, Spec.G1) + Spec.P1,
89+
add_points_g1(Spec.P1, add_points_g1(Spec.G1, Spec.P1)),
90+
None,
91+
id="associativity_check",
92+
),
93+
pytest.param( # -(P+G) = (-P)+(-G)
94+
(-(add_points_g1(Spec.P1, Spec.G1))) + Spec.INF_G1,
95+
add_points_g1((-Spec.P1), (-Spec.G1)),
96+
None,
97+
id="negation_of_sum",
98+
),
7199
pytest.param(
72-
G1_POINT_NEAR_P + Spec.INF_G1,
73-
G1_POINT_NEAR_P,
100+
add_points_g1(Spec.G1, Spec.G1) + add_points_g1(Spec.P1, Spec.P1),
101+
add_points_g1(add_points_g1(Spec.G1, Spec.G1), add_points_g1(Spec.P1, Spec.P1)),
74102
None,
75-
id="near_p_boundary_plus_inf",
103+
id="double_generator_plus_double_point",
76104
),
77105
pytest.param(
78-
G1_POINT_NEAR_ZERO + Spec.INF_G1,
79-
G1_POINT_NEAR_ZERO,
106+
add_points_g1(Spec.G1, Spec.G1) + add_points_g1(Spec.G1, Spec.G1),
107+
add_points_g1(add_points_g1(Spec.G1, Spec.G1), add_points_g1(Spec.G1, Spec.G1)),
108+
None,
109+
id="double_generator_plus_double_generator",
110+
),
111+
pytest.param( # (x,y) + (x,-y) = INF
112+
PointG1(Spec.P1.x, Spec.P1.y) + PointG1(Spec.P1.x, Spec.P - Spec.P1.y),
113+
Spec.INF_G1,
80114
None,
81-
id="near_zero_boundary_plus_inf",
115+
id="point_plus_reflected_point",
82116
),
117+
# Not in the r-order subgroup test cases.
118+
# Checks that any point on the curve but not in the subgroup is used for operations.
83119
pytest.param(
84-
G1_POINT_NEAR_ZERO + G1_POINT_NEAR_P,
85-
add_points_g1(G1_POINT_NEAR_ZERO, G1_POINT_NEAR_P),
120+
Spec.P1_NOT_IN_SUBGROUP + Spec.P1_NOT_IN_SUBGROUP,
121+
Spec.P1_NOT_IN_SUBGROUP_TIMES_2,
122+
None,
123+
id="non_sub_plus_non_sub",
124+
),
125+
pytest.param( # `P1_NOT_IN_SUBGROUP` has an small order subgroup of 3: 3P = INF.
126+
Spec.P1_NOT_IN_SUBGROUP + Spec.P1_NOT_IN_SUBGROUP_TIMES_2,
127+
Spec.INF_G1,
86128
None,
87-
id="near_zero_boundary_plus_near_p_boundary",
129+
id="non_sub_order_3_to_inf",
88130
),
89131
pytest.param(
90-
G1_POINT_NEAR_P + G1_POINT_NEAR_P,
91-
add_points_g1(G1_POINT_NEAR_P, G1_POINT_NEAR_P),
132+
Spec.P1_NOT_IN_SUBGROUP + Spec.INF_G1,
133+
Spec.P1_NOT_IN_SUBGROUP,
92134
None,
93-
id="doubling_near_p_boundary",
135+
id="non_sub_plus_inf",
94136
),
95137
pytest.param(
96-
Spec.G1 + G1_POINT_NEAR_P + G1_POINT_NEAR_ZERO,
97-
add_points_g1(add_points_g1(Spec.G1, G1_POINT_NEAR_P), G1_POINT_NEAR_ZERO),
138+
Spec.G1 + Spec.P1_NOT_IN_SUBGROUP,
139+
add_points_g1(Spec.G1, Spec.P1_NOT_IN_SUBGROUP),
98140
None,
99-
id="chained_boundary_points",
141+
id="generator_plus_non_sub",
100142
),
101143
pytest.param(
102-
G1_POINT_NEAR_P + PointG1(G1_POINT_NEAR_P.x, Spec.P - G1_POINT_NEAR_P.y),
144+
Spec.P1_NOT_IN_SUBGROUP + (-Spec.P1_NOT_IN_SUBGROUP),
103145
Spec.INF_G1,
104146
None,
105-
id="near_p_boundary_plus_its_neg",
147+
id="non_sub_plus_neg_non_sub",
148+
),
149+
pytest.param(
150+
Spec.P1 + Spec.P1_NOT_IN_SUBGROUP,
151+
add_points_g1(Spec.P1, Spec.P1_NOT_IN_SUBGROUP),
152+
None,
153+
id="in_sub_plus_non_sub",
106154
),
155+
pytest.param(
156+
Spec.P1_NOT_IN_SUBGROUP_TIMES_2 + Spec.P1,
157+
add_points_g1(Spec.P1_NOT_IN_SUBGROUP_TIMES_2, Spec.P1),
158+
None,
159+
id="doubled_non_sub_plus_in_sub",
160+
),
161+
pytest.param(
162+
Spec.P1_NOT_IN_SUBGROUP_TIMES_2 + (-Spec.P1_NOT_IN_SUBGROUP),
163+
Spec.P1_NOT_IN_SUBGROUP,
164+
None,
165+
id="doubled_non_sub_plus_neg",
166+
),
167+
# Boundary point test cases. TODO: requires generated points
168+
# pytest.param(
169+
# G1_POINT_NEAR_P + Spec.INF_G1,
170+
# G1_POINT_NEAR_P,
171+
# None,
172+
# id="near_p_boundary_plus_inf",
173+
# ),
174+
# pytest.param(
175+
# G1_POINT_NEAR_ZERO + Spec.INF_G1,
176+
# G1_POINT_NEAR_ZERO,
177+
# None,
178+
# id="near_zero_boundary_plus_inf",
179+
# ),
180+
# pytest.param(
181+
# G1_POINT_NEAR_ZERO + G1_POINT_NEAR_P,
182+
# add_points_g1(G1_POINT_NEAR_ZERO, G1_POINT_NEAR_P),
183+
# None,
184+
# id="near_zero_boundary_plus_near_p_boundary",
185+
# ),
186+
# pytest.param(
187+
# G1_POINT_NEAR_P + G1_POINT_NEAR_P,
188+
# add_points_g1(G1_POINT_NEAR_P, G1_POINT_NEAR_P),
189+
# None,
190+
# id="doubling_near_p_boundary",
191+
# ),
192+
# pytest.param(
193+
# Spec.G1 + G1_POINT_NEAR_P + G1_POINT_NEAR_ZERO,
194+
# add_points_g1(add_points_g1(Spec.G1, G1_POINT_NEAR_P), G1_POINT_NEAR_ZERO),
195+
# None,
196+
# id="chained_boundary_points",
197+
# ),
198+
# pytest.param(
199+
# G1_POINT_NEAR_P + PointG1(G1_POINT_NEAR_P.x, Spec.P - G1_POINT_NEAR_P.y),
200+
# Spec.INF_G1,
201+
# None,
202+
# id="near_p_boundary_plus_its_neg",
203+
# ),
107204
],
108205
)
109206
def test_valid(
@@ -123,6 +220,7 @@ def test_valid(
123220

124221
@pytest.mark.parametrize(
125222
"input_data",
223+
# Test vectors from the reference spec (from the cryptography team)
126224
vectors_from_file("fail-add_G1_bls.json")
127225
+ [
128226
pytest.param(
@@ -222,13 +320,26 @@ def test_valid(
222320
id="swapped_coordinates",
223321
),
224322
pytest.param(
225-
PointG1(
226-
Spec.P1.x,
227-
Spec.P - Spec.P1.y, # The other y-coordinate for the same x
228-
)
229-
+ Spec.INF_G1,
230-
id="non_canonical_y_coordinate",
323+
b"\x00" * 96,
324+
id="all_zero_96_bytes",
325+
),
326+
pytest.param(
327+
b"\xff" + b"\x00" * 47 + b"\xff" + b"\x00" * 47,
328+
id="bad_inf_flag",
329+
),
330+
pytest.param(
331+
b"\xc0" + b"\x00" * 47 + b"\xc0" + b"\x00" * 47,
332+
id="comp_instead_of_uncomp",
231333
),
334+
# TODO: requires generated points
335+
# pytest.param(
336+
# PointG1() + Spec.INF_G1,
337+
# id="random_off_curve_1",
338+
# ),
339+
# pytest.param(
340+
# PointG1() + Spec.INF_G1,
341+
# id="random_off_curve_2",
342+
# ),
232343
],
233344
)
234345
@pytest.mark.parametrize("expected_output", [Spec.INVALID], ids=[""])

0 commit comments

Comments
 (0)