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 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 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 optimized_swu_G2(t: FQ2) -> Tuple[FQ2, FQ2, FQ2]: t2 = t ** 2 iso_3_z_t2 = ISO_3_Z * t2 temp = iso_3_z_t2 + iso_3_z_t2 ** 2 denominator = -(ISO_3_A * temp) # -a(Z * t^2 + Z^2 * t^4) temp = temp + FQ2.one() numerator = ISO_3_B * temp # b(Z * t^2 + Z^2 * t^4 + 1) # Exceptional case if denominator == FQ2.zero(): denominator = ISO_3_Z * ISO_3_A # v = D^3 v = denominator ** 3 # u = N^3 + a * N * D^2 + b* D^3 u = (numerator ** 3) + (ISO_3_A * numerator * (denominator ** 2)) + (ISO_3_B * v) # Attempt y = sqrt(u / v) (success, sqrt_candidate) = sqrt_division_FQ2(u, v) y = sqrt_candidate # Handle case where (u / v) is not square # sqrt_candidate(x1) = sqrt_candidate(x0) * t^3 sqrt_candidate = sqrt_candidate * t ** 3 # u(x1) = Z^3 * t^6 * u(x0) u = (iso_3_z_t2) ** 3 * u success_2 = False etas = ETAS for eta in etas: # Valid solution if (eta * sqrt_candidate(x1)) ** 2 * v - u == 0 eta_sqrt_candidate = eta * sqrt_candidate temp1 = eta_sqrt_candidate ** 2 * v - u if temp1 == FQ2.zero() and not success and not success_2: y = eta_sqrt_candidate success_2 = True if not success and not success_2: # Unreachable raise Exception("Hash to Curve - Optimized SWU failure") if not success: numerator = numerator * iso_3_z_t2 if t.sgn0 != y.sgn0: y = -y y = y * denominator return (numerator, y, denominator)
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 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')
), # noqa: E501 FQ(1339506544944476473020471379941921221584933875938349620426543736416511423956333506472724655353366534992391756441569 ), # noqa: E501 FQ(1), ) # Generator for twisted curve over FQ2 G2 = ( FQ2(( 352701069587466618187139116011060144890029952792775240219908644239793785735715026873347600343865175952761926303160, # noqa: E501 3059144344244213709971259814753781636986470325476647558659373206291635324768958432433509563104347017837885763365758, # noqa: E501 )), FQ2(( 1985150602287291935568054521177171638300868978215655730859378665066344726373823718423869104263333984641494340347905, # noqa: E501 927553665492332455747201965776037880757740193453592970025027978793976877002675564980949289727957565575433344219582, # noqa: E501 )), FQ2.one(), ) # Point at infinity over FQ Z1 = (FQ.one(), FQ.one(), FQ.zero()) # Point at infinity for twisted curve over FQ2 Z2 = (FQ2.one(), FQ2.one(), FQ2.zero()) # Check if a point is the point at infinity def is_inf(pt: Optimized_Point3D[Optimized_Field]) -> bool: return pt[-1] == pt[-1].__class__.zero() # Check that a point is on the curve defined by y**2 == x**3 + b def is_on_curve(pt: Optimized_Point3D[Optimized_Field], b: Optimized_Field) -> bool:
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
ISO_3_K_1_3 = FQ2([ 3557697382419259905260257622876359250272784728834673675850718343221361467102966990615722337003569479144794908942033, 0 ]) # noqa: E501 ISO_3_X_NUMERATOR = (ISO_3_K_1_0, ISO_3_K_1_1, ISO_3_K_1_2, ISO_3_K_1_3) # X Denominator ISO_3_K_2_0 = FQ2([ 0, 4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559715 ]) # noqa: E501 ISO_3_K_2_1 = FQ2([ 12, 4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559775 ]) # noqa: E501 ISO_3_K_2_2 = FQ2.one() ISO_3_K_2_3 = FQ2.zero() ISO_3_X_DENOMINATOR = (ISO_3_K_2_0, ISO_3_K_2_1, ISO_3_K_2_2, ISO_3_K_2_3) # Y Numerator ISO_3_K_3_0_VAL = 3261222600550988246488569487636662646083386001431784202863158481286248011511053074731078808919938689216061999863558 # noqa: E501 ISO_3_K_3_0 = FQ2([ISO_3_K_3_0_VAL, ISO_3_K_3_0_VAL]) # noqa: E501 ISO_3_K_3_1 = FQ2([ 0, 889424345604814976315064405719089812568196182208668418962679585805340366775741747653930584250892369786198727235518 ]) # noqa: E501 ISO_3_K_3_2 = FQ2([ 2668273036814444928945193217157269437704588546626005256888038757416021100327225242961791752752677109358596181706524, 1334136518407222464472596608578634718852294273313002628444019378708010550163612621480895876376338554679298090853263 ]) # noqa: E501 ISO_3_K_3_3 = FQ2([