Пример #1
0
 def verify_eval(self, c, i, phi_at_i, witness):
     t = witness[-1][0] - 1
     y_vec = [ZR(i)**j for j in range(t + 1)]
     if len(witness) == 6:
         [S, T, D, mu, t_hat, iproof] = witness
         challenge = ZR.hash(pickle.dumps([self.gs, self.h, self.u, S, T]))
     else:
         [roothash, branch, S, T, D, mu, t_hat, iproof] = witness
         if not MerkleTree.verify_membership(pickle.dumps(T), branch,
                                             roothash):
             return False
         challenge = ZR.hash(
             pickle.dumps([roothash, self.gs, self.h, self.u, S]))
     ret = self.gs[0]**t_hat == self.gs[0]**phi_at_i * T**challenge
     ret &= D * self.h**mu == S**challenge * c
     if len(iproof[-1]) > 3:
         ret &= verify_batch_inner_product_one_known(D,
                                                     t_hat,
                                                     y_vec,
                                                     iproof,
                                                     crs=[self.gs, self.u])
     else:
         ret &= verify_inner_product_one_known(D,
                                               t_hat,
                                               y_vec,
                                               iproof,
                                               crs=[self.gs, self.u])
     return ret
Пример #2
0
def test_batch_inner_product_proof_one_known():
    n = 13
    a = [ZR.random() for i in range(n)]
    bs = [[ZR.random() for j in range(n)] for i in range(3 * n)]
    comm, iprods, proofs = prove_batch_inner_product_one_known(a, bs)
    assert verify_batch_inner_product_one_known(comm, iprods[2], bs[2],
                                                proofs[2])
    comm, iprods, badproofs = prove_batch_inner_product_one_known(
        a, bs, comm=G1.rand())
    assert not verify_batch_inner_product_one_known(comm, iprods[2], bs[2],
                                                    badproofs[2])
Пример #3
0
def poly_lagrange_at_x(s, j, x):
    s = sorted(s)
    assert j in s
    l1 = [x - jj for jj in s if jj != j]
    l2 = [j - jj for jj in s if jj != j]
    (num, den) = (ZR(1), ZR(1))
    for item in l1:
        num *= item
    for item in l2:
        den *= item
    return num / den
Пример #4
0
def test_inner_product_proof_one_known():
    n = 15
    a = [ZR.random() for i in range(n)]
    b = [ZR.random() for i in range(n)]
    iprod = ZR(0)
    for i in range(n):
        iprod += a[i] * b[i]
    comm, iprod, proof = prove_inner_product_one_known(a, b)
    assert verify_inner_product_one_known(comm, iprod, b, proof)
    comm, iprod, badproof = prove_inner_product_one_known(a, b, comm=G1.rand())
    assert not verify_inner_product_one_known(comm, iprod, b, badproof)
Пример #5
0
def get_all_roots_of_unity(n):
    #get smallest power of two greater than or equal to N
    N = 2**ceil(log(n, 2))
    #hardcoded value for bls12-381. modulus = 2^s * t + 1
    s = 32
    omega = ZR.root_of_unity()
    for i in range(s, ceil(log(n, 2)), -1):
        omega *= ZR.root_of_unity()
    omegas = [ZR(1), omega]
    for i in range(2, n):
        omegas.append(omegas[i - 1] * omega)
    return omegas
Пример #6
0
def gen_crs(degree_max=32, alpha=None):
    if alpha is None:
        alpha = ZR.rand()
    g1g = G1.hash(b"honeybadgerg1g")
    g2g = G2.hash(b"honeybadgerg2g")
    exp = ZR(1)
    g1s = [g1g]
    g2s = [g2g]
    for i in range(degree_max):
        exp *= alpha
        g1s.append(g1g**exp)
        g2s.append(g2g**exp)
    return [g1s, g2s]
Пример #7
0
def test_inner_product_proof():
    n = 10
    a = [ZR.random() for i in range(n)]
    b = [ZR.random() for i in range(n)]
    iprod = ZR(0)
    for i in range(n):
        iprod += a[i] * b[i]
    comm, iprod, proof = prove_inner_product(a, b)
    assert verify_inner_product(comm, iprod, proof)
    comm, iprod, proof2 = prove_inner_product(a, b, comm=comm)
    assert verify_inner_product(comm, iprod, proof2)
    comm, iprod, badproof = prove_inner_product(a, b, comm=G1.rand())
    assert not verify_inner_product(comm, iprod, badproof)
