Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Polycommitlog #364

Open
wants to merge 14 commits into
base: dev
Choose a base branch
from
3 changes: 3 additions & 0 deletions .flake8
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,6 @@ exclude =
.eggs/,
apps/tutorial/
ignore = E203, E266, E501, W503
per-file-ignores =
honeybadgermpc/poly_commit_log.py: N806, N803
honeybadgermpc/proofs.py: N806, N803
29 changes: 29 additions & 0 deletions benchmark/test_benchmark_poly_commit_const.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
from pytest import mark
from honeybadgermpc.betterpairing import G1, ZR
from honeybadgermpc.polynomial import polynomials_over
from honeybadgermpc.poly_commit_const import PolyCommitConst, gen_pc_const_crs


@mark.parametrize("t", [3, 10, 20, 33])
def test_benchmark_commit(benchmark, t):
alpha = ZR.random()
g = G1.rand()
h = G1.rand()
crs = gen_pc_const_crs(t, alpha=alpha, g=g, h=h)
pc = PolyCommitConst(crs)
phi = polynomials_over(ZR).random(t)
benchmark(pc.commit, phi)


@mark.parametrize("t", [3, 10, 20, 33])
def test_benchmark_create_witness(benchmark, t):
alpha = ZR.random()
g = G1.rand()
h = G1.rand()
crs = gen_pc_const_crs(t, alpha=alpha, g=g, h=h)
pc = PolyCommitConst(crs)
phi = polynomials_over(ZR).random(t)
c, phi_hat = pc.commit(phi)
pc.preprocess_prover(10)
i = ZR.random()
benchmark(pc.create_witness, phi, phi_hat, i)
23 changes: 23 additions & 0 deletions benchmark/test_benchmark_poly_commit_lin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
from pytest import mark
from honeybadgermpc.betterpairing import G1, ZR
from honeybadgermpc.polynomial import polynomials_over
from honeybadgermpc.poly_commit_lin import PolyCommitLin


@mark.parametrize("t", [3, 10, 20, 33])
def test_benchmark_commit(benchmark, t):
g = G1.rand()
h = G1.rand()
pc = PolyCommitLin([g, h])
phi = polynomials_over(ZR).random(t)
benchmark(pc.commit, phi)


@mark.parametrize("t", [3, 10, 20, 33])
def test_benchmark_create_witness(benchmark, t):
g = G1.rand()
h = G1.rand()
pc = PolyCommitLin([g, h])
phi_hat = polynomials_over(ZR).random(t)
i = ZR.random()
benchmark(pc.create_witness, phi_hat, i)
29 changes: 29 additions & 0 deletions benchmark/test_benchmark_poly_commit_log.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
from pytest import mark
from honeybadgermpc.betterpairing import ZR
from honeybadgermpc.polynomial import polynomials_over
from honeybadgermpc.poly_commit_log import PolyCommitLog


@mark.parametrize("t", [3, 10, 20, 33])
def test_benchmark_commit(benchmark, t):
pc = PolyCommitLog(degree_max=t)
r = ZR.random()
phi = polynomials_over(ZR).random(t)
benchmark(pc.commit, phi, r)


@mark.parametrize("t", [3, 10, 20, 33])
def test_benchmark_create_witness(benchmark, t):
pc = PolyCommitLog(degree_max=t)
r = ZR.random()
phi = polynomials_over(ZR).random(t)
benchmark(pc.create_witness, phi, r, 3)


@mark.parametrize("t", [3, 10, 20, 33])
def test_benchmark_create_batch_witness(benchmark, t):
pc = PolyCommitLog(degree_max=t)
r = ZR.random()
phi = polynomials_over(ZR).random(t)
pc.preprocess_prover()
benchmark(pc.batch_create_witness, phi, r, n=3 * t + 1)
1 change: 1 addition & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ services:
- ./apps:/usr/src/HoneyBadgerMPC/apps
- ./progs:/usr/src/HoneyBadgerMPC/progs
- ./benchmark:/usr/src/HoneyBadgerMPC/benchmark
- ./.benchmarks:/usr/src/HoneyBadgerMPC/.benchmarks
- ./aws:/usr/src/HoneyBadgerMPC/aws
- ./conf:/usr/src/HoneyBadgerMPC/conf
- ./docs:/usr/src/HoneyBadgerMPC/docs
Expand Down
10 changes: 6 additions & 4 deletions honeybadgermpc/betterpairing.py
Original file line number Diff line number Diff line change
Expand Up @@ -215,12 +215,13 @@ def rand(seed=None):

# length determines how many G1 values to return
@staticmethod
def hash(bytestr, length=1):
def hash(bytestr, length=None):
assert type(bytestr) is bytes
hashout = sha256(bytestr).hexdigest()
seed = [int(hashout[i : i + 8], 16) for i in range(0, 64, 8)]
if length == 1:
if length is None:
return G1.rand(seed)
assert type(length) is int
out = [G1.rand(seed)]
for j in range(0, length - 1):
bytestr += b"x42"
Expand Down Expand Up @@ -419,12 +420,13 @@ def rand(seed=None):

# length determines how many G2 values to return
@staticmethod
def hash(bytestr, length=1):
def hash(bytestr, length=None):
assert type(bytestr) is bytes
hashout = sha256(bytestr).hexdigest()
seed = [int(hashout[i : i + 8], 16) for i in range(0, 64, 8)]
if length == 1:
if length is None:
return G2.rand(seed)
assert type(length) is int
out = [G2.rand(seed)]
for j in range(0, length - 1):
bytestr += b"x42"
Expand Down
126 changes: 126 additions & 0 deletions honeybadgermpc/poly_commit_log.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
from honeybadgermpc.betterpairing import ZR, G1
from honeybadgermpc.proofs import (
prove_inner_product_one_known,
verify_inner_product_one_known,
prove_batch_inner_product_one_known,
verify_batch_inner_product_one_known,
MerkleTree,
)
import pickle


class PolyCommitLog:
def __init__(self, crs=None, degree_max=33):
if crs is None:
n = degree_max + 1
self.gs = G1.hash(b"honeybadgerg", length=n)
self.h = G1.hash(b"honeybadgerh")
self.u = G1.hash(b"honeybadgeru")
else:
assert len(crs) == 3
[self.gs, self.h, self.u] = crs
self.y_vecs = []

def commit(self, phi, r):
c = G1.one()
for i in range(len(phi.coeffs)):
c *= self.gs[i] ** phi.coeffs[i]
c *= self.h ** r
return c

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.one()
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.one()
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]

# Create witnesses for points 1 to n. n defaults to 3*degree+1 if unset.
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.one()
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.one()
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

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

def preprocess_prover(self, level=10):
self.u.preprocess(level)
for i in range(len(self.gs) - 1):
self.y_vecs.append([ZR(i + 1) ** j for j in range(len(self.gs))])
Loading