diff --git a/parallel-crypto3/libs/parallel-containers/test/merkle/merkle.cpp b/parallel-crypto3/libs/parallel-containers/test/merkle/merkle.cpp index 7db3a093f4..f3d8dc2d5d 100644 --- a/parallel-crypto3/libs/parallel-containers/test/merkle/merkle.cpp +++ b/parallel-crypto3/libs/parallel-containers/test/merkle/merkle.cpp @@ -26,12 +26,6 @@ #define BOOST_TEST_MODULE containter_merkletree_test -#include -#include -#include -#include -#include - #include #include #include @@ -41,7 +35,6 @@ #include #include #include -#include #include #include @@ -50,6 +43,12 @@ #include #include +#include +#include +#include +#include +#include + using namespace nil::crypto3; using namespace nil::crypto3::containers; diff --git a/parallel-crypto3/libs/parallel-zk/include/nil/crypto3/zk/commitments/detail/polynomial/basic_fri.hpp b/parallel-crypto3/libs/parallel-zk/include/nil/crypto3/zk/commitments/detail/polynomial/basic_fri.hpp index 0b9690e7db..ddc90f0e09 100644 --- a/parallel-crypto3/libs/parallel-zk/include/nil/crypto3/zk/commitments/detail/polynomial/basic_fri.hpp +++ b/parallel-crypto3/libs/parallel-zk/include/nil/crypto3/zk/commitments/detail/polynomial/basic_fri.hpp @@ -289,7 +289,61 @@ namespace nil { std::vector round_proofs; }; + struct commitments_part_of_proof { + bool operator==(const commitments_part_of_proof& rhs) const { + return fri_roots == rhs.fri_roots && + final_polynomial == rhs.final_polynomial; + } + + bool operator!=(const commitments_part_of_proof& rhs) const { + return !(rhs == *this); + } + + // Vector of size 'step_list.size()'. + std::vector fri_roots; + math::polynomial final_polynomial; + }; + + struct round_proofs_batch_type { + bool operator==(const round_proofs_batch_type &rhs) const { + return round_proofs == rhs.round_proofs; + } + + bool operator!=(const round_proofs_batch_type &rhs) const { + return !(rhs == *this); + } + + // Vector of size 'lambda'. + std::vector> round_proofs; + }; + + struct initial_proofs_batch_type { + bool operator==(const initial_proofs_batch_type &rhs) const { + return initial_proofs == rhs.initial_proofs; + } + + bool operator!=(const initial_proofs_batch_type &rhs) const { + return !(rhs == *this); + } + + // Vector of size 'lambda'. + std::vector> initial_proofs; + }; + struct proof_type { + proof_type() = default; + proof_type(const proof_type&) = default; + + proof_type(const round_proofs_batch_type& round_proofs, + const initial_proofs_batch_type& intial_proofs) + : fri_roots(round_proofs.fri_roots) + , final_polynomial(round_proofs.final_polynomial) { + for (std::size_t i = 0; i < intial_proofs.initial_proofs.size(); ++i) { + query_proofs.emplace_back( + {intial_proofs.initial_proofs[i], round_proofs.round_proofs[i]}); + } + } + bool operator==(const proof_type &rhs) const { // TODO(martun): check if the following comment can be deleted. // if( FRI::use_grinding && proof_of_work != rhs.proof_of_work ){ @@ -376,13 +430,13 @@ namespace nil { FRI>::value, bool>::type = true> static typename FRI::precommitment_type - precommit(math::polynomial_dfs &f, + precommit(const math::polynomial_dfs &f, std::shared_ptr> D, const std::size_t fri_step) { - if (f.size() != D->size()) { - f.resize(D->size(), nullptr, D); + throw std::runtime_error("Polynomial size does not match the domain size in FRI precommit."); } + std::size_t domain_size = D->size(); std::size_t coset_size = 1 << fri_step; std::size_t leafs_number = domain_size / coset_size; @@ -441,6 +495,10 @@ namespace nil { math::polynomial_dfs f_dfs; f_dfs.from_coefficients(f); + if (f_dfs.size() != D->size()) { + f_dfs.resize(D->size(), nullptr, D); + } + return precommit(f_dfs, D, fri_step); } @@ -681,12 +739,10 @@ namespace nil { static std::tuple< std::vector, std::vector, - std::vector, - math::polynomial + typename FRI::commitments_part_of_proof > commit_phase( const PolynomialType& combined_Q, - const std::map &precommitments, const typename FRI::precommitment_type &combined_Q_precommitment, const typename FRI::params_type &fri_params, typename FRI::transcript_type &transcript) @@ -694,8 +750,7 @@ namespace nil { PROFILE_SCOPE("Basic FRI commit phase"); std::vector fs; std::vector fri_trees; - std::vector fri_roots; - math::polynomial final_polynomial; + typename FRI::commitments_part_of_proof commitments_proof; auto f = combined_Q; auto precommitment = combined_Q_precommitment; @@ -704,7 +759,7 @@ namespace nil { for (std::size_t i = 0; i < fri_params.step_list.size(); i++) { fs.push_back(f); fri_trees.push_back(precommitment); - fri_roots.push_back(commit(precommitment)); + commitments_proof.fri_roots.push_back(commit(precommitment)); transcript(commit(precommitment)); for (std::size_t step_i = 0; step_i < fri_params.step_list[i]; ++step_i, ++t) { typename FRI::field_type::value_type alpha = transcript.template challenge(); @@ -717,17 +772,26 @@ namespace nil { f = commitments::detail::fold_polynomial(f, alpha); } } - if (i != fri_params.step_list.size() - 1) - precommitment = precommit(f, fri_params.D[t], fri_params.step_list[i + 1]); + if (i != fri_params.step_list.size() - 1) { + const auto& D = fri_params.D[t]; + if constexpr (std::is_same, + PolynomialType>::value) { + if (f.size() != D->size()) { + f.resize(D->size(), nullptr, D); + } + } + precommitment = precommit(f, D, fri_params.step_list[i + 1]); + } + } fs.push_back(f); if constexpr (std::is_same, PolynomialType>::value) { - final_polynomial = math::polynomial(f.coefficients()); + commitments_proof.final_polynomial = math::polynomial(f.coefficients()); } else { - final_polynomial = f; + commitments_proof.final_polynomial = f; } - return std::make_tuple(fs, fri_trees, fri_roots, final_polynomial); + return std::make_tuple(fs, fri_trees, commitments_proof); } /** @brief Convert a set of polynomials from DFS form into coefficients form, parallel version */ @@ -877,11 +941,6 @@ namespace nil { static std::vector build_round_proofs( const typename FRI::params_type &fri_params, - const std::map> &g, - const std::map< - std::size_t, - std::vector> - > &g_coeffs, const std::vector &fri_trees, const std::vector &fs, const math::polynomial &final_polynomial, @@ -952,18 +1011,45 @@ namespace nil { template - static std::vector - query_phase( - const std::map &precommitments, + static typename FRI::round_proofs_batch_type query_phase_round_proofs( const typename FRI::params_type &fri_params, - typename FRI::transcript_type &transcript, - const std::map> &g, const std::vector &fri_trees, const std::vector &fs, - const math::polynomial &final_polynomial) + const math::polynomial &final_polynomial, + const std::vector& challenges) { - PROFILE_SCOPE("Basic FRI query phase"); - std::vector query_proofs(fri_params.lambda); + typename FRI::round_proofs_batch_type proof; + + for (std::size_t query_id = 0; query_id < fri_params.lambda; query_id++) { + std::size_t domain_size = fri_params.D[0]->size(); + typename FRI::field_type::value_type x = challenges[query_id]; + x = x.pow((FRI::field_type::modulus - 1) / domain_size); + + std::uint64_t x_index = 0; + + while (fri_params.D[0]->get_domain_element(x_index) != x) { + ++x_index; + } + + // Fill round proofs + std::vector round_proofs = + build_round_proofs( + fri_params, fri_trees, fs, final_polynomial, x_index); + + proof.round_proofs.emplace_back(std::move(round_proofs)); + } + return proof; + } + + template + static typename FRI::initial_proofs_batch_type query_phase_initial_proofs( + const std::map &precommitments, + const typename FRI::params_type &fri_params, + const std::map> &g, + const std::vector& challenges) + { + typename FRI::initial_proofs_batch_type proof; + proof.initial_proofs.resize(fri_params.lambda); // If we have DFS polynomials, and we are going to resize them, better convert them to coefficients form, // and compute their values in those 2 * FRI::lambda points each, which is normally 2 * 20. @@ -972,18 +1058,12 @@ namespace nil { std::map>> g_coeffs = convert_polynomials_to_coefficients(fri_params, g); - std::vector challenges(fri_params.lambda); - - for (std::size_t query_id = 0; query_id < fri_params.lambda; ++query_id) - challenges[query_id] = transcript.template challenge(); - parallel_for(0, fri_params.lambda, - [&final_polynomial, &query_proofs, &fri_params, &fri_trees, - &fs, &precommitments, &g_coeffs, &g, &challenges](std::size_t query_id) { + [&proof, &fri_params, &precommitments, &g_coeffs, &g, &challenges](std::size_t query_id) { std::size_t domain_size = fri_params.D[0]->size(); typename FRI::field_type::value_type x = challenges[query_id]; - x = x.pow((FRI::field_type::modulus - 1)/domain_size); + x = x.pow((FRI::field_type::modulus - 1) / domain_size); std::uint64_t x_index = 0; @@ -991,34 +1071,73 @@ namespace nil { ++x_index; } - // Initial proof std::map initial_proof = build_initial_proof( precommitments, fri_params, g, g_coeffs, x_index); + proof.initial_proofs[query_id] = std::move(initial_proof); + }, ThreadPool::PoolLevel::HIGH); - // Fill round proofs - std::vector - round_proofs = build_round_proofs( - fri_params, g, g_coeffs, fri_trees, fs, final_polynomial, x_index); + return proof; + } - typename FRI::query_proof_type query_proof = {std::move(initial_proof), std::move(round_proofs)}; - query_proofs[query_id] = std::move(query_proof); - }, ThreadPool::PoolLevel::HIGH); + template + static std::vector + query_phase_with_challenges( + const std::map &precommitments, + const typename FRI::params_type &fri_params, + const std::vector& challenges, + const std::map> &g, + const std::vector &fri_trees, + const std::vector &fs, + const math::polynomial &final_polynomial) + { + typename FRI::initial_proofs_batch_type initial_proofs = + query_phase_initial_proofs( + precommitments, fri_params, g, challenges); + + typename FRI::round_proofs_batch_type round_proofs = + query_phase_round_proofs( + fri_params, fri_trees, fs, final_polynomial, challenges); + + // Join intial proofs and round proofs into a structure of query proofs. + std::vector query_proofs(fri_params.lambda); - return std::move(query_proofs); + for (std::size_t query_id = 0; query_id < fri_params.lambda; query_id++) { + query_proofs[query_id] = {std::move(initial_proofs.initial_proofs[query_id]), + std::move(round_proofs.round_proofs[query_id])}; + } + return query_proofs; } + template + static std::vector + query_phase( + const std::map &precommitments, + const typename FRI::params_type &fri_params, + typename FRI::transcript_type &transcript, + const std::map> &g, + const std::vector &fri_trees, + const std::vector &fs, + const math::polynomial &final_polynomial) + { + PROFILE_SCOPE("Basic FRI query phase"); + std::vector challenges = + transcript.template challenges(fri_params.lambda); + + return query_phase_with_challenges( + precommitments, fri_params, challenges, g, fri_trees, fs, final_polynomial); + } template, - FRI>::value, - bool>::type = true> + std::is_base_of< + commitments::detail::basic_batched_fri< + typename FRI::field_type, typename FRI::merkle_tree_hash_type, + typename FRI::transcript_hash_type, + FRI::m, typename FRI::grinding_type>, + FRI>::value, + bool>::type = true> static typename FRI::proof_type proof_eval( const std::map> &g, const PolynomialType& combined_Q, @@ -1037,18 +1156,19 @@ namespace nil { // Commit phase std::vector fri_trees; - std::vector fri_roots; std::vector fs; - math::polynomial final_polynomial; - std::tie(fs, fri_trees, fri_roots, final_polynomial) = - commit_phase( - combined_Q, precommitments, + // Contains fri_roots and final_polynomial. + typename FRI::commitments_part_of_proof commitments_proof; + + std::tie(fs, fri_trees, commitments_proof) = + commit_phase( + combined_Q, combined_Q_precommitment, fri_params, transcript); // Grinding - if ( fri_params.use_grinding ) { + if (fri_params.use_grinding) { PROFILE_SCOPE("Basic FRI grinding phase"); proof.proof_of_work = FRI::grinding_type::generate(transcript, fri_params.grinding_parameter); } @@ -1056,10 +1176,10 @@ namespace nil { // Query phase proof.query_proofs = query_phase( precommitments, fri_params, transcript, - g, fri_trees, fs, final_polynomial); + g, fri_trees, fs, commitments_proof.final_polynomial); - proof.fri_roots = std::move(fri_roots); - proof.final_polynomial = std::move(final_polynomial); + proof.fri_roots = std::move(commitments_proof.fri_roots); + proof.final_polynomial = std::move(commitments_proof.final_polynomial); return proof; } diff --git a/parallel-crypto3/libs/parallel-zk/include/nil/crypto3/zk/commitments/polynomial/lpc.hpp b/parallel-crypto3/libs/parallel-zk/include/nil/crypto3/zk/commitments/polynomial/lpc.hpp index 2740a3b54c..835a21ce7a 100644 --- a/parallel-crypto3/libs/parallel-zk/include/nil/crypto3/zk/commitments/polynomial/lpc.hpp +++ b/parallel-crypto3/libs/parallel-zk/include/nil/crypto3/zk/commitments/polynomial/lpc.hpp @@ -48,6 +48,7 @@ namespace nil { namespace commitments { // Placeholder-friendly class. + // LPCScheme is usually 'batched_list_polynomial_commitment<...>'. template> class lpc_commitment_scheme : public polys_evaluator(); preprocessed_data_type result; @@ -134,6 +138,7 @@ namespace nil { commitment_type commit(std::size_t index) { this->state_commited(index); + _trees[index] = nil::crypto3::zk::algorithms::precommit( this->_polys[index], _fri_params.D[0], _fri_params.step_list.front()); return _trees[index].root(); @@ -152,13 +157,135 @@ namespace nil { BOOST_ASSERT(this->_points.size() == this->_polys.size()); BOOST_ASSERT(this->_points.size() == this->_z.get_batches_num()); + // For each batch we have a merkle tree. for(auto const& it: this->_trees) { transcript(it.second.root()); } // Prepare z-s and combined_Q; auto theta = transcript.template challenge(); - polynomial_type combined_Q; + polynomial_type combined_Q = prepare_combined_Q(theta); + + auto fri_proof = commit_and_fri_proof(combined_Q, transcript); + return proof_type({this->_z, fri_proof}); + } + + /** This function must be called for the cases where we want to skip the + * round proof for FRI. Must be called once per instance of prover for the aggregated FRI. + * \param[in] combined_Q - Polynomial combined_Q was already computed by the current + prover in the previous step of the aggregated FRI protocol. + * \param[in] transcript - This transcript is initialized from a challenge sent from the "Main" prover, + on which the round proof was created for the polynomial F(x) = Sum(combined_Q). + */ + lpc_proof_type proof_eval_lpc_proof( + const polynomial_type& combined_Q, transcript_type &transcript) { + + this->eval_polys(); + + BOOST_ASSERT(this->_points.size() == this->_polys.size()); + BOOST_ASSERT(this->_points.size() == this->_z.get_batches_num()); + + // For each batch we have a merkle tree. + for (auto const& it: this->_trees) { + transcript(it.second.root()); + } + + std::vector challenges = + transcript.template challenges(this->_fri_params.lambda); + + typename fri_type::initial_proofs_batch_type initial_proofs = + nil::crypto3::zk::algorithms::query_phase_initial_proofs( + this->_trees, this->_fri_params, this->_polys, challenges); + return {this->_z, initial_proofs}; + } + + /** This function must be called once for the aggregated FRI, to proof that polynomial + 'sum_poly' has low degree. + * \param[in] sum_poly - polynomial F(x) = Sum(combined_Q). + * \param[in] transcript - This transcript is initialized on the main prover, which has digested + challenges from all the other provers. + */ + fri_proof_type proof_eval_FRI_proof(const polynomial_type& sum_poly, transcript_type &transcript) { + // TODO(martun): this function belongs to FRI, not here, will move later. + // Precommit to sum_poly. + if (sum_poly.size() != _fri_params.D[0]->size()) { + sum_poly.resize(_fri_params.D[0]->size(), nullptr, _fri_params.D[0]); + } + precommitment_type sum_poly_precommitment = nil::crypto3::zk::algorithms::precommit( + sum_poly, + _fri_params.D[0], + _fri_params.step_list.front() + ); + + std::vector fri_trees; + std::vector fs; + math::polynomial final_polynomial; + + // Contains fri_roots and final_polynomial. + typename fri_type::commitments_part_of_proof commitments_proof; + + // Commit to sum_poly. + std::tie(fs, fri_trees, commitments_proof) = + nil::crypto3::zk::algorithms::commit_phase( + sum_poly, + sum_poly_precommitment, + _fri_params, transcript); + + std::vector challenges = + transcript.template challenges(this->_fri_params.lambda); + + fri_proof_type result; + + result.fri_round_proof = nil::crypto3::zk::algorithms::query_phase_round_proofs< + fri_type, polynomial_type>( + _fri_params, + fri_trees, + fs, + sum_poly, + challenges); + + result.fri_commitments_proof_part.fri_roots = std::move(commitments_proof.fri_roots); + result.fri_commitments_proof_part.final_polynomial = std::move(final_polynomial); + + return result; + } + + typename fri_type::proof_type commit_and_fri_proof( + const polynomial_type& combined_Q, transcript_type &transcript) { + + + precommitment_type combined_Q_precommitment = nil::crypto3::zk::algorithms::precommit( + combined_Q, + _fri_params.D[0], + _fri_params.step_list.front() + ); + + typename fri_type::proof_type fri_proof = nil::crypto3::zk::algorithms::proof_eval< + fri_type, polynomial_type>( + this->_polys, + combined_Q, + this->_trees, + combined_Q_precommitment, + this->_fri_params, + transcript + ); + return fri_proof; + } + /** \brief + * \param theta The value of challenge. When called from aggregated FRI, this values is sent from + the "main prover" machine. + * \param starting_power When aggregated FRI is used, the value is not zero, it's the total degree of all + the polynomials in all the provers with indices lower than the current one. + */ + polynomial_type prepare_combined_Q( + const typename field_type::value_type& theta, + std::size_t starting_power = 0) { + typename field_type::value_type theta_acc = theta.pow(starting_power); + + polynomial_type combined_Q; + math::polynomial V; + + this->build_points_map(); auto points = this->get_unique_points(); math::polynomial combined_Q_normal; @@ -176,10 +303,8 @@ namespace nil { // each entry of 'point_batch_pairs'. std::vector theta_powers_for_each_batch; - this->build_points_map(); - - theta_powers.push_back(0); - std::size_t current_power = 0; + theta_powers.push_back(starting_power); + std::size_t current_power = starting_power; for (std::size_t point_index = 0; point_index < points.size(); ++point_index) { for(std::size_t batch_idx = 0; batch_idx < this->_z.get_batches().size(); ++batch_idx) { point_batch_pairs.push_back({point_index, batch_idx}); @@ -261,6 +386,7 @@ namespace nil { combined_Q_normal += Q_normal; } + // TODO(martun): the following code is the same as above with point = _etha, de-duplicate it. theta_powers = {theta_powers[points.size()]}; for(std::size_t i : this->_z.get_batches()) { theta_powers.push_back(theta_powers.back() + this->_z.get_batch_size(i)); @@ -293,27 +419,14 @@ namespace nil { if constexpr (std::is_same, PolynomialType>::value) { combined_Q.from_coefficients(combined_Q_normal); + if (combined_Q.size() != _fri_params.D[0]->size()) { + combined_Q.resize(_fri_params.D[0]->size(), nullptr, _fri_params.D[0]); + } } else { combined_Q = std::move(combined_Q_normal); } - precommitment_type combined_Q_precommitment = nil::crypto3::zk::algorithms::precommit( - combined_Q, - _fri_params.D[0], - _fri_params.step_list.front() - ); - - typename fri_type::proof_type fri_proof = nil::crypto3::zk::algorithms::proof_eval< - fri_type, polynomial_type - >( - this->_polys, - combined_Q, - this->_trees, - combined_Q_precommitment, - this->_fri_params, - transcript - ); - return proof_type({this->_z, fri_proof}); + return combined_Q; } bool verify_eval( @@ -502,6 +615,60 @@ namespace nil { eval_storage_type z; typename basic_fri::proof_type fri_proof; }; + + // Represents an initial proof, which must be created for each of the N provers. + struct lpc_proof_type { + bool operator==(const lpc_proof_type &rhs) const { + return initial_fri_proofs == rhs.initial_fri_proofs && z == rhs.z; + } + + bool operator!=(const lpc_proof_type &rhs) const { + return !(rhs == *this); + } + + eval_storage_type z; + typename basic_fri::initial_proofs_batch_type initial_fri_proofs; + }; + + // Represents a round proof, which must be created just once on the main prover. + struct fri_proof_type { + bool operator==(const fri_proof_type &rhs) const { + return fri_round_proof == rhs.fri_round_proof && + fri_commitments_proof_part == rhs.fri_commitments_proof_part; + } + + bool operator!=(const fri_proof_type &rhs) const { + return !(rhs == *this); + } + + // We have a single round proof for checking that F(X) is a low degree polynomial. + typename basic_fri::round_proofs_batch_type fri_round_proof; + + // Contains fri_roots and final_polynomial that correspond to the polynomial F(x). + typename basic_fri::commitments_part_of_proof fri_commitments_proof_part; + }; + + // A single instance of this class will store all the LPC proofs for a group of provers + // when aggregated FRI is used. + struct aggregated_proof_type { + bool operator==(const aggregated_proof_type &rhs) const { + return fri_proof == rhs.fri_proof && + intial_proofs_per_prover == rhs.intial_proofs_per_prover && + proof_of_work == rhs.proof_of_work; + } + + bool operator!=(const proof_type &rhs) const { + return !(rhs == *this); + } + + // We have a single round proof for checking that F(X) is a low degree polynomial. + fri_proof_type fri_proof; + + // For each prover we have an initial proof. + std::vector intial_proofs_per_prover; + + typename LPCParams::grinding_type::output_type proof_of_work; + }; }; template diff --git a/parallel-crypto3/libs/parallel-zk/include/nil/crypto3/zk/snark/arithmetization/plonk/assignment.hpp b/parallel-crypto3/libs/parallel-zk/include/nil/crypto3/zk/snark/arithmetization/plonk/assignment.hpp index 435686ae77..287ef0bede 100644 --- a/parallel-crypto3/libs/parallel-zk/include/nil/crypto3/zk/snark/arithmetization/plonk/assignment.hpp +++ b/parallel-crypto3/libs/parallel-zk/include/nil/crypto3/zk/snark/arithmetization/plonk/assignment.hpp @@ -39,6 +39,7 @@ namespace nil { template class assignment; } // namespace blueprint + namespace crypto3 { namespace zk { namespace snark { @@ -55,6 +56,7 @@ namespace nil { template class plonk_private_table { public: + using column_type = ColumnType; using witnesses_container_type = std::vector; using VariableType = plonk_variable; @@ -99,6 +101,7 @@ namespace nil { abort(); } } + ColumnType get_variable_value(const VariableType& var, std::shared_ptr> domain) const { if (var.rotation == 0) { return get_variable_value_without_rotation(var); @@ -149,6 +152,7 @@ namespace nil { template class plonk_public_table { public: + using column_type = ColumnType; using public_input_container_type = std::vector; using constant_container_type = std::vector; using selector_container_type = std::vector; @@ -337,15 +341,16 @@ namespace nil { , _public_table(public_inputs_amount, constants_amount, selectors_amount) { } - const ColumnType& get_variable_value_without_rotation(const VariableType& var) const { + template + const ColumnType& get_variable_value_without_rotation(const InputVariableType& var) const { switch (var.type) { - case VariableType::column_type::witness: + case InputVariableType::column_type::witness: return witness(var.index); - case VariableType::column_type::public_input: + case InputVariableType::column_type::public_input: return public_input(var.index); - case VariableType::column_type::constant: + case InputVariableType::column_type::constant: return constant(var.index); - case VariableType::column_type::selector: + case InputVariableType::column_type::selector: return selector(var.index); default: std::cerr << "Invalid column type" << std::endl; diff --git a/parallel-crypto3/libs/parallel-zk/include/nil/crypto3/zk/snark/arithmetization/plonk/constraint.hpp b/parallel-crypto3/libs/parallel-zk/include/nil/crypto3/zk/snark/arithmetization/plonk/constraint.hpp index a8eb452354..63df5e2e11 100644 --- a/parallel-crypto3/libs/parallel-zk/include/nil/crypto3/zk/snark/arithmetization/plonk/constraint.hpp +++ b/parallel-crypto3/libs/parallel-zk/include/nil/crypto3/zk/snark/arithmetization/plonk/constraint.hpp @@ -109,9 +109,8 @@ namespace nil { } math::polynomial - evaluate(const plonk_polynomial_table &assignments, - std::shared_ptr> domain) const { - + evaluate(const plonk_polynomial_table &assignments, + std::shared_ptr> domain) const { using polynomial_type = math::polynomial; using polynomial_variable_type = plonk_variable; diff --git a/parallel-crypto3/libs/parallel-zk/include/nil/crypto3/zk/snark/arithmetization/plonk/lookup_table_definition.hpp b/parallel-crypto3/libs/parallel-zk/include/nil/crypto3/zk/snark/arithmetization/plonk/lookup_table_definition.hpp index 4551fb421e..101a9b4ca8 100644 --- a/parallel-crypto3/libs/parallel-zk/include/nil/crypto3/zk/snark/arithmetization/plonk/lookup_table_definition.hpp +++ b/parallel-crypto3/libs/parallel-zk/include/nil/crypto3/zk/snark/arithmetization/plonk/lookup_table_definition.hpp @@ -68,6 +68,27 @@ namespace nil { virtual ~lookup_table_definition() {}; }; + template + class dynamic_table_definition { + protected: + bool defined; + public: + plonk_lookup_table lookup_table; + std::string name; + + dynamic_table_definition(std::string _name): name(_name), defined(false) {} + + void define(const plonk_lookup_table &table){ + BOOST_ASSERT(!defined); + lookup_table = table; + defined = true; + } + bool is_defined(){ + return defined; + } + virtual ~dynamic_table_definition() {}; + }; + template std::vector get_tables_ordered_by_rows_number(const std::map>> &tables){ @@ -107,6 +128,7 @@ namespace nil { std::size_t pack_lookup_tables( const TableIdsMapType &lookup_table_ids, const std::map>> &lookup_tables, + const std::map>> &dynamic_tables, plonk_constraint_system &bp, plonk_assignment_table &assignment, const std::vector &constant_columns_ids, @@ -176,6 +198,10 @@ namespace nil { } start_row += table->get_rows_number(); } + for( const auto&[k, table]:dynamic_tables ){ + BOOST_ASSERT(table->is_defined()); + bp_lookup_tables[lookup_table_ids.at(k) - 1] = table->lookup_table; + } for(std::size_t i = 0; i < bp_lookup_tables.size(); i++){ bp.add_lookup_table(std::move(bp_lookup_tables[i])); } @@ -190,6 +216,7 @@ namespace nil { std::size_t pack_lookup_tables_horizontal( const LookupTableIds &lookup_table_ids, const std::map>> &lookup_tables, + const std::map>> &dynamic_tables, plonk_constraint_system &bp, plonk_assignment_table &assignment, const std::vector &constant_columns_ids, @@ -330,6 +357,10 @@ namespace nil { } start_row += table->get_rows_number(); } + for( const auto&[k, table]:dynamic_tables ){ + BOOST_ASSERT(table->is_defined()); + bp_lookup_tables[lookup_table_ids.at(k) - 1] = table->lookup_table; + } for(std::size_t i = 0; i < bp_lookup_tables.size(); i++){ bp.add_lookup_table(std::move(bp_lookup_tables[i])); } diff --git a/parallel-crypto3/libs/parallel-zk/include/nil/crypto3/zk/snark/systems/plonk/placeholder/detail/transcript_initialization_context.hpp b/parallel-crypto3/libs/parallel-zk/include/nil/crypto3/zk/snark/systems/plonk/placeholder/detail/transcript_initialization_context.hpp index db7e6cd2c1..98cc6d9414 100644 --- a/parallel-crypto3/libs/parallel-zk/include/nil/crypto3/zk/snark/systems/plonk/placeholder/detail/transcript_initialization_context.hpp +++ b/parallel-crypto3/libs/parallel-zk/include/nil/crypto3/zk/snark/systems/plonk/placeholder/detail/transcript_initialization_context.hpp @@ -124,7 +124,7 @@ namespace nil { std::vector cv(filled_context.length(), 0x00); auto write_iter = cv.begin(); nil::marshalling::status_type status = filled_context.write(write_iter, cv.size()); - BOOST_ASSERT(status == nil::marshalling::status_type::success); + THROW_IF_ERROR_STATUS(status, "transcript_initialization_context::compute_constraint_system_with_params_hash"); // Append constraint_system to the buffer "cv". using FieldType = typename PlaceholderParamsType::field_type; diff --git a/parallel-crypto3/libs/parallel-zk/include/nil/crypto3/zk/snark/systems/plonk/placeholder/gates_argument.hpp b/parallel-crypto3/libs/parallel-zk/include/nil/crypto3/zk/snark/systems/plonk/placeholder/gates_argument.hpp index a7555f869f..09bbc12b08 100644 --- a/parallel-crypto3/libs/parallel-zk/include/nil/crypto3/zk/snark/systems/plonk/placeholder/gates_argument.hpp +++ b/parallel-crypto3/libs/parallel-zk/include/nil/crypto3/zk/snark/systems/plonk/placeholder/gates_argument.hpp @@ -52,6 +52,8 @@ #include #include +#include + #include #include @@ -132,7 +134,7 @@ namespace nil { std::uint32_t max_gates_degree, const polynomial_dfs_type &mask_polynomial, transcript_type& transcript) { - PROFILE_PLACEHOLDER_SCOPE("Gate Argument prove_eval"); + PROFILE_SCOPE("gate_argument_time"); // max_gates_degree that comes from the outside does not take into account multiplication // by selector. @@ -187,7 +189,8 @@ namespace nil { auto selector = variable_type( gate.selector_index, 0, false, variable_type::column_type::selector); for (size_t i = 0; i < extended_domain_sizes.size(); ++i) { - expressions[i] += gate_results[i] * selector; + gate_results[i] *= selector; + expressions[i] += gate_results[i]; } } diff --git a/parallel-crypto3/libs/parallel-zk/include/nil/crypto3/zk/snark/systems/plonk/placeholder/permutation_argument.hpp b/parallel-crypto3/libs/parallel-zk/include/nil/crypto3/zk/snark/systems/plonk/placeholder/permutation_argument.hpp index 328c9375e5..ad75babf55 100644 --- a/parallel-crypto3/libs/parallel-zk/include/nil/crypto3/zk/snark/systems/plonk/placeholder/permutation_argument.hpp +++ b/parallel-crypto3/libs/parallel-zk/include/nil/crypto3/zk/snark/systems/plonk/placeholder/permutation_argument.hpp @@ -42,9 +42,10 @@ #include #include #include -#include #include +#include + #include #include @@ -79,7 +80,7 @@ namespace nil { typename ParamsType::commitment_scheme_type& commitment_scheme, transcript_type& transcript ) { - PROFILE_PLACEHOLDER_SCOPE("Permutation Argument prove_eval Time"); + PROFILE_SCOPE("permutation_argument_prove_eval_time"); const std::vector> &S_sigma = preprocessed_data.permutation_polynomials; @@ -125,7 +126,7 @@ namespace nil { }, ThreadPool::PoolLevel::HIGH); V_P[0] = FieldType::value_type::one(); - + auto V_P_parts = std::make_unique>( basic_domain->size(), FieldType::value_type::zero()); parallel_for(1, basic_domain->size(), [&g_v, &h_v, &S_id, &V_P_parts](std::size_t j) { @@ -138,7 +139,7 @@ namespace nil { } (*V_P_parts)[j] = nom * denom.inversed(); }, ThreadPool::PoolLevel::LOW); - + for (std::size_t j = 1; j < basic_domain->size(); ++j) V_P[j] = V_P[j - 1] * (*V_P_parts)[j]; V_P_parts.reset(nullptr); @@ -201,7 +202,7 @@ namespace nil { F_dfs[1] -= preprocessed_data.q_blind; F_dfs[1] *= V_P_shifted; } else { - PROFILE_PLACEHOLDER_SCOPE("PERMUTATION ARGUMENT else block"); + PROFILE_SCOPE("PERMUTATION ARGUMENT else block"); math::polynomial_dfs previous_poly = V_P; math::polynomial_dfs current_poly = V_P; // We need to store all the values of current_poly. Suddenly this increases the RAM usage, but @@ -213,6 +214,7 @@ namespace nil { const auto& h = hs[i]; auto reduced_g = reduce_dfs_polynomial_domain(g, basic_domain->m); auto reduced_h = reduce_dfs_polynomial_domain(h, basic_domain->m); + parallel_for(0, preprocessed_data.common_data.desc.usable_rows_amount, [&reduced_g, &reduced_h, ¤t_poly, &previous_poly](std::size_t j) { current_poly[j] = (previous_poly[j] * reduced_g[j]) * reduced_h[j].inversed(); diff --git a/parallel-crypto3/libs/parallel-zk/include/nil/crypto3/zk/snark/systems/plonk/placeholder/preprocessor.hpp b/parallel-crypto3/libs/parallel-zk/include/nil/crypto3/zk/snark/systems/plonk/placeholder/preprocessor.hpp index f2c4e59013..fd66fb36dc 100644 --- a/parallel-crypto3/libs/parallel-zk/include/nil/crypto3/zk/snark/systems/plonk/placeholder/preprocessor.hpp +++ b/parallel-crypto3/libs/parallel-zk/include/nil/crypto3/zk/snark/systems/plonk/placeholder/preprocessor.hpp @@ -43,7 +43,6 @@ #include #include #include -#include #include #include #include @@ -52,6 +51,8 @@ #include #include +#include + namespace nil { namespace crypto3 { namespace zk { @@ -64,10 +65,11 @@ namespace nil { template class placeholder_public_preprocessor { - typedef detail::placeholder_policy policy_type; - typedef typename plonk_constraint::variable_type variable_type; - typedef typename math::polynomial polynomial_type; - typedef typename math::polynomial_dfs polynomial_dfs_type; + using policy_type = detail::placeholder_policy; + using variable_type = typename plonk_constraint::variable_type; + using value_type = typename FieldType::value_type; + using polynomial_type = typename math::polynomial; + using polynomial_dfs_type = typename math::polynomial_dfs; using params_type = ParamsType; using commitment_scheme_type = typename params_type::commitment_scheme_type; using commitment_type = typename commitment_scheme_type::commitment_type; @@ -78,15 +80,21 @@ namespace nil { static std::size_t permutation_partitions_num( std::size_t permutation_size, std::size_t max_quotient_chunks - ){ - if( permutation_size == 0 ) return 0; - if( max_quotient_chunks == 0 ){ + ) { + if (permutation_size == 0) return 0; + if (max_quotient_chunks == 0) { return 1; } - return (permutation_size % (max_quotient_chunks - 1) == 0)? permutation_size / (max_quotient_chunks - 1) : permutation_size / (max_quotient_chunks - 1) + 1; + return (permutation_size % (max_quotient_chunks - 1) == 0) ? + permutation_size / (max_quotient_chunks - 1) : + permutation_size / (max_quotient_chunks - 1) + 1; } struct preprocessed_data_type { + // Used in marshalling. + using plonk_public_polynomial_dfs_table_type = plonk_public_polynomial_dfs_table; + using polynomial_dfs_type = typename math::polynomial_dfs; + struct public_commitments_type { commitment_type fixed_values; @@ -154,6 +162,8 @@ namespace nil { std::uint32_t permutation_parts; std::uint32_t lookup_parts; + common_data_type(const common_data_type& other) = default; + // Constructor with pregenerated domain common_data_type( std::shared_ptr> D, @@ -252,17 +262,30 @@ namespace nil { } }; - plonk_public_polynomial_dfs_table public_polynomial_table; + bool operator==(const preprocessed_data_type &rhs) const { + return public_polynomial_table == rhs.public_polynomial_table && + permutation_polynomials == rhs.permutation_polynomials && + identity_polynomials == rhs.identity_polynomials && + q_last == rhs.q_last && + q_blind == rhs.q_blind && + common_data == rhs.common_data; + } + + bool operator!=(const preprocessed_data_type &rhs) const { + return !(rhs == *this); + } + + plonk_public_polynomial_dfs_table_type public_polynomial_table; // S_sigma std::vector permutation_polynomials; // S_id std::vector identity_polynomials; - polynomial_dfs_type q_last; - polynomial_dfs_type q_blind; + polynomial_dfs_type q_last; + polynomial_dfs_type q_blind; - common_data_type common_data; + common_data_type common_data; }; private: @@ -366,6 +389,7 @@ namespace nil { const plonk_constraint_system &constraint_system, const plonk_table_description &table_description ) { + using var = plonk_variable; std::vector> result(table_description.table_width()); for (auto & s : result) { @@ -402,11 +426,23 @@ namespace nil { ].insert(1); for( const auto &option:table.lookup_options){ for( const auto &column:option){ - result[ - table_description.witness_columns + - table_description.public_input_columns + - column.index - ].insert(1); + switch( column.type ){ + case var::column_type::witness: + result[column.index].insert(1); + break; + case var::column_type::public_input: + result[ table_description.witness_columns + column.index].insert(1); + break; + case var::column_type::constant: + result[ table_description.witness_columns + table_description.public_input_columns + column.index ].insert(1); + break; + case var::column_type::selector: + result[ table_description.witness_columns + table_description.public_input_columns + table_description.constant_columns + column.index].insert(1); + break; + case var::column_type::uninitialized: + break; + } + } } } @@ -485,7 +521,8 @@ namespace nil { commitment_scheme.append_to_batch(FIXED_VALUES_BATCH, public_table.constants()); commitment_scheme.append_to_batch(FIXED_VALUES_BATCH, public_table.selectors()); - auto result = typename preprocessed_data_type::public_commitments_type({commitment_scheme.commit(FIXED_VALUES_BATCH)}); + typename preprocessed_data_type::public_commitments_type result( + {commitment_scheme.commit(FIXED_VALUES_BATCH)}); commitment_scheme.mark_batch_as_fixed(FIXED_VALUES_BATCH); return result; } @@ -504,7 +541,7 @@ namespace nil { const std::size_t max_quotient_poly_chunks = 0, const typename FieldType::value_type& delta=algebra::fields::arithmetic_params::multiplicative_generator ) { - PROFILE_PLACEHOLDER_SCOPE("Placeholder public preprocessor"); + PROFILE_SCOPE("Placeholder public preprocessor"); std::size_t N_rows = table_description.rows_amount; std::size_t usable_rows = table_description.usable_rows_amount; diff --git a/parallel-crypto3/libs/parallel-zk/include/nil/crypto3/zk/snark/systems/plonk/placeholder/proof.hpp b/parallel-crypto3/libs/parallel-zk/include/nil/crypto3/zk/snark/systems/plonk/placeholder/proof.hpp index 8c57cb86fa..c5cd9b9d35 100644 --- a/parallel-crypto3/libs/parallel-zk/include/nil/crypto3/zk/snark/systems/plonk/placeholder/proof.hpp +++ b/parallel-crypto3/libs/parallel-zk/include/nil/crypto3/zk/snark/systems/plonk/placeholder/proof.hpp @@ -40,6 +40,33 @@ namespace nil { constexpr std::size_t QUOTIENT_BATCH = 3; constexpr std::size_t LOOKUP_BATCH = 4; + // A part of the placeholder_proof. Used for proofs with aggregated FRI. + template + struct placeholder_partial_proof { + static constexpr std::size_t FIXED_VALUES_BATCH = 0; + static constexpr std::size_t VARIABLE_VALUES_BATCH = 1; + static constexpr std::size_t PERMUTATION_BATCH = 2; + static constexpr std::size_t QUOTIENT_BATCH = 3; + static constexpr std::size_t LOOKUP_BATCH = 4; + + typedef FieldType field_type; + typedef ParamsType params_type; + + using commitment_scheme_type = typename ParamsType::commitment_scheme_type; + using commitment_type = typename commitment_scheme_type::commitment_type; + + placeholder_partial_proof() = default; + + bool operator==(const placeholder_partial_proof &rhs) const { + return commitments == rhs.commitments; + } + bool operator!=(const placeholder_partial_proof &rhs) const { + return !(rhs == *this); + } + + std::map commitments; + }; + /** * A proof for the Placeholder scheme. * @@ -48,10 +75,10 @@ namespace nil { * about the structure for marshalling purposes. */ template - struct placeholder_proof { + struct placeholder_proof : public placeholder_partial_proof { static constexpr std::size_t FIXED_VALUES_BATCH = 0; static constexpr std::size_t VARIABLE_VALUES_BATCH = 1; - static constexpr std::size_t PERMUTATION_BATCH =2; + static constexpr std::size_t PERMUTATION_BATCH = 2; static constexpr std::size_t QUOTIENT_BATCH = 3; static constexpr std::size_t LOOKUP_BATCH = 4; @@ -76,20 +103,45 @@ namespace nil { } }; - placeholder_proof() { - } - - std::map commitments; - evaluation_proof eval_proof; + placeholder_proof() = default; bool operator==(const placeholder_proof &rhs) const { - return - commitments == rhs.commitments && + return placeholder_partial_proof::operator==(rhs) && eval_proof == rhs.eval_proof; } bool operator!=(const placeholder_proof &rhs) const { return !(rhs == *this); } + + evaluation_proof eval_proof; + }; + + /** + * An aggregated proof for the Placeholder scheme. It contains N partial proofs from N provers, with a shared + * aggregated FRI proof. + */ + template + struct placeholder_aggregated_proof { + typedef FieldType field_type; + typedef ParamsType params_type; + + using circuit_params_type = typename ParamsType::circuit_params_type; + using commitment_scheme_type = typename ParamsType::commitment_scheme_type; + using commitment_type = typename commitment_scheme_type::commitment_type; + + placeholder_aggregated_proof() = default; + + bool operator==(const placeholder_aggregated_proof &rhs) const { + return partial_proofs == rhs.partial_proofs && + aggregated_proof == rhs.aggregated_proof; + } + bool operator!=(const placeholder_aggregated_proof &rhs) const { + return !(rhs == *this); + } + + // This vector contains N partial proofs, one per prover. + std::vector> partial_proofs; + typename commitment_type::aggregated_proof_type aggregated_proof; }; } // namespace snark } // namespace zk diff --git a/parallel-crypto3/libs/parallel-zk/include/nil/crypto3/zk/snark/systems/plonk/placeholder/prover.hpp b/parallel-crypto3/libs/parallel-zk/include/nil/crypto3/zk/snark/systems/plonk/placeholder/prover.hpp index e93497273c..d70f066384 100644 --- a/parallel-crypto3/libs/parallel-zk/include/nil/crypto3/zk/snark/systems/plonk/placeholder/prover.hpp +++ b/parallel-crypto3/libs/parallel-zk/include/nil/crypto3/zk/snark/systems/plonk/placeholder/prover.hpp @@ -40,13 +40,14 @@ #include #include #include -#include #include #include #include #include #include +#include + namespace nil { namespace crypto3 { namespace zk { @@ -56,7 +57,7 @@ namespace nil { static inline std::vector> split_polynomial(const math::polynomial &f, std::size_t max_degree) { - PROFILE_PLACEHOLDER_SCOPE("split_polynomial_time"); + PROFILE_SCOPE("split_polynomial_time"); std::vector> f_splitted; @@ -96,11 +97,12 @@ namespace nil { typename private_preprocessor_type::preprocessed_data_type preprocessed_private_data, const plonk_table_description &table_description, const plonk_constraint_system &constraint_system, - commitment_scheme_type commitment_scheme + commitment_scheme_type commitment_scheme, + bool skip_commitment_scheme_eval_proofs = false ) { auto prover = placeholder_prover( preprocessed_public_data, std::move(preprocessed_private_data), table_description, - constraint_system, commitment_scheme); + constraint_system, commitment_scheme, skip_commitment_scheme_eval_proofs); return prover.process(); } @@ -109,7 +111,8 @@ namespace nil { typename private_preprocessor_type::preprocessed_data_type preprocessed_private_data, const plonk_table_description &table_description, const plonk_constraint_system &constraint_system, - const commitment_scheme_type &commitment_scheme + const commitment_scheme_type &commitment_scheme, + bool skip_commitment_scheme_eval_proofs = false ) : preprocessed_public_data(preprocessed_public_data) , table_description(table_description) @@ -121,8 +124,8 @@ namespace nil { , transcript(std::vector({})) , _is_lookup_enabled(constraint_system.lookup_gates().size() > 0) , _commitment_scheme(commitment_scheme) + , _skip_commitment_scheme_eval_proofs(skip_commitment_scheme_eval_proofs) { - // Initialize transcript. transcript(preprocessed_public_data.common_data.vk.constraint_system_with_params_hash); transcript(preprocessed_public_data.common_data.vk.fixed_values_commitment); @@ -132,12 +135,15 @@ namespace nil { } placeholder_proof process() { - PROFILE_PLACEHOLDER_SCOPE("Placeholder prover, total time"); + PROFILE_SCOPE("Placeholder prover, total time"); // 2. Commit witness columns and public_input columns _commitment_scheme.append_to_batch(VARIABLE_VALUES_BATCH, _polynomial_table->witnesses()); _commitment_scheme.append_to_batch(VARIABLE_VALUES_BATCH, _polynomial_table->public_inputs()); - _proof.commitments[VARIABLE_VALUES_BATCH] = _commitment_scheme.commit(VARIABLE_VALUES_BATCH); + { + PROFILE_SCOPE("variable_values_precommit_time"); + _proof.commitments[VARIABLE_VALUES_BATCH] = _commitment_scheme.commit(VARIABLE_VALUES_BATCH); + } transcript(_proof.commitments[VARIABLE_VALUES_BATCH]); // 4. permutation_argument @@ -202,12 +208,11 @@ namespace nil { transcript(_proof.commitments[QUOTIENT_BATCH]); // 8. Run evaluation proofs - _proof.eval_proof.challenge = transcript.template challenge(); + if (!_skip_commitment_scheme_eval_proofs) { + // 8. Run evaluation proofs + _proof.eval_proof.challenge = transcript.template challenge(); + generate_evaluation_points(); - generate_evaluation_points(); - - { - PROFILE_PLACEHOLDER_SCOPE("commitment scheme proof eval time"); _proof.eval_proof.eval_proof = _commitment_scheme.proof_eval(transcript); } @@ -216,7 +221,7 @@ namespace nil { private: std::vector quotient_polynomial_split_dfs() { - PROFILE_PLACEHOLDER_SCOPE("quotient_polynomial_split_dfs"); + PROFILE_SCOPE("quotient_polynomial_split_dfs"); // TODO: pass max_degree parameter placeholder std::vector T_splitted = detail::split_polynomial( @@ -260,7 +265,7 @@ namespace nil { } polynomial_type quotient_polynomial() { - PROFILE_PLACEHOLDER_SCOPE("Quotient polynomial time"); + PROFILE_SCOPE("quotient_polynomial_time"); // 7.1. Get $\alpha_0, \dots, \alpha_8 \in \mathbb{F}$ from $hash(\text{transcript})$ std::array alphas = @@ -288,8 +293,8 @@ namespace nil { } typename placeholder_lookup_argument_prover::prover_lookup_result - lookup_argument() { - PROFILE_PLACEHOLDER_SCOPE("Lookup argument time"); + lookup_argument() { + PROFILE_SCOPE("lookup_argument_time"); typename placeholder_lookup_argument_prover< FieldType, @@ -317,7 +322,7 @@ namespace nil { } commitment_type T_commit(const std::vector& T_splitted_dfs) { - PROFILE_PLACEHOLDER_SCOPE("T_splitted precommit time"); + PROFILE_SCOPE("T_split_precommit_time"); _commitment_scheme.append_to_batch(QUOTIENT_BATCH, T_splitted_dfs); return _commitment_scheme.commit(QUOTIENT_BATCH); } @@ -349,7 +354,7 @@ namespace nil { } void generate_evaluation_points() { - PROFILE_PLACEHOLDER_SCOPE("Evaluation points generation time"); + PROFILE_SCOPE("evaluation_points_generated_time"); _omega = preprocessed_public_data.common_data.basic_domain->get_domain_element(1); const std::size_t witness_columns = table_description.witness_columns; @@ -373,15 +378,16 @@ namespace nil { } } - if(_is_lookup_enabled||constraint_system.copy_constraints().size() > 0){ + if (_is_lookup_enabled||constraint_system.copy_constraints().size() > 0) { _commitment_scheme.append_eval_point(PERMUTATION_BATCH, _proof.eval_proof.challenge); } - if( constraint_system.copy_constraints().size() > 0 ) + if (constraint_system.copy_constraints().size() > 0) _commitment_scheme.append_eval_point(PERMUTATION_BATCH, 0, _proof.eval_proof.challenge * _omega); - if(_is_lookup_enabled){ - _commitment_scheme.append_eval_point(PERMUTATION_BATCH, preprocessed_public_data.common_data.permutation_parts , _proof.eval_proof.challenge * _omega); + if (_is_lookup_enabled) { + _commitment_scheme.append_eval_point(PERMUTATION_BATCH, preprocessed_public_data.common_data.permutation_parts, + _proof.eval_proof.challenge * _omega); _commitment_scheme.append_eval_point(LOOKUP_BATCH, _proof.eval_proof.challenge); _commitment_scheme.append_eval_point(LOOKUP_BATCH, _proof.eval_proof.challenge * _omega); _commitment_scheme.append_eval_point(LOOKUP_BATCH, _proof.eval_proof.challenge * @@ -396,7 +402,7 @@ namespace nil { std::size_t start_index = preprocessed_public_data.identity_polynomials.size() + preprocessed_public_data.permutation_polynomials.size() + 2; - for( i = 0; i < start_index; i++){ + for (i = 0; i < start_index; i++) { _commitment_scheme.append_eval_point(FIXED_VALUES_BATCH, i, _proof.eval_proof.challenge); } @@ -482,6 +488,7 @@ namespace nil { typename FieldType::value_type _omega; std::vector _challenge_point; commitment_scheme_type _commitment_scheme; + bool _skip_commitment_scheme_eval_proofs; }; } // namespace snark } // namespace zk diff --git a/parallel-crypto3/libs/parallel-zk/include/nil/crypto3/zk/transcript/fiat_shamir.hpp b/parallel-crypto3/libs/parallel-zk/include/nil/crypto3/zk/transcript/fiat_shamir.hpp index 8f8ce1be04..92da6d01a1 100644 --- a/parallel-crypto3/libs/parallel-zk/include/nil/crypto3/zk/transcript/fiat_shamir.hpp +++ b/parallel-crypto3/libs/parallel-zk/include/nil/crypto3/zk/transcript/fiat_shamir.hpp @@ -230,6 +230,17 @@ namespace nil { return result; } + template + std::vector challenges(std::size_t N) { + + std::vector result; + for (std::size_t i = 0; i < N; ++i) { + result.push_back(challenge()); + } + + return result; + } + private: typename hash_type::digest_type state; }; @@ -341,6 +352,17 @@ namespace nil { return result; } + template + std::vector challenges(std::size_t N) { + + std::vector result; + for (std::size_t i = 0; i < N; ++i) { + result.push_back(challenge()); + } + + return result; + } + public: hashes::detail::poseidon_sponge_construction_custom sponge; }; diff --git a/parallel-crypto3/libs/parallel-zk/test/commitment/fri.cpp b/parallel-crypto3/libs/parallel-zk/test/commitment/fri.cpp index a6064750d6..776b3b4c58 100644 --- a/parallel-crypto3/libs/parallel-zk/test/commitment/fri.cpp +++ b/parallel-crypto3/libs/parallel-zk/test/commitment/fri.cpp @@ -130,6 +130,9 @@ void fri_basic_test() if constexpr (std::is_same, PolynomialType>::value) { f.from_coefficients(coefficients); + if (f.size() != params.D[0]->size()) { + f.resize(params.D[0]->size(), nullptr, params.D[0]); + } } else { f = PolynomialType(coefficients); }