Пример #8
0
 def double_batch_create_witness(self, phis, r, n=None):
     t = len(phis[0].coeffs) - 1
     numpolys = len(phis)
     if n is None:
         n = 3 * t + 1
     numverifiers = n
     if len(self.y_vecs) < numverifiers:
         i = len(self.y_vecs)
         while i < numverifiers:
             self.y_vecs.append([ZR(i + 1)**j for j in range(t + 1)])
             i += 1
     # length t
     s_vec = [ZR.random() for _ in range(t + 1)]
     sy_prods = [ZR(0) for _ in range(numverifiers)]
     S = G1.identity()
     T_vec = [None] * numverifiers
     witnesses = [[] for _ in range(numverifiers)]
     for i in range(t + 1):
         S *= self.gs[i].pow(s_vec[i])
     for j in range(numverifiers):
         for i in range(t + 1):
             sy_prods[j] += s_vec[i] * self.y_vecs[j][i]
         T_vec[j] = self.gs[0].pow(sy_prods[j])
     rho = ZR.random()
     S *= self.h**rho
     # Fiat Shamir
     tree = MerkleTree()
     for j in range(numverifiers):
         tree.append(pickle.dumps(T_vec[j]))
     roothash = tree.get_root_hash()
     for j in range(numverifiers):
         branch = tree.get_branch(j)
         witnesses[j].append(roothash)
         witnesses[j].append(branch)
     challenge = ZR.hash(
         pickle.dumps([roothash, self.gs, self.h, self.u, S]))
     d_vecs = []
     for i in range(len(phis)):
         d_vecs.append([
             phis[i].coeffs[j] + s_vec[j] * challenge for j in range(t + 1)
         ])
     Ds = [G1.identity() for _ in range(len(phis))]
     _ = [[
         Ds[i].__imul__(self.gs[j].pow(d_vecs[i][j])) for j in range(t + 1)
     ] for i in range(len(phis))]
     mu = r + rho * challenge
     comms, t_hats, iproofs = prove_double_batch_inner_product_one_known_but_differenter(
         d_vecs, self.y_vecs, crs=[self.gs, self.u])
     for j in range(numverifiers):
         witnesses[j] += [t, S, T_vec[j], Ds, mu, t_hats[j], iproofs[j]]
     return witnesses
Пример #9
0
def gen_accumulator_tree(n):
    omegas = get_all_roots_of_unity(n)
    #tree is a list of lists, where tree[i][j] is the j'th leaf in the i'th row (bottom row is row 0)
    numlevels = ceil(log(n, 2)) + 1
    tree = [2**i * [None] for i in reversed(range(numlevels))]
    poly = polynomials_over(ZR)
    for i in range(len(omegas)):
        tree[0][bit_reverse(i,
                            numlevels - 1)] = poly([ZR(-1) * omegas[i],
                                                    ZR(1)])
    for k in range(1, numlevels):
        for i in range(len(tree[k])):
            tree[k][i] = tree[k - 1][2 * i] * tree[k - 1][2 * i + 1]
    return tree
Пример #10
0
async def test_HbACSS1Recoverer(test_router):
    t = 2
    n = 3 * t + 1
    poly = polynomials_over(ZR)
    secrets = [ZR.random() for i in range(t + 1)]
    secretpolys = [poly.random(t, secrets[i]) for i in range(t + 1)]
    crs = gen_pc_const_dl_crs(t)
    pc = PolyCommitConstDL(crs)
    commits = [pc.commit(phi) for phi in secretpolys]
    #witnesses[i][j] should give the proof for party i's share of polynomial number j
    witnesses = [[pc.create_witness(phi, i) for phi in secretpolys]
                 for i in range(1, n + 1)]
    shares = [[phi(i) for phi in secretpolys] for i in range(1, n + 1)]
    sends, recvs, _ = test_router(n)

    loop = asyncio.get_event_loop()
    players = [
        HbACSS1Recoverer(crs,
                         n,
                         t,
                         i,
                         sends[i],
                         recvs[i],
                         shares[i],
                         True,
                         commits,
                         witnesses[i],
                         pc=pc) for i in range(n)
    ]
    playertasks = [loop.create_task(player._run()) for player in players]
    for task in playertasks:
        task.add_done_callback(print_exception_callback)
    #loop.run_forever()
    await asyncio.gather(*playertasks)
Пример #11
0
def test_pc_log_batch(t):
    pc = PolyCommitLog()
    phi = polynomials_over(ZR).random(t)
    r = ZR.random()
    c = pc.commit(phi, r)
    witnesses = pc.batch_create_witness(phi, r)
    assert pc.verify_eval(c, 4, phi(4), witnesses[3])
