def iparg_cont(self, chal): nP = self.n // 2 cInv = util.invert_modp(chal, Defs.prime) if self.gV is None: self.gV = [ self.gops.pow_gij(idx, nP + idx, cInv, chal) for idx in xrange(nP) ] h1g = ((chal * iv) % Defs.prime for iv in self.YIpows[:nP]) h2g = ((cInv * iv) % Defs.prime for iv in self.YIpows[nP:]) self.hV = [ self.gops.pow_gij(self.n + idx, self.n + nP + idx, h1g.next(), h2g.next()) for idx in xrange(nP) ] else: self.gV = [ self.gops.multiexp([self.gV[idx], self.gV[idx + nP]], [cInv, chal]) for idx in xrange(nP) ] self.hV = [ self.gops.multiexp([self.hV[idx], self.hV[idx + nP]], [chal, cInv]) for idx in xrange(nP) ] self.lEv = [(al * chal + ar * cInv) % Defs.prime for (al, ar) in izip(self.lEv[:nP], self.lEv[nP:])] self.rEv = [(bl * cInv + br * chal) % Defs.prime for (bl, br) in izip(self.rEv[:nP], self.rEv[nP:])] self.n = nP if self.n > 1: return True return False
def compute_y_z_w_vals(self, y, z, do_K): self.y = y self.yInv = util.invert_modp(y, Defs.prime) self.z = z Zpows = _compute_powers(z, z, self.Q) Ypows = _compute_powers(1, self.y, self.n) self.YIpows = _compute_powers(1, self.yInv, self.n) # compute matrix-vector products wvec = _compute_sparse_vec_mat(self.ckt.waq, Zpows) # Zpows * WL self.ZWL = [wvec.get(idx, 0) % Defs.prime for idx in xrange(self.n)] wvec = _compute_sparse_vec_mat(self.ckt.wbq, Zpows) # Zpows * WR self.yIZWR = [(yv * wvec.get(idx, 0)) % Defs.prime for (idx, yv) in enumerate(self.YIpows)] wvec = _compute_sparse_vec_mat(self.ckt.wcq, Zpows) # Zpows * WO self.ZWO = [wvec.get(idx, 0) % Defs.prime for idx in xrange(self.n)] if do_K: # compute k(y,z) + Zpows * c, where c is Kq in BCCGP notation kyzgen = sum( (rv * lv) for (lv, rv) in izip(self.ZWL, self.yIZWR)) % Defs.prime zcgen = sum( (zv * kv) for (zv, kv) in izip(Zpows, self.Kq)) % Defs.prime self.K = kyzgen + zcgen else: self.Ypows = Ypows # Prover needs this, Verifier doesn't
def redc_cont_p(self, c): assert self.rLval is not None assert self.rRval is not None assert len(self.avals) == len(self.bvals) assert self.rPval is not None assert self.gvals is None or len(self.gvals) == len(self.avals) cm1 = util.invert_modp(c, self.gops.q, self.com.rec_q) # compute new avals and bvals self.avals = self._collapse_vec(self.avals, c, cm1) self.bvals = self._collapse_vec(self.bvals, cm1, c) # compute new gvals self.gvals = self._collapse_gvec(self.gvals, cm1, c) # compute new rAval and rZval self.rPval += self.rLval * c * c + self.rRval * cm1 * cm1 self.rPval %= self.gops.q self.rLval = None self.rRval = None if self.com.rec: self.com.rec_q.did_inv() self.com.rec_q.did_mul(4) self.com.rec_q.did_add(2) return len(self.gvals) > 1
def redc_cont_p(self, c): assert self.rA1vals is not None assert self.rZ1vals is not None assert len(self.avals) == len(self.bvals) assert self.rAval is not None assert self.rZval is not None assert self.gvals is None or len(self.gvals) == len(self.avals) cm1 = util.invert_modp(c, self.gops.q, self.com.rec_q) cm2 = (cm1 * cm1) % self.gops.q # compute new avals and bvals self.avals = self._collapse_vec(self.avals, c) self.bvals = self._collapse_vec(self.bvals, cm1, cm2) # compute new gvals self.gvals = self._collapse_gvec(self.gvals, cm1, cm2) # compute new rAval and rZval self.rAval = (self.rA1vals[0] * cm1 + self.rAval + self.rA1vals[1] * c) % self.gops.q self.rZval = (self.rZ1vals[0] * c + self.rZval + self.rZ1vals[1] * cm1) % self.gops.q self.rA1vals = None self.rZ1vals = None if self.com.rec: self.com.rec_q.did_inv() self.com.rec_q.did_mul(4) self.com.rec_q.did_add(6) return len(self.gvals) > self.stoplen
def compute_x_vals(self, x): self.x = x xInv = util.invert_modp(x, Defs.prime) xn = pow(x, self.nP, Defs.prime) xnInv = pow(xInv, self.nP, Defs.prime) # powers of X for the polycommit self.Zvec_neg = _compute_powers(xnInv, xnInv, self.m1P) self.Zvec_pos = _compute_powers(x, xn, self.m2P) self.Zvec_last = ((x * x) % Defs.prime,) # powers of X for evaluating R and S self.Xpows_neg = _compute_powers(xInv, xInv, self.m) self.Xpows_pos = _compute_powers(x, x, self.m)
def compute_y_w_vals(self, y, do_K): self.y = y self.yInv = util.invert_modp(y, Defs.prime) self.Yvec = _compute_powers(y, y, self.m) YIvec = _compute_powers(self.yInv, self.yInv, self.m) self.Ypvec = _compute_powers(self.Yvec[-1], self.Yvec[-1], self.n) yM = (self.Yvec[-1] * self.Ypvec[-1] * y) % Defs.prime Yqvec = _compute_powers(yM, y, self.Q) self.wai = _compute_wia(self.ckt.waq, Yqvec, YIvec, self.n, self.m) self.wbi = _compute_wib(self.ckt.wbq, Yqvec, self.n, self.m) self.wci = _compute_wic(self.ckt.wcq, Yqvec, self.Ypvec, self.Yvec, self.n, self.m) if do_K: self.K = sum( y * k % Defs.prime for (y, k) in izip(Yqvec, self.Kq) ) % Defs.prime
self.LRvals = [] self.nbits = util.clog2(self.n) if self.n != 2**self.nbits: self.n = 2**self.nbits self.extend_yipows() def iparg_cont(self, chal, LRval): self.cvals.append(chal) self.LRvals.extend(LRval) return self.nbits != len(self.cvals) def iparg_fin(self, (a, b)): # compute inverses mod p cprod = reduce(lambda x, y: (x * y) % Defs.prime, self.cvals) cprodinv = util.invert_modp(cprod, Defs.prime) cinvs = [0] * len(self.cvals) for idx in xrange(len(self.cvals)): cvs = chain(self.cvals[:idx], self.cvals[idx + 1:]) cinvs[idx] = reduce(lambda x, y: (x * y) % Defs.prime, cvs, cprodinv) csqs = [(cval * cval) % Defs.prime for cval in self.cvals] cinvsqs = [(cval * cval) % Defs.prime for cval in cinvs] # compute powers for multiexps gpows = [cprodinv] for cval in csqs: new = [0] * 2 * len(gpows) for (idx, gpow) in enumerate(gpows): new[2 * idx] = gpow new[2 * idx + 1] = (gpow * cval) % Defs.prime
class WitnessLogCommitShort(_WCBase): # pylint: disable=super-init-not-called avals = None bvals = None cvals = None gvals = None rvals = None r0val = None rPval = None rLval = None rRval = None Pvals = None dval = None rdelta = None rbeta = None def __init__(self, com, bitdiv=0): self.com = com self.gops = com.gops if bitdiv < 2: self.bitdiv = 0 else: self.bitdiv = bitdiv 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.rPval = util.dot_product(self.svals, mvals, self.com.rec_q) else: self.avals = self.tvals[0] self.rPval = self.svals[0] self.bvals = VerifierIOMLExt.compute_beta(rvals[self.v1bits:], self.com.rec_q, r0val) self.rPval += rZval if self.com.rec: self.com.rec_q.did_add() 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 redc_init(self): assert self.rLval is None assert self.rRval is None assert len(self.avals) == len(self.bvals) nprime = len(self.avals) // 2 self.rLval = self.gops.rand_scalar() self.rRval = self.gops.rand_scalar() cL = sum( util.mul_vecs(self.avals[:nprime], self.bvals[nprime:], self.com.rec_q)) % self.gops.q cR = sum( util.mul_vecs(self.avals[nprime:], self.bvals[:nprime], self.com.rec_q)) % self.gops.q # g2^a1, g1^a2 if self.gvals is None: Lval = self.gops.maul( self.gops.pow_gih(self.avals[:nprime], self.rLval, nprime), self.gops.q - cL) Rval = self.gops.maul( self.gops.pow_gih(self.avals[nprime:], self.rRval, 0), self.gops.q - cR) else: Lval = self.gops.multiexp( self.gvals[nprime:] + [self.gops.g, self.gops.h], self.avals[:nprime] + [cL, self.rLval]) Rval = self.gops.multiexp( self.gvals[:nprime] + [self.gops.g, self.gops.h], self.avals[nprime:] + [cR, self.rRval]) if self.com.rec: self.com.rec_q.did_rng(2) self.com.rec_p.did_mexps([2 + nprime] * 2) return (Lval, Rval) def _collapse_vec(self, v, c, c2): nprime = len(v) // 2 ret = [] for (v1, v2) in izip(v[:nprime], v[nprime:]): ret.append((v1 * c + v2 * c2) % self.gops.q) assert len(ret) == nprime if self.com.rec: self.com.rec_q.did_mul(len(v)) self.com.rec_q.did_add(nprime) return ret def _collapse_gvec(self, v, c, c2): ret = [] if v is None: nprime = 2**(self.v2bits - 1) for idx in xrange(0, nprime): ret.append(self.gops.pow_gij(idx, idx + nprime, c, c2)) else: nprime = len(v) // 2 for (v1, v2) in izip(v[:nprime], v[nprime:]): ret.append(self.gops.multiexp([v1, v2], [c, c2])) assert len(ret) == nprime if self.com.rec: self.com.rec_p.did_mexps([2] * nprime) return ret def redc_cont_p(self, c): assert self.rLval is not None assert self.rRval is not None assert len(self.avals) == len(self.bvals) assert self.rPval is not None assert self.gvals is None or len(self.gvals) == len(self.avals) cm1 = util.invert_modp(c, self.gops.q, self.com.rec_q) # compute new avals and bvals self.avals = self._collapse_vec(self.avals, c, cm1) self.bvals = self._collapse_vec(self.bvals, cm1, c) # compute new gvals self.gvals = self._collapse_gvec(self.gvals, cm1, c) # compute new rAval and rZval self.rPval += self.rLval * c * c + self.rRval * cm1 * cm1 self.rPval %= self.gops.q self.rLval = None self.rRval = None if self.com.rec: self.com.rec_q.did_inv() self.com.rec_q.did_mul(4) self.com.rec_q.did_add(2) return len(self.gvals) > 1 def redc_cont_v(self, c, LRval): assert self.Pvals is not None assert self.bvals is None assert self.gvals is None # record c, Aval, and Zval self.cvals.append(c) self.Pvals.extend(LRval) return self.v2bits != len(self.cvals) def fin_init(self): assert len(self.gvals) == 1 assert len(self.bvals) == 1 assert len(self.avals) == 1 self.dval = self.gops.rand_scalar() self.rdelta = self.gops.rand_scalar() self.rbeta = self.gops.rand_scalar() # delta and beta are g'^d and g^d, respectively delta = self.gops.multiexp([self.gvals[0], self.gops.h], [self.dval, self.rdelta]) beta = self.gops.pow_gh(self.dval, self.rbeta) if self.com.rec: self.com.rec_q.did_rng(3) self.com.rec_p.did_mexps([2, 2]) return (delta, beta) def fin_finish(self, c): z1val = (c * self.avals[0] * self.bvals[0] + self.dval) % self.gops.q z2val = ((c * self.rPval + self.rbeta) * self.bvals[0] + self.rdelta) % self.gops.q if self.com.rec: self.com.rec_q.did_add(3) self.com.rec_q.did_mul(4) return (z1val, z2val) def fin_check(self, c, (delta, beta), (z1val, z2val)): # compute inverses cprod = reduce(lambda x, y: (x * y) % self.gops.q, self.cvals) cprodinv = util.invert_modp(cprod, self.gops.q, self.com.rec_q) cinvs = [0] * len(self.cvals) for idx in xrange(0, len(self.cvals)): cvs = chain(self.cvals[:idx], self.cvals[idx + 1:]) cinvs[idx] = reduce(lambda x, y: (x * y) % self.gops.q, cvs, cprodinv) csqs = [(cval * cval) % self.gops.q for cval in self.cvals] cinvsqs = [(cval * cval) % self.gops.q for cval in cinvs] # compute powers for multiexps gpows = [cprodinv] for cval in csqs: new = [0] * 2 * len(gpows) for (idx, gpow) in enumerate(gpows): new[2 * idx] = gpow new[2 * idx + 1] = (gpow * cval) % self.gops.q gpows = new # compute powers for P commitments bval = (VerifierIOMLExt(self.rvals, self.com.rec_q).compute(gpows) * self.r0val) % self.gops.q bc = (bval * c) % self.gops.q azpows = [bc] + [(bc * cval) % self.gops.q for cval in chain.from_iterable(izip(csqs, cinvsqs))] # now compute the check values themselves gval = self.gops.pow_gi(gpows, 0) lhs = self.gops.multiexp(self.Pvals + [beta, delta], azpows + [bval, 1]) rhs = self.gops.multiexp([gval, self.gops.g, self.gops.h], [z1val, (z1val * bval) % self.gops.q, z2val]) if self.com.rec: clen = len(self.cvals) self.com.rec_p.did_mexps([3, 2 + len(self.Pvals), len(gpows)]) self.com.rec_q.did_mul( len(gpows) + (clen + 1) * (clen - 1) + 4 * clen + 2) return lhs == rhs
def fin_finish(self, c): zvals = [(c * a + d) % self.gops.q for (a, d) in izip(self.avals, self.dvals)] zdelta = (c * self.rAval + self.rdelta) % self.gops.q zbeta = (c * self.rZval + self.rbeta) % self.gops.q if self.com.rec: self.com.rec_q.did_add(2 + len(self.avals)) self.com.rec_q.did_mul(2 + len(self.avals)) return (zvals, zdelta, zbeta) def fin_check(self, c, (delta, beta), (zvals, zdelta, zbeta)): # compute inverses cprod = reduce(lambda x, y: (x * y) % self.gops.q, self.cvals) cprodinv = util.invert_modp(cprod, self.gops.q, self.com.rec_q) cinvs = [] for idx in xrange(0, len(self.cvals)): cinvs.append( reduce(lambda x, y: (x * y) % self.gops.q, self.cvals[:idx] + self.cvals[idx + 1:], cprodinv)) # compute powers for multiexps azpows = [c] + [ (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: