diff --git a/include/nil/crypto3/zk/commitments/polynomial/kzg.hpp b/include/nil/crypto3/zk/commitments/polynomial/kzg.hpp index b60cc7553..ef42e1b54 100644 --- a/include/nil/crypto3/zk/commitments/polynomial/kzg.hpp +++ b/include/nil/crypto3/zk/commitments/polynomial/kzg.hpp @@ -41,6 +41,9 @@ #include #include #include +#include + +#include #include @@ -52,7 +55,7 @@ namespace nil { namespace commitments { /** - * @brief The KZG Polynomial Commitment.. + * @brief The KZG Polynomial Commitment with Fiat-Shamir heuristic. * * References: * "Constant-Size Commitments to Polynomials and @@ -60,18 +63,23 @@ namespace nil { * Aniket Kate, Gregory M. Zaverucha, and Ian Goldberg, * */ - template + template struct kzg { typedef CurveType curve_type; + typedef TranscriptHashType transcript_hash_type; typedef typename curve_type::gt_type::value_type gt_value_type; using multiexp_method = typename algebra::policies::multiexp_method_BDLO12; + using field_type = typename curve_type::scalar_field_type; using scalar_value_type = typename curve_type::scalar_field_type::value_type; 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 proof_type = commitment_type; + using transcript_type = transcript::fiat_shamir_heuristic_sequential; + + using serializer = typename nil::marshalling::curve_element_serializer; struct params_type { commitment_key_type commitment_key; @@ -79,6 +87,17 @@ namespace nil { params_type(commitment_key_type ck, verification_key_type vk) : commitment_key(ck), verification_key(vk) {} }; + struct public_key_type { + scalar_value_type eval; + commitment_type commit; + public_key_type() {} + public_key_type(scalar_value_type e, commitment_type c) : eval(e), commit(c) {} + public_key_type operator=(const public_key_type &other) { + eval = other.eval; + commit = other.commit; + return *this; + } + }; }; } // namespace commitments @@ -86,7 +105,7 @@ namespace nil { template, + commitments::kzg, KZG>::value, bool>::type = true> static typename KZG::params_type setup(std::size_t max_degree, typename KZG::scalar_value_type alpha) { @@ -102,11 +121,26 @@ namespace nil { return typename KZG::params_type(commitment_key, verification_key); } + template, + KZG>::value, + bool>::type = true> + static typename KZG::transcript_type setup_transcript(const typename KZG::params_type ¶ms) { + typename KZG::transcript_type transcript = typename KZG::transcript_type(); + for (auto g1_elem : params.commitment_key) { + transcript(KZG::serializer::point_to_octets(g1_elem)); + } + transcript(KZG::serializer::point_to_octets(params.verification_key)); + + return transcript; + } template, + commitments::kzg, KZG>::value, bool>::type = true> static typename KZG::commitment_type commit(const typename KZG::params_type ¶ms, @@ -119,21 +153,21 @@ namespace nil { template, + commitments::kzg, KZG>::value, bool>::type = true> static typename KZG::proof_type proof_eval(typename KZG::params_type params, const typename math::polynomial &f, - typename KZG::scalar_value_type i, + typename KZG::scalar_value_type z, typename KZG::scalar_value_type eval) { - const typename math::polynomial denominator_polynom = {-i, 1}; + const typename math::polynomial denominator_polynom = {-z, 1}; typename math::polynomial q = f; q[0] -= eval; auto r = q % denominator_polynom; if (r != typename KZG::scalar_value_type(0)) { - throw std::runtime_error("incorrect eval or point i"); + throw std::runtime_error("incorrect eval or point z"); } q = q / denominator_polynom; @@ -143,19 +177,39 @@ namespace nil { template, + commitments::kzg, + KZG>::value, + bool>::type = true> + static std::pair + proof_eval(typename KZG::params_type params, + const typename math::polynomial &f, + typename KZG::transcript_type &transcript) { + auto commitment = commit(params, f); + transcript(KZG::serializer::point_to_octets(commitment)); + auto z = transcript.template challenge(); + auto eval = f.evaluate(z); + return {proof_eval(params, f, z, eval), {eval, commitment}}; + } + + template, KZG>::value, bool>::type = true> static bool verify_eval(typename KZG::params_type params, - typename KZG::proof_type p, - typename KZG::commitment_type C_f, - typename KZG::scalar_value_type i, - typename KZG::scalar_value_type eval) { - auto A_1 = algebra::precompute_g1(p); + typename KZG::proof_type proof, + typename KZG::public_key_type pk, + typename KZG::transcript_type &transcript) { + transcript(KZG::serializer::point_to_octets(pk.commit)); + + auto i = transcript.template challenge(); + + auto A_1 = algebra::precompute_g1(proof); auto A_2 = algebra::precompute_g2(params.verification_key - i * KZG::curve_type::template g2_type<>::value_type::one()); - auto B_1 = algebra::precompute_g1(eval * KZG::curve_type::template g1_type<>::value_type::one() - - C_f); + auto B_1 = algebra::precompute_g1(pk.eval * KZG::curve_type::template g1_type<>::value_type::one() - + pk.commit); auto B_2 = algebra::precompute_g2(KZG::curve_type::template g2_type<>::value_type::one()); typename KZG::gt_value_type gt3 = algebra::double_miller_loop(A_1, A_2, B_1, B_2); @@ -167,11 +221,6 @@ namespace nil { namespace commitments { - template - struct batched_kzg_params { - constexpr static const std::size_t batch_size = BatchSize; - }; - /** * @brief Based on the KZG Commitment. * @@ -181,12 +230,12 @@ namespace nil { * Ariel Gabizon, Zachary J. Williamson, Oana Ciobotaru, * */ - template - struct batched_kzg : public kzg { + template + struct batched_kzg : public kzg { typedef CurveType curve_type; - typedef KZGParams kzg_type; - constexpr static const std::size_t batch_size = KZGParams::batch_size; + typedef TranscriptHashType transcript_hash_type; + constexpr static const std::size_t batch_size = BatchSize; typedef typename curve_type::gt_type::value_type gt_value_type; using multiexp_method = typename algebra::policies::multiexp_method_BDLO12; @@ -194,12 +243,25 @@ 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 batch_of_batches_of_polynomials_type = std::array>, batch_size>; + using evals_type = std::array, batch_size>; + using batched_proof_type = std::array; - using basic_kzg = kzg; + using basic_kzg = kzg; using params_type = typename basic_kzg::params_type; + + struct batched_public_key_type { + std::array, batch_size> commits; + evals_type evals; + batched_public_key_type() {}; + batched_public_key_type(std::array commitments, evals_type evals) + : commits(commitments), evals(evals) {}; + batched_public_key_type operator=(const batched_public_key_type &other) { + commits = other.commits; + evals = other.evals; + return *this; + } + }; }; } // namespace commitments @@ -208,11 +270,13 @@ namespace nil { template, + commitments::batched_kzg, KZG>::value, bool>::type = true> - static typename math::polynomial accumulate(const std::vector> &polys, - const typename KZG::scalar_value_type &factor) { + static typename math::polynomial + accumulate(const std::vector> &polys, + typename KZG::scalar_value_type factor) { std::size_t num = polys.size(); if (num == 1) return polys[0]; @@ -226,21 +290,20 @@ namespace nil { template, + commitments::batched_kzg, KZG>::value, bool>::type = true> static typename KZG::evals_type evaluate_polynomials(const typename KZG::batch_of_batches_of_polynomials_type &polys, - const std::vector zs) { - - BOOST_ASSERT(polys.size() == zs.size()); + const std::array zs) { - std::vector> evals; - for (std::size_t i = 0; i < polys.size(); ++i) { + typename KZG::evals_type evals; + for (std::size_t i = 0; i < KZG::batch_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); + evals[i] = evals_at_z_i; } return evals; @@ -249,14 +312,16 @@ namespace nil { template, + commitments::batched_kzg, KZG>::value, bool>::type = true> - static std::vector commit(const typename KZG::params_type ¶ms, - const std::vector> &polys) { + static std::vector + commit(const typename KZG::params_type ¶ms, + const std::vector> &polys) { std::vector commitments; for (const auto &poly : polys) { - commitments.push_back(commit(params, poly)); + commitments.push_back(commit(params, poly)); } return commitments; } @@ -264,53 +329,68 @@ namespace nil { template, + commitments::batched_kzg, KZG>::value, bool>::type = true> - static typename KZG::batched_proof_type proof_eval(const typename KZG::params_type ¶ms, - const typename KZG::batch_of_batches_of_polynomials_type &polys, - const typename KZG::evals_type &evals, - const std::vector zs, - const std::vector gammas) { - - BOOST_ASSERT(polys.size() == evals.size()); - BOOST_ASSERT(polys.size() == gammas.size()); - std::vector proofs; - - for (std::size_t i = 0; i < polys.size(); ++i) { - auto accum = accumulate(polys[i], gammas[i]); - auto accum_eval = typename math::polynomial{evals[i]}.evaluate(gammas[i]); - typename KZG::basic_kzg::proof_type proof = proof_eval(params, accum, zs[i], accum_eval); - proofs.push_back(proof); + static std::pair + proof_eval(const typename KZG::params_type ¶ms, + const typename KZG::batch_of_batches_of_polynomials_type &polys, + typename KZG::transcript_type &transcript) { + + typename KZG::batched_proof_type proof; + typename KZG::batched_public_key_type public_key; + std::array zs; + + for (std::size_t i = 0; i < KZG::batch_size; ++i) { + auto commits = commit(params, polys[i]); + for (const auto &commit : commits) { + transcript(KZG::serializer::point_to_octets(commit)); + } + auto gamma = transcript.template challenge(); + zs[i] = transcript.template challenge(); + auto accum = accumulate(polys[i], gamma); + proof[i] = proof_eval(params, accum, zs[i], accum.evaluate(zs[i])); + public_key.commits[i] = commits; } + public_key.evals = evaluate_polynomials(polys, zs); - return proofs; + return {proof, public_key}; } template, + commitments::batched_kzg, KZG>::value, bool>::type = true> static bool verify_eval(typename KZG::params_type params, const typename KZG::batched_proof_type &proof, - const typename KZG::evals_type &evals, - const std::vector> &commits, - std::vector zs, - std::vector gammas, - typename KZG::scalar_value_type r) { + const typename KZG::batched_public_key_type &pk, + typename KZG::transcript_type &transcript) { + + std::array zs; + std::array gammas; + for (std::size_t i = 0; i < KZG::batch_size; ++i) { + for (const auto &commit : pk.commits[i]) { + transcript(KZG::serializer::point_to_octets(commit)); + } + gammas[i] = transcript.template challenge(); + zs[i] = transcript.template challenge(); + } + typename KZG::scalar_value_type r = transcript.template challenge(); auto F = KZG::curve_type::template g1_type<>::value_type::zero(); auto z_r_proofs = KZG::curve_type::template g1_type<>::value_type::zero(); auto r_proofs = KZG::curve_type::template g1_type<>::value_type::zero(); auto cur_r = KZG::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]; + for (std::size_t i = 0; i < KZG::batch_size; ++i) { + auto eval_accum = pk.evals[i].back(); + auto comm_accum = pk.commits[i].back(); + for (int j = pk.commits[i].size() - 2; j >= 0; --j) { + comm_accum = (gammas[i] * comm_accum) + pk.commits[i][j]; + eval_accum = (eval_accum * gammas[i]) + pk.evals[i][j]; } F = F + cur_r * (comm_accum - eval_accum * KZG::curve_type::template g1_type<>::value_type::one()); z_r_proofs = z_r_proofs + cur_r * zs[i] * proof[i]; @@ -328,7 +408,7 @@ namespace nil { return gt_4 == KZG::gt_value_type::one(); } - } // namespace algorithms + } // namespace algorithms } // namespace zk } // namespace crypto3 } // namespace nil diff --git a/test/commitment/kzg.cpp b/test/commitment/kzg.cpp index c300223cd..8f739c883 100644 --- a/test/commitment/kzg.cpp +++ b/test/commitment/kzg.cpp @@ -35,21 +35,21 @@ #include #include -#include -#include -#include #include #include #include #include #include #include +#include #include #include #include #include #include +#include +#include using namespace nil::crypto3; using namespace nil::crypto3::math; @@ -58,15 +58,16 @@ BOOST_AUTO_TEST_SUITE(kzg_test_suite) BOOST_AUTO_TEST_CASE(kzg_basic_test) { - typedef algebra::curves::mnt4<298> curve_type; + typedef algebra::curves::bls12<381> curve_type; typedef typename curve_type::base_field_type::value_type base_value_type; typedef typename curve_type::base_field_type base_field_type; typedef typename curve_type::scalar_field_type scalar_field_type; typedef typename curve_type::scalar_field_type::value_type scalar_value_type; - typedef zk::commitments::kzg kzg_type; + typedef hashes::sha2<256> transcript_hash_type; + typedef zk::commitments::kzg kzg_type; + typedef kzg_type::transcript_type transcript_type; scalar_value_type alpha = 10; - scalar_value_type i = 2; std::size_t n = 16; const polynomial f = {-1, 1, 2, 3}; @@ -80,47 +81,50 @@ BOOST_AUTO_TEST_CASE(kzg_basic_test) { auto commit = zk::algorithms::commit(params, f); BOOST_CHECK(3209 * curve_type::template g1_type<>::value_type::one() == commit); - auto eval = f.evaluate(i); - auto proof = zk::algorithms::proof_eval(params, f, i, eval); - BOOST_CHECK(33 * scalar_value_type::one() == eval); - BOOST_CHECK(397 * curve_type::template g1_type<>::value_type::one() == proof); + transcript_type transcript = zk::algorithms::setup_transcript(params); + auto [proof, pk] = zk::algorithms::proof_eval(params, f, transcript); - BOOST_CHECK(zk::algorithms::verify_eval(params, proof, commit, i, eval)); + transcript_type transcript_verifier = zk::algorithms::setup_transcript(params); + BOOST_CHECK(zk::algorithms::verify_eval(params, proof, pk, transcript_verifier)); } BOOST_AUTO_TEST_CASE(kzg_random_test) { - typedef algebra::curves::mnt4<298> curve_type; + typedef algebra::curves::bls12<381> curve_type; typedef typename curve_type::base_field_type::value_type base_value_type; typedef typename curve_type::base_field_type base_field_type; typedef typename curve_type::scalar_field_type scalar_field_type; typedef typename curve_type::scalar_field_type::value_type scalar_value_type; - typedef zk::commitments::kzg kzg_type; + typedef hashes::sha2<256> transcript_hash_type; + typedef zk::commitments::kzg kzg_type; + typedef kzg_type::transcript_type transcript_type; - scalar_value_type i = algebra::random_element(); scalar_value_type alpha = algebra::random_element(); std::size_t n = 298; const polynomial f = {-1, 1, 2, 3, 5, -15}; auto params = zk::algorithms::setup(n, alpha); auto commit = zk::algorithms::commit(params, f); - auto eval = f.evaluate(i); - auto proof = zk::algorithms::proof_eval(params, f, i, eval); - BOOST_CHECK(zk::algorithms::verify_eval(params, proof, commit, i, eval)); + transcript_type transcript = zk::algorithms::setup_transcript(params); + auto [proof, pk] = zk::algorithms::proof_eval(params, f, transcript); + + transcript_type transcript_verifier = zk::algorithms::setup_transcript(params); + BOOST_CHECK(zk::algorithms::verify_eval(params, proof, pk, transcript_verifier)); } BOOST_AUTO_TEST_CASE(kzg_false_test) { - typedef algebra::curves::mnt4<298> curve_type; + typedef algebra::curves::bls12<381> curve_type; typedef typename curve_type::base_field_type::value_type base_value_type; typedef typename curve_type::base_field_type base_field_type; typedef typename curve_type::scalar_field_type scalar_field_type; typedef typename curve_type::scalar_field_type::value_type scalar_value_type; - typedef zk::commitments::kzg kzg_type; + typedef hashes::sha2<256> transcript_hash_type; + typedef zk::commitments::kzg kzg_type; + typedef kzg_type::transcript_type transcript_type; scalar_value_type alpha = 10; - scalar_value_type i = 2; std::size_t n = 16; const polynomial f = {100, 1, 2, 3}; @@ -128,132 +132,68 @@ BOOST_AUTO_TEST_CASE(kzg_false_test) { auto commit = zk::algorithms::commit(params, f); - auto eval = f.evaluate(i); - auto proof = zk::algorithms::proof_eval(params, f, i, eval); + transcript_type transcript = zk::algorithms::setup_transcript(params); + auto [proof, pk] = zk::algorithms::proof_eval(params, f, transcript); - BOOST_CHECK(zk::algorithms::verify_eval(params, proof, commit, i, eval)); + transcript_type transcript_verifier = zk::algorithms::setup_transcript(params); + BOOST_CHECK(zk::algorithms::verify_eval(params, proof, pk, transcript_verifier)); + + // wrong transcript - already used + BOOST_CHECK(!zk::algorithms::verify_eval(params, proof, pk, transcript_verifier)); // wrong params auto ck2 = params.commitment_key; ck2[0] = ck2[0] * 2; auto params2 = kzg_type::params_type(ck2, params.verification_key * 2); - BOOST_CHECK(!zk::algorithms::verify_eval(params2, proof, commit, i, eval)); + transcript_type transcript_verifier_wp = zk::algorithms::setup_transcript(params2); + BOOST_CHECK(!zk::algorithms::verify_eval(params2, proof, pk, transcript_verifier_wp)); // wrong commit - auto commit2 = commit * 2; - BOOST_CHECK(!zk::algorithms::verify_eval(params, proof, commit2, i, eval)); - - // wrong i - auto i2 = i * 2; - BOOST_CHECK(!zk::algorithms::verify_eval(params, proof, commit, i2, eval)); + auto pk2 = pk; + pk2.commit = pk2.commit * 2; + transcript_type transcript_verifier_wc = zk::algorithms::setup_transcript(params); + BOOST_CHECK(!zk::algorithms::verify_eval(params, proof, pk2, transcript_verifier_wc)); // wrong eval - auto eval2 = eval * 2; - BOOST_CHECK(!zk::algorithms::verify_eval(params, proof, commit, i, eval2)); + pk2 = pk; + pk2.eval *= 2; + transcript_type transcript_verifier_we = zk::algorithms::setup_transcript(params); + BOOST_CHECK(!zk::algorithms::verify_eval(params, proof, pk2, transcript_verifier_we)); // wrong proof { // wrong params typename kzg_type::proof_type proof2; + typename kzg_type::public_key_type pk2; bool exception = false; - try {proof2 = zk::algorithms::proof_eval(params2, f, i, eval);} - catch (std::runtime_error& e) {exception = true;} - if (!exception) { - BOOST_CHECK(proof2 != proof); - BOOST_CHECK_MESSAGE(!zk::algorithms::verify_eval(params, proof2, commit, i, eval), "wrong params"); - } - - // wrong i - exception = false; - try {proof2 = zk::algorithms::proof_eval(params, f, i2, eval);} + transcript_type transcript_wp = zk::algorithms::setup_transcript(params); + try {auto [proof2, pk2] = zk::algorithms::proof_eval(params2, f, transcript_wp);} catch (std::runtime_error& e) {exception = true;} if (!exception) { BOOST_CHECK(proof2 != proof); - BOOST_CHECK_MESSAGE(!zk::algorithms::verify_eval(params, proof2, commit, i, eval), "wrong i"); + transcript_type transcript_wp_verifier = zk::algorithms::setup_transcript(params2); + BOOST_CHECK_MESSAGE(!zk::algorithms::verify_eval(params, proof2, pk, transcript_wp_verifier), "wrong params"); } - // wrong eval + // wrong transcript exception = false; - try {proof2 = zk::algorithms::proof_eval(params, f, i, eval2);} + try {auto [proof2, pk2] = zk::algorithms::proof_eval(params, f, transcript_wp);} catch (std::runtime_error& e) {exception = true;} if (!exception) { BOOST_CHECK(proof2 != proof); - BOOST_CHECK_MESSAGE(!zk::algorithms::verify_eval(params, proof2, commit, i, eval), "wrong eval"); + transcript_type transcript_wt_verifier = zk::algorithms::setup_transcript(params); + BOOST_CHECK_MESSAGE(!zk::algorithms::verify_eval(params, proof2, pk, transcript_wt_verifier), "wrong transcript"); } } auto proof2 = proof * 2; - BOOST_CHECK(!zk::algorithms::verify_eval(params, proof2, commit, i, eval)); + transcript_type transcript_wp_verifier = zk::algorithms::setup_transcript(params); + BOOST_CHECK(!zk::algorithms::verify_eval(params, proof2, pk, transcript_wp_verifier)); } BOOST_AUTO_TEST_SUITE_END() BOOST_AUTO_TEST_SUITE(batched_kzg_test_suite) -BOOST_AUTO_TEST_CASE(kzg_batched_accumulate_test) { - - typedef algebra::curves::mnt4<298> curve_type; - typedef typename curve_type::base_field_type::value_type base_value_type; - typedef typename curve_type::base_field_type base_field_type; - typedef typename curve_type::scalar_field_type scalar_field_type; - typedef typename curve_type::scalar_field_type::value_type scalar_value_type; - - typedef zk::commitments::batched_kzg_params<2> batched_kzg_params_type; - typedef zk::commitments::batched_kzg kzg_type; - - { - const std::vector> polynomials = {{ - {1, 2, 3, 4}, // 1 + 2x + 2x^2 + 3x^3 - }}; - const scalar_value_type beta = 29; - - const polynomial expect_result = {1, 2, 3, 4}; - - BOOST_CHECK(expect_result == zk::algorithms::accumulate(polynomials, beta)); - } - - { - const std::vector> polynomials = {{ - {1, 2, 3, 4}, // 1 + 2x + 2x^2 + 3x^3 - {5, 6, 7}, - {8, 9, 10, 11, 12}, - }}; - const scalar_value_type beta = 29; - - const polynomial expect_result = { - 1 + beta * 5 + beta * beta * 8, - 2 + beta * 6 + beta * beta * 9, - 3 + beta * 7 + beta * beta * 10, - 4 + beta * 0 + beta * beta * 11, - 0 + beta * 0 + beta * beta * 12 - }; - - BOOST_CHECK(expect_result == zk::algorithms::accumulate(polynomials, beta)); - } - - { - const std::vector> f_set{ - {1, 2, 3, 4, 5, 6, 7, 8}, - {11, 12, 0, 14, 15, 16, 17}, - }; - const scalar_value_type beta = 29; - - const polynomial expect{ - 1 + beta * 11, - 2 + beta * 12, - 3 + beta * 0, - 4 + beta * 14, - 5 + beta * 15, - 6 + beta * 16, - 7 + beta * 17, - 8 + beta * 0}; - - const polynomial actual = - zk::algorithms::accumulate(f_set, beta); - - BOOST_CHECK(expect == actual); - } -} - BOOST_AUTO_TEST_CASE(kzg_batched_basic_test) { typedef algebra::curves::bls12<381> curve_type; @@ -262,8 +202,9 @@ BOOST_AUTO_TEST_CASE(kzg_batched_basic_test) { typedef typename curve_type::scalar_field_type scalar_field_type; typedef typename curve_type::scalar_field_type::value_type scalar_value_type; - typedef zk::commitments::batched_kzg_params<2> batched_kzg_params_type; - typedef zk::commitments::batched_kzg kzg_type; + typedef hashes::sha2<256> transcript_hash_type; + typedef zk::commitments::batched_kzg kzg_type; + typedef typename kzg_type::transcript_type transcript_type; scalar_value_type alpha = 7; std::size_t n = 8; @@ -279,31 +220,14 @@ BOOST_AUTO_TEST_CASE(kzg_batched_basic_test) { {{91, 92, 93, 94, 95, 96, 97, 98}}, }}; typename kzg_type::batch_of_batches_of_polynomials_type polys = {fs, gs}; - - std::vector zs = {123, 456}; - auto evals = zk::algorithms::evaluate_polynomials(polys, zs); auto params = zk::algorithms::setup(n, alpha); - - std::vector gammas = {54321, 98760}; - - auto proof = zk::algorithms::proof_eval(params, 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 < 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[j]); - } - scalar_value_type r = 23546; - auto c0 = zk::algorithms::commit(params, fs); - auto c1 = zk::algorithms::commit(params, gs); - BOOST_CHECK(zk::algorithms::verify_eval(params, proof, evals, {c0, c1}, zs, gammas, r)); + transcript_type transcript = zk::algorithms::setup_transcript(params); + auto [proof, pk] = zk::algorithms::proof_eval(params, polys, transcript); + + transcript_type transcript_verification = zk::algorithms::setup_transcript(params); + BOOST_CHECK(zk::algorithms::verify_eval(params, proof, pk, transcript_verification)); } BOOST_AUTO_TEST_CASE(kzg_batched_random_test) { @@ -314,8 +238,9 @@ BOOST_AUTO_TEST_CASE(kzg_batched_random_test) { typedef typename curve_type::scalar_field_type scalar_field_type; typedef typename curve_type::scalar_field_type::value_type scalar_value_type; - typedef zk::commitments::batched_kzg_params<2> batched_kzg_params_type; - typedef zk::commitments::batched_kzg kzg_type; + typedef hashes::sha2<256> transcript_hash_type; + typedef zk::commitments::batched_kzg kzg_type; + typedef typename kzg_type::transcript_type transcript_type; std::size_t n = 298; scalar_value_type alpha = algebra::random_element(); @@ -336,40 +261,14 @@ BOOST_AUTO_TEST_CASE(kzg_batched_random_test) { {{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 = zk::algorithms::evaluate_polynomials(polys, zs); auto params = zk::algorithms::setup(n, alpha); - - std::vector gammas; - for (std::size_t i = 0; i < num_polys; ++i) { - gammas.push_back(algebra::random_element()); - } - - auto proof = zk::algorithms::proof_eval(params, polys, evals, zs, gammas); - for (std::size_t j = 0; j < proof.size(); ++j) { - scalar_value_type h0_x = scalar_value_type::zero(); - 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[j]); - } + transcript_type transcript = zk::algorithms::setup_transcript(params); + auto [proof, pk] = zk::algorithms::proof_eval(params, polys, transcript); - scalar_value_type r = algebra::random_element(); - std::vector> cs; - for (std::size_t j = 0; j < num_polys; ++j) { - cs.push_back(zk::algorithms::commit(params, polys[j])); - } - BOOST_CHECK(zk::algorithms::verify_eval(params, proof, evals, cs, zs, gammas, r)); + transcript_type transcript_verification = zk::algorithms::setup_transcript(params); + BOOST_CHECK(zk::algorithms::verify_eval(params, proof, pk, transcript_verification)); } BOOST_AUTO_TEST_CASE(kzg_batched_false_test) { @@ -380,8 +279,9 @@ BOOST_AUTO_TEST_CASE(kzg_batched_false_test) { typedef typename curve_type::scalar_field_type scalar_field_type; typedef typename curve_type::scalar_field_type::value_type scalar_value_type; - typedef zk::commitments::batched_kzg_params<2> batched_kzg_params_type; - typedef zk::commitments::batched_kzg kzg_type; + typedef hashes::sha2<256> transcript_hash_type; + typedef zk::commitments::batched_kzg kzg_type; + typedef typename kzg_type::transcript_type transcript_type; scalar_value_type alpha = 7; std::size_t n = 298; @@ -400,95 +300,92 @@ BOOST_AUTO_TEST_CASE(kzg_batched_false_test) { {{71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81}}, }}; typename kzg_type::batch_of_batches_of_polynomials_type polys = {fs, gs, hs}; - std::size_t num_polys = polys.size(); - - std::vector zs = {123, 456, 789}; - auto evals = zk::algorithms::evaluate_polynomials(polys, zs); auto params = zk::algorithms::setup(n, alpha); - - std::vector gammas = {54321, 98760, 12345}; - auto proof = zk::algorithms::proof_eval(params, polys, evals, zs, gammas); + transcript_type transcript = zk::algorithms::setup_transcript(params); + auto [proof, pk] = zk::algorithms::proof_eval(params, polys, transcript); - scalar_value_type r = 23546; - std::vector> cs; - for (std::size_t j = 0; j < num_polys; ++j) { - cs.push_back(zk::algorithms::commit(params, polys[j])); - } - BOOST_CHECK(zk::algorithms::verify_eval(params, proof, evals, cs, zs, gammas, r)); + transcript_type transcript_verification = zk::algorithms::setup_transcript(params); + BOOST_CHECK(zk::algorithms::verify_eval(params, proof, pk, transcript_verification)); - // wrong verification key + // wrong params auto ck2 = params.commitment_key; ck2[0] = ck2[0] * 2; auto params2 = kzg_type::params_type(ck2, params.verification_key * 2); - BOOST_CHECK(!zk::algorithms::verify_eval(params2, proof, evals, cs, zs, gammas, r)); + transcript_type transcript_verification_wp = zk::algorithms::setup_transcript(params); + BOOST_CHECK(!zk::algorithms::verify_eval(params2, proof, pk, transcript_verification_wp)); - // wrong evals - auto evals2 = evals; - evals2[evals.size() / 2][0] = evals2[evals.size() / 2][0] * 2; - BOOST_CHECK(!zk::algorithms::verify_eval(params, proof, evals2, cs, zs, gammas, r)); + // wrong transcript - used + BOOST_CHECK(!zk::algorithms::verify_eval(params, proof, pk, transcript_verification)); - // wrong commitments - auto cs2 = cs; - cs2[0].back() = cs2[0].back() * 2; - BOOST_CHECK(!zk::algorithms::verify_eval(params, proof, evals, cs2, zs, gammas, r)); + // wrong transcript - wrong params + transcript_type transcript_verification_wpt = zk::algorithms::setup_transcript(params2); + BOOST_CHECK(!zk::algorithms::verify_eval(params, proof, pk, transcript_verification_wpt)); - // wrong zs - auto zs2 = zs; - zs2[zs2.size() / 2] = zs2[zs2.size() / 2] * 2; - BOOST_CHECK(!zk::algorithms::verify_eval(params, proof, evals, cs, zs2, gammas, r)); + // wrong evals + auto pk_we = pk; + pk_we.evals[0].back() = pk_we.evals[0].back() * 2; + transcript_type transcript_verification_we = zk::algorithms::setup_transcript(params); + BOOST_CHECK(!zk::algorithms::verify_eval(params, proof, pk_we, transcript_verification_we)); - // wrong gammas - auto gammas2 = gammas; - gammas2[gammas2.size() / 2] = gammas2[gammas2.size() / 2] * 2; - BOOST_CHECK(!zk::algorithms::verify_eval(params, proof, evals, cs, zs, gammas2, r)); + // wrong commitments + auto pk_wc = pk; + pk_wc.commits[0].back() = pk_wc.commits[0].back() * 2; + transcript_type transcript_verification_wc = zk::algorithms::setup_transcript(params); + BOOST_CHECK(!zk::algorithms::verify_eval(params, proof, pk_wc, transcript_verification_wc)); + + // wrong pk + auto pk2 = pk; + pk2.commits[0].back() = pk2.commits[0].back() * 2; + pk2.evals[0].back() = pk2.evals[0].back() * 2; + transcript_type transcript_verification_wpk = zk::algorithms::setup_transcript(params); + BOOST_CHECK(!zk::algorithms::verify_eval(params, proof, pk2, transcript_verification_wpk)); // wrong proof { // wrong params typename kzg_type::batched_proof_type proof2; + typename kzg_type::batched_public_key_type pk2; bool exception = false; - try {proof2 = zk::algorithms::proof_eval(params2, polys, evals, zs, gammas);} - catch (std::runtime_error& e) {exception = true;} - if (!exception) { - BOOST_CHECK(proof2 != proof); - BOOST_CHECK_MESSAGE(!zk::algorithms::verify_eval(params, proof2, evals, cs, zs, gammas, r), "wrong params"); - } - - // wrong evals - exception = false; - try {proof2 = zk::algorithms::proof_eval(params, polys, evals2, zs, gammas);} + transcript_type transcript_wpp = zk::algorithms::setup_transcript(params2); + try {auto [proof2, pk2] = zk::algorithms::proof_eval(params2, polys, transcript_wpp);} catch (std::runtime_error& e) {exception = true;} if (!exception) { BOOST_CHECK(proof2 != proof); - BOOST_CHECK_MESSAGE(!zk::algorithms::verify_eval(params, proof2, evals, cs, zs, gammas, r), "wrong evals"); + transcript_type transcript_verification_wpp = zk::algorithms::setup_transcript(params); + BOOST_CHECK_MESSAGE(!zk::algorithms::verify_eval(params, proof2, pk, transcript_verification_wpp), "wrong params"); } - // wrong zs + // wrong transcript - used exception = false; - try {proof2 = zk::algorithms::proof_eval(params, polys, evals, zs2, gammas);} + try {auto [proof2, pk2] = zk::algorithms::proof_eval(params, polys, transcript_wpp);} catch (std::runtime_error& e) {exception = true;} if (!exception) { BOOST_CHECK(proof2 != proof); - BOOST_CHECK_MESSAGE(!zk::algorithms::verify_eval(params, proof2, evals, cs, zs, gammas, r), "wrong zs"); + transcript_type transcript_verification_wpt = zk::algorithms::setup_transcript(params); + BOOST_CHECK_MESSAGE(!zk::algorithms::verify_eval(params, proof2, pk, transcript_verification_wpt), "wrong transcript"); } - - // wrong gammas + + // wrong evals exception = false; - try {proof2 = zk::algorithms::proof_eval(params, polys, evals, zs, gammas2);} + transcript_type transcript_wpe = zk::algorithms::setup_transcript(params); + try {auto [proof2, pk2] = zk::algorithms::proof_eval(params, polys, transcript_wpe);} catch (std::runtime_error& e) {exception = true;} if (!exception) { BOOST_CHECK(proof2 != proof); - BOOST_CHECK_MESSAGE(!zk::algorithms::verify_eval(params, proof2, evals, cs, zs, gammas, r), "wrong gammas"); + transcript_type transcript_verification_wpe = zk::algorithms::setup_transcript(params); + BOOST_CHECK_MESSAGE(!zk::algorithms::verify_eval(params, proof2, pk, transcript_verification_wpe), "wrong evals"); } } auto proof2 = proof; proof2.back() = proof2.back() * 2; - BOOST_CHECK(!zk::algorithms::verify_eval(params, proof2, evals, cs, zs, gammas, r)); + transcript_type transcript_verification_wpr = zk::algorithms::setup_transcript(params); + BOOST_CHECK(!zk::algorithms::verify_eval(params, proof2, pk, transcript_verification_wpr)); // wrong combination of all - BOOST_CHECK(!zk::algorithms::verify_eval(params2, proof2, evals2, cs2, zs2, gammas2, r)); + transcript_type transcript_verification_2 = zk::algorithms::setup_transcript(params); + BOOST_CHECK(!zk::algorithms::verify_eval(params2, proof2, pk2, transcript_verification_2)); } BOOST_AUTO_TEST_SUITE_END() \ No newline at end of file