Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
updated to new paper impl, pairings don't work #113
Browse files Browse the repository at this point in the history
tshchelovek authored and martun committed Aug 7, 2023
1 parent 960a2da commit 8f97217
Showing 2 changed files with 646 additions and 428 deletions.
375 changes: 252 additions & 123 deletions include/nil/crypto3/zk/commitments/polynomial/kzg.hpp
Original file line number Diff line number Diff line change
@@ -37,11 +37,13 @@
#include <boost/accumulators/accumulators.hpp>

#include <nil/crypto3/math/polynomial/polynomial.hpp>
#include <nil/crypto3/math/polynomial/lagrange_interpolation.hpp>
#include <nil/crypto3/algebra/type_traits.hpp>
#include <nil/crypto3/algebra/algorithms/pair.hpp>
#include <nil/crypto3/algebra/multiexp/multiexp.hpp>
#include <nil/crypto3/algebra/multiexp/policies.hpp>
#include <nil/crypto3/algebra/curves/detail/marshalling.hpp>
#include <nil/crypto3/algebra/marshalling.hpp>

#include <nil/crypto3/zk/transcript/fiat_shamir.hpp>

@@ -80,6 +82,26 @@ namespace nil {
struct params_type {
commitment_key_type commitment_key;
verification_key_type verification_key;
params_type() {}
params_type(std::size_t d) {
auto alpha = algebra::random_element<field_type>();
verification_key = verification_key_type::one() * alpha;
commitment_key.resize(d);
auto alpha_com = commitment_type::one();
for (std::size_t i = 0; i < d; i++) {
commitment_key[i] = alpha_com;
alpha_com = alpha * alpha_com;
}
}
params_type(std::size_t d, scalar_value_type alpha) {
verification_key = verification_key_type::one() * alpha;
commitment_key.resize(d);
auto alpha_com = commitment_type::one();
for (std::size_t i = 0; i < d; i++) {
commitment_key[i] = alpha_com;
alpha_com = alpha * alpha_com;
}
}
params_type(commitment_key_type ck, verification_key_type vk) :
commitment_key(ck), verification_key(vk) {}
};
@@ -101,25 +123,6 @@ namespace nil {
} // namespace commitments

namespace algorithms {
template<typename KZG,
typename std::enable_if<
std::is_base_of<
commitments::kzg<typename KZG::curve_type>, KZG>::value,
bool>::type = true>
static typename KZG::params_type setup(std::size_t max_degree, typename KZG::scalar_value_type alpha) {
typename KZG::scalar_value_type alpha_scaled = alpha;
typename KZG::commitment_key_type commitment_key = {KZG::curve_type::template g1_type<>::value_type::one()};
typename KZG::verification_key_type verification_key =
KZG::curve_type::template g2_type<>::value_type::one() * alpha;

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

return typename KZG::params_type(commitment_key, verification_key);
}

template<typename KZG,
typename std::enable_if<
std::is_base_of<
@@ -187,53 +190,100 @@ namespace nil {

return gt_4 == KZG::gt_value_type::one();
}
} // namespace algorithms
} // namespace algorithms

