ethereum.london.vm.precompiled_contracts.alt_bn128ethereum.arrow_glacier.vm.precompiled_contracts.alt_bn128

Ethereum Virtual Machine (EVM) ALT_BN128 CONTRACTS ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

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

Introduction

Implementation of the ALT_BN128 precompiled contracts.

bytes_to_G1

Decode 64 bytes to a point on the curve.

Parameters

data : The bytes data to decode.

Returns

point : Point2D A point on the curve.

Raises

InvalidParameter Either a field element is invalid or the point is not on the curve.

def bytes_to_G1(data: Bytes) -> Point2D:
38
    """
39
    Decode 64 bytes to a point on the curve.
40
41
    Parameters
42
    ----------
43
    data :
44
        The bytes data to decode.
45
46
    Returns
47
    -------
48
    point : Point2D
49
        A point on the curve.
50
51
    Raises
52
    ------
53
    InvalidParameter
54
        Either a field element is invalid or the point is not on the curve.
55
    """
56
    if len(data) != 64:
57
        raise InvalidParameter("Input should be 64 bytes long")
58
59
    x_bytes = buffer_read(data, U256(0), U256(32))
60
    x = int(U256.from_be_bytes(x_bytes))
61
    y_bytes = buffer_read(data, U256(32), U256(32))
62
    y = int(U256.from_be_bytes(y_bytes))
63
64
    if x >= field_modulus:
65
        raise InvalidParameter("Invalid field element")
66
    if y >= field_modulus:
67
        raise InvalidParameter("Invalid field element")
68
69
    if x == 0 and y == 0:
70
        return None
71
72
    point = (FQ(x), FQ(y))
73
74
    # Check if the point is on the curve
75
    if not is_on_curve(point, b):
76
        raise InvalidParameter("Point is not on curve")
77
78
    return point

bytes_to_G2

Decode 128 bytes to a G2 point.

Parameters

data : The bytes data to decode.

Returns

point : Point2D A point on the curve.

Raises

InvalidParameter Either a field element is invalid or the point is not on the curve.

def bytes_to_G2(data: Bytes) -> Point2D:
82
    """
83
    Decode 128 bytes to a G2 point.
84
85
    Parameters
86
    ----------
87
    data :
88
        The bytes data to decode.
89
90
    Returns
91
    -------
92
    point : Point2D
93
        A point on the curve.
94
95
    Raises
96
    ------
97
    InvalidParameter
98
        Either a field element is invalid or the point is not on the curve.
99
    """
100
    if len(data) != 128:
101
        raise InvalidParameter("G2 should be 128 bytes long")
102
103
    x0_bytes = buffer_read(data, U256(0), U256(32))
104
    x0 = int(U256.from_be_bytes(x0_bytes))
105
    x1_bytes = buffer_read(data, U256(32), U256(32))
106
    x1 = int(U256.from_be_bytes(x1_bytes))
107
108
    y0_bytes = buffer_read(data, U256(64), U256(32))
109
    y0 = int(U256.from_be_bytes(y0_bytes))
110
    y1_bytes = buffer_read(data, U256(96), U256(32))
111
    y1 = int(U256.from_be_bytes(y1_bytes))
112
113
    if x0 >= field_modulus or x1 >= field_modulus:
114
        raise InvalidParameter("Invalid field element")
115
    if y0 >= field_modulus or y1 >= field_modulus:
116
        raise InvalidParameter("Invalid field element")
117
118
    x = FQ2((x1, x0))
119
    y = FQ2((y1, y0))
120
121
    if x == FQ2((0, 0)) and y == FQ2((0, 0)):
122
        return None
123
124
    point = (x, y)
125
126
    # Check if the point is on the curve
127
    if not is_on_curve(point, b2):
128
        raise InvalidParameter("Point is not on curve")
129
130
    return point

alt_bn128_add

The ALT_BN128 addition precompiled contract.

Parameters

evm : The current EVM frame.

def alt_bn128_add(evm: Evm) -> None:
134
    """
135
    The ALT_BN128 addition precompiled contract.
136
137
    Parameters
138
    ----------
139
    evm :
140
        The current EVM frame.
141
    """
142
    data = evm.message.data
143
144
    # GAS
145
    charge_gas(evm, Uint(150))
146
147
    # OPERATION
148
    try:
149
        p0 = bytes_to_G1(buffer_read(data, U256(0), U256(64)))
150
        p1 = bytes_to_G1(buffer_read(data, U256(64), U256(64)))
151
    except InvalidParameter as e:
152
        raise OutOfGasError from e
153
154
    p = add(p0, p1)
155
    if p is None:
156
        x, y = (0, 0)
157
    else:
158
        x, y = p
159
160
    evm.output = Uint(x).to_be_bytes32() + Uint(y).to_be_bytes32()

alt_bn128_mul

The ALT_BN128 multiplication precompiled contract.

Parameters

evm : The current EVM frame.

def alt_bn128_mul(evm: Evm) -> None:
164
    """
165
    The ALT_BN128 multiplication precompiled contract.
166
167
    Parameters
168
    ----------
169
    evm :
170
        The current EVM frame.
171
    """
172
    data = evm.message.data
173
174
    # GAS
175
    charge_gas(evm, Uint(6000))
176
177
    # OPERATION
178
    try:
179
        p0 = bytes_to_G1(buffer_read(data, U256(0), U256(64)))
180
    except InvalidParameter as e:
181
        raise OutOfGasError from e
182
    n = int(U256.from_be_bytes(buffer_read(data, U256(64), U256(32))))
183
184
    p = multiply(p0, n)
185
    if p is None:
186
        x, y = (0, 0)
187
    else:
188
        x, y = p
189
190
    evm.output = Uint(x).to_be_bytes32() + Uint(y).to_be_bytes32()

alt_bn128_pairing_check

The ALT_BN128 pairing check precompiled contract.

Parameters

evm : The current EVM frame.

def alt_bn128_pairing_check(evm: Evm) -> None:
194
    """
195
    The ALT_BN128 pairing check precompiled contract.
196
197
    Parameters
198
    ----------
199
    evm :
200
        The current EVM frame.
201
    """
202
    data = evm.message.data
203
204
    # GAS
205
    charge_gas(evm, Uint(34000 * (len(data) // 192) + 45000))
206
207
    # OPERATION
208
    if len(data) % 192 != 0:
209
        raise OutOfGasError
210
    result = FQ12.one()
211
    for i in range(len(data) // 192):
212
        try:
213
            p = bytes_to_G1(buffer_read(data, U256(192 * i), U256(64)))
214
            q = bytes_to_G2(buffer_read(data, U256(192 * i + 64), U256(128)))
215
        except InvalidParameter as e:
216
            raise OutOfGasError from e
217
        if multiply(p, curve_order) is not None:
218
            raise OutOfGasError
219
        if multiply(q, curve_order) is not None:
220
            raise OutOfGasError
221
        if p is not None and q is not None:
222
            result *= pairing(q, p)
223
224
    if result == FQ12.one():
225
        evm.output = U256(1).to_be_bytes32()
226
    else:
227
        evm.output = U256(0).to_be_bytes32()