diff --git a/libs/blueprint/include/nil/blueprint/basic_non_native_policy.hpp b/libs/blueprint/include/nil/blueprint/basic_non_native_policy.hpp index d57b1f1e7..f53e192f2 100644 --- a/libs/blueprint/include/nil/blueprint/basic_non_native_policy.hpp +++ b/libs/blueprint/include/nil/blueprint/basic_non_native_policy.hpp @@ -253,8 +253,6 @@ namespace nil { typedef std::array non_native_var_type; }; - - /* * Native element type. */ diff --git a/libs/marshalling/zk/include/nil/crypto3/marshalling/zk/types/plonk/assignment_table.hpp b/libs/marshalling/zk/include/nil/crypto3/marshalling/zk/types/plonk/assignment_table.hpp index 2621c90c8..d96324832 100644 --- a/libs/marshalling/zk/include/nil/crypto3/marshalling/zk/types/plonk/assignment_table.hpp +++ b/libs/marshalling/zk/include/nil/crypto3/marshalling/zk/types/plonk/assignment_table.hpp @@ -43,6 +43,60 @@ namespace nil { namespace marshalling { namespace types { + ///////////////////////////////////////////////////////////////////////////////////////////////////////////// + ///////// Marshalling the assignment table description. + ///////////////////////////////////////////////////////////////////////////////////////////////////////////// + + // TODO(we may consider to use this construct when marshalling the assignment table.) + template + using plonk_assignment_table_description = nil::marshalling::types::bundle< + TTypeBase, std::tuple< + nil::marshalling::types::integral, // witness_amount + nil::marshalling::types::integral, // public_input_amount + nil::marshalling::types::integral, // constant_amount + nil::marshalling::types::integral, // selector_amount + + nil::marshalling::types::integral, // usable_rows + nil::marshalling::types::integral // rows_amount + > + >; + + template + plonk_assignment_table_description> fill_assignment_table_description( + const zk::snark::plonk_table_description& desc + ) { + using TTypeBase = nil::marshalling::field_type; + using result_type = plonk_assignment_table_description>; + using value_type = typename FieldType::value_type; + + return result_type(std::move(std::make_tuple( + nil::marshalling::types::integral(desc.witness_columns), + nil::marshalling::types::integral(desc.public_input_columns), + nil::marshalling::types::integral(desc.constant_columns), + nil::marshalling::types::integral(desc.selector_columns), + nil::marshalling::types::integral(desc.usable_rows_amount), + nil::marshalling::types::integral(desc.rows_amount)))); + } + + template + zk::snark::plonk_table_description make_assignment_table_description( + const plonk_assignment_table_description> &filled_description) { + + zk::snark::plonk_table_description desc( + std::get<0>(filled_description.value()).value(), + std::get<1>(filled_description.value()).value(), + std::get<2>(filled_description.value()).value(), + std::get<3>(filled_description.value()).value(), + std::get<4>(filled_description.value()).value(), + std::get<5>(filled_description.value()).value() + ); + return desc; + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////// + ///////// Marshalling the assignment table. + ///////////////////////////////////////////////////////////////////////////////////////////////////////////// + template using plonk_assignment_table = nil::marshalling::types::bundle< TTypeBase, std::tuple< @@ -143,7 +197,7 @@ namespace nil { plonk_assignment_table, PlonkTable> fill_assignment_table( std::size_t usable_rows, const PlonkTable &assignments - ){ + ) { using TTypeBase = nil::marshalling::field_type; using result_type = plonk_assignment_table, PlonkTable>; using value_type = typename PlonkTable::field_type::value_type; @@ -228,6 +282,8 @@ namespace nil { typename PlonkTable::public_table_type(public_inputs, constants, selectors) )); } + + } //namespace types } // namespace marshalling } // namespace crypto3 diff --git a/libs/marshalling/zk/test/plonk_assignment_table.cpp b/libs/marshalling/zk/test/plonk_assignment_table.cpp index 2d5b58ebc..353d779b8 100644 --- a/libs/marshalling/zk/test/plonk_assignment_table.cpp +++ b/libs/marshalling/zk/test/plonk_assignment_table.cpp @@ -60,6 +60,30 @@ void print_hex_byteblob(std::ostream &os, TIter iter_begin, TIter iter_end, bool } } +template +void test_assignment_table_description(const PlonkTableDescription& val) { + using TTypeBase = nil::marshalling::field_type; + using FieldType = typename PlonkTableDescription::field_type; + using value_marshalling_type = nil::crypto3::marshalling::types::plonk_assignment_table_description; + + auto filled_val = types::fill_assignment_table_description(val); + auto table_desc = types::make_assignment_table_description(filled_val); + BOOST_CHECK(val == table_desc); + + std::vector cv; + cv.resize(filled_val.length(), 0x00); + + auto write_iter = cv.begin(); + nil::marshalling::status_type status = filled_val.write(write_iter, cv.size()); + value_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); + table_desc = types::make_assignment_table_description(test_val_read); + + BOOST_CHECK(val == table_desc); +} + template void test_assignment_table(std::size_t usable_rows, PlonkTable val, std::string folder_name = "") { using TTypeBase = nil::marshalling::field_type; @@ -148,7 +172,10 @@ BOOST_FIXTURE_TEST_CASE(assignment_table_marshalling_test, test_tools::random_te test_assignment_table(desc.usable_rows_amount, assignments, "circuit1"); else test_assignment_table(desc.usable_rows_amount, assignments); + + test_assignment_table_description>(desc); } + BOOST_AUTO_TEST_SUITE_END() BOOST_AUTO_TEST_SUITE(placeholder_circuit2) @@ -209,6 +236,8 @@ BOOST_FIXTURE_TEST_CASE(assignment_table_marshalling_test, test_tools::random_te test_assignment_table(desc.usable_rows_amount, assignments, "circuit2"); else test_assignment_table(desc.usable_rows_amount, assignments); + + test_assignment_table_description>(desc); } BOOST_AUTO_TEST_SUITE_END() @@ -266,6 +295,8 @@ BOOST_FIXTURE_TEST_CASE(assignment_table_marshalling_test, test_tools::random_te test_assignment_table(desc.usable_rows_amount, assignments, "circuit3"); else test_assignment_table(desc.usable_rows_amount, assignments); + + test_assignment_table_description>(desc); } BOOST_AUTO_TEST_SUITE_END() @@ -325,6 +356,8 @@ BOOST_FIXTURE_TEST_CASE(assignment_table_marshalling_test, test_tools::random_te test_assignment_table(desc.usable_rows_amount, assignments, "circuit4"); else test_assignment_table(desc.usable_rows_amount, assignments); + + test_assignment_table_description>(desc); } BOOST_AUTO_TEST_SUITE_END() @@ -386,6 +419,8 @@ BOOST_FIXTURE_TEST_CASE(assignment_table_marshalling_test, test_tools::random_te test_assignment_table(desc.usable_rows_amount, assignments, "circuit5"); else test_assignment_table(desc.usable_rows_amount, assignments); + + test_assignment_table_description>(desc); } BOOST_AUTO_TEST_SUITE_END() @@ -442,6 +477,8 @@ BOOST_FIXTURE_TEST_CASE(assignment_table_marshalling_test, test_tools::random_te test_assignment_table(desc.usable_rows_amount, assignments, "circuit6"); else test_assignment_table(desc.usable_rows_amount, assignments); + + test_assignment_table_description>(desc); } BOOST_AUTO_TEST_SUITE_END() @@ -498,5 +535,7 @@ BOOST_FIXTURE_TEST_CASE(assignment_table_marshalling_test, test_tools::random_te test_assignment_table(desc.usable_rows_amount, assignments, "circuit7"); else test_assignment_table(desc.usable_rows_amount, assignments); + + test_assignment_table_description>(desc); } BOOST_AUTO_TEST_SUITE_END() diff --git a/libs/zk/include/nil/crypto3/zk/commitments/batched_commitment.hpp b/libs/zk/include/nil/crypto3/zk/commitments/batched_commitment.hpp index c34a020dd..1a0d884e0 100644 --- a/libs/zk/include/nil/crypto3/zk/commitments/batched_commitment.hpp +++ b/libs/zk/include/nil/crypto3/zk/commitments/batched_commitment.hpp @@ -101,6 +101,13 @@ namespace nil { } } + // This function is called from verifier directly, without actually committing to the + // polynomials. + void state_commited(std::size_t index) { + _locked[index] = true; + _points[index].resize(_polys[index].size()); + } + protected: math::polynomial get_V( const std::vector &points) const { @@ -160,16 +167,16 @@ namespace nil { std::vector> get_unique_point_sets_list() const{ std::vector> unique_points; - for(auto const &[k, point]:_points){ - for( std::size_t i = 0; i < point.size(); i++ ){ + for (auto const &[k, point]:_points) { + for (std::size_t i = 0; i < point.size(); i++) { bool found = false; - for( std::size_t j = 0; j < unique_points.size(); j++ ){ + for (std::size_t j = 0; j < unique_points.size(); j++) { if( unique_points[j] == point[i] ){ found = true; break; } } - if( !found ){ + if (!found) { unique_points.push_back(point[i]); } } @@ -198,12 +205,6 @@ namespace nil { return eval_map; } - - void state_commited(std::size_t index){ - _locked[index] = true; - _points[index].resize(_polys[index].size()); - } - void eval_polys() { for(auto const &[k, poly] : _polys) { _z.set_batch_size(k, poly.size()); @@ -249,7 +250,7 @@ namespace nil { // We can add points only after polynomails are commited. BOOST_ASSERT(_locked[batch_id]); - for(std::size_t i = 0; i < _points[batch_id].size(); i++){ + for (std::size_t i = 0; i < _points[batch_id].size(); i++) { _points[batch_id][i].push_back(point); } } @@ -260,6 +261,11 @@ namespace nil { // We can add points only after polynomails are commited. BOOST_ASSERT(_locked[batch_id]); + // When called from verifier, this vector is not properly resized, so we resize to + // the required size when needed. + if (poly_id + 1 > _points[batch_id].size()) + _points[batch_id].resize(poly_id + 1); + _points[batch_id][poly_id].push_back(point); } @@ -272,13 +278,16 @@ namespace nil { } // This function don't check evaluation points repeats - void append_eval_points(std::size_t batch_id, std::size_t poly_id, std::set points){ - BOOST_ASSERT(_locked[batch_id]); // We can add points only after polynomails are commited. + void append_eval_points(std::size_t batch_id, std::size_t poly_id, + std::set points) { + // We can add points only after polynomails are commited. + BOOST_ASSERT(_locked[batch_id]); + _points[batch_id][poly_id].insert(_points[batch_id][poly_id].end(), points.begin(), points.end()); } - void set_batch_size(std::size_t batch_id, std::size_t batch_size){ - if( _points.find(batch_id) == _points.end() ){ + void set_batch_size(std::size_t batch_id, std::size_t batch_size) { + if (_points.find(batch_id) == _points.end()) { _points[batch_id] = {}; } _points[batch_id].resize(batch_size); 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 f99d49e71..000a2fe17 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 @@ -1087,7 +1087,7 @@ namespace nil { } } - //Calculate combinedQ values + // Calculate combinedQ values typename FRI::field_type::value_type theta_acc = FRI::field_type::value_type::one(); typename FRI::polynomial_values_type y; typename FRI::polynomial_values_type combined_eval_values; @@ -1123,7 +1123,8 @@ namespace nil { typename FRI::polynomial_values_type y_next; for (std::size_t i = 0; i < fri_params.step_list.size(); i++) { coset_size = 1 << fri_params.step_list[i]; - if (query_proof.round_proofs[i].p.root() != proof.fri_roots[i]) return false; + if (query_proof.round_proofs[i].p.root() != proof.fri_roots[i]) + return false; std::tie(s, s_indices) = calculate_s(x_index, fri_params.step_list[i], fri_params.D[t]); diff --git a/libs/zk/include/nil/crypto3/zk/snark/arithmetization/plonk/table_description.hpp b/libs/zk/include/nil/crypto3/zk/snark/arithmetization/plonk/table_description.hpp index b716482be..bda775459 100644 --- a/libs/zk/include/nil/crypto3/zk/snark/arithmetization/plonk/table_description.hpp +++ b/libs/zk/include/nil/crypto3/zk/snark/arithmetization/plonk/table_description.hpp @@ -36,8 +36,12 @@ namespace nil { namespace zk { namespace snark { + // TODO(martun): this class actually does not depend on the FieldType. template struct plonk_table_description { + // Needed for marshalling. + using field_type = FieldType; + std::size_t witness_columns; std::size_t public_input_columns; std::size_t constant_columns; diff --git a/libs/zk/include/nil/crypto3/zk/snark/systems/plonk/placeholder/preprocessor.hpp b/libs/zk/include/nil/crypto3/zk/snark/systems/plonk/placeholder/preprocessor.hpp index 56918f0d5..fd66fb36d 100644 --- a/libs/zk/include/nil/crypto3/zk/snark/systems/plonk/placeholder/preprocessor.hpp +++ b/libs/zk/include/nil/crypto3/zk/snark/systems/plonk/placeholder/preprocessor.hpp @@ -80,12 +80,14 @@ namespace nil { static std::size_t permutation_partitions_num( std::size_t permutation_size, std::size_t max_quotient_chunks - ){ - if( permutation_size == 0 ) return 0; - if( max_quotient_chunks == 0 ){ + ) { + if (permutation_size == 0) return 0; + if (max_quotient_chunks == 0) { return 1; } - return (permutation_size % (max_quotient_chunks - 1) == 0)? permutation_size / (max_quotient_chunks - 1) : permutation_size / (max_quotient_chunks - 1) + 1; + return (permutation_size % (max_quotient_chunks - 1) == 0) ? + permutation_size / (max_quotient_chunks - 1) : + permutation_size / (max_quotient_chunks - 1) + 1; } struct preprocessed_data_type { @@ -160,6 +162,8 @@ namespace nil { std::uint32_t permutation_parts; std::uint32_t lookup_parts; + common_data_type(const common_data_type& other) = default; + // Constructor with pregenerated domain common_data_type( std::shared_ptr> D, 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 8ec7b78d8..e05a6ef97 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 @@ -375,8 +375,9 @@ namespace nil { if( constraint_system.copy_constraints().size() > 0 ) _commitment_scheme.append_eval_point(PERMUTATION_BATCH, 0, _proof.eval_proof.challenge * _omega); - if(_is_lookup_enabled){ - _commitment_scheme.append_eval_point(PERMUTATION_BATCH, preprocessed_public_data.common_data.permutation_parts , _proof.eval_proof.challenge * _omega); + if(_is_lookup_enabled) { + _commitment_scheme.append_eval_point(PERMUTATION_BATCH, preprocessed_public_data.common_data.permutation_parts, + _proof.eval_proof.challenge * _omega); _commitment_scheme.append_eval_point(LOOKUP_BATCH, _proof.eval_proof.challenge); _commitment_scheme.append_eval_point(LOOKUP_BATCH, _proof.eval_proof.challenge * _omega); _commitment_scheme.append_eval_point(LOOKUP_BATCH, _proof.eval_proof.challenge * @@ -391,7 +392,7 @@ namespace nil { std::size_t start_index = preprocessed_public_data.identity_polynomials.size() + preprocessed_public_data.permutation_polynomials.size() + 2; - for( i = 0; i < start_index; i++){ + for( i = 0; i < start_index; i++) { _commitment_scheme.append_eval_point(FIXED_VALUES_BATCH, i, _proof.eval_proof.challenge); } diff --git a/libs/zk/include/nil/crypto3/zk/snark/systems/plonk/placeholder/verifier.hpp b/libs/zk/include/nil/crypto3/zk/snark/systems/plonk/placeholder/verifier.hpp index fbd573402..293bcb106 100644 --- a/libs/zk/include/nil/crypto3/zk/snark/systems/plonk/placeholder/verifier.hpp +++ b/libs/zk/include/nil/crypto3/zk/snark/systems/plonk/placeholder/verifier.hpp @@ -61,6 +61,8 @@ namespace nil { constexpr static const std::size_t f_parts = 8; public: + + // TODO(martun): this function is pretty similar to the one in prover, we should de-duplicate it. static void generate_evaluation_points( commitment_scheme_type &_commitment_scheme, const typename public_preprocessor_type::preprocessed_data_type::common_data_type &common_data, @@ -69,7 +71,12 @@ namespace nil { typename FieldType::value_type challenge, bool _is_lookup_enabled ) { - PROFILE_SCOPE("evaluation_points_generated_time"); + // We cannot add eval points unless everything is committed, so when verifying assume it's committed. + _commitment_scheme.state_commited(FIXED_VALUES_BATCH); + _commitment_scheme.state_commited(VARIABLE_VALUES_BATCH); + _commitment_scheme.state_commited(PERMUTATION_BATCH); + _commitment_scheme.state_commited(QUOTIENT_BATCH); + _commitment_scheme.state_commited(LOOKUP_BATCH); const std::size_t witness_columns = table_description.witness_columns; const std::size_t public_input_columns = table_description.public_input_columns; @@ -116,7 +123,7 @@ namespace nil { std::size_t i = 0; std::size_t start_index = common_data.permuted_columns.size() * 2 + 2; - for( i = 0; i < start_index; i++){ + for( i = 0; i < start_index; i++) { _commitment_scheme.append_eval_point(FIXED_VALUES_BATCH, i, challenge); } @@ -156,11 +163,12 @@ namespace nil { numerator *= typename FieldType::value_type(table_description.rows_amount).inversed(); // If public input sizes are set, all of them should be set. - if(constraint_system.public_input_sizes_num() != 0 && constraint_system.public_input_sizes_num() != table_description.public_input_columns){ + if (constraint_system.public_input_sizes_num() != 0 && + constraint_system.public_input_sizes_num() != table_description.public_input_columns) { return false; } - for( std::size_t i = 0; i < public_input.size(); ++i ){ + for (std::size_t i = 0; i < public_input.size(); ++i) { typename FieldType::value_type value = FieldType::value_type::zero(); std::size_t max_size = public_input[i].size(); if (constraint_system.public_input_sizes_num() != 0) @@ -171,7 +179,7 @@ namespace nil { omega_pow = omega_pow * omega; } value *= numerator; - if( value != proof.eval_proof.eval_proof.z.get(VARIABLE_VALUES_BATCH, table_description.witness_columns + i, 0) ) + if (value != proof.eval_proof.eval_proof.z.get(VARIABLE_VALUES_BATCH, table_description.witness_columns + i, 0) ) { return false; } @@ -204,13 +212,15 @@ namespace nil { std::vector special_selector_values(3); special_selector_values[0] = common_data.lagrange_0.evaluate(proof.eval_proof.challenge); - special_selector_values[1] = proof.eval_proof.eval_proof.z.get(FIXED_VALUES_BATCH, 2*common_data.permuted_columns.size(), 0); - special_selector_values[2] = proof.eval_proof.eval_proof.z.get(FIXED_VALUES_BATCH, 2*common_data.permuted_columns.size() + 1, 0); + special_selector_values[1] = proof.eval_proof.eval_proof.z.get( + FIXED_VALUES_BATCH, 2*common_data.permuted_columns.size(), 0); + special_selector_values[2] = proof.eval_proof.eval_proof.z.get( + FIXED_VALUES_BATCH, 2*common_data.permuted_columns.size() + 1, 0); // 4. prepare evaluaitons of the polynomials that are copy-constrained std::array F; std::size_t permutation_size = (proof.eval_proof.eval_proof.z.get_batch_size(FIXED_VALUES_BATCH) - 2 - constant_columns - selector_columns) / 2; - if( constraint_system.copy_constraints().size() > 0 ){ + if (constraint_system.copy_constraints().size() > 0) { // Permutation polys std::vector permuted_polys_global_indices = common_data.permuted_columns; std::vector f(permutation_size); @@ -361,7 +371,7 @@ namespace nil { BOOST_ASSERT(challenge == proof.eval_proof.challenge); commitment_scheme.set_batch_size(VARIABLE_VALUES_BATCH, proof.eval_proof.eval_proof.z.get_batch_size(VARIABLE_VALUES_BATCH)); - if( is_lookup_enabled || constraint_system.copy_constraints().size()) + if (is_lookup_enabled || constraint_system.copy_constraints().size()) commitment_scheme.set_batch_size(PERMUTATION_BATCH, proof.eval_proof.eval_proof.z.get_batch_size(PERMUTATION_BATCH)); commitment_scheme.set_batch_size(QUOTIENT_BATCH, proof.eval_proof.eval_proof.z.get_batch_size(QUOTIENT_BATCH)); if (is_lookup_enabled) diff --git a/libs/zk/test/systems/plonk/placeholder/placeholder_test_runner.hpp b/libs/zk/test/systems/plonk/placeholder/placeholder_test_runner.hpp index bae48452d..95adf512d 100644 --- a/libs/zk/test/systems/plonk/placeholder/placeholder_test_runner.hpp +++ b/libs/zk/test/systems/plonk/placeholder/placeholder_test_runner.hpp @@ -104,6 +104,9 @@ struct placeholder_test_runner { lpc_preprocessed_public_data, std::move(lpc_preprocessed_private_data), desc, constraint_system, lpc_scheme); + // We must not use the same instance of lpc_scheme. + lpc_scheme_type verifier_lpc_scheme(fri_params); + bool verifier_res = placeholder_verifier::process( lpc_preprocessed_public_data.common_data, lpc_proof, desc, constraint_system, lpc_scheme); return verifier_res;