def decompress_G2(p: G2Compressed) -> G2Uncompressed: """ Recovers x and y coordinates from the compressed point (z1, z2). """ z1, z2 = p # b_flag == 1 indicates the infinity point b_flag1 = (z1 % POW_2_383) // POW_2_382 if b_flag1 == 1: return Z2 x1 = z1 % POW_2_381 x2 = z2 # x1 is the imaginary part, x2 is the real part x = FQ2([x2, x1]) y = modular_squareroot_in_FQ2(x**3 + b2) if y is None: raise ValueError("Failed to find a modular squareroot") # Choose the y whose leftmost bit of the imaginary part is equal to the a_flag1 # If y_im happens to be zero, then use the bit of y_re a_flag1 = (z1 % POW_2_382) // POW_2_381 y_re, y_im = y.coeffs if (y_im > 0 and (y_im * 2) // q != a_flag1) or (y_im == 0 and (y_re * 2) // q != a_flag1): y = FQ2((y * -1).coeffs) if not is_on_curve((x, y, FQ2([1, 0])), b2): raise ValueError( "The given point is not on the twisted curve over FQ**2") return (x, y, FQ2([1, 0]))
def OpBLS_G2_Add(arg): op = json.loads(arg) a_v = to_int(op['a_v']) a_w = to_int(op['a_w']) a_x = to_int(op['a_x']) a_y = to_int(op['a_y']) b_v = to_int(op['b_v']) b_w = to_int(op['b_w']) b_x = to_int(op['b_x']) b_y = to_int(op['b_y']) A = (FQ2((a_v, a_x)), FQ2((a_w, a_y)), FQ2.one()) B = (FQ2((b_v, b_x)), FQ2((b_w, b_y)), FQ2.one()) if not (is_on_curve(A, b2) and subgroup_check(A)): return if not (is_on_curve(B, b2) and subgroup_check(B)): return result = add(A, B) x = result[0] / result[2] y = result[1] / result[2] result = [[str(x.coeffs[0]), str(y.coeffs[0])], [str(x.coeffs[1]), str(y.coeffs[1])]] r = json.dumps(result) return bytes(r, 'utf-8')
def check_pairing(participantG1, participantG2, previousParticipantG1): # G1 point for participant participant_g1_x = FQ(int(participantG1['x'])) participant_g1_y = FQ(int(participantG1['y'])) participant_g1 = (participant_g1_x, participant_g1_y) # G2 point for participant participant_g2_x = FQ2( [int(participantG2['x']['c0']), int(participantG2['x']['c1'])]) participant_g2_y = FQ2( [int(participantG2['y']['c0']), int(participantG2['y']['c1'])]) participant_g2 = (participant_g2_x, participant_g2_y) # G1 point for previous participant previous_participant_g1_x = FQ(int(previousParticipantG1['x'])) previous_participant_g1_y = FQ(int(previousParticipantG1['y'])) previous_participant_g1 = (previous_participant_g1_x, previous_participant_g1_y) e1 = bn128.final_exponentiate(bn128.pairing(G2, participant_g1)) e2 = bn128.final_exponentiate( bn128.pairing(participant_g2, previous_participant_g1)) pairing_result = (e1 == e2) assert (pairing_result == True)
def to_point(self) -> G2Uncompressed: x_im = int.from_bytes(self.value[:48], 'big') x_re = int.from_bytes(self.value[48:96], 'big') y_im = int.from_bytes(self.value[96:144], 'big') y_re = int.from_bytes(self.value[144:192], 'big') point = FQ2([x_re, x_im]), FQ2([y_re, y_im]), FQ2([1, 0]) return cast(G2Uncompressed, point)
def OpBLS_Verify(arg): op = json.loads(arg) verified = False g1_x = to_int(op['g1_x']) g1_y = to_int(op['g1_y']) g1 = [FQ(g1_x), FQ(g1_y), FQ.one()] if is_on_curve(g1, b) == False: r = json.dumps(verified) return bytes(r, 'utf-8') g1 = G1_to_pubkey(g1) g2_v = to_int(op['g2_v']) g2_w = to_int(op['g2_w']) g2_x = to_int(op['g2_x']) g2_y = to_int(op['g2_y']) g2 = (FQ2((g2_v, g2_x)), FQ2((g2_w, g2_y)), FQ2.one()) try: g2 = G2_to_signature(g2) except: r = json.dumps(verified) return bytes(r, 'utf-8') msg = bytes.fromhex(op['cleartext']) verified = bls_pop.Verify(g1, msg, g2) r = json.dumps(verified) return bytes(r, 'utf-8')
def of_hex(hexstr: str) -> G2Point: x_bytes = bytes.fromhex(hexstr[2:194]) y_bytes = bytes.fromhex(hexstr[194:]) x_im_bytes, x_re_bytes = x_bytes[0:48], x_bytes[48:] y_im_bytes, y_re_bytes = y_bytes[0:48], y_bytes[48:] x_im = int.from_bytes(x_im_bytes, byteorder='big') x_re = int.from_bytes(x_re_bytes, byteorder='big') y_im = int.from_bytes(y_im_bytes, byteorder='big') y_re = int.from_bytes(y_re_bytes, byteorder='big') return (FQ2([x_re, x_im]), FQ2([y_re, y_im]), FQ2([1, 0]))
def decompress_G2(p: G2Compressed) -> G2Uncompressed: """ Recovers x and y coordinates from the compressed point (z1, z2). """ z1, z2 = p c_flag1, b_flag1, a_flag1 = get_flags(z1) # c_flag == 1 indicates the compressed form # MSB should be 1 if not c_flag1: raise ValueError("c_flag should be 1") is_inf_pt = is_point_at_infinity(z1, z2) if b_flag1 != is_inf_pt: raise ValueError("b_flag should be %d" % int(is_inf_pt)) if is_inf_pt: # 3 MSBs should be 110 if a_flag1: raise ValueError("a point at infinity should have a_flag == 0") return Z2 # Else, not point at infinity # 3 MSBs should be 100 or 101 x1 = z1 % POW_2_381 # Ensure that x1 is less than the field modulus. if x1 >= q: raise ValueError("x1 value should be less than field modulus. Got %d", x1) # Ensure that z2 is less than the field modulus. if z2 >= q: raise ValueError( "z2 point value should be less than field modulus. Got %d", z2) x2 = z2 # x1 is the imaginary part, x2 is the real part x = FQ2([x2, x1]) y = modular_squareroot_in_FQ2(x**3 + b2) if y is None: raise ValueError("Failed to find a modular squareroot") # Choose the y whose leftmost bit of the imaginary part is equal to the a_flag1 # If y_im happens to be zero, then use the bit of y_re y_re, y_im = y.coeffs if ((y_im > 0 and (y_im * 2) // q != int(a_flag1)) or (y_im == 0 and (y_re * 2) // q != int(a_flag1))): y = FQ2((y * -1).coeffs) if not is_on_curve((x, y, FQ2([1, 0])), b2): raise ValueError( "The given point is not on the twisted curve over FQ**2") return (x, y, FQ2([1, 0]))
def OpMisc_Fq2_Sqrt(arg): op = json.loads(arg) a_x = to_int_from_binary(op['a_x']) a_y = to_int_from_binary(op['a_y']) a = FQ2((a_x, a_y)) b_x = to_int_from_binary(op['b_x']) b_y = to_int_from_binary(op['b_y']) b = FQ2((b_x, b_y)) sqrt_division_FQ2(a, b)
def OpBLS_IsG2OnCurve(arg): op = json.loads(arg) v = to_int(op['g2_v']) w = to_int(op['g2_w']) x = to_int(op['g2_x']) y = to_int(op['g2_y']) g2 = (FQ2((v, x)), FQ2((w, y)), FQ2.one()) if is_valid([v, w, x, y]) == False: return r = json.dumps(is_on_curve(g2, b2) and subgroup_check(g2)) return bytes(r, 'utf-8')
def hash_to_G2(message_hash: Hash32, domain: int) -> G2Uncompressed: x_coordinate = _get_x_coordinate(message_hash, domain) # Test candidate y coordinates until a one is found while 1: y_coordinate_squared = x_coordinate ** 3 + FQ2([4, 4]) # The curve is y^2 = x^3 + 4(i + 1) y_coordinate = modular_squareroot_in_FQ2(y_coordinate_squared) if y_coordinate is not None: # Check if quadratic residue found break x_coordinate += FQ2([1, 0]) # Add 1 and try again return multiply( (x_coordinate, y_coordinate, FQ2([1, 0])), G2_cofactor, )
def OpBLS_G2_IsEq(arg): op = json.loads(arg) a_v = to_int(op['a_v']) a_w = to_int(op['a_w']) a_x = to_int(op['a_x']) a_y = to_int(op['a_y']) b_v = to_int(op['b_v']) b_w = to_int(op['b_w']) b_x = to_int(op['b_x']) b_y = to_int(op['b_y']) A = (FQ2((a_v, a_x)), FQ2((a_w, a_y)), FQ2.one()) B = (FQ2((b_v, b_x)), FQ2((b_w, b_y)), FQ2.one()) r = json.dumps(A == B) return bytes(r, 'utf-8')
def test_get_x_coordinate(message_hash, domain): domain_in_bytes = domain.to_bytes(8, 'big') x_coordinate = _get_x_coordinate(message_hash, domain_in_bytes) assert x_coordinate == FQ2([ big_endian_to_int(hash_eth2(message_hash + domain_in_bytes + b'\x01')), big_endian_to_int(hash_eth2(message_hash + domain_in_bytes + b'\x02')), ])
def OpMisc_Iso_Map_G2(arg): op = json.loads(arg) a_x = to_int_from_binary(op['a_x']) a_y = to_int_from_binary(op['a_y']) a = FQ2((a_x, a_y)) b_x = to_int_from_binary(op['b_x']) b_y = to_int_from_binary(op['b_y']) b = FQ2((b_x, b_y)) c_x = to_int_from_binary(op['c_x']) c_y = to_int_from_binary(op['c_y']) c = FQ2((c_x, c_y)) iso_map_G2(a, b, c)
def _get_x_coordinate(message_hash: Hash32, domain: Domain) -> FQ2: # Initial candidate x coordinate x_re = big_endian_to_int(hash_eth2(message_hash + domain + b'\x01')) x_im = big_endian_to_int(hash_eth2(message_hash + domain + b'\x02')) x_coordinate = FQ2([x_re, x_im]) # x_re + x_im * i return x_coordinate
def _get_x_coordinate(message_hash: Hash32, domain: int) -> FQ2: domain_in_bytes = domain.to_bytes(8, 'big') # Initial candidate x coordinate x_re = big_endian_to_int(hash_eth2(message_hash + domain_in_bytes + b'\x01')) x_im = big_endian_to_int(hash_eth2(message_hash + domain_in_bytes + b'\x02')) x_coordinate = FQ2([x_re, x_im]) # x_re + x_im * i return x_coordinate
def OpBLS_G2_Neg(arg): op = json.loads(arg) a_v = to_int(op['a_v']) a_w = to_int(op['a_w']) a_x = to_int(op['a_x']) a_y = to_int(op['a_y']) A = (FQ2((a_v, a_x)), FQ2((a_w, a_y)), FQ2.one()) result = neg(A) x = result[0] / result[2] y = result[1] / result[2] result = [[str(x.coeffs[0]), str(y.coeffs[0])], [str(x.coeffs[1]), str(y.coeffs[1])]] r = json.dumps(result) return bytes(r, 'utf-8')
def OpBLS_Compress_G2(arg): op = json.loads(arg) v = to_int(op['g2_v']) w = to_int(op['g2_w']) x = to_int(op['g2_x']) y = to_int(op['g2_y']) g2 = (FQ2((v, x)), FQ2((w, y)), FQ2.one()) try: compressed = compress_G2(g2) except ValueError: return point = [str(compressed[0]), str(compressed[1])] r = json.dumps(point) return bytes(r, 'utf-8')
def OpMisc_Multiply(arg): op = json.loads(arg) a_x = to_int_from_binary(op['a_x']) a_y = to_int_from_binary(op['a_y']) a = FQ2((a_x, a_y)) b_x = to_int_from_binary(op['b_x']) b_y = to_int_from_binary(op['b_y']) b = FQ2((b_x, b_y)) c_x = to_int_from_binary(op['c_x']) c_y = to_int_from_binary(op['c_y']) c = FQ2((c_x, c_y)) multiplier = to_int_from_binary(op['multiplier']) x = [a, b, c] multiply(x, multiplier)
def test_FQ_sgn0(degree, value, expected): if degree == 1: x = FQ(value) elif degree == 2: x = FQ2([value, 0]) elif degree == 12: x = FQ12([value] + [0] * 11) assert x.sgn0 == expected if value != 0: assert x.sgn0 != (-x).sgn0
def OpBLS_MapToG2(arg): op = json.loads(arg) u_x = to_int(op['u_x']) u_y = to_int(op['u_y']) v_x = to_int(op['v_x']) v_y = to_int(op['v_y']) u = FQ2((u_x, u_y)) v = FQ2((v_x, v_y)) g2_u = map_to_curve_G2(u) g2_v = map_to_curve_G2(v) r = add(g2_u, g2_v) point = clear_cofactor_G2(r) x = point[0] / point[2] y = point[1] / point[2] point = [[str(x.coeffs[0]), str(y.coeffs[0])], [str(x.coeffs[1]), str(y.coeffs[1])]] r = json.dumps(point) return bytes(r, 'utf-8')
def hash_to_base_FQ2(message: bytes, ctr: int, DST: bytes) -> FQ2: """ Hash To Base for FQ2 Convert a message to a point in the finite field as defined here: https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-05#section-5 """ m_prime = hkdf_extract(DST, message + b'\x00') info_pfx = b'H2C' + bytes([ctr]) e = [] # for i in (1, ..., m), where m is the extension degree of FQ2 for i in range(1, 3): info = info_pfx + bytes([i]) t = hkdf_expand(m_prime, info, HASH_TO_G2_L) e.append(big_endian_to_int(t)) return FQ2(e)
def hash_to_field_FQ2(message: bytes, count: int, DST: bytes, hash_function: HASH) -> Tuple[FQ2, ...]: """ Hash To Base Field for FQ2 Convert a message to a point in the finite field as defined here: https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-09#section-5.3 """ M = 2 # m is the extension degree of FQ2 len_in_bytes = count * M * HASH_TO_FIELD_L pseudo_random_bytes = expand_message_xmd(message, DST, len_in_bytes, hash_function) u = [] for i in range(0, count): e = [] for j in range(0, M): elem_offset = HASH_TO_FIELD_L * (j + i * M) tv = pseudo_random_bytes[elem_offset: elem_offset + HASH_TO_FIELD_L] e.append(os2ip(tv) % field_modulus) u.append(FQ2(e)) return tuple(u)
) from .bls12_381_field_elements import ( field_modulus, ) curve_order = 52435875175126190479447740508185965837690552500527637822603658699938581184513 # Curve order should be prime assert pow(2, curve_order, curve_order) == 2 # Curve order should be a factor of field_modulus**12 - 1 assert (field_modulus**12 - 1) % curve_order == 0 # Curve is y**2 = x**3 + 4 b = FQ(4) # Twisted curve over FQ**2 b2 = FQ2((4, 4)) # Extension curve over FQ**12; same b value as over FQ b12 = FQ12((4, ) + (0, ) * 11) # Generator for curve over FQ G1 = ( FQ(3685416753713387016781088315183077757961620795782546409894578378688607592378376318836054947676345821548104185464507 ), # noqa: E501 FQ(1339506544944476473020471379941921221584933875938349620426543736416511423956333506472724655353366534992391756441569 ), # noqa: E501 ) # Generator for twisted curve over FQ2 G2 = ( FQ2([ 352701069587466618187139116011060144890029952792775240219908644239793785735715026873347600343865175952761926303160, # noqa: E501 3059144344244213709971259814753781636986470325476647558659373206291635324768958432433509563104347017837885763365758, # noqa: E501
from py_ecc.fields import ( optimized_bls12_381_FQ2 as FQ2, ) from py_ecc.optimized_bls12_381 import ( field_modulus as q, ) G2_COFACTOR = 305502333931268344200999753193121504214466019254188142667664032982267604182971884026507427359259977847832272839041616661285803823378372096355777062779109 # noqa: E501 FQ2_ORDER = q**2 - 1 EIGTH_ROOTS_OF_UNITY = tuple( FQ2([1, 1])**((FQ2_ORDER * k) // 8) for k in range(8)) POW_2_381 = 2**381 POW_2_382 = 2**382 POW_2_383 = 2**383 # Paramaters for hashing to the field as specified in: # https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-07#section-8.8.1 HASH_TO_FIELD_L = 64
b, b2, is_on_curve, multiply, normalize, field_modulus as q, iso_map_G2, ) DST = b'BLS_SIG_BLS12381G2-SHA256-SSWU-RO_POP_' # TODO: Switch out test for valid DST @pytest.mark.parametrize( 'iso_x,iso_y,iso_z,g2_x,g2_y', [ (FQ2([int('0888F3832AD680917A71A1816C939290473474982C647B0B196BA0EDF62A0BC1A15D3E87CF6A287137B16C057E1AC808', 16), int('0B3D6E7A20275C100B460A900B23F2D8D5E9A53C3E59066E8D968D07AB0787940C0AC8A6C8C118FAD9068A2ECF00ADD7', 16)]), # Iso-x0 FQ2([int('08696DF8BAF8C488B7CFCA14CB984D0B78C998C3431E41700B493AAF921F779AA7F3660B1F5D6AC3BA4EBC85A1132CF3', 16), int('053003D3ED23019E585CF255A58634CEDA4C362B2E1D75E2AE85F4D1EF9C400786256D4AEE443DD1C900DD72E4089F73', 16)]), # Iso-y0 FQ2([int('108F7DF15439154BF32D7E4D1B6FEFC4BEF7C39A16AACA469D249770AD7B9F4AD3EA3CE58333A3194177C2D14B5CD2BC', 16), int('09E2E891E7A7AB58D5BF93864000ADBF0B6C31A8E35AB6AEC3B0820C2E536D6F0D170840B0AAFB470A9FD9B2F7DE3C27', 16)]), # Iso-z0 FQ2([int('168A912067A8F06CEB1F5F59DCEC69CE47F5A2B1696DFD5E67F1CF675587AD3A19831842D2543957BEE44FE29592996E', 16), int('116F36861307AA38251CAA73AA44FA359732DD92A15CDC70B21E3F7B2A332F73F86801789C469FE3FBB24DEB18AD5F0C', 16)]), # G2-x0 FQ2([int('0D4976CD99F4AD7204BC5983F6CE590766852DB93E5BE6CAB4C28591013E132BC6100D42022D5B66CE68A64A6B2A9C24', 16), int('0C6BA0E076144119F2B272718EC04C3FB037C9AA2C4074E64BE233AB27C0397BE175B9FDA277DCE8841669F787161AD2', 16)])), # G2-y0 (FQ2([int('039C33A34D97134F01D334F13C76BD5BB803B853BE4221A826026BFC93B5CA39E74B51A15D00BF88DF4F655915553027', 16), int('08DA2162E554A644AECC1F904F2B140D0296B7AC85B4EE59313DCEDE58B375C2E677160BC97CF8114361ABBE7D4672CD', 16)]), # Iso-x1 FQ2([int('1201968136C60428FB9DF8004C4915DC5E502D20D32F9DD87BC38163A52E2729289490030235E61EAEA098B0E8D63BF8', 16), int('116524863E40B6437BBAB965CDB84614F2346F1AD40300E9B15C3BDDE498E1FC1F76346452D3CF25553E2A3B89D9C5B1', 16)]), # Iso-y1 FQ2([int('08C3BCEBE1FC7F9987AE406A78C3FC898AE0C8A2FF0139A523E3CE91263EAA617519FC1A1158AF39BBA705316C9C2678', 16), int('0C9E92BB5509704DA0B6825A3AA36BA68A877875258F17C315FEA1527A82C7975E8439E91644616DABFD28E1DB43C1D9', 16)]), # Iso-z1 FQ2([int('1990072F0029639467E5C5EF9F65B31F194C31586D56141A7906DE6EE2B40803E06A301F9EEE9C8B04FA6AF8C5950F64', 16), int('0910709BEC8515357CB68AE88EA0B7EC6D54190773CC82EDDA68180D62BA214737DC708A5DA815E8B872D3C5B31E5A00', 16)]), # G2-x1 FQ2([int('12416C8B9159A047D5F92A6A4E941156E29E2A489B671D2FC3D8ED60FFA5F53FE846ECFB0090211197EF3BA4C07424F9', 16), int('089977D619CEA9D6D11F7148E1CB7622E46153BF1B4D81944603AA72AEFA6CE7CF07550CB6B582D17440F5949D1214FA', 16)])), # G2-y1 ] ) def test_iso_map_G2(iso_x, iso_y, iso_z, g2_x, g2_y): (result_x, result_y, result_z) = iso_map_G2(iso_x, iso_y, iso_z) result_x = result_x / result_z
normalize(decompress_G1(z)) == normalize(pt) else: with pytest.raises(ValueError): decompress_G1(z) @pytest.mark.parametrize( 'pt,on_curve,is_infinity', [ # On curve points (G2, True, False), (multiply(G2, 5), True, False), # Infinity point but still on curve (Z2, True, True), # Not on curve ((FQ2([5566, 5566]), FQ2([5566, 5566]), FQ2.one()), False, None), ]) def test_G2_compress_and_decompress_flags(pt, on_curve, is_infinity): if on_curve: z1, z2 = compress_G2(pt) x1 = z1 % POW_2_381 c_flag1 = (z1 % 2**384) // POW_2_383 b_flag1 = (z1 % POW_2_383) // POW_2_382 a_flag1 = (z1 % POW_2_382) // POW_2_381 x2 = z2 % POW_2_381 c_flag2 = (z2 % 2**384) // POW_2_383 b_flag2 = (z2 % POW_2_383) // POW_2_382 a_flag2 = (z2 % POW_2_382) // POW_2_381 assert x1 < q assert x2 < q assert c_flag2 == b_flag2 == a_flag2 == 0
from py_ecc.fields import ( optimized_bls12_381_FQ2 as FQ2, ) from py_ecc.optimized_bls12_381 import ( field_modulus as q, ) G2_COFACTOR = 305502333931268344200999753193121504214466019254188142667664032982267604182971884026507427359259977847832272839041616661285803823378372096355777062779109 # noqa: E501 FQ2_ORDER = q ** 2 - 1 EIGTH_ROOTS_OF_UNITY = tuple( FQ2([1, 1]) ** ((FQ2_ORDER * k) // 8) for k in range(8) ) POW_2_381 = 2**381 POW_2_382 = 2**382 POW_2_383 = 2**383 POW_2_384 = 2**384 # Paramaters for hashing to the field as specified in: # https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-09#section-8.8.1 HASH_TO_FIELD_L = 64
from py_ecc.fields import ( optimized_bls12_381_FQ2 as FQ2, ) # # Ciphersuite BLS12381G2-SHA256-SSWU-RO paramters # ISO_3_A = FQ2([0, 240]) ISO_3_B = FQ2([1012, 1012]) ISO_3_Z = FQ2([-2, -1]) P_MINUS_9_DIV_16 = 1001205140483106588246484290269935788605945006208159541241399033561623546780709821462541004956387089373434649096260670658193992783731681621012512651314777238193313314641988297376025498093520728838658813979860931248214124593092835 # noqa: E501 EV1 = 1015919005498129635886032702454337503112659152043614931979881174103627376789972962005013361970813319613593700736144 # noqa: E501 EV2 = 1244231661155348484223428017511856347821538750986231559855759541903146219579071812422210818684355842447591283616181 # noqa: E501 EV3 = 1646015993121829755895883253076789309308090876275172350194834453434199515639474951814226234213676147507404483718679 # noqa: E501 EV4 = 1637752706019426886789797193293828301565549384974986623510918743054325021588194075665960171838131772227885159387073 # noqa: E501 ETAS = [FQ2([EV1, EV2]), FQ2([-EV2, EV1]), FQ2([EV3, EV4]), FQ2([-EV4, EV3])] RV1 = 1028732146235106349975324479215795277384839936929757896155643118032610843298655225875571310552543014690878354869257 # noqa: E501 POSITIVE_EIGTH_ROOTS_OF_UNITY = ( FQ2([1, 0]), FQ2([0, 1]), FQ2([RV1, RV1]), FQ2([RV1, -RV1]), ) # X Numerator ISO_3_K_1_0_VAL = 889424345604814976315064405719089812568196182208668418962679585805340366775741747653930584250892369786198727235542 # noqa: E501 ISO_3_K_1_0 = FQ2([ISO_3_K_1_0_VAL, ISO_3_K_1_0_VAL]) # noqa: E501 ISO_3_K_1_1 = FQ2([ 0, 2668273036814444928945193217157269437704588546626005256888038757416021100327225242961791752752677109358596181706522
from py_ecc.optimized_bn128 import G1, G2, Z2 from py_ecc.optimized_bn128 import add, multiply, neg, normalize, pairing, is_on_curve from py_ecc.optimized_bn128 import curve_order as CURVE_ORDER from py_ecc.fields import optimized_bn128_FQ2 as FQ2 from py_ecc.fields import optimized_bn128_FQ as FQ from Crypto.Cipher import Salsa20 from Crypto.Hash import SHA256 from Crypto.Protocol.KDF import HKDF H2 = (FQ2(( 9110522554455888802745409460679507850660709404525090688071718755658817738702, 14120302265976430476300156362541817133873389322564306174224598966336605751189 )), FQ2(( 8015061597608194114184122605728732604411275728909990814600934336120589400179, 21550838471174089343030649382112381550278244756451022825185015902639198926789 )), FQ2.one()) H1 = ( FQ(9727523064272218541460723335320998459488975639302513747055235660443850046724 ), FQ(5031696974169251245229961296941447383441169981934237515842977230762345915487 ), FQ(1), ) class IntPoly: def __init__(self, coeffs): self.coeffs = [coeff % CURVE_ORDER for coeff in coeffs]
Optimized_Point2D, Optimized_Point3D, ) field_modulus = field_properties["bn128"]["field_modulus"] curve_order = 21888242871839275222246405745257275088548364400416034343698204186575808495617 # Curve order should be prime assert pow(2, curve_order, curve_order) == 2 # Curve order should be a factor of field_modulus**12 - 1 assert (field_modulus**12 - 1) % curve_order == 0 # Curve is y**2 = x**3 + 3 b = FQ(3) # Twisted curve over FQ**2 b2 = FQ2([3, 0]) / FQ2([9, 1]) # Extension curve over FQ**12; same b value as over FQ b12 = FQ12([3] + [0] * 11) # 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, ]),