def verify(self, proof): """Verify if a proof is correct for the given inputs""" if not isinstance(proof, Proof): raise TypeError("Invalid proof type") # Compute the linear combination vk_x # vk_x = gammaABC[0] + gammaABC[1]^x[0] + ... + gammaABC[n+1]^x[n] vk_x = self.gammaABC[0] for i, x in enumerate(proof.input): vk_x = add(vk_x, multiply(self.gammaABC[i + 1], x)) # e(B, A) * e(gamma, -vk_x) * e(delta, -C) * e(beta, -alpha) return pairingProd((proof.A, proof.B), (neg(vk_x), self.gamma), (neg(proof.C), self.delta), (neg(self.alpha), self.beta))
def encryptC(self, a, p): random = getRandomElement().n hR = bn128.bn128_curve.multiply(self.publicKey, random) gM = bn128.multiply(bn128.multiply(bn128.G1, a.n), p.n) return Ciphertext(bn128.bn128_curve.multiply(bn128.G1, random), bn128.bn128_curve.add(hR, bn128.neg(gM)))
def generateCommitment(publicKey, alpha, beta, secretRandomness, currentD0_2i, currentD1_2i, isZeroEncryption): com = Proof() com.secretRandomness = secretRandomness com.isZeroEncryption = isZeroEncryption com.publicKey = publicKey com.alpha = alpha com.beta = beta com.currentD0_2i = currentD0_2i com.currentD1_2i = currentD1_2i if isZeroEncryption == False: com.r2 = getRandomElement() com.d2 = getRandomElement() com.w = getRandomElement() # a1 = w G # b1 = w H com.a1 = bn128.multiply(bn128.G1, com.w.n) com.b1 = bn128.multiply(publicKey, com.w.n) # a2 = r_2G + d2 beta com.a2 = bn128.add(bn128.multiply(bn128.G1, com.r2.n), bn128.multiply(beta, com.d2.n)) # b2 = r_2H + d2 alpha com.b2 = bn128.add(bn128.multiply(publicKey, com.r2.n), bn128.multiply(alpha, com.d2.n)) else: com.r1 = getRandomElement() com.d1 = getRandomElement() com.w = getRandomElement() # a1 = r_1 G + d1 (beta - 2iD0) inner = bn128.add(beta, bn128.neg(currentD0_2i)) com.a1 = bn128.add(bn128.multiply(bn128.G1, com.r1.n), bn128.multiply(inner, com.d1.n)) # b1 = r_1 H + d1 (alpha - 2i D_1) inner = bn128.add(alpha, bn128.neg(currentD1_2i)) com.b1 = bn128.add(bn128.multiply(publicKey, com.r1.n), bn128.multiply(inner, com.d1.n)) # a2 = w G # b2 = w H com.a2 = bn128.multiply(bn128.G1, com.w.n) com.b2 = bn128.multiply(publicKey, com.w.n) return com
def check_pairing(P1: PointG1, Q1: PointG2, P2: PointG1, Q2: PointG2) -> bool: """ performs the pairing check as specified in https://github.com/ethereum/EIPs/blob/master/EIPS/eip-197.md this check is compatible with the implementation in the precompiled solidity contract NOTICE THIS IS DIFFERENT FROM WHAT ONE WOULD ACTUALLY THINK OF WHEN CHECKING THE PAIRING seed __check_pairing_equality for the intuitive understanding of a pairing check """ P1 = _wrap(P1) Q1 = _wrap(Q1) P2 = bn128.neg(_wrap(P2)) Q2 = _wrap(Q2) return bn128.pairing(Q1, P1) == bn128.pairing(Q2, P2)
def verify(self, proof): """Verify if a proof is correct for the given inputs""" if not isinstance(proof, Proof): raise TypeError("Invalid proof type") # Compute the linear combination vk_x # vk_x = IC[0] + IC[1]^x[0] + ... + IC[n+1]^x[n] vk_x = self.IC[0] for i, x in enumerate(proof.input): IC_mul_x = multiply(self.IC[i + 1], x) vk_x = add(vk_x, IC_mul_x) # e(V_a,P_a) * e(G2,-P_a_p) == 1 if not pairingProd((proof.a, self.a), (neg(proof.a_p), bn128.G2)): raise RuntimeError("Proof step 1 failed") # e(P_b,V_b) * e(G2,-P_b_p) == 1 if not pairingProd((self.b, proof.b), (neg(proof.b_p), bn128.G2)): raise RuntimeError("Proof step 2 failed") # e(V_c,P_c) * e(G2,-P_c_p) == 1 if not pairingProd((proof.c, self.c), (neg(proof.c_p), bn128.G2)): raise RuntimeError("Proof step 3 failed") # e(V_g,P_k) * e(V_gb2,-(vk_x+P_a+P_c)) * e(P_b,-P_gb1) == 1 if not pairingProd( (proof.k, self.g), (neg(add(vk_x, add(proof.a, proof.c))), self.gb2), (neg(self.gb1), proof.b)): raise RuntimeError("Proof step 4 failed") # e(P_b, vk_x+P_a) * e(V_z,-P_h) * e(G2,-P_c) == 1 if not pairingProd( (add(vk_x, proof.a), proof.b), (neg(proof.h), self.z), (neg(proof.c), bn128.G2)): raise RuntimeError("Proof step 5 failed") return True
def decrypt(secretKey, ciphertext): grx = bn128.bn128_curve.multiply(ciphertext.c1, secretKey.n) return bn128.bn128_curve.add(bn128.neg(grx), ciphertext.c2)
def test_pairing_python_neg(): assert pairing(G2, multiply(G1, 5)) != pairing(multiply(G2, 5), neg(G1))
def neg(point: Point) -> Point: return _unwrap(bn128.neg(_wrap(point)))