Elliptic curve crypto in python including secp256k1, alt_bn128, and bls12_381
—
Reference implementation of BLS12-381 elliptic curve operations including point arithmetic and bilinear pairings. This curve is used in Ethereum 2.0 and other modern blockchain applications for its security properties and efficient pairing operations.
# Generator points
G1 # Generator point on G1 (base curve)
G2 # Generator point on G2 (twist curve)
G12 # Identity element in GT (target group)
# Points at infinity
Z1 # Point at infinity for G1
Z2 # Point at infinity for G2
# Curve parameters
b: int # Curve coefficient for G1: y^2 = x^3 + b
b2 # Curve coefficient for G2 (quadratic extension)
b12 # Curve coefficient for G12 (degree 12 extension)
curve_order: int # Order of the curve
field_modulus: int # Prime modulus of the base field
twist # Twist parameter for G2Basic elliptic curve point operations for both G1 and G2 groups.
def add(p1, p2):
"""
Add two elliptic curve points.
Args:
p1: First point (G1 or G2)
p2: Second point (G1 or G2, same type as p1)
Returns:
Point of same type as inputs representing p1 + p2
"""
def double(p):
"""
Double an elliptic curve point.
Args:
p: Point to double (G1 or G2)
Returns:
Point of same type representing 2 * p
"""
def multiply(p, n):
"""
Multiply a point by a scalar.
Args:
p: Point to multiply (G1 or G2)
n (int): Scalar multiplier
Returns:
Point of same type representing n * p
"""
def neg(p):
"""
Negate a point.
Args:
p: Point to negate (G1 or G2)
Returns:
Point of same type representing -p
"""Functions to check point properties and validate curve membership.
def eq(p1, p2) -> bool:
"""
Test if two points are equal.
Args:
p1: First point
p2: Second point
Returns:
bool: True if points are equal, False otherwise
"""
def is_inf(p) -> bool:
"""
Check if a point is the point at infinity.
Args:
p: Point to check
Returns:
bool: True if point is at infinity, False otherwise
"""
def is_on_curve(p) -> bool:
"""
Verify that a point lies on the curve.
Args:
p: Point to validate
Returns:
bool: True if point is on curve, False otherwise
"""Pairing functions that map pairs of points to elements in the target group GT.
def pairing(p1, p2):
"""
Compute the bilinear pairing e(p1, p2).
Args:
p1: Point in G1
p2: Point in G2
Returns:
Element in GT (degree 12 extension field)
"""
def final_exponentiate(p):
"""
Perform the final exponentiation step of pairing computation.
Args:
p: Element from the Miller loop computation
Returns:
Final pairing result in GT
"""The BLS12-381 curve operations work with various field elements:
# Field element types (imported from py_ecc.fields)
FQ # Base field element (Fp)
FQ2 # Quadratic extension field element (Fp2)
FQ12 # Degree 12 extension field element (Fp12, target group GT)
FQP # General polynomial field elementfrom py_ecc.bls12_381 import G1, G2, multiply, add, is_on_curve
# Scalar multiplication
point1 = multiply(G1, 123)
point2 = multiply(G1, 456)
# Point addition
sum_point = add(point1, point2)
# Verify points are on curve
assert is_on_curve(point1)
assert is_on_curve(point2)
assert is_on_curve(sum_point)
# This should equal (123 + 456) * G1
expected = multiply(G1, 123 + 456)
assert eq(sum_point, expected)from py_ecc.bls12_381 import G1, G2, multiply, pairing
# Create some points
p1 = multiply(G1, 123)
q1 = multiply(G2, 456)
p2 = multiply(G1, 789)
q2 = multiply(G2, 321)
# Compute pairings
pairing1 = pairing(p1, q1)
pairing2 = pairing(p2, q2)
# Pairing is bilinear: e(a*P, Q) = e(P, a*Q) = e(P, Q)^a
a = 42
pa_q = pairing(multiply(p1, a), q1)
p_aq = pairing(p1, multiply(q1, a))
p_q_a = pairing1 ** a
# All should be equal (up to field arithmetic precision)
print("Bilinearity verified")from py_ecc.bls12_381 import G1, G2, multiply, pairing
from py_ecc.fields import bls12_381_FQ12 as FQ12
# Multiple pairing computation
points_g1 = [multiply(G1, i) for i in [1, 2, 3]]
points_g2 = [multiply(G2, i) for i in [4, 5, 6]]
# Compute individual pairings
pairings = [pairing(p1, p2) for p1, p2 in zip(points_g1, points_g2)]
# Product of pairings
result = FQ12.one()
for p in pairings:
result = result * p
print(f"Multi-pairing result computed")from py_ecc.bls12_381 import G1, G2, is_on_curve, is_inf, multiply
from py_ecc.fields import bls12_381_FQ as FQ
# Validate generator points
assert is_on_curve(G1)
assert is_on_curve(G2)
assert not is_inf(G1)
assert not is_inf(G2)
# Create and validate random points
random_point = multiply(G1, 12345)
assert is_on_curve(random_point)
assert not is_inf(random_point)
# Check point at infinity
zero_point = multiply(G1, 0) # Should be point at infinity
assert is_inf(zero_point)
print("Point validation complete")from py_ecc.fields import bls12_381_FQ as FQ, bls12_381_FQ2 as FQ2
# Work with field elements directly
a = FQ(123)
b = FQ(456)
c = a + b
d = a * b
e = a ** 3
# Quadratic extension field
f = FQ2([1, 2]) # 1 + 2*i where i^2 = -1
g = FQ2([3, 4]) # 3 + 4*i
h = f * g
print(f"Field arithmetic results: {c}, {d}, {e}")
print(f"Extension field result: {h}")from typing import Optional, Tuple
from py_ecc.fields import bls12_381_FQ, bls12_381_FQ2
# Point types (None represents point at infinity)
Point2D = Optional[Tuple[bls12_381_FQ, bls12_381_FQ]]
Point2D_FQ2 = Optional[Tuple[bls12_381_FQ2, bls12_381_FQ2]] # For G2 points
# Field element types
Field = bls12_381_FQ
ExtensionField2 = bls12_381_FQ2
ExtensionField12 = bls12_381_FQ12BLS12-381 operations may raise various exceptions:
from py_ecc.bls12_381 import is_on_curve, pairing, multiply, G1, G2
try:
# Validate points before pairing
p1 = multiply(G1, some_scalar)
p2 = multiply(G2, some_other_scalar)
if is_on_curve(p1) and is_on_curve(p2):
result = pairing(p1, p2)
else:
raise ValueError("Invalid curve points")
except Exception as e:
print(f"Curve operation error: {e}")Install with Tessl CLI
npx tessl i tessl/pypi-py-ecc