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 7dbaa92763..fb05df1de2 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 027f3100b8..534f23e67d 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 4d1e0f510b..318e0bb06f 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 @@ -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; @@ -268,25 +268,63 @@ namespace nil { std::vector round_proofs; }; - struct proof_type { - 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 ){ -// return false; -// } + struct partial_proof_type { + virtual ~partial_proof_type() = default; + + bool operator==(const partial_proof_type &rhs) const { +// if( FRI::use_grinding && proof_of_work != rhs.proof_of_work ){ +// 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