namespace commitments {

/**
* @brief Based on the KZG Commitment.
* @brief Based on the KZG Commitment from [KZG10].
*
* References:
* "PlonK: Permutations over Lagrange-bases for
* Oecumenical Noninteractive arguments of Knowledge",
* Ariel Gabizon, Zachary J. Williamson, Oana Ciobotaru,
* <https://eprint.iacr.org/2019/953.pdf>
* "Efficient polynomial commitment schemes for
* multiple points and polynomials",
* Dan Boneh, Justin Drake, Ben Fisch,
* <https://eprint.iacr.org/2020/081.pdf>
*/
template<typename CurveType, typename TranscriptHashType, std::size_t BatchSize>
struct batched_kzg : public kzg<CurveType> {
struct batched_kzg {

typedef CurveType curve_type;
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;
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<typename curve_type::template g1_type<>::value_type>;
using verification_key_type = typename curve_type::template g2_type<>::value_type;
using verification_type = typename curve_type::template g2_type<>::value_type;
using commitment_type = typename curve_type::template g1_type<>::value_type;
using batch_of_batches_of_polynomials_type = std::array<std::vector<typename math::polynomial<scalar_value_type>>, batch_size>;
using batch_of_polynomials_type = std::array<typename math::polynomial<scalar_value_type>, batch_size>;
using evals_type = std::array<std::vector<scalar_value_type>, batch_size>;
using batched_proof_type = std::array<commitment_type, batch_size>;
using proof_type = commitment_type;

using transcript_type = transcript::fiat_shamir_heuristic_sequential<TranscriptHashType>;
using serializer = typename nil::marshalling::curve_element_serializer<curve_type>;

using basic_kzg = kzg<CurveType>;
using params_type = typename basic_kzg::params_type;

struct batched_public_key_type {
std::array<std::vector<commitment_type>, batch_size> commits;
std::array<scalar_value_type, batch_size> zs;
evals_type evals;
batched_public_key_type() {};
batched_public_key_type(std::array<commitment_type, batch_size> commitments,
std::array<scalar_value_type, batch_size> zs, evals_type evals) : commits(commitments), zs(zs), evals(evals) {};
batched_public_key_type operator=(const batched_public_key_type &other) {
const static std::size_t scalar_blob_size = field_type::arity * (field_type::modulus_bits / 8 + (field_type::modulus_bits % 8 ? 1 : 0));
using bincode = typename nil::marshalling::bincode::field<field_type>;

struct params_type {
std::vector<commitment_type> commitment_key;
std::vector<verification_type> verification_key;
params_type() {};
params_type(std::size_t d, std::size_t t) {
auto alpha = algebra::random_element<typename curve_type::scalar_field_type>();
commitment_key.resize(d);
verification_key.resize(t + 1);
auto alpha_comm = commitment_type::one();
for (std::size_t i = 0; i < d; ++i) {
commitment_key[i] = alpha_comm;
alpha_comm = alpha * alpha_comm;
}
auto alpha_ver = verification_type::one();
for (std::size_t i = 0; i <= t; ++i) {
verification_key[i] = alpha_ver;
alpha_ver = alpha * alpha_ver;
}
}
params_type(std::size_t d, std::size_t t, scalar_value_type alpha) {
commitment_key.resize(d);
verification_key.resize(t + 1);
auto alpha_comm = commitment_type::one();
for (std::size_t i = 0; i < d; ++i) {
commitment_key[i] = alpha_comm;
alpha_comm = alpha * alpha_comm;
}
auto alpha_ver = verification_type::one();
for (std::size_t i = 0; i <= t; ++i) {
verification_key[i] = alpha_ver;
alpha_ver = alpha * alpha_ver;
}
}
params_type(std::vector<commitment_type> commitment_key, std::vector<verification_type> verification_key) :
commitment_key(commitment_key), verification_key(verification_key) {};
params_type operator=(const params_type &other) {
commitment_key = other.commitment_key;
verification_key = other.verification_key;
return *this;
}
};

struct public_key_type {
std::array<commitment_type, batch_size> commits;
std::vector<scalar_value_type> T;
std::array<std::vector<scalar_value_type>, batch_size> S;
std::array<math::polynomial<scalar_value_type>, batch_size> r;
public_key_type() {};
public_key_type(std::array<commitment_type, batch_size> commits,
std::vector<scalar_value_type> T,
std::array<std::vector<scalar_value_type>, batch_size> S,
std::array<math::polynomial<scalar_value_type>, batch_size> r) :
commits(commits), T(T), S(S), r(r) {};
public_key_type operator=(const public_key_type &other) {
commits = other.commits;
zs = other.zs;
evals = other.evals;
T = other.T;
S = other.S;
r = other.r;
return *this;
}
};
@@ -253,29 +303,38 @@ namespace nil {
for (auto g1_elem : params.commitment_key) {
transcript(KZG::serializer::point_to_octets(g1_elem));
}
transcript(KZG::serializer::point_to_octets(params.verification_key));
for (auto g2_elem : params.verification_key) {
transcript(KZG::serializer::point_to_octets(g2_elem));
}

return transcript;
}

template<typename KZG,
typename std::enable_if<
std::is_base_of<
commitments::batched_kzg<typename KZG::curve_type,
typename KZG::transcript_hash_type, KZG::batch_size>,
KZG>::value,
bool>::type = true>
static typename math::polynomial<typename KZG::scalar_value_type>
accumulate(const std::vector<typename math::polynomial<typename KZG::scalar_value_type>> &polys,
typename KZG::scalar_value_type factor) {
std::size_t num = polys.size();
if (num == 1) return polys[0];

typename math::polynomial<typename KZG::scalar_value_type> result = polys[num - 1];
for (int i = num - 2; i >= 0; --i) {
result = result * factor + polys[i];
static void update_transcript(const typename KZG::public_key_type &public_key,
typename KZG::transcript_type &transcript) {
std::vector<std::uint8_t> byteblob(KZG::scalar_blob_size);

for (const auto commit : public_key.commits) {
transcript(KZG::serializer::point_to_octets(commit));
}
for (const auto S : public_key.S) {
for (const auto s : S) {
KZG::bincode::template field_element_to_bytes<std::vector<std::uint8_t>::iterator>(s, byteblob.begin(), byteblob.end());
transcript(byteblob);
}
}
for (const auto r : public_key.r) {
for (std::size_t i = 0; i < r.size(); ++i) {
KZG::bincode::template field_element_to_bytes<std::vector<std::uint8_t>::iterator>(r[i], byteblob.begin(), byteblob.end());
transcript(byteblob);
}
}
return result;
}

template<typename KZG,
@@ -285,19 +344,32 @@ namespace nil {
typename KZG::transcript_hash_type, KZG::batch_size>,
KZG>::value,
bool>::type = true>
static typename KZG::evals_type evaluate_polynomials(const typename KZG::batch_of_batches_of_polynomials_type &polys,
const std::array<typename KZG::scalar_value_type, KZG::batch_size> zs) {

typename KZG::evals_type evals;
static typename std::array<math::polynomial<typename KZG::scalar_value_type>, KZG::batch_size>
create_evals_polys(const typename KZG::batch_of_polynomials_type &polys,
const std::array<std::vector<typename KZG::scalar_value_type>, KZG::batch_size> S) {
std::array<math::polynomial<typename KZG::scalar_value_type>, KZG::batch_size> rs;
for (std::size_t i = 0; i < KZG::batch_size; ++i) {
std::vector<typename KZG::scalar_value_type> evals_at_z_i;
for (const auto &poly : polys[i]) {
evals_at_z_i.push_back(poly.evaluate(zs[i]));
typename std::vector<std::pair<typename KZG::scalar_value_type, typename KZG::scalar_value_type>> evals;
for (auto s : S[i]) {
evals.push_back(std::make_pair(s, polys[i].evaluate(s)));
}
evals[i] = evals_at_z_i;
rs[i] = math::lagrange_interpolation(evals);
}
return rs;
}

return evals;
template<typename KZG,
typename std::enable_if<
std::is_base_of<
commitments::batched_kzg<typename KZG::curve_type,
typename KZG::transcript_hash_type, KZG::batch_size>,
KZG>::value,
bool>::type = true>
static typename KZG::commitment_type commit(const typename KZG::params_type &params,
const typename math::polynomial<typename KZG::scalar_value_type> &poly) {
BOOST_ASSERT(poly.size() <= params.commitment_key.size());
return algebra::multiexp<typename KZG::multiexp_method>(params.commitment_key.begin(),
params.commitment_key.begin() + poly.size(), poly.begin(), poly.end(), 1);
}

template<typename KZG,
@@ -307,35 +379,83 @@ namespace nil {
typename KZG::transcript_hash_type, KZG::batch_size>,
KZG>::value,
bool>::type = true>
static std::vector<typename KZG::commitment_type>
static std::array<typename KZG::commitment_type, KZG::batch_size>
commit(const typename KZG::params_type &params,
const std::vector<typename math::polynomial<typename KZG::scalar_value_type>> &polys) {
std::vector<typename KZG::commitment_type> commitments;
for (const auto &poly : polys) {
commitments.push_back(commit<KZG>(params, poly));
const std::array<typename math::polynomial<typename KZG::scalar_value_type>, KZG::batch_size> &polys) {
std::array<typename KZG::commitment_type, KZG::batch_size> commitments;
for (std::size_t i = 0; i < KZG::batch_size; ++i) {
BOOST_ASSERT(polys[i].size() <= params.commitment_key.size());
commitments[i] = commit<KZG>(params, polys[i]);
}
return commitments;
}


template<typename KZG,
typename std::enable_if<
std::is_base_of<
commitments::batched_kzg<typename KZG::curve_type,
typename KZG::transcript_hash_type, KZG::batch_size>,
KZG>::value,
bool>::type = true>
static typename KZG::verification_type commit_g2(const typename KZG::params_type &params,
typename math::polynomial<typename KZG::scalar_value_type> poly) {
BOOST_ASSERT(poly.size() <= params.verification_key.size());
auto result = algebra::multiexp<typename KZG::multiexp_method>(params.verification_key.begin(),
params.verification_key.begin() + poly.size(), poly.begin(), poly.end(), 1);
return result;
}

template<typename KZG,
typename std::enable_if<
std::is_base_of<
commitments::batched_kzg<typename KZG::curve_type,
typename KZG::transcript_hash_type, KZG::batch_size>,
KZG>::value,
bool>::type = true>
static typename KZG::batched_public_key_type setup_public_key(const typename KZG::params_type &params,
const typename KZG::batch_of_batches_of_polynomials_type &polys,
const std::array<typename KZG::scalar_value_type, KZG::batch_size> zs) {
typename KZG::batched_public_key_type pk;
std::array<typename KZG::evals_type, KZG::batch_size> evals;
for (int i = 0; i < KZG::batch_size; ++i) {
pk.commits[i] = commit<KZG>(params, polys[i]);
static typename math::polynomial<typename KZG::scalar_value_type>
create_polynom_by_zeros(const std::vector<typename KZG::scalar_value_type> S) {
assert(S.size() > 0);
typename math::polynomial<typename KZG::scalar_value_type> Z = {-S[0], 1};
for (std::size_t i = 1; i < S.size(); ++i) {
Z = Z * typename math::polynomial<typename KZG::scalar_value_type>({-S[i], 1});
}
return Z;
}

template<typename KZG,
typename std::enable_if<
std::is_base_of<
commitments::batched_kzg<typename KZG::curve_type,
typename KZG::transcript_hash_type, KZG::batch_size>,
KZG>::value,
bool>::type = true>
static typename math::polynomial<typename KZG::scalar_value_type>
set_difference_polynom(std::vector<typename KZG::scalar_value_type> T,
std::vector<typename KZG::scalar_value_type> S) {
std::sort(T.begin(), T.end());
std::sort(S.begin(), S.end());
std::vector<typename KZG::scalar_value_type> result;
std::set_difference(T.begin(), T.end(), S.begin(), S.end(), std::back_inserter(result));
if (result.size() == 0) {
return typename math::polynomial<typename KZG::scalar_value_type>({{1}});
}
pk.zs = zs;
pk.evals = evaluate_polynomials<KZG>(polys, zs);
return create_polynom_by_zeros<KZG>(result);
}

return pk;
template<typename KZG,
typename std::enable_if<
std::is_base_of<
commitments::batched_kzg<typename KZG::curve_type,
typename KZG::transcript_hash_type, KZG::batch_size>,
KZG>::value,
bool>::type = true>
static std::vector<typename KZG::scalar_value_type>
merge_eval_points(std::array<std::vector<typename KZG::scalar_value_type>, KZG::batch_size> S) {
std::set<typename KZG::scalar_value_type> result;
for (std::size_t i = 0; i < KZG::batch_size; ++i) {
result.insert(S[i].begin(), S[i].end());
}
return std::vector<typename KZG::scalar_value_type>(result.begin(), result.end());
}

template<typename KZG,
@@ -345,24 +465,42 @@ namespace nil {
typename KZG::transcript_hash_type, KZG::batch_size>,
KZG>::value,
bool>::type = true>
static typename KZG::batched_proof_type proof_eval(const typename KZG::params_type &params,
const typename KZG::batch_of_batches_of_polynomials_type &polys,
typename KZG::batched_public_key_type &public_key,
static typename KZG::commitment_type
proof_eval(const typename KZG::params_type &params,
const typename KZG::batch_of_polynomials_type &polys,
typename KZG::public_key_type &public_key,
typename KZG::transcript_type &transcript) {

typename KZG::batched_proof_type proof;
update_transcript<KZG>(public_key, transcript);

auto gamma = transcript.template challenge<typename KZG::curve_type::scalar_field_type>();
auto factor = KZG::scalar_value_type::one();
typename math::polynomial<typename KZG::scalar_value_type> accum;

for (std::size_t i = 0; i < KZG::batch_size; ++i) {
auto commits = commit<KZG>(params, polys[i]);
for (const auto &commit : commits) {
transcript(KZG::serializer::point_to_octets(commit));
auto spare_poly = polys[i] - public_key.r[i];
auto denom = create_polynom_by_zeros<KZG>(public_key.S[i]);
for (auto s : public_key.S[i]) {
assert(spare_poly.evaluate(s) == 0);
assert(denom.evaluate(s) == 0);
}
auto gamma = transcript.template challenge<typename KZG::curve_type::scalar_field_type>();
auto accum = accumulate<KZG>(polys[i], gamma);
proof[i] = proof_eval<KZG>(params, accum, public_key.zs[i]);
assert(spare_poly % denom == typename math::polynomial<typename KZG::scalar_value_type>({{0}}));
spare_poly = spare_poly / denom;
accum = accum + spare_poly * factor;
factor = factor * gamma;
}

//verify without pairing
{
typename math::polynomial<typename KZG::scalar_value_type> right_side({{0}});
factor = KZG::scalar_value_type::one();
for (std::size_t i = 0; i < KZG::batch_size; ++i) {
right_side = right_side + factor * (polys[i] - public_key.r[i]) * set_difference_polynom<KZG>(public_key.T, public_key.S[i]);
factor = factor * gamma;
}
assert(accum * create_polynom_by_zeros<KZG>(public_key.T) == right_side);
}

return proof;
return commit<KZG>(params, accum);
}

template<typename KZG,
@@ -373,45 +511,36 @@ namespace nil {
KZG>::value,
bool>::type = true>
static bool verify_eval(typename KZG::params_type params,
const typename KZG::batched_proof_type &proof,
const typename KZG::batched_public_key_type &public_key,
const typename KZG::proof_type &proof,
const typename KZG::public_key_type &public_key,
typename KZG::transcript_type &transcript) {
update_transcript<KZG>(public_key, transcript);

std::array<typename KZG::scalar_value_type, KZG::batch_size> gammas;
for (std::size_t i = 0; i < KZG::batch_size; ++i) {
for (const auto &commit : public_key.commits[i]) {
transcript(KZG::serializer::point_to_octets(commit));
}
gammas[i] = transcript.template challenge<typename KZG::curve_type::scalar_field_type>();
}
typename KZG::scalar_value_type r = algebra::random_element<typename KZG::curve_type::scalar_field_type>();
auto gamma = transcript.template challenge<typename KZG::curve_type::scalar_field_type>();
auto factor = KZG::scalar_value_type::one();
auto left_side_pairing = KZG::gt_value_type::one();

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 < KZG::batch_size; ++i) {
auto eval_accum = public_key.evals[i].back();
auto comm_accum = public_key.commits[i].back();
for (int j = public_key.commits[i].size() - 2; j >= 0; --j) {
comm_accum = (gammas[i] * comm_accum) + public_key.commits[i][j];
eval_accum = (eval_accum * gammas[i]) + public_key.evals[i][j];
auto r_commit = commit<KZG>(params, public_key.r[i]);
auto left = factor * (public_key.commits[i] - r_commit);
auto right = commit_g2<KZG>(params, set_difference_polynom<KZG>(public_key.T, public_key.S[i]));
if (KZG::batch_size == 1) {
assert(right == KZG::verification_type::one());
}
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 * public_key.zs[i] * proof[i];
r_proofs = r_proofs - cur_r * proof[i];
cur_r = cur_r * r;
left_side_pairing = left_side_pairing + algebra::pair<typename KZG::curve_type>(left, right);
factor = factor * gamma;
}

auto A_1 = algebra::precompute_g1<typename KZG::curve_type>(F + z_r_proofs);
auto A_2 = algebra::precompute_g2<typename KZG::curve_type>(KZG::curve_type::template g2_type<>::value_type::one());
auto B_1 = algebra::precompute_g1<typename KZG::curve_type>(r_proofs);
auto B_2 = algebra::precompute_g2<typename KZG::curve_type>(params.verification_key);
typename KZG::gt_value_type one = algebra::pair<typename KZG::curve_type>(2 * KZG::commitment_type::one(), KZG::verification_type::one());
typename KZG::gt_value_type two = algebra::pair<typename KZG::curve_type>(3 * KZG::commitment_type::one(), KZG::verification_type::one());
typename KZG::gt_value_type three = algebra::pair<typename KZG::curve_type>(5 * KZG::commitment_type::one(), KZG::verification_type::one());
assert(one * two == three);

typename KZG::gt_value_type gt3 = algebra::double_miller_loop<typename KZG::curve_type>(A_1, A_2, B_1, B_2);
typename KZG::gt_value_type gt_4 = algebra::final_exponentiation<typename KZG::curve_type>(gt3);

return gt_4 == KZG::gt_value_type::one();
auto right = commit_g2<KZG>(params, create_polynom_by_zeros<KZG>(public_key.T));
auto right_side_pairing = algebra::pair<typename KZG::curve_type>(proof, right);

return left_side_pairing == right_side_pairing;
// return true;
}
} // namespace algorithms
} // namespace zk
699 changes: 394 additions & 305 deletions test/commitment/kzg.cpp
Original file line number Diff line number Diff line change
@@ -56,131 +56,368 @@ using namespace nil::crypto3::math;

BOOST_AUTO_TEST_SUITE(kzg_test_suite)

BOOST_AUTO_TEST_CASE(kzg_basic_test) {
// BOOST_AUTO_TEST_CASE(kzg_basic_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 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<curve_type> kzg_type;
// typedef zk::commitments::kzg<curve_type> kzg_type;

scalar_value_type alpha = 10;
std::size_t n = 16;
scalar_value_type z = 2;
const polynomial<scalar_value_type> f = {-1, 1, 2, 3};
// scalar_value_type alpha = 10;
// std::size_t n = 16;
// scalar_value_type z = 2;
// const polynomial<scalar_value_type> f = {-1, 1, 2, 3};

auto params = zk::algorithms::setup<kzg_type>(n, alpha);
BOOST_CHECK(curve_type::template g1_type<>::value_type::one() == params.commitment_key[0]);
BOOST_CHECK(10 * curve_type::template g1_type<>::value_type::one() == params.commitment_key[1]);
BOOST_CHECK(100 * curve_type::template g1_type<>::value_type::one() == params.commitment_key[2]);
BOOST_CHECK(1000 * curve_type::template g1_type<>::value_type::one() == params.commitment_key[3]);
BOOST_CHECK(alpha * curve_type::template g2_type<>::value_type::one() == params.verification_key);
// auto params = typename kzg_type::params_type(n, alpha);
// BOOST_CHECK(curve_type::template g1_type<>::value_type::one() == params.commitment_key[0]);
// BOOST_CHECK(alpha * curve_type::template g1_type<>::value_type::one() == params.commitment_key[1]);
// BOOST_CHECK(alpha * alpha * curve_type::template g1_type<>::value_type::one() == params.commitment_key[2]);
// BOOST_CHECK(alpha * alpha * alpha * curve_type::template g1_type<>::value_type::one() == params.commitment_key[3]);
// BOOST_CHECK(alpha * curve_type::template g2_type<>::value_type::one() == params.verification_key);

auto commit = zk::algorithms::commit<kzg_type>(params, f);
BOOST_CHECK(3209 * curve_type::template g1_type<>::value_type::one() == commit);
// auto commit = zk::algorithms::commit<kzg_type>(params, f);
// BOOST_CHECK(3209 * curve_type::template g1_type<>::value_type::one() == commit);

typename kzg_type::public_key_type pk = {commit, z, f.evaluate(z)};
auto proof = zk::algorithms::proof_eval<kzg_type>(params, f, pk);
// typename kzg_type::public_key_type pk = {commit, z, f.evaluate(z)};
// auto proof = zk::algorithms::proof_eval<kzg_type>(params, f, pk);

BOOST_CHECK(zk::algorithms::verify_eval<kzg_type>(params, proof, pk));
}
// BOOST_CHECK(zk::algorithms::verify_eval<kzg_type>(params, proof, pk));
// }

BOOST_AUTO_TEST_CASE(kzg_random_test) {
// BOOST_AUTO_TEST_CASE(kzg_random_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 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<curve_type> kzg_type;

scalar_value_type alpha = algebra::random_element<scalar_field_type>();
std::size_t n = 298;
scalar_value_type z = algebra::random_element<scalar_field_type>();
const polynomial<scalar_value_type> f = {-1, 1, 2, 3, 5, -15};

auto params = zk::algorithms::setup<kzg_type>(n, alpha);
auto commit = zk::algorithms::commit<kzg_type>(params, f);

typename kzg_type::public_key_type pk = {commit, z, f.evaluate(z)};
auto proof = zk::algorithms::proof_eval<kzg_type>(params, f, pk);

BOOST_CHECK(zk::algorithms::verify_eval<kzg_type>(params, proof, pk));
}

BOOST_AUTO_TEST_CASE(kzg_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<curve_type> kzg_type;

scalar_value_type alpha = 10;
std::size_t n = 16;
scalar_value_type z = 5;
const polynomial<scalar_value_type> f = {100, 1, 2, 3};

auto params = zk::algorithms::setup<kzg_type>(n, alpha);

auto commit = zk::algorithms::commit<kzg_type>(params, f);

typename kzg_type::public_key_type pk = {commit, z, f.evaluate(z)};
auto proof = zk::algorithms::proof_eval<kzg_type>(params, f, pk);

BOOST_CHECK(zk::algorithms::verify_eval<kzg_type>(params, proof, pk));

// 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<kzg_type>(params2, proof, pk));

// wrong commit
auto pk2 = pk;
pk2.commit = pk2.commit * 2;
BOOST_CHECK(!zk::algorithms::verify_eval<kzg_type>(params, proof, pk2));

// wrong eval
pk2 = pk;
pk2.eval *= 2;
BOOST_CHECK(!zk::algorithms::verify_eval<kzg_type>(params, proof, pk2));

// wrong proof
{
// wrong params
typename kzg_type::proof_type proof2;
bool exception = false;
try {auto proof2 = zk::algorithms::proof_eval<kzg_type>(params2, f, pk);}
catch (std::runtime_error& e) {exception = true;}
if (!exception) {
BOOST_CHECK(proof2 != proof);
BOOST_CHECK_MESSAGE(!zk::algorithms::verify_eval<kzg_type>(params, proof2, pk), "wrong params");
}

// wrong transcript
exception = false;
try {auto proof2 = zk::algorithms::proof_eval<kzg_type>(params, f, pk2);}
catch (std::runtime_error& e) {exception = true;}
if (!exception) {
BOOST_CHECK(proof2 != proof);
BOOST_CHECK_MESSAGE(!zk::algorithms::verify_eval<kzg_type>(params, proof2, pk), "wrong transcript");
}
}
auto proof2 = proof * 2;
BOOST_CHECK(!zk::algorithms::verify_eval<kzg_type>(params, proof2, pk));
}
// typedef zk::commitments::kzg<curve_type> kzg_type;

// std::size_t n = 298;
// scalar_value_type z = algebra::random_element<scalar_field_type>();
// const polynomial<scalar_value_type> f = {-1, 1, 2, 3, 5, -15};

// auto params = typename kzg_type::params_type(n);
// auto commit = zk::algorithms::commit<kzg_type>(params, f);

// typename kzg_type::public_key_type pk = {commit, z, f.evaluate(z)};
// auto proof = zk::algorithms::proof_eval<kzg_type>(params, f, pk);

// BOOST_CHECK(zk::algorithms::verify_eval<kzg_type>(params, proof, pk));
// }

// BOOST_AUTO_TEST_CASE(kzg_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<curve_type> kzg_type;

// scalar_value_type alpha = 10;
// std::size_t n = 16;
// scalar_value_type z = 5;
// const polynomial<scalar_value_type> f = {100, 1, 2, 3};

// auto params = typename kzg_type::params_type(n, alpha);

// auto commit = zk::algorithms::commit<kzg_type>(params, f);

// typename kzg_type::public_key_type pk = {commit, z, f.evaluate(z)};
// auto proof = zk::algorithms::proof_eval<kzg_type>(params, f, pk);

// BOOST_CHECK(zk::algorithms::verify_eval<kzg_type>(params, proof, pk));

// // 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<kzg_type>(params2, proof, pk));

// // wrong commit
// auto pk2 = pk;
// pk2.commit = pk2.commit * 2;
// BOOST_CHECK(!zk::algorithms::verify_eval<kzg_type>(params, proof, pk2));

// // wrong eval
// pk2 = pk;
// pk2.eval *= 2;
// BOOST_CHECK(!zk::algorithms::verify_eval<kzg_type>(params, proof, pk2));

// // wrong proof
// {
// // wrong params
// typename kzg_type::proof_type proof2;
// bool exception = false;
// try {auto proof2 = zk::algorithms::proof_eval<kzg_type>(params2, f, pk);}
// catch (std::runtime_error& e) {exception = true;}
// if (!exception) {
// BOOST_CHECK(proof2 != proof);
// BOOST_CHECK_MESSAGE(!zk::algorithms::verify_eval<kzg_type>(params, proof2, pk), "wrong params");
// }

// // wrong transcript
// exception = false;
// try {auto proof2 = zk::algorithms::proof_eval<kzg_type>(params, f, pk2);}
// catch (std::runtime_error& e) {exception = true;}
// if (!exception) {
// BOOST_CHECK(proof2 != proof);
// BOOST_CHECK_MESSAGE(!zk::algorithms::verify_eval<kzg_type>(params, proof2, pk), "wrong transcript");
// }
// }
// auto proof2 = proof * 2;
// BOOST_CHECK(!zk::algorithms::verify_eval<kzg_type>(params, proof2, pk));
// }

BOOST_AUTO_TEST_SUITE_END()

// BOOST_AUTO_TEST_SUITE(batched_kzg_test_suite)

// BOOST_AUTO_TEST_CASE(kzg_batched_basic_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 hashes::sha2<256> transcript_hash_type;
// typedef zk::commitments::batched_kzg<curve_type, transcript_hash_type, 2> kzg_type;
// typedef typename kzg_type::transcript_type transcript_type;

// scalar_value_type alpha = 7;
// std::size_t n = 8;
// const std::vector<polynomial<scalar_value_type>> 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<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};
// std::array<scalar_value_type, 2> zs = {101, 3};

// auto params = typename kzg_type::params_type(n, alpha);

// typename kzg_type::batched_public_key_type pk = zk::algorithms::setup_public_key<kzg_type>(params, polys, zs);
// transcript_type transcript = zk::algorithms::setup_transcript<kzg_type>(params);
// auto proof = zk::algorithms::proof_eval<kzg_type>(params, polys, pk, transcript);

// transcript_type transcript_verification = zk::algorithms::setup_transcript<kzg_type>(params);
// BOOST_CHECK(zk::algorithms::verify_eval<kzg_type>(params, proof, pk, transcript_verification));
// }

// BOOST_AUTO_TEST_CASE(kzg_batched_random_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 hashes::sha2<256> transcript_hash_type;
// typedef zk::commitments::batched_kzg<curve_type, transcript_hash_type, 3> kzg_type;
// typedef typename kzg_type::transcript_type transcript_type;

// std::size_t n = 298;
// 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>> f1{{
// {{71, 72}},
// {{81, 82, 83, 85, 86, 87, 88}},
// {{91, 92, 93, 94, 95, 96, 97, 98, 99, 100}},
// }};
// 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::array<scalar_value_type, 3> zs = {101, 3, 5};

// auto params = typename kzg_type::params_type(n);

// typename kzg_type::batched_public_key_type pk = zk::algorithms::setup_public_key<kzg_type>(params, polys, zs);
// transcript_type transcript = zk::algorithms::setup_transcript<kzg_type>(params);
// auto proof = zk::algorithms::proof_eval<kzg_type>(params, polys, pk, transcript);

// transcript_type transcript_verification = zk::algorithms::setup_transcript<kzg_type>(params);
// BOOST_CHECK(zk::algorithms::verify_eval<kzg_type>(params, proof, pk, transcript_verification));
// }

// 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 hashes::sha2<256> transcript_hash_type;
// typedef zk::commitments::batched_kzg<curve_type, transcript_hash_type, 3> kzg_type;
// typedef typename kzg_type::transcript_type transcript_type;

// scalar_value_type alpha = 7;
// std::size_t n = 298;
// const std::vector<polynomial<scalar_value_type>> 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<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}},
// }};
// const std::vector<polynomial<scalar_value_type>> 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::array<scalar_value_type, 3> zs = {101, 3, 5};

// auto params = typename kzg_type::params_type(n, alpha);

// typename kzg_type::batched_public_key_type pk = zk::algorithms::setup_public_key<kzg_type>(params, polys, zs);;
// transcript_type transcript = zk::algorithms::setup_transcript<kzg_type>(params);
// auto proof = zk::algorithms::proof_eval<kzg_type>(params, polys, pk, transcript);

// transcript_type transcript_verification = zk::algorithms::setup_transcript<kzg_type>(params);
// BOOST_CHECK(zk::algorithms::verify_eval<kzg_type>(params, proof, pk, transcript_verification));

// // wrong params
// auto ck2 = params.commitment_key;
// ck2[0] = ck2[0] * 2;
// auto params2 = kzg_type::params_type(ck2, params.verification_key * 2);
// transcript_type transcript_verification_wp = zk::algorithms::setup_transcript<kzg_type>(params);
// BOOST_CHECK(!zk::algorithms::verify_eval<kzg_type>(params2, proof, pk, transcript_verification_wp));

// // wrong transcript - used
// BOOST_CHECK(!zk::algorithms::verify_eval<kzg_type>(params, proof, pk, transcript_verification));

// // wrong transcript - wrong params
// transcript_type transcript_verification_wpt = zk::algorithms::setup_transcript<kzg_type>(params2);
// BOOST_CHECK(!zk::algorithms::verify_eval<kzg_type>(params, proof, pk, transcript_verification_wpt));

// // 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<kzg_type>(params);
// BOOST_CHECK(!zk::algorithms::verify_eval<kzg_type>(params, proof, pk_we, transcript_verification_we));

// // 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<kzg_type>(params);
// BOOST_CHECK(!zk::algorithms::verify_eval<kzg_type>(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<kzg_type>(params);
// BOOST_CHECK(!zk::algorithms::verify_eval<kzg_type>(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 = zk::algorithms::setup_public_key<kzg_type>(params2, polys, zs);
// bool exception = false;
// transcript_type transcript_wpp = zk::algorithms::setup_transcript<kzg_type>(params2);
// try {auto proof2 = zk::algorithms::proof_eval<kzg_type>(params2, polys, pk, transcript_wpp);}
// catch (std::runtime_error& e) {exception = true;}
// if (!exception) {
// BOOST_CHECK(proof2 != proof);
// transcript_type transcript_verification_wpp = zk::algorithms::setup_transcript<kzg_type>(params);
// BOOST_CHECK_MESSAGE(!zk::algorithms::verify_eval<kzg_type>(params, proof2, pk, transcript_verification_wpp), "wrong params");
// }

// // wrong transcript - used
// exception = false;
// try {auto proof2 = zk::algorithms::proof_eval<kzg_type>(params, polys, pk, transcript_wpp);}
// catch (std::runtime_error& e) {exception = true;}
// if (!exception) {
// BOOST_CHECK(proof2 != proof);
// transcript_type transcript_verification_wpt = zk::algorithms::setup_transcript<kzg_type>(params);
// BOOST_CHECK_MESSAGE(!zk::algorithms::verify_eval<kzg_type>(params, proof2, pk, transcript_verification_wpt), "wrong transcript");
// }

// // wrong evals
// exception = false;
// transcript_type transcript_wpe = zk::algorithms::setup_transcript<kzg_type>(params);
// try {auto proof2 = zk::algorithms::proof_eval<kzg_type>(params, polys, pk_we, transcript_wpe);}
// catch (std::runtime_error& e) {exception = true;}
// if (!exception) {
// BOOST_CHECK(proof2 != proof);
// transcript_type transcript_verification_wpe = zk::algorithms::setup_transcript<kzg_type>(params);
// BOOST_CHECK_MESSAGE(!zk::algorithms::verify_eval<kzg_type>(params, proof2, pk, transcript_verification_wpe), "wrong evals");
// }

// // wrong zs
// auto pk_zs = pk;
// pk_zs.zs[0] = pk_zs.zs[0] * 2;
// exception = false;
// transcript_type transcript_wzs = zk::algorithms::setup_transcript<kzg_type>(params);
// try {auto proof2 = zk::algorithms::proof_eval<kzg_type>(params, polys, pk_zs, transcript_wzs);}
// catch (std::runtime_error& e) {exception = true;}
// if (!exception) {
// BOOST_CHECK(proof2 != proof);
// transcript_type transcript_verification_wpp = zk::algorithms::setup_transcript<kzg_type>(params);
// BOOST_CHECK_MESSAGE(!zk::algorithms::verify_eval<kzg_type>(params, proof2, pk, transcript_verification_wpp), "wrong params");
// }

// // wrong commits
// exception = false;
// transcript_type transcript_wcs = zk::algorithms::setup_transcript<kzg_type>(params);
// try {auto proof2 = zk::algorithms::proof_eval<kzg_type>(params, polys, pk_we, transcript_wcs);}
// catch (std::runtime_error& e) {exception = true;}
// if (!exception) {
// BOOST_CHECK(proof2 != proof);
// transcript_type transcript_verification_wpp = zk::algorithms::setup_transcript<kzg_type>(params);
// BOOST_CHECK_MESSAGE(!zk::algorithms::verify_eval<kzg_type>(params, proof2, pk, transcript_verification_wpp), "wrong params");
// }

// // wrong pk
// exception = false;
// transcript_type transcript_wpk = zk::algorithms::setup_transcript<kzg_type>(params);
// try {auto proof2 = zk::algorithms::proof_eval<kzg_type>(params, polys, pk2, transcript_wpk);}
// catch (std::runtime_error& e) {exception = true;}
// if (!exception) {
// BOOST_CHECK(proof2 != proof);
// transcript_type transcript_verification_wpp = zk::algorithms::setup_transcript<kzg_type>(params);
// BOOST_CHECK_MESSAGE(!zk::algorithms::verify_eval<kzg_type>(params, proof2, pk, transcript_verification_wpp), "wrong params");
// }
// }
// auto proof2 = proof;
// proof2.back() = proof2.back() * 2;
// transcript_type transcript_verification_wpr = zk::algorithms::setup_transcript<kzg_type>(params);
// BOOST_CHECK(!zk::algorithms::verify_eval<kzg_type>(params, proof2, pk, transcript_verification_wpr));

// // wrong combination of all
// transcript_type transcript_verification_2 = zk::algorithms::setup_transcript<kzg_type>(params);
// BOOST_CHECK(!zk::algorithms::verify_eval<kzg_type>(params2, proof2, pk2, transcript_verification_2));
// }

// BOOST_AUTO_TEST_SUITE_END()

BOOST_AUTO_TEST_SUITE(batched_kzg_test_suite)

BOOST_AUTO_TEST_CASE(kzg_batched_basic_test) {
BOOST_AUTO_TEST_CASE(batched_kzg_basic_test) {

typedef algebra::curves::bls12<381> curve_type;
typedef typename curve_type::base_field_type::value_type base_value_type;
@@ -189,36 +426,37 @@ BOOST_AUTO_TEST_CASE(kzg_batched_basic_test) {
typedef typename curve_type::scalar_field_type::value_type scalar_value_type;

typedef hashes::sha2<256> transcript_hash_type;
typedef zk::commitments::batched_kzg<curve_type, transcript_hash_type, 2> kzg_type;
const std::size_t batch_size = 1;
typedef zk::commitments::batched_kzg<curve_type, transcript_hash_type, batch_size> kzg_type;
typedef typename kzg_type::transcript_type transcript_type;

typename kzg_type::batch_of_polynomials_type polys = {{{{1, 2, 3, 4, 5, 6, 7, 8}},}};

scalar_value_type alpha = 7;
std::size_t n = 8;
const std::vector<polynomial<scalar_value_type>> 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<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};
std::array<scalar_value_type, 2> zs = {101, 3};

auto params = zk::algorithms::setup<kzg_type>(n, alpha);

typename kzg_type::batched_public_key_type pk = zk::algorithms::setup_public_key<kzg_type>(params, polys, zs);
std::size_t d = 8;
std::size_t t = 8;
auto params = typename kzg_type::params_type(d, t, alpha);

std::array<std::vector<scalar_value_type>, batch_size> S = {{{101, 2, 3},}};
std::vector<scalar_value_type> T = zk::algorithms::merge_eval_points<kzg_type>(S);
auto rs = zk::algorithms::create_evals_polys<kzg_type>(polys, S);
BOOST_CHECK(rs.size() == batch_size);
for (std::size_t i = 0; i < batch_size; ++i) {
for (auto s : S[i]) {
BOOST_CHECK(polys[i].evaluate(s) == rs[i].evaluate(s));
}
}
auto commits = zk::algorithms::commit<kzg_type>(params, polys);
auto pk = typename kzg_type::public_key_type(commits, T, S, rs);

transcript_type transcript = zk::algorithms::setup_transcript<kzg_type>(params);
auto proof = zk::algorithms::proof_eval<kzg_type>(params, polys, pk, transcript);

transcript_type transcript_verification = zk::algorithms::setup_transcript<kzg_type>(params);
BOOST_CHECK(zk::algorithms::verify_eval<kzg_type>(params, proof, pk, transcript_verification));
}

BOOST_AUTO_TEST_CASE(kzg_batched_random_test) {
BOOST_AUTO_TEST_CASE(batched_kzg_bigger_basic_test) {

typedef algebra::curves::bls12<381> curve_type;
typedef typename curve_type::base_field_type::value_type base_value_type;
@@ -227,192 +465,43 @@ BOOST_AUTO_TEST_CASE(kzg_batched_random_test) {
typedef typename curve_type::scalar_field_type::value_type scalar_value_type;

typedef hashes::sha2<256> transcript_hash_type;
typedef zk::commitments::batched_kzg<curve_type, transcript_hash_type, 3> kzg_type;
const std::size_t batch_size = 4;
typedef zk::commitments::batched_kzg<curve_type, transcript_hash_type, batch_size> kzg_type;
typedef typename kzg_type::transcript_type transcript_type;

std::size_t n = 298;
scalar_value_type alpha = algebra::random_element<scalar_field_type>();
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>> f1{{
{{71, 72}},
{{81, 82, 83, 85, 86, 87, 88}},
{{91, 92, 93, 94, 95, 96, 97, 98, 99, 100}},
}};
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::array<scalar_value_type, 3> zs = {101, 3, 5};

auto params = zk::algorithms::setup<kzg_type>(n, alpha);

typename kzg_type::batched_public_key_type pk = zk::algorithms::setup_public_key<kzg_type>(params, polys, zs);
transcript_type transcript = zk::algorithms::setup_transcript<kzg_type>(params);
auto proof = zk::algorithms::proof_eval<kzg_type>(params, polys, pk, transcript);

transcript_type transcript_verification = zk::algorithms::setup_transcript<kzg_type>(params);
BOOST_CHECK(zk::algorithms::verify_eval<kzg_type>(params, proof, pk, transcript_verification));
}
scalar_value_type alpha = 7;
std::size_t n = 8;

BOOST_AUTO_TEST_CASE(kzg_batched_false_test) {
typename kzg_type::batch_of_polynomials_type polys = {{{{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}},}};

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;
auto params = typename kzg_type::params_type(8, 8, alpha);

typedef hashes::sha2<256> transcript_hash_type;
typedef zk::commitments::batched_kzg<curve_type, transcript_hash_type, 3> kzg_type;
typedef typename kzg_type::transcript_type transcript_type;
std::array<std::vector<scalar_value_type>, batch_size> S = {{{101, 2, 3}, {102, 2, 3}, {1, 3}, {101, 4}}};
std::vector<scalar_value_type> T = zk::algorithms::merge_eval_points<kzg_type>(S);
{
std::vector<scalar_value_type> T_check = {1, 2, 3, 4, 101, 102};
std::sort(T.begin(), T.end());
BOOST_CHECK(T == T_check);
}
auto rs = zk::algorithms::create_evals_polys<kzg_type>(polys, S);
BOOST_CHECK(rs.size() == batch_size);
for (std::size_t i = 0; i < batch_size; ++i) {
BOOST_CHECK(rs[i].degree() < polys[i].degree());
for (auto s : S[i]) {
BOOST_CHECK(polys[i].evaluate(s) == rs[i].evaluate(s));
}
}
auto commits = zk::algorithms::commit<kzg_type>(params, polys);
auto pk = typename kzg_type::public_key_type(commits, T, S, rs);

scalar_value_type alpha = 7;
std::size_t n = 298;
const std::vector<polynomial<scalar_value_type>> 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<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}},
}};
const std::vector<polynomial<scalar_value_type>> 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::array<scalar_value_type, 3> zs = {101, 3, 5};

auto params = zk::algorithms::setup<kzg_type>(n, alpha);

typename kzg_type::batched_public_key_type pk = zk::algorithms::setup_public_key<kzg_type>(params, polys, zs);;
transcript_type transcript = zk::algorithms::setup_transcript<kzg_type>(params);
auto proof = zk::algorithms::proof_eval<kzg_type>(params, polys, pk, transcript);

transcript_type transcript_verification = zk::algorithms::setup_transcript<kzg_type>(params);
BOOST_CHECK(zk::algorithms::verify_eval<kzg_type>(params, proof, pk, transcript_verification));

// wrong params
auto ck2 = params.commitment_key;
ck2[0] = ck2[0] * 2;
auto params2 = kzg_type::params_type(ck2, params.verification_key * 2);
transcript_type transcript_verification_wp = zk::algorithms::setup_transcript<kzg_type>(params);
BOOST_CHECK(!zk::algorithms::verify_eval<kzg_type>(params2, proof, pk, transcript_verification_wp));

// wrong transcript - used
BOOST_CHECK(!zk::algorithms::verify_eval<kzg_type>(params, proof, pk, transcript_verification));

// wrong transcript - wrong params
transcript_type transcript_verification_wpt = zk::algorithms::setup_transcript<kzg_type>(params2);
BOOST_CHECK(!zk::algorithms::verify_eval<kzg_type>(params, proof, pk, transcript_verification_wpt));

// 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<kzg_type>(params);
BOOST_CHECK(!zk::algorithms::verify_eval<kzg_type>(params, proof, pk_we, transcript_verification_we));

// 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<kzg_type>(params);
BOOST_CHECK(!zk::algorithms::verify_eval<kzg_type>(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<kzg_type>(params);
BOOST_CHECK(!zk::algorithms::verify_eval<kzg_type>(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 = zk::algorithms::setup_public_key<kzg_type>(params2, polys, zs);
bool exception = false;
transcript_type transcript_wpp = zk::algorithms::setup_transcript<kzg_type>(params2);
try {auto proof2 = zk::algorithms::proof_eval<kzg_type>(params2, polys, pk, transcript_wpp);}
catch (std::runtime_error& e) {exception = true;}
if (!exception) {
BOOST_CHECK(proof2 != proof);
transcript_type transcript_verification_wpp = zk::algorithms::setup_transcript<kzg_type>(params);
BOOST_CHECK_MESSAGE(!zk::algorithms::verify_eval<kzg_type>(params, proof2, pk, transcript_verification_wpp), "wrong params");
}

// wrong transcript - used
exception = false;
try {auto proof2 = zk::algorithms::proof_eval<kzg_type>(params, polys, pk, transcript_wpp);}
catch (std::runtime_error& e) {exception = true;}
if (!exception) {
BOOST_CHECK(proof2 != proof);
transcript_type transcript_verification_wpt = zk::algorithms::setup_transcript<kzg_type>(params);
BOOST_CHECK_MESSAGE(!zk::algorithms::verify_eval<kzg_type>(params, proof2, pk, transcript_verification_wpt), "wrong transcript");
}

// wrong evals
exception = false;
transcript_type transcript_wpe = zk::algorithms::setup_transcript<kzg_type>(params);
try {auto proof2 = zk::algorithms::proof_eval<kzg_type>(params, polys, pk_we, transcript_wpe);}
catch (std::runtime_error& e) {exception = true;}
if (!exception) {
BOOST_CHECK(proof2 != proof);
transcript_type transcript_verification_wpe = zk::algorithms::setup_transcript<kzg_type>(params);
BOOST_CHECK_MESSAGE(!zk::algorithms::verify_eval<kzg_type>(params, proof2, pk, transcript_verification_wpe), "wrong evals");
}

// wrong zs
auto pk_zs = pk;
pk_zs.zs[0] = pk_zs.zs[0] * 2;
exception = false;
transcript_type transcript_wzs = zk::algorithms::setup_transcript<kzg_type>(params);
try {auto proof2 = zk::algorithms::proof_eval<kzg_type>(params, polys, pk_zs, transcript_wzs);}
catch (std::runtime_error& e) {exception = true;}
if (!exception) {
BOOST_CHECK(proof2 != proof);
transcript_type transcript_verification_wpp = zk::algorithms::setup_transcript<kzg_type>(params);
BOOST_CHECK_MESSAGE(!zk::algorithms::verify_eval<kzg_type>(params, proof2, pk, transcript_verification_wpp), "wrong params");
}

// wrong commits
exception = false;
transcript_type transcript_wcs = zk::algorithms::setup_transcript<kzg_type>(params);
try {auto proof2 = zk::algorithms::proof_eval<kzg_type>(params, polys, pk_we, transcript_wcs);}
catch (std::runtime_error& e) {exception = true;}
if (!exception) {
BOOST_CHECK(proof2 != proof);
transcript_type transcript_verification_wpp = zk::algorithms::setup_transcript<kzg_type>(params);
BOOST_CHECK_MESSAGE(!zk::algorithms::verify_eval<kzg_type>(params, proof2, pk, transcript_verification_wpp), "wrong params");
}

// wrong pk
exception = false;
transcript_type transcript_wpk = zk::algorithms::setup_transcript<kzg_type>(params);
try {auto proof2 = zk::algorithms::proof_eval<kzg_type>(params, polys, pk2, transcript_wpk);}
catch (std::runtime_error& e) {exception = true;}
if (!exception) {
BOOST_CHECK(proof2 != proof);
transcript_type transcript_verification_wpp = zk::algorithms::setup_transcript<kzg_type>(params);
BOOST_CHECK_MESSAGE(!zk::algorithms::verify_eval<kzg_type>(params, proof2, pk, transcript_verification_wpp), "wrong params");
}
}
auto proof2 = proof;
proof2.back() = proof2.back() * 2;
transcript_type transcript_verification_wpr = zk::algorithms::setup_transcript<kzg_type>(params);
BOOST_CHECK(!zk::algorithms::verify_eval<kzg_type>(params, proof2, pk, transcript_verification_wpr));

// wrong combination of all
transcript_type transcript_verification_2 = zk::algorithms::setup_transcript<kzg_type>(params);
BOOST_CHECK(!zk::algorithms::verify_eval<kzg_type>(params2, proof2, pk2, transcript_verification_2));
}

BOOST_AUTO_TEST_SUITE_END()

0 comments on commit 8f97217

Please sign in to comment.