def verify_share(j: int, s_ij: int, Cik: List[PointG1]) -> bool: """ check share validity and return True if the share is valid, False otherwise """ r = Cik[0] for k, c in enumerate(Cik[1:]): r = add(r, multiply(c, pow(j, k + 1, CURVE_ORDER))) return normalize(multiply(G1, s_ij)) == normalize(r)
def encrypt_share(s_ij: int, k_ij: PointG1, j: int) -> int: """ Encrypt the given share s_ij using the shared key k_ij. As no symmetric key encryption algorithm is natively support in the EVM, the encryption is implemented by and xor-operation and a hash function. The parameter j is added to ensure that s_ij and s_ji are xored with different values. """ x = normalize(k_ij)[0].n h = keccak_256(abi_types=["uint256", "uint256"], values=[x, j]) return s_ij ^ int.from_bytes(h, "big")
def ec_mul(data: List[int]) -> List[int]: bytes_data = bytearray(data) x = extract32(bytes_data, 0) y = extract32(bytes_data, 32) m = extract32(bytes_data, 64) p = validate_point(x, y) if p is False: return [] o = bn128.normalize(bn128.multiply(p, m)) return [safe_ord(c) for c in (encode_int32(o[0].n) + encode_int32(o[1].n))]
def point_to_eth(p): """ Transform a point of py-ecc in G1 to a tuple Args: p (Tuple(py_ecc.fields.optimized_bn128_FQ2)): a point in G1 Returns: A tuple of 2 int containing the coefficients of the point """ pn = normalize(p) return int(pn[0]), int(pn[1])
def ec_add(data: List[int]) -> List[int]: bytes_data = bytearray(data) x1 = extract32(bytes_data, 0) y1 = extract32(bytes_data, 32) x2 = extract32(bytes_data, 64) y2 = extract32(bytes_data, 96) p1 = validate_point(x1, y1) p2 = validate_point(x2, y2) if p1 is False or p2 is False: return [] o = bn128.normalize(bn128.add(p1, p2)) return [safe_ord(x) for x in (encode_int32(o[0].n) + encode_int32(o[1].n))]
def dleq_verify(x1, y1, x2, y2, challenge, response): """ Verify the proof computed with the dleq function in G1 Args: x1: a point in G1 y1: a point in G1 x2: a point in G1 y2: a point in G1 challenge (int): the first coefficient of the proof response (int): the second coefficient of the proof Returns: True if the proof is correct, False else """ a1 = add(multiply(x1, response), multiply(y1, challenge)) a2 = add(multiply(x2, response), multiply(y2, challenge)) c = keccak_256( # pylint: disable=E1120 abi_types=["uint256"] * 12, # 12, values=[ int(v) for v in normalize(a1) + normalize(a2) + normalize(x1) + normalize(y1) + normalize(x2) + normalize(y2) ], ) c = int.from_bytes(c, "big") return c == challenge
def _ecmull(data): x_bytes = pad32r(data[:32]) y_bytes = pad32r(data[32:64]) m_bytes = pad32r(data[64:96]) x = big_endian_to_int(x_bytes) y = big_endian_to_int(y_bytes) m = big_endian_to_int(m_bytes) p = validate_point(x, y) result = bn128.normalize(bn128.multiply(p, m)) return result
def _ecmull(data: bytes) -> Tuple[bn128.FQ, bn128.FQ]: x_bytes = pad32r(data[:32]) y_bytes = pad32r(data[32:64]) m_bytes = pad32r(data[64:96]) x = big_endian_to_int(x_bytes) y = big_endian_to_int(y_bytes) m = big_endian_to_int(m_bytes) p = validate_point(x, y) result = bn128.normalize(bn128.multiply(p, m)) return result
def _ecadd(data): x1_bytes = pad32r(data[:32]) y1_bytes = pad32r(data[32:64]) x2_bytes = pad32r(data[64:96]) y2_bytes = pad32r(data[96:128]) x1 = big_endian_to_int(x1_bytes) y1 = big_endian_to_int(y1_bytes) x2 = big_endian_to_int(x2_bytes) y2 = big_endian_to_int(y2_bytes) p1 = validate_point(x1, y1) p2 = validate_point(x2, y2) result = bn128.normalize(bn128.add(p1, p2)) return result
def proc_ecmul(ext, msg): if not ext.post_metropolis_hardfork(): return 1, msg.gas, [] import py_ecc.optimized_bn128 as bn128 FQ = bn128.FQ print('ecmul proc', msg.gas) if msg.gas < opcodes.GECMUL: return 0, 0, [] x = msg.data.extract32(0) y = msg.data.extract32(32) m = msg.data.extract32(64) p = validate_point(x, y) if p is False: return 0, 0, [] o = bn128.normalize(bn128.multiply(p, m)) return (1, msg.gas - opcodes.GECMUL, [safe_ord(c) for c in (encode_int32(o[0].n) + encode_int32(o[1].n))])
def proc_ecmul(ext, msg): import py_ecc.optimized_bn128 as bn128 FQ = bn128.FQ if msg.gas < opcodes.GECMUL: return 0, 0, [] x = msg.data.extract32(0) y = msg.data.extract32(32) m = msg.data.extract32(64) p = validate_point(x, y) if p is False: return 0, 0, [] o = bn128.normalize(bn128.multiply(p, m)) return ( 1, msg.gas - opcodes.GECMUL, [safe_ord(c) for c in (encode_int32(o[0].n) + encode_int32(o[1].n))], )
def dleq_verify(x1: PointG1, y1: PointG1, x2: PointG1, y2: PointG1, challenge: int, response: int) -> bool: a1 = add(multiply(x1, response), multiply(y1, challenge)) a2 = add(multiply(x2, response), multiply(y2, challenge)) c = keccak_256( # pylint: disable=E1120 abi_types=["uint256"] * 12, # 12, values=[ int(v) for v in normalize(a1) + normalize(a2) + normalize(x1) + normalize(y1) + normalize(x2) + normalize(y2) ], ) c = int.from_bytes(c, "big") return c == challenge
def proc_ecadd(ext, msg): import py_ecc.optimized_bn128 as bn128 FQ = bn128.FQ if msg.gas < opcodes.GECADD: return 0, 0, [] x1 = msg.data.extract32(0) y1 = msg.data.extract32(32) x2 = msg.data.extract32(64) y2 = msg.data.extract32(96) p1 = validate_point(x1, y1) p2 = validate_point(x2, y2) if p1 is False or p2 is False: return 0, 0, [] o = bn128.normalize(bn128.add(p1, p2)) return ( 1, msg.gas - opcodes.GECADD, [safe_ord(x) for x in (encode_int32(o[0].n) + encode_int32(o[1].n))], )
def proc_ecadd(ext, msg): if not ext.post_metropolis_hardfork(): return 1, msg.gas, [] import py_ecc.optimized_bn128 as bn128 FQ = bn128.FQ print('ecadd proc:', msg.gas) if msg.gas < opcodes.GECADD: return 0, 0, [] x1 = msg.data.extract32(0) y1 = msg.data.extract32(32) x2 = msg.data.extract32(64) y2 = msg.data.extract32(96) p1 = validate_point(x1, y1) p2 = validate_point(x2, y2) if p1 is False or p2 is False: return 0, 0, [] o = bn128.normalize(bn128.add(p1, p2)) return 1, msg.gas - \ opcodes.GECADD, [safe_ord(x) for x in ( encode_int32(o[0].n) + encode_int32(o[1].n))]
def compute_mpk(self): if len(self.gpk_0) > self.threshold and not self.has_mpk: self.has_mpk = True self.mpk = Z1 for gpki, ui in self.gpk_0[0:self.threshold + 1]: coeff = 1 for gpkj, uj in self.gpk_0[0:self.threshold + 1]: if uj != ui: coeff *= uj * sympy.mod_inverse( (uj - ui) % CURVE_ORDER, CURVE_ORDER) coeff %= CURVE_ORDER self.mpk = add(self.mpk, multiply(gpki, coeff)) self.mpk = normalize(self.mpk) db = get_db() value = (str(self.mpk[0]), str(self.mpk[1])) db.execute("INSERT INTO mpk (x,y) VALUES (?,?)", value) db.commit() db.close()
def dleq(x1: PointG1, y1: PointG1, x2: PointG1, y2: PointG1, alpha: int) -> Tuple[int, int]: """ DLEQ... discrete logarithm equality Proofs that the caller knows alpha such that y1 = x1**alpha and y2 = x2**alpha without revealing alpha. """ w = random_scalar() a1 = multiply(x1, w) a2 = multiply(x2, w) c = keccak_256( abi_types=["uint256"] * 12, values=[ int(v) for v in normalize(a1) + normalize(a2) + normalize(x1) + normalize(y1) + normalize(x2) + normalize(y2) ], ) c = int.from_bytes(c, "big") r = (w - alpha * c) % CURVE_ORDER return c, r
def G2_to_signature(point: G2Point) -> Signature: x, y = normalize(point) return Signature(x.coeffs[0].to_bytes(32, "big") + x.coeffs[1].to_bytes(32, "big") + y.coeffs[0].to_bytes(32, "big") + y.coeffs[1].to_bytes(32, "big"))
def _normalize(p1): x, y = normalize(p1) return (x, y, FQ2.one())
def priv_to_pub(priv: PrivateKey) -> Pubkey: x, y = normalize(multiply(G2, priv)) g2 = (x, y, FQ2.one()) return g2_to_pubkey(g2)
def sign(msg: Message, priv: PrivateKey) -> Signature: x, y = normalize(multiply(hash_to_g1(msg), priv)) g1 = (x, y, FQ.one()) return g1_to_signature(g1)
def rand_g2(): return normalize(multiply(G2, rand_int()))
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)
def priv_to_pub(priv: PrivateKey) -> Pubkey: x, y = normalize(multiply(G1, priv)) g1 = (x, y, FQ.one()) return G1_to_pubkey(g1)
def g1_to_signature(point: G1Point) -> Signature: x, y = normalize(point) return Pubkey(x.n.to_bytes(32, "big") + y.n.to_bytes(32, "big"))
def compress_G1(pt: Tuple[FQ, FQ, FQ]) -> int: x, y = normalize(pt) return x.n + 2**255 * (y.n % 2)
def compress_G1(pt): x, y = normalize(pt) return x.n + 2**255 * (y.n % 2)
def compress_G2(pt): assert is_on_curve(pt, b2) x, y = normalize(pt) return (x.coeffs[0] + 2**255 * (y.coeffs[0] % 2), x.coeffs[1])
def G1_to_pubkey(point: G1Point) -> Pubkey: x, y = normalize(point) return Pubkey(x.n.to_bytes(32, "big") + y.n.to_bytes(32, "big"))
def compress_G2(pt: Tuple[FQP, FQP, FQP]) -> Tuple[int, int]: assert is_on_curve(pt, b2) x, y = normalize(pt) return (int(x.coeffs[0] + 2**255 * (y.coeffs[0] % 2)), int(x.coeffs[1]))
def g2_to_pubkey(point: G2Point) -> Signature: x, y = normalize(point) return Pubkey(x.coeffs[0].to_bytes(32, "big") + x.coeffs[1].to_bytes(32, "big") + y.coeffs[0].to_bytes(32, "big") + y.coeffs[1].to_bytes(32, "big"))