def angle_sequence(p, eps=1e-4, suc=1 - 1e-4): """ Solve for the angle sequence corresponding to the array p, with eps error budget and suc success probability. The bigger the error budget and the smaller the success probability, the better the numerical stability of the process. """ p = LPoly.LPoly(p, -len(p) + 1) # Capitalization: eps/2 amount of error budget is put to the highest power for sake of numerical stability. p_new = suc * (p + LPoly.LPoly([eps / 4], p.degree) + LPoly.LPoly([eps / 4], -p.degree)) # Completion phase t = time.time() g = completion.completion_from_root_finding(p_new) t_comp = time.time() print("Completion part finished within time ", t_comp - t) # Decomposition phase seq = decomposition.angseq(g) t_dec = time.time() print("Decomposition part finished within time ", t_dec - t_comp) print(seq) # Make sure that the reconstructed element lies in the desired error tolerance regime g_recon = LPoly.LAlg.unitary_from_angles(seq) final_error = (1 / suc * g_recon.IPoly - p).inf_norm if final_error < eps: return seq else: raise ValueError( "The angle finding program failed on given instance, with an error of {}. Please relax the error budget and/ or the success probability." .format(final_error))
def test_gen_eq(): a = LPoly([0, 1, 2, 3]) b = LPoly([1, 2, 3], deg=1) c = LPoly([0, 1, 2, Bn(3)]) assert a == b assert a == c assert LPoly([0]) == LPoly([0, 0], -5, Bn(3))
def test_eval(): from numpy import fft x = LPoly([1], 1) y = LPoly([0, 1]) assert (y * y).eval(1) == 1 assert x.eval(0) == 0 x = Bn.from_binary(b"10000adadadadada000001").random() print x #x=Bn(1) m = Bn.from_binary(b"10000adadadadadad000001").random() p = LPoly([1, 1], mod=m) q = LPoly([1, 1]) q5 = q * q * q * q * q p5 = p * p * p * p * p rh = p * p assert rh == p.fft_mul(p) assert p5 == q5 #only for small coeffs assert q5.eval(x) % m == pow(x + 1, 5, m) assert (p * p * p * p * p).eval(x) % m == pow( x + 1, 5, m) #this should not be needed but it might help pin down bugs assert (p * p * p * p * p).eval(x) == pow(x + 1, 5, m) assert LPoly([1], -1, 13).eval(5) == 8 assert LPoly([1], -1, 13).eval(Bn(5)) == 8
def PolyEval(ck, sk, x): G, key = ck g = G.generator() p = G.order() h, b, bb, bneg, bbneg, r, rr, rrneg, bh = sk v = h.eval(x) #Hscale=[[elem*pow(x,i,p) for elem in bh[i]] for i in xrange(len(bh))] #wrong Hscale = LPoly([Ve(hi) for hi in bh], mod=p).eval(x) Zh = sum([r[i] * pow(x, i, p) for i in xrange(len(r))]) try: xi = x.mod_inverse(p) #print 'Bn path succeeded' except AttributeError: #print 'Generic path' xi = _invert(x, p) Zb = rr * x - rrneg * xi pi = (Hscale, Zh, Zb) return v, pi
def PolyVerify(ck, pk, m, n1, n2, x, v, pi, commitfunction=Commitment.commit): G, key = ck g = G.generator() p = G.order() H, BP, BPP = pk Hscale, Zh, Zb = pi try: xi = x.mod_inverse(p) #print 'Bn path succeeded' except AttributeError: #print 'Generic path' xi = _invert(x, p) Cleft = reduce(operator.add, [pow(x, i, p) * H[i] for i in xrange(len(H))]) #print 'x=',x #print Hscale #print v #print [xss%p for xss in Hscale] Cright = commitfunction(ck, Hscale, Zh) if not Cleft == Cright: print 'Verification Failed (1)' return 0 Cleft2 = x * BP - xi * BPP ppoly = LPoly(Hscale[:n1], mod=p) npoly = LPoly(Hscale[-n2:], mod=p) assert len(ppoly) == n1 assert len(npoly) == n2 rv1 = ppoly.eval(pow(x, m, p)) * x #print 'rv1sc',x #print 'rv1e ',ppoly.eval(pow(x,m,p)) rv2 = npoly.eval(pow(x, m, p)) * pow(xi, m * n2 + 1, p) #print 'rv2sc',pow(xi,m*n2+1,p) #print 'rv2e ',npoly.eval(pow(xi,m,p)) rval2 = (rv1 + rv2 - v) % p #print 'diff==',(rv1+rv2-v)%p #print 'rval2=',rval2,ppoly,'=',rv1,npoly,'=',rv2 Cright2 = commitfunction(ck, [rval2], Zb) if not Cleft2 == Cright2: print 'Verification Failed (2)' return 0 print 'Verification successful' return 1
def test_aio(): nn2 = Bn(50000).random() + 10 nn1 = Bn(50000).random() + 10 m = int(math.sqrt(int(max(nn1, nn2)))) n1 = int(math.ceil(int(nn1 / m))) + 1 n2 = int(math.ceil(int(nn2 / m))) + 1 assert m * n1 >= nn1 assert m * n2 >= nn2 ck = commitment_key_gen(n1 + n2) G, key = ck g = G.generator() p = G.order() np = [Bn(2**20).random() for c in xrange(nn2)] h = LPoly(np, deg=-len(np), mod=p) h.append(0) np = [Bn(2**20).random() for c in xrange(nn1)] h = h + LPoly(np, deg=1, mod=p) #h=LPoly([-3,-2,-1,0,1,2,3,4,5,6,7,8],deg=-3,mod=p) #h=LPoly([3,0,5],deg=-1,mod=23) #h=LPoly([100,-10,4,5],deg=8,mod=p) #h=LPoly([100],deg=1,mod=p) x0 = p.random() #print h.pp() pk, sk = PolyCommit(ck, m, n1, n2, h) print 'Commit Ok' v, pi = PolyEval(ck, sk, x0) #print v,h.eval(x0) assert v == h.eval(x0) print 'Eval Ok' ver = PolyVerify(ck, pk, m, n1, n2, x0, v, pi) assert ver == 1 #print 'h(x)=',h.pp() print 'x0=', x0 print 'p=', p
def verifier_sat_log(ck, m, n, N, m1, n1, n2, Q, W, index, C, Trans, usesmallints=0): G, key = ck p = G.order() Lcomm, Rcomm, Pcomm, Bcomm, y, pk, x, V, pi, z_x, proof = Trans commitf = commit def shortint(x): return long(int(x)) if usesmallints == 1: y = Bn.from_decimal(str(y)) xs = x xx = Bn.from_decimal(str(x)) commitf = commit_str else: commitf = commit xx = x xs = x if m * n > N: #print 'N' #state.resize(m*n,refcheck=False) #yolo N = m * n if not PolyVerify(ck, pk, m1, n1, n2, xx, V, pi, commitf): return False #A,A_open,A_rand,B,B_open,B_rand,z,T = proof Y = Ve([y.mod_pow(i, p) for i in range(n)]) #yN=y.mod_pow(N+1,p) yn = Y[-1] * y % p yN = (yn).mod_pow(m, p) * y % p #y^(N+1) YN = [yn.mod_pow(i, p) for i in range(m)] YInv = [v.mod_inverse(p) for v in YN] YInv_n = [v.mod_inverse(p) for v in Y] if usesmallints == 1: #print "Smallnumming" #y,Y,yn,yN,YN,YINV pp = p p = shortint(p) y = shortint(y) yn = shortint(yn) yN = shortint(yN) YNN = [i for i in YN] #backup for i in xrange(len(YN)): YN[i] = shortint(YN[i]) for i in xrange(len(YInv)): YInv[i] = shortint(YInv[i]) for i in xrange(len(Y)): Y[i] = shortint(Y[i]) #print "trying small" else: YNN = YN #ref copy null_vec = LPoly([Ve([0 for i in range(n)])], 0, p) #null vector # Polynomial g: c = reduce(lambda x, z: (x * y + z) % p, [v * yN for v in C[::-1]]) ynq = [1] * Q t = yN for i in xrange(Q): ynq[i] = t t = t * y % p #in paper, q starts from 1 w_L = [0] * N w_R = [0] * N w_P = [0] * N for i in xrange(N): ii = 3 * i if i % 50000 == 0: print i #for j in index[ii] : print W[j][ii]!=0 w_L[i] = sum((W[j])[ii] * ynq[j] for j in index[ii]) % p w_R[i] = sum((W[j])[ii + 1] * ynq[j] for j in index[ii + 1]) % p w_P[i] = sum((W[j])[ii + 2] * ynq[j] for j in index[ii + 2]) % p ww_L = [w_L[i * n:(i + 1) * n:1] for i in range(m)] ww_R = [w_R[i * n:(i + 1) * n:1] for i in range(m)] ww_P = [w_P[i * n:(i + 1) * n:1] for i in range(m)] g_L = LPoly([Ve(v) % p for v in ww_L[::-1]], -m, p) g_R = LPoly([Ve(ww_R[i]) * YInv[i] for i in range(m)], 1, p) g_P = LPoly([Ve(ww_P[i]) - Y * YN[i] for i in range(m - 1, -1, -1)], -2 * m, p) g = (g_L + g_R + g_P) g_x = g.eval(xs) if usesmallints: p = pp xinv = xx.mod_inverse(p) #print x,xinv X = [xx.mod_pow(i + 1, p) for i in range(m)] XInv = [xinv.mod_pow(i + 1, p) * YNN[i] % p for i in range(m) ] #XInv=[X[i].mod_inverse(p)*YN[i]%p for i in range(m)] #Xm=[x.mod_pow(i+1+m,p) for i in range(m)] Xm = [X[i] * X[-1] % p for i in range(m)] xm = Xm[-1] * xx % p #xm=x.mod_pow(2*m+1,p)#xm=Xm[-1]*x%p D = reduce(lambda a, b: a + b, [ X[i] * Lcomm[i] + XInv[i] * Rcomm[i] + Xm[i] * Pcomm[i] for i in range(m) ]) BB = xm * Bcomm #compute c_f1,c_f2 and abort if different form the proof key_1 = [key[i] for i in range(n)] + [key[-1]] key_2 = [YInv_n[i] * key_1[i] for i in range(n)] + [key[-1]] ck_1 = G, key_1 ck_2 = G, key_2 c_f1 = D + BB + commitf( ck_1, [0], -z_x) # the verifier can compute it given z and initial commitments. #print c_f1 c_f2 = c_f1 + commitf( ck_2, 2 * g_x, 0) # the verifier can compute it given z and initial commitments. pub_key = G, key_1, key_2 print 'Ok so far...' return recursive_verifier(pub_key, c_f1, c_f2, V, proof)
def prover_sat_log(ck, m, n, N, m1, n1, n2, Q, state, W, index, C, usesmallints=1, mu=-1): if len(state) != 3 * N: raise Exception('Input size do no match with number of gates -1') if len(W) != Q: raise Exception('Input size do no match with number of gates -2') if len(C) != Q: raise Exception('Input size do no match with number of gates -3') if m * n < N: raise Exception('(m,n) Does not match with N=' + str(N)) if m * n > N: #state.resize(m*n,refcheck=False) #yolo print 'resizing' state += [0] * (3 * (m * n - N)) N = m * n if mu == -1: mu = n / 2 def shortint(x): return long(int(x)) comcost = [0, 0] commitf = commit G, key = ck p = G.order() pp = p #ROUND 1: Initial commitments Lopen = [state[i * 3 * n:(i + 1) * 3 * n:3] for i in range(m)] Ropen = [state[i * 3 * n + 1:(i + 1) * 3 * n:3] for i in range(m)] Popen = [state[i * 3 * n + 2:(i + 1) * 3 * n:3] for i in range(m)] del state if usesmallints == 0: Lopen = [[bigint(x % p) for x in xi] for xi in Lopen] Ropen = [[bigint(x % p) for x in xi] for xi in Ropen] Popen = [[bigint(x % p) for x in xi] for xi in Popen] else: commitf = commit_str print "Starting Commitments" tcom = time.time() L = [commitf(ck, v) for v in Lopen] Lcomm = [v[0] for v in L] #try *zipped_list Lrand = [v[1] for v in L] del L R = [commitf(ck, v) for v in Ropen] Rcomm = [v[0] for v in R] Rrand = [v[1] for v in R] del R P = [commitf(ck, v) for v in Popen] Pcomm = [v[0] for v in P] Prand = [v[1] for v in P] del P Bopen = [p.random() for i in range(n)] #Bopen=[bigint(0) for i in range(n)] Bcomm, Brand = commitf(ck, Bopen) tcom = time.time() - tcom print("Commitments done: " + str(tcom) + "s") #ROUND 2: define challenge y y = p.random() #ROUND 3: Compute polynomials f,g,h, and commit to h Y = Ve([y.mod_pow(i, p) for i in range(n)]) #yN=y.mod_pow(N+1,p) # yn = Y[-1] * y % p yN = (yn).mod_pow(m, p) * y % p #y^(N+1) YN = [yn.mod_pow(i, p) for i in range(m)] YInv = [v.mod_inverse(p) for v in YN] YInv_n = [v.mod_inverse(p) for v in Y] if usesmallints == 1: print "Smallnumming" #y,Y,yn,yN,YN,YINV p = shortint(p) y = shortint(y) yn = shortint(yn) yN = shortint(yN) for i in xrange(len(YN)): YN[i] = shortint(YN[i]) for i in xrange(len(YInv)): YInv[i] = shortint(YInv[i]) for i in xrange(len(Y)): Y[i] = shortint(Y[i]) for i in xrange(len(Rrand)): Rrand[i] = shortint(Rrand[i]) for i in xrange(len(Lrand)): Lrand[i] = shortint(Lrand[i]) for i in xrange(len(Prand)): Prand[i] = shortint(Prand[i]) for i in xrange(len(Bopen)): Bopen[i] = shortint(Bopen[i]) Brand = shortint(Brand) print "trying small" null_vec = LPoly([Ve([0 for i in range(n)])], 0, p) #null vector print "Powers of y Done" # Polynomial f: f_L = LPoly([Ve(v) for v in Lopen], 1, p) f_R = LPoly([Ve(Ropen[i]) * YN[i] for i in range(m - 1, -1, -1)], -m, p) f_P = LPoly([Ve(v) for v in Popen], m + 1, p) f_B = LPoly([Ve(Bopen)], 2 * m + 1, p) f = f_L + f_R + f_P + f_B + null_vec #sometimes dot_mul uses 0X^0 if the constant term is missing, null_vec avoids problems del f_L, f_R, f_P, f_B, Lopen, Ropen, Popen, Bopen z_L = LPoly([v for v in Lrand], 1, p) z_R = LPoly([Rrand[i] * YN[i] for i in range(m - 1, -1, -1)], -m, p) z_P = LPoly([v for v in Prand], m + 1, p) z_B = LPoly([Brand], 2 * m + 1, p) z = z_L + z_R + z_P + z_B del z_L, z_R, z_P, z_B, Lrand, Rrand, Prand, Brand #print 'f=',f.pp() # Polynomial g: c = reduce(lambda x, z: (x * y + z) % p, [v * yN for v in C[::-1]]) del C print 'c=', c # Derive a single constraint out of Q by randomizing with y print "starting W" tfft = time.time() #w_L=reduce((lambda x,z:(x*y+z)%p),(Ve(dense(v,3*N)[::3])*yN%p for v in reversed(W))) ynq = [1] * Q t = yN for i in xrange(Q): ynq[i] = t t = t * y % p #in paper, q starts from 1 w_L = [0] * N w_R = [0] * N w_P = [0] * N #print index[0],index[-1] for i in xrange(N): ii = 3 * i if i % 100000 == 0: print i #for j in index[ii] : print W[j][ii]!=0 w_L[i] = sum((W[j])[ii] * ynq[j] % p for j in index[ii]) % p w_R[i] = sum((W[j])[ii + 1] * ynq[j] % p for j in index[ii + 1]) % p w_P[i] = sum((W[j])[ii + 2] * ynq[j] % p for j in index[ii + 2]) % p del index tfft = time.time() - tfft print "*Prover W done in ", tfft, ' sec' # Parse into m vectors of size n ww_L = [w_L[i * n:(i + 1) * n:1] for i in range(m)] ww_R = [w_R[i * n:(i + 1) * n:1] for i in range(m)] ww_P = [w_P[i * n:(i + 1) * n:1] for i in range(m)] del w_L, w_R, w_P print "Parsing W done, starting g" g_L = LPoly([Ve(v) % p for v in ww_L[::-1]], -m, p) g_R = LPoly([Ve(ww_R[i]) * YInv[i] for i in range(m)], 1, p) g_P = LPoly([Ve(ww_P[i]) - Y * YN[i] for i in range(m - 1, -1, -1)], -2 * m, p) g = g_L + g_R + g_P + null_vec #print g del ww_L, ww_R, ww_P, g_L, g_R, g_P if usesmallints == 999: print "Smallnumming" f, Y, c, g, p #shortint=long for i in xrange(len(Y)): Y[i] = shortint(Y[i]) c = shortint(c) pp = p p = shortint(p) f.setmodulus(shortint(f.modulus)) for i in xrange(len(f)): for j in xrange(len(f[i])): f[i][j] = shortint(f[i][j]) g.setmodulus(shortint(g.modulus)) for i in xrange(len(g)): for j in xrange(len(g[i])): g[i][j] = shortint(g[i][j]) print "trying small" #deleting stuff del YN, YInv #gc.collect #Output commitments to a file and f,pt,ck,usesmallints into another print "g done, starting h" # Polynomial h: print "f,g:", f.ldegree, g.ldegree pt = f * Y + 2 * g print "pt:", pt.ldegree #print f #print pt tfft = time.time() polyfile = open('polyfile_before.txt', 'w', buffering=4096 * 1000) polyfile.write(str(p) + '\n') polyfile.write(str(len(f)) + '\n') polyfile.write(str(len(pt)) + '\n') polyfile.write(str(len(f[0])) + '\n') vsize = len(f[0]) for i in xrange(vsize): polyfile.write('[' + ' '.join((str(cf[i]) for cf in f)) + ']\n') polyfile.write('[' + ' '.join((str(cg[i]) for cg in pt)) + ']\n') polyfile.close() tfft = time.time() - tfft print '*File out took ' + str(tfft) + ' seconds.' tfft = time.time() deg = pt.ldegree del pt #gc.collect() #subprocess.call('./polyhelper') os.system('./polyhelper') tfft = time.time() - tfft print '*FFT took ' + str(tfft) + ' seconds.' polyfile = open('polyfile_after.txt', 'r') tfft = time.time() hvec = ast.literal_eval(polyfile.read()) #fills hvec tfft = time.time() - tfft polyfile.close() print 'File in out took ' + str(tfft) + ' seconds.' tfft = time.time() hh2 = LPoly(hvec, f.ldegree + deg, p) - 2 * c #1:-1 drop [ ] from ntl #h1= f.fft_mul(pt)-2*c #dot_mul does not reduce after sum h = hh2 tfft = time.time() - tfft #print '*sub took '+str(tfft)+' seconds.' print "Commiting to h" print h.getcoeff(0), h.getcoeff(0) == 0 #print hh2-h%p #if usesmallints==1: if 1: for i in xrange(len(h)): h[i] = Bn.from_decimal(str(h[i] % p)) #print h h.setmodulus(Bn.from_decimal(str(p))) p = pp #print "sum of coeff 0",sum(h.getcoeff(0))%p # Commit to h tfft = time.time() pk, sk = PolyCommit(ck, m1, n1, n2, h, commitf) print "Message done" tfft = time.time() - tfft print '*PolyCommit out took ' + str(tfft) + ' seconds.' # Challenge x x = pp.random() xx = x if usesmallints == 1: x = shortint(x) # evaluate commitment to generate first part of the proof print "Starting PolyEval" print type(xx) v, pi = PolyEval(ck, sk, xx) f_x = f.eval(x) z_x = z.eval(x) g_x = g.eval(x) #print f_x,v #print z_x print "PolyEval done" # call recursive prover to generate proof and append trascript to proof. # compute A,B key_1 = [key[i] for i in xrange(n)] + [key[-1]] #print key_1,len(key_1),key[-1]==key_1[-1] key_2 = [YInv_n[i] * key_1[i] for i in range(n)] + [key[-1]] #print key_2,len(key_2),key[-1]==key_2[-1],Y[2]*key_2[2]==key[2] ck_1 = G, key_1 ck_2 = G, key_2 c_f1 = commitf( ck_1, f_x, 0) # the verifier can compute it given z and initial commitments. #print c_f1 c_f2 = c_f1 + commitf( ck_2, 2 * g_x, 0) # the verifier can compute it given z and initial commitments. #print c_f2 pub_key = G, key_1, key_2 #print '---',f_x*2,'---',f_x,'---',(f_x*Y+2*g_x)%p proof, comcost = recursive_prover(pub_key, c_f1, f_x, 0, c_f2, f_x * Y + 2 * g_x, 0, v - 2 * c, N, mu, [], usesmallints) #recursive_prover(public_key,A,Aopen ,Arand,B,Bopen,Brand ,z, N,mu=0,T=[],usesmallints=0) comcost[0] += 3 * len(Lcomm) + 1 + (m1 + 1) comcost[1] += 2 + n1 + n2 + 2 #print '*** Comcost (log):',comcost return (Lcomm, Rcomm, Pcomm, Bcomm, y, pk, x, v, pi, z_x, proof), comcost
def verifier_sat(ck, m, n, N, m1, n1, n2, Q, W, index, C, Trans, usesmallints=0, verbose=0): #shortint=long commitf = commit_str G, key = ck p = G.order() Lcomm, Rcomm, Pcomm, Bcomm, y, pk, x, pi, f_x, z_x = Trans if usesmallints == 1: y = Bn.from_decimal(str(y)) xs = x xx = Bn.from_decimal(str(x)) else: commitf = commit xx = x xs = x if m * n > N: #print 'N' #state.resize(m*n,refcheck=False) #yolo N = m * n Y = Ve([y.mod_pow(i, p) for i in range(n)]) #yN=y.mod_pow(N+1,p) yn = Y[-1] * y % p yN = (yn).mod_pow(m, p) * y % p #y^(N+1) YN = [yn.mod_pow(i, p) for i in range(m)] YInv = [v.mod_inverse(p) for v in YN] if usesmallints == 1: if verbose: print "Smallnumming" #y,Y,yn,yN,YN,YINV pp = p p = shortint(p) y = shortint(y) yn = shortint(yn) yN = shortint(yN) YNN = [i for i in YN] #backup for i in xrange(len(YN)): YN[i] = shortint(YN[i]) for i in xrange(len(YInv)): YInv[i] = shortint(YInv[i]) for i in xrange(len(Y)): Y[i] = shortint(Y[i]) if verbose: print "trying small" else: YNN = YN #ref copy null_vec = LPoly([Ve([0 for i in xrange(n)])], 0, p) #null vector # Polynomial g: c = reduce(lambda x, z: (x * y + z) % p, [v * yN for v in C[::-1]]) ynq = [1] * Q t = yN for i in xrange(Q): ynq[i] = t t = t * y % p #in paper, q starts from 1 w_L = [0] * N w_R = [0] * N w_P = [0] * N for i in xrange(N): ii = 3 * i if i % 100000 == 0 and verbose: print i #for j in index[ii] : print W[j][ii]!=0 w_L[i] = sum((W[j])[ii] * ynq[j] % p for j in index[ii]) % p w_R[i] = sum((W[j])[ii + 1] * ynq[j] % p for j in index[ii + 1]) % p w_P[i] = sum((W[j])[ii + 2] * ynq[j] % p for j in index[ii + 2]) % p #w_L[i]=reduce((lambda x,z:x+z%p),((W[j])[ii]*ynq[j]%p for j in index[ii])) #w_R[i]=reduce((lambda x,z:x+z%p),((W[j])[ii+1]*ynq[j]%p for j in index[ii+1])) #w_P[i]=reduce((lambda x,z:x+z%p),((W[j])[ii+2]*ynq[j]%p for j in index[ii+2])) ww_L = [w_L[i * n:(i + 1) * n:1] for i in range(m)] ww_R = [w_R[i * n:(i + 1) * n:1] for i in range(m)] ww_P = [w_P[i * n:(i + 1) * n:1] for i in range(m)] g_L = LPoly([Ve(v) % p for v in ww_L[::-1]], -m, p) g_R = LPoly([Ve(ww_R[i]) * YInv[i] for i in range(m)], 1, p) g_P = LPoly([Ve(ww_P[i]) - Y * YN[i] for i in range(m - 1, -1, -1)], -2 * m, p) g = (g_L + g_R + g_P) g_x = g.eval(xs) v = dotprod(f_x, f_x * Y + 2 * g_x) - 2 * c if usesmallints: v = Bn.from_decimal(str(v)) p = pp if not PolyVerify(ck, pk, m1, n1, n2, xx, v, pi, commitf): return False xinv = xx.mod_inverse(p) #print x,xinv X = [xx.mod_pow(i + 1, p) for i in range(m)] XInv = [xinv.mod_pow(i + 1, p) * YNN[i] % p for i in range(m) ] #XInv=[X[i].mod_inverse(p)*YN[i]%p for i in range(m)] #Xm=[x.mod_pow(i+1+m,p) for i in range(m)] Xm = [X[i] * X[-1] % p for i in range(m)] xm = Xm[-1] * xx % p #xm=x.mod_pow(2*m+1,p)#xm=Xm[-1]*x%p D = reduce(lambda a, b: a + b, [ X[i] * Lcomm[i] + XInv[i] * Rcomm[i] + Xm[i] * Pcomm[i] for i in range(m) ]) #RR=reduce(lambda a,b:a+b,[XInv[i]*Rcomm[i] for i in range(m)]) #PP=reduce(lambda a,b:a+b,[Xm[i]*Pcomm[i] for i in range(m)]) BB = xm * Bcomm #print LL,RR,PP,BB #D=LL+RR+PP+BB if usesmallints: return check_open_commit_str(ck, D + BB, f_x, z_x) else: return check_open_commit(ck, D + BB, f_x, z_x)
def test_add_mul(): a = LPoly([0, 1, Bn(2), 3]) b = LPoly([1, 2, 3], deg=1) c = LPoly([0, 1, 2, Bn(3)], mod=3, deg=4) assert a + b == b + a assert 2 * a == a + a assert 5 * c == c + c + c + c + c x = LPoly([1], 1) y = LPoly([0, 1]) assert x == y assert x.setbot(2) == y * y m = Bn.from_binary(b"10000adadadadadad000001").random() p = LPoly([1, 1], mod=m) q = LPoly([1, 1]) q5 = q * q * q * q * q p5 = p * p * p * p * p assert p5 == q5 #only for small coeffs assert (p * p * p).modulus == m assert (q - q) == LPoly([0]) assert LPoly([0]) + p == (q - q) + p assert LPoly([0], mod=m) == p - p print(-1 * p).modulus print(p - p).pp(), (p - p).modulus assert (p - p).reduce() == LPoly([0], mod=m) assert (p - p) == LPoly([0], mod=m) assert (q - q) + p == LPoly([0]) + p pstride = LPoly([3, 2, 1, 0, 1, 2, 3], deg=-3) assert pstride + LPoly([0]) == pstride
assert len(b) == len(5 * b) assert a - b + b == a assert a + 2 == 2 + a assert a * 5 == 5 * a from petlib.ec import * import numpy as np G = EcGroup() a = np.array([G.order(), G.order().random()]) x = [1, 2, 3, 4, G.order().random()] y = Ve2(x) print x, x + x, y + y, y // y print a, a * a, a * a % G.order() - G.order(), a + a, a * 2, 2 * a, a % 2 G = EcGroup() p1 = LPoly([[Bn(1), int(2)], [3, 4]], 0, 7) p2 = LPoly([Ve([10000000000000000000, 2]), Ve([3, 4])], 0) print p2, p2.fft_mul_np(p2), (p2 * p2) assert False print p print p.ldegree print p.pp() p.settop(5) print p.ldegree p.pp() p.setbot(-4) p.pp() q = LPoly([3, 4]) print q.pp() r = p * q
def PolyCommit(ck, m, n1, n2, h, commitfunction=Commitment.commit): ''' Beware: currently the table is pos|neg rather than neg|pos as in the paper. Operations and coeffs are adjusted to match but care should be taken. ''' G, key = ck g = G.generator() p = G.order() #print h.getcoeff(0),(h.getcoeff(0)%p) assert h.getcoeff(0) == 0 #blinders b = [p.random() for i in xrange(1, n1)] bneg = [p.random() for i in xrange(1, n2)] bb = p.random() bbneg = p.random() #rands r = [p.random() for i in xrange(0, m + 1)] rr = p.random() rrneg = p.random() #ezmode #b=[0]*(n1-1) #bneg=[0]*(n2-1) #bb=0 #bbneg=5 #r=[0]*(m+1) #rr=0 #rrneg=0 h = h + LPoly([0], mod=p) #force 0 to actually be present #print h.pp() maxdeg = h.ldegree + len(h) mindeg = h.ldegree assert mindeg <= 0 assert maxdeg >= 0 hneg = h[:max(0, -mindeg)] hneg.reverse() #yes, but re-reverse later hpos = h[max(0, -mindeg + 1):] assert len(hpos) <= n1 * m + 1 assert len(hneg) <= n2 * m + 1 hpos += [0] * (n1 * m + 1 - len(hpos)) #list operations, not polynomial hneg += [0] * (n2 * m + 1 - len(hneg)) hneg.reverse() #re-reverse bh = [0] * (m + 1) bh[0] = hpos[0:1] + b + hneg[0:1] + bneg for i in xrange(1, m + 1): bh[i] = [hpos[j * m + i] for j in xrange(n1)] bh[i] += [hneg[j * m + i] for j in xrange(n2)] bh[m] = map(lambda x, y: x - y, bh[m], b + [0] + bneg + [0]) bh[0][0] += bb bh[m][-1] -= bbneg #print 'bh=',bh assert len(bh) == m + 1 assert len(bh) == len(r) for x in bh: assert len(x) == n1 + n2 #print len(bh) #print len(zip(bh,r)),len(ck[1]) H = [commitfunction(ck, x, rand) for x, rand in zip(bh, r)] BP = commitfunction(ck, [bb], rr) BPP = commitfunction(ck, [bbneg], rrneg) pk = H, BP, BPP sk = h, b, bb, bneg, bbneg, r, rr, rrneg, bh #print h.pp() return pk, sk