@pytest.mark.parametrize(
"input_data,expected_output,vector_gas_value",
# Test vectors from the reference spec (from the cryptography team)
vectors_from_file("msm_G2_bls.json")
+ [
# Multiple pair scalar multiplication cases.
pytest.param(
Spec.G2 + Scalar(1) + Spec.INF_G2 + Scalar(1),
Spec.G2,
None,
id="g2_plus_inf",
),
pytest.param(
Spec.G2
+ Scalar(0)
+ Spec.P2
+ Scalar(0)
+ Spec.INF_G2
+ Scalar(0),
Spec.INF_G2,
None,
id="all_zero_scalars",
),
pytest.param(
Spec.G2 + Scalar(1) + (-Spec.G2) + Scalar(1),
Spec.INF_G2,
None,
id="sum_to_identity_opposite",
),
pytest.param(
Spec.G2 + Scalar(Spec.Q - 1) + Spec.G2 + Scalar(1),
Spec.INF_G2,
None,
id="scalars_sum_to_q",
),
pytest.param(
Spec.G2
+ Scalar(1)
+ Spec.G2
+ Scalar(0)
+ Spec.INF_G2
+ Scalar(5),
Spec.G2,
None,
id="combined_basic_cases",
),
pytest.param(
Spec.G2 + Scalar(1) + Spec.INF_G2 + Scalar(500),
Spec.G2,
None,
id="identity_with_large_scalar",
),
pytest.param(
Spec.G2 + Scalar(0) + Spec.P2 + Scalar(0) + (-Spec.G2) + Scalar(0),
Spec.INF_G2,
None,
id="multiple_points_zero_scalar",
),
pytest.param( # Scalar above Q with bit 255 set on the multi-pair path
Spec.G2
+ Scalar(2**256 - 1)
+ Spec.G2
+ Scalar(Spec.Q - (2**256 - 1) % Spec.Q),
Spec.INF_G2,
None,
id="max_scalar_sum_to_identity",
),
# Cases with maximum discount table (test vector for gas cost
# calculation)
pytest.param(
(Spec.P2 + Scalar(Spec.Q)) * (len(Spec.G2MSM_DISCOUNT_TABLE) - 1),
Spec.INF_G2,
None,
id="max_discount",
marks=pytest.mark.slow,
),
pytest.param(
(Spec.P2 + Scalar(Spec.Q)) * len(Spec.G2MSM_DISCOUNT_TABLE),
Spec.INF_G2,
None,
id="max_discount_plus_1",
marks=pytest.mark.slow,
),
],
)
@pytest.mark.slow()
def test_valid(
state_test: StateTestFiller,
pre: Alloc,
post: dict,
tx: Transaction,
) -> None:
"""Test valid calls to the BLS12_G2MSM precompile."""
state_test(
env=Environment(),
pre=pre,
tx=tx,
post=post,
)