From 09169aaf0724e8e1644566a8137f0611a415d45a Mon Sep 17 00:00:00 2001 From: Polina Chernyshova Date: Mon, 6 Feb 2023 14:22:41 +0000 Subject: [PATCH] updated interfaces for arbitrary num of polynomial batched #113 --- .../crypto3/zk/commitments/polynomial/kzg.hpp | 108 ++++++++---------- test/commitment/kzg.cpp | 98 ++++++++-------- 2 files changed, 94 insertions(+), 112 deletions(-) diff --git a/include/nil/crypto3/zk/commitments/polynomial/kzg.hpp b/include/nil/crypto3/zk/commitments/polynomial/kzg.hpp index 15540eb29..802ad97ee 100644 --- a/include/nil/crypto3/zk/commitments/polynomial/kzg.hpp +++ b/include/nil/crypto3/zk/commitments/polynomial/kzg.hpp @@ -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; } @@ -156,24 +156,14 @@ namespace nil { using commitment_key_type = std::vector::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; + using evals_type = std::vector>; + using batch_of_batches_of_polynomials_type = std::vector>>; using kzg = kzg_commitment; using kzg_params_type = typename kzg::kzg_params_type; using srs_type = typename kzg::srs_type; - struct evals_type { - std::vector evals_at_z0; - std::vector evals_at_z1; - evals_type(const std::vector &e1, const std::vector &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 accumulate(const std::vector> &polys, const scalar_value_type &factor) { std::size_t num = polys.size(); @@ -186,78 +176,78 @@ namespace nil { return result; } - static evals_type evaluate_polynomials(const std::vector> &polys0, - const std::vector> &polys1, - scalar_value_type z0, scalar_value_type z1) { - std::vector 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 zs) { + + assert(polys.size() == zs.size()); - std::vector evals_at_z1; - for (const auto &poly : polys1) { - evals_at_z1.emplace_back(poly.evaluate(z1)); + std::vector> evals; + for (std::size_t i = 0; i < polys.size(); ++i) { + std::vector 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 commit(const srs_type &srs, const std::vector> &polys) { std::vector 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> &polys0, - const std::vector> &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{evals.evals_at_z0}.evaluate(gamma0); - typename kzg::proof_type proof0 = kzg::proof_eval(srs, accum0, z0, accum_eval0); + const std::vector zs, + const std::vector gammas) { + + std::vector proofs; - auto accum1 = accumulate(polys1, gamma1); - auto accum_eval1 = polynomial{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{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 &commits0, - const std::vector &commits1, - scalar_value_type z0, scalar_value_type z1, - scalar_value_type gamma0, scalar_value_type gamma1, + const std::vector> &commits, + std::vector zs, + std::vector 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(F + z0 * proof.commit0 + z1 * r * proof.commit1); + auto A_1 = algebra::precompute_g1(F + z_r_proofs); auto A_2 = algebra::precompute_g2(curve_type::template g2_type<>::value_type::one()); - auto B_1 = algebra::precompute_g1(-proof.commit0 - r * proof.commit1); + auto B_1 = algebra::precompute_g1(r_proofs); auto B_2 = algebra::precompute_g2(srs.verification_key); gt_value_type gt3 = algebra::double_miller_loop(A_1, A_2, B_1, B_2); diff --git a/test/commitment/kzg.cpp b/test/commitment/kzg.cpp index 8f694e982..706970e0d 100644 --- a/test/commitment/kzg.cpp +++ b/test/commitment/kzg.cpp @@ -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> 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 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 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 &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 &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 &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) { @@ -245,54 +234,57 @@ BOOST_AUTO_TEST_CASE(kzg_batched_random_test) { scalar_value_type alpha = algebra::random_element(); std::size_t n = 298; - const std::vector> fs{{ + const std::vector> 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> gs{{ + const std::vector> 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_value_type z1 = algebra::random_element(); - auto evals = kzg_type::evaluate_polynomials(fs, gs, z0, z1); + const std::vector> 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 zs; + for (std::size_t i = 0; i < num_polys; ++i) { + zs.push_back(algebra::random_element()); + } + auto evals = kzg_type::evaluate_polynomials(polys, zs); auto srs = kzg_type::setup({n, alpha}); - scalar_value_type gamma0 = algebra::random_element(); - scalar_value_type gamma1 = algebra::random_element(); + std::vector gammas; + for (std::size_t i = 0; i < num_polys; ++i) { + gammas.push_back(algebra::random_element()); + } - 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 &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 &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 &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(); - 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> 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() \ No newline at end of file