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_point = bytes_to_g1(data[g1_start : g1_start + Uint(128)])
56
        if not is_inf(bls12_multiply(g1_point, curve_order)):
57
            raise InvalidParameter("Sub-group check failed for G1 point.")
58
59
        g2_point = bytes_to_g2(data[g2_start : g2_start + Uint(256)])
60
        if not is_inf(bls12_multiply(g2_point, curve_order)):
61
            raise InvalidParameter("Sub-group check failed for G2 point.")
62
63
        result *= pairing(g2_point, g1_point)
64
65
    if result == FQ12.one():
66
        evm.output = b"\x00" * 31 + b"\x01"
67
    else:
68
        evm.output = b"\x00" * 32