0
# Field Arithmetic
1
2
Finite field arithmetic supporting all implemented curves with both basic and extension field operations. This module provides the fundamental mathematical operations underlying all elliptic curve computations in py-ecc.
3
4
## Base Field Classes
5
6
```python { .api }
7
# Import base field classes
8
from py_ecc.fields.field_elements import FQ, FQ2, FQ12, FQP
9
from py_ecc.fields.optimized_field_elements import (
10
FQ as optimized_FQ,
11
FQ2 as optimized_FQ2,
12
FQ12 as optimized_FQ12,
13
FQP as optimized_FQP
14
)
15
```
16
17
## Capabilities
18
19
### Basic Finite Field (FQ)
20
21
Operations in prime finite fields Fp.
22
23
```python { .api }
24
class FQ:
25
"""
26
Element of a prime finite field Fp.
27
"""
28
29
field_modulus: int # Prime modulus p
30
31
def __init__(self, val: int):
32
"""
33
Create a field element.
34
35
Args:
36
val (int): Integer value (will be reduced modulo p)
37
"""
38
39
def __add__(self, other):
40
"""Addition in the field."""
41
42
def __sub__(self, other):
43
"""Subtraction in the field."""
44
45
def __mul__(self, other):
46
"""Multiplication in the field."""
47
48
def __truediv__(self, other):
49
"""Division in the field (multiplication by inverse)."""
50
51
def __pow__(self, other):
52
"""Exponentiation in the field."""
53
54
def __eq__(self, other) -> bool:
55
"""Equality comparison."""
56
57
def __neg__(self):
58
"""Additive inverse (negation)."""
59
60
def inverse(self):
61
"""
62
Multiplicative inverse of the element.
63
64
Returns:
65
FQ: Multiplicative inverse (1/self)
66
"""
67
68
@classmethod
69
def zero(cls):
70
"""Return the additive identity (0)."""
71
72
@classmethod
73
def one(cls):
74
"""Return the multiplicative identity (1)."""
75
```
76
77
### Quadratic Extension Field (FQ2)
78
79
Operations in quadratic extension fields Fp2 = Fp[i]/(i^2 + 1).
80
81
```python { .api }
82
class FQ2:
83
"""
84
Element of quadratic extension field Fp2.
85
Represented as a + b*i where i^2 = -1.
86
"""
87
88
field_modulus: int # Base field modulus
89
FQ2_MODULUS_COEFFS: Tuple[int, int] # Coefficients for i^2 + 1
90
91
def __init__(self, coeffs: Sequence[int]):
92
"""
93
Create an Fp2 element.
94
95
Args:
96
coeffs: [a, b] representing a + b*i
97
"""
98
99
def __add__(self, other):
100
"""Addition in Fp2."""
101
102
def __sub__(self, other):
103
"""Subtraction in Fp2."""
104
105
def __mul__(self, other):
106
"""Multiplication in Fp2."""
107
108
def __truediv__(self, other):
109
"""Division in Fp2."""
110
111
def __pow__(self, other):
112
"""Exponentiation in Fp2."""
113
114
def __eq__(self, other) -> bool:
115
"""Equality comparison."""
116
117
def __neg__(self):
118
"""Additive inverse."""
119
120
def inverse(self):
121
"""Multiplicative inverse in Fp2."""
122
123
def norm(self):
124
"""Norm of the element (a^2 + b^2)."""
125
126
def conjugate(self):
127
"""Complex conjugate (a - b*i)."""
128
129
@classmethod
130
def zero(cls):
131
"""Additive identity in Fp2."""
132
133
@classmethod
134
def one(cls):
135
"""Multiplicative identity in Fp2."""
136
```
137
138
### Degree-12 Extension Field (FQ12)
139
140
Operations in degree-12 extension fields Fp12 used as the target group for pairings.
141
142
```python { .api }
143
class FQ12:
144
"""
145
Element of degree-12 extension field Fp12.
146
Used as the target group GT for bilinear pairings.
147
"""
148
149
field_modulus: int # Base field modulus
150
FQ12_MODULUS_COEFFS: Tuple[int, ...] # Coefficients for the irreducible polynomial
151
152
def __init__(self, coeffs: Sequence[int]):
153
"""
154
Create an Fp12 element.
155
156
Args:
157
coeffs: 12 coefficients representing the polynomial
158
"""
159
160
def __add__(self, other):
161
"""Addition in Fp12."""
162
163
def __sub__(self, other):
164
"""Subtraction in Fp12."""
165
166
def __mul__(self, other):
167
"""Multiplication in Fp12."""
168
169
def __truediv__(self, other):
170
"""Division in Fp12."""
171
172
def __pow__(self, other):
173
"""Exponentiation in Fp12."""
174
175
def __eq__(self, other) -> bool:
176
"""Equality comparison."""
177
178
def __neg__(self):
179
"""Additive inverse."""
180
181
def inverse(self):
182
"""Multiplicative inverse in Fp12."""
183
184
@classmethod
185
def zero(cls):
186
"""Additive identity in Fp12."""
187
188
@classmethod
189
def one(cls):
190
"""Multiplicative identity in Fp12."""
191
```
192
193
### General Polynomial Field (FQP)
194
195
Base class for polynomial field extensions.
196
197
```python { .api }
198
class FQP:
199
"""
200
Base class for polynomial field extensions.
201
"""
202
203
field_modulus: int # Base field modulus
204
205
def __init__(self, coeffs: Sequence[int]):
206
"""Initialize with polynomial coefficients."""
207
208
def degree(self) -> int:
209
"""Degree of the polynomial representation."""
210
211
def __add__(self, other):
212
"""Polynomial addition."""
213
214
def __sub__(self, other):
215
"""Polynomial subtraction."""
216
217
def __mul__(self, other):
218
"""Polynomial multiplication with reduction."""
219
220
def __eq__(self, other) -> bool:
221
"""Polynomial equality."""
222
```
223
224
## Curve-Specific Field Classes
225
226
### BN128 Fields
227
228
```python { .api }
229
# BN128 curve fields
230
from py_ecc.fields import (
231
bn128_FQ, # Base field for BN128
232
bn128_FQ2, # Quadratic extension for BN128
233
bn128_FQ12, # Degree-12 extension for BN128 (GT)
234
bn128_FQP # General polynomial field for BN128
235
)
236
237
# Optimized BN128 fields
238
from py_ecc.fields import (
239
optimized_bn128_FQ,
240
optimized_bn128_FQ2,
241
optimized_bn128_FQ12,
242
optimized_bn128_FQP
243
)
244
```
245
246
### BLS12-381 Fields
247
248
```python { .api }
249
# BLS12-381 curve fields
250
from py_ecc.fields import (
251
bls12_381_FQ, # Base field for BLS12-381
252
bls12_381_FQ2, # Quadratic extension for BLS12-381
253
bls12_381_FQ12, # Degree-12 extension for BLS12-381 (GT)
254
bls12_381_FQP # General polynomial field for BLS12-381
255
)
256
257
# Optimized BLS12-381 fields
258
from py_ecc.fields import (
259
optimized_bls12_381_FQ,
260
optimized_bls12_381_FQ2,
261
optimized_bls12_381_FQ12,
262
optimized_bls12_381_FQP
263
)
264
```
265
266
### Field Properties
267
268
```python { .api }
269
from py_ecc.fields.field_properties import field_properties
270
271
# Access curve parameters
272
bn128_params = field_properties["bn128"]
273
bls12_381_params = field_properties["bls12_381"]
274
275
# Available parameters:
276
# - field_modulus: Prime modulus for the base field
277
# - fq2_modulus_coeffs: Coefficients for Fp2 construction
278
# - fq12_modulus_coeffs: Coefficients for Fp12 construction
279
```
280
281
## Usage Examples
282
283
### Basic Field Arithmetic
284
285
```python
286
from py_ecc.fields import bls12_381_FQ as FQ
287
288
# Create field elements
289
a = FQ(123)
290
b = FQ(456)
291
292
# Basic operations
293
sum_val = a + b
294
diff_val = a - b
295
product = a * b
296
quotient = a / b
297
power = a ** 3
298
299
# Special elements
300
zero = FQ.zero()
301
one = FQ.one()
302
neg_a = -a
303
inv_a = a.inverse()
304
305
print(f"Field operations: {sum_val}, {product}, {power}")
306
```
307
308
### Quadratic Extension Field
309
310
```python
311
from py_ecc.fields import bls12_381_FQ2 as FQ2
312
313
# Create Fp2 elements: a + b*i
314
x = FQ2([1, 2]) # 1 + 2*i
315
y = FQ2([3, 4]) # 3 + 4*i
316
317
# Complex arithmetic
318
sum_xy = x + y # (1+3) + (2+4)*i = 4 + 6*i
319
product_xy = x * y # (1 + 2*i)(3 + 4*i) = (3-8) + (6+4)*i = -5 + 10*i
320
321
# Special operations
322
norm_x = x.norm() # 1^2 + 2^2 = 5
323
conjugate_x = x.conjugate() # 1 - 2*i
324
inverse_x = x.inverse() # 1/(1 + 2*i)
325
326
print(f"Fp2 operations: {sum_xy}, {product_xy}, {norm_x}")
327
```
328
329
### Target Group Operations (Fp12)
330
331
```python
332
from py_ecc.fields import bls12_381_FQ12 as FQ12
333
334
# Create Fp12 elements (12 coefficients)
335
coeffs1 = [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] # 1
336
coeffs2 = [0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] # generator element
337
338
gt_element1 = FQ12(coeffs1)
339
gt_element2 = FQ12(coeffs2)
340
341
# Target group operations (used in pairing results)
342
product = gt_element1 * gt_element2
343
power = gt_element1 ** 12345
344
345
# Check for identity
346
is_identity = (product == FQ12.one())
347
348
print(f"Target group operations completed: {is_identity}")
349
```
350
351
### Cross-Curve Field Compatibility
352
353
```python
354
from py_ecc.fields import bn128_FQ, bls12_381_FQ
355
356
# Different curves have different field moduli
357
bn128_element = bn128_FQ(123)
358
bls12_381_element = bls12_381_FQ(123)
359
360
# These are elements of different fields
361
print(f"BN128 field modulus: {bn128_FQ.field_modulus}")
362
print(f"BLS12-381 field modulus: {bls12_381_FQ.field_modulus}")
363
364
# Operations are only valid within the same field
365
bn128_sum = bn128_element + bn128_FQ(456)
366
bls12_381_sum = bls12_381_element + bls12_381_FQ(456)
367
```
368
369
### Optimized vs Reference Fields
370
371
```python
372
import time
373
from py_ecc.fields import bls12_381_FQ as RefFQ
374
from py_ecc.fields import optimized_bls12_381_FQ as OptFQ
375
376
# Performance comparison
377
a_ref = RefFQ(12345)
378
b_ref = RefFQ(67890)
379
380
a_opt = OptFQ(12345)
381
b_opt = OptFQ(67890)
382
383
# Time reference implementation
384
start = time.time()
385
for _ in range(10000):
386
result_ref = a_ref * b_ref
387
ref_time = time.time() - start
388
389
# Time optimized implementation
390
start = time.time()
391
for _ in range(10000):
392
result_opt = a_opt * b_opt
393
opt_time = time.time() - start
394
395
print(f"Reference time: {ref_time:.4f}s")
396
print(f"Optimized time: {opt_time:.4f}s")
397
print(f"Speedup: {ref_time/opt_time:.2f}x")
398
```
399
400
### Field Extension Tower
401
402
```python
403
from py_ecc.fields import (
404
bls12_381_FQ as FQ,
405
bls12_381_FQ2 as FQ2,
406
bls12_381_FQ12 as FQ12
407
)
408
409
# Build field extension tower: Fp -> Fp2 -> Fp12
410
base_element = FQ(123)
411
412
# Embed in Fp2 as constant term
413
fp2_element = FQ2([base_element.n, 0])
414
415
# Elements can be lifted through the tower
416
# but operations must respect the field structure
417
print(f"Field tower: Fp -> Fp2 -> Fp12")
418
print(f"Base: {base_element}")
419
print(f"In Fp2: {fp2_element}")
420
```
421
422
## Utility Functions
423
424
```python { .api }
425
from py_ecc.utils import prime_field_inv, deg, poly_rounded_div
426
427
def prime_field_inv(a: int, n: int) -> int:
428
"""
429
Compute modular inverse using extended Euclidean algorithm.
430
431
Args:
432
a (int): Element to invert
433
n (int): Modulus
434
435
Returns:
436
int: Modular inverse of a modulo n
437
"""
438
439
def deg(p: Sequence) -> int:
440
"""
441
Compute degree of polynomial representation.
442
443
Args:
444
p: Polynomial coefficients
445
446
Returns:
447
int: Degree of the polynomial
448
"""
449
450
def poly_rounded_div(a: Sequence, b: Sequence) -> Tuple:
451
"""
452
Polynomial division with rounding.
453
454
Args:
455
a: Dividend polynomial coefficients
456
b: Divisor polynomial coefficients
457
458
Returns:
459
Tuple: Quotient coefficients
460
"""
461
```
462
463
## Error Handling
464
465
Field operations may raise various exceptions:
466
467
- `ZeroDivisionError`: Division by zero or computing inverse of zero
468
- `ValueError`: Invalid field element construction
469
- `TypeError`: Incompatible field operations
470
471
```python
472
from py_ecc.fields import bls12_381_FQ as FQ
473
474
try:
475
a = FQ(123)
476
b = FQ(0)
477
478
# This will raise ZeroDivisionError
479
result = a / b
480
481
except ZeroDivisionError:
482
print("Cannot divide by zero in field")
483
except ValueError as e:
484
print(f"Invalid field operation: {e}")
485
```