Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

derive constants from BN parameter #3

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions py_ecc/optimized_bn128/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from .optimized_field_elements import field_modulus, FQ, FQP, FQ2, FQ12
from .optimized_curve import add, double, multiply, is_inf, is_on_curve, eq, neg, twist, b, b2, b12, curve_order, G1, G2, G12, normalize
from .optimized_field_elements import FQ, FQP, FQ2, FQ12
from .optimized_curve import add, double, multiply, is_inf, is_on_curve, eq, neg, twist, b, b2, b12, curve_order, G1, normalize
from .optimized_pairing import pairing, final_exponentiate
from .parameters import field_modulus
29 changes: 20 additions & 9 deletions py_ecc/optimized_bn128/optimized_curve.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from .optimized_field_elements import FQ2, FQ12, field_modulus, FQ
from .optimized_field_elements import FQ2, FQ12, FQ

curve_order = 21888242871839275222246405745257275088548364400416034343698204186575808495617
from .parameters import curve_order, field_modulus

# Curve order should be prime
assert pow(2, curve_order, curve_order) == 2
Expand All @@ -16,9 +16,6 @@

# Generator for curve over FQ
G1 = (FQ(1), FQ(2), FQ(1))
# Generator for twisted curve over FQ2
G2 = (FQ2([10857046999023057135944570762232829481370756359578518086990519993285655852781, 11559732032986387107991004021392285783925812861821192530917403151452391805634]),
FQ2([8495653923123431417604973247489272438418190587263600148770280649306958101930, 4082367875863433681332203403145435568316851327593401208105741076214120093531]), FQ2.one())

# Check if a point is the point at infinity
def is_inf(pt):
Expand All @@ -31,9 +28,6 @@ def is_on_curve(pt, b):
x, y, z = pt
return y**2 * z - x**3 == b * z**3

assert is_on_curve(G1, b)
assert is_on_curve(G2, b2)

# Elliptic curve doubling
def double(pt):
x, y, z = pt
Expand Down Expand Up @@ -118,6 +112,23 @@ def twist(pt):
nz = FQ12([zcoeffs[0]] + [0] * 5 + [zcoeffs[1]] + [0] * 5)
return (nx * w **2, ny * w**3, nz)


"""
# Generators for twisted curve over FQ2

# Generator used in libsnark alt_bn128 implementation
alt_bn128_G2 = (FQ2([10857046999023057135944570762232829481370756359578518086990519993285655852781, 11559732032986387107991004021392285783925812861821192530917403151452391805634]),
FQ2([8495653923123431417604973247489272438418190587263600148770280649306958101930, 4082367875863433681332203403145435568316851327593401208105741076214120093531]), FQ2.one())
assert is_on_curve(alt_bn128_G2, b)

# Generator used in libsnark bn128 implementation
bn128_G2 = (FQ2([15267802884793550383558706039165621050290089775961208824303765753922461897946, 9034493566019742339402378670461897774509967669562610788113215988055021632533]),
FQ2([644888581738283025171396578091639672120333224302184904896215738366765861164, 20532875081203448695448744255224543661959516361327385779878476709582931298750]), FQ2.one())
assert is_on_curve(bn128_G2, b2)

# Check that the twist creates a point that is on the curve
G12 = twist(G2)
G12 = twist(alt_bn128_G2)
assert is_on_curve(G12, b12)
G12 = twist(bn128_G2)
assert is_on_curve(G12, b12)
"""
3 changes: 1 addition & 2 deletions py_ecc/optimized_bn128/optimized_field_elements.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
field_modulus = 21888242871839275222246405745257275088696311157297823662689037894645226208583
FQ12_modulus_coeffs = [82, 0, 0, 0, 0, 0, -18, 0, 0, 0, 0, 0] # Implied + [1]
from .parameters import field_modulus, FQ12_modulus_coeffs
FQ12_mc_tuples = [(i, c) for i, c in enumerate(FQ12_modulus_coeffs) if c]

