Elliptic curve crypto in python including secp256k1, alt_bn128, and bls12_381
—
High-performance versions of BLS12-381 and BN128 operations with additional specialized functions for production use. These optimized implementations provide significant performance improvements over the reference implementations while maintaining the same API.
# Import optimized BLS12-381 operations
from py_ecc.optimized_bls12_381 import (
G1, G2, G12, Z1, Z2,
add, double, multiply, neg, eq, is_inf, is_on_curve, normalize,
pairing, final_exponentiate,
multiply_clear_cofactor_G1, multiply_clear_cofactor_G2,
optimized_swu_G1, optimized_swu_G2, iso_map_G1, iso_map_G2,
curve_order, field_modulus, twist, b, b2, b12
)# Import optimized BN128 operations
from py_ecc.optimized_bn128 import (
G1, G2, G12, Z1, Z2,
add, double, multiply, neg, eq, is_inf, is_on_curve, normalize,
pairing, final_exponentiate,
curve_order, field_modulus, twist, b, b2, b12
)All standard point operations with optimized implementations for better performance.
def add(p1, p2):
"""Optimized point addition with improved performance."""
def double(p):
"""Optimized point doubling with improved performance."""
def multiply(p, n):
"""Optimized scalar multiplication with windowing and precomputation."""
def normalize(p):
"""
Normalize a point to affine coordinates.
Args:
p: Point in projective or jacobian coordinates
Returns:
Point in affine coordinates (x, y)
"""Additional operations specific to BLS12-381 that are not available in the reference implementation.
def multiply_clear_cofactor_G1(p):
"""
Clear the cofactor for a G1 point to ensure it's in the correct subgroup.
Args:
p: Point in G1 (may not be in correct subgroup)
Returns:
Point in the correct G1 subgroup
"""
def multiply_clear_cofactor_G2(p):
"""
Clear the cofactor for a G2 point to ensure it's in the correct subgroup.
Args:
p: Point in G2 (may not be in correct subgroup)
Returns:
Point in the correct G2 subgroup
"""Optimized implementations of hash-to-curve operations for BLS12-381.
def optimized_swu_G1(t):
"""
Optimized Simplified SWU hash-to-curve for G1.
Args:
t: Field element to map to curve
Returns:
Point on the G1 curve
"""
def optimized_swu_G2(t):
"""
Optimized Simplified SWU hash-to-curve for G2.
Args:
t: Field element (in Fp2) to map to curve
Returns:
Point on the G2 curve
"""
def iso_map_G1(p):
"""
Apply the isomorphism map for G1 points.
Args:
p: Point on the isogenous curve
Returns:
Point on the target G1 curve
"""
def iso_map_G2(p):
"""
Apply the isomorphism map for G2 points.
Args:
p: Point on the isogenous curve
Returns:
Point on the target G2 curve
"""Optimized pairing computations with better performance characteristics.
def pairing(p1, p2):
"""
Optimized bilinear pairing computation.
Args:
p1: Point in G1
p2: Point in G2
Returns:
Element in GT with optimized computation
"""
def final_exponentiate(p):
"""
Optimized final exponentiation for pairing.
Args:
p: Element from Miller loop
Returns:
Final pairing result with optimized exponentiation
"""import time
from py_ecc.bls12_381 import multiply as ref_multiply, G1 as ref_G1
from py_ecc.optimized_bls12_381 import multiply as opt_multiply, G1 as opt_G1
# Large scalar for performance testing
large_scalar = 2**128 + 12345
# Reference implementation timing
start = time.time()
ref_result = ref_multiply(ref_G1, large_scalar)
ref_time = time.time() - start
# Optimized implementation timing
start = time.time()
opt_result = opt_multiply(opt_G1, large_scalar)
opt_time = time.time() - start
print(f"Reference time: {ref_time:.4f}s")
print(f"Optimized time: {opt_time:.4f}s")
print(f"Speedup: {ref_time/opt_time:.2f}x")from py_ecc.optimized_bls12_381 import (
G1, G2, multiply_clear_cofactor_G1, multiply_clear_cofactor_G2,
is_on_curve
)
# Create points that may not be in the correct subgroup
# (In practice, these might come from untrusted sources)
point_g1 = multiply(G1, 12345)
point_g2 = multiply(G2, 67890)
# Ensure points are in correct subgroups
cleared_g1 = multiply_clear_cofactor_G1(point_g1)
cleared_g2 = multiply_clear_cofactor_G2(point_g2)
# Verify they're still on the curve
assert is_on_curve(cleared_g1)
assert is_on_curve(cleared_g2)
print("Subgroup clearing completed")from py_ecc.optimized_bls12_381 import (
optimized_swu_G1, optimized_swu_G2,
iso_map_G1, iso_map_G2,
multiply_clear_cofactor_G1, multiply_clear_cofactor_G2
)
from py_ecc.fields import optimized_bls12_381_FQ as FQ, optimized_bls12_381_FQ2 as FQ2
def hash_to_g1(data: bytes):
"""Complete hash-to-G1 pipeline."""
# In practice, you'd hash the data to get field elements
# This is a simplified example
t = FQ(int.from_bytes(data[:32], 'big'))
# Apply SWU map
point = optimized_swu_G1(t)
# Apply isomorphism
iso_point = iso_map_G1(point)
# Clear cofactor
final_point = multiply_clear_cofactor_G1(iso_point)
return final_point
def hash_to_g2(data: bytes):
"""Complete hash-to-G2 pipeline."""
# Create Fp2 element from data
t = FQ2([
int.from_bytes(data[:32], 'big'),
int.from_bytes(data[32:64], 'big')
])
# Apply SWU map
point = optimized_swu_G2(t)
# Apply isomorphism
iso_point = iso_map_G2(point)
# Clear cofactor
final_point = multiply_clear_cofactor_G2(iso_point)
return final_point
# Example usage
message = b"Hello, hash-to-curve!" + b"\x00" * 43 # Pad to 64 bytes
g1_point = hash_to_g1(message)
g2_point = hash_to_g2(message)
print("Hash-to-curve operations completed")from py_ecc.optimized_bls12_381 import G1, G2, multiply, pairing
from py_ecc.fields import optimized_bls12_381_FQ12 as FQ12
def optimized_multi_pairing(g1_points, g2_points):
"""Compute product of multiple pairings efficiently."""
assert len(g1_points) == len(g2_points)
# Compute individual pairings
pairings = []
for p1, p2 in zip(g1_points, g2_points):
pairings.append(pairing(p1, p2))
# Multiply all results
result = FQ12.one()
for p in pairings:
result = result * p
return result
# Example: Aggregate signature verification style computation
g1_points = [multiply(G1, i) for i in [123, 456, 789]]
g2_points = [multiply(G2, i) for i in [321, 654, 987]]
multi_pairing_result = optimized_multi_pairing(g1_points, g2_points)
print("Multi-pairing computation completed")from py_ecc.optimized_bls12_381 import G1, multiply, normalize, add
# Operations may result in points in projective coordinates
p1 = multiply(G1, 123)
p2 = multiply(G1, 456)
sum_point = add(p1, p2)
# Normalize to affine coordinates for storage or transmission
normalized_point = normalize(sum_point)
print(f"Point normalized to affine coordinates")from py_ecc.optimized_bls12_381 import pairing, G1, multiply
from py_ecc.bls.g2_primitives import signature_to_G2, pubkey_to_G1
def fast_bls_verify(pubkey_bytes, message_hash_point, signature_bytes):
"""
Fast BLS signature verification using optimized operations.
Args:
pubkey_bytes: 48-byte compressed public key
message_hash_point: Pre-computed hash-to-curve of message
signature_bytes: 96-byte signature
Returns:
bool: True if signature is valid
"""
try:
# Convert bytes to curve points
pubkey = pubkey_to_G1(pubkey_bytes)
signature = signature_to_G2(signature_bytes)
# Pairing check: e(H(m), pk) == e(sig, G1)
lhs = pairing(message_hash_point, pubkey)
rhs = pairing(signature, G1)
return lhs == rhs
except:
return False
# Example usage would require proper message hashing
print("Fast BLS verification function defined")The optimized implementations provide significant performance improvements:
For production applications requiring high throughput (like blockchain consensus), always prefer the optimized implementations over the reference versions.
The optimized implementations maintain API compatibility with their reference counterparts:
The only differences are in performance characteristics and the availability of additional specialized functions in the optimized versions.
Install with Tessl CLI
npx tessl i tessl/pypi-py-ecc