ethereum.prague.vm.precompiled_contracts.bls12_381.bls12_381_pairingethereum.osaka.vm.precompiled_contracts.bls12_381.bls12_381_pairing

Ethereum Virtual Machine (EVM) BLS12 381 PAIRING PRE-COMPILE ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

.. contents:: Table of Contents :backlinks: none :local:

Introduction

Implementation of the BLS12 381 pairing pre-compile.

bls12_pairing

The bls12_381 pairing precompile.

Parameters

evm : The current EVM frame.

Raises

InvalidParameter If the input length is invalid or if sub-group check fails.

def bls12_pairing(evm: Evm) -> None:
26
    """
27
    The bls12_381 pairing precompile.
28
29
    Parameters
30
    ----------
31
    evm :
32
        The current EVM frame.
33
34
    Raises
35
    ------
36
    InvalidParameter
37
        If the input length is invalid or if sub-group check fails.
38
    """
39
    data = evm.message.data
40
    if len(data) == 0 or len(data) % 384 != 0:
41
        raise InvalidParameter("Invalid Input Length")
42
43
    # GAS
44
    k = len(data) // 384
45
    gas_cost = Uint(32600 * k + 37700)
46
    charge_gas(evm, gas_cost)
47
48
    # OPERATION
49
    result = FQ12.one()
50
    for i in range(k):
51
        g1_start = Uint(384 * i)
52
        g2_start = Uint(384 * i + 128)
53
54
        g1_slice = data[g1_start : g1_start + Uint(128)]
55
        g1_point = bytes_to_g1(bytes(g1_slice))
56
        if not is_inf(bls12_multiply(g1_point, curve_order)):
57
            raise InvalidParameter("Sub-group check failed for G1 point.")
58
59
        g2_slice = data[g2_start : g2_start + Uint(256)]
60
        g2_point = bytes_to_g2(bytes(g2_slice))
61
        if not is_inf(bls12_multiply(g2_point, curve_order)):
62
            raise InvalidParameter("Sub-group check failed for G2 point.")
63
64
        result *= pairing(g2_point, g1_point)
65
66
    if result == FQ12.one():
67
        evm.output = b"\x00" * 31 + b"\x01"
68
    else:
69
        evm.output = b"\x00" * 32