# python3 compatibility
Expand Down
15 changes: 3 additions & 12 deletions py_ecc/optimized_bn128/optimized_pairing.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,6 @@
from .optimized_curve import double, add, multiply, is_on_curve, neg, twist, b, b2, b12, curve_order, G1, G2, G12, normalize
from .optimized_curve import double, add, multiply, is_on_curve, neg, twist, b, b2, b12, curve_order, G1, normalize
from .optimized_field_elements import FQ2, FQ12, field_modulus, FQ

ate_loop_count = 29793968203157093288
log_ate_loop_count = 63
pseudo_binary_encoding = [0, 0, 0, 1, 0, 1, 0, -1, 0, 0, 1, -1, 0, 0, 1, 0,
0, 1, 1, 0, -1, 0, 0, 1, 0, -1, 0, 0, 0, 0, 1, 1,
1, 0, 0, -1, 0, 0, 1, 0, 0, 0, 0, 0, -1, 0, 0, 1,
1, 0, 0, -1, 0, 0, 0, 1, 1, 0, -1, 0, 0, 1, 0, 1, 1]

assert sum([e * 2**i for i, e in enumerate(pseudo_binary_encoding)]) == ate_loop_count

from .parameters import pseudo_binary_encoding

def normalize1(p):
x, y = normalize(p)
Expand Down Expand Up @@ -68,7 +59,7 @@ def miller_loop(Q, P, final_exponentiate=True):
return FQ12.one()
R = Q
f_num, f_den = FQ12.one(), FQ12.one()
for b in pseudo_binary_encoding[63::-1]:
for b in pseudo_binary_encoding[-2::-1]:
#for i in range(log_ate_loop_count, -1, -1):
_n, _d = linefunc(R, R, P)
f_num = f_num * f_num * _n
Expand Down
41 changes: 41 additions & 0 deletions py_ecc/optimized_bn128/parameters.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# for an explanation of the BN parameters, see https://eprint.iacr.org/2010/429.pdf
# and https://eprint.iacr.org/2005/133.pdf

BN_PARAM_U = 4965661367192848881

curve_order = 36*(BN_PARAM_U**4) + 36*(BN_PARAM_U**3) + 18*(BN_PARAM_U**2) + 6*BN_PARAM_U + 1
field_modulus = 36*(BN_PARAM_U**4) + 36*(BN_PARAM_U**3) + 24*(BN_PARAM_U**2) + 6*BN_PARAM_U + 1
ate_loop_count = 6*BN_PARAM_U + 2

#frobenius_trace = 6*(BN_PARAM_U**2) + 1
#assert field_modulus == 21888242871839275222246405745257275088696311157297823662689037894645226208583
#assert curve_order == 21888242871839275222246405745257275088548364400416034343698204186575808495617
#assert ate_loop_count = 29793968203157093288
#assert log_ate_loop_count = 63


# extension field coefficients derived (somehow?) from w^6 = (i + 9)
FQ12_modulus_coeffs = [82, 0, 0, 0, 0, 0, -18, 0, 0, 0, 0, 0] # Implied + [1]


# Non-Adjacent Form
def naf(d):
naf_repr = []
while d > 0:
d_j = d % 2
if d_j == 1 and ( (((d - d_j)//2) % 2) == 1):
d_j = -1
d = (d - d_j) // 2
naf_repr.append(d_j)
return naf_repr


# used for the miller loop in the pairing check
pseudo_binary_encoding = naf(ate_loop_count)

#pseudo_binary_encoding = [0, 0, 0, 1, 0, 1, 0, -1, 0, 0, 1, -1, 0, 0, 1, 0,
# 0, 1, 1, 0, -1, 0, 0, 1, 0, -1, 0, 0, 0, 0, 1, 1,
# 1, 0, 0, -1, 0, 0, 1, 0, 0, 0, 0, 0, -1, 0, 0, 1,
# 1, 0, 0, -1, 0, 0, 0, 1, 1, 0, -1, 0, 0, 1, 0, 1, 1]

assert sum([e * 2**i for i, e in enumerate(pseudo_binary_encoding)]) == ate_loop_count