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