def custom_hash(*args) -> bytes: m = hashlib.sha256() for arg in args: if isinstance(arg, tuple) and len(arg) == 3: m.update(compress_G1(arg).to_bytes(48, "big", signed=False)) elif isinstance(arg, int): m.update(arg.to_bytes(8, "big", signed=False)) elif isinstance(arg, FQ): m.update(arg.n.to_bytes(32, "big", signed=False)) else: m.update(arg) hash_in_bytes = m.digest() hash_in_Fr = Fr(int.from_bytes(hash_in_bytes, "big")) return hash_in_Fr
def OpBLS_Compress_G1(arg): op = json.loads(arg) x = to_int(op['g1_x']) y = to_int(op['g1_y']) if (x % MOD, y % MOD) == (0, 0): return g1 = [FQ(x), FQ(y), FQ.one()] compressed = compress_G1(g1) if is_valid([x, y]) == True and is_on_curve(g1, b): decompressed = decompress_G1(compressed) assert g1[0] == decompressed[0] and g1[1] == decompressed[1] r = json.dumps(str(compressed)) return bytes(r, 'utf-8')
def test_G1_compress_and_decompress_flags(pt, on_curve, is_infinity): assert on_curve == is_on_curve(pt, b) z = compress_G1(pt) if on_curve: x = z % POW_2_381 c_flag = (z % 2**384) // POW_2_383 b_flag = (z % POW_2_383) // POW_2_382 a_flag = (z % POW_2_382) // POW_2_381 assert x < q assert c_flag == 1 if is_infinity: assert b_flag == 1 assert a_flag == x == 0 else: assert b_flag == 0 pt_x, pt_y = normalize(pt) assert a_flag == (pt_y.n * 2) // q assert x == pt_x.n # Correct flags should decompress correct x, y normalize(decompress_G1(z)) == normalize(pt) else: with pytest.raises(ValueError): decompress_G1(z)
if is_infinity: assert b_flag == 1 assert a_flag == x == 0 else: assert b_flag == 0 pt_x, pt_y = normalize(pt) assert a_flag == (pt_y.n * 2) // q assert x == pt_x.n # Correct flags should decompress correct x, y normalize(decompress_G1(z)) == normalize(pt) else: with pytest.raises(ValueError): decompress_G1(z) compressed_g1 = compress_G1(G1) compressed_z1 = compress_G1(Z1) @pytest.mark.parametrize( 'z, error_message', [ (compressed_g1, None), # baseline (compressed_g1 & ~(1 << 383), "c_flag should be 1"), # set c_flag to 0 (compressed_g1 | (1 << 382), "b_flag should be 0"), # set b_flag to 1 (compressed_z1 & ~(1 << 382), "b_flag should be 1"), # set b_flag to 0 (compressed_z1 | (1 << 381), "a point at infinity should have a_flag == 0"), # set a_flag to 1 ]) def test_decompress_G1_edge_case(z, error_message): if error_message is None: