CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-py-ecc

Elliptic curve crypto in python including secp256k1, alt_bn128, and bls12_381

Pending
Overview
Eval results
Files

bn128.mddocs/

BN128 Curve

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.

Constants and Generator Points

# 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 G2

Capabilities

Point Arithmetic

Basic 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
    """

Point Properties and Validation

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
    """

Bilinear Pairing Operations

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
    """

Field Elements

The BN128 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 element

Usage Examples

Basic Point Operations

from py_ecc.bn128 import G1, G2, multiply, add, is_on_curve, eq

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

Pairing Computation

from py_ecc.bn128 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

print("Bilinearity verified")

Ethereum Precompile Compatibility

from py_ecc.bn128 import G1, G2, multiply, add, pairing

# Example compatible with Ethereum's bn256Add precompile
def bn256_add_example():
    """Example usage compatible with Ethereum's bn256Add precompile."""
    # Points represented as (x, y) coordinates
    p1 = multiply(G1, 123)
    p2 = multiply(G1, 456)
    
    # Addition (compatible with precompile format)
    result = add(p1, p2)
    return result

# Example compatible with Ethereum's bn256ScalarMul precompile  
def bn256_scalar_mul_example():
    """Example usage compatible with Ethereum's bn256ScalarMul precompile."""
    point = G1
    scalar = 12345
    
    # Scalar multiplication
    result = multiply(point, scalar)
    return result

# Example compatible with Ethereum's bn256Pairing precompile
def bn256_pairing_example():
    """Example usage compatible with Ethereum's bn256Pairing precompile."""
    # Multiple pairing check: e(p1, q1) * e(p2, q2) = 1
    p1 = multiply(G1, 123)
    q1 = multiply(G2, 456)
    p2 = multiply(G1, 789)
    q2 = neg(multiply(G2, 321))  # Negative for pairing check
    
    # Compute product of pairings
    pairing1 = pairing(p1, q1)
    pairing2 = pairing(p2, q2)
    product = pairing1 * pairing2
    
    # Check if product equals 1 (identity in GT)
    from py_ecc.fields import bn128_FQ12 as FQ12
    return product == FQ12.one()

zkSNARK Compatibility

from py_ecc.bn128 import G1, G2, multiply, pairing, add

def groth16_pairing_example():
    """Example pairing computation similar to Groth16 verification."""
    # Simulated proof elements (in practice these come from the proof)
    proof_a = multiply(G1, 123)
    proof_b = multiply(G2, 456)
    proof_c = multiply(G1, 789)
    
    # Simulated verification key elements
    vk_alpha = multiply(G1, 111)
    vk_beta = multiply(G2, 222)
    vk_gamma = multiply(G2, 333)
    vk_delta = multiply(G2, 444)
    
    # Groth16 pairing equation: e(A, B) = e(α, β) * e(C, γ) * ...
    # (This is a simplified example)
    lhs = pairing(proof_a, proof_b)
    rhs_1 = pairing(vk_alpha, vk_beta)
    rhs_2 = pairing(proof_c, vk_gamma)
    
    print("zkSNARK-style pairing computation completed")
    return lhs, rhs_1, rhs_2

Point Validation

from py_ecc.bn128 import G1, G2, is_on_curve, is_inf, multiply

# 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")

Field Operations

from py_ecc.fields import bn128_FQ as FQ, bn128_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}")

Types

from typing import Optional, Tuple
from py_ecc.fields import bn128_FQ, bn128_FQ2, bn128_FQ12

# Point types (None represents point at infinity)
Point2D = Optional[Tuple[bn128_FQ, bn128_FQ]]
Point2D_FQ2 = Optional[Tuple[bn128_FQ2, bn128_FQ2]]  # For G2 points

# Field element types
Field = bn128_FQ
ExtensionField2 = bn128_FQ2
ExtensionField12 = bn128_FQ12

Error Handling

BN128 operations may raise various exceptions:

  • Field arithmetic errors for invalid operations
  • Curve validation errors for points not on the curve
  • Pairing computation errors for invalid inputs
from py_ecc.bn128 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}")

Ethereum Integration Notes

The BN128 curve is specifically designed for compatibility with Ethereum's precompiled contracts:

  • 0x06 (bn256Add): Point addition in G1
  • 0x07 (bn256ScalarMul): Scalar multiplication in G1
  • 0x08 (bn256Pairing): Pairing check operation

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.

Install with Tessl CLI

npx tessl i tessl/pypi-py-ecc

docs

bls-signatures.md

bls12-381.md

bn128.md

fields.md

index.md

optimized.md

secp256k1.md

tile.json