Skip to content

test_invalid()

Documentation for tests/prague/eip2537_bls_12_381_precompiles/test_bls12_g2msm.py::test_invalid@ffe48572.

Generate fixtures for these test cases for Bogota with:

fill -v tests/prague/eip2537_bls_12_381_precompiles/test_bls12_g2msm.py::test_invalid --fork Bogota

Test invalid calls to the BLS12_G2MSM precompile.

Source code in tests/prague/eip2537_bls_12_381_precompiles/test_bls12_g2msm.py
@pytest.mark.parametrize(
    "input_data",
    # Test vectors from the reference spec (from the cryptography team)
    vectors_from_file("fail-msm_G2_bls.json")
    + [
        pytest.param(
            Spec.P2_NOT_IN_SUBGROUP + Scalar(1),
            id="not_in_subgroup_1_pos_0",
        ),
        pytest.param(
            Spec.P2_NOT_IN_SUBGROUP_TIMES_2 + Scalar(1),
            id="not_in_subgroup_2_pos_0",
        ),
        pytest.param(
            Spec.G2 + Scalar(1) + Spec.P2_NOT_IN_SUBGROUP + Scalar(1),
            id="not_in_subgroup_1_pos_1",
        ),
        pytest.param(
            Spec.G2 + Scalar(1) + Spec.P2_NOT_IN_SUBGROUP_TIMES_2 + Scalar(1),
            id="not_in_subgroup_2_pos_1",
        ),
        pytest.param(
            G2_POINTS_NOT_IN_SUBGROUP[0] + Scalar(1),
            id="rand_not_in_subgroup_0_pos_0",
        ),
        pytest.param(
            G2_POINTS_NOT_IN_SUBGROUP[1] + Scalar(1),
            id="rand_not_in_subgroup_1_pos_0",
        ),
        pytest.param(
            Spec.G2 + Scalar(1) + G2_POINTS_NOT_IN_SUBGROUP[0] + Scalar(1),
            id="rand_not_in_subgroup_0_pos_1",
        ),
        pytest.param(
            Spec.G2 + Scalar(1) + G2_POINTS_NOT_IN_SUBGROUP[1] + Scalar(1),
            id="rand_not_in_subgroup_1_pos_1",
        ),
        pytest.param(
            G2_POINTS_NOT_ON_CURVE[0] + Scalar(0),
            id="not_on_curve_0_pos_0",
        ),
        pytest.param(
            G2_POINTS_NOT_ON_CURVE[1] + Scalar(1),
            id="not_on_curve_1_pos_0",
        ),
        pytest.param(
            Spec.G2 + Scalar(1) + G2_POINTS_NOT_ON_CURVE[0] + Scalar(0),
            id="not_on_curve_0_pos_1",
        ),
        pytest.param(
            Spec.G2 + Scalar(1) + G2_POINTS_NOT_ON_CURVE[1] + Scalar(1),
            id="not_on_curve_1_pos_1",
        ),
        pytest.param(
            Spec.G2 + Scalar(1) + Spec.G2,
            id="incomplete_input_missing_scalar",
        ),
        pytest.param(
            Spec.G2 + Scalar(1) + bytes([0]),
            id="incomplete_input_extra_byte",
        ),
        pytest.param(
            Spec.G2 + Scalar(1) + Spec.G1 + Scalar(1),
            id="mixing_g2_with_g1",
        ),
        pytest.param(
            Spec.G2 + (b"\x01" + b"\x00" * 32),  # Scalar > UINT256_MAX
            id="scalar_too_large",
        ),
        pytest.param(
            # Invalid scalar length
            Spec.G2 + Scalar(1).x.to_bytes(16, byteorder="big"),
            id="scalar_too_short",
        ),
        pytest.param(
            bytes([0]) * 287,  # Just under minimum valid length
            id="input_too_short_by_1",
        ),
        # Coordinates above modulus p cases.
        pytest.param(
            PointG2((Spec.P2.x[0] + Spec.P, Spec.P2.x[1]), Spec.P2.y)
            + Scalar(1),
            id="x_c0_above_p_pos_0",
        ),
        pytest.param(
            PointG2((Spec.P2.x[0], Spec.P2.x[1] + Spec.P), Spec.P2.y)
            + Scalar(1),
            id="x_c1_above_p_pos_0",
        ),
        pytest.param(
            PointG2(Spec.P2.x, (Spec.P2.y[0] + Spec.P, Spec.P2.y[1]))
            + Scalar(1),
            id="y_c0_above_p_pos_0",
        ),
        pytest.param(
            PointG2(Spec.P2.x, (Spec.P2.y[0], Spec.P2.y[1] + Spec.P))
            + Scalar(1),
            id="y_c1_above_p_pos_0",
        ),
        pytest.param(
            Spec.G2
            + Scalar(1)
            + PointG2((Spec.P2.x[0] + Spec.P, Spec.P2.x[1]), Spec.P2.y)
            + Scalar(0),
            id="x_c0_above_p_pos_1",
        ),
        pytest.param(
            Spec.G2
            + Scalar(1)
            + PointG2((Spec.P2.x[0], Spec.P2.x[1] + Spec.P), Spec.P2.y)
            + Scalar(0),
            id="x_c1_above_p_pos_1",
        ),
        pytest.param(
            Spec.G2
            + Scalar(1)
            + PointG2(Spec.P2.x, (Spec.P2.y[0] + Spec.P, Spec.P2.y[1]))
            + Scalar(0),
            id="y_c0_above_p_pos_1",
        ),
        pytest.param(
            Spec.G2
            + Scalar(1)
            + PointG2(Spec.P2.x, (Spec.P2.y[0], Spec.P2.y[1] + Spec.P))
            + Scalar(0),
            id="y_c1_above_p_pos_1",
        ),
        pytest.param(
            Spec.G2
            + Scalar(1)
            + PointG2(
                (Spec.P2.x[0] | Spec.MAX_FP_BIT_SET, Spec.P2.x[1]), Spec.P2.y
            )
            + Scalar(0),
            id="non_zero_byte_16_boundary_violation_x1_pos_1",
        ),
    ],
    # Input length tests can be found in
    # ./test_bls12_variable_length_input_contracts.py
)
@pytest.mark.parametrize(
    "precompile_gas_modifier", [100_000], ids=[""]
)  # Add gas so that won't be the cause of failure
@pytest.mark.parametrize("expected_output", [Spec.INVALID], ids=[""])
@pytest.mark.eels_base_coverage
def test_invalid(
    state_test: StateTestFiller,
    pre: Alloc,
    post: dict,
    tx: Transaction,
) -> None:
    """Test invalid calls to the BLS12_G2MSM precompile."""
    state_test(
        env=Environment(),
        pre=pre,
        tx=tx,
        post=post,
    )

Parametrized Test Cases

This test generates 34 parametrized test cases across 4 forks.