From 6fc1353c73440d0b154d67bcf9677c4668e5058c Mon Sep 17 00:00:00 2001 From: Iluvmagick Date: Tue, 17 Sep 2024 04:18:21 +0400 Subject: [PATCH] Added marshalling for aggregated proofs. --- .../marshalling/zk/types/commitments/fri.hpp | 425 +++++++++++++++++- .../marshalling/zk/types/commitments/lpc.hpp | 196 +++++++- .../zk/types/placeholder/proof.hpp | 66 +++ .../marshalling/zk/test/lpc_commitment.cpp | 41 ++ .../marshalling/zk/test/placeholder_proof.cpp | 43 ++ .../zk/test/random_test_data_generation.hpp | 136 ++++++ .../detail/polynomial/basic_fri.hpp | 16 +- .../snark/systems/plonk/placeholder/proof.hpp | 7 + 8 files changed, 913 insertions(+), 17 deletions(-) diff --git a/crypto3/libs/marshalling/zk/include/nil/crypto3/marshalling/zk/types/commitments/fri.hpp b/crypto3/libs/marshalling/zk/include/nil/crypto3/marshalling/zk/types/commitments/fri.hpp index 7dbaa92763..43af54811c 100644 --- a/crypto3/libs/marshalling/zk/include/nil/crypto3/marshalling/zk/types/commitments/fri.hpp +++ b/crypto3/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 /////////////////////////////////////////////////// @@ -88,6 +90,243 @@ 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::standard_array_list< + TTypeBase, + nil::marshalling::types::standard_array_list< + TTypeBase, + nil::marshalling::types::standard_array_list< + TTypeBase, + field_element>> + >, + // 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 value_type = typename FRI::field_type::value_type; + using filled_type = fri_initial_proof_type; + using outer_list_type = nil::marshalling::types::standard_array_list< + TTypeBase, + nil::marshalling::types::standard_array_list< + TTypeBase, + field_element + > + >; + using inner_list_type = nil::marshalling::types::standard_array_list< + TTypeBase, + field_element + >; + + filled_type filled; + + for (std::size_t i = 0; i < initial_proof.values.size(); i++) { + outer_list_type outer_list; + for (std::size_t j = 0; j < initial_proof.values[i].size(); j++) { + inner_list_type inner_list; + for (std::size_t k = 0; k < FRI::m; k++) { + inner_list.value().push_back( + field_element( + initial_proof.values[i][j][k]) + ); + } + outer_list.value().push_back(inner_list); + } + std::get<0>(filled.value()).value().push_back(outer_list); + } + // 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 + ) { + typename FRI::initial_proof_type initial_proof; + // polynomials_values_type values; + auto &values = std::get<0>(filled.value()).value(); + initial_proof.values.resize(values.size()); + for (std::size_t i = 0; i < values.size(); i++) { + auto &outer_values = values[i].value(); + initial_proof.values[i].resize(outer_values.size()); + for (std::size_t j = 0; j < outer_values.size(); j++) { + auto &inner_values = outer_values[j].value(); + for (std::size_t k = 0; k < FRI::m; k++) { + initial_proof.values[i][j][k] = inner_values[k].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 + ) { + typename FRI::round_proof_type round_proof; + // std::vector> y; + const std::size_t size = std::get<0>(filled.value()).value().size(); + BOOST_ASSERT(size % FRI::m == 0); + const std::size_t coset_size = 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++] + ) + ); + } + + return query_proof; + } + /////////////////////////////////////////////////// // fri::proof_type marshalling /////////////////////////////////////////////////// @@ -262,7 +501,8 @@ namespace nil { 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) + nil::marshalling::types::integral( + proof.proof_of_work) ) ); } @@ -350,6 +590,189 @@ namespace nil { proof.proof_of_work = std::get<7>(filled_proof.value()).value(); return proof; } + + template + using initial_proofs_batch_type = nil::marshalling::types::standard_array_list< + TTypeBase, + nil::marshalling::types::bundle< + TTypeBase, + std::tuple< + nil::marshalling::types::standard_array_list< + TTypeBase, + nil::marshalling::types::integral + >, + nil::marshalling::types::standard_array_list< + TTypeBase, + fri_initial_proof_type + > + > + > + >; + + template + initial_proofs_batch_type, FRI> + fill_initial_proofs_batch(const typename FRI::initial_proofs_batch_type &initial_proofs_batch) { + using TTypeBase = nil::marshalling::field_type; + using filled_type = initial_proofs_batch_type; + using bundle_type = nil::marshalling::types::bundle< + TTypeBase, + std::tuple< + nil::marshalling::types::standard_array_list< + TTypeBase, + nil::marshalling::types::integral + >, + nil::marshalling::types::standard_array_list< + TTypeBase, + fri_initial_proof_type + > + > + >; + + filled_type filled; + + for (const auto &inital_proof : initial_proofs_batch.initial_proofs) { + nil::marshalling::types::standard_array_list< + TTypeBase, + nil::marshalling::types::integral + > filled_step_list; + nil::marshalling::types::standard_array_list< + TTypeBase, + fri_initial_proof_type + > filled_initial_proofs; + for (const auto &[step_list, proof] : inital_proof) { + filled_step_list.value().push_back( + nil::marshalling::types::integral(step_list)); + filled_initial_proofs.value().push_back(fill_fri_initial_proof( + proof)); + } + auto filled_bundle = std::make_tuple(filled_step_list, filled_initial_proofs); + filled.value().push_back(bundle_type(filled_bundle)); + } + + return filled; + } + + template + typename FRI::initial_proofs_batch_type make_initial_proofs_batch( + const initial_proofs_batch_type, FRI> &filled + ) { + typename FRI::initial_proofs_batch_type initial_proofs_batch; + for (const auto &batch : filled.value()) { + std::map batch_initial_proofs; + auto &batch_index_vector = std::get<0>(batch.value()).value(); + auto &batch_proof_vector = std::get<1>(batch.value()).value(); + for (std::size_t i = 0; i < batch_index_vector.size(); i++) { + batch_initial_proofs[batch_index_vector[i].value()] = + make_fri_initial_proof(batch_proof_vector[i]); + } + initial_proofs_batch.initial_proofs.push_back(batch_initial_proofs); + } + return initial_proofs_batch; + } + + template + using round_proofs_batch_type = nil::marshalling::types::standard_array_list< + TTypeBase, + nil::marshalling::types::standard_array_list< + TTypeBase, + fri_round_proof_type + > + >; + + template + round_proofs_batch_type, FRI> + fill_round_proofs_batch(const typename FRI::round_proofs_batch_type &round_proofs_batch) { + using TTypeBase = nil::marshalling::field_type; + using filled_type = round_proofs_batch_type; + + filled_type filled; + + for (const auto &round_proof_vector : round_proofs_batch.round_proofs) { + nil::marshalling::types::standard_array_list< + TTypeBase, + fri_round_proof_type + > filled_round_proof_vector; + for (const auto &round_proof : round_proof_vector) { + filled_round_proof_vector.value().push_back( + fill_fri_round_proof(round_proof)); + } + filled.value().push_back(filled_round_proof_vector); + } + + return filled; + } + + template + typename FRI::round_proofs_batch_type make_round_proofs_batch( + const round_proofs_batch_type, FRI> &filled + ) { + typename FRI::round_proofs_batch_type round_proofs_batch; + for (const auto &round_proof_vector : filled.value()) { + std::vector round_proofs; + for (const auto &round_proof : round_proof_vector.value()) { + round_proofs.push_back(make_fri_round_proof(round_proof)); + } + round_proofs_batch.round_proofs.push_back(round_proofs); + } + return round_proofs_batch; + } + + template + using commitments_part_of_proof_type = nil::marshalling::types::bundle< + TTypeBase, + std::tuple< + nil::marshalling::types::standard_array_list< + TTypeBase, + typename types::merkle_node_value::type + >, + typename polynomial::type + > + >; + + template + commitments_part_of_proof_type, FRI> + fill_commitments_part_of_proof( + const typename FRI::commitments_part_of_proof &commitments_part_of_proof + ) { + using TTypeBase = nil::marshalling::field_type; + using filled_type = commitments_part_of_proof_type; + + filled_type filled; + + nil::marshalling::types::standard_array_list< + TTypeBase, + typename types::merkle_node_value::type + > filled_fri_roots; + for (const auto &fri_root : commitments_part_of_proof.fri_roots) { + filled_fri_roots.value().push_back( + fill_merkle_node_value(fri_root)); + } + std::get<0>(filled.value()) = filled_fri_roots; + + std::get<1>(filled.value()) = fill_polynomial( + commitments_part_of_proof.final_polynomial + ); + + return filled; + } + + template + typename FRI::commitments_part_of_proof make_commitments_part_of_proof( + const commitments_part_of_proof_type, FRI> &filled + ) { + typename FRI::commitments_part_of_proof commitments_part_of_proof; + for (const auto &fri_root : std::get<0>(filled.value()).value()) { + commitments_part_of_proof.fri_roots.push_back( + make_merkle_node_value(fri_root) + ); + } + commitments_part_of_proof.final_polynomial = + make_polynomial( + std::get<1>(filled.value()) + ); + return commitments_part_of_proof; + } + } // namespace types } // namespace marshalling } // namespace crypto3 diff --git a/crypto3/libs/marshalling/zk/include/nil/crypto3/marshalling/zk/types/commitments/lpc.hpp b/crypto3/libs/marshalling/zk/include/nil/crypto3/marshalling/zk/types/commitments/lpc.hpp index d0ee08b67e..1cb4bb5915 100644 --- a/crypto3/libs/marshalling/zk/include/nil/crypto3/marshalling/zk/types/commitments/lpc.hpp +++ b/crypto3/libs/marshalling/zk/include/nil/crypto3/marshalling/zk/types/commitments/lpc.hpp @@ -237,7 +237,7 @@ namespace nil { // that the precommitment is a merkle tree. template struct precommitment_type && + std::enable_if_t && std::is_same< typename LPCScheme::precommitment_type, nil::crypto3::containers::merkle_tree< @@ -306,7 +306,7 @@ namespace nil { }; template - typename commitment_scheme_state, LPCScheme, + typename commitment_scheme_state, LPCScheme, std::enable_if_t>>::type fill_commitment_scheme(const LPCScheme &scheme) { using TTypeBase = nil::marshalling::field_type; @@ -353,14 +353,14 @@ namespace nil { filled_batch_fixed_values.value().push_back( nil::marshalling::types::integral(value)); } - + return result_type(std::make_tuple( filled_trees_keys, filled_trees_values, fill_commitment_params(scheme.get_fri_params()), field_element(scheme.get_etha()), filled_batch_fixed_keys, - filled_batch_fixed_values, + filled_batch_fixed_values, fill_commitment_preprocessed_data(scheme.get_fixed_polys_values()), fill_polys_evaluator( static_cast(scheme)) @@ -370,7 +370,7 @@ namespace nil { template LPCScheme make_commitment_scheme( typename commitment_scheme_state< - nil::marshalling::field_type, LPCScheme, + nil::marshalling::field_type, LPCScheme, std::enable_if_t>>::type& filled_commitment_scheme ) { using TTypeBase = typename nil::marshalling::field_type; @@ -383,7 +383,7 @@ namespace nil { BOOST_ASSERT(filled_tree_keys.size() == filled_tree_values.size()); for (std::size_t i = 0; i < filled_tree_keys.size(); i++) { - trees[std::size_t(filled_tree_keys[i].value())] = + trees[std::size_t(filled_tree_keys[i].value())] = make_merkle_tree( filled_tree_values[i]); } @@ -391,7 +391,7 @@ namespace nil { typename LPCScheme::fri_type::params_type fri_params = make_commitment_params( std::get<2>(filled_commitment_scheme.value())); typename LPCScheme::value_type etha = std::get<3>(filled_commitment_scheme.value()).value(); - + std::map batch_fixed; const auto& batch_fixed_keys = std::get<4>(filled_commitment_scheme.value()).value(); const auto& batch_fixed_values = std::get<5>(filled_commitment_scheme.value()).value(); @@ -402,7 +402,7 @@ namespace nil { batch_fixed[std::size_t(batch_fixed_keys[i].value())] = bool(batch_fixed_values[i].value()); } - typename LPCScheme::preprocessed_data_type fixed_polys_values = + typename LPCScheme::preprocessed_data_type fixed_polys_values = make_commitment_preprocessed_data( std::get<6>(filled_commitment_scheme.value())); @@ -413,6 +413,186 @@ namespace nil { return LPCScheme(evaluator, trees, fri_params, etha, batch_fixed, fixed_polys_values); } + + template + using initial_fri_proof_type = nil::marshalling::types::bundle< + TTypeBase, + std::tuple< + // typename basic_fri::round_proofs_batch_type fri_round_proof; + nil::crypto3::marshalling::types::round_proofs_batch_type< + TTypeBase, + typename LPCScheme::basic_fri>, + // typename basic_fri::commitments_part_of_proof fri_commitments_proof_part; + nil::crypto3::marshalling::types::commitments_part_of_proof_type< + TTypeBase, + typename LPCScheme::basic_fri> + > + >; + + template + initial_fri_proof_type, LPCScheme> + fill_initial_fri_proof(const typename LPCScheme::fri_proof_type &proof) { + using TTypeBase = nil::marshalling::field_type; + + nil::crypto3::marshalling::types::round_proofs_batch_type< + TTypeBase, + typename LPCScheme::basic_fri> filled_round_proofs_batch; + nil::crypto3::marshalling::types::commitments_part_of_proof_type< + TTypeBase, + typename LPCScheme::basic_fri> filled_commitments_part_of_proof; + + filled_round_proofs_batch = fill_round_proofs_batch( + proof.fri_round_proof); + + filled_commitments_part_of_proof = + fill_commitments_part_of_proof( + proof.fri_commitments_proof_part); + + return initial_fri_proof_type, LPCScheme>( + std::make_tuple(filled_round_proofs_batch, filled_commitments_part_of_proof)); + } + + template + typename LPCScheme::fri_proof_type + make_initial_fri_proof( + const initial_fri_proof_type, LPCScheme> &filled_proof + ) { + typename LPCScheme::fri_proof_type proof; + + proof.fri_round_proof = make_round_proofs_batch< + Endianness, typename LPCScheme::basic_fri>( + std::get<0>(filled_proof.value())); + + proof.fri_commitments_proof_part = make_commitments_part_of_proof< + Endianness, typename LPCScheme::basic_fri>( + std::get<1>(filled_proof.value())); + + return proof; + } + + template + using inital_eval_proof = nil::marshalling::types::bundle< + TTypeBase, + std::tuple< + // eval_storage_type z; + eval_storage, + // typename basic_fri::initial_proofs_batch_type initial_fri_proofs; + initial_proofs_batch_type + > + >; + + template + inital_eval_proof, LPCScheme> + fill_initial_eval_proof( + const typename LPCScheme::lpc_proof_type &intial_proof + ){ + using TTypeBase = nil::marshalling::field_type; + + auto filled_z = fill_eval_storage( + intial_proof.z); + + initial_proofs_batch_type< + nil::marshalling::field_type, typename LPCScheme::basic_fri> filled_fri_proof = + fill_initial_proofs_batch( + intial_proof.initial_fri_proofs + ); + + return inital_eval_proof, LPCScheme>( + std::tuple(filled_z, filled_fri_proof) + ); + } + + template + typename LPCScheme::lpc_proof_type + make_initial_eval_proof( + const inital_eval_proof, LPCScheme> &filled_proof + ) { + typename LPCScheme::lpc_proof_type proof; + + proof.z = make_eval_storage( + std::get<0>(filled_proof.value())); + + proof.initial_fri_proofs = make_initial_proofs_batch( + std::get<1>(filled_proof.value())); + + return proof; + } + + template + using aggregated_proof = nil::marshalling::types::bundle< + TTypeBase, + std::tuple< + // fri_proof_type fri_proof; + initial_fri_proof_type, + // std::vector intial_proofs_per_prover; + nil::marshalling::types::standard_array_list< + TTypeBase, + inital_eval_proof + >, + // typename LPCParams::grinding_type::output_type proof_of_work; + nil::marshalling::types::integral< + TTypeBase, typename LPCScheme::params_type::grinding_type::output_type> + > + >; + + template + aggregated_proof, LPCScheme> + fill_aggregated_proof( + const typename LPCScheme::aggregated_proof_type &proof, + const typename LPCScheme::fri_type::params_type &fri_params + ){ + using TTypeBase = nil::marshalling::field_type; + + initial_fri_proof_type filled_fri_proof = + fill_initial_fri_proof( + proof.fri_proof + ); + + nil::marshalling::types::standard_array_list< + TTypeBase, + inital_eval_proof + > filled_initial_proofs; + for (const auto &initial_proof : proof.intial_proofs_per_prover) { + filled_initial_proofs.value().push_back( + fill_initial_eval_proof( + initial_proof + ) + ); + } + + return aggregated_proof, LPCScheme>( + std::make_tuple( + filled_fri_proof, + filled_initial_proofs, + nil::marshalling::types::integral< + TTypeBase, typename LPCScheme::params_type::grinding_type::output_type>( + proof.proof_of_work) + ) + ); + } + + template + typename LPCScheme::aggregated_proof_type + make_aggregated_proof( + const aggregated_proof, LPCScheme> &filled_proof + ) { + typename LPCScheme::aggregated_proof_type proof; + + proof.fri_proof = make_initial_fri_proof( + std::get<0>(filled_proof.value())); + + for (const auto &filled_initial_proof : std::get<1>(filled_proof.value()).value()) { + proof.intial_proofs_per_prover.push_back( + make_initial_eval_proof( + filled_initial_proof + ) + ); + } + + proof.proof_of_work = std::get<2>(filled_proof.value()).value(); + + return proof; + } } // namespace types } // namespace marshalling } // namespace crypto3 diff --git a/crypto3/libs/marshalling/zk/include/nil/crypto3/marshalling/zk/types/placeholder/proof.hpp b/crypto3/libs/marshalling/zk/include/nil/crypto3/marshalling/zk/types/placeholder/proof.hpp index d7a228b1de..ed54ead563 100644 --- a/crypto3/libs/marshalling/zk/include/nil/crypto3/marshalling/zk/types/placeholder/proof.hpp +++ b/crypto3/libs/marshalling/zk/include/nil/crypto3/marshalling/zk/types/placeholder/proof.hpp @@ -47,6 +47,72 @@ namespace nil { namespace crypto3 { namespace marshalling { namespace types { + template + using placeholder_partial_evaluation_proof = nil::marshalling::types::bundle< + TTypeBase, + std::tuple< + // batch size integers + nil::marshalling::types::standard_array_list< + TTypeBase, + nil::marshalling::types::integral + >, + nil::marshalling::types::standard_array_list< + TTypeBase, + typename commitment::type + > + > + >; + + template + placeholder_partial_evaluation_proof, Proof> + fill_placeholder_partial_evaluation_proof( + const typename Proof::partial_proof_type &partial_proof) { + + using TTypeBase = nil::marshalling::field_type; + + // batch size integers + nil::marshalling::types::standard_array_list< + TTypeBase, + nil::marshalling::types::integral + > filled_batch_size; + // batch commitments + nil::marshalling::types::standard_array_list< + TTypeBase, + typename commitment::type + > filled_commitments; + for (const auto &[batch_index, commitment] : partial_proof.commitments) { + filled_batch_size.value().push_back( + nil::marshalling::types::integral(batch_index)); + filled_commitments.value().push_back( + fill_commitment(commitment)); + } + + return placeholder_partial_evaluation_proof(std::make_tuple( + filled_batch_size, + filled_commitments + )); + } + + template + typename Proof::partial_proof_type make_placeholder_partial_evaluation_proof( + const placeholder_partial_evaluation_proof< + nil::marshalling::field_type, Proof> &filled_proof + ) { + typename Proof::partial_proof_type partial_proof; + + // batch size integers + auto filled_batch_size = std::get<0>(filled_proof.value()).value(); + auto filled_commitments = std::get<1>(filled_proof.value()).value(); + + for (std::size_t i = 0; i < filled_batch_size.size(); i++) { + partial_proof.commitments[filled_batch_size[i].value()] = + make_commitment( + filled_commitments[i]); + } + + return partial_proof; + } + // This should be different for different commitment schemes! template using placeholder_evaluation_proof = nil::marshalling::types::bundle< diff --git a/crypto3/libs/marshalling/zk/test/lpc_commitment.cpp b/crypto3/libs/marshalling/zk/test/lpc_commitment.cpp index 413b479d4d..01fe347716 100644 --- a/crypto3/libs/marshalling/zk/test/lpc_commitment.cpp +++ b/crypto3/libs/marshalling/zk/test/lpc_commitment.cpp @@ -96,6 +96,33 @@ void test_lpc_proof(typename LPC::proof_type &proof, typename LPC::fri_type::par BOOST_CHECK(proof == constructed_val_read); } +template +void test_lpc_aggregated_proof( + typename LPC::aggregated_proof_type &proof, + typename LPC::fri_type::params_type fri_params +) { + using TTypeBase = nil::marshalling::field_type; + + auto filled_proof = + nil::crypto3::marshalling::types::fill_aggregated_proof(proof, fri_params); + auto _proof = nil::crypto3::marshalling::types::make_aggregated_proof(filled_proof); + BOOST_CHECK(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::aggregated_proof test_val_read; + auto read_iter = cv.begin(); + test_val_read.read(read_iter, cv.size()); + BOOST_CHECK(status == nil::marshalling::status_type::success); + typename LPC::aggregated_proof_type constructed_val_read = + nil::crypto3::marshalling::types::make_aggregated_proof(test_val_read); + BOOST_CHECK(proof == constructed_val_read); +} + // This function will test saving and restoring LPC commitment scheme state to a file/buffer. template void test_lpc_state_recovery(const LPC& lpc_commitment_scheme) { @@ -158,6 +185,20 @@ BOOST_FIXTURE_TEST_CASE(lpc_proof_test, zk::test_tools::random_test_initializer< test_lpc_proof(proof, fri_params); } +BOOST_FIXTURE_TEST_CASE(lpc_aggregated_proof_test, zk::test_tools::random_test_initializer) { + typename FRI::params_type fri_params(1, r + 1, lambda, 4); + + auto proof = generate_random_lpc_aggregated_proof( + final_polynomial_degree, 5, + fri_params.step_list, + lambda, + false, + alg_random_engines.template get_alg_engine(), + generic_random_engine + ); + test_lpc_aggregated_proof(proof, fri_params); +} + BOOST_AUTO_TEST_SUITE_END() BOOST_AUTO_TEST_SUITE(marshalling_real) diff --git a/crypto3/libs/marshalling/zk/test/placeholder_proof.cpp b/crypto3/libs/marshalling/zk/test/placeholder_proof.cpp index 1613efd676..89e25d4030 100644 --- a/crypto3/libs/marshalling/zk/test/placeholder_proof.cpp +++ b/crypto3/libs/marshalling/zk/test/placeholder_proof.cpp @@ -220,6 +220,36 @@ void test_placeholder_proof(const ProofType &proof, const CommitmentParamsType& BOOST_CHECK(proof == constructed_val_read); } +template +void test_placeholder_partial_proof(const typename ProofType::partial_proof_type &proof, const CommitmentParamsType& params, std::string output_file = "") { + + using namespace nil::crypto3::marshalling; + + using TTypeBase = nil::marshalling::field_type; + using proof_marshalling_type = nil::crypto3::marshalling::types::placeholder_partial_evaluation_proof; + + auto filled_placeholder_proof = types::fill_placeholder_partial_evaluation_proof(proof); + ProofType _proof = types::make_placeholder_partial_evaluation_proof(filled_placeholder_proof); + BOOST_CHECK(_proof == proof); + + std::vector cv; + cv.resize(filled_placeholder_proof.length(), 0x00); + auto write_iter = cv.begin(); + auto status = filled_placeholder_proof.write(write_iter, cv.size()); + BOOST_CHECK(status == nil::marshalling::status_type::success); + + if (output_file != "") { + print_placeholder_proof(cv.cbegin(), cv.cend(), false, output_file.c_str()); + } + + proof_marshalling_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); + auto constructed_val_read = types::make_placeholder_partial_evaluation_proof(test_val_read); + BOOST_CHECK(proof == constructed_val_read); +} + bool has_argv(std::string name){ bool result = false; for (std::size_t i = 0; i < std::size_t(boost::unit_test::framework::master_test_suite().argc); i++) { @@ -241,6 +271,9 @@ void print_placeholder_proof_with_params( std::filesystem::create_directory(folder_name); test_placeholder_proof>( proof, commitment_scheme.get_commitment_params(), folder_name + "/proof.bin"); + test_placeholder_partial_proof>( + proof, commitment_scheme.get_commitment_params(), folder_name + "/partial_proof.bin" + ); print_placeholder_params ( preprocessed_data, commitment_scheme, table_description, folder_name + "/params.json", folder_name ); @@ -353,6 +386,7 @@ BOOST_FIXTURE_TEST_CASE(proof_marshalling_test, test_tools::random_test_initiali ); } else { test_placeholder_proof>(lpc_proof, fri_params); + test_placeholder_partial_proof>(lpc_proof, fri_params); } auto verifier_res = placeholder_verifier::process( lpc_preprocessed_public_data.common_data, lpc_proof, desc, constraint_system, lpc_scheme @@ -447,6 +481,7 @@ BOOST_FIXTURE_TEST_CASE(proof_marshalling_test, test_tools::random_test_initiali print_public_input(desc.public_input_columns == 0? std::vector({}):assignments.public_input(0), "circuit1/public_input.inp"); } else { test_placeholder_proof>(lpc_proof, fri_params); + test_placeholder_partial_proof>(lpc_proof, fri_params); } auto verifier_res = placeholder_verifier::process( lpc_preprocessed_public_data.common_data, lpc_proof, desc, constraint_system, lpc_scheme @@ -548,6 +583,7 @@ BOOST_FIXTURE_TEST_CASE(proof_marshalling_test, test_tools::random_test_initiali print_public_input(desc.public_input_columns == 0? std::vector({}):assignments.public_input(0), "circuit2/public_input.inp"); }else { test_placeholder_proof>(lpc_proof, fri_params); + test_placeholder_partial_proof>(lpc_proof, fri_params); } verifier_res = placeholder_verifier::process( @@ -637,6 +673,7 @@ BOOST_FIXTURE_TEST_CASE(proof_marshalling_test, test_tools::random_test_initiali print_public_input(desc.public_input_columns == 0? std::vector({}):assignments.public_input(0), "circuit3/public_input.inp"); } else { test_placeholder_proof>(proof, fri_params); + test_placeholder_partial_proof>(proof, fri_params); } bool verifier_res = placeholder_verifier::process( @@ -727,6 +764,7 @@ BOOST_FIXTURE_TEST_CASE(proof_marshalling_test, test_tools::random_test_initiali print_public_input(desc.public_input_columns == 0? std::vector({}):assignments.public_input(0), "circuit4/public_input.inp"); }else { test_placeholder_proof>(proof, fri_params); + test_placeholder_partial_proof>(proof, fri_params); } bool verifier_res = placeholder_verifier::process( @@ -816,6 +854,7 @@ BOOST_FIXTURE_TEST_CASE(proof_marshalling_test100, test_tools::random_test_initi print_public_input(desc.public_input_columns == 0? std::vector({}):assignments.public_input(0), "circuit5_chunk100/public_input.inp"); }else { test_placeholder_proof>(proof, fri_params); + test_placeholder_partial_proof>(proof, fri_params); } bool verifier_res = placeholder_verifier::process( @@ -872,6 +911,7 @@ BOOST_FIXTURE_TEST_CASE(proof_marshalling_test, test_tools::random_test_initiali print_public_input(desc.public_input_columns == 0? std::vector({}):assignments.public_input(0), "circuit5_chunk10/public_input.inp"); }else { test_placeholder_proof>(proof, fri_params); + test_placeholder_partial_proof>(proof, fri_params); } bool verifier_res = placeholder_verifier::process( @@ -961,6 +1001,7 @@ BOOST_FIXTURE_TEST_CASE(proof_marshalling_test, test_tools::random_test_initiali print_public_input(desc.public_input_columns == 0? std::vector({}):assignments.public_input(0), "circuit6/public_input.inp"); }else { test_placeholder_proof>(proof, fri_params); + test_placeholder_partial_proof>(proof, fri_params); } bool verifier_res = placeholder_verifier::process( preprocessed_public_data.common_data, proof, desc, constraint_system, lpc_scheme); @@ -1047,6 +1088,7 @@ BOOST_FIXTURE_TEST_CASE(proof_marshalling_test, test_tools::random_test_initiali print_public_input(desc.public_input_columns == 0? std::vector({}):assignments.public_input(0), "circuit7/public_input.inp"); }else { test_placeholder_proof>(proof, fri_params); + test_placeholder_partial_proof>(proof, fri_params); } bool verifier_res = placeholder_verifier::process( preprocessed_public_data.common_data, proof, desc, constraint_system, lpc_scheme); @@ -1101,6 +1143,7 @@ BOOST_FIXTURE_TEST_CASE(proof_marshalling_test10, test_tools::random_test_initia print_public_input(desc.public_input_columns == 0? std::vector({}):assignments.public_input(0), "circuit7_chunk10/public_input.inp"); }else { test_placeholder_proof>(proof, fri_params); + test_placeholder_partial_proof>(proof, fri_params); } bool verifier_res = placeholder_verifier::process( preprocessed_public_data.common_data, proof, desc, constraint_system, lpc_scheme); diff --git a/crypto3/libs/marshalling/zk/test/random_test_data_generation.hpp b/crypto3/libs/marshalling/zk/test/random_test_data_generation.hpp index ac21739f24..5301742098 100644 --- a/crypto3/libs/marshalling/zk/test/random_test_data_generation.hpp +++ b/crypto3/libs/marshalling/zk/test/random_test_data_generation.hpp @@ -259,6 +259,65 @@ typename FRI::proof_type generate_random_fri_proof( return res; } +template +typename FRI::initial_proofs_batch_type generate_random_inital_proofs_batch( + std::size_t lambda, + std::size_t max_batch_size, + std::vector step_list, + nil::crypto3::random::algebraic_engine &alg_rnd, + boost::random::mt11213b &rnd +) { + typename FRI::initial_proofs_batch_type res; + res.initial_proofs.resize(lambda); + for (std::size_t i = 0; i < lambda; i++) { + std::map initial_proof; + for (const auto &it : step_list) { + initial_proof[it] = generate_random_fri_initial_proof(max_batch_size, it, alg_rnd, rnd); + } + res.initial_proofs[i] = std::move(initial_proof); + } + return res; +} + +template +typename FRI::round_proofs_batch_type generate_random_round_proofs_batch( + std::size_t lambda, + std::size_t max_batch_size, + std::vector step_list, + nil::crypto3::random::algebraic_engine &alg_rnd, + boost::random::mt11213b &rnd +) { + typename FRI::round_proofs_batch_type res; + res.round_proofs.resize(lambda); + for (std::size_t i = 0; i < lambda; i++) { + res.round_proofs[i].resize(step_list.size()); + for (std::size_t j = 0; j < step_list.size(); j++) { + res.round_proofs[i][j] = generate_random_fri_round_proof(step_list[j], alg_rnd, rnd); + } + } + return res; +} + +template +typename FRI::commitments_part_of_proof generate_random_commitments_part_of_proof( + std::size_t d, //final polynomial degree + std::size_t max_batch_size, + std::vector step_list, + std::size_t lambda, + bool use_grinding, + nil::crypto3::random::algebraic_engine &alg_rnd, + boost::random::mt11213b &rnd +) { + typename FRI::commitments_part_of_proof res; + res.fri_roots.resize(step_list.size()); + for (std::size_t k = 0; k < step_list.size(); k++) { + res.fri_roots[k] = nil::crypto3::hash( + generate_random_data(1, rnd).at(0) + ); + } + res.final_polynomial = generate_random_polynomial(d, alg_rnd); + return res; +} template typename LPC::proof_type generate_random_lpc_proof( @@ -289,6 +348,83 @@ typename LPC::proof_type generate_random_lpc_proof( return res; } +template +typename LPC::fri_proof_type generate_random_lpc_intial_fri_proof( + std::size_t d, //final polynomial degree + std::size_t max_batch_size, + std::vector step_list, + std::size_t lambda, + std::size_t use_grinding, + nil::crypto3::random::algebraic_engine &alg_rnd, + boost::random::mt11213b &rnd +) { + typename LPC::fri_proof_type res; + + res.fri_round_proof = generate_random_round_proofs_batch( + lambda, max_batch_size, step_list, alg_rnd, rnd); + + res.fri_commitments_proof_part = generate_random_commitments_part_of_proof( + d, max_batch_size, step_list, lambda, use_grinding, alg_rnd, rnd); + + return res; +} + +template +typename LPC::lpc_proof_type generate_random_lpc_inital_proof( + std::size_t d, //final polynomial degree + std::size_t max_batch_size, + std::vector step_list, + std::size_t lambda, + std::size_t use_grinding, + nil::crypto3::random::algebraic_engine &alg_rnd, + boost::random::mt11213b &rnd +) { + typename LPC::lpc_proof_type res; + + nil::crypto3::marshalling::types::batch_info_type batch_info; + for (std::size_t i = 0; i < 6; i++) { + batch_info[rnd()%6] = rnd()%9 + 1; + } + for (const auto&it: batch_info) { + res.z.set_batch_size(it.first, it.second); + for( std::size_t i = 0; i < it.second; i++){ + res.z.set_poly_points_number(it.first, i, rnd()%3 + 1); + for( std::size_t j = 0; j < res.z.get_poly_points_number(it.first, i); j++){ + res.z.set(it.first, i, j, alg_rnd()); + } + } + } + res.initial_fri_proofs = generate_random_inital_proofs_batch( + lambda, max_batch_size, step_list, alg_rnd, rnd); + + return res; +} + +template +typename LPC::aggregated_proof_type generate_random_lpc_aggregated_proof( + std::size_t d, //final polynomial degree + std::size_t max_batch_size, + std::vector step_list, + std::size_t lambda, + std::size_t use_grinding, + nil::crypto3::random::algebraic_engine &alg_rnd, + boost::random::mt11213b &rnd +) { + typename LPC::aggregated_proof_type res; + + res.fri_proof = generate_random_lpc_intial_fri_proof( + d, max_batch_size, step_list, lambda, use_grinding, alg_rnd, rnd); + + res.intial_proofs_per_prover.resize(lambda); + for (std::size_t i = 0; i < lambda; i++) { + res.intial_proofs_per_prover[i] = generate_random_lpc_inital_proof( + d, max_batch_size, step_list, lambda, use_grinding, alg_rnd, rnd); + } + + res.proof_of_work = rnd(); + + return res; +} template math::polynomial_dfs diff --git a/crypto3/libs/zk/include/nil/crypto3/zk/commitments/detail/polynomial/basic_fri.hpp b/crypto3/libs/zk/include/nil/crypto3/zk/commitments/detail/polynomial/basic_fri.hpp index a32ef505ec..65094a2595 100644 --- a/crypto3/libs/zk/include/nil/crypto3/zk/commitments/detail/polynomial/basic_fri.hpp +++ b/crypto3/libs/zk/include/nil/crypto3/zk/commitments/detail/polynomial/basic_fri.hpp @@ -235,7 +235,7 @@ namespace nil { } // For the last round it's final_polynomial's values - + // Values for the next round. polynomial_values_type y; @@ -415,7 +415,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 +1051,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 +1063,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 +1117,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( diff --git a/crypto3/libs/zk/include/nil/crypto3/zk/snark/systems/plonk/placeholder/proof.hpp b/crypto3/libs/zk/include/nil/crypto3/zk/snark/systems/plonk/placeholder/proof.hpp index c5cd9b9d35..80f40a64e3 100644 --- a/crypto3/libs/zk/include/nil/crypto3/zk/snark/systems/plonk/placeholder/proof.hpp +++ b/crypto3/libs/zk/include/nil/crypto3/zk/snark/systems/plonk/placeholder/proof.hpp @@ -88,6 +88,7 @@ namespace nil { 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; + using partial_proof_type = placeholder_partial_proof; struct evaluation_proof { // TODO: remove it! @@ -105,6 +106,12 @@ namespace nil { placeholder_proof() = default; + placeholder_proof(const partial_proof_type &partial_proof) : + placeholder_partial_proof(partial_proof) {} + + placeholder_proof(const partial_proof_type &partial_proof, const evaluation_proof &eval_proof) : + placeholder_partial_proof(partial_proof), eval_proof(eval_proof) {} + bool operator==(const placeholder_proof &rhs) const { return placeholder_partial_proof::operator==(rhs) && eval_proof == rhs.eval_proof;