ethereum.forks.bpo1.vm.precompiled_contracts.bls12_381.bls12_381_g2ethereum.forks.bpo2.vm.precompiled_contracts.bls12_381.bls12_381_g2

Ethereum Virtual Machine (EVM) BLS12 381 G2 CONTRACTS.

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

Introduction

Implementation of pre-compiles in G2 (curve over base prime field).

LENGTH_PER_PAIR

36
LENGTH_PER_PAIR = 288

bls12_g2_add

The bls12_381 G2 point addition precompile.

Parameters

evm : The current EVM frame.

Raises

InvalidParameter If the input length is invalid.

def bls12_g2_add(evm: Evm) -> None:
40
    """
41
    The bls12_381 G2 point addition precompile.
42
43
    Parameters
44
    ----------
45
    evm :
46
        The current EVM frame.
47
48
    Raises
49
    ------
50
    InvalidParameter
51
        If the input length is invalid.
52
53
    """
54
    data = evm.message.data
55
    if len(data) != 512:
56
        raise InvalidParameter("Invalid Input Length")
57
58
    # GAS
62
    charge_gas(evm, GasCosts.PRECOMPILE_BLS_G2ADD)
59
    charge_gas(evm, Uint(GasCosts.PRECOMPILE_BLS_G2ADD))
60
61
    # OPERATION
62
    p1 = bytes_to_g2(buffer_read(data, U256(0), U256(256)))
63
    p2 = bytes_to_g2(buffer_read(data, U256(256), U256(256)))
64
65
    result = bls12_add(p1, p2)
66
67
    evm.output = g2_to_bytes(result)

bls12_g2_msm

The bls12_381 G2 multi-scalar multiplication precompile. Note: This uses the naive approach to multi-scalar multiplication which is not suitably optimized for production clients. Clients are required to implement a more efficient algorithm such as the Pippenger algorithm.

Parameters

evm : The current EVM frame.

Raises

InvalidParameter If the input length is invalid.

def bls12_g2_msm(evm: Evm) -> None:
71
    """
72
    The bls12_381 G2 multi-scalar multiplication precompile.
73
    Note: This uses the naive approach to multi-scalar multiplication
74
    which is not suitably optimized for production clients. Clients are
75
    required to implement a more efficient algorithm such as the Pippenger
76
    algorithm.
77
78
    Parameters
79
    ----------
80
    evm :
81
        The current EVM frame.
82
83
    Raises
84
    ------
85
    InvalidParameter
86
        If the input length is invalid.
87
88
    """
89
    data = evm.message.data
90
    if len(data) == 0 or len(data) % LENGTH_PER_PAIR != 0:
91
        raise InvalidParameter("Invalid Input Length")
92
93
    # GAS
94
    k = len(data) // LENGTH_PER_PAIR
95
    if k <= 128:
96
        discount = Uint(G2_K_DISCOUNT[k - 1])
97
    else:
98
        discount = Uint(G2_MAX_DISCOUNT)
99
100
    gas_cost = Uint(k) * GasCosts.PRECOMPILE_BLS_G2MUL * discount // MULTIPLIER
101
    charge_gas(evm, gas_cost)
102
103
    # OPERATION
104
    for i in range(k):
105
        start_index = i * LENGTH_PER_PAIR
106
        end_index = start_index + LENGTH_PER_PAIR
107
108
        p, m = decode_g2_scalar_pair(data[start_index:end_index])
109
        product = bls12_multiply(p, m)
110
111
        if i == 0:
112
            result = product
113
        else:
114
            result = bls12_add(result, product)
115
116
    evm.output = g2_to_bytes(result)

bls12_map_fp2_to_g2

Precompile to map field element to G2.

Parameters

evm : The current EVM frame.

Raises

InvalidParameter If the input length is invalid.

def bls12_map_fp2_to_g2(evm: Evm) -> None:
120
    """
121
    Precompile to map field element to G2.
122
123
    Parameters
124
    ----------
125
    evm :
126
        The current EVM frame.
127
128
    Raises
129
    ------
130
    InvalidParameter
131
        If the input length is invalid.
132
133
    """
134
    data = evm.message.data
135
    if len(data) != 128:
136
        raise InvalidParameter("Invalid Input Length")
137
138
    # GAS
142
    charge_gas(evm, GasCosts.PRECOMPILE_BLS_G2MAP)
139
    charge_gas(evm, Uint(GasCosts.PRECOMPILE_BLS_G2MAP))
140
141
    # OPERATION
142
    field_element = bytes_to_fq2(data)
143
    assert isinstance(field_element, FQ2)
144
145
    fp2 = bytes_to_fq2(data)
146
    g2_3d = clear_cofactor_G2(map_to_curve_G2(fp2))
147
148
    evm.output = g2_to_bytes(g2_3d)