def compress_G2(pt: G2Uncompressed) -> G2Compressed: """ The compressed point (z1, z2) has the bit order: z1: (c_flag1, b_flag1, a_flag1, x1) z2: (c_flag2, b_flag2, a_flag2, x2) where - c_flag1 is always set to 1 - b_flag1 indicates infinity when set to 1 - a_flag1 helps determine the y-coordinate when decompressing, - a_flag2, b_flag2, and c_flag2 are always set to 0 """ if not is_on_curve(pt, b2): raise ValueError( "The given point is not on the twisted curve over FQ**2") if is_inf(pt): return G2Compressed((POW_2_383 + POW_2_382, 0)) x, y = normalize(pt) x_re, x_im = x.coeffs y_re, y_im = y.coeffs # Record the leftmost bit of y_im to the a_flag1 # If y_im happens to be zero, then use the bit of y_re a_flag1 = (y_im * 2) // q if y_im > 0 else (y_re * 2) // q # Imaginary part of x goes to z1, real part goes to z2 # c_flag1 = 1, b_flag1 = 0 z1 = x_im + a_flag1 * POW_2_381 + POW_2_383 # a_flag2 = b_flag2 = c_flag2 = 0 z2 = x_re return G2Compressed((z1, z2))
def from_point(cls, point: G1Uncompressed) -> 'BLS12_381_G1Type': if bls12_381.is_inf(point): x, y = POW_2_382, 0 else: x_pt, y_pt = bls12_381.normalize(point) x, y = x_pt.n, y_pt.n value = x.to_bytes(48, 'big') + y.to_bytes(48, 'big') return cls.from_value(value)
def to_hex(g1_point: G1Point) -> str: if bls12_381.is_inf(g1_point): xxx, yyy = bls.constants.POW_2_382, 0 else: xxx_pt, yyy_pt = bls12_381.normalize(g1_point) xxx, yyy = xxx_pt.n, yyy_pt.n xxx_bytes = xxx.to_bytes(48, byteorder='big') yyy_bytes = yyy.to_bytes(48, byteorder='big') return f'0x{(xxx_bytes + yyy_bytes).hex()}'
def from_point(cls, point: G2Uncompressed) -> 'BLS12_381_G2Type': if bls12_381.is_inf(point): x_re, x_im, y_re, y_im = 0, POW_2_382, 0, 0 else: x, y = bls12_381.normalize(point) x_re, x_im = x.coeffs y_re, y_im = y.coeffs value = x_im.to_bytes(48, 'big') + x_re.to_bytes(48, 'big') \ + y_im.to_bytes(48, 'big') + y_re.to_bytes(48, 'big') return cls(value)
def to_hex(g2_point: G2Point) -> str: if bls12_381.is_inf(g2_point): x_re, x_im, y_re, y_im = 0, bls.constants.POW_2_382, 0, 0 else: xxx, yyy = bls12_381.normalize(g2_point) x_re, x_im = xxx.coeffs y_re, y_im = yyy.coeffs x_re_bytes = x_re.to_bytes(48, byteorder='big') x_im_bytes = x_im.to_bytes(48, byteorder='big') y_re_bytes = y_re.to_bytes(48, byteorder='big') y_im_bytes = y_im.to_bytes(48, byteorder='big') x_bytes = x_im_bytes + x_re_bytes y_bytes = y_im_bytes + y_re_bytes return f'0x{(x_bytes + y_bytes).hex()}'
def compress_G1(pt: G1Uncompressed) -> G1Compressed: """ A compressed point is a 384-bit integer with the bit order (c_flag, b_flag, a_flag, x), where the c_flag bit is always set to 1, the b_flag bit indicates infinity when set to 1, the a_flag bit helps determine the y-coordinate when decompressing, and the 381-bit integer x is the x-coordinate of the point. """ if is_inf(pt): # Set c_flag = 1 and b_flag = 1. leave a_flag = x = 0 return G1Compressed(POW_2_383 + POW_2_382) else: x, y = normalize(pt) # Record y's leftmost bit to the a_flag a_flag = (y.n * 2) // q # Set c_flag = 1 and b_flag = 0 return G1Compressed(x.n + a_flag * POW_2_381 + POW_2_383)
def subgroup_check(P: Optimized_Point3D) -> bool: return is_inf(multiply(P, curve_order))
def is_inf(self) -> bool: return is_inf(self.py_ecc_object)