Пример #12
0
    def recursive_verify(g_vec, b_vec, u, proofs, n, Ps, transcript):
        if n == 1:
            ret = True
            for i in range(len(proofs)):
                a, b = proofs[i][0][0], b_vec[0]
                ret &= Ps[i] == g_vec[0].pow(a) * u.pow(a * b)
            return ret
        Ls = []
        Rs = []
        branches = []
        last_roothash = None
        if n % 2 == 1:
            for i in range(len(proofs)):
                [na, roothash, branch, L, R] = proofs[i][-1]
                Ps[i] *= g_vec[-1].pow(na) * u.pow(na * b_vec[-1])
                Ls.append(L)
                Rs.append(R)
                branches.append(branch)
                if i != 0:
                    assert last_roothash == roothash
                else:
                    last_roothash = roothash
        else:
            for i in range(len(proofs)):
                [roothash, branch, L, R] = proofs[i][-1]
                Ls.append(L)
                Rs.append(R)
                branches.append(branch)
                if i != 0:
                    assert last_roothash == roothash
                else:
                    last_roothash = roothash

        for i in range(len(proofs)):
            leafi = hash_list_to_bytes(
                [hashzrlist(b_vec),
                 hashg1list([Ps[i], Ls[i], Rs[i]])])
            if not MerkleTree.verify_membership(leafi, branches[i],
                                                last_roothash):
                return False
        transcript += pickle.dumps([hashg1list(g_vec), last_roothash])
        x = ZR.hash(transcript)
        xi = x**-1
        x2 = x * x
        xi2 = xi * xi
        n_p = n // 2
        g_vec_p = []
        b_vec_p = []
        for i in range(n_p):
            g_vec_p.append(g_vec[:n_p][i].pow(xi) * g_vec[n_p:][i].pow(x))
            b_vec_p.append(b_vec[:n_p][i] * xi + b_vec[n_p:][i] * x)
        Ps_p = []
        for i in range(len(proofs)):
            Ps_p.append(Ls[i]**(x2) * Ps[i] * Rs[i]**(xi2))
        proofs_p = []
        for i in range(len(proofs)):
            proofs_p.append(proofs[i][:-1])
        return recursive_verify(g_vec_p, b_vec_p, u, proofs_p, n_p, Ps_p,
                                transcript)
Пример #13
0
def test_inner_product_interactive_proof():

    loop = asyncio.get_event_loop()
    pr_queue = asyncio.Queue(loop=loop)
    vr_queue = asyncio.Queue(loop=loop)
    prover = inner_product_prover(vr_queue, pr_queue)
    verifier = inner_product_verifier(pr_queue, vr_queue)

    n = 10
    a = [ZR.random() for i in range(n)]
    b = [ZR.random() for i in range(n)]
    iprod = ZR(0)
    for i in range(n):
        iprod += a[i] * b[i]

    (comm1, iprod1, g_vec1, h_vec1, u1, a_vec1, b_vec1, n1,
     P1) = prover.set_up_params(a, b)
    (g_vec2, h_vec2, u2, n2, P2) = verifier.set_up_params(n1, P1)
    prover_coro = prover.recursive_prove(g_vec1, h_vec1, u1, a_vec1, b_vec1,
                                         n1, P1)
    verifier_coro = verifier.recursive_verify(g_vec2, h_vec2, u2, n2, P2)
    _, ret = loop.run_until_complete(asyncio.gather(prover_coro,
                                                    verifier_coro))
    assert ret == True

    (_, _, g_vec1, h_vec1, u1, a_vec1, b_vec1, n1,
     P1) = prover.set_up_params(a, b, comm=comm1)
    (g_vec2, h_vec2, u2, n2, P2) = verifier.set_up_params(n1, P1)
    prover_coro = prover.recursive_prove(g_vec1, h_vec1, u1, a_vec1, b_vec1,
                                         n1, P1)
    verifier_coro = verifier.recursive_verify(g_vec2, h_vec2, u2, n2, P2)
    _, ret = loop.run_until_complete(asyncio.gather(prover_coro,
                                                    verifier_coro))
    assert ret == True

    (comm1, iprod1, g_vec1, h_vec1, u1, a_vec1, b_vec1, n1,
     P1) = prover.set_up_params(a, b, comm=G1.rand())
    (g_vec2, h_vec2, u2, n2, P2) = verifier.set_up_params(n1, P1)
    prover_coro = prover.recursive_prove(g_vec1, h_vec1, u1, a_vec1, b_vec1,
                                         n1, P1)
    verifier_coro = verifier.recursive_verify(g_vec2, h_vec2, u2, n2, P2)
    _, ret = loop.run_until_complete(asyncio.gather(prover_coro,
                                                    verifier_coro))
    assert ret == False
    loop.close()
def test_hbacss2_size_benchmark_batch_creation(benchmark, t):
    pc = PolyCommitLog(degree_max=t)
    pc.preprocess_prover(16)
    r = ZR.random()
    phis = []
    for _ in range(t):
        phi_curr = polynomials_over(ZR).random(t)
        phis.append(phi_curr)
    benchmark(pc.double_batch_create_witness, phis, r)
Пример #15
0
 def batch_create_witness(self, phi, r, n=None):
     t = len(phi.coeffs) - 1
     if n is None:
         n = 3 * t + 1
     if len(self.y_vecs) < n:
         i = len(self.y_vecs)
         while i < n:
             self.y_vecs.append([ZR(i + 1)**j for j in range(t + 1)])
             i += 1
     s_vec = [ZR.random() for _ in range(t + 1)]
     sy_prods = [ZR(0) for _ in range(n)]
     S = G1.identity()
     T_vec = [None] * n
     witnesses = [[] for _ in range(n)]
     for i in range(t + 1):
         S *= self.gs[i]**s_vec[i]
     for j in range(n):
         for i in range(t + 1):
             sy_prods[j] += s_vec[i] * self.y_vecs[j][i]
         T_vec[j] = self.gs[0]**sy_prods[j]
     rho = ZR.random()
     S *= self.h**rho
     # Fiat Shamir
     tree = MerkleTree()
     for j in range(n):
         tree.append(pickle.dumps(T_vec[j]))
     roothash = tree.get_root_hash()
     for j in range(n):
         branch = tree.get_branch(j)
         witnesses[j].append(roothash)
         witnesses[j].append(branch)
     challenge = ZR.hash(
         pickle.dumps([roothash, self.gs, self.h, self.u, S]))
     d_vec = [phi.coeffs[j] + s_vec[j] * challenge for j in range(t + 1)]
     D = G1.identity()
     for j in range(t + 1):
         D *= self.gs[j]**d_vec[j]
     mu = r + rho * challenge
     comm, t_hats, iproofs = prove_batch_inner_product_one_known(
         d_vec, self.y_vecs, crs=[self.gs, self.u])
     for j in range(len(witnesses)):
         witnesses[j] += [S, T_vec[j], D, mu, t_hats[j], iproofs[j]]
     return witnesses
