From 4f1cb82625b19c0dc7e377798614ce95f89e8e4f Mon Sep 17 00:00:00 2001 From: Martun Karapetyan Date: Wed, 11 Sep 2024 11:48:41 +0400 Subject: [PATCH 1/3] Creating structures for aggregated FRI. --- .../detail/polynomial/basic_fri.hpp | 212 +++++++++++++++--- .../crypto3/zk/commitments/polynomial/lpc.hpp | 69 ++++-- .../snark/systems/plonk/placeholder/proof.hpp | 2 +- .../systems/plonk/placeholder/prover.hpp | 26 ++- 4 files changed, 239 insertions(+), 70 deletions(-) diff --git a/libs/zk/include/nil/crypto3/zk/commitments/detail/polynomial/basic_fri.hpp b/libs/zk/include/nil/crypto3/zk/commitments/detail/polynomial/basic_fri.hpp index cdf02d4d9..76f762754 100644 --- a/libs/zk/include/nil/crypto3/zk/commitments/detail/polynomial/basic_fri.hpp +++ b/libs/zk/include/nil/crypto3/zk/commitments/detail/polynomial/basic_fri.hpp @@ -268,7 +268,55 @@ namespace nil { std::vector round_proofs; }; + struct round_proofs_batch { + bool operator==(const round_proofs_batch &rhs) const { + return fri_roots == rhs.fri_roots && + round_proofs == rhs.round_proofs && + final_polynomial == rhs.final_polynomial; + } + + bool operator!=(const round_proofs_batch &rhs) const { + return !(rhs == *this); + } + + std::vector fri_roots; // 0,..step_list.size() + std::vector> round_proofs; // 0...lambda - 1 + math::polynomial final_polynomial; + }; + + struct initial_proofs_batch { + initial_proofs_batch() = default; + + // Just pre-allocate the vector for a given size. + initial_proofs_batch(std::size_t lambda) + : initial_proofs(lambda) { + } + + bool operator==(const initial_proofs_batch &rhs) const { + return initial_proofs == rhs.initial_proofs; + } + + bool operator!=(const initial_proofs_batch &rhs) const { + return !(rhs == *this); + } + + std::vector> initial_proofs; // 0...lambda - 1 + }; + struct proof_type { + proof_type() = default; + proof_type(const proof_type&) = default; + + proof_type(const round_proofs_batch& round_proofs, + const initial_proofs_batch& 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 ){ @@ -288,6 +336,40 @@ namespace nil { std::vector query_proofs; // 0...lambda - 1 typename GrindingType::output_type proof_of_work; }; + + // This represents and aggregated proofs of N provers with shared initial proof. + struct aggregated_proof { + aggregated_proof() = default; + aggregated_proof(const aggregated_proof&) = default; + + // Size of vector 'round_proofs_per_prover' is the number of provers. + aggregated_proof( + const std::vector& round_proofs_per_prover, + const initial_proofs_batch& intial_proofs) + : round_proofs_per_prover(round_proofs_per_prover) + , intial_proofs(intial_proofs) { + } + + bool operator==(const aggregated_proof &rhs) const { + //if (FRI::use_grinding && proof_of_work != rhs.proof_of_work) { + // return false; + //} + return round_proofs_per_prover == rhs.round_proofs_per_prover && + intial_proofs == rhs.intial_proofs; + } + + bool operator!=(const aggregated_proof &rhs) const { + return !(rhs == *this); + } + + // For each prover we have a rounds proof partial FRI proof for consistency checks. + std::vector round_proofs_per_prover; + + // We have a single intial proof for checking that F(X) is a low degree polynomial. + initial_proofs_batch intial_proofs; + + typename GrindingType::output_type proof_of_work; + }; }; } // namespace detail } // namespace commitments @@ -665,7 +747,6 @@ namespace nil { > 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) @@ -840,11 +921,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, @@ -915,18 +991,44 @@ namespace nil { template - static std::vector - query_phase( - const std::map &precommitments, + static typename FRI::round_proofs_batch query_phase_round_proofs_with_challenges( 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 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[query_id] = std::move(round_proofs); + } + return proof; + } + + template + static typename FRI::initial_proofs_batch query_phase_initial_proofs_with_challenges( + const std::map &precommitments, + const typename FRI::params_type &fri_params, + const std::map> &g, + const std::vector& challenges) + { + typename FRI::initial_proofs_batch proof(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. @@ -937,8 +1039,8 @@ namespace nil { 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 = transcript.template challenge(); - x = x.pow((FRI::field_type::modulus - 1)/domain_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; @@ -946,34 +1048,76 @@ namespace nil { ++x_index; } - // Initial proof std::map initial_proof = build_initial_proof( precommitments, fri_params, g, g_coeffs, x_index); - // Fill round proofs - std::vector - round_proofs = build_round_proofs( - fri_params, g, g_coeffs, fri_trees, fs, final_polynomial, x_index); + proof.initial_proofs.emplace_back(std::move(initial_proof)); + } + 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); + 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 initial_proofs = + query_phase_initial_proofs_with_challenges( + precommitments, fri_params, g, challenges); + + typename FRI::round_proofs_batch round_proofs = + query_phase_round_proofs_with_challenges( + 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); + + 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; + } - return std::move(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; + for (std::size_t query_id = 0; query_id < fri_params.lambda; query_id++) { + typename FRI::field_type::value_type x = transcript.template challenge(); + challenges.push_back(x); + } + 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, @@ -997,13 +1141,13 @@ namespace nil { math::polynomial final_polynomial; std::tie(fs, fri_trees, fri_roots, final_polynomial) = - commit_phase( - combined_Q, precommitments, + 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); } diff --git a/libs/zk/include/nil/crypto3/zk/commitments/polynomial/lpc.hpp b/libs/zk/include/nil/crypto3/zk/commitments/polynomial/lpc.hpp index 8b5b695d9..1a6a80f5a 100644 --- a/libs/zk/include/nil/crypto3/zk/commitments/polynomial/lpc.hpp +++ b/libs/zk/include/nil/crypto3/zk/commitments/polynomial/lpc.hpp @@ -110,7 +110,7 @@ namespace nil { : _fri_params(fri_params), _etha(0u) { } - preprocessed_data_type preprocess(transcript_type& transcript) const{ + preprocessed_data_type preprocess(transcript_type& transcript) const { auto etha = transcript.template challenge(); preprocessed_data_type result; @@ -149,24 +149,61 @@ namespace nil { BOOST_ASSERT(this->_points.size() == this->_polys.size()); BOOST_ASSERT(this->_points.size() == this->_z.get_batches_num()); - for(auto const& it: this->_trees) { + // 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(); - typename field_type::value_type theta_acc = field_type::value_type::one(); + polynomial_type combined_Q = prepare_combined_Q(theta); + + auto fri_proof = commit_and_fri_proof(combined_Q); + return proof_type({this->_z, fri_proof}); + } + + typename fri_type::proof_type commit_and_fri_proof(const polynomial_type& combined_Q) { + + 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; auto points = this->get_unique_points(); math::polynomial combined_Q_normal; - for (auto const &point: points){ + for (auto const &point: points) { V = {-point, 1u}; math::polynomial Q_normal; - for(std::size_t i: this->_z.get_batches()){ - for(std::size_t j = 0; j < this->_z.get_batch_size(i); j++){ + for (std::size_t i: this->_z.get_batches()) { + for (std::size_t j = 0; j < this->_z.get_batch_size(i); j++) { auto it = std::find(this->_points[i][j].begin(), this->_points[i][j].end(), point); if( it == this->_points[i][j].end()) continue; math::polynomial g_normal; @@ -185,6 +222,7 @@ namespace nil { combined_Q_normal += Q_normal; } + // TODO(martun): the following code is the same as above with point = _etha, de-duplicate it. for (std::size_t i: this->_z.get_batches()) { if (!_batch_fixed[i]) continue; @@ -215,24 +253,7 @@ namespace nil { } 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( diff --git a/libs/zk/include/nil/crypto3/zk/snark/systems/plonk/placeholder/proof.hpp b/libs/zk/include/nil/crypto3/zk/snark/systems/plonk/placeholder/proof.hpp index 8c57cb86f..aa76cd045 100644 --- a/libs/zk/include/nil/crypto3/zk/snark/systems/plonk/placeholder/proof.hpp +++ b/libs/zk/include/nil/crypto3/zk/snark/systems/plonk/placeholder/proof.hpp @@ -51,7 +51,7 @@ namespace nil { struct placeholder_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; diff --git a/libs/zk/include/nil/crypto3/zk/snark/systems/plonk/placeholder/prover.hpp b/libs/zk/include/nil/crypto3/zk/snark/systems/plonk/placeholder/prover.hpp index 679ee8b5c..6fcf1c715 100644 --- a/libs/zk/include/nil/crypto3/zk/snark/systems/plonk/placeholder/prover.hpp +++ b/libs/zk/include/nil/crypto3/zk/snark/systems/plonk/placeholder/prover.hpp @@ -110,7 +110,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) @@ -122,6 +123,7 @@ 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); @@ -204,13 +206,15 @@ namespace nil { } transcript(_proof.commitments[QUOTIENT_BATCH]); - // 8. Run evaluation proofs - _proof.eval_proof.challenge = transcript.template challenge(); - generate_evaluation_points(); + if (!_skip_commitment_scheme_eval_proofs) { + // 8. Run evaluation proofs + _proof.eval_proof.challenge = transcript.template challenge(); + generate_evaluation_points(); - { - PROFILE_SCOPE("commitment scheme proof eval time"); - _proof.eval_proof.eval_proof = _commitment_scheme.proof_eval(transcript); + { + PROFILE_SCOPE("commitment scheme proof eval time"); + _proof.eval_proof.eval_proof = _commitment_scheme.proof_eval(transcript); + } } return _proof; @@ -369,14 +373,14 @@ 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) { + 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); @@ -387,7 +391,6 @@ namespace nil { _commitment_scheme.append_eval_point(QUOTIENT_BATCH, _proof.eval_proof.challenge); - // fixed values' rotations (table columns) std::size_t i = 0; std::size_t start_index = preprocessed_public_data.identity_polynomials.size() + @@ -479,6 +482,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 From 49ef6ba62e45233e9da621048f6e9c6d51db7ce3 Mon Sep 17 00:00:00 2001 From: Martun Karapetyan Date: Wed, 11 Sep 2024 19:36:22 +0400 Subject: [PATCH 2/3] Dividing LPC and FRI into stages and creating structures for aggregated FRI. --- .../detail/polynomial/basic_fri.hpp | 148 ++++++++--------- .../crypto3/zk/commitments/polynomial/lpc.hpp | 154 +++++++++++++++++- .../snark/systems/plonk/placeholder/proof.hpp | 68 +++++++- .../systems/plonk/placeholder/prover.hpp | 12 +- .../nil/crypto3/zk/transcript/fiat_shamir.hpp | 22 +++ 5 files changed, 301 insertions(+), 103 deletions(-) diff --git a/libs/zk/include/nil/crypto3/zk/commitments/detail/polynomial/basic_fri.hpp b/libs/zk/include/nil/crypto3/zk/commitments/detail/polynomial/basic_fri.hpp index 76f762754..a32ef505e 100644 --- a/libs/zk/include/nil/crypto3/zk/commitments/detail/polynomial/basic_fri.hpp +++ b/libs/zk/include/nil/crypto3/zk/commitments/detail/polynomial/basic_fri.hpp @@ -268,47 +268,53 @@ namespace nil { std::vector round_proofs; }; - struct round_proofs_batch { - bool operator==(const round_proofs_batch &rhs) const { + struct commitments_part_of_proof { + bool operator==(const commitments_part_of_proof& rhs) const { return fri_roots == rhs.fri_roots && - round_proofs == rhs.round_proofs && final_polynomial == rhs.final_polynomial; } - bool operator!=(const round_proofs_batch &rhs) const { + bool operator!=(const commitments_part_of_proof& rhs) const { return !(rhs == *this); } - std::vector fri_roots; // 0,..step_list.size() - std::vector> round_proofs; // 0...lambda - 1 + // Vector of size 'step_list.size()'. + std::vector fri_roots; math::polynomial final_polynomial; }; - struct initial_proofs_batch { - initial_proofs_batch() = default; + struct round_proofs_batch_type { + bool operator==(const round_proofs_batch_type &rhs) const { + return round_proofs == rhs.round_proofs; + } - // Just pre-allocate the vector for a given size. - initial_proofs_batch(std::size_t lambda) - : initial_proofs(lambda) { + bool operator!=(const round_proofs_batch_type &rhs) const { + return !(rhs == *this); } - bool operator==(const initial_proofs_batch &rhs) const { + // 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 &rhs) const { + bool operator!=(const initial_proofs_batch_type &rhs) const { return !(rhs == *this); } - std::vector> initial_proofs; // 0...lambda - 1 + // 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& round_proofs, - const initial_proofs_batch& intial_proofs) + 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) { @@ -336,40 +342,6 @@ namespace nil { std::vector query_proofs; // 0...lambda - 1 typename GrindingType::output_type proof_of_work; }; - - // This represents and aggregated proofs of N provers with shared initial proof. - struct aggregated_proof { - aggregated_proof() = default; - aggregated_proof(const aggregated_proof&) = default; - - // Size of vector 'round_proofs_per_prover' is the number of provers. - aggregated_proof( - const std::vector& round_proofs_per_prover, - const initial_proofs_batch& intial_proofs) - : round_proofs_per_prover(round_proofs_per_prover) - , intial_proofs(intial_proofs) { - } - - bool operator==(const aggregated_proof &rhs) const { - //if (FRI::use_grinding && proof_of_work != rhs.proof_of_work) { - // return false; - //} - return round_proofs_per_prover == rhs.round_proofs_per_prover && - intial_proofs == rhs.intial_proofs; - } - - bool operator!=(const aggregated_proof &rhs) const { - return !(rhs == *this); - } - - // For each prover we have a rounds proof partial FRI proof for consistency checks. - std::vector round_proofs_per_prover; - - // We have a single intial proof for checking that F(X) is a low degree polynomial. - initial_proofs_batch intial_proofs; - - typename GrindingType::output_type proof_of_work; - }; }; } // namespace detail } // namespace commitments @@ -437,13 +409,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; @@ -502,6 +474,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); } @@ -742,8 +718,7 @@ 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, @@ -754,8 +729,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; @@ -764,7 +738,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(); @@ -777,17 +751,25 @@ 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 */ @@ -991,14 +973,14 @@ namespace nil { template - static typename FRI::round_proofs_batch query_phase_round_proofs_with_challenges( + static typename FRI::round_proofs_batch_type query_phase_round_proofs( const typename FRI::params_type &fri_params, const std::vector &fri_trees, const std::vector &fs, const math::polynomial &final_polynomial, const std::vector& challenges) { - typename FRI::round_proofs_batch proof; + 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(); @@ -1016,19 +998,19 @@ namespace nil { build_round_proofs( fri_params, fri_trees, fs, final_polynomial, x_index); - proof.round_proofs[query_id] = std::move(round_proofs); + proof.round_proofs.emplace_back(std::move(round_proofs)); } return proof; } template - static typename FRI::initial_proofs_batch query_phase_initial_proofs_with_challenges( + 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 proof(fri_params.lambda); + typename FRI::initial_proofs_batch_type proof; // 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. @@ -1069,12 +1051,12 @@ namespace nil { const std::vector &fs, const math::polynomial &final_polynomial) { - typename FRI::initial_proofs_batch initial_proofs = - query_phase_initial_proofs_with_challenges( + typename FRI::initial_proofs_batch_type initial_proofs = + query_phase_initial_proofs( precommitments, fri_params, g, challenges); - typename FRI::round_proofs_batch round_proofs = - query_phase_round_proofs_with_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. @@ -1099,11 +1081,9 @@ namespace nil { const math::polynomial &final_polynomial) { PROFILE_SCOPE("Basic FRI query phase"); - std::vector challenges; - for (std::size_t query_id = 0; query_id < fri_params.lambda; query_id++) { - typename FRI::field_type::value_type x = transcript.template challenge(); - challenges.push_back(x); - } + std::vector challenges = + transcript.template challenges(fri_params.lambda); + return query_phase_with_challenges( precommitments, fri_params, challenges, g, fri_trees, fs, final_polynomial); } @@ -1136,11 +1116,13 @@ namespace nil { // Commit phase std::vector fri_trees; - std::vector fri_roots; std::vector fs; - math::polynomial final_polynomial; + math::polynomial final_polynomial; + + // Contains fri_roots and final_polynomial. + typename FRI::commitments_part_of_proof commitments_proof; - std::tie(fs, fri_trees, fri_roots, final_polynomial) = + std::tie(fs, fri_trees, commitments_proof) = commit_phase( combined_Q, combined_Q_precommitment, @@ -1155,10 +1137,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/libs/zk/include/nil/crypto3/zk/commitments/polynomial/lpc.hpp b/libs/zk/include/nil/crypto3/zk/commitments/polynomial/lpc.hpp index 1a6a80f5a..f93adac47 100644 --- a/libs/zk/include/nil/crypto3/zk/commitments/polynomial/lpc.hpp +++ b/libs/zk/include/nil/crypto3/zk/commitments/polynomial/lpc.hpp @@ -46,6 +46,7 @@ namespace nil { namespace commitments { // Placeholder-friendly class. + // LPCScheme is usually 'batched_list_polynomial_commitment<...>'. template> class lpc_commitment_scheme : public polys_evaluatorstate_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(); @@ -158,11 +163,93 @@ namespace nil { auto theta = transcript.template challenge(); polynomial_type combined_Q = prepare_combined_Q(theta); - auto fri_proof = commit_and_fri_proof(combined_Q); + auto fri_proof = commit_and_fri_proof(combined_Q, transcript); return proof_type({this->_z, fri_proof}); } - - typename fri_type::proof_type commit_and_fri_proof(const polynomial_type& combined_Q) { + + /** 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, @@ -171,8 +258,7 @@ namespace nil { ); typename fri_type::proof_type fri_proof = nil::crypto3::zk::algorithms::proof_eval< - fri_type, polynomial_type - >( + fri_type, polynomial_type>( this->_polys, combined_Q, this->_trees, @@ -250,9 +336,13 @@ 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); } + return combined_Q; } @@ -442,6 +532,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/libs/zk/include/nil/crypto3/zk/snark/systems/plonk/placeholder/proof.hpp b/libs/zk/include/nil/crypto3/zk/snark/systems/plonk/placeholder/proof.hpp index aa76cd045..c5cd9b9d3 100644 --- a/libs/zk/include/nil/crypto3/zk/snark/systems/plonk/placeholder/proof.hpp +++ b/libs/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,7 +75,7 @@ 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; @@ -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/libs/zk/include/nil/crypto3/zk/snark/systems/plonk/placeholder/prover.hpp b/libs/zk/include/nil/crypto3/zk/snark/systems/plonk/placeholder/prover.hpp index 6fcf1c715..f81bb2fd2 100644 --- a/libs/zk/include/nil/crypto3/zk/snark/systems/plonk/placeholder/prover.hpp +++ b/libs/zk/include/nil/crypto3/zk/snark/systems/plonk/placeholder/prover.hpp @@ -97,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(); } @@ -111,7 +112,7 @@ namespace nil { const plonk_table_description &table_description, const plonk_constraint_system &constraint_system, const commitment_scheme_type &commitment_scheme, - bool skip_commitment_scheme_eval_proofs=false + bool skip_commitment_scheme_eval_proofs = false ) : preprocessed_public_data(preprocessed_public_data) , table_description(table_description) @@ -211,10 +212,7 @@ namespace nil { _proof.eval_proof.challenge = transcript.template challenge(); generate_evaluation_points(); - { - PROFILE_SCOPE("commitment scheme proof eval time"); - _proof.eval_proof.eval_proof = _commitment_scheme.proof_eval(transcript); - } + _proof.eval_proof.eval_proof = _commitment_scheme.proof_eval(transcript); } return _proof; diff --git a/libs/zk/include/nil/crypto3/zk/transcript/fiat_shamir.hpp b/libs/zk/include/nil/crypto3/zk/transcript/fiat_shamir.hpp index 8f8ce1be0..92da6d01a 100644 --- a/libs/zk/include/nil/crypto3/zk/transcript/fiat_shamir.hpp +++ b/libs/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; }; From fa50644273f4969c8506d5667773d7d9815d3fab Mon Sep 17 00:00:00 2001 From: Iluvmagick Date: Sun, 8 Sep 2024 19:15:01 +0400 Subject: [PATCH 3/3] Added some more fri marshalling variants. --- .../marshalling/zk/types/commitments/fri.hpp | 650 ++++++++++++------ libs/marshalling/zk/test/fri_commitment.cpp | 103 ++- .../detail/polynomial/basic_fri.hpp | 64 +- 3 files changed, 586 insertions(+), 231 deletions(-) diff --git a/libs/marshalling/zk/include/nil/crypto3/marshalling/zk/types/commitments/fri.hpp b/libs/marshalling/zk/include/nil/crypto3/marshalling/zk/types/commitments/fri.hpp index 7dbaa9276..fb05df1de 100644 --- a/libs/marshalling/zk/include/nil/crypto3/marshalling/zk/types/commitments/fri.hpp +++ b/libs/marshalling/zk/include/nil/crypto3/marshalling/zk/types/commitments/fri.hpp @@ -49,6 +49,8 @@ namespace nil { namespace marshalling { namespace types { + using batch_info_type = std::map; // batch_id->batch_size + /////////////////////////////////////////////////// // fri::merkle_proofs marshalling /////////////////////////////////////////////////// @@ -56,7 +58,7 @@ namespace nil { using merkle_proof_vector_type = nil::marshalling::types::array_list< TTypeBase, types::merkle_proof, - nil::marshalling::option::sequence_size_field_prefix> + nil::marshalling::option::size_t_sequence_size_field_prefix >; template< typename Endianness, typename FRI > @@ -67,7 +69,6 @@ namespace nil { filled_type filled; - for( size_t i = 0; i < merkle_proofs.size(); i++){ filled.value().push_back( fill_merkle_proof(merkle_proofs[i]) @@ -88,181 +89,366 @@ namespace nil { return merkle_proofs; } + /////////////////////////////////////////////////// + // fri::initial_proof_type marshalling + /////////////////////////////////////////////////// + template + using fri_initial_proof_type = nil::marshalling::types::bundle< + TTypeBase, + std::tuple< + // polynomials_values_type values; + nil::marshalling::types::array_list< + TTypeBase, + field_element, + nil::marshalling::option::size_t_sequence_size_field_prefix + >, + // merkle_proof_type p; + typename types::merkle_proof + > + >; + + template + fri_initial_proof_type, FRI> + fill_fri_initial_proof( + const typename FRI::initial_proof_type &initial_proof + ) { + using TTypeBase = nil::marshalling::field_type; + using filled_type = fri_initial_proof_type; + + filled_type filled; + + for (std::size_t i = 0; i < initial_proof.values.size(); i++) { + for (std::size_t j = 0; j < initial_proof.values[i].size(); j++) { + for (std::size_t k = 0; k < FRI::m; k++) { + std::get<0>(filled.value()).value().push_back( + field_element( + initial_proof.values[i][j][k]) + ); + } + } + } + // merkle_proof_type p; + std::get<1>(filled.value()) = + fill_merkle_proof(initial_proof.p); + + return filled; + } + + template + typename FRI::initial_proof_type + make_fri_initial_proof( + const fri_initial_proof_type, FRI> &filled, + const std::size_t batch_size, + const std::size_t coset_size + ) { + typename FRI::initial_proof_type initial_proof; + // polynomials_values_type values; + BOOST_ASSERT(std::get<0>(filled.value()).value().size() == batch_size * coset_size * FRI::m); + std::size_t cur = 0; + initial_proof.values.resize(batch_size); + for (std::size_t i = 0; i < batch_size; i++) { + initial_proof.values[i].resize(coset_size); + for (std::size_t j = 0; j < coset_size; j++) { + for (std::size_t k = 0; k < FRI::m; k++) { + initial_proof.values[i][j][k] = + std::get<0>(filled.value()).value()[cur++].value(); + } + } + } + + // merkle_proof_type p; + initial_proof.p = make_merkle_proof( + std::get<1>(filled.value())); + + return initial_proof; + } + + /////////////////////////////////////////////////// + // fri::round_proof_type marshalling + /////////////////////////////////////////////////// + template + using fri_round_proof_type = nil::marshalling::types::bundle< + TTypeBase, + std::tuple< + // std::vector> y; + nil::marshalling::types::array_list< + TTypeBase, + field_element, + nil::marshalling::option::size_t_sequence_size_field_prefix + >, + // merkle_proof_type p; + typename types::merkle_proof + > + >; + + template + fri_round_proof_type, FRI> + fill_fri_round_proof( + const typename FRI::round_proof_type &round_proof + ) { + using TTypeBase = nil::marshalling::field_type; + using filled_type = fri_round_proof_type; + + filled_type filled; + + for (std::size_t i = 0; i < round_proof.y.size(); i++) { + for (std::size_t j = 0; j < FRI::m; j++) { + std::get<0>(filled.value()).value().push_back( + field_element( + round_proof.y[i][j]) + ); + } + } + // merkle_proof_type p; + std::get<1>(filled.value()) = + fill_merkle_proof(round_proof.p); + + return filled; + } + + template + typename FRI::round_proof_type + make_fri_round_proof( + const fri_round_proof_type, FRI> &filled, + const std::size_t coset_size + ) { + typename FRI::round_proof_type round_proof; + // std::vector> y; + BOOST_ASSERT(std::get<0>(filled.value()).value().size() == coset_size * FRI::m); + std::size_t cur = 0; + round_proof.y.resize(coset_size); + for (std::size_t i = 0; i < coset_size; i++) { + for (std::size_t j = 0; j < FRI::m; j++) { + round_proof.y[i][j] = std::get<0>(filled.value()).value()[cur++].value(); + } + } + + // merkle_proof_type p; + round_proof.p = make_merkle_proof( + std::get<1>(filled.value())); + + return round_proof; + } + + /////////////////////////////////////////////////// + // fri::query_proof_type marshalling + /////////////////////////////////////////////////// + template + using fri_query_proof_type = nil::marshalling::types::bundle< + TTypeBase, + std::tuple< + // std::map initial_proof; + nil::marshalling::types::array_list< + TTypeBase, + fri_initial_proof_type, + nil::marshalling::option::size_t_sequence_size_field_prefix + >, + // std::vector round_proofs; + nil::marshalling::types::array_list< + TTypeBase, + fri_round_proof_type, + nil::marshalling::option::size_t_sequence_size_field_prefix + > + > + >; + + template + fri_query_proof_type, FRI> + fill_fri_query_proof( + const typename FRI::query_proof_type &query_proof + ) { + using TTypeBase = nil::marshalling::field_type; + using filled_type = fri_query_proof_type; + + filled_type filled; + + for (auto &[key, value] : query_proof.initial_proof) { + std::get<0>(filled.value()).value().push_back( + fill_fri_initial_proof(value) + ); + } + + for (std::size_t i = 0; i < query_proof.round_proofs.size(); i++) { + std::get<1>(filled.value()).value().push_back( + fill_fri_round_proof(query_proof.round_proofs[i]) + ); + } + + return filled; + } + + template + typename FRI::query_proof_type + make_fri_query_proof( + const fri_query_proof_type, FRI> &filled, + const batch_info_type &batch_info, + const std::vector &step_list + ) { + typename FRI::query_proof_type query_proof; + // std::map initial_proof; + std::size_t cur = 0; + std::size_t coset_size = 1 << (step_list[0] - 1); + for (const auto &[batch_id, batch_size] : batch_info) { + query_proof.initial_proof[batch_id] = + make_fri_initial_proof( + std::get<0>(filled.value()).value()[cur++], batch_size, coset_size + ); + } + // std::vector round_proofs; + cur = 0; + for (std::size_t r = 0; r < step_list.size(); r++) { + coset_size = r == step_list.size() - 1 ? 1 : (1 << (step_list[r+1]-1)); + query_proof.round_proofs.push_back( + make_fri_round_proof( + std::get<1>(filled.value()).value()[cur++], coset_size + ) + ); + } + + return query_proof; + } + + /////////////////////////////////////////////////// + // fri::partial_proof_type marshalling + /////////////////////////////////////////////////// + template + using fri_partial_proof_type = nil::marshalling::types::bundle< + TTypeBase, + std::tuple< + // std::vector fri_roots; + nil::marshalling::types::array_list< + TTypeBase, + typename types::merkle_node_value::type, + nil::marshalling::option::size_t_sequence_size_field_prefix + >, + // math::polynomial final_polynomial; + typename polynomial::type, + // typename GrindingType::output_type proof_of_work; + nil::marshalling::types::integral + > + >; + + template + fri_partial_proof_type, FRI> + fill_partial_proof( + const typename FRI::partial_proof_type &partial_proof + ) { + using TTypeBase = nil::marshalling::field_type; + using filled_type = fri_partial_proof_type; + + filled_type filled; + + for (size_t i = 0; i < partial_proof.fri_roots.size(); i++) { + std::get<0>(filled.value()).value().push_back( + fill_merkle_node_value(partial_proof.fri_roots[i]) + ); + } + + std::get<1>(filled.value()) = fill_polynomial( + partial_proof.final_polynomial + ); + + std::get<2>(filled.value()) = + nil::marshalling::types::integral( + partial_proof.proof_of_work + ); + + return filled; + } + + template + typename FRI::partial_proof_type + make_fri_partial_proof( + const fri_partial_proof_type, FRI> &filled + ) { + typename FRI::partial_proof_type partial_proof; + // std::vector fri_roots; + for (std::size_t i = 0; i < std::get<0>(filled.value()).value().size(); i++) { + partial_proof.fri_roots.push_back( + make_merkle_node_value( + std::get<0>(filled.value()).value()[i] + ) + ); + } + + // math::polynomial final_polynomial; + partial_proof.final_polynomial = make_polynomial( + std::get<1>(filled.value()) + ); + + // typename GrindingType::output_type proof_of_work; + partial_proof.proof_of_work = std::get<2>(filled.value()).value(); + + return partial_proof; + } + /////////////////////////////////////////////////// // fri::proof_type marshalling /////////////////////////////////////////////////// - template struct fri_proof { + template + struct fri_proof { using type = nil::marshalling::types::bundle< TTypeBase, std::tuple< - // step_list.size() merkle roots - // Fixed size. It's Ok - nil::marshalling::types::array_list< - TTypeBase, typename types::merkle_node_value::type, - nil::marshalling::option::sequence_size_field_prefix> - >, - + // partial_proof + fri_partial_proof_type, // step_list. // We'll check is it good for current EVM instance nil::marshalling::types::array_list< TTypeBase, nil::marshalling::types::integral, - nil::marshalling::option::sequence_size_field_prefix> - >, - - // Polynomials' values for initial proofs - // Fixed size - // lambda * polynomials_num * m - nil::marshalling::types::array_list< - TTypeBase, - field_element, - nil::marshalling::option::sequence_size_field_prefix> - >, - - // Polynomials' values for round proofs - // Fixed size - // lambda * \sum_rounds{m^{r_i}} - nil::marshalling::types::array_list< - TTypeBase, - field_element, - nil::marshalling::option::sequence_size_field_prefix> + nil::marshalling::option::size_t_sequence_size_field_prefix >, - - // Merkle proofs for initial proofs - // Fixed size lambda * batches_num - nil::marshalling::types::array_list< - TTypeBase, - typename types::merkle_proof, - nil::marshalling::option::sequence_size_field_prefix> - >, - - // Merkle proofs for round proofs - // Fixed size lambda * |step_list| + // (lambda) query proofs nil::marshalling::types::array_list< TTypeBase, - typename types::merkle_proof, - nil::marshalling::option::sequence_size_field_prefix> - >, - - // std::select_container final_polynomials - // May be different size, because real degree may be less than before. So put int in the end - typename polynomial::type, - - // proof of work. TODO: how to do it optional? - nil::marshalling::types::integral //proof of work*/ + fri_query_proof_type, + nil::marshalling::option::size_t_sequence_size_field_prefix + > > >; }; - using batch_info_type = std::map;// batch_id->batch_size - template typename fri_proof, FRI>::type - fill_fri_proof(const typename FRI::proof_type &proof, const batch_info_type &batch_info, const typename FRI::params_type& params) { + fill_fri_proof( + const typename FRI::proof_type &proof, + const batch_info_type &batch_info, + const typename FRI::params_type& params + ) { using TTypeBase = nil::marshalling::field_type; - // merkle roots - nil::marshalling::types::array_list< - TTypeBase, typename types::merkle_node_value::type, - nil::marshalling::option::sequence_size_field_prefix> - > filled_fri_roots; - for( size_t i = 0; i < proof.fri_roots.size(); i++){ - filled_fri_roots.value().push_back(fill_merkle_node_value(proof.fri_roots[i])); - } - - std::size_t lambda = proof.query_proofs.size(); - // initial_polynomials values - std::vector initial_val; - for( std::size_t i = 0; i < lambda; i++ ){ - auto &query_proof = proof.query_proofs[i]; - for( const auto &it: query_proof.initial_proof){ - auto &initial_proof = it.second; - BOOST_ASSERT(initial_proof.values.size() == batch_info.at(it.first)); - for( std::size_t j = 0; j < initial_proof.values.size(); j++ ){ - for(std::size_t k = 0; k < initial_proof.values[j].size(); k++ ){ - for( std::size_t l = 0; l < FRI::m; l++ ){ - initial_val.push_back(initial_proof.values[j][k][l]); - } - } - BOOST_ASSERT(std::size_t(1 << (params.step_list[0] - 1)) == initial_proof.values[j].size()); - } - } - } - nil::marshalling::types::array_list< - TTypeBase, - field_element, - nil::marshalling::option::sequence_size_field_prefix> - > filled_initial_val = fill_field_element_vector(initial_val); - - // fill round values - std::vector round_val; - for( std::size_t i = 0; i < lambda; i++ ){ - auto &query_proof = proof.query_proofs[i]; - for( std::size_t j = 0; j < query_proof.round_proofs.size(); j++ ){ - auto &round_proof = query_proof.round_proofs[j]; - for( std::size_t k = 0; k < round_proof.y.size(); k++){ - round_val.push_back(round_proof.y[k][0]); - round_val.push_back(round_proof.y[k][1]); - } - } - } - nil::marshalling::types::array_list< - TTypeBase, - field_element, - nil::marshalling::option::sequence_size_field_prefix> - > filled_round_val = fill_field_element_vector(round_val); + // partial_proof + auto filled_partial_proof = fill_partial_proof( + proof + ); // step_list nil::marshalling::types::array_list< TTypeBase, nil::marshalling::types::integral, - nil::marshalling::option::sequence_size_field_prefix> + nil::marshalling::option::size_t_sequence_size_field_prefix > filled_step_list; for (const auto& step : params.step_list) { - filled_step_list.value().push_back(nil::marshalling::types::integral(step)); - } - - // initial merkle proofs - nil::marshalling::types::array_list< - TTypeBase, - typename types::merkle_proof, - nil::marshalling::option::sequence_size_field_prefix> - > filled_initial_merkle_proofs; - for( std::size_t i = 0; i < lambda; i++){ - const auto &query_proof = proof.query_proofs[i]; - for( const auto &it:query_proof.initial_proof){ - const auto &initial_proof = it.second; - filled_initial_merkle_proofs.value().push_back( - fill_merkle_proof(initial_proof.p) - ); - } + filled_step_list.value().push_back( + nil::marshalling::types::integral(step)); } - // round merkle proofs + // lambda query proofs nil::marshalling::types::array_list< TTypeBase, - typename types::merkle_proof, - nil::marshalling::option::sequence_size_field_prefix> - > filled_round_merkle_proofs; - for( std::size_t i = 0; i < lambda; i++){ - const auto &query_proof = proof.query_proofs[i]; - for( const auto &round_proof:query_proof.round_proofs){ - filled_round_merkle_proofs.value().push_back( - fill_merkle_proof(round_proof.p) - ); - } + fri_query_proof_type, + nil::marshalling::option::size_t_sequence_size_field_prefix + > filled_query_proofs; + for (std::size_t i = 0; i < proof.query_proofs.size(); i++) { + filled_query_proofs.value().push_back( + fill_fri_query_proof(proof.query_proofs[i]) + ); } - auto filled_final_polynomial = fill_polynomial( - proof.final_polynomial - ); - - // proof_of_work return typename fri_proof, FRI>::type( std::tuple( - filled_fri_roots, filled_step_list, filled_initial_val, filled_round_val, - filled_initial_merkle_proofs, filled_round_merkle_proofs, filled_final_polynomial, - nil::marshalling::types::integral(proof.proof_of_work) + filled_partial_proof, filled_step_list, filled_query_proofs ) ); } @@ -270,86 +456,144 @@ namespace nil { template typename FRI::proof_type make_fri_proof( - const typename fri_proof, FRI>::type &filled_proof, const batch_info_type &batch_info + const typename fri_proof, FRI>::type &filled_proof, + const batch_info_type &batch_info ){ typename FRI::proof_type proof; - // merkle roots - for( std::size_t i = 0; i < std::get<0>(filled_proof.value()).value().size(); i++){ - proof.fri_roots.push_back( - make_merkle_node_value(std::get<0>(filled_proof.value()).value()[i]) - ); - } + // partial_proof + proof = make_fri_partial_proof( + std::get<0>(filled_proof.value()) + ); // step_list std::vector step_list; - for( std::size_t i = 0; i < std::get<1>(filled_proof.value()).value().size(); i++){ + for(std::size_t i = 0; i < std::get<1>(filled_proof.value()).value().size(); i++){ auto c = std::get<1>(filled_proof.value()).value()[i].value(); step_list.push_back(c); } - - std::size_t lambda = std::get<5>(filled_proof.value()).value().size() / step_list.size(); + const std::size_t lambda = std::get<2>(filled_proof.value()).value().size(); proof.query_proofs.resize(lambda); - // initial_polynomials values - std::size_t coset_size = 1 << (step_list[0] - 1); - std::size_t cur = 0; - for( std::size_t i = 0; i < lambda; i++ ){ - for( const auto &it:batch_info){ - proof.query_proofs[i].initial_proof[it.first] = typename FRI::initial_proof_type(); - proof.query_proofs[i].initial_proof[it.first].values.resize(it.second); - for( std::size_t j = 0; j < it.second; j++ ){ - proof.query_proofs[i].initial_proof[it.first].values[j].resize(coset_size); - for( std::size_t k = 0; k < coset_size; k++){ - for( std::size_t l = 0; l < FRI::m; l++, cur++ ){ - BOOST_ASSERT(cur < std::get<2>(filled_proof.value()).value().size()); - proof.query_proofs[i].initial_proof[it.first].values[j][k][l] = std::get<2>(filled_proof.value()).value()[cur].value(); - } - } - } - } + for (std::size_t i = 0; i < lambda; i++) { + proof.query_proofs[i] = make_fri_query_proof( + std::get<2>(filled_proof.value()).value()[i], batch_info, step_list + ); } - // round polynomials values - cur = 0; - for(std::size_t i = 0; i < lambda; i++ ){ - proof.query_proofs[i].round_proofs.resize(step_list.size()); - for(std::size_t r = 0; r < step_list.size(); r++ ){ - coset_size = r == step_list.size() - 1? 1: (1 << (step_list[r+1]-1)); - proof.query_proofs[i].round_proofs[r].y.resize(coset_size); - for( std::size_t j = 0; j < coset_size; j++){ - for( std::size_t k = 0; k < FRI::m; k++, cur++){ - BOOST_ASSERT(cur < std::get<3>(filled_proof.value()).value().size()); - proof.query_proofs[i].round_proofs[r].y[j][k] = std::get<3>(filled_proof.value()).value()[cur].value(); - } - } - } + return proof; + } + + /////////////////////////////////////////////////// + // fri::aggregated_proof_type marshalling + /////////////////////////////////////////////////// + template + using fri_aggregated_proof_type = nil::marshalling::types::bundle< + TTypeBase, + std::tuple< + // std::vector partial_proofs; + nil::marshalling::types::array_list< + TTypeBase, + fri_partial_proof_type, + nil::marshalling::option::size_t_sequence_size_field_prefix + >, + // std::vector step_list; + nil::marshalling::types::array_list< + TTypeBase, + nil::marshalling::types::integral, + nil::marshalling::option::size_t_sequence_size_field_prefix + >, + // std::vector query_proofs; + nil::marshalling::types::array_list< + TTypeBase, + fri_query_proof_type, + nil::marshalling::option::size_t_sequence_size_field_prefix + > + > + >; + + template + fri_aggregated_proof_type, FRI> + fill_fri_aggregated_proof( + const typename FRI::aggregated_proof_type &aggregated_proof, + const typename FRI::params_type& params + ) { + using TTypeBase = nil::marshalling::field_type; + + // partial_proofs + nil::marshalling::types::array_list< + TTypeBase, + fri_partial_proof_type, + nil::marshalling::option::size_t_sequence_size_field_prefix + > filled_partial_proofs; + for (std::size_t i = 0; i < aggregated_proof.partial_proofs.size(); i++) { + filled_partial_proofs.value().push_back( + fill_partial_proof(aggregated_proof.partial_proofs[i]) + ); } - // initial merkle proofs - cur = 0; - for( std::size_t i = 0; i < lambda; i++ ){ - for( const auto &it:batch_info){ - proof.query_proofs[i].initial_proof[it.first].p = make_merkle_proof( - std::get<4>(filled_proof.value()).value()[cur++] - ); - } + + // step_list + nil::marshalling::types::array_list< + TTypeBase, + nil::marshalling::types::integral, + nil::marshalling::option::size_t_sequence_size_field_prefix + > filled_step_list; + for (const auto& step : params.step_list) { + filled_step_list.value().push_back( + nil::marshalling::types::integral(step)); } - // round merkle proofs - cur = 0; - for( std::size_t i = 0; i < lambda; i++ ){ - for( std::size_t r = 0; r < step_list.size(); r++, cur++ ){ - proof.query_proofs[i].round_proofs[r].p = make_merkle_proof( - std::get<5>(filled_proof.value()).value()[cur] - ); - } + // query_proofs + nil::marshalling::types::array_list< + TTypeBase, + fri_query_proof_type, + nil::marshalling::option::size_t_sequence_size_field_prefix + > filled_query_proofs; + for (std::size_t i = 0; i < aggregated_proof.query_proofs.size(); i++) { + filled_query_proofs.value().push_back( + fill_fri_query_proof(aggregated_proof.query_proofs[i]) + ); } - // final_polynomial - proof.final_polynomial = make_polynomial( - std::get<6>(filled_proof.value()) + return fri_aggregated_proof_type, FRI>( + std::tuple( + filled_partial_proofs, filled_step_list, filled_query_proofs + ) ); - // proof_of_work - proof.proof_of_work = std::get<7>(filled_proof.value()).value(); - return proof; } + + template + typename FRI::aggregated_proof_type + make_fri_aggregated_proof( + const fri_aggregated_proof_type, FRI> &filled, + const batch_info_type &batch_info + ) { + typename FRI::aggregated_proof_type aggregated_proof; + // partial_proofs + for (std::size_t i = 0; i < std::get<0>(filled.value()).value().size(); i++) { + aggregated_proof.partial_proofs.push_back( + make_fri_partial_proof( + std::get<0>(filled.value()).value()[i] + ) + ); + } + + // step_list + std::vector step_list; + for(std::size_t i = 0; i < std::get<1>(filled.value()).value().size(); i++){ + auto c = std::get<1>(filled.value()).value()[i].value(); + step_list.push_back(c); + } + + // query_proofs + const std::size_t lambda = std::get<2>(filled.value()).value().size(); + aggregated_proof.query_proofs.resize(lambda); + for (std::size_t i = 0; i < lambda; i++) { + aggregated_proof.query_proofs[i] = make_fri_query_proof( + std::get<2>(filled.value()).value()[i], batch_info, step_list + ); + } + + return aggregated_proof; + } + } // namespace types } // namespace marshalling } // namespace crypto3 diff --git a/libs/marshalling/zk/test/fri_commitment.cpp b/libs/marshalling/zk/test/fri_commitment.cpp index 027f3100b..534f23e67 100644 --- a/libs/marshalling/zk/test/fri_commitment.cpp +++ b/libs/marshalling/zk/test/fri_commitment.cpp @@ -112,6 +112,46 @@ void test_fri_proof(typename FRI::proof_type &proof, typename nil::crypto3::mars BOOST_CHECK(proof == constructed_val_read); } +template +void test_fri_aggregated_proof( + std::vector &partial_proofs, + std::vector &query_proofs, + typename nil::crypto3::marshalling::types::batch_info_type batch_info, + const typename FRI::params_type& params +) { + using TTypeBase = nil::marshalling::field_type; + + auto og_proof = typename FRI::aggregated_proof_type{partial_proofs, query_proofs}; + + auto filled_proof = nil::crypto3::marshalling::types::fill_fri_aggregated_proof( + og_proof, params + ); + auto _proof = nil::crypto3::marshalling::types::make_fri_aggregated_proof( + filled_proof, batch_info + ); + BOOST_CHECK(partial_proofs == _proof.partial_proofs); + BOOST_CHECK(query_proofs == _proof.query_proofs); + BOOST_CHECK(og_proof == _proof); + + std::vector cv; + cv.resize(filled_proof.length(), 0x00); + auto write_iter = cv.begin(); + auto status = filled_proof.write(write_iter, cv.size()); + BOOST_CHECK(status == nil::marshalling::status_type::success); + + typename nil::crypto3::marshalling::types::fri_aggregated_proof_type test_val_read; + auto read_iter = cv.begin(); + status = test_val_read.read(read_iter, cv.size()); + BOOST_CHECK(status == nil::marshalling::status_type::success); + typename FRI::aggregated_proof_type constructed_val_read = + nil::crypto3::marshalling::types::make_fri_aggregated_proof( + test_val_read, batch_info + ); + BOOST_CHECK(partial_proofs == constructed_val_read.partial_proofs); + BOOST_CHECK(query_proofs == constructed_val_read.query_proofs); + BOOST_CHECK(og_proof == constructed_val_read); +} + BOOST_FIXTURE_TEST_SUITE(marshalling_fri_proof_elements, zk::test_tools::random_test_initializer::scalar_field_type>) static constexpr std::size_t lambda = 40; static constexpr std::size_t m = 2; @@ -184,13 +224,13 @@ BOOST_FIXTURE_TEST_SUITE(marshalling_fri_proof_elements, zk::test_tools::random_ ); auto proof = generate_random_fri_proof( - 2, 5, - fri_params.step_list, - lambda, - false, - batch_info, - alg_random_engines.template get_alg_engine(), - generic_random_engine + 2, 5, + fri_params.step_list, + lambda, + false, + batch_info, + alg_random_engines.template get_alg_engine(), + generic_random_engine ); test_fri_proof(proof, batch_info, fri_params); } @@ -205,6 +245,29 @@ BOOST_FIXTURE_TEST_SUITE(marshalling_fri_proof_elements, zk::test_tools::random_ typename FRI::params_type fri_params(1, 11, lambda, 4, true); auto proof = generate_random_fri_proof( + 2, 5, + fri_params.step_list, + lambda, + true, + batch_info, + alg_random_engines.template get_alg_engine(), + generic_random_engine + ); + test_fri_proof(proof, batch_info, fri_params); + } + + BOOST_AUTO_TEST_CASE(fri_aggregated_proof_Test) { + nil::crypto3::marshalling::types::batch_info_type batch_info; + batch_info[0] = 1; + batch_info[1] = 5; + batch_info[3] = 6; + batch_info[4] = 3; + + typename FRI::params_type fri_params(1, 11, lambda, 4, true); + // we just generate a vector of random proofs for this test + std::vector proofs; + for (std::size_t i = 0; i < 10; i++) { + proofs.push_back(generate_random_fri_proof( 2, 5, fri_params.step_list, lambda, @@ -212,9 +275,21 @@ BOOST_FIXTURE_TEST_SUITE(marshalling_fri_proof_elements, zk::test_tools::random_ batch_info, alg_random_engines.template get_alg_engine(), generic_random_engine - ); - test_fri_proof(proof, batch_info, fri_params); + )); + } + std::vector partial_proofs; + for (std::size_t i = 0; i < 10; i++) { + partial_proofs.push_back(proofs[i]); + } + std::vector query_proofs; + for (std::size_t i = 0; i < 10; i++) { + for (std::size_t j = 0; j < proofs[i].query_proofs.size(); j++) { + query_proofs.push_back(proofs[i].query_proofs[j]); + } + } + test_fri_aggregated_proof(partial_proofs, query_proofs, batch_info, fri_params); } + BOOST_AUTO_TEST_SUITE_END() @@ -246,11 +321,11 @@ BOOST_AUTO_TEST_CASE(marshalling_fri_basic_test) { // Setup params std::size_t degree_log = std::ceil(std::log2(d - 1)); typename fri_type::params_type fri_params( - 3, /*max_step*/ - degree_log, - lambda, - 2 //expand_factor - ); + 3, /*max_step*/ + degree_log, + lambda, + 2 //expand_factor + ); // commit math::polynomial f = {{ diff --git a/libs/zk/include/nil/crypto3/zk/commitments/detail/polynomial/basic_fri.hpp b/libs/zk/include/nil/crypto3/zk/commitments/detail/polynomial/basic_fri.hpp index a32ef505e..465aae0ad 100644 --- a/libs/zk/include/nil/crypto3/zk/commitments/detail/polynomial/basic_fri.hpp +++ b/libs/zk/include/nil/crypto3/zk/commitments/detail/polynomial/basic_fri.hpp @@ -234,9 +234,8 @@ namespace nil { return !(rhs == *this); } - // For the last round it's final_polynomial's values - // Values for the next round. + // For the last round it's final_polynomial's values polynomial_values_type y; // Merkle proof(values[i-1], T_i). @@ -329,18 +328,55 @@ namespace nil { // return false; // } return fri_roots == rhs.fri_roots && - query_proofs == rhs.query_proofs && final_polynomial == rhs.final_polynomial; } + bool operator!=(const partial_proof_type &rhs) const { + return !(rhs == *this); + } + + std::vector fri_roots; // 0..step_list.size() + math::polynomial final_polynomial; + typename GrindingType::output_type proof_of_work; + }; + + struct proof_type : public partial_proof_type { + proof_type() = default; + + proof_type(const partial_proof_type &partial_proof) + : partial_proof_type(partial_proof) {} + + virtual ~proof_type() = default; + + bool operator==(const proof_type &rhs) const { + return partial_proof_type::operator==(rhs) && + query_proofs == rhs.query_proofs; + } + bool operator!=(const proof_type &rhs) const { return !(rhs == *this); } - std::vector fri_roots; // 0,..step_list.size() - math::polynomial final_polynomial; - std::vector query_proofs; // 0...lambda - 1 - typename GrindingType::output_type proof_of_work; + std::vector query_proofs; // 0..lambda - 1 + }; + + struct aggregated_proof_type { + aggregated_proof_type() = default; + aggregated_proof_type(const std::vector &partial_proofs, + const std::vector &query_proofs) + : partial_proofs(partial_proofs), query_proofs(query_proofs) {} + + bool operator==(const aggregated_proof_type &rhs) const { + return partial_proofs == rhs.partial_proofs && + query_proofs == rhs.query_proofs; + } + + bool operator!=(const aggregated_proof_type &rhs) const { + return !(rhs == *this); + } + + std::vector partial_proofs; + std::vector query_proofs; }; }; } // namespace detail @@ -415,7 +451,7 @@ namespace nil { if (f.size() != D->size()) { 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; @@ -1051,11 +1087,11 @@ namespace nil { const std::vector &fs, const math::polynomial &final_polynomial) { - typename FRI::initial_proofs_batch_type initial_proofs = + 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 = + + typename FRI::round_proofs_batch_type round_proofs = query_phase_round_proofs( fri_params, fri_trees, fs, final_polynomial, challenges); @@ -1063,7 +1099,7 @@ namespace nil { std::vector query_proofs(fri_params.lambda); 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]), + query_proofs[query_id] = {std::move(initial_proofs.initial_proofs[query_id]), std::move(round_proofs.round_proofs[query_id])}; } return query_proofs; @@ -1117,10 +1153,10 @@ namespace nil { std::vector fri_trees; std::vector fs; - math::polynomial final_polynomial; + math::polynomial final_polynomial; // Contains fri_roots and final_polynomial. - typename FRI::commitments_part_of_proof commitments_proof; + typename FRI::commitments_part_of_proof commitments_proof; std::tie(fs, fri_trees, commitments_proof) = commit_phase(