0
# BN128 Curve
1
2
Reference implementation of BN128 (also known as alt_bn128) elliptic curve operations used in Ethereum's precompiled contracts. This curve provides efficient pairing operations and is used in various Ethereum applications including zkSNARKs and other zero-knowledge proof systems.
3
4
## Constants and Generator Points
5
6
```python { .api }
7
# Generator points
8
G1 # Generator point on G1 (base curve)
9
G2 # Generator point on G2 (twist curve)
10
G12 # Identity element in GT (target group)
11
12
# Points at infinity
13
Z1 # Point at infinity for G1
14
Z2 # Point at infinity for G2
15
16
# Curve parameters
17
b: int # Curve coefficient for G1: y^2 = x^3 + b
18
b2 # Curve coefficient for G2 (quadratic extension)
19
b12 # Curve coefficient for G12 (degree 12 extension)
20
curve_order: int # Order of the curve
21
field_modulus: int # Prime modulus of the base field
22
twist # Twist parameter for G2
23
```
24
25
## Capabilities
26
27
### Point Arithmetic
28
29
Basic elliptic curve point operations for both G1 and G2 groups.
30
31
```python { .api }
32
def add(p1, p2):
33
"""
34
Add two elliptic curve points.
35
36
Args:
37
p1: First point (G1 or G2)
38
p2: Second point (G1 or G2, same type as p1)
39
40
Returns:
41
Point of same type as inputs representing p1 + p2
42
"""
43
44
def double(p):
45
"""
46
Double an elliptic curve point.
47
48
Args:
49
p: Point to double (G1 or G2)
50
51
Returns:
52
Point of same type representing 2 * p
53
"""
54
55
def multiply(p, n):
56
"""
57
Multiply a point by a scalar.
58
59
Args:
60
p: Point to multiply (G1 or G2)
61
n (int): Scalar multiplier
62
63
Returns:
64
Point of same type representing n * p
65
"""
66
67
def neg(p):
68
"""
69
Negate a point.
70
71
Args:
72
p: Point to negate (G1 or G2)
73
74
Returns:
75
Point of same type representing -p
76
"""
77
```
78
79
### Point Properties and Validation
80
81
Functions to check point properties and validate curve membership.
82
83
```python { .api }
84
def eq(p1, p2) -> bool:
85
"""
86
Test if two points are equal.
87
88
Args:
89
p1: First point
90
p2: Second point
91
92
Returns:
93
bool: True if points are equal, False otherwise
94
"""
95
96
def is_inf(p) -> bool:
97
"""
98
Check if a point is the point at infinity.
99
100
Args:
101
p: Point to check
102
103
Returns:
104
bool: True if point is at infinity, False otherwise
105
"""
106
107
def is_on_curve(p) -> bool:
108
"""
109
Verify that a point lies on the curve.
110
111
Args:
112
p: Point to validate
113
114
Returns:
115
bool: True if point is on curve, False otherwise
116
"""
117
```
118
119
### Bilinear Pairing Operations
120
121
Pairing functions that map pairs of points to elements in the target group GT.
122
123
```python { .api }
124
def pairing(p1, p2):
125
"""
126
Compute the bilinear pairing e(p1, p2).
127
128
Args:
129
p1: Point in G1
130
p2: Point in G2
131
132
Returns:
133
Element in GT (degree 12 extension field)
134
"""
135
136
def final_exponentiate(p):
137
"""
138
Perform the final exponentiation step of pairing computation.
139
140
Args:
141
p: Element from the Miller loop computation
142
143
Returns:
144
Final pairing result in GT
145
"""
146
```
147
148
## Field Elements
149
150
The BN128 curve operations work with various field elements:
151
152
```python { .api }
153
# Field element types (imported from py_ecc.fields)
154
FQ # Base field element (Fp)
155
FQ2 # Quadratic extension field element (Fp2)
156
FQ12 # Degree 12 extension field element (Fp12, target group GT)
157
FQP # General polynomial field element
158
```
159
160
## Usage Examples
161
162
### Basic Point Operations
163
164
```python
165
from py_ecc.bn128 import G1, G2, multiply, add, is_on_curve, eq
166
167
# Scalar multiplication
168
point1 = multiply(G1, 123)
169
point2 = multiply(G1, 456)
170
171
# Point addition
172
sum_point = add(point1, point2)
173
174
# Verify points are on curve
175
assert is_on_curve(point1)
176
assert is_on_curve(point2)
177
assert is_on_curve(sum_point)
178
179
# This should equal (123 + 456) * G1
180
expected = multiply(G1, 123 + 456)
181
assert eq(sum_point, expected)
182
```
183
184
### Pairing Computation
185
186
```python
187
from py_ecc.bn128 import G1, G2, multiply, pairing
188
189
# Create some points
190
p1 = multiply(G1, 123)
191
q1 = multiply(G2, 456)
192
p2 = multiply(G1, 789)
193
q2 = multiply(G2, 321)
194
195
# Compute pairings
196
pairing1 = pairing(p1, q1)
197
pairing2 = pairing(p2, q2)
198
199
# Pairing is bilinear: e(a*P, Q) = e(P, a*Q) = e(P, Q)^a
200
a = 42
201
pa_q = pairing(multiply(p1, a), q1)
202
p_aq = pairing(p1, multiply(q1, a))
203
p_q_a = pairing1 ** a
204
205
print("Bilinearity verified")
206
```
207
208
### Ethereum Precompile Compatibility
209
210
```python
211
from py_ecc.bn128 import G1, G2, multiply, add, pairing
212
213
# Example compatible with Ethereum's bn256Add precompile
214
def bn256_add_example():
215
"""Example usage compatible with Ethereum's bn256Add precompile."""
216
# Points represented as (x, y) coordinates
217
p1 = multiply(G1, 123)
218
p2 = multiply(G1, 456)
219
220
# Addition (compatible with precompile format)
221
result = add(p1, p2)
222
return result
223
224
# Example compatible with Ethereum's bn256ScalarMul precompile
225
def bn256_scalar_mul_example():
226
"""Example usage compatible with Ethereum's bn256ScalarMul precompile."""
227
point = G1
228
scalar = 12345
229
230
# Scalar multiplication
231
result = multiply(point, scalar)
232
return result
233
234
# Example compatible with Ethereum's bn256Pairing precompile
235
def bn256_pairing_example():
236
"""Example usage compatible with Ethereum's bn256Pairing precompile."""
237
# Multiple pairing check: e(p1, q1) * e(p2, q2) = 1
238
p1 = multiply(G1, 123)
239
q1 = multiply(G2, 456)
240
p2 = multiply(G1, 789)
241
q2 = neg(multiply(G2, 321)) # Negative for pairing check
242
243
# Compute product of pairings
244
pairing1 = pairing(p1, q1)
245
pairing2 = pairing(p2, q2)
246
product = pairing1 * pairing2
247
248
# Check if product equals 1 (identity in GT)
249
from py_ecc.fields import bn128_FQ12 as FQ12
250
return product == FQ12.one()
251
```
252
253
### zkSNARK Compatibility
254
255
```python
256
from py_ecc.bn128 import G1, G2, multiply, pairing, add
257
258
def groth16_pairing_example():
259
"""Example pairing computation similar to Groth16 verification."""
260
# Simulated proof elements (in practice these come from the proof)
261
proof_a = multiply(G1, 123)
262
proof_b = multiply(G2, 456)
263
proof_c = multiply(G1, 789)
264
265
# Simulated verification key elements
266
vk_alpha = multiply(G1, 111)
267
vk_beta = multiply(G2, 222)
268
vk_gamma = multiply(G2, 333)
269
vk_delta = multiply(G2, 444)
270
271
# Groth16 pairing equation: e(A, B) = e(α, β) * e(C, γ) * ...
272
# (This is a simplified example)
273
lhs = pairing(proof_a, proof_b)
274
rhs_1 = pairing(vk_alpha, vk_beta)
275
rhs_2 = pairing(proof_c, vk_gamma)
276
277
print("zkSNARK-style pairing computation completed")
278
return lhs, rhs_1, rhs_2
279
```
280
281
### Point Validation
282
283
```python
284
from py_ecc.bn128 import G1, G2, is_on_curve, is_inf, multiply
285
286
# Validate generator points
287
assert is_on_curve(G1)
288
assert is_on_curve(G2)
289
assert not is_inf(G1)
290
assert not is_inf(G2)
291
292
# Create and validate random points
293
random_point = multiply(G1, 12345)
294
assert is_on_curve(random_point)
295
assert not is_inf(random_point)
296
297
# Check point at infinity
298
zero_point = multiply(G1, 0) # Should be point at infinity
299
assert is_inf(zero_point)
300
301
print("Point validation complete")
302
```
303
304
### Field Operations
305
306
```python
307
from py_ecc.fields import bn128_FQ as FQ, bn128_FQ2 as FQ2
308
309
# Work with field elements directly
310
a = FQ(123)
311
b = FQ(456)
312
c = a + b
313
d = a * b
314
e = a ** 3
315
316
# Quadratic extension field
317
f = FQ2([1, 2]) # 1 + 2*i where i^2 = -1
318
g = FQ2([3, 4]) # 3 + 4*i
319
h = f * g
320
321
print(f"Field arithmetic results: {c}, {d}, {e}")
322
print(f"Extension field result: {h}")
323
```
324
325
## Types
326
327
```python { .api }
328
from typing import Optional, Tuple
329
from py_ecc.fields import bn128_FQ, bn128_FQ2, bn128_FQ12
330
331
# Point types (None represents point at infinity)
332
Point2D = Optional[Tuple[bn128_FQ, bn128_FQ]]
333
Point2D_FQ2 = Optional[Tuple[bn128_FQ2, bn128_FQ2]] # For G2 points
334
335
# Field element types
336
Field = bn128_FQ
337
ExtensionField2 = bn128_FQ2
338
ExtensionField12 = bn128_FQ12
339
```
340
341
## Error Handling
342
343
BN128 operations may raise various exceptions:
344
345
- Field arithmetic errors for invalid operations
346
- Curve validation errors for points not on the curve
347
- Pairing computation errors for invalid inputs
348
349
```python
350
from py_ecc.bn128 import is_on_curve, pairing, multiply, G1, G2
351
352
try:
353
# Validate points before pairing
354
p1 = multiply(G1, some_scalar)
355
p2 = multiply(G2, some_other_scalar)
356
357
if is_on_curve(p1) and is_on_curve(p2):
358
result = pairing(p1, p2)
359
else:
360
raise ValueError("Invalid curve points")
361
362
except Exception as e:
363
print(f"Curve operation error: {e}")
364
```
365
366
## Ethereum Integration Notes
367
368
The BN128 curve is specifically designed for compatibility with Ethereum's precompiled contracts:
369
370
- **0x06 (bn256Add)**: Point addition in G1
371
- **0x07 (bn256ScalarMul)**: Scalar multiplication in G1
372
- **0x08 (bn256Pairing)**: Pairing check operation
373
374
These precompiles use specific encoding formats for points and scalars. When integrating with Ethereum smart contracts, ensure proper encoding/decoding of curve points and field elements.