Пример #16
0
 def recursive_proof(g_vec, h_vec, u, a_vec, b_vec, n, P, transcript):
     if n == 1:
         proof = []
         proof.append([a_vec[0], b_vec[0]])
         return proof
     proofstep = []
     if n % 2 == 1:
         na, nb = a_vec[-1] * -1, b_vec[-1] * -1
         P *= g_vec[-1]**(na) * h_vec[-1]**(nb) * u**(-na * nb)
         proofstep.append(na)
         proofstep.append(nb)
     n_p = n // 2
     cl = ZR(0)
     cr = ZR(0)
     L = G1.identity()
     R = G1.identity()
     for i in range(n_p):
         cl += a_vec[:n_p][i] * b_vec[n_p:][i]
         cr += a_vec[n_p:][i] * b_vec[:n_p][i]
         L *= g_vec[n_p:][i]**a_vec[:n_p][i] * h_vec[:n_p][i]**b_vec[n_p:][i]
         R *= g_vec[:n_p][i]**a_vec[n_p:][i] * h_vec[n_p:][i]**b_vec[:n_p][i]
     L *= u**cl
     R *= u**cr
     # Fiat Shamir L, R, state...
     #transcript += pickle.dumps([g_vec, h_vec, u, P, L, R])
     transcript += pickle.dumps(hashg1list(g_vec + h_vec + [u, P, L, R]))
     x = ZR.hash(transcript)
     xi = x**-1
     # this part must come after the challenge is generated, which must
     # come after L and R are calculated. Don't try to condense the loops
     g_vec_p, h_vec_p, a_vec_p, b_vec_p = [], [], [], []
     for i in range(n_p):
         g_vec_p.append(g_vec[:n_p][i]**xi * g_vec[n_p:][i]**x)
         h_vec_p.append(h_vec[:n_p][i]**x * h_vec[n_p:][i]**xi)
         a_vec_p.append(a_vec[:n_p][i] * x + a_vec[n_p:][i] * xi)
         b_vec_p.append(b_vec[:n_p][i] * xi + b_vec[n_p:][i] * x)
     P_p = L**(x * x) * P * R**(xi * xi)
     proof = recursive_proof(g_vec_p, h_vec_p, u, a_vec_p, b_vec_p, n_p,
                             P_p, transcript)
     proofstep.append(L)
     proofstep.append(R)
     proof.append(proofstep)
     return proof
Пример #17
0
 def batch_verify_eval(self, cs, i, phis_at_i, witness, degree=None):
     [roothash, branch, t, S, T, Ds, mu, t_hats, proof] = witness
     if degree is not None:
         t = degree
     iproof, treeparts = proof
     if not MerkleTree.verify_membership(pickle.dumps(T), branch, roothash):
         return False
     # TODO: Should include cs
     challenge = ZR.hash(
         pickle.dumps([roothash, self.gs, self.h, self.u, S]))
     y_vec = [ZR(i)**j for j in range(t + 1)]
     ret = True
     for j in range(len(Ds)):
         ret &= self.gs[0]**t_hats[
             j] == self.gs[0]**phis_at_i[j] * T**challenge
         ret &= Ds[j] * self.h**mu == S**challenge * cs[j]
     ret &= verify_double_batch_inner_product_one_known_but_differenter(
         Ds, t_hats, y_vec, iproof, treeparts, crs=[self.gs, self.u])
     return ret
