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

41
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:
45
    """
46
    The bls12_381 G2 point addition precompile.
47
48
    Parameters
49
    ----------
50
    evm :
51
        The current EVM frame.
52
53
    Raises
54
    ------
55
    InvalidParameter
56
        If the input length is invalid.
57
58
    """
59
    data = evm.message.data
60
    if len(data) != 512:
61
        raise InvalidParameter("Invalid Input Length")
62
63
    # GAS
64
    charge_gas(evm, Uint(GAS_BLS_G2_ADD))
65
66
    # OPERATION
67
    p1 = bytes_to_g2(buffer_read(data, U256(0), U256(256)))
68
    p2 = bytes_to_g2(buffer_read(data, U256(256), U256(256)))
69
70
    result = bls12_add(p1, p2)
71
72
    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:
76
    """
77
    The bls12_381 G2 multi-scalar multiplication precompile.
78
    Note: This uses the naive approach to multi-scalar multiplication
79
    which is not suitably optimized for production clients. Clients are
80
    required to implement a more efficient algorithm such as the Pippenger
81
    algorithm.
82
83
    Parameters
84
    ----------
85
    evm :
86
        The current EVM frame.
87
88
    Raises
89
    ------
90
    InvalidParameter
91
        If the input length is invalid.
92
93
    """
94
    data = evm.message.data
95
    if len(data) == 0 or len(data) % LENGTH_PER_PAIR != 0:
96
        raise InvalidParameter("Invalid Input Length")
97
98
    # GAS
99
    k = len(data) // LENGTH_PER_PAIR
100
    if k <= 128:
101
        discount = Uint(G2_K_DISCOUNT[k - 1])
102
    else:
103
        discount = Uint(G2_MAX_DISCOUNT)
104
105
    gas_cost = Uint(k) * GAS_BLS_G2_MUL * discount // MULTIPLIER
106
    charge_gas(evm, gas_cost)
107
108
    # OPERATION
109
    for i in range(k):
110
        start_index = i * LENGTH_PER_PAIR
111
        end_index = start_index + LENGTH_PER_PAIR
112
113
        p, m = decode_g2_scalar_pair(data[start_index:end_index])
114
        product = bls12_multiply(p, m)
115
116
        if i == 0:
117
            result = product
118
        else:
119
            result = bls12_add(result, product)
120
121
    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:
125
    """
126
    Precompile to map field element to G2.
127
128
    Parameters
129
    ----------
130
    evm :
131
        The current EVM frame.
132
133
    Raises
134
    ------
135
    InvalidParameter
136
        If the input length is invalid.
137
138
    """
139
    data = evm.message.data
140
    if len(data) != 128:
141
        raise InvalidParameter("Invalid Input Length")
142
143
    # GAS
144
    charge_gas(evm, Uint(GAS_BLS_G2_MAP))
145
146
    # OPERATION
147
    field_element = bytes_to_fq2(data)
148
    assert isinstance(field_element, FQ2)
149
150
    fp2 = bytes_to_fq2(data)
151
    g2_3d = clear_cofactor_G2(map_to_curve_G2(fp2))
152
153
    evm.output = g2_to_bytes(g2_3d)