ethereum.forks.amsterdam.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

40
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:
44
    <snip>
58
    data = evm.call_data
59
    if len(data) != 512:
60
        raise InvalidParameter("Invalid Input Length")
61
62
    # GAS
63
    charge_gas(evm, GasCosts.PRECOMPILE_BLS_G2ADD)
64
65
    # OPERATION
66
    p1 = bytes_to_g2(buffer_read(data, U256(0), U256(256)))
67
    p2 = bytes_to_g2(buffer_read(data, U256(256), U256(256)))
68
69
    result = bls12_add(p1, p2)
70
71
    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:
75
    <snip>
93
    data = evm.call_data
94
    if len(data) == 0 or len(data) % LENGTH_PER_PAIR != 0:
95
        raise InvalidParameter("Invalid Input Length")
96
97
    # GAS
98
    k = len(data) // LENGTH_PER_PAIR
99
    if k <= 128:
100
        discount = Uint(G2_K_DISCOUNT[k - 1])
101
    else:
102
        discount = Uint(G2_MAX_DISCOUNT)
103
104
    gas_cost = ExecutionGas(
105
        Uint(k) * GasCosts.PRECOMPILE_BLS_G2MUL * discount // MULTIPLIER
106
    )
107
    charge_gas(evm, gas_cost)
108
109
    # OPERATION
110
    for i in range(k):
111
        start_index = i * LENGTH_PER_PAIR
112
        end_index = start_index + LENGTH_PER_PAIR
113
114
        p, m = decode_g2_scalar_pair(data[start_index:end_index])
115
        product = bls12_multiply(p, m)
116
117
        if i == 0:
118
            result = product
119
        else:
120
            result = bls12_add(result, product)
121
122
    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:
126
    <snip>
140
    data = evm.call_data
141
    if len(data) != 128:
142
        raise InvalidParameter("Invalid Input Length")
143
144
    # GAS
145
    charge_gas(evm, GasCosts.PRECOMPILE_BLS_G2MAP)
146
147
    # OPERATION
148
    field_element = bytes_to_fq2(data)
149
    assert isinstance(field_element, FQ2)
150
151
    fp2 = bytes_to_fq2(data)
152
    g2_3d = clear_cofactor_G2(map_to_curve_G2(fp2))
153
154
    evm.output = g2_to_bytes(g2_3d)