Пример #18
0
    async def recursive_prove(self, g_vec, h_vec, u, a_vec, b_vec, n, P):
        if n == 1:
            await self.send_queue.put([a_vec[0], b_vec[0]])
            return

        proofStep = []
        if n % 2 == 1:
            na, nb = a_vec[-1] * -1, b_vec[-1] * -1
            P *= g_vec[-1]**(na) * h_vec[-1]**(nb) * u**(-na * nb)
            proofStep.append(na)
            proofStep.append(nb)

        n_p = n // 2
        cl = ZR(0)
        cr = ZR(0)
        L = G1.identity()
        R = G1.identity()
        for i in range(n_p):
            cl += a_vec[:n_p][i] * b_vec[n_p:][i]
            cr += a_vec[n_p:][i] * b_vec[:n_p][i]
            L *= g_vec[n_p:][i]**a_vec[:n_p][i] * h_vec[:n_p][i]**b_vec[n_p:][i]
            R *= g_vec[:n_p][i]**a_vec[n_p:][i] * h_vec[n_p:][i]**b_vec[:n_p][i]
        L *= u**cl
        R *= u**cr

        proofStep.append(L)
        proofStep.append(R)
        await self.send_queue.put(proofStep)
        x = await self.receive_queue.get()

        xi = x**-1
        g_vec_p, h_vec_p, a_vec_p, b_vec_p = [], [], [], []
        for i in range(n_p):
            g_vec_p.append(g_vec[:n_p][i]**xi * g_vec[n_p:][i]**x)
            h_vec_p.append(h_vec[:n_p][i]**x * h_vec[n_p:][i]**xi)
            a_vec_p.append(a_vec[:n_p][i] * x + a_vec[n_p:][i] * xi)
            b_vec_p.append(b_vec[:n_p][i] * xi + b_vec[n_p:][i] * x)
        P_p = L**(x * x) * P * R**(xi * xi)

        await self.recursive_prove(g_vec_p, h_vec_p, u, a_vec_p, b_vec_p, n_p,
                                   P_p)
        return
Пример #19
0
def test_pc_log(t):
    pc = PolyCommitLog()
    phi = polynomials_over(ZR).random(t)
    # ToDo: see if other polycommits return the commit randomness
    # rather than expecting it as arg
    r = ZR.random()
    c = pc.commit(phi, r)
    witness = pc.create_witness(phi, r, 3)
    assert pc.verify_eval(c, 3, phi(3), witness)
    assert not pc.verify_eval(c, 4, phi(3), witness)
    assert not pc.verify_eval(G1.rand(), 3, phi(3), witness)
Пример #20
0
def test_double_batch_pc_log_batch_prove_and_verify(t):
    pc = PolyCommitLog()
    phi1 = polynomials_over(ZR).random(t)
    phi2 = polynomials_over(ZR).random(t)
    phi3 = polynomials_over(ZR).random(t)
    r = ZR.random()
    c1 = pc.commit(phi1, r)
    c2 = pc.commit(phi2, r)
    witnesses = pc.double_batch_create_witness([phi1, phi2], r)
    assert pc.batch_verify_eval([c1,c2], 4, [phi1(4), phi2(4)], witnesses[3])
    assert not pc.batch_verify_eval([c1,c2], 3, [phi1(4), phi2(4)], witnesses[3])
    assert not pc.batch_verify_eval([c1,c2], 4, [phi1(4), phi2(4)], witnesses[2])
    assert not pc.batch_verify_eval([c1,c1], 4, [phi1(4), phi2(4)], witnesses[3])
Пример #21
0
 def create_witness(self, phi, r, i):
     t = len(phi.coeffs) - 1
     y_vec = [ZR(i)**j for j in range(t + 1)]
     s_vec = [ZR.random() for _ in range(t + 1)]
     sy_prod = ZR(0)
     S = G1.identity()
     for j in range(t + 1):
         S *= self.gs[j]**s_vec[j]
         sy_prod += s_vec[j] * y_vec[j]
     T = self.gs[0]**sy_prod
     rho = ZR.random()
     S *= self.h**rho
     # Fiat Shamir
     challenge = ZR.hash(pickle.dumps([self.gs, self.h, self.u, S, T]))
     d_vec = [phi.coeffs[j] + s_vec[j] * challenge for j in range(t + 1)]
     D = G1.identity()
     for j in range(t + 1):
         D *= self.gs[j]**d_vec[j]
     mu = r + rho * challenge
     comm, t_hat, iproof = prove_inner_product_one_known(
         d_vec, y_vec, crs=[self.gs, self.u])
     return [S, T, D, mu, t_hat, iproof]
Пример #22
0
def test_double_batch_pc_log_batch_differing_degrees(t):
    pc = PolyCommitLog()
    n = 2*t+1
    phi1 = polynomials_over(ZR).random(t)
    phi2 = polynomials_over(ZR).random(t)
    r = ZR.random()
    c1 = pc.commit(phi1, r)
    c2 = pc.commit(phi2, r)
    witnesses = pc.double_batch_create_witness([phi1, phi2], r, n=n)
    assert pc.batch_verify_eval([c1,c2], 4, [phi1(4), phi2(4)], witnesses[3])
    assert pc.batch_verify_eval([c1,c2], 4, [phi1(4), phi2(4)], witnesses[3], degree=t)
    assert not pc.batch_verify_eval([c1,c2], 4, [phi1(4), phi2(4)], witnesses[3], degree=t+1)
    assert not pc.batch_verify_eval([c1,c2], 4, [phi1(4), phi2(4)], witnesses[3], degree=t-1)
def test_hbacss2_size_benchmark_batch_verify(benchmark, t):
    pc = PolyCommitLog(degree_max=t)
    pc.preprocess_verifier(16)
    phis = []
    r = ZR.random()
    cs = []
    for _ in range(t):
        phi_curr = polynomials_over(ZR).random(t)
        phis.append(phi_curr)
        c_curr = pc.commit(phi_curr, r)
        cs.append(c_curr)
    witnesses = pc.double_batch_create_witness(phis, r)

    i = 4
    phis_at_4 = []
    for j in range(len(phis)):
        phis_at_4.append(phis[j](i))
    benchmark(pc.batch_verify_eval, cs, i, phis_at_4, witnesses[i - 1])
