def encrypt(self,m,r1=None,r2=None, r3=None): ''' Outputs a PPATCCiphertext on m using r1,r2 as the randomness for the commitment and r1,r2,r3 as the randomness for the encryption ''' # notations q = self.PPATCpp.order g = self.PPATCpp.g ECG = g.ECG # EFp2 Jcoord = self.PPATCpp.Jcoord if r1 == None: r1 = randint(1,int(q)) if r2 == None: r2 = randint(1,int(q)) if r3 == None: r3 = randint(1,int(q)) # commitment d = self.commit(m,r1,r2) # encryption c1t = oEC.mul_comb2_EFp2(ECG,r2,self.precomp_g,Jcoord) c1 = oEC.toEFp2(ECG,c1t,Jcoord) #c1 = r2*g c2t = oEC.mul_comb2_EFp2(ECG,r3,self.precomp_g,Jcoord) c2 = oEC.toEFp2(ECG,c2t,Jcoord) #c2 = r3*g c31t = oEC.mul_comb2_EFp2(ECG,r1,self.precomp_g1,Jcoord) c32t = oEC.mul_comb2_EFp2(ECG,r3,self.precomp_g2,Jcoord) c3t = oEC.addEFp2(ECG,c31t,c32t,Jcoord) c3 = oEC.toEFp2(ECG,c3t,Jcoord) #c3 = (r1*g1)+(r3*g2) return PPATCCiphertext(d,c1,c2,c3,self)
def commit(self,m,r1=None,r2=None): q = self.PPATCpp.order if r1 == None: r1 = randint(1,int(q)) if r2 == None: r2 = randint(1,int(q)) # notations Jcoord = self.PPATCpp.Jcoord ECG1 = self.h1.ECG ECG2 = self.g1.ECG # commitment d11t = oEC.mul_comb2_EFp(ECG1,r1,self.precomp_h,Jcoord) d12t = oEC.mul_comb2_EFp(ECG1,r2,self.precomp_h1,Jcoord) d1t = oEC.addEFp(ECG1,d11t,d12t,Jcoord) d1 = oEC.toEFp(ECG1,d1t,Jcoord) #d1 = (r1*h)+(r2*h1) mp = self.encode(m) d21t = oEC.mul_comb2_EFp2(ECG2,r2,self.precomp_g1,Jcoord) d2t = oEC.addEFp2(ECG2,mp,d21t,Jcoord) d2 = oEC.toEFp2(ECG2,d2t,Jcoord) #d2 = mp + r2*g1 return PPATCCommitment(d1,d2,self)
def commit(self, m, r1=None, r2=None): q = self.PPATCpp.order if r1 == None: r1 = randint(1, int(q)) if r2 == None: r2 = randint(1, int(q)) # notations Jcoord = self.PPATCpp.Jcoord ECG1 = self.h1.ECG ECG2 = self.g1.ECG # commitment d11t = oEC.mul_comb2_EFp(ECG1, r1, self.precomp_h, Jcoord) d12t = oEC.mul_comb2_EFp(ECG1, r2, self.precomp_h1, Jcoord) d1t = oEC.addEFp(ECG1, d11t, d12t, Jcoord) d1 = oEC.toEFp(ECG1, d1t, Jcoord) #d1 = (r1*h)+(r2*h1) mp = self.encode(m) d21t = oEC.mul_comb2_EFp2(ECG2, r2, self.precomp_g1, Jcoord) d2t = oEC.addEFp2(ECG2, mp, d21t, Jcoord) d2 = oEC.toEFp2(ECG2, d2t, Jcoord) #d2 = mp + r2*g1 return PPATCCommitment(d1, d2, self)
def encrypt(self, m, r1=None, r2=None, r3=None): ''' Outputs a PPATCCiphertext on m using r1,r2 as the randomness for the commitment and r1,r2,r3 as the randomness for the encryption ''' # notations q = self.PPATCpp.order g = self.PPATCpp.g ECG = g.ECG # EFp2 Jcoord = self.PPATCpp.Jcoord if r1 == None: r1 = randint(1, int(q)) if r2 == None: r2 = randint(1, int(q)) if r3 == None: r3 = randint(1, int(q)) # commitment d = self.commit(m, r1, r2) # encryption c1t = oEC.mul_comb2_EFp2(ECG, r2, self.precomp_g, Jcoord) c1 = oEC.toEFp2(ECG, c1t, Jcoord) #c1 = r2*g c2t = oEC.mul_comb2_EFp2(ECG, r3, self.precomp_g, Jcoord) c2 = oEC.toEFp2(ECG, c2t, Jcoord) #c2 = r3*g c31t = oEC.mul_comb2_EFp2(ECG, r1, self.precomp_g1, Jcoord) c32t = oEC.mul_comb2_EFp2(ECG, r3, self.precomp_g2, Jcoord) c3t = oEC.addEFp2(ECG, c31t, c32t, Jcoord) c3 = oEC.toEFp2(ECG, c3t, Jcoord) #c3 = (r1*g1)+(r3*g2) return PPATCCiphertext(d, c1, c2, c3, self)
def encrypt(self,m,r=None,s=None): ''' Outputs a PPATSCiphertext on m using r as the randomness for the commitment and s as the randomness for the encryption ''' #limit = 2**self.maxexp #assert m < limit #assert m >= 0 order = self.PPATSpp.order if r == None: r = randint(1,int(order)) if s == None: s = randint(1,int(order)) # notations g1 = self.g1 ECG = g1.ECG Jcoord = self.PPATSpp.Jcoord # commitment part d,r = self.commit(m,r) #d = (r*h)+(m*h1) # encryption part c1t = oEC.mul_comb2_EFp2(ECG,s,self.precomp_g,Jcoord) c1 = oEC.toEFp2(ECG,c1t,Jcoord) #c1 = s*g rgt = oEC.mul_comb2_EFp2(ECG,r,self.precomp_g,Jcoord) sg1t = oEC.mul_comb2_EFp2(ECG,s,self.precomp_g1,Jcoord) c2t = oEC.addEFp2(ECG,rgt,sg1t,Jcoord) c2 = oEC.toEFp2(ECG,c2t,Jcoord) #c2 = (r*g)+(s*g1) return PPATSCiphertext(d,c1,c2,self)
def verifyEvalBatch(self, com, B, rem1_x, rem2_x, w_B): ''' Check if com is a commitment on a polynomial phi such that (b_j,phi_b_j) belongs to the polynomial for each b_j in B. The verification uses the witness w_B and the remainder polynomial rem1_x, rem2_x (see self.createWitnessBatch(...) for their construction). Return True if the verification succeeds. This method computes 3 pairings. ''' Fr = self.Fr e = oEC.OptimAtePairing Pair = self.pairing gp = self.gprimeVec[-1] EFp2 = gp.ECG Fp12 = Pair.Fpk prod_x_minus_b_j = field.polynom(Fr,[Fr.one()]) for b_j in B : x_minus_b_j = field.polynom(Fr,[Fr.one(),-b_j]) prod_x_minus_b_j *= x_minus_b_j if len(prod_x_minus_b_j.coef) < self.deg_pol+1 : # Append zeros coef to phi_x if its coef list is too short (< deg_pol+1) diff = self.deg_pol+1 - len(prod_x_minus_b_j.coef) L = [Fr.zero()]*diff new_prod_x_minus_b_j = field.polynom(Fr,L+prod_x_minus_b_j.coef) prod_x_minus_b_j = new_prod_x_minus_b_j t1 = EFp2.infty t1t = oEC.toTupleEFp2(t1, self.Jcoord) #TODO: Optimize here # DONE for i in range(self.deg_pol+1): #t1 += prod_x_minus_b_j.coef[i].val*self.gprimeVec[i] a = oEC.mul_comb2_EFp2(EFp2,prod_x_minus_b_j.coef[i].val,self.gprimeVecTab[i],self.Jcoord) t1t = oEC.addEFp2(EFp2,t1t,a,self.Jcoord) t1g = oEC.toEFp2(EFp2,t1t,self.Jcoord) if self.Jcoord : t1g.toAffine() #assert t1g == t1 u1 , rem2_x = self.commit(rem1_x,rem2_x) rm = e(com.c,gp,Pair) lm1 = e(w_B.c,t1g,Pair) lm2 = e(u1.c,gp,Pair) lm = oEC.mulFp12(Fp12,lm1,lm2) return rm == lm
def __add__(self,b): ''' Addition between two PPATC ciphertext The result is a PPATC ciphertext which encrypts and commits on the sum of the initial messages ''' assert isinstance(b,PPATCCiphertext) assert self.PPATCpk == b.PPATCpk # ciphertexts built using the same public key Jcoord = self.PPATCpk.PPATCpp.Jcoord ECG = self.PPATCpk.g1.ECG newcom = self.d+b.d c1t = oEC.toTupleEFp2(self.c1,Jcoord) bc1t = oEC.toTupleEFp2(b.c1,Jcoord) nc1t = oEC.addEFp2(ECG,c1t,bc1t,Jcoord) newc1 = oEC.toEFp2(ECG,nc1t,Jcoord) c2t = oEC.toTupleEFp2(self.c2,Jcoord) bc2t = oEC.toTupleEFp2(b.c2,Jcoord) nc2t = oEC.addEFp2(ECG,c2t,bc2t,Jcoord) newc2 = oEC.toEFp2(ECG,nc2t,Jcoord) c3t = oEC.toTupleEFp2(self.c3,Jcoord) bc3t = oEC.toTupleEFp2(b.c3,Jcoord) nc3t = oEC.addEFp2(ECG,c3t,bc3t,Jcoord) newc3 = oEC.toEFp2(ECG,nc3t,Jcoord) return PPATCCiphertext(newcom,newc1,newc2,newc3,self.PPATCpk)
def __add__(self, b): ''' Addition between two PPATC ciphertext The result is a PPATC ciphertext which encrypts and commits on the sum of the initial messages ''' assert isinstance(b, PPATCCiphertext) assert self.PPATCpk == b.PPATCpk # ciphertexts built using the same public key Jcoord = self.PPATCpk.PPATCpp.Jcoord ECG = self.PPATCpk.g1.ECG newcom = self.d + b.d c1t = oEC.toTupleEFp2(self.c1, Jcoord) bc1t = oEC.toTupleEFp2(b.c1, Jcoord) nc1t = oEC.addEFp2(ECG, c1t, bc1t, Jcoord) newc1 = oEC.toEFp2(ECG, nc1t, Jcoord) c2t = oEC.toTupleEFp2(self.c2, Jcoord) bc2t = oEC.toTupleEFp2(b.c2, Jcoord) nc2t = oEC.addEFp2(ECG, c2t, bc2t, Jcoord) newc2 = oEC.toEFp2(ECG, nc2t, Jcoord) c3t = oEC.toTupleEFp2(self.c3, Jcoord) bc3t = oEC.toTupleEFp2(b.c3, Jcoord) nc3t = oEC.addEFp2(ECG, c3t, bc3t, Jcoord) newc3 = oEC.toEFp2(ECG, nc3t, Jcoord) return PPATCCiphertext(newcom, newc1, newc2, newc3, self.PPATCpk)
def opens(self,c): assert isinstance(c,PPATCCiphertext) #notations Jcoord = self.PPATCpp.Jcoord ECG = self.PPATCpp.g.ECG c2 = c.c2 c3 = c.c3 c2t = oEC.toTupleEFp2(c2,Jcoord) c3t = oEC.toTupleEFp2(c3,Jcoord) c2x2t = oEC.mulECP(ECG,c2t,-self.x2,sq= True, Jcoord = Jcoord) c3c2x2t = oEC.addEFp2(ECG,c3t,c2x2t,Jcoord) ope = oEC.toEFp2(ECG,c3c2x2t,Jcoord) # ope = c3-(self.x2*c2) return ope
def decrypt(self,c): assert isinstance(c,PPATCCiphertext) #notations Jcoord = self.PPATCpp.Jcoord ECG = self.PPATCpp.g.ECG d2 = c.d.d2 d2t = oEC.toTupleEFp2(d2,Jcoord) c1 = c.c1 c1t = oEC.toTupleEFp2(c1,Jcoord) c1x1t = oEC.mulECP(ECG,c1t,-self.x1,sq= True, Jcoord = Jcoord) d2c1x1t = oEC.addEFp2(ECG,d2t,c1x1t,Jcoord) dec = oEC.toEFp2(ECG,d2c1x1t,Jcoord) # dec = d2 - (self.x1*c1) return dec
def opens(self, c): assert isinstance(c, PPATCCiphertext) #notations Jcoord = self.PPATCpp.Jcoord ECG = self.PPATCpp.g.ECG c2 = c.c2 c3 = c.c3 c2t = oEC.toTupleEFp2(c2, Jcoord) c3t = oEC.toTupleEFp2(c3, Jcoord) c2x2t = oEC.mulECP(ECG, c2t, -self.x2, sq=True, Jcoord=Jcoord) c3c2x2t = oEC.addEFp2(ECG, c3t, c2x2t, Jcoord) ope = oEC.toEFp2(ECG, c3c2x2t, Jcoord) # ope = c3-(self.x2*c2) return ope
def decrypt(self, c): assert isinstance(c, PPATCCiphertext) #notations Jcoord = self.PPATCpp.Jcoord ECG = self.PPATCpp.g.ECG d2 = c.d.d2 d2t = oEC.toTupleEFp2(d2, Jcoord) c1 = c.c1 c1t = oEC.toTupleEFp2(c1, Jcoord) c1x1t = oEC.mulECP(ECG, c1t, -self.x1, sq=True, Jcoord=Jcoord) d2c1x1t = oEC.addEFp2(ECG, d2t, c1x1t, Jcoord) dec = oEC.toEFp2(ECG, d2c1x1t, Jcoord) # dec = d2 - (self.x1*c1) return dec
def verifyEval(self, com, b, phi_b, phiprime_b, w_b): ''' Check if com is a commitment on a polynomial phi such that (b,phi_b) belongs to the polynomial. The verification uses the witness w_b and the evaluation of the polynomial phiprime at b. Return True if the verification succeeds. This method computes 3 pairings. ''' EFp = self.pairing.EFp e = oEC.OptimAtePairing Pair = self.pairing Fp12 = Pair.Fpk #gamma = Pair.gamma #g = self.gVec[-1] #h = self.hVec[-1] gp = self.gprimeVec[-1] EFp2 = gp.ECG gp_alpha = self.gprimeVec[-2] #TODO: Optimize here # DONE #gprime_b = (b.val)*gp gprime_bt = oEC.mul_comb2_EFp2(EFp2,b.val,self.gprimeVecTab[-1],self.Jcoord) mgprime_bt = oEC.negEFp2(gprime_bt,self.Jcoord) gpat = oEC.toTupleEFp2(gp_alpha,self.Jcoord) t1t = oEC.addEFp2(EFp2,gpat,mgprime_bt,self.Jcoord) #t1 = gp_alpha-gprime_b #u1 = (phi_b.val)*g + (phiprime_b.val)*h a1 = oEC.mul_comb2_EFp(EFp,phi_b.val,self.gVecTab[-1],self.Jcoord) b1 = oEC.mul_comb2_EFp(EFp,phiprime_b.val,self.hVecTab[-1],self.Jcoord) u1t = oEC.addEFp(EFp,a1,b1,self.Jcoord) t1g = oEC.toEFp2(EFp2,t1t,self.Jcoord) u1g = oEC.toEFp(EFp,u1t,self.Jcoord) if self.Jcoord : t1g.toAffine() u1g.toAffine() #assert t1g == t1 #assert u1g == u1 rm = e(com.c,gp,Pair) lm1 = e(w_b.c,t1g,Pair) lm2 = e(u1g,gp,Pair) lm = oEC.mulFp12(Fp12,lm1,lm2) return rm == lm
def __add__(self,b): ''' Addition between two PPATC commitments The result is a PPATC commitment which commits on the sum of the initial messages ''' assert isinstance(b,PPATCCommitment) assert self.PPATCpk == b.PPATCpk # commitments built using the same public key Jcoord = self.PPATCpk.PPATCpp.Jcoord ECG1 = self.PPATCpk.h1.ECG ECG2 = self.PPATCpk.g1.ECG d1t = oEC.toTupleEFp(self.d1,Jcoord) bd1t = oEC.toTupleEFp(b.d1,Jcoord) nd1t = oEC.addEFp(ECG1,d1t,bd1t,Jcoord) newd1 = oEC.toEFp(ECG1,nd1t,Jcoord) d2t = oEC.toTupleEFp2(self.d2,Jcoord) bd2t = oEC.toTupleEFp2(b.d2,Jcoord) nd2t = oEC.addEFp2(ECG2,d2t,bd2t,Jcoord) newd2 = oEC.toEFp2(ECG2,nd2t,Jcoord) return PPATCCommitment(newd1,newd2,self.PPATCpk)
def __add__(self, b): ''' Addition between two PPATC commitments The result is a PPATC commitment which commits on the sum of the initial messages ''' assert isinstance(b, PPATCCommitment) assert self.PPATCpk == b.PPATCpk # commitments built using the same public key Jcoord = self.PPATCpk.PPATCpp.Jcoord ECG1 = self.PPATCpk.h1.ECG ECG2 = self.PPATCpk.g1.ECG d1t = oEC.toTupleEFp(self.d1, Jcoord) bd1t = oEC.toTupleEFp(b.d1, Jcoord) nd1t = oEC.addEFp(ECG1, d1t, bd1t, Jcoord) newd1 = oEC.toEFp(ECG1, nd1t, Jcoord) d2t = oEC.toTupleEFp2(self.d2, Jcoord) bd2t = oEC.toTupleEFp2(b.d2, Jcoord) nd2t = oEC.addEFp2(ECG2, d2t, bd2t, Jcoord) newd2 = oEC.toEFp2(ECG2, nd2t, Jcoord) return PPATCCommitment(newd1, newd2, self.PPATCpk)
def verifyZKS(self, com, b, proof): ''' Checks that the NIZKPoK holds meaning that phi(b) = 0 or phi(b) != 0 where phi is the polynomial commited to in com. ''' Fr = self.Fr e = oEC.OptimAtePairing Pair = self.pairing Fp12 = Pair.Fpk gp = self.gprimeVec[-1] gp_alpha = self.gprimeVec[-2] EFp2 = gp.ECG bp, w_b, phiprime_b_eval, A = proof if A == None : return self.verifyEval(com, b, Fr.zero(), phiprime_b_eval, w_b) elif phiprime_b_eval == None : #TODO: Optimize here # DONE z_j, proof_z_j = A cond1 = self.checkOpeningNIZKPOK(com,proof_z_j) #gprime_b = b.val*gp gprime_bt = oEC.mul_comb2_EFp2(EFp2,b.val,self.gprimeVecTab[-1],self.Jcoord) mgprime_bt = oEC.negEFp2(gprime_bt,self.Jcoord) gpat = oEC.toTupleEFp2(gp_alpha,self.Jcoord) t1t = oEC.addEFp2(EFp2,gpat,mgprime_bt,self.Jcoord) t1g = oEC.toEFp2(EFp2,t1t,self.Jcoord) if self.Jcoord : t1g.toAffine() #gprime_alpha_minus_b = self.gprimeVec[-2]-gprime_b #assert gprime_alpha_minus_b == t1g rm = e(com.c,gp,Pair) lm1 = e(w_b.c,t1g,Pair) lm2 = e(z_j,gp,Pair) lm = oEC.mulFp12(Fp12,lm1,lm2) #cond2 = e(com.c,gp,Pair) == e(w_b.c,t1g,Pair)*e(z_j,gp,Pair) cond2 = rm == lm return cond1 and cond2 else : return False