Skip to content

Commit

Permalink
updated interfaces for arbitrary num of polynomial batched #113
Browse files Browse the repository at this point in the history
  • Loading branch information
tshchelovek committed Feb 6, 2023
1 parent 290204c commit 09169aa
Show file tree
Hide file tree
Showing 2 changed files with 94 additions and 112 deletions.
108 changes: 49 additions & 59 deletions include/nil/crypto3/zk/commitments/polynomial/kzg.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ namespace nil {
curve_type::template g2_type<>::value_type::one() * params.alpha;

for (std::size_t i = 0; i < params.n; i++) {
commitment_key.emplace_back(alpha_scaled * (curve_type::template g1_type<>::value_type::one()));
commitment_key.push_back(alpha_scaled * (curve_type::template g1_type<>::value_type::one()));
alpha_scaled = alpha_scaled * params.alpha;
}

Expand Down Expand Up @@ -156,24 +156,14 @@ namespace nil {
using commitment_key_type = std::vector<typename curve_type::template g1_type<>::value_type>;
using verification_key_type = typename curve_type::template g2_type<>::value_type;
using commitment_type = typename curve_type::template g1_type<>::value_type;
using batched_proof_type = std::vector<commitment_type>;
using evals_type = std::vector<std::vector<scalar_value_type>>;
using batch_of_batches_of_polynomials_type = std::vector<std::vector<polynomial<scalar_value_type>>>;

using kzg = kzg_commitment<CurveType>;
using kzg_params_type = typename kzg::kzg_params_type;
using srs_type = typename kzg::srs_type;

struct evals_type {
std::vector<scalar_value_type> evals_at_z0;
std::vector<scalar_value_type> evals_at_z1;
evals_type(const std::vector<scalar_value_type> &e1, const std::vector<scalar_value_type> &e2)
: evals_at_z0(e1), evals_at_z1(e2) {}
};

struct batched_proof_type {
commitment_type commit0;
commitment_type commit1;
batched_proof_type(commitment_type c0, commitment_type c1) : commit0(c0), commit1(c1) {}
};

static polynomial<scalar_value_type> accumulate(const std::vector<polynomial<scalar_value_type>> &polys,
const scalar_value_type &factor) {
std::size_t num = polys.size();
Expand All @@ -186,78 +176,78 @@ namespace nil {
return result;
}

static evals_type evaluate_polynomials(const std::vector<polynomial<scalar_value_type>> &polys0,
const std::vector<polynomial<scalar_value_type>> &polys1,
scalar_value_type z0, scalar_value_type z1) {
std::vector<scalar_value_type> evals_at_z0;
for (const auto &poly : polys0) {
evals_at_z0.emplace_back(poly.evaluate(z0));
}
static evals_type evaluate_polynomials(const batch_of_batches_of_polynomials_type &polys,
const std::vector<scalar_value_type> zs) {

assert(polys.size() == zs.size());

std::vector<scalar_value_type> evals_at_z1;
for (const auto &poly : polys1) {
evals_at_z1.emplace_back(poly.evaluate(z1));
std::vector<std::vector<scalar_value_type>> evals;
for (std::size_t i = 0; i < polys.size(); ++i) {
std::vector<scalar_value_type> evals_at_z_i;
for (const auto &poly : polys[i]) {
evals_at_z_i.push_back(poly.evaluate(zs[i]));
}
evals.push_back(evals_at_z_i);
}

return evals_type(evals_at_z0, evals_at_z1);
return evals;
}

static std::vector<commitment_type> commit(const srs_type &srs,
const std::vector<polynomial<scalar_value_type>> &polys) {
std::vector<commitment_type> commitments;
for (const auto &poly : polys) {
commitments.emplace_back(kzg::commit(srs, poly));
commitments.push_back(kzg::commit(srs, poly));
}
return commitments;
}

static batched_proof_type proof_eval(const srs_type &srs,
const std::vector<polynomial<scalar_value_type>> &polys0,
const std::vector<polynomial<scalar_value_type>> &polys1,
const batch_of_batches_of_polynomials_type &polys,
const evals_type &evals,
scalar_value_type z0, scalar_value_type z1,
scalar_value_type gamma0, scalar_value_type gamma1) {

auto accum0 = accumulate(polys0, gamma0);
auto accum_eval0 = polynomial<scalar_value_type>{evals.evals_at_z0}.evaluate(gamma0);
typename kzg::proof_type proof0 = kzg::proof_eval(srs, accum0, z0, accum_eval0);
const std::vector<scalar_value_type> zs,
const std::vector<scalar_value_type> gammas) {

std::vector<commitment_type> proofs;

auto accum1 = accumulate(polys1, gamma1);
auto accum_eval1 = polynomial<scalar_value_type>{evals.evals_at_z1}.evaluate(gamma1);
typename kzg::proof_type proof1 = kzg::proof_eval(srs, accum1, z1, accum_eval1);
for (std::size_t i = 0; i < polys.size(); ++i) {
auto accum = accumulate(polys[i], gammas[i]);
auto accum_eval = polynomial<scalar_value_type>{evals[i]}.evaluate(gammas[i]);
typename kzg::proof_type proof = kzg::proof_eval(srs, accum, zs[i], accum_eval);
proofs.push_back(proof);
}

return batched_proof_type(proof0, proof1);
return proofs;
}

static bool verify_eval(srs_type srs,
const batched_proof_type &proof,
const evals_type &evals,
const std::vector<commitment_type> &commits0,
const std::vector<commitment_type> &commits1,
scalar_value_type z0, scalar_value_type z1,
scalar_value_type gamma0, scalar_value_type gamma1,
const std::vector<std::vector<commitment_type>> &commits,
std::vector<scalar_value_type> zs,
std::vector<scalar_value_type> gammas,
scalar_value_type r) {

auto eval0_accum = evals.evals_at_z0.back();
auto comm0_accum = commits0.back();
for (int i = commits0.size() - 2; i >= 0; --i) {
comm0_accum = (gamma0 * comm0_accum) + commits0[i];
eval0_accum = (eval0_accum * gamma0) + evals.evals_at_z0[i];
auto F = curve_type::template g1_type<>::value_type::zero();
auto z_r_proofs = curve_type::template g1_type<>::value_type::zero();
auto r_proofs = curve_type::template g1_type<>::value_type::zero();
auto cur_r = scalar_value_type::one();
for (std::size_t i = 0; i < proof.size(); ++i) {
auto eval_accum = evals[i].back();
auto comm_accum = commits[i].back();
for (int j = commits[i].size() - 2; j >= 0; --j) {
comm_accum = (gammas[i] * comm_accum) + commits[i][j];
eval_accum = (eval_accum * gammas[i]) + evals[i][j];
}
F = F + cur_r * (comm_accum - eval_accum * curve_type::template g1_type<>::value_type::one());
z_r_proofs = z_r_proofs + cur_r * zs[i] * proof[i];
r_proofs = r_proofs - cur_r * proof[i];
cur_r = cur_r * r;
}

auto eval1_accum = evals.evals_at_z1.back();
auto comm1_accum = commits1.back();
for (int i = commits1.size() - 2; i >= 0; --i) {
comm1_accum = (gamma1 * comm1_accum) + commits1[i];
eval1_accum = (eval1_accum * gamma1) + evals.evals_at_z1[i];
}

auto F = (comm0_accum - eval0_accum * curve_type::template g1_type<>::value_type::one()) +
r * (comm1_accum - eval1_accum * curve_type::template g1_type<>::value_type::one());

auto A_1 = algebra::precompute_g1<curve_type>(F + z0 * proof.commit0 + z1 * r * proof.commit1);
auto A_1 = algebra::precompute_g1<curve_type>(F + z_r_proofs);
auto A_2 = algebra::precompute_g2<curve_type>(curve_type::template g2_type<>::value_type::one());
auto B_1 = algebra::precompute_g1<curve_type>(-proof.commit0 - r * proof.commit1);
auto B_1 = algebra::precompute_g1<curve_type>(r_proofs);
auto B_2 = algebra::precompute_g2<curve_type>(srs.verification_key);

gt_value_type gt3 = algebra::double_miller_loop<curve_type>(A_1, A_2, B_1, B_2);
Expand Down
98 changes: 45 additions & 53 deletions test/commitment/kzg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -190,48 +190,37 @@ BOOST_AUTO_TEST_CASE(kzg_batched_basic_test) {
{{21, 22, 23, 24, 25, 26, 27, 28}},
{{31, 32, 33, 34, 35, 36, 37, 38}},
}};

const std::vector<polynomial<scalar_value_type>> gs{{
{{71, 72, 73, 74, 75, 76, 77, 78}},
{{81, 82, 83, 84, 85, 86, 87, 88}},
{{91, 92, 93, 94, 95, 96, 97, 98}},
}};
typename kzg_type::batch_of_batches_of_polynomials_type polys = {fs, gs};

scalar_value_type z0 = 123;
scalar_value_type z1 = 456;
auto evals = kzg_type::evaluate_polynomials(fs, gs, z0, z1);
std::vector<scalar_value_type> zs = {123, 456};
auto evals = kzg_type::evaluate_polynomials(polys, zs);

auto srs = kzg_type::setup({n, alpha});

scalar_value_type gamma0 = 54321;
scalar_value_type gamma1 = 98760;
std::vector<scalar_value_type> gammas = {54321, 98760};

auto proof = kzg_type::proof_eval(srs, fs, gs, evals, z0, z1, gamma0, gamma1);
auto proof = kzg_type::proof_eval(srs, polys, evals, zs, gammas);

{
for (size_t j = 0; j < proof.size(); ++j) {
scalar_value_type h0_x = scalar_value_type::zero();
for (size_t i = 0; i < fs.size(); ++i) {
const polynomial<scalar_value_type> &f_i = fs[i];
const scalar_value_type f_x_minus_f_z0 = f_i.evaluate(alpha) - f_i.evaluate(z0);
const scalar_value_type gamma_power = gamma0.pow(i);
h0_x += gamma_power * f_x_minus_f_z0 * ((alpha - z0).inversed());
for (size_t i = 0; i < polys[j].size(); ++i) {
const polynomial<scalar_value_type> &f_i = polys[j][i];
const scalar_value_type f_x_minus_f_z0 = f_i.evaluate(alpha) - f_i.evaluate(zs[j]);
const scalar_value_type gamma_power = gammas[j].pow(i);
h0_x += gamma_power * f_x_minus_f_z0 * ((alpha - zs[j]).inversed());
}
BOOST_CHECK(h0_x * curve_type::template g1_type<>::value_type::one() == proof.commit0);

scalar_value_type h1_x = scalar_value_type::zero();
for (size_t i = 0; i < gs.size(); ++i) {
const polynomial<scalar_value_type> &g_i = gs[i];
const scalar_value_type g_x_minus_g_z1 = g_i.evaluate(alpha) - g_i.evaluate(z1);
const scalar_value_type gamma_power = gamma1.pow(i);
h1_x += gamma_power * g_x_minus_g_z1 * ((alpha - z1).inversed());
}
BOOST_CHECK(h1_x * curve_type::template g1_type<>::value_type::one() == proof.commit1);
BOOST_CHECK(h0_x * curve_type::template g1_type<>::value_type::one() == proof[j]);
}

scalar_value_type r = 23546;
auto c0 = kzg_type::commit(srs, fs);
auto c1 = kzg_type::commit(srs, gs);
BOOST_CHECK(kzg_type::verify_eval(srs, proof, evals, c0, c1, z0, z1, gamma0, gamma1, r));
BOOST_CHECK(kzg_type::verify_eval(srs, proof, evals, {c0, c1}, zs, gammas, r));
}

BOOST_AUTO_TEST_CASE(kzg_batched_random_test) {
Expand All @@ -245,54 +234,57 @@ BOOST_AUTO_TEST_CASE(kzg_batched_random_test) {

scalar_value_type alpha = algebra::random_element<scalar_field_type>();
std::size_t n = 298;
const std::vector<polynomial<scalar_value_type>> fs{{
const std::vector<polynomial<scalar_value_type>> f0{{
{{1, 2, 3, 4, 5, 6, 7, 8}},
{{11, 12, 13, 14, 15, 16, 17}},
{{21, 22, 23, 24, 25, 26, 27, 28}},
{{31, 32, 33, 34, 35, 36, 37, 38, 39}},
}};

const std::vector<polynomial<scalar_value_type>> gs{{
const std::vector<polynomial<scalar_value_type>> f1{{
{{71, 72}},
{{81, 82, 83, 85, 86, 87, 88}},
{{91, 92, 93, 94, 95, 96, 97, 98, 99, 100}},
}};

scalar_value_type z0 = algebra::random_element<scalar_field_type>();
scalar_value_type z1 = algebra::random_element<scalar_field_type>();
auto evals = kzg_type::evaluate_polynomials(fs, gs, z0, z1);
const std::vector<polynomial<scalar_value_type>> f2{{
{{73, 74, 25}},
{{87}},
{{91, 92, 93, 94, 95, 96, 97, 100, 1, 2, 3}},
}};
const kzg_type::batch_of_batches_of_polynomials_type polys = {f0, f1, f2};
std::size_t num_polys = polys.size();

std::vector<scalar_value_type> zs;
for (std::size_t i = 0; i < num_polys; ++i) {
zs.push_back(algebra::random_element<scalar_field_type>());
}
auto evals = kzg_type::evaluate_polynomials(polys, zs);

auto srs = kzg_type::setup({n, alpha});

scalar_value_type gamma0 = algebra::random_element<scalar_field_type>();
scalar_value_type gamma1 = algebra::random_element<scalar_field_type>();
std::vector<scalar_value_type> gammas;
for (std::size_t i = 0; i < num_polys; ++i) {
gammas.push_back(algebra::random_element<scalar_field_type>());
}

auto proof = kzg_type::proof_eval(srs, fs, gs, evals, z0, z1, gamma0, gamma1);
auto proof = kzg_type::proof_eval(srs, polys, evals, zs, gammas);

{
for (std::size_t j = 0; j < proof.size(); ++j) {
scalar_value_type h0_x = scalar_value_type::zero();
for (size_t i = 0; i < fs.size(); ++i) {
const polynomial<scalar_value_type> &f_i = fs[i];
const scalar_value_type f_x_minus_f_z0 = f_i.evaluate(alpha) - f_i.evaluate(z0);
const scalar_value_type gamma_power = gamma0.pow(i);
h0_x += gamma_power * f_x_minus_f_z0 * ((alpha - z0).inversed());
for (std::size_t i = 0; i < polys[j].size(); ++i) {
const polynomial<scalar_value_type> &f_i = polys[j][i];
const scalar_value_type f_x_minus_f_z0 = f_i.evaluate(alpha) - f_i.evaluate(zs[j]);
const scalar_value_type gamma_power = gammas[j].pow(i);
h0_x += gamma_power * f_x_minus_f_z0 * ((alpha - zs[j]).inversed());
}
BOOST_CHECK(h0_x * curve_type::template g1_type<>::value_type::one() == proof.commit0);

scalar_value_type h1_x = scalar_value_type::zero();
for (size_t i = 0; i < gs.size(); ++i) {
const polynomial<scalar_value_type> &g_i = gs[i];
const scalar_value_type g_x_minus_g_z1 = g_i.evaluate(alpha) - g_i.evaluate(z1);
const scalar_value_type gamma_power = gamma1.pow(i);
h1_x += gamma_power * g_x_minus_g_z1 * ((alpha - z1).inversed());
}
BOOST_CHECK(h1_x * curve_type::template g1_type<>::value_type::one() == proof.commit1);
BOOST_CHECK(h0_x * curve_type::template g1_type<>::value_type::one() == proof[j]);
}

scalar_value_type r = algebra::random_element<scalar_field_type>();
auto c0 = kzg_type::commit(srs, fs);
auto c1 = kzg_type::commit(srs, gs);
BOOST_CHECK(kzg_type::verify_eval(srs, proof, evals, c0, c1, z0, z1, gamma0, gamma1, r));
std::vector<std::vector<kzg_type::commitment_type>> cs;
for (std::size_t j = 0; j < num_polys; ++j) {
cs.push_back(kzg_type::commit(srs, polys[j]));
}
BOOST_CHECK(kzg_type::verify_eval(srs, proof, evals, cs, zs, gammas, r));
}

BOOST_AUTO_TEST_SUITE_END()

0 comments on commit 09169aa

Please sign in to comment.