From e25c79df338b84269c5fab4beca26e2a107e1bff Mon Sep 17 00:00:00 2001 From: Polina Chernyshova Date: Wed, 8 Feb 2023 15:39:03 +0000 Subject: [PATCH] added tests for kzg and fixed a bug #113 --- .../crypto3/zk/commitments/polynomial/kzg.hpp | 19 +- test/commitment/kzg.cpp | 192 ++++++++++++++++++ 2 files changed, 205 insertions(+), 6 deletions(-) diff --git a/include/nil/crypto3/zk/commitments/polynomial/kzg.hpp b/include/nil/crypto3/zk/commitments/polynomial/kzg.hpp index 0fc6d2812..a1fcdf5f1 100644 --- a/include/nil/crypto3/zk/commitments/polynomial/kzg.hpp +++ b/include/nil/crypto3/zk/commitments/polynomial/kzg.hpp @@ -97,12 +97,12 @@ namespace nil { alpha_scaled = alpha_scaled * params.alpha; } - return srs_type(std::move(commitment_key), verification_key); + return srs_type(commitment_key, verification_key); } static commitment_type commit(const srs_type &srs, const polynomial &f) { - assert(f.size() <= srs.commitment_key.size()); + BOOST_ASSERT(f.size() <= srs.commitment_key.size()); return algebra::multiexp(srs.commitment_key.begin(), srs.commitment_key.begin() + f.size(), f.begin(), f.end(), 1); } @@ -119,8 +119,14 @@ namespace nil { scalar_value_type eval) { const polynomial denominator_polynom = {-i, 1}; - const polynomial q = - (f - polynomial{eval}) / denominator_polynom; + + polynomial q = f; + q[0] -= eval; + auto r = q % denominator_polynom; + if (r != scalar_value_type(0)) { + throw std::runtime_error("incorrect eval or point i"); + } + q = q / denominator_polynom; return commit(srs, q); } @@ -130,7 +136,6 @@ namespace nil { commitment_type C_f, scalar_value_type i, scalar_value_type eval) { - auto A_1 = algebra::precompute_g1(p); auto A_2 = algebra::precompute_g2(srs.verification_key - i * curve_type::template g2_type<>::value_type::one()); @@ -180,7 +185,7 @@ namespace nil { static evals_type evaluate_polynomials(const batch_of_batches_of_polynomials_type &polys, const std::vector zs) { - assert(polys.size() == zs.size()); + BOOST_ASSERT(polys.size() == zs.size()); std::vector> evals; for (std::size_t i = 0; i < polys.size(); ++i) { @@ -209,6 +214,8 @@ namespace nil { 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) { diff --git a/test/commitment/kzg.cpp b/test/commitment/kzg.cpp index 451c5a5ba..7023c8231 100644 --- a/test/commitment/kzg.cpp +++ b/test/commitment/kzg.cpp @@ -110,6 +110,81 @@ BOOST_AUTO_TEST_CASE(kzg_random_test) { BOOST_CHECK(kzg_type::verify_eval(srs, proof, commit, i, eval)); } +BOOST_AUTO_TEST_CASE(kzg_false_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::kzg_commitment kzg_type; + + scalar_value_type alpha = 10; + scalar_value_type i = 2; + std::size_t n = 16; + const polynomial f = {100, 1, 2, 3}; + + auto srs = kzg_type::setup({n, alpha}); + + auto commit = kzg_type::commit(srs, f); + + auto eval = f.evaluate(i); + auto proof = kzg_type::proof_eval(srs, f, i, eval); + + BOOST_CHECK(kzg_type::verify_eval(srs, proof, commit, i, eval)); + + // wrong srs + auto ck2 = srs.commitment_key; + ck2[0] = ck2[0] * 2; + auto srs2 = kzg_type::srs_type(ck2, srs.verification_key * 2); + BOOST_CHECK(!kzg_type::verify_eval(srs2, proof, commit, i, eval)); + + // wrong commit + auto commit2 = commit * 2; + BOOST_CHECK(!kzg_type::verify_eval(srs, proof, commit2, i, eval)); + + // wrong i + auto i2 = i * 2; + BOOST_CHECK(!kzg_type::verify_eval(srs, proof, commit, i2, eval)); + + // wrong eval + auto eval2 = eval * 2; + BOOST_CHECK(!kzg_type::verify_eval(srs, proof, commit, i, eval2)); + + // wrong proof + { + // wrong srs + typename kzg_type::proof_type proof2; + bool exception = false; + try {proof2 = kzg_type::proof_eval(srs2, f, i, eval);} + catch (std::runtime_error& e) {exception = true;} + if (!exception) { + BOOST_CHECK(proof2 != proof); + BOOST_CHECK_MESSAGE(!kzg_type::verify_eval(srs, proof2, commit, i, eval), "wrong srs"); + } + + // wrong i + exception = false; + try {proof2 = kzg_type::proof_eval(srs, f, i2, eval);} + catch (std::runtime_error& e) {exception = true;} + if (!exception) { + BOOST_CHECK(proof2 != proof); + BOOST_CHECK_MESSAGE(!kzg_type::verify_eval(srs, proof2, commit, i, eval), "wrong i"); + } + + // wrong eval + exception = false; + try {proof2 = kzg_type::proof_eval(srs, f, i, eval2);} + catch (std::runtime_error& e) {exception = true;} + if (!exception) { + BOOST_CHECK(proof2 != proof); + BOOST_CHECK_MESSAGE(!kzg_type::verify_eval(srs, proof2, commit, i, eval), "wrong eval"); + } + } + auto proof2 = proof * 2; + BOOST_CHECK(!kzg_type::verify_eval(srs, proof2, commit, i, eval)); +} + BOOST_AUTO_TEST_CASE(kzg_batched_accumulate_test) { typedef algebra::curves::mnt4<298> curve_type; @@ -288,4 +363,121 @@ BOOST_AUTO_TEST_CASE(kzg_batched_random_test) { BOOST_CHECK(kzg_type::verify_eval(srs, proof, evals, cs, zs, gammas, r)); } +BOOST_AUTO_TEST_CASE(kzg_batched_false_test) { + + 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_batched_commitment kzg_type; + + scalar_value_type alpha = 7; + std::size_t n = 298; + const std::vector> fs{{ + {{1, 2, 3, 4, 5, 6, 7, 8}}, + {{11, 12, 13, 14, 15, 16, 17, 18}}, + {{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}}, + }}; + const std::vector> hs{{ + {{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 = kzg_type::evaluate_polynomials(polys, zs); + + auto srs = kzg_type::setup({n, alpha}); + + std::vector gammas = {54321, 98760, 12345}; + + auto proof = kzg_type::proof_eval(srs, polys, evals, zs, gammas); + + scalar_value_type r = 23546; + 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)); + + // wrong verification key + auto ck2 = srs.commitment_key; + ck2[0] = ck2[0] * 2; + auto srs2 = kzg_type::srs_type(ck2, srs.verification_key * 2); + BOOST_CHECK(!kzg_type::verify_eval(srs2, proof, evals, cs, zs, gammas, r)); + + // wrong evals + auto evals2 = evals; + evals2[evals.size() / 2][0] = evals2[evals.size() / 2][0] * 2; + BOOST_CHECK(!kzg_type::verify_eval(srs, proof, evals2, cs, zs, gammas, r)); + + // wrong commitments + auto cs2 = cs; + cs2[0].back() = cs2[0].back() * 2; + BOOST_CHECK(!kzg_type::verify_eval(srs, proof, evals, cs2, zs, gammas, r)); + + // wrong zs + auto zs2 = zs; + zs2[zs2.size() / 2] = zs2[zs2.size() / 2] * 2; + BOOST_CHECK(!kzg_type::verify_eval(srs, proof, evals, cs, zs2, gammas, r)); + + // wrong gammas + auto gammas2 = gammas; + gammas2[gammas2.size() / 2] = gammas2[gammas2.size() / 2] * 2; + BOOST_CHECK(!kzg_type::verify_eval(srs, proof, evals, cs, zs, gammas2, r)); + + // wrong proof + { + // wrong srs + typename kzg_type::batched_proof_type proof2; + bool exception = false; + try {proof2 = kzg_type::proof_eval(srs2, polys, evals, zs, gammas);} + catch (std::runtime_error& e) {exception = true;} + if (!exception) { + BOOST_CHECK(proof2 != proof); + BOOST_CHECK_MESSAGE(!kzg_type::verify_eval(srs, proof2, evals, cs, zs, gammas, r), "wrong srs"); + } + + // wrong evals + exception = false; + try {proof2 = kzg_type::proof_eval(srs, polys, evals2, zs, gammas);} + catch (std::runtime_error& e) {exception = true;} + if (!exception) { + BOOST_CHECK(proof2 != proof); + BOOST_CHECK_MESSAGE(!kzg_type::verify_eval(srs, proof2, evals, cs, zs, gammas, r), "wrong evals"); + } + + // wrong zs + exception = false; + try {proof2 = kzg_type::proof_eval(srs, polys, evals, zs2, gammas);} + catch (std::runtime_error& e) {exception = true;} + if (!exception) { + BOOST_CHECK(proof2 != proof); + BOOST_CHECK_MESSAGE(!kzg_type::verify_eval(srs, proof2, evals, cs, zs, gammas, r), "wrong zs"); + } + + // wrong gammas + exception = false; + try {proof2 = kzg_type::proof_eval(srs, polys, evals, zs, gammas2);} + catch (std::runtime_error& e) {exception = true;} + if (!exception) { + BOOST_CHECK(proof2 != proof); + BOOST_CHECK_MESSAGE(!kzg_type::verify_eval(srs, proof2, evals, cs, zs, gammas, r), "wrong gammas"); + } + } + auto proof2 = proof; + proof2.back() = proof2.back() * 2; + BOOST_CHECK(!kzg_type::verify_eval(srs, proof2, evals, cs, zs, gammas, r)); + + // wrong combination of all + BOOST_CHECK(!kzg_type::verify_eval(srs2, proof2, evals2, cs2, zs2, gammas2, r)); +} + BOOST_AUTO_TEST_SUITE_END() \ No newline at end of file