def commit(h, m, n, d): if len(h) != m * n + d + 1: raise ArithmeticError if m < 1 or n < 1 or d < 0 or d >= m: raise IndexError b = [dumb25519.random_scalar() for j in range(n)] + [dumb25519.Scalar(0)] # blinding terms M = [] # blinded coefficient matrix; initially we define using columns # the first column is unique M.append([h[i] for i in range(d)] + [h[d] - b[0]] + [dumb25519.Scalar(0) for i in range(m - d)]) # the rest of the columns (this is why there is an extra blinding term) for j in range(n): M.append([b[j]] + [h[i] for i in range(j * m + d + 1, (j + 1) * m + d)] + [h[(j + 1) * m + d] - b[j + 1]]) # test that each matrix entry is a Scalar for i in range(n + 1): for j in range(m + 1): if not isinstance(M[i][j], dumb25519.Scalar): raise TypeError # commit to each row r = [dumb25519.random_scalar() for i in range(m + 1)] # masks H = [] # commitments for i in range(m + 1): H.append(dumb25519.pedersen_commit([col[i] for col in M], r[i])) return H, [M, b, r]
def test_batch_2_m_1_n_4(self): M = 1 N = 4 data = [[Scalar(random.randint(0,2**N-1)),random_scalar()] for i in range(M)] proof1 = pybullet.prove(data,N) data = [[Scalar(random.randint(0,2**N-1)),random_scalar()] for i in range(M)] proof2 = pybullet.prove(data,N) pybullet.verify([proof1,proof2],N)
def test_scalar_vector_mul_scalar(self): l = 3 v = ScalarVector([random_scalar() for i in range(l)]) s = random_scalar() w = v*s self.assertEqual(len(w),l) for i in range(l): self.assertEqual(w[i],v[i]*s)
def test_scalar_vector_sub(self): l = 3 v = ScalarVector([random_scalar() for i in range(l)]) w = ScalarVector([random_scalar() for i in range(l)]) x = v-w self.assertEqual(len(x),l) for i in range(l): self.assertEqual(x[i],v[i]-w[i])
def test_scalar_vector_hadamard(self): l = 3 v = ScalarVector([random_scalar() for i in range(l)]) w = ScalarVector([random_scalar() for i in range(l)]) x = v*w self.assertEqual(len(x),l) for i in range(l): self.assertEqual(x[i],v[i]*w[i])
def test_inner_product(self): l = 3 v = ScalarVector([random_scalar() for i in range(l)]) w = ScalarVector([random_scalar() for i in range(l)]) x = v**w r = Scalar(0) for i in range(l): r += v[i]*w[i] self.assertEqual(r,x)
def test_invalid_batch_2_m_1_2_n_4(self): M = 1 N = 4 data = [[Scalar(random.randint(0,2**N-1)),random_scalar()] for i in range(M)] proof1 = pybullet.prove(data,N) M = 2 data = [[Scalar(random.randint(2**N,2**(N+1)-1)),random_scalar()] for i in range(M)] proof2 = pybullet.prove(data,N) with self.assertRaises(ArithmeticError): pybullet.verify([proof1,proof2],N)
def gen_account(public_key,a): r = dumb25519.random_scalar() co = G*a + H*r ek = dumb25519.random_scalar() s = dumb25519.hash_to_scalar(str(public_key.tpk)+str(public_key.spk)+str(public_key.X)+str(ek)) pk = public_key.X + H*s _ek = ecies.encrypt(public_key.tpk,str(pk)+str(co),str(ek)) _a = ecies.encrypt(public_key.spk,str(pk)+str(co),str(a)) _r = ecies.encrypt(public_key.spk,str(pk)+str(co),str(r)) return Account(pk,co,_ek,_a,_r),DepositKey(a,r)
def test_scalar_vector_slice(self): l = 3 scalars = [random_scalar() for i in range(2*l)] v = ScalarVector(scalars) w = v[:l] self.assertEqual(len(w),l) self.assertEqual(w.scalars,scalars[:l])
def test_point_vector_mul_scalar(self): l = 3 V = PointVector([random_point() for i in range(l)]) s = random_scalar() W = V*s self.assertEqual(len(W),l) for i in range(l): self.assertEqual(W[i],V[i]*s)
def encrypt(m,A): k = Scalar(0) while k == Scalar(0): k = random_scalar() output = Ciphertext() output.K = G*k output.M = m + hash_to_scalar(A*k) return output
def test_batch_inversion(self): l = 8 v = ScalarVector([random_scalar() for i in range(l)]) v.append(Scalar(1)) v.append(Scalar(dumb25519.l - 1)) w = v.invert() for i in range(len(v)): self.assertEqual(v[i] * w[i], Scalar(1))
def test_invalid_value(self): M = 1 N = 4 data = [[ Scalar(random.randint(2**N, 2**(N + 1) - 1)), random_scalar() ]] with self.assertRaises(ArithmeticError): pybullet.verify([pybullet.prove(data, N)], N)
def test_point_vector_mul_scalar_vector(self): l = 3 V = PointVector([random_point() for i in range(l)]) v = ScalarVector([random_scalar() for i in range(l)]) W = V*v R = dumb25519.Z for i in range(l): R += V[i]*v[i] self.assertEqual(W,R)
def spend(withdrawal_keys, deposit_keys, tx, mu): witness = prepare_witness(withdrawal_keys, deposit_keys) witness_list = [ witness.d_ijk, witness.x_i, witness.a_in, witness.a_ij, witness.r_in, witness.r_out ] # this is so we can flatten for commitment t = dumb25519.random_scalar() C = dumb25519.pedersen_commit(dumb25519.flatten(witness_list), t) s = dumb25519.hash_to_scalar(str(C) + str(tx) + str(mu))
def encrypt(public_key, tag, message): if not isinstance(public_key, dumb25519.Point): raise TypeError r = dumb25519.random_scalar() R = G * r P = public_key * r hashes = hashlib.sha256(str(P) + str(tag)).hexdigest() sym_key = hashes[:len(hashes) / 2] mac_key = hashes[len(hashes) / 2:] e = binascii.hexlify( AES.new(sym_key, AES.MODE_CFB, '0' * 16).encrypt(str(message))) sigma = hashlib.sha256(mac_key + hashlib.sha256(mac_key + e).hexdigest()).hexdigest() return Ciphertext(R, e, sigma)
def prove(data,N): clear_cache() M = len(data) # curve points G = dumb25519.G H = hash_to_point('pybullet H') Gi = PointVector([hash_to_point('pybullet Gi ' + str(i)) for i in range(M*N)]) Hi = PointVector([hash_to_point('pybullet Hi ' + str(i)) for i in range(M*N)]) # set amount commitments V = PointVector([]) aL = ScalarVector([]) for v,gamma in data: V.append((H*v + G*gamma)*inv8) mash(V[-1]) aL.extend(scalar_to_bits(v,N)) # set bit arrays aR = ScalarVector([]) for bit in aL.scalars: aR.append(bit-Scalar(1)) alpha = random_scalar() A = (Gi*aL + Hi*aR + G*alpha)*inv8 sL = ScalarVector([random_scalar()]*(M*N)) sR = ScalarVector([random_scalar()]*(M*N)) rho = random_scalar() S = (Gi*sL + Hi*sR + G*rho)*inv8 # get challenges mash(A) mash(S) y = cache y_inv = y.invert() mash('') z = cache # polynomial coefficients l0 = aL - ScalarVector([z]*(M*N)) l1 = sL # ugly sum zeros_twos = [] for i in range (M*N): zeros_twos.append(Scalar(0)) for j in range(1,M+1): temp = Scalar(0) if i >= (j-1)*N and i < j*N: temp = Scalar(2)**(i-(j-1)*N) zeros_twos[-1] += temp*(z**(1+j)) # more polynomial coefficients r0 = aR + ScalarVector([z]*(M*N)) r0 = r0*exp_scalar(y,M*N) r0 += ScalarVector(zeros_twos) r1 = exp_scalar(y,M*N)*sR # build the polynomials t0 = l0**r0 t1 = l0**r1 + l1**r0 t2 = l1**r1 tau1 = random_scalar() tau2 = random_scalar() T1 = (H*t1 + G*tau1)*inv8 T2 = (H*t2 + G*tau2)*inv8 mash(T1) mash(T2) x = cache # challenge taux = tau1*x + tau2*(x**2) for j in range(1,M+1): gamma = data[j-1][1] taux += z**(1+j)*gamma mu = x*rho+alpha l = l0 + l1*x r = r0 + r1*x t = l**r mash(taux) mash(mu) mash(t) x_ip = cache # challenge L = PointVector([]) R = PointVector([]) # initial inner product inputs data_ip = [Gi,PointVector([Hi[i]*(y_inv**i) for i in range(len(Hi))]),H*x_ip,l,r,None,None] while True: data_ip = inner_product(data_ip) # we have reached the end of the recursion if len(data_ip) == 2: return [V,A,S,T1,T2,taux,mu,L,R,data_ip[0],data_ip[1],t] # we are not done yet L.append(data_ip[-2]) R.append(data_ip[-1])
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 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 prove(data,N): tr = transcript.Transcript('Bulletproof') M = len(data) # curve points Gi = PointVector([hash_to_point('pybullet Gi ' + str(i)) for i in range(M*N)]) Hi = PointVector([hash_to_point('pybullet Hi ' + str(i)) for i in range(M*N)]) # set amount commitments V = PointVector([]) aL = ScalarVector([]) for v,gamma in data: V.append(com(v,gamma)*inv8) tr.update(V[-1]) aL.extend(scalar_to_bits(v,N)) # set bit arrays aR = ScalarVector([]) for bit in aL.scalars: aR.append(bit-Scalar(1)) alpha = random_scalar() A = (Gi**aL + Hi**aR + Gc*alpha)*inv8 sL = ScalarVector([random_scalar()]*(M*N)) sR = ScalarVector([random_scalar()]*(M*N)) rho = random_scalar() S = (Gi**sL + Hi**sR + Gc*rho)*inv8 # get challenges tr.update(A) tr.update(S) y = tr.challenge() z = tr.challenge() y_inv = y.invert() # polynomial coefficients l0 = aL - ScalarVector([z]*(M*N)) l1 = sL # for polynomial coefficients zeros_twos = [] z_cache = z**2 for j in range(M): for i in range(N): zeros_twos.append(z_cache*2**i) z_cache *= z # more polynomial coefficients r0 = aR + ScalarVector([z]*(M*N)) r0 = r0*exp_scalar(y,M*N) r0 += ScalarVector(zeros_twos) r1 = exp_scalar(y,M*N)*sR # build the polynomials t0 = l0**r0 t1 = l0**r1 + l1**r0 t2 = l1**r1 tau1 = random_scalar() tau2 = random_scalar() T1 = com(t1,tau1)*inv8 T2 = com(t2,tau2)*inv8 tr.update(T1) tr.update(T2) x = tr.challenge() taux = tau1*x + tau2*(x**2) for j in range(1,M+1): gamma = data[j-1][1] taux += z**(1+j)*gamma mu = x*rho+alpha l = l0 + l1*x r = r0 + r1*x t = l**r tr.update(taux) tr.update(mu) tr.update(t) x_ip = tr.challenge() # initial inner product inputs data = InnerProductRound(Gi,PointVector([Hi[i]*(y_inv**i) for i in range(len(Hi))]),Hc*x_ip,l,r,tr) while True: inner_product(data) # we have reached the end of the recursion if data.done: return Bulletproof(V,A,S,T1,T2,taux,mu,data.L,data.R,data.a,data.b,t)
def gen_private_key(): return dumb25519.random_scalar()
def prove(x): if not x < max_x: raise ValueError('Discrete log is too large!') if not x >= 0: raise ValueError('Discrete log must not be negative!') b = nary(x, 2) # generate blinders that sum to zero r = dumb25519.ScalarVector([]) r_sum = dumb25519.Scalar(0) s = dumb448.ScalarVector([]) s_sum = dumb448.Scalar(0) for i in range(len(b) - 1): r.append(dumb25519.random_scalar()) r_sum += dumb25519.Scalar(2)**i * r[-1] s.append(dumb448.random_scalar()) s_sum += dumb448.Scalar(2)**i * s[-1] temp_2inv_25519 = (dumb25519.Scalar(2)**(len(b) - 1)).invert() temp_2inv_448 = (dumb448.Scalar(2)**(len(b) - 1)).invert() r.append(-temp_2inv_25519 * r_sum) s.append(-temp_2inv_448 * s_sum) # sanity check on blinder sums temp_r = dumb25519.Scalar(0) temp_s = dumb448.Scalar(0) for i in range(len(b)): temp_r += dumb25519.Scalar(2)**i * r[i] temp_s += dumb448.Scalar(2)**i * s[i] if not temp_r == dumb25519.Scalar(0) or not temp_s == dumb448.Scalar(0): raise ArithmeticError('Blinder sum check failed!') # generators G = dumb25519.G G1 = dumb25519.hash_to_point('G1') H = dumb448.hash_to_point('H') H1 = dumb448.hash_to_point('H1') # commitments to bits of x C_G = dumb25519.PointVector([]) C_H = dumb448.PointVector([]) for i in range(len(b)): C_G.append(dumb25519.Scalar(b[i]) * G1 + r[i] * G) C_H.append(dumb448.Scalar(b[i]) * H1 + s[i] * H) # sanity check on commitment sums temp_C_G = dumb25519.Z temp_C_H = dumb448.Z for i in range(len(b)): temp_C_G += dumb25519.Scalar(2)**i * C_G[i] temp_C_H += dumb448.Scalar(2)**i * C_H[i] if not temp_C_G == dumb25519.Scalar( x) * G1 or not temp_C_H == dumb448.Scalar(x) * H1: raise ArithmeticError('Bit construction check failed!') # proof elements e0_G = dumb25519.ScalarVector([]) e0_H = dumb448.ScalarVector([]) a0 = dumb25519.ScalarVector([]) a1 = dumb25519.ScalarVector([]) b0 = dumb448.ScalarVector([]) b1 = dumb448.ScalarVector([]) # construct the proof for i in range(len(b)): # the current bit is 0 if b[i] == 0: j = dumb25519.random_scalar() k = dumb448.random_scalar() e1_G = dumb25519.hash_to_scalar(C_G[i], C_H[i], j * G, k * H) e1_H = dumb448.hash_to_scalar(C_G[i], C_H[i], j * G, k * H) a0.append(dumb25519.random_scalar()) b0.append(dumb448.random_scalar()) e0_G.append( dumb25519.hash_to_scalar(C_G[i], C_H[i], a0[i] * G - e1_G * (C_G[i] - G1), b0[i] * H - e1_H * (C_H[i] - H1))) e0_H.append( dumb448.hash_to_scalar(C_G[i], C_H[i], a0[i] * G - e1_G * (C_G[i] - G1), b0[i] * H - e1_H * (C_H[i] - H1))) a1.append(j + e0_G[i] * r[i]) b1.append(k + e0_H[i] * s[i]) # the current bit is 1 elif b[i] == 1: j = dumb25519.random_scalar() k = dumb448.random_scalar() e0_G.append(dumb25519.hash_to_scalar(C_G[i], C_H[i], j * G, k * H)) e0_H.append(dumb448.hash_to_scalar(C_G[i], C_H[i], j * G, k * H)) a1.append(dumb25519.random_scalar()) b1.append(dumb448.random_scalar()) e1_G = dumb25519.hash_to_scalar(C_G[i], C_H[i], a1[i] * G - e0_G[i] * C_G[i], b1[i] * H - e0_H[i] * C_H[i]) e1_H = dumb448.hash_to_scalar(C_G[i], C_H[i], a1[i] * G - e0_G[i] * C_G[i], b1[i] * H - e0_H[i] * C_H[i]) a0.append(j + e1_G * r[i]) b0.append(k + e1_H * s[i]) # somehow the bit is something else else: raise ArithmeticError('Bit decomposition must be 0 or 1!') return Proof( dumb25519.Scalar(x) * G1, dumb448.Scalar(x) * H1, C_G, C_H, e0_G, e0_H, a0, a1, b0, b1)
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_random(self): random_scalar() random_point()
def gen_private_key(): return PrivateKey(ecies.gen_private_key(),ecies.gen_private_key(),dumb25519.random_scalar())
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 test_prove_verify_m_2_n_4(self): M = 2 N = 4 data = [[Scalar(random.randint(0,2**N-1)),random_scalar()] for i in range(M)] pybullet.verify([pybullet.prove(data,N)],N)