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() |