@pytest.mark.parametrize(
"input_data,expected_output,vector_gas_value",
# Test vectors from the reference spec (from the cryptography team)
vectors_from_file("add_G2_bls.json")
+ [
# Identity (infinity) element test cases. Checks that any point added
# to the identity element (INF) equals itself.
pytest.param(
Spec.G2 + Spec.INF_G2,
Spec.G2,
None,
id="generator_plus_inf",
),
pytest.param(
Spec.INF_G2 + Spec.G2,
Spec.G2,
None,
id="inf_plus_generator",
),
pytest.param(
Spec.INF_G2 + Spec.INF_G2,
Spec.INF_G2,
None,
id="inf_plus_inf",
),
pytest.param(
Spec.INF_G2 + Spec.P2,
Spec.P2,
None,
id="inf_plus_point",
),
# Basic arithmetic properties test cases.
# Checks fundamental properties of the BLS12-381 curve.
pytest.param(
Spec.P2 + (-Spec.P2),
Spec.INF_G2,
None,
id="point_plus_neg_point",
),
pytest.param(
Spec.G2 + (-Spec.G2),
Spec.INF_G2,
None,
id="generator_plus_neg_point",
),
pytest.param(
Spec.P2 + Spec.G2,
add_points_g2(Spec.G2, Spec.P2),
None,
id="commutative_check_a",
),
pytest.param(
Spec.G2 + Spec.P2,
add_points_g2(Spec.P2, Spec.G2),
None,
id="commutative_check_b",
),
pytest.param(
Spec.P2 + Spec.P2,
add_points_g2(Spec.P2, Spec.P2),
None,
id="point_doubling",
),
pytest.param( # (P + G) + P = P + (G + P)
add_points_g2(Spec.P2, Spec.G2) + Spec.P2,
add_points_g2(Spec.P2, add_points_g2(Spec.G2, Spec.P2)),
None,
id="associativity_check",
),
pytest.param( # -(P+G) = (-P)+(-G)
(-(add_points_g2(Spec.P2, Spec.G2))) + Spec.INF_G2,
add_points_g2((-Spec.P2), (-Spec.G2)),
None,
id="negation_of_sum",
),
pytest.param(
add_points_g2(Spec.G2, Spec.G2) + add_points_g2(Spec.P2, Spec.P2),
add_points_g2(
add_points_g2(Spec.G2, Spec.G2),
add_points_g2(Spec.P2, Spec.P2),
),
None,
id="double_generator_plus_double_point",
),
pytest.param(
add_points_g2(Spec.G2, Spec.G2) + add_points_g2(Spec.G2, Spec.G2),
add_points_g2(
add_points_g2(Spec.G2, Spec.G2),
add_points_g2(Spec.G2, Spec.G2),
),
None,
id="double_generator_plus_double_generator",
),
pytest.param( # (x,y) + (x,-y) = INF
PointG2(Spec.P2.x, Spec.P2.y)
+ PointG2(
Spec.P2.x, (-Spec.P2.y[0] % Spec.P, -Spec.P2.y[1] % Spec.P)
),
Spec.INF_G2,
None,
id="point_plus_reflected_point",
),
# Not in the r-order subgroup test cases. Checks that any point on the
# curve but not in the subgroup is used for operations.
pytest.param(
Spec.P2_NOT_IN_SUBGROUP + Spec.P2_NOT_IN_SUBGROUP,
Spec.P2_NOT_IN_SUBGROUP_TIMES_2,
None,
id="non_sub_plus_non_sub",
),
pytest.param(
Spec.P2_NOT_IN_SUBGROUP + Spec.P2_NOT_IN_SUBGROUP_TIMES_2,
add_points_g2(
Spec.P2_NOT_IN_SUBGROUP, Spec.P2_NOT_IN_SUBGROUP_TIMES_2
),
None,
id="non_sub_plus_doubled_non_sub",
),
pytest.param(
Spec.P2_NOT_IN_SUBGROUP + Spec.INF_G2,
Spec.P2_NOT_IN_SUBGROUP,
None,
id="non_sub_plus_inf",
),
pytest.param(
Spec.G2 + Spec.P2_NOT_IN_SUBGROUP,
add_points_g2(Spec.G2, Spec.P2_NOT_IN_SUBGROUP),
None,
id="generator_plus_non_sub",
),
pytest.param(
Spec.P2_NOT_IN_SUBGROUP + (-Spec.P2_NOT_IN_SUBGROUP),
Spec.INF_G2,
None,
id="non_sub_plus_neg_non_sub",
),
pytest.param(
Spec.P2 + Spec.P2_NOT_IN_SUBGROUP,
add_points_g2(Spec.P2, Spec.P2_NOT_IN_SUBGROUP),
None,
id="in_sub_plus_non_sub",
),
pytest.param(
Spec.P2_NOT_IN_SUBGROUP_TIMES_2 + Spec.P2,
add_points_g2(Spec.P2_NOT_IN_SUBGROUP_TIMES_2, Spec.P2),
None,
id="doubled_non_sub_plus_in_sub",
),
pytest.param(
Spec.P2_NOT_IN_SUBGROUP_TIMES_2 + (-Spec.P2_NOT_IN_SUBGROUP),
Spec.P2_NOT_IN_SUBGROUP,
None,
id="doubled_non_sub_plus_neg",
),
# More not in the r-order subgroup test cases, but using random
# generated points.
pytest.param(
G2_POINTS_NOT_IN_SUBGROUP[0] + Spec.P2,
add_points_g2(G2_POINTS_NOT_IN_SUBGROUP[0], Spec.P2),
None,
id="rand_not_in_subgroup_0_plus_point",
),
pytest.param(
G2_POINTS_NOT_IN_SUBGROUP[1] + Spec.G2,
add_points_g2(G2_POINTS_NOT_IN_SUBGROUP[1], Spec.G2),
None,
id="rand_not_in_subgroup_1_plus_generator",
),
pytest.param(
G2_POINTS_NOT_IN_SUBGROUP[2] + Spec.INF_G2,
G2_POINTS_NOT_IN_SUBGROUP[2],
None,
id="rand_not_in_subgroup_2_plus_inf",
),
pytest.param(
G2_POINTS_NOT_IN_SUBGROUP[3] + (-G2_POINTS_NOT_IN_SUBGROUP[3]),
Spec.INF_G2,
None,
id="rand_not_in_subgroup_3_plus_neg_self",
),
pytest.param(
G2_POINTS_NOT_IN_SUBGROUP[4] + G2_POINTS_NOT_IN_SUBGROUP[0],
add_points_g2(
G2_POINTS_NOT_IN_SUBGROUP[4], G2_POINTS_NOT_IN_SUBGROUP[0]
),
None,
id="rand_not_in_subgroup_4_plus_0",
),
],
)
@pytest.mark.eels_base_coverage
def test_valid(
state_test: StateTestFiller,
pre: Alloc,
post: dict,
tx: Transaction,
) -> None:
"""Test the BLS12_G2ADD precompile."""
state_test(
env=Environment(),
pre=pre,
tx=tx,
post=post,
)