Пример #24
0
def gen_pc_const_dl_crs(t, alpha=None, g=None, ghat=None, ZR=ZR, G1=G1, G2=G2):
    nonetype = type(None)
    assert type(t) is int
    assert type(alpha) in (ZR, int, nonetype)
    assert type(g) in (G1, nonetype)
    assert type(ghat) in (G2, nonetype)
    if alpha is None:
        alpha = ZR.random()
    if g is None:
        g = G1.rand()
    if ghat is None:
        ghat = G2.rand()
    (gs, ghats) = ([], [])
    for i in range(t + 1):
        gs.append(g**(alpha**i))
    for i in range(2):
        ghats.append(ghat**(alpha**i))
    crs = [gs, ghats]
    return crs
Пример #25
0
 async def recursive_verify(self, g_vec, h_vec, u, n, P):
     if n == 1:
         [a, b] = await self.receive_queue.get()
         return P == g_vec[0]**a * h_vec[0]**b * u**(a * b)
     if n % 2 == 1:
         [na, nb, L, R] = await self.receive_queue.get()
         P *= g_vec[-1]**(na) * h_vec[-1]**(nb) * u**(-na * nb)
     else:
         [L, R] = await self.receive_queue.get()
     x = ZR.random()
     await self.send_queue.put(x)
     xi = x**-1
     n_p = n // 2
     g_vec_p = []
     h_vec_p = []
     for i in range(n_p):
         g_vec_p.append(g_vec[:n_p][i]**xi * g_vec[n_p:][i]**x)
         h_vec_p.append(h_vec[:n_p][i]**x * h_vec[n_p:][i]**xi)
     P_p = L**(x * x) * P * R**(xi * xi)
     ret = await self.recursive_verify(g_vec_p, h_vec_p, u, n_p, P_p)
     return ret
Пример #26
0
 def set_up_params(self, a_vec, b_vec, comm=None, crs=None):
     n = len(a_vec)
     assert len(b_vec) == n
     if crs is None:
         g_vec = G1.hash_many(b"honeybadgerg", n)
         h_vec = G1.hash_many(b"honeybadgerh", n)
         u = G1.hash(b"honeybadgeru")
     else:
         [g_vec, h_vec, u] = crs
         g_vec = g_vec[:n]
         h_vec = h_vec[:n]
     if comm is not None:
         P = comm * G1.identity()
     else:
         comm = G1.identity()
         for i in range(n):
             comm *= g_vec[i]**a_vec[i] * h_vec[i]**b_vec[i]
     iprod = ZR(0)
     for i in range(n):
         iprod += a_vec[i] * b_vec[i]
     P = comm * u**iprod
     return (comm, iprod, g_vec, h_vec, u, a_vec, b_vec, n, P)
Пример #27
0
 def recursive_verify(g_vec, b_vec, u, proof, n, P, transcript):
     if n == 1:
         a, b = proof[0][0], b_vec[0]
         return P == g_vec[0]**a * u**(a * b)
     if n % 2 == 1:
         [na, L, R] = proof[-1]
         P *= g_vec[-1]**(na) * u**(na * b_vec[-1])
     else:
         [L, R] = proof[-1]
     #transcript += pickle.dumps([g_vec, u, P, L, R])
     transcript += pickle.dumps(hashg1list(g_vec + [u, P, L, R]))
     x = ZR.hash(transcript)
     xi = x**-1
     n_p = n // 2
     g_vec_p = []
     b_vec_p = []
     for i in range(n_p):
         g_vec_p.append(g_vec[:n_p][i]**xi * g_vec[n_p:][i]**x)
         b_vec_p.append(b_vec[:n_p][i] * xi + b_vec[n_p:][i] * x)
     P_p = L**(x * x) * P * R**(xi * xi)
     return recursive_verify(g_vec_p, b_vec_p, u, proof[:-1], n_p, P_p,
                             transcript)
Пример #28
0
 def recursive_verify(g_vec, b_vec, u, proof, n, P, transcript):
     if n == 1:
         a, b = proof[0][0], b_vec[0]
         return P == g_vec[0]**a * u.pow(a * b)
     if n % 2 == 1:
         [na, roothash, branch, L, R] = proof[-1]
         P *= g_vec[-1]**(na) * u.pow(na * b_vec[-1])
     else:
         [roothash, branch, L, R] = proof[-1]
     leaf = hash_list_to_bytes([hashzrlist(b_vec), hashg1list([P, L, R])])
     if not MerkleTree.verify_membership(leaf, branch, roothash):
         return False
     transcript += pickle.dumps([hashg1list(g_vec), roothash])
     x = ZR.hash(transcript)
     xi = x**-1
     n_p = n // 2
     g_vec_p = []
     b_vec_p = []
     for i in range(n_p):
         g_vec_p.append(g_vec[:n_p][i].pow(xi) * g_vec[n_p:][i].pow(x))
         b_vec_p.append(b_vec[:n_p][i] * xi + b_vec[n_p:][i] * x)
     P_p = L**(x * x) * P * R**(xi * xi)
     return recursive_verify(g_vec_p, b_vec_p, u, proof[:-1], n_p, P_p,
                             transcript)
Пример #29
0
    def recursive_proofs(g_vec, a_vecs, b_vecs, u, n, P_vec, transcript):
        numverifiers = len(b_vecs)
        numpolys = len(a_vecs)
        numproofs = numverifiers * numpolys
        _ = [g.preprocess(5) for g in g_vec]
        if n == 1:
            treeparts = [[] for j in range(numverifiers)]
            proofs = [[[[a_vecs[i][0]]] for i in range(numpolys)]
                      for _ in range(numverifiers)]
            return [proofs, treeparts]
        proofsteps = [[[] for _ in range(numpolys)]
                      for _ in range(numverifiers)]
        nas = None
        if n % 2 == 1:
            for i in range(numpolys):
                na = a_vecs[i][-1] * -1
                gtail = g_vec[-1].pow(na)
                for j in range(numverifiers):
                    P_vec[j][i] *= gtail * u.pow(na * b_vecs[j][-1])
            #        proofsteps[j][i].append(na)
            nas = [a_vecs[i][-1] * -1 for i in range(numpolys)]
            proofsteps = [[[nas[i]] for i in range(numpolys)]
                          for j in range(numverifiers)]

        n_p = n // 2
        #cl_vec = [ [ 0 for _ in range(numpolys)] for _ in range(numverifiers)]
        #cr_vec = [ [ 0 for _ in range(numpolys)] for _ in range(numverifiers)]
        #L_vec = [ [ [] for _ in range(numpolys)] for _ in range(numverifiers)]
        #R_vec = [ [ [] for _ in range(numpolys)] for _ in range(numverifiers)]
        Las = [G1.identity() for _ in range(len(a_vecs))]
        Ras = [G1.identity() for _ in range(len(a_vecs))]
        for j in range(len(a_vecs)):
            for i in range(n_p):
                Las[j] *= g_vec[n_p:][i].pow(a_vecs[j][:n_p][i])
                Ras[j] *= g_vec[:n_p][i].pow(a_vecs[j][n_p:][i])
        #for i in range(numpolys):
        #    for j in range(numverifiers):
        #        cl_vec[j][i] = inner_product(a_vecs[i][:n_p], b_vecs[j][n_p:2*n_p])
        #        cr_vec[j][i] = inner_product(a_vecs[i][n_p:2*n_p], b_vecs[j][:n_p])
        #        L_vec[j][i] = Las[i] * (u.pow(cl_vec[j][i]))
        #        R_vec[j][i] = Ras[i] * (u.pow(cr_vec[j][i]))
        cl_vec = [[
            inner_product(a_vecs[i][:n_p], b_vecs[j][n_p:2 * n_p])
            for i in range(numpolys)
        ] for j in range(numverifiers)]
        cr_vec = [[
            inner_product(a_vecs[i][n_p:2 * n_p], b_vecs[j][:n_p])
            for i in range(numpolys)
        ] for j in range(numverifiers)]
        L_vec = [[Las[i] * (u.pow(cl_vec[j][i])) for i in range(numpolys)]
                 for j in range(numverifiers)]
        R_vec = [[Ras[i] * (u.pow(cr_vec[j][i])) for i in range(numpolys)]
                 for j in range(numverifiers)]
        # Fiat Shamir
        # Make a merkle tree over everything that varies between verifiers
        # TODO: na should be in the transcript
        tree = MerkleTree()
        if nas is None:
            zr_hashes = [hashzrlist(b_vecs[i]) for i in range(len(b_vecs))]
        else:
            zr_hashes = [
                hashzrlist(b_vecs[i] + nas) for i in range(len(b_vecs))
            ]
        g1lists = [[] for j in range(numverifiers)]
        for j in range(numverifiers):
            #smash each list of lists into a single list (list() causes the map operation to execute)
            _ = list(map(g1lists[j].extend, [P_vec[j], L_vec[j], R_vec[j]]))
        leaves = [
            pickle.dumps([zr_hashes[j], hashg1listbn(g1lists[j])])
            for j in range(numverifiers)
        ]
        tree.append_many(leaves)
        roothash = tree.get_root_hash()
        treesteps = [[roothash, tree.get_branch(j)]
                     for j in range(numverifiers)]
        transcript += pickle.dumps([hashg1list(g_vec), roothash])
        x = ZR.hash(transcript)
        xi = x**-1
        # this part must come after the challenge is generated, which must
        # come after L and R are calculated. Don't try to condense the loops
        g_vec_p, a_vecs_p = [], []
        b_vecs_p = [[] for _ in range(len(b_vecs))]
        for i in range(n_p):
            g_vec_p.append(g_vec[:n_p][i].pow(xi) * g_vec[n_p:][i].pow(x))
        for k in range(len(a_vecs)):
            a_vecs_p.append([])
            for i in range(n_p):
                a_vecs_p[k].append(a_vecs[k][:n_p][i] * x +
                                   a_vecs[k][n_p:][i] * xi)
        for j in range(len(b_vecs)):
            b_vecs_p[j] = [
                b_vecs[j][:n_p][i] * xi + b_vecs[j][n_p:][i] * x
                for i in range(n_p)
            ]
        x2, xi2 = x * x, xi * xi
        Lax2Raxi2s = [
            Las[i].pow(x2) * Ras[i].pow(xi2) for i in range(len(a_vecs))
        ]
        xil = [x2, xi2]
        # the following line is equivalent to:
        # for i in range(numpolys):
        #    for j in range(numverifiers):
        #        upow = inner_product(xil, [cl_vec[j][i], cr_vec[j][i]])
        #        P_vec[j][i] *= Lax2Raxi2s[i] * u.pow(upow)
        _ = [[
            P_vec[j][i].__imul__(
                Lax2Raxi2s[i] *
                u.pow(inner_product(xil, [cl_vec[j][i], cr_vec[j][i]])))
            for i in range(numpolys)
        ] for j in range(numverifiers)]
        proofs, treeparts = recursive_proofs(g_vec_p, a_vecs_p, b_vecs_p, u,
                                             n_p, P_vec, transcript)
        for j in range(len(proofs)):
            treeparts[j].append(treesteps[j])
            #for i in range(len(proofs[0])):
            #    proofs[j][i].append(proofsteps[j][i] + [L_vec[j][i]] + [R_vec[j][i]])
        _ = [[
            proofs[j][i].append(proofsteps[j][i] + [L_vec[j][i]] +
                                [R_vec[j][i]]) for i in range(numpolys)
        ] for j in range(numverifiers)]
        return [proofs, treeparts]
Пример #30
0
def prove_inner_product(a_vec, b_vec, comm=None, crs=None):
    def recursive_proof(g_vec, h_vec, u, a_vec, b_vec, n, P, transcript):
        if n == 1:
            proof = []
            proof.append([a_vec[0], b_vec[0]])
            return proof
        proofstep = []
        if n % 2 == 1:
            na, nb = a_vec[-1] * -1, b_vec[-1] * -1
            P *= g_vec[-1]**(na) * h_vec[-1]**(nb) * u**(-na * nb)
            proofstep.append(na)
            proofstep.append(nb)
        n_p = n // 2
        cl = ZR(0)
        cr = ZR(0)
        L = G1.identity()
        R = G1.identity()
        for i in range(n_p):
            cl += a_vec[:n_p][i] * b_vec[n_p:][i]
            cr += a_vec[n_p:][i] * b_vec[:n_p][i]
            L *= g_vec[n_p:][i]**a_vec[:n_p][i] * h_vec[:n_p][i]**b_vec[n_p:][i]
            R *= g_vec[:n_p][i]**a_vec[n_p:][i] * h_vec[n_p:][i]**b_vec[:n_p][i]
        L *= u**cl
        R *= u**cr
        # Fiat Shamir L, R, state...
        #transcript += pickle.dumps([g_vec, h_vec, u, P, L, R])
        transcript += pickle.dumps(hashg1list(g_vec + h_vec + [u, P, L, R]))
        x = ZR.hash(transcript)
        xi = x**-1
        # this part must come after the challenge is generated, which must
        # come after L and R are calculated. Don't try to condense the loops
        g_vec_p, h_vec_p, a_vec_p, b_vec_p = [], [], [], []
        for i in range(n_p):
            g_vec_p.append(g_vec[:n_p][i]**xi * g_vec[n_p:][i]**x)
            h_vec_p.append(h_vec[:n_p][i]**x * h_vec[n_p:][i]**xi)
            a_vec_p.append(a_vec[:n_p][i] * x + a_vec[n_p:][i] * xi)
            b_vec_p.append(b_vec[:n_p][i] * xi + b_vec[n_p:][i] * x)
        P_p = L**(x * x) * P * R**(xi * xi)
        proof = recursive_proof(g_vec_p, h_vec_p, u, a_vec_p, b_vec_p, n_p,
                                P_p, transcript)
        proofstep.append(L)
        proofstep.append(R)
        proof.append(proofstep)
        return proof

    n = len(a_vec)
    assert len(b_vec) == n
    if crs is None:
        g_vec = G1.hash_many(b"honeybadgerg", n)
        h_vec = G1.hash_many(b"honeybadgerh", n)
        u = G1.hash(b"honeybadgeru")
    else:
        [g_vec, h_vec, u] = crs
        g_vec = g_vec[:n]
        h_vec = h_vec[:n]
    if comm is not None:
        P = comm * G1.identity()
    else:
        comm = G1.identity()
        for i in range(n):
            comm *= g_vec[i]**a_vec[i] * h_vec[i]**b_vec[i]
    iprod = ZR(0)
    for i in range(n):
        iprod += a_vec[i] * b_vec[i]
    P = comm * u**iprod
    transcript = b""
    return [
        comm,
        iprod,
        [n] + recursive_proof(g_vec, h_vec, u, a_vec, b_vec, n, P, transcript),
    ]