def add_mixed_hmv( pt1, pt2: Optimized_Point3D[Optimized_Field] ) -> Optimized_Point3D[Optimized_Field]: x1, y1, z1 = pt1 x2, y2, z2 = pt2 assert z2 == FQ2.one() T1 = z1 * z1 T2 = T1 * z1 T1 = T1 * x2 T2 = T2 * y2 T1 = T1 - x1 T2 = T2 - y1 if T1 == FQ2.zero(): if T2 == FQ2.zero(): return double(pt1) return inf z3 = z1 * T1 T3 = T1 * T1 T4 = T3 * T1 T3 = T3 * x1 T1 = 2 * T3 x3 = T2 * T2 x3 = x3 - T1 x3 = x3 - T4 T3 = T3 - x3 T3 = T3 * T2 T4 = T4 * y1 y3 = T3 - T4 return (x3, y3, z3)
def normalize( pt: Optimized_Point3D[Optimized_Field], ) -> Optimized_Point3D[Optimized_Field]: x1, y1, z1 = pt z = z1.inv() z2 = z * z x3 = x1 * z2 y3 = y1 * z2 * z return (x3, y3, FQ2.one())
def _try_sqrt_in_fp2(a: FQ2) -> FQ2: a1 = a**P_MINUS3_OVER4 alpha = a1 * a1 * a x0 = a1 * a if alpha == FQ2([-1, 0]): return FQ2((x0.coeffs[1], x0.coeffs[0])) alpha = alpha + FQ2.one() alpha = alpha**P_MINUS1_OVER2 return alpha * x0
def pubkey_to_g2(pub: Pubkey) -> G2Point: g2 = ( FQ2([big_endian_to_int(pub[:32]), big_endian_to_int(pub[32:64])]), FQ2([big_endian_to_int(pub[64:96]), big_endian_to_int(pub[96:])]), FQ2.one(), ) assert is_valid_g2_point(g2) return g2
def map_to_g2(raw_hash: FQ2) -> G2Point: one = FQ2.one() x = raw_hash while True: y = x * x * x + b2 y = sqrt(y) if y is not None: break x += one h = multiply((x, y, one), COFACTOR_G2) assert is_on_curve(h, b2) return h
def signature_to_G2(signature: Signature) -> G2Point: g2 = ( FQ2([ big_endian_to_int(signature[:32]), big_endian_to_int(signature[32:64]) ]), FQ2([ big_endian_to_int(signature[64:96]), big_endian_to_int(signature[96:]) ]), FQ2.one(), ) assert is_g2_on_curve(g2) return g2
def _normalize(p1) -> Optimized_Point3D[Optimized_Field]: x, y = normalize(p1) return (x, y, FQ2.one())
def sign(msg: Message, priv: PrivateKey) -> Signature: x, y = normalize(multiply(hash_to_g2(msg), priv)) g2 = (x, y, FQ2.one()) return G2_to_signature(g2)
from py_ecc.optimized_bn128 import FQ2, b2 as B from py_ecc.typing import Optimized_Field, Optimized_Point3D inf = (FQ2.zero(), FQ2.one(), FQ2.zero()) def double( pt: Optimized_Point3D[Optimized_Field], ) -> Optimized_Point3D[Optimized_Field]: x, y, z = pt A = x * x B = y * y C = B * B t = x + B D = 2 * (t * t - A - C) E = 3 * A F = E * E x3 = F - 2 * D y3 = E * (D - x3) - 8 * C z3 = 2 * z * y return (x3, y3, z3) def add( pt1, pt2: Optimized_Point3D[Optimized_Field] ) -> Optimized_Point3D[Optimized_Field]: x1, y1, z1 = pt1 x2, y2, z2 = pt2 Z1Z1 = z1 * z1 Z2Z2 = z2 * z2 U1 = x1 * Z2Z2
def priv_to_pub(priv: PrivateKey) -> Pubkey: x, y = normalize(multiply(G2, priv)) g2 = (x, y, FQ2.one()) return g2_to_pubkey(g2)
def _normalize(p1): x, y = normalize(p1) return (x, y, FQ2.one())