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 commit(self,phi_x,phiprime_x= None): ''' Return a polynomial commitment on the polynomial phi_x eventually using phiprime_x as the randomness polynomial ''' #Fp = self.pairing.Fp Fr = self.Fr EFp = self.pairing.EFp #order = self.pairing.r assert len(phi_x.coef) <= self.deg_pol+1 if len(phi_x.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(phi_x.coef) L = [Fr.zero()]*diff new_phi_x = field.polynom(Fr,L+phi_x.coef) phi_x = new_phi_x if phiprime_x == None : phiprime_x = self.randomPolynomial() if len(phiprime_x.coef) < self.deg_pol+1 : # Append zeros coef to phiprime_x if its coef list is too short (< deg_pol+1) diff = self.deg_pol+1 - len(phiprime_x.coef) L = [Fr.zero()]*diff new_phiprime_x = field.polynom(Fr,L+phiprime_x.coef) phiprime_x = new_phiprime_x c = EFp.infty ct = oEC.toTupleEFp(c,self.Jcoord) #TODO: Optimize here # DONE for i in range(self.deg_pol+1): #c = c + (phi_x.coef[i].val)*self.gVec[i] + (phiprime_x.coef[i].val)*self.hVec[i] a = oEC.mul_comb2_EFp(EFp,phi_x.coef[i].val,self.gVecTab[i],self.Jcoord) b = oEC.mul_comb2_EFp(EFp,phiprime_x.coef[i].val,self.hVecTab[i],self.Jcoord) a_plus_b = oEC.addEFp(EFp, a,b,self.Jcoord) ct = oEC.addEFp(EFp, ct,a_plus_b,self.Jcoord) cg = oEC.toEFp(EFp,ct,self.Jcoord) if self.Jcoord : cg.toAffine() #assert cg == c #print 'cg,c',cg,c com = PolynomialCommitment(cg,self) return com, phiprime_x
def createWitnessBatch(self, phi_x, phiprime_x, B): ''' Return a witness w_b for the list of points (b_j,phi(b_j)) where b_j in the list B to prove latter that each phi(b_j) is the evaluation of phi on b_j ''' Fr = self.Fr 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 psi_x, rem1_x = phi_x/prod_x_minus_b_j psiprime_x, rem2_x = phiprime_x/prod_x_minus_b_j w_B, psiprime_x = self.commit(psi_x,psiprime_x) return B, rem1_x, rem2_x, w_B
def randomPolynomial(self): ''' Return a random polynomial of degree self.deg_pol ''' Fr = self.Fr L = [] for i in range(self.deg_pol+1): L.append(Fr.random()) return field.polynom(Fr,L)
def commit_messages(self,messageslist,phiprime_x= None): ''' Commit to a list of messages m_i by building the polynomial prod(x-m_i) By default, messages m_j = 0 are append to the list if the lenght of messageslist is smaller than self.deg_pol ''' assert len(messageslist)<=self.deg_pol Fr = self.Fr mlist_copy = messageslist+[] if len(messageslist) < self.deg_pol : for i in range(self.deg_pol-len(messageslist)): mlist_copy.append(Fr.zero()) phi_x = field.polynom(Fr,[Fr.one()]) for i in range(self.deg_pol): x_minus_m_i = field.polynom(Fr,[Fr.one(),-mlist_copy[i]]) phi_x = phi_x*x_minus_m_i return phi_x, self.commit(phi_x,phiprime_x)
def createWitness(self,phi_x,phiprime_x,b): ''' Return a witness w_b for the point (b,phi(b)) to prove latter that phi(b) is the evaluation of phi on b ''' Fr = self.Fr phi_b_eval = phi_x.evaluate(b) phi_b = field.polynom(Fr,[phi_b_eval]) x_minus_b = field.polynom(Fr,[Fr.one(),-b]) psi_x, rem1 = (phi_x-phi_b)/x_minus_b phiprime_b_eval = phiprime_x.evaluate(b) phiprime_b = field.polynom(Fr,[phiprime_b_eval]) psiprime_x, rem2 = (phiprime_x-phiprime_b)/x_minus_b assert rem1.iszero() assert rem2.iszero() w_b, psiprime_x = self.commit(psi_x,psiprime_x) return b, phi_b_eval, phiprime_b_eval, w_b
##### Fp ##### Fp = field.Field(p) fp0 = Fp.zero() fp1 = Fp.one() print Fp, " ...done" ##### E[Fp] ##### C = ellipticCurve.Curve(fp0, b * fp1, Fp) # Y**2 = X**3+b PInf = ellipticCurve.ECPoint(infty=True) EFp = ellipticCurve.ECGroup(Fp, C, PInf) P = EFp.elem((-d**2) * fp1, (c**2) * fp1) # P is a generetor of EFp of order n (n*P = Pinf) ##### Fp2b ##### poly1 = field.polynom(Fp, [fp1, fp0, fp1]) # X**2+1 print poly1 Fp2 = field.ExtensionField(Fp, poly1, rep='i') # A**2 = -1 print Fp2, " ...done" fp2_0 = Fp2.zero() fp2_1 = Fp2.one() fp2_ip = field.polynom(Fp, [fp1, fp0]) # 1*A+0 fp2_i = field.ExtensionFieldElem(Fp2, fp2_ip) xi = (c**2) * fp2_1 + (d**3) * fp2_i # c**2+(d**3)*A (4+i) cxi = (c**2) * fp2_1 - (d**3) * fp2_i # c**2-(d**3)*A #ixi = 8*fp2bi-8*fp2b1 # 8*A-8 #xi = ixi.invert() #C2b = EllipticCurve.Curve(fp2b0, 3*ixi,Fp2b) # Y**2 = X**3+3*(8*A-8) C2 = ellipticCurve.Curve(fp2_0, cxi, Fp2) # Y**2 = X**3+c**2-(d**3)*A The twisted curve
##### Fp ##### Fp = field.Field(p) fp0 = Fp.zero() fp1 = Fp.one() print Fp, " ...done" ##### E[Fp] ##### C = ellipticCurve.Curve(fp0,b*fp1,Fp) # Y**2 = X**3+b PInf = ellipticCurve.ECPoint(infty = True) EFp = ellipticCurve.ECGroup(Fp,C,PInf) P = EFp.elem((-d**2)*fp1,(c**2)*fp1) # P is a generetor of EFp of order n (n*P = Pinf) ##### Fp2b ##### poly1 = field.polynom(Fp,[fp1,fp0,fp1]) # X**2+1 print poly1 Fp2 = field.ExtensionField(Fp,poly1,rep='i') # A**2 = -1 print Fp2, " ...done" fp2_0 = Fp2.zero() fp2_1 = Fp2.one() fp2_ip = field.polynom(Fp,[fp1,fp0]) # 1*A+0 fp2_i = field.ExtensionFieldElem(Fp2,fp2_ip) xi = (c**2)*fp2_1+(d**3)*fp2_i # c**2+(d**3)*A (4+i) cxi = (c**2)*fp2_1-(d**3)*fp2_i # c**2-(d**3)*A #ixi = 8*fp2bi-8*fp2b1 # 8*A-8 #xi = ixi.invert() #C2b = EllipticCurve.Curve(fp2b0, 3*ixi,Fp2b) # Y**2 = X**3+3*(8*A-8) C2 = ellipticCurve.Curve(fp2_0, cxi,Fp2) # Y**2 = X**3+c**2-(d**3)*A The twisted curve PInf2 = ellipticCurve.ECPoint(infty = True)