@pytest.mark.parametrize(
"input_data",
# Test vectors from the reference spec (from the cryptography team)
vectors_from_file("fail-add_G1_bls.json")
+ [
pytest.param(
PointG1(0, 1) + Spec.INF_G1,
id="invalid_point_a_1",
),
pytest.param(
PointG1(Spec.P1.x, Spec.P1.y - 1) + Spec.INF_G1,
id="invalid_point_a_2",
),
pytest.param(
PointG1(Spec.P1.x, Spec.P1.y + 1) + Spec.INF_G1,
id="invalid_point_a_3",
),
pytest.param(
PointG1(Spec.P1.x, Spec.P1.x) + Spec.INF_G1,
id="invalid_point_a_4",
),
pytest.param(
PointG1(Spec.P1.x, Spec.P1.y - 1) + Spec.P1,
id="invalid_point_a_5",
),
pytest.param(
Spec.INF_G1 + PointG1(0, 1),
id="invalid_point_b_1",
),
pytest.param(
Spec.INF_G1 + PointG1(Spec.P1.x, Spec.P1.y - 1),
id="invalid_point_b_2",
),
pytest.param(
Spec.INF_G1 + PointG1(Spec.P1.x, Spec.P1.y + 1),
id="invalid_point_b_3",
),
pytest.param(
Spec.INF_G1 + PointG1(Spec.P1.x, Spec.P1.x),
id="invalid_point_b_4",
),
pytest.param(
Spec.P1 + PointG1(Spec.P1.x, Spec.P1.y - 1),
id="invalid_point_b_5",
),
pytest.param(
PointG1(Spec.P, 0) + Spec.INF_G1,
id="a_x_equal_to_p",
),
pytest.param(
Spec.INF_G1 + PointG1(Spec.P, 0),
id="b_x_equal_to_p",
),
pytest.param(
PointG1(0, Spec.P) + Spec.INF_G1,
id="a_y_equal_to_p",
),
pytest.param(
Spec.INF_G1 + PointG1(0, Spec.P),
id="b_y_equal_to_p",
),
pytest.param(
PointG1(Spec.P1.x + Spec.P, Spec.P1.y) + Spec.G1,
id="a_x_above_p",
),
pytest.param(
PointG1(Spec.P1.x, Spec.P1.y + Spec.P) + Spec.G1,
id="a_y_above_p",
),
pytest.param(
Spec.P1 + PointG1(Spec.G1.x + Spec.P, Spec.G1.y),
id="b_x_above_p",
),
pytest.param(
Spec.P1 + PointG1(Spec.G1.x, Spec.G1.y + Spec.P),
id="b_y_above_p",
),
pytest.param(
b"\x80" + bytes(Spec.INF_G1)[1:] + Spec.INF_G1,
id="invalid_encoding_a",
),
pytest.param(
Spec.INF_G1 + b"\x80" + bytes(Spec.INF_G1)[1:],
id="invalid_encoding_b",
),
pytest.param(
(Spec.INF_G1 + PointG1(Spec.P1.x, Spec.P1.x))[:-1],
id="input_too_short",
),
pytest.param(
b"\x00" + (Spec.INF_G1 + PointG1(Spec.P1.x, Spec.P1.x)),
id="input_too_long",
),
pytest.param(
b"",
id="zero_length_input",
),
pytest.param(
Spec.G1,
id="only_one_point",
),
pytest.param(
Spec.G2 + Spec.G2,
id="g2_points",
),
pytest.param(
PointG1(Spec.P + 1, 0) + Spec.INF_G1,
id="x_above_modulus",
),
pytest.param( # Point on curve y^2 = x^3 + 5.
PointG1(0x01, 0x07) + Spec.INF_G1,
id="point_on_wrong_curve_b=5",
),
pytest.param(
PointG1(Spec.P1.y, Spec.P1.x) + Spec.INF_G1,
id="swapped_coordinates",
),
pytest.param(
b"\x00" * 96,
id="all_zero_96_bytes",
),
pytest.param(
b"\xff" + b"\x00" * 47 + b"\xff" + b"\x00" * 47,
id="bad_inf_flag",
),
pytest.param(
b"\xc0" + b"\x00" * 47 + b"\xc0" + b"\x00" * 47,
id="comp_instead_of_uncomp",
),
pytest.param(
PointG1(Spec.P1.x | Spec.MAX_FP_BIT_SET, Spec.P1.y) + Spec.P1,
id="non_zero_byte_16_boundary_violation_x",
),
pytest.param(
PointG1(Spec.P1.x, Spec.P1.y | Spec.MAX_FP_BIT_SET) + Spec.P1,
id="non_zero_byte_16_boundary_violation_y",
),
# Not on the curve cases using random generated points.
pytest.param(
G1_POINTS_NOT_ON_CURVE[0] + Spec.INF_G1,
id="rand_not_on_curve_0_plus_inf",
),
pytest.param(
G1_POINTS_NOT_ON_CURVE[1] + Spec.P1,
id="rand_not_on_curve_1_plus_point",
),
pytest.param(
G1_POINTS_NOT_ON_CURVE[2] + G1_POINTS_NOT_IN_SUBGROUP[0],
id="rand_not_on_curve_2_plus_not_in_subgroup_0",
),
pytest.param(
G1_POINTS_NOT_ON_CURVE[3] + G1_POINTS_NOT_ON_CURVE[4],
id="rand_not_on_curve_3_plus_4",
),
pytest.param(
Spec.INF_G1 + G1_POINTS_NOT_ON_CURVE[0],
id="inf_plus_rand_not_on_curve_0",
),
pytest.param(
Spec.P1 + G1_POINTS_NOT_ON_CURVE[1],
id="point_plus_rand_not_on_curve_1",
),
pytest.param(
G1_POINTS_NOT_IN_SUBGROUP[2] + G1_POINTS_NOT_ON_CURVE[2],
id="rand_not_in_subgroup_2_plus_rand_not_on_curve_2",
),
],
)
@pytest.mark.parametrize("expected_output", [Spec.INVALID], ids=[""])
@pytest.mark.slow()
def test_invalid(
state_test: StateTestFiller,
pre: Alloc,
post: dict,
tx: Transaction,
) -> None:
"""Negative tests for the BLS12_G1ADD precompile."""
state_test(
env=Environment(),
pre=pre,
tx=tx,
post=post,
)