def set_z(self, z1, z1_2, muls): assert len( muls) == 2, "Got muls of wrong size with non-None z1_2 in set_z()" self.roundNum = 0 self.compute_z1chi = VerifierIOMLExt.compute_beta( z1, self.circuit.comp_chi, muls[0]) self.compute_z1chi_2 = VerifierIOMLExt.compute_beta( z1_2, self.circuit.comp_chi, muls[1]) # loop over all the gates and make them update their z coeffs for g in self.gates: g.set_z()
def set_rvals(self, rvals, r0val): self.r0val = r0val if self.nbits is not None: assert len(rvals) == self.nbits else: self.nbits = len(rvals) self.v1bits = self.nbits // 2 self.v2bits = self.nbits - self.v1bits self.v1vals = VerifierIOMLExt.compute_beta(rvals[:self.v1bits], self.com.rec_q) self.v2vals = VerifierIOMLExt.compute_beta(rvals[self.v1bits:], self.com.rec_q)
def set_rvals_p(self, rvals, r0val, rZval): assert self.nbits == len(rvals) if self.v1bits > 0: mvals = VerifierIOMLExt.compute_beta(rvals[:self.v1bits], self.com.rec_q) assert len(mvals) == len(self.tvals) assert len(mvals) == len(self.svals) self.avals = util.vector_times_matrix(self.tvals, mvals, self.com.rec_q) self.rAval = util.dot_product(self.svals, mvals, self.com.rec_q) else: self.avals = self.tvals[0] self.rAval = self.svals[0] self.bvals = VerifierIOMLExt.compute_beta(rvals[self.v1bits:], self.com.rec_q, r0val) self.rZval = rZval
def speed_test(num_tests): nBits = random.randint(3, 8) inputs = [ [ Defs.gen_random() for _ in xrange(0, nBits) ] for _ in xrange(0, num_tests) ] lcb = LayerComputeBeta(nBits) lcb.other_factors = [] runtime = time.time() for idx in xrange(0, num_tests): lcb.set_inputs(inputs[idx]) runtime = time.time() - runtime runtime2 = time.time() for idx in xrange(0, num_tests): VerifierIOMLExt.compute_beta(inputs[idx]) runtime2 = time.time() - runtime2 print "nBits: %d\nLayerComputeBeta: %f\nVerifierIOMLExt: %f\n" % (nBits, runtime, runtime2)
def run_test(): # pylint: disable=global-variable-undefined,redefined-outer-name tinputs = [Defs.gen_random() for _ in xrange(0, nOutBits)] taus = [Defs.gen_random() for _ in xrange(0, nOutBits)] lcv.set_inputs(tinputs) assert lcv.outputs == VerifierIOMLExt.compute_beta(tinputs) inputs = [ util.chi(util.numToBin(x, nOutBits), tinputs) for x in xrange(0, 2**nOutBits) ] global scratch global outputs scratch = list(inputs) outputs = list(inputs) def compute_next_value(tau): global scratch global outputs nscratch = [] tauInv = (1 - tau) % Defs.prime for i in xrange(0, len(scratch) / 2): val = ((scratch[2 * i] * tauInv) + (scratch[2 * i + 1] * tau)) % Defs.prime nscratch.append(val) del val scratch = nscratch #ndups = len(outputs) / len(scratch) #nouts = [ [val] * ndups for val in scratch ] outputs = scratch #outputs = [item for sublist in nouts for item in sublist] for i in xrange(0, nOutBits): assert lcv.inputs == inputs assert lcv.outputs == outputs assert lcv.scratch == scratch compute_next_value(taus[i]) lcv.next_round(taus[i]) assert outputs == lcv.outputs assert scratch == lcv.scratch assert lcv.prevPassValue == scratch[0] assert all([lcv.prevPassValue == elm[0] for elm in lcv.outputs_fact])
def set_rvals_v(self, rvals, r0val, Avals, Zval, vxeval): self.nbits = len(rvals) if self.bitdiv == 0: self.v1bits = 0 else: self.v1bits = int(self.nbits / self.bitdiv) self.v2bits = self.nbits - self.v1bits self.rvals = rvals[self.v1bits:] self.r0val = r0val if self.v1bits == 0: Pval = Avals[0] else: mvals = VerifierIOMLExt.compute_beta(rvals[:self.v1bits], self.com.rec_q) assert len(Avals) == len(mvals) Pval = self.gops.multiexp(Avals, mvals) if self.com.rec: self.com.rec_p.did_mexp(len(mvals)) self.Pvals = [self.gops.mul(Pval, self.gops.maul(Zval, vxeval))] self.cvals = []
def run_one_test(nbits, squawk, nbins, pattern): z = [Defs.gen_random() for _ in xrange(0, nbits)] inv = [Defs.gen_random() for _ in xrange(0, (2**nbits) - nbins)] if pattern is 0: inv += [0 for _ in xrange(0, nbins)] elif pattern is 1: inv += [1 for _ in xrange(0, nbins)] elif pattern == 2: inv += [(i % 2) for i in xrange(0, nbins)] elif pattern == 3: inv += [((i + 1) % 2) for i in xrange(0, nbins)] else: inv += [random.randint(0, 1) for _ in xrange(0, nbins)] assert len(inv) == (2**nbits) Defs.track_fArith = True fa = Defs.fArith() oldrec = fa.new_cat("old") newrec = fa.new_cat("new") nw2rec = fa.new_cat("nw2") oldbeta = LayerComputeBeta(nbits, z, oldrec) oldval = sum(util.mul_vecs(oldbeta.outputs, inv)) % Defs.prime oldrec.did_mul(len(inv)) oldrec.did_add(len(inv) - 1) newcomp = VerifierIOMLExt(z, newrec) newval = newcomp.compute(inv) nw2comp = LayerComputeV(nbits, nw2rec) nw2comp.other_factors = [] nw2comp.set_inputs(inv) for zz in z: nw2comp.next_round(zz) nw2val = nw2comp.prevPassValue assert oldval == newval, "error for inputs (new) %s : %s" % (str(z), str(inv)) assert oldval == nw2val, "error for inputs (nw2) %s : %s" % (str(z), str(inv)) if squawk: print print "nbits: %d" % nbits print "OLD: %s" % str(oldrec) print "NEW: %s" % str(newrec) print "NW2: %s" % str(nw2rec) betacomp = VerifierIOMLExt.compute_beta(z) beta_lo = random.randint(0, 2**nbits - 1) beta_hi = random.randint(beta_lo, 2**nbits - 1) betacomp2 = VerifierIOMLExt.compute_beta(z, None, 1, beta_lo, beta_hi) # make sure that the right range was generated, and correctly assert len(betacomp) == len(betacomp2) assert all([b is None for b in betacomp2[:beta_lo]]) assert all([b is not None for b in betacomp2[beta_lo:beta_hi + 1]]) assert all([b is None for b in betacomp2[beta_hi + 1:]]) assert all([ b2 == b if b2 is not None else True for (b, b2) in zip(betacomp, betacomp2) ]) return newrec.get_counts()
(c * cval) % self.gops.q for cval in chain.from_iterable(izip(cinvs, self.cvals)) ] gpows = [(cprodinv * cprodinv) % self.gops.q] for cval in self.cvals: new = [] for gpow in gpows: new.extend([(gpow * cval) % self.gops.q, gpow]) gpows = new # compute bvals stopbits = util.clog2(self.stoplen) bvinit = (VerifierIOMLExt(self.rvals[stopbits:], self.com.rec_q).compute(gpows) * self.r0val) % self.gops.q bvals = VerifierIOMLExt.compute_beta(self.rvals[:stopbits], self.com.rec_q, bvinit) # now compute the check values themselves gvals = [ self.gops.pow_gi(gpows, idx, self.stoplen) for idx in xrange(0, self.stoplen) ] lhs1 = self.gops.multiexp(self.Avals + [delta], azpows + [1]) rhs1 = self.gops.multiexp(gvals + [self.gops.h], zvals + [zdelta]) prod_bz = sum(util.mul_vecs(bvals, zvals, self.com.rec_q)) % self.gops.q lhs2 = self.gops.multiexp(self.Zvals + [beta], azpows + [1]) rhs2 = self.gops.pow_gh(prod_bz, zbeta) if self.com.rec:
def run(self, pf, _=None): # pylint: disable=arguments-differ assert Defs.prime == self.com.gops.q self.fs = fs.FiatShamir.from_string(pf) assert Defs.prime == self.fs.q #### # 0. Get i/o #### self.muxbits = self.fs.take(True) self.inputs = self.fs.take(True) # get witness commitments nd_cvals = [] if self.fs.ndb is not None: num_vals = 2**(self.nInBits - self.fs.ndb) nCopies = 1 if self.rdl is None: nCopies = self.nCopies for copy in xrange(0, nCopies): (cvals, is_ok) = self.check_pok(num_vals) if not is_ok: raise ValueError( "Failed getting commitments to input for copy %d" % copy) if self.rdl is None: nd_cvals.append(cvals) else: nd_cvals.extend(cvals) # now generate rvals if self.fs.rvstart is not None and self.fs.rvend is not None: r_values = [ self.fs.rand_scalar() for _ in xrange(self.fs.rvstart, self.fs.rvend + 1) ] nCopies = 1 if self.rdl is None: nCopies = self.nCopies for idx in xrange(0, nCopies): first = idx * (2**self.nInBits) + self.fs.rvstart last = first + self.fs.rvend - self.fs.rvstart + 1 self.inputs[first:last] = r_values # finally, get outputs self.outputs = self.fs.take(True) #### # 1. mlext of outs #### nOutBits = util.clog2(len(self.in0vv[-1])) assert util.clog2(len(self.outputs)) == nOutBits + self.nCopyBits # z1 and z2 vals z1 = [self.fs.rand_scalar() for _ in xrange(0, nOutBits)] z1_2 = None z2 = [self.fs.rand_scalar() for _ in xrange(0, self.nCopyBits)] if Defs.track_fArith: self.sc_a.did_rng(nOutBits + self.nCopyBits) # instructions for P muls = None project_line = len(self.in0vv) == 1 expectNext = VerifierIOMLExt(z1 + z2, self.out_a).compute(self.outputs) prev_cval = None #### # 2. Simulate prover interactions #### for lay in xrange(0, len(self.in0vv)): nInBits = self.layInBits[lay] nOutBits = self.layOutBits[lay] w1 = [] w2 = [] w3 = [] if Defs.track_fArith: self.sc_a.did_rng(2 * nInBits + self.nCopyBits) #### # A. Sumcheck #### for rd in xrange(0, 2 * nInBits + self.nCopyBits): if rd < self.nCopyBits: nelms = 4 else: nelms = 3 (cvals, is_ok) = self.check_pok(nelms) if not is_ok: raise ValueError( "PoK failed for commits in round %d of layer %d" % (rd, lay)) ncom = self.com.zero_plus_one_eval(cvals) if prev_cval is None: is_ok = self.check_val_proof(ncom, expectNext) else: is_ok = self.check_eq_proof(prev_cval, ncom) if not is_ok: raise ValueError( "Verification failed in round %d of layer %d" % (rd, lay)) nrand = self.fs.rand_scalar() prev_cval = self.com.horner_eval(cvals, nrand) if rd < self.nCopyBits: w3.append(nrand) elif rd < self.nCopyBits + nInBits: w1.append(nrand) else: w2.append(nrand) #### # B. Extend to next layer #### if project_line: assert lay == len(self.in0vv) - 1 (cvals, c2val, c3val, is_ok) = self.check_final_prod_pok(nInBits) if not is_ok: raise ValueError( "Verification of final product PoK failed") pr_cvals = (cvals[0], c2val, c3val) else: (pr_cvals, is_ok) = self.check_prod_pok() if not is_ok: raise ValueError( "Verification of product PoK failed in layer %d" % lay) # check final val with mlext eval (mlext_evals, mlx_z2) = self.eval_mlext(lay, z1, z2, w1, w2, w3, z1_2, muls) tV_cval = self.com.tV_eval(pr_cvals, mlext_evals, mlx_z2) is_ok = self.check_eq_proof(prev_cval, tV_cval) if not is_ok: raise ValueError( "Verification of mlext eq proof failed in layer %d" % lay) project_next = lay == len(self.in0vv) - 2 if project_line: tau = self.fs.rand_scalar() muls = None prev_cval = self.com.horner_eval(cvals, tau) z1 = [(elm1 + (elm2 - elm1) * tau) % Defs.prime for (elm1, elm2) in izip(w1, w2)] z1_2 = None if Defs.track_fArith: self.nlay_a.did_sub(len(w1)) self.nlay_a.did_mul(len(w1)) self.nlay_a.did_add(len(w1)) self.sc_a.did_rng() else: muls = [self.fs.rand_scalar(), self.fs.rand_scalar()] tau = None prev_cval = self.com.muls_eval(pr_cvals, muls) z1 = w1 z1_2 = w2 if Defs.track_fArith: self.sc_a.did_rng(2) project_line = project_next z2 = w3 #### # 3. mlext of inputs #### if self.rdl is None: fin_inputs = self.inputs else: fin_inputs = [] for r_ents in self.rdl: fin_inputs.extend(self.inputs[r_ent] for r_ent in r_ents) input_mlext_eval = VerifierIOMLExt(z1 + z2, self.in_a).compute(fin_inputs) if len(nd_cvals) is 0 or self.fs.ndb is None: is_ok = self.check_val_proof(prev_cval, input_mlext_eval) elif self.rdl is None: copy_vals = VerifierIOMLExt.compute_beta(z2, self.in_a) loIdx = (2**self.nInBits) - (2**(self.nInBits - self.fs.ndb)) hiIdx = (2**self.nInBits) - 1 gate_vals = VerifierIOMLExt.compute_beta(z1, self.in_a, 1, loIdx, hiIdx) num_nd = 2**(self.nInBits - self.fs.ndb) cval_acc = self.com.accum_init(input_mlext_eval) for (cidx, vals) in enumerate(nd_cvals): copy_mul = copy_vals[cidx] assert len(vals) == num_nd for (gidx, val) in enumerate(vals, start=loIdx): exp = (copy_mul * gate_vals[gidx]) % Defs.prime cval_acc = self.com.accum_add(cval_acc, val, exp) if Defs.track_fArith: self.com_q_a.did_mul(len(vals)) fin_cval = self.com.accum_finish(cval_acc) is_ok = self.check_eq_proof(prev_cval, fin_cval) else: beta_vals = VerifierIOMLExt.compute_beta(z1 + z2, self.in_a) loIdx = (2**self.nInBits) - (2**(self.nInBits - self.fs.ndb)) perCkt = 2**self.nCktBits nd_cvals.append(self.com.gops.g) exps = [0] * len(nd_cvals) exps[-1] = input_mlext_eval for (cidx, r_ents) in enumerate(self.rdl): for (gidx, r_ent) in enumerate(r_ents): if r_ent >= loIdx: exps[r_ent - loIdx] += beta_vals[cidx * perCkt + gidx] exps[r_ent - loIdx] %= Defs.prime fin_cval = self.com.gops.multiexp(nd_cvals, exps) is_ok = self.check_eq_proof(prev_cval, fin_cval) if not is_ok: raise ValueError("Verification failed checking input mlext")