def verify(proofs,N): # determine the length of the longest proof max_MN = 2**max([len(proof.L) for proof in proofs]) # curve points Z = dumb25519.Z Gi = PointVector([hash_to_point('pybullet Gi ' + str(i)) for i in range(max_MN)]) Hi = PointVector([hash_to_point('pybullet Hi ' + str(i)) for i in range(max_MN)]) # set up weighted aggregates y0 = Scalar(0) y1 = Scalar(0) z1 = Scalar(0) z3 = Scalar(0) z4 = [Scalar(0)]*max_MN z5 = [Scalar(0)]*max_MN scalars = ScalarVector([]) # for final check points = PointVector([]) # for final check # run through each proof for proof in proofs: tr = transcript.Transcript('Bulletproof') V = proof.V A = proof.A S = proof.S T1 = proof.T1 T2 = proof.T2 taux = proof.taux mu = proof.mu L = proof.L R = proof.R a = proof.a b = proof.b t = proof.t # get size information M = 2**len(L)/N # weighting factors for batching weight_y = random_scalar() weight_z = random_scalar() if weight_y == Scalar(0) or weight_z == Scalar(0): raise ArithmeticError # reconstruct challenges for v in V: tr.update(v) tr.update(A) tr.update(S) y = tr.challenge() if y == Scalar(0): raise ArithmeticError y_inv = y.invert() z = tr.challenge() if z == Scalar(0): raise ArithmeticError tr.update(T1) tr.update(T2) x = tr.challenge() if x == Scalar(0): raise ArithmeticError tr.update(taux) tr.update(mu) tr.update(t) x_ip = tr.challenge() if x_ip == Scalar(0): raise ArithmeticError y0 += taux*weight_y k = (z-z**2)*sum_scalar(y,M*N) for j in range(1,M+1): k -= (z**(j+2))*sum_scalar(Scalar(2),N) y1 += (t-k)*weight_y for j in range(M): scalars.append(z**(j+2)*weight_y) points.append(V[j]*Scalar(8)) scalars.append(x*weight_y) points.append(T1*Scalar(8)) scalars.append(x**2*weight_y) points.append(T2*Scalar(8)) scalars.append(weight_z) points.append(A*Scalar(8)) scalars.append(x*weight_z) points.append(S*Scalar(8)) # inner product W = ScalarVector([]) for i in range(len(L)): tr.update(L[i]) tr.update(R[i]) W.append(tr.challenge()) if W[i] == Scalar(0): raise ArithmeticError W_inv = W.invert() for i in range(M*N): index = i g = a h = b*((y_inv)**i) for j in range(len(L)-1,-1,-1): J = len(W)-j-1 base_power = 2**j if index/base_power == 0: g *= W_inv[J] h *= W[J] else: g *= W[J] h *= W_inv[J] index -= base_power g += z h -= (z*(y**i) + (z**(2+i/N))*(Scalar(2)**(i%N)))*((y_inv)**i) z4[i] += g*weight_z z5[i] += h*weight_z z1 += mu*weight_z for i in range(len(L)): scalars.append(W[i]**2*weight_z) points.append(L[i]*Scalar(8)) scalars.append(W_inv[i]**2*weight_z) points.append(R[i]*Scalar(8)) z3 += (t-a*b)*x_ip*weight_z # now check all proofs together scalars.append(-y0-z1) points.append(Gc) scalars.append(-y1+z3) points.append(Hc) for i in range(max_MN): scalars.append(-z4[i]) points.append(Gi[i]) scalars.append(-z5[i]) points.append(Hi[i]) if not dumb25519.multiexp(scalars,points) == Z: raise ArithmeticError('Bad verification!') return True
def verify(proofs,N): # determine the length of the longest proof max_MN = 2**max([len(proof[7]) for proof in proofs]) # curve points Z = dumb25519.Z G = dumb25519.G H = hash_to_point('pybullet H') Gi = PointVector([hash_to_point('pybullet Gi ' + str(i)) for i in range(max_MN)]) Hi = PointVector([hash_to_point('pybullet Hi ' + str(i)) for i in range(max_MN)]) # set up weighted aggregates y0 = Scalar(0) y1 = Scalar(0) z1 = Scalar(0) z3 = Scalar(0) z4 = [Scalar(0)]*max_MN z5 = [Scalar(0)]*max_MN scalars = ScalarVector([]) # for final check points = PointVector([]) # for final check # run through each proof for proof in proofs: clear_cache() V,A,S,T1,T2,taux,mu,L,R,a,b,t = proof # get size information M = 2**len(L)/N # weighting factors for batching weight_y = random_scalar() weight_z = random_scalar() if weight_y == Scalar(0) or weight_z == Scalar(0): raise ArithmeticError # reconstruct all challenges for v in V: mash(v) mash(A) mash(S) if cache == Scalar(0): raise ArithmeticError y = cache y_inv = y.invert() mash('') if cache == Scalar(0): raise ArithmeticError z = cache mash(T1) mash(T2) if cache == Scalar(0): raise ArithmeticError x = cache mash(taux) mash(mu) mash(t) if cache == Scalar(0): raise ArithmeticError x_ip = cache y0 += taux*weight_y k = (z-z**2)*sum_scalar(y,M*N) for j in range(1,M+1): k -= (z**(j+2))*sum_scalar(Scalar(2),N) y1 += (t-k)*weight_y for j in range(M): scalars.append(z**(j+2)*weight_y) points.append(V[j]*Scalar(8)) scalars.append(x*weight_y) points.append(T1*Scalar(8)) scalars.append(x**2*weight_y) points.append(T2*Scalar(8)) scalars.append(weight_z) points.append(A*Scalar(8)) scalars.append(x*weight_z) points.append(S*Scalar(8)) # inner product W = ScalarVector([]) for i in range(len(L)): mash(L[i]) mash(R[i]) if cache == Scalar(0): raise ArithmeticError W.append(cache) W_inv = W.invert() for i in range(M*N): index = i g = a h = b*((y_inv)**i) for j in range(len(L)-1,-1,-1): J = len(W)-j-1 base_power = 2**j if index/base_power == 0: g *= W_inv[J] h *= W[J] else: g *= W[J] h *= W_inv[J] index -= base_power g += z h -= (z*(y**i) + (z**(2+i/N))*(Scalar(2)**(i%N)))*((y_inv)**i) z4[i] += g*weight_z z5[i] += h*weight_z z1 += mu*weight_z for i in range(len(L)): scalars.append(W[i]**2*weight_z) points.append(L[i]*Scalar(8)) scalars.append(W_inv[i]**2*weight_z) points.append(R[i]*Scalar(8)) z3 += (t-a*b)*x_ip*weight_z # now check all proofs together scalars.append(-y0-z1) points.append(G) scalars.append(-y1+z3) points.append(H) for i in range(max_MN): scalars.append(-z4[i]) points.append(Gi[i]) scalars.append(-z5[i]) points.append(Hi[i]) if not dumb25519.multiexp(scalars,points) == Z: raise ArithmeticError('Bad z check!') return True
def test_8_random(self): data = [[random_point(),random_scalar()] for i in range(8)] result = Z for datum in data: result += datum[0]*datum[1] self.assertEqual(dumb25519.multiexp(data),result)
def verify(proofs,N): # determine the length of the longest proof max_MN = 2**max([len(proof[7]) for proof in proofs]) # curve points Z = dumb25519.Z G = dumb25519.G H = dumb25519.H Gi = PointVector([hash_to_point('pybullet Gi ' + str(i)) for i in range(max_MN)]) Hi = PointVector([hash_to_point('pybullet Hi ' + str(i)) for i in range(max_MN)]) # verify that all points are in the correct subgroup for item in dumb25519.flatten(proofs): if not isinstance(item,Point): continue if not item*Scalar(dumb25519.l) == Z: raise ArithmeticError # set up weighted aggregates y0 = Scalar(0) y1 = Scalar(0) Y2 = Z Y3 = Z Y4 = Z Z0 = Z z1 = Scalar(0) Z2 = Z z3 = Scalar(0) z4 = [Scalar(0)]*max_MN z5 = [Scalar(0)]*max_MN # run through each proof for proof in proofs: clear_cache() V,A,S,T1,T2,taux,mu,L,R,a,b,t = proof # get size information M = 2**len(L)/N # weighting factor for batching w = random_scalar() # reconstruct all challenges for v in V: mash(v) mash(A) mash(S) y = cache mash('') z = cache mash(T1) mash(T2) x = cache mash(taux) mash(mu) mash(t) x_ip = cache y0 += taux*w k = (z-z**2)*sum_scalar(y,M*N) for j in range(1,M+1): k -= (z**(j+2))*sum_scalar(Scalar(2),N) y1 += (t-k)*w Temp = Z for j in range(M): Temp += V[j]*(z**(j+2)*Scalar(8)) Y2 += Temp*w Y3 += T1*(x*w*Scalar(8)) Y4 += T2*((x**2)*w*Scalar(8)) Z0 += (A*Scalar(8)+S*(x*Scalar(8)))*w # inner product W = [] for i in range(len(L)): mash(L[i]) mash(R[i]) W.append(cache) for i in range(M*N): index = i g = a h = b*((y.invert())**i) for j in range(len(L)-1,-1,-1): J = len(W)-j-1 base_power = 2**j if index/base_power == 0: g *= W[J].invert() h *= W[J] else: g *= W[J] h *= W[J].invert() index -= base_power g += z h -= (z*(y**i) + (z**(2+i/N))*(Scalar(2)**(i%N)))*((y.invert())**i) z4[i] += g*w z5[i] += h*w z1 += mu*w Multiexp = [] for i in range(len(L)): Multiexp.append([L[i],Scalar(8)*(W[i]**2)]) Multiexp.append([R[i],Scalar(8)*(W[i].invert()**2)]) Z2 += dumb25519.multiexp(Multiexp)*w z3 += (t-a*b)*x_ip*w # now check all proofs together if not G*y0 + H*y1 - Y2 - Y3 - Y4 == Z: raise ArithmeticError('Bad y check!') Multiexp = [[Z0,Scalar(1)],[G,-z1],[Z2,Scalar(1)],[H,z3]] for i in range(max_MN): Multiexp.append([Gi[i],-z4[i]]) Multiexp.append([Hi[i],-z5[i]]) if not dumb25519.multiexp(Multiexp) == Z: raise ArithmeticError('Bad z check!') return True
def test_2_G_2_G_n1(self): data = [[G,Scalar(2)],[G,Scalar(-1)]] self.assertEqual(dumb25519.multiexp(data),G)
def test_2_G_1_H_2(self): data = [[G,Scalar(1)],[H,Scalar(2)]] self.assertEqual(dumb25519.multiexp(data),G+H*Scalar(2))
def test_1_G_2(self): data = [[G,Scalar(2)]] self.assertEqual(dumb25519.multiexp(data),G*Scalar(2))
def test_1_G_0(self): data = [[G,Scalar(0)]] self.assertEqual(dumb25519.multiexp(data),Z)
def test_0(self): self.assertEqual(dumb25519.multiexp([]),Z)