Ejemplo n.º 1
0
    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
Ejemplo n.º 2
0
    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
Ejemplo n.º 3
0
    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
Ejemplo n.º 4
0
    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
Ejemplo n.º 5
0
    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)
Ejemplo n.º 6
0
    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
Ejemplo n.º 7
0
        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
Ejemplo n.º 8
0
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
Ejemplo n.º 9
0
    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: