diff --git a/include/nil/crypto3/zk/commitments/detail/polynomial/basic_fri.hpp b/include/nil/crypto3/zk/commitments/detail/polynomial/basic_fri.hpp index 6a9548b78..63ec1195c 100644 --- a/include/nil/crypto3/zk/commitments/detail/polynomial/basic_fri.hpp +++ b/include/nil/crypto3/zk/commitments/detail/polynomial/basic_fri.hpp @@ -596,7 +596,7 @@ namespace nil { FRI>::value, bool>::type = true> static typename FRI::proof_type proof_eval( - std::map> &g, + const std::map> &g, const PolynomialType combined_Q, const std::map &precommitments, const typename FRI::precommitment_type &combined_Q_precommitment, @@ -609,18 +609,21 @@ namespace nil { // TODO: add necessary checks //BOOST_ASSERT(check_initial_precommitment(precommitments, fri_params)); - // Think about resizing polynomials. Problems with const. - if constexpr (std::is_same, PolynomialType>::value) { - for( auto const &it:g ){ - auto k = it.first; - for (int i = 0; i < g[k].size(); ++i ){ - // If LPC works properly this if is never executed. - if (g[k][i].size() != fri_params.D[0]->size()) { - g[k][i].resize(fri_params.D[0]->size()); - } - } - } - } + // This resizes actually happens when called at the end of prover: + // _proof.eval_proof.eval_proof = _commitment_scheme.proof_eval(transcript); + // We DO NOT resize it here, it takes waaay too much RAM, resize it when needed. + + //if constexpr (std::is_same, PolynomialType>::value) { + // for( auto const &it:g ){ + // auto k = it.first; + // for (int i = 0; i < g[k].size(); ++i ){ + // // If LPC works properly this if is never executed. + // if (g[k][i].size() != fri_params.D[0]->size()) { + // g[k][i].resize(fri_params.D[0]->size()); + // } + // } + // } + //} // Commit phase auto f = combined_Q; @@ -667,6 +670,26 @@ namespace nil { // Query phase std::array query_proofs; + + // 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. + // In case lambda becomes much larger than log(2, average polynomial size), then this will not be optimal. + // For lambda = 20 and 2^20 rows in assignment table, it's faster and uses less RAM. + std::map>> g_coeffs; + if constexpr (std::is_same< + math::polynomial_dfs, + PolynomialType>::value + ) { + for (const auto &[key, poly_vector]: g) { + for (const auto& poly: poly_vector) { + // All the polynomials have the same size, so we have no bugs here. + if (poly.size() != fri_params.D[0]->size()) { + g_coeffs[key].emplace_back(poly.coefficients()); + } + } + } + } + for (std::size_t query_id = 0; query_id < FRI::lambda; query_id++) { std::size_t domain_size = fri_params.D[0]->size(); std::uint64_t x_index = (transcript.template int_challenge()) % domain_size; @@ -679,7 +702,7 @@ namespace nil { //Initial proof std::map initial_proof; - for( const auto &it: g ){ + for (const auto &it: g) { auto k = it.first; initial_proof[k] = {}; initial_proof[k].values.resize(it.second.size()); @@ -689,25 +712,37 @@ namespace nil { //Fill values t = 0; - for (std::size_t polynomial_index = 0; polynomial_index < g[k].size(); ++polynomial_index) { + const auto& g_k = it.second; // g[k] + + for (std::size_t polynomial_index = 0; polynomial_index < g_k.size(); ++polynomial_index) { initial_proof[k].values[polynomial_index].resize(coset_size / FRI::m); - for (std::size_t j = 0; j < coset_size / FRI::m; j++) { - if constexpr (std::is_same< + if constexpr (std::is_same< math::polynomial_dfs, PolynomialType>::value ) { - initial_proof[k].values[polynomial_index][j][0] = std::move(g[k][polynomial_index][s_indices[j][0]]); - initial_proof[k].values[polynomial_index][j][1] = std::move(g[k][polynomial_index][s_indices[j][1]]); + if (g_k[polynomial_index].size() == fri_params.D[0]->size()) { + for (std::size_t j = 0; j < coset_size / FRI::m; j++) { + initial_proof[k].values[polynomial_index][j][0] = g_k[polynomial_index][s_indices[j][0]]; + initial_proof[k].values[polynomial_index][j][1] = g_k[polynomial_index][s_indices[j][1]]; + } } else { - initial_proof[k].values[polynomial_index][j][0] = g[k][polynomial_index].evaluate( - s[j][0]); - initial_proof[k].values[polynomial_index][j][1] = g[k][polynomial_index].evaluate( - s[j][1]); + // Convert to coefficients form and evaluate. coset_size / FRI::m is usually just 1, + // It makes no sense to resize in dfs form to then use just 2 values in 2 points. + for (std::size_t j = 0; j < coset_size / FRI::m; j++) { + initial_proof[k].values[polynomial_index][j][0] = g_coeffs[k][polynomial_index].evaluate(s[j][0]); + initial_proof[k].values[polynomial_index][j][1] = g_coeffs[k][polynomial_index].evaluate(s[j][1]); + } + } + } else { + // Same for poly in coefficients form. + for (std::size_t j = 0; j < coset_size / FRI::m; j++) { + initial_proof[k].values[polynomial_index][j][0] = g_k[polynomial_index].evaluate(s[j][0]); + initial_proof[k].values[polynomial_index][j][1] = g_k[polynomial_index].evaluate(s[j][1]); } } } - //Fill merkle proofs + // Fill merkle proofs initial_proof[k].p = make_proof_specialized( get_folded_index(x_index, fri_params.D[0]->size(), fri_params.step_list[0]), fri_params.D[0]->size(), precommitments.at(k) @@ -758,13 +793,14 @@ namespace nil { round_proofs[i].y[0][1] = final_polynomial.evaluate(-x); } } - typename FRI::query_proof_type query_proof = {initial_proof, round_proofs}; - query_proofs[query_id] = query_proof; + typename FRI::query_proof_type query_proof = {std::move(initial_proof), std::move(round_proofs)}; + query_proofs[query_id] = std::move(query_proof); } - proof.fri_roots = fri_roots; - proof.final_polynomial = final_polynomial; - proof.query_proofs = query_proofs; + proof.fri_roots = std::move(fri_roots); + proof.final_polynomial = std::move(final_polynomial); + proof.query_proofs = std::move(query_proofs); + return proof;//typename FRI::proof_type{fri_roots, final_polynomial, query_proofs}; } diff --git a/include/nil/crypto3/zk/snark/arithmetization/plonk/assignment.hpp b/include/nil/crypto3/zk/snark/arithmetization/plonk/assignment.hpp index 2bc102bb7..b66fdf50c 100644 --- a/include/nil/crypto3/zk/snark/arithmetization/plonk/assignment.hpp +++ b/include/nil/crypto3/zk/snark/arithmetization/plonk/assignment.hpp @@ -81,6 +81,10 @@ namespace nil { return _witnesses; } + witnesses_container_type move_witnesses() { + return std::move(_witnesses); + } + const ColumnType& operator[](std::uint32_t index) const { if (index < ArithmetizationParams::witness_columns) return _witnesses[index]; @@ -147,6 +151,10 @@ namespace nil { return _public_inputs; } + public_input_container_type move_public_inputs() const { + return std::move(_public_inputs); + } + std::uint32_t constants_amount() const { return _constants.size(); } @@ -164,6 +172,10 @@ namespace nil { return _constants; } + constant_container_type move_constants() const { + return std::move(_constants); + } + constexpr std::uint32_t selectors_amount() const { return _selectors.size(); } @@ -181,6 +193,10 @@ namespace nil { return _selectors; } + selector_container_type move_selectors() const { + return std::move(_selectors); + } + void fill_constant(std::uint32_t index, const ColumnType& column) { BOOST_ASSERT(index < constants_amount()); BOOST_ASSERT(_constants[index].size() == 0); @@ -246,6 +262,7 @@ namespace nil { using selector_container_type = typename public_table_type::selector_container_type; protected: + // These are normally created by the assigner, or read from a file. private_table_type _private_table; public_table_type _public_table; @@ -309,10 +326,18 @@ namespace nil { return _private_table; } + private_table_type move_private_table() { + return std::move(_private_table); + } + const public_table_type& public_table() const { return _public_table; } + public_table_type move_public_table() { + return std::move(_public_table); + } + std::uint32_t size() const { return _private_table.size() + _public_table.size(); } diff --git a/include/nil/crypto3/zk/snark/arithmetization/plonk/detail/column_polynomial.hpp b/include/nil/crypto3/zk/snark/arithmetization/plonk/detail/column_polynomial.hpp index 68ebb36e8..de9d06dd4 100644 --- a/include/nil/crypto3/zk/snark/arithmetization/plonk/detail/column_polynomial.hpp +++ b/include/nil/crypto3/zk/snark/arithmetization/plonk/detail/column_polynomial.hpp @@ -91,9 +91,8 @@ namespace nil { template math::polynomial_dfs - column_polynomial_dfs(const plonk_column &column_assignment, - std::shared_ptr> - domain) { + column_polynomial_dfs(plonk_column column_assignment, + std::shared_ptr> domain) { std::size_t d = std::distance(column_assignment.begin(), column_assignment.end()) - 1; @@ -107,16 +106,15 @@ namespace nil { template std::vector> - column_range_polynomial_dfs(const std::vector> &column_range_assignment, - std::shared_ptr> - domain) { + column_range_polynomial_dfs(std::vector> column_range_assignment, + std::shared_ptr> domain) { std::size_t columns_amount = column_range_assignment.size(); std::vector> columns(columns_amount); for (std::size_t column_index = 0; column_index < columns_amount; column_index++) { columns[column_index] = - column_polynomial_dfs(column_range_assignment[column_index], domain); + column_polynomial_dfs(std::move(column_range_assignment[column_index]), domain); } return columns; @@ -125,7 +123,7 @@ namespace nil { template std::array, columns_amount> column_range_polynomial_dfs( - const std::array, columns_amount> &column_range_assignment, + std::array, columns_amount> column_range_assignment, std::shared_ptr> domain) { @@ -133,7 +131,7 @@ namespace nil { for (std::size_t column_index = 0; column_index < columns_amount; column_index++) { columns[column_index] = - column_polynomial_dfs(column_range_assignment[column_index], domain); + column_polynomial_dfs(std::move(column_range_assignment[column_index]), domain); } return columns; diff --git a/include/nil/crypto3/zk/snark/systems/plonk/placeholder/lookup_argument.hpp b/include/nil/crypto3/zk/snark/systems/plonk/placeholder/lookup_argument.hpp index a403ef112..441675ce7 100644 --- a/include/nil/crypto3/zk/snark/systems/plonk/placeholder/lookup_argument.hpp +++ b/include/nil/crypto3/zk/snark/systems/plonk/placeholder/lookup_argument.hpp @@ -4,6 +4,7 @@ // Copyright (c) 2022 Ilia Shirobokov // Copyright (c) 2022 Alisa Cherniaeva // Copyright (c) 2023 Elena Tatuzova +// Copyright (c) 2023 Martun Karapetyan // // MIT License // @@ -52,7 +53,7 @@ namespace nil { namespace zk { namespace snark { template - class placeholder_lookup_argument { + class placeholder_lookup_argument_prover { using transcript_hash_type = typename ParamsType::transcript_hash_type; using transcript_type = transcript::fiat_shamir_heuristic_sequential; using polynomial_dfs_type = math::polynomial_dfs; @@ -66,6 +67,318 @@ namespace nil { typedef detail::placeholder_policy policy_type; public: + + struct prover_lookup_result { + std::array, argument_size> F_dfs; + typename commitment_scheme_type::commitment_type lookup_commitment; + }; + + placeholder_lookup_argument_prover( + const plonk_constraint_system + &constraint_system, + const typename placeholder_public_preprocessor::preprocessed_data_type + &preprocessed_data, + const plonk_polynomial_dfs_table + &plonk_columns, + commitment_scheme_type &commitment_scheme, + transcript_type &transcript = transcript_type()) + : constraint_system(constraint_system) + , preprocessed_data(preprocessed_data) + , plonk_columns(plonk_columns) + , commitment_scheme(commitment_scheme) + , transcript(transcript) + , basic_domain(preprocessed_data.common_data.basic_domain) + , lookup_gates(constraint_system.lookup_gates()) + , lookup_tables(constraint_system.lookup_tables()) + { + // $/theta = \challenge$ + theta = transcript.template challenge(); + } + + prover_lookup_result prove_eval() { + PROFILE_PLACEHOLDER_SCOPE("Lookup argument prove eval time"); + + // Construct lookup gates + math::polynomial_dfs one_polynomial( + 0, basic_domain->m, FieldType::value_type::one()); + math::polynomial_dfs zero_polynomial( + 0, basic_domain->m, FieldType::value_type::zero()); + math::polynomial_dfs mask_assignment = + one_polynomial - preprocessed_data.q_last - preprocessed_data.q_blind; + + std::unique_ptr>> lookup_value_ptr = + prepare_lookup_value(lookup_tables, plonk_columns, theta, mask_assignment); + auto& lookup_value = *lookup_value_ptr; + + std::unique_ptr>> lookup_input_ptr = + prepare_lookup_input(plonk_columns, lookup_gates, preprocessed_data, theta); + auto& lookup_input = *lookup_input_ptr; + + // 3. Lookup_input and lookup_value are ready + // Now sort them! + // Reduce value and input: + auto reduced_value_ptr = std::make_unique>>(); + auto& reduced_value = *reduced_value_ptr; + + for( std::size_t i = 0; i < lookup_value.size(); i++ ){ + reduced_value.push_back(reduce_dfs_polynomial_domain(lookup_value[i], basic_domain->m)); + } + auto reduced_input_ptr = std::make_unique>>(); + auto& reduced_input = *reduced_input_ptr; + + for( std::size_t i = 0; i < lookup_input.size(); i++ ){ + reduced_input.push_back(reduce_dfs_polynomial_domain(lookup_input[i], basic_domain->m)); + } + // Sort + auto sorted = sort_polynomials(reduced_input, reduced_value, basic_domain->m, + preprocessed_data.common_data.usable_rows_amount); + + // 4. Commit sorted polys + for( std::size_t i = 0; i < sorted.size(); i++){ + commitment_scheme.append_to_batch(LOOKUP_BATCH, sorted[i]); + } + typename commitment_scheme_type::commitment_type lookup_commitment = commitment_scheme.commit(LOOKUP_BATCH); + transcript(lookup_commitment); + + //5. Compute V_L polynomial. + typename FieldType::value_type beta = transcript.template challenge(); + typename FieldType::value_type gamma = transcript.template challenge(); + + math::polynomial_dfs V_L = compute_V_L( + sorted, preprocessed_data, reduced_input, reduced_value, beta, gamma); + + // We don't use reduced_input and reduced_value after this line. + reduced_input_ptr.reset(nullptr); + reduced_value_ptr.reset(nullptr); + + commitment_scheme.append_to_batch(PERMUTATION_BATCH, V_L); + + BOOST_CHECK(V_L[preprocessed_data.common_data.usable_rows_amount] == FieldType::value_type::one()); + + // After this call of compute_g lookup_input_ptr and lookup_value_ptr are deleted. + math::polynomial_dfs g = compute_g( + std::move(lookup_input_ptr), std::move(lookup_value_ptr), beta, gamma); + + math::polynomial_dfs h = compute_h(sorted, beta, gamma); + math::polynomial_dfs V_L_shifted = + math::polynomial_shift(V_L, 1, basic_domain->m); + + std::array, argument_size> F_dfs; + + F_dfs[0] = preprocessed_data.common_data.lagrange_0 * (one_polynomial - V_L); + F_dfs[1] = preprocessed_data.q_last * ( V_L * V_L - V_L ); + + // Polynomial g is waaay too large, saving memory here, by making code very unreadable. + //F_dfs[2] = (one_polynomial - (preprocessed_data.q_last + preprocessed_data.q_blind)) * + // (V_L_shifted * h - V_L * g); + g *= V_L; + h *= V_L_shifted; + g -= h; + h = math::polynomial_dfs(); // just clean the memory of h. + g *= (preprocessed_data.q_last + preprocessed_data.q_blind) - one_polynomial; + F_dfs[2] = std::move(g); + + F_dfs[3] = zero_polynomial; + + for( std::size_t i = 1; i < sorted.size(); i++){ + typename FieldType::value_type alpha = transcript.template challenge(); + math::polynomial_dfs sorted_shifted = math::polynomial_shift(sorted[i-1], preprocessed_data.common_data.usable_rows_amount , basic_domain->m); + F_dfs[3] += alpha * preprocessed_data.common_data.lagrange_0 * (sorted[i] - sorted_shifted); + } + +/* for( std::size_t i = 0; i < basic_domain->m; i++){ + BOOST_CHECK( F_dfs[0].evaluate(basic_domain->get_domain_element(i)) == FieldType::value_type::zero() ); + BOOST_CHECK( F_dfs[1].evaluate(basic_domain->get_domain_element(i)) == FieldType::value_type::zero() ); + BOOST_CHECK( F_dfs[2].evaluate(basic_domain->get_domain_element(i)) == FieldType::value_type::zero() ); + BOOST_CHECK( F_dfs[3].evaluate(basic_domain->get_domain_element(i)) == FieldType::value_type::zero() ); + }*/ + + return { + std::move(F_dfs), + std::move(lookup_commitment) + }; + } + + math::polynomial_dfs compute_g( + std::unique_ptr>> lookup_input_ptr, + std::unique_ptr>> lookup_value_ptr, + const typename FieldType::value_type& beta, + const typename FieldType::value_type& gamma) { + + auto& lookup_value = *lookup_value_ptr; + auto& lookup_input = *lookup_input_ptr; + + auto g = math::polynomial_dfs::one(); + auto one = FieldType::value_type::one(); + g *= (one + beta).pow(lookup_input.size()); + + std::vector> g_multipliers; + for( std::size_t i = 0; i < lookup_input.size(); i++) { + g_multipliers.push_back(gamma + lookup_input[i]); + } + + // We don't use lookup_input after this line. + lookup_input_ptr.reset(nullptr); + + auto part1 = (one+beta) * gamma; + for( std::size_t i = 0; i < lookup_value.size(); i++ ){ + auto lookup_shifted = math::polynomial_shift(lookup_value[i], 1, basic_domain->m); + g_multipliers.push_back( part1 + lookup_value[i] + beta * lookup_shifted); + } + + // We don't use lookup_value after this line. + lookup_value_ptr.reset(nullptr); + + g *= polynomial_product(std::move(g_multipliers)); + return g; + } + + math::polynomial_dfs compute_h( + const std::vector>& sorted, + const typename FieldType::value_type& beta, + const typename FieldType::value_type& gamma + ) { + auto one = FieldType::value_type::one(); + + std::vector> h_multipliers; + for( std::size_t i = 0; i < sorted.size(); i++){ + auto sorted_shifted = math::polynomial_shift(sorted[i], 1, basic_domain->m); + h_multipliers.push_back((one + beta) * gamma + sorted[i] + beta * sorted_shifted); + } + return polynomial_product(h_multipliers); + } + + math::polynomial_dfs compute_V_L( + const std::vector>& sorted, + const typename placeholder_public_preprocessor::preprocessed_data_type + &preprocessed_data, + const std::vector>& reduced_input, + const std::vector>& reduced_value, + const typename FieldType::value_type& beta, + const typename FieldType::value_type& gamma) { + + math::polynomial_dfs V_L( + basic_domain->m-1,basic_domain->m, FieldType::value_type::zero()); + V_L[0] = FieldType::value_type::one(); + auto one = FieldType::value_type::one(); + + for (std::size_t k = 1; k <= preprocessed_data.common_data.usable_rows_amount; k++) { + V_L[k] = V_L[k-1]; + + typename FieldType::value_type g_tmp = (one + beta).pow(reduced_input.size()); + for( std::size_t i = 0; i < reduced_input.size(); i++){ + g_tmp *= gamma + reduced_input[i][k-1]; + } + + auto part1 = (one + beta) * gamma; + for( std::size_t i = 0; i < reduced_value.size(); i++){ + g_tmp *= part1 + reduced_value[i][k-1] + beta * reduced_value[i][k]; + } + + V_L[k] *= g_tmp; + + typename FieldType::value_type h_tmp = FieldType::value_type::one(); + for (std::size_t i = 0; i < sorted.size(); i++) { + h_tmp *= part1 + sorted[i][k-1] + beta * sorted[i][k]; + } + V_L[k] *= h_tmp.inversed(); + } + return V_L; + } + + std::unique_ptr>> prepare_lookup_value( + const std::vector> &lookup_tables, + const plonk_polynomial_dfs_table &plonk_columns, + const typename FieldType::value_type& theta, + const math::polynomial_dfs& mask_assignment) { + typename FieldType::value_type theta_acc; + + // Prepare lookup value + auto lookup_value_ptr = std::make_unique>>(); + for(std::size_t t_id = 0; t_id < lookup_tables.size(); t_id++) { + const plonk_lookup_table &l_table = lookup_tables[t_id]; + const math::polynomial_dfs &lookup_tag = plonk_columns.selector(l_table.tag_index); + for( std::size_t o_id = 0; o_id < l_table.lookup_options.size(); o_id++ ){ + math::polynomial_dfs v = (typename FieldType::value_type(t_id + 1)) * lookup_tag; + theta_acc = theta; + for(std::size_t i = 0; i < l_table.columns_number; i++) { + v += theta_acc * lookup_tag * plonk_columns.constant(l_table.lookup_options[o_id][i].index); + theta_acc *= theta; + } + v *= mask_assignment; + lookup_value_ptr->push_back(v); + } + } + return std::move(lookup_value_ptr); + } + + std::unique_ptr>> prepare_lookup_input( + const plonk_polynomial_dfs_table &plonk_columns, + const std::vector>> &lookup_gates, + const typename placeholder_public_preprocessor::preprocessed_data_type &preprocessed_data, + const typename FieldType::value_type& theta + ) { + + // Copied from gate argument. + // TODO: remove code duplication. + auto value_type_to_polynomial_dfs = [&assignments=plonk_columns]( + const typename VariableType::assignment_type& coeff) { + return polynomial_dfs_type(0, 1, coeff); + }; + + math::expression_variable_type_converter converter( + value_type_to_polynomial_dfs); + + auto get_var_value = [&domain=basic_domain, &assignments=plonk_columns] + (const DfsVariableType &var) { + polynomial_dfs_type assignment; + switch (var.type) { + case DfsVariableType::column_type::witness: + assignment = assignments.witness(var.index); + break; + case DfsVariableType::column_type::public_input: + assignment = assignments.public_input(var.index); + break; + case DfsVariableType::column_type::constant: + assignment = assignments.constant(var.index); + break; + case DfsVariableType::column_type::selector: + assignment = assignments.selector(var.index); + break; + } + + if (var.rotation != 0) { + assignment = math::polynomial_shift(assignment, var.rotation, domain->m); + } + return assignment; + }; + + typename FieldType::value_type theta_acc; + + // Prepare lookup input + auto lookup_input_ptr = std::make_unique>>(); + for (const auto &gate : lookup_gates) { + math::expression expr; + math::polynomial_dfs lookup_selector = plonk_columns.selector(gate.tag_index); + for (const auto &constraint : gate.constraints) { + math::polynomial_dfs l = lookup_selector * (typename FieldType::value_type(constraint.table_id)); + theta_acc = theta; + for( std::size_t k = 0; k < constraint.lookup_input.size(); k++){ + expr = converter.convert(constraint.lookup_input[k]); + math::cached_expression_evaluator evaluator(expr, get_var_value); + + l += theta_acc * lookup_selector * evaluator.evaluate(); + theta_acc *= theta; + } + lookup_input_ptr->push_back(l); + } + } + return std::move(lookup_input_ptr); + } + + + private: + static math::polynomial_dfs reduce_dfs_polynomial_domain( const math::polynomial_dfs &polynomial, std::size_t &new_domain_size @@ -123,11 +436,6 @@ namespace nil { return result; } - struct prover_lookup_result { - std::array, argument_size> F_dfs; - typename commitment_scheme_type::commitment_type lookup_commitment; - }; - // Each lookup table should fill full rectangle inside assignment table // Lookup tables may contain repeated values, but they shoul be placed into one // option one under another. @@ -135,7 +443,7 @@ namespace nil { // similar values only with negligible probability. // So similar values in compressed lookup tables vectors repeated values may be only in one column // near each other. - static inline std::vector> sort_polynomials( + std::vector> sort_polynomials( const std::vector>& reduced_input, const std::vector>& reduced_value, std::size_t domain_size, @@ -213,226 +521,42 @@ namespace nil { while (stride < multipliers.size() ) { for(std::size_t i = 0; i + stride < multipliers.size(); i += stride*2) { multipliers[i] *= multipliers[ i + stride ]; + // Free the memeory we don't use. any more. + multipliers[ i + stride ] = math::polynomial_dfs(); } stride *= 2; } - return multipliers[0]; + return std::move(multipliers[0]); } - static inline prover_lookup_result prove_eval( - const plonk_constraint_system - &constraint_system, - const typename placeholder_public_preprocessor::preprocessed_data_type - &preprocessed_data, - const plonk_polynomial_dfs_table - &plonk_columns, - commitment_scheme_type &commitment_scheme, - transcript_type &transcript = transcript_type() - ) { - PROFILE_PLACEHOLDER_SCOPE("Lookup argument prove eval time"); - - // Copied from gate argument. - // TODO: remove code duplication. - auto value_type_to_polynomial_dfs = [&assignments=plonk_columns]( - const typename VariableType::assignment_type& coeff) { - return polynomial_dfs_type(0, 1, coeff); - }; - - math::expression_variable_type_converter converter( - value_type_to_polynomial_dfs); - - std::shared_ptr> basic_domain = - preprocessed_data.common_data.basic_domain; - - auto get_var_value = [&domain=basic_domain, &assignments=plonk_columns] - (const DfsVariableType &var) { - polynomial_dfs_type assignment; - switch (var.type) { - case DfsVariableType::column_type::witness: - assignment = assignments.witness(var.index); - break; - case DfsVariableType::column_type::public_input: - assignment = assignments.public_input(var.index); - break; - case DfsVariableType::column_type::constant: - assignment = assignments.constant(var.index); - break; - case DfsVariableType::column_type::selector: - assignment = assignments.selector(var.index); - break; - } - - if (var.rotation != 0) { - assignment = math::polynomial_shift(assignment, var.rotation, domain->m); - } - return assignment; - }; - - - prover_lookup_result result; - - // $/theta = \challenge$ - typename FieldType::value_type theta = transcript.template challenge(); - typename FieldType::value_type theta_acc; - - // Construct lookup gates - const std::vector>> &lookup_gates = - constraint_system.lookup_gates(); - - const std::vector> &lookup_tables = constraint_system.lookup_tables(); - std::array, argument_size> F_dfs; - - math::polynomial_dfs one_polynomial( - 0, basic_domain->m, FieldType::value_type::one()); - math::polynomial_dfs zero_polynomial( - 0, basic_domain->m, FieldType::value_type::zero()); - math::polynomial_dfs mask_assignment = - one_polynomial - preprocessed_data.q_last - preprocessed_data.q_blind; - - // Prepare lookup value - std::vector> lookup_value; - for(std::size_t t_id = 0; t_id < lookup_tables.size(); t_id++){ - const plonk_lookup_table &l_table = lookup_tables[t_id]; - const math::polynomial_dfs &lookup_tag = plonk_columns.selector(l_table.tag_index); - for( std::size_t o_id = 0; o_id < l_table.lookup_options.size(); o_id++ ){ - math::polynomial_dfs v = (typename FieldType::value_type(t_id + 1)) * lookup_tag; - theta_acc = theta; - for(std::size_t i = 0; i < l_table.columns_number; i++) { - v += theta_acc * lookup_tag * plonk_columns.constant(l_table.lookup_options[o_id][i].index); - theta_acc *= theta; - } - v *= mask_assignment; - auto reduced_v = reduce_dfs_polynomial_domain(v, basic_domain->m); - lookup_value.push_back(v); - } - } - - // Prepare lookup input - std::vector> lookup_input; - for( const auto &gate:lookup_gates ){ - math::expression expr; - math::polynomial_dfs lookup_selector = plonk_columns.selector(gate.tag_index); - for( const auto &constraint: gate.constraints ){ - math::polynomial_dfs l = lookup_selector * (typename FieldType::value_type(constraint.table_id)); - theta_acc = theta; - for( std::size_t k = 0; k < constraint.lookup_input.size(); k++){ - expr = converter.convert(constraint.lookup_input[k]); - math::cached_expression_evaluator evaluator(expr, get_var_value); - - l += theta_acc * lookup_selector * evaluator.evaluate(); - theta_acc *= theta; - } - lookup_input.push_back(l); - } - } - - // 3. Lookup_input and lookup_value are ready - // Now sort them! - // Reduce value and input: - std::vector> reduced_value; - for( std::size_t i = 0; i < lookup_value.size(); i++ ){ - reduced_value.push_back(reduce_dfs_polynomial_domain(lookup_value[i], basic_domain->m)); - } - std::vector> reduced_input; - - for( std::size_t i = 0; i < lookup_input.size(); i++ ){ - reduced_input.push_back(reduce_dfs_polynomial_domain(lookup_input[i], basic_domain->m)); - } - // Sort - auto sorted = sort_polynomials(reduced_input, reduced_value, basic_domain->m, preprocessed_data.common_data.usable_rows_amount); - - // 4. Commit sorted polys - for( std::size_t i = 0; i < sorted.size(); i++){ - commitment_scheme.append_to_batch(LOOKUP_BATCH, sorted[i]); - } - typename commitment_scheme_type::commitment_type lookup_commitment = commitment_scheme.commit(LOOKUP_BATCH); - transcript(lookup_commitment); - - //5. Compute V_L polynomial. - typename FieldType::value_type beta = transcript.template challenge(); - typename FieldType::value_type gamma = transcript.template challenge(); - - math::polynomial_dfs V_L(basic_domain->m-1,basic_domain->m, FieldType::value_type::zero()); - V_L[0] = FieldType::value_type::one(); - auto one = FieldType::value_type::one(); - - for (std::size_t k = 1; k <= preprocessed_data.common_data.usable_rows_amount; k++) { - V_L[k] = V_L[k-1]; - - typename FieldType::value_type g_tmp = (one+beta).pow(reduced_input.size()); - for( std::size_t i = 0; i < reduced_input.size(); i++){ - g_tmp *= gamma + reduced_input[i][k-1]; - } - - auto part1 = (one+beta) * gamma; - for( std::size_t i = 0; i < reduced_value.size(); i++){ - g_tmp *= part1 + reduced_value[i][k-1] + beta * reduced_value[i][k]; - } - - V_L[k] *= g_tmp; - - typename FieldType::value_type h_tmp = FieldType::value_type::one(); - for (std::size_t i = 0; i < sorted.size(); i++) { - h_tmp *= part1 + sorted[i][k-1] + beta * sorted[i][k]; - } - V_L[k] *= h_tmp.inversed(); - } - commitment_scheme.append_to_batch(PERMUTATION_BATCH, V_L); - - BOOST_CHECK(V_L[preprocessed_data.common_data.usable_rows_amount] == FieldType::value_type::one()); - - math::polynomial_dfs g = math::polynomial_dfs::one(); - g *= (one+beta).pow(lookup_input.size()); - - std::vector> g_multipliers; - for( std::size_t i = 0; i < lookup_input.size(); i++) { - g_multipliers.push_back(gamma + lookup_input[i]); - } - - auto part1 = (one+beta) * gamma; - for( std::size_t i = 0; i < lookup_value.size(); i++ ){ - auto lookup_shifted = math::polynomial_shift(lookup_value[i], 1, basic_domain->m); - g_multipliers.push_back( part1 + lookup_value[i] + beta * lookup_shifted); - } + const plonk_constraint_system& constraint_system; + const typename placeholder_public_preprocessor::preprocessed_data_type& preprocessed_data; + const plonk_polynomial_dfs_table& plonk_columns; + commitment_scheme_type& commitment_scheme; + transcript_type& transcript; + std::shared_ptr> basic_domain; + const std::vector>>& lookup_gates; + const std::vector>& lookup_tables; + typename FieldType::value_type theta; - g *= polynomial_product(std::move(g_multipliers)); - - math::polynomial_dfs h; - std::vector> h_multipliers; - for( std::size_t i = 0; i < sorted.size(); i++){ - auto sorted_shifted = math::polynomial_shift(sorted[i], 1, basic_domain->m); - h_multipliers.push_back((one+beta) * gamma + sorted[i] + beta * sorted_shifted); - } - h = polynomial_product(h_multipliers); + }; - math::polynomial_dfs V_L_shifted = - math::polynomial_shift(V_L, 1, basic_domain->m); - F_dfs[0] = preprocessed_data.common_data.lagrange_0 * (one_polynomial - V_L); - F_dfs[1] = preprocessed_data.q_last * ( V_L * V_L - V_L ); - F_dfs[2] = (one_polynomial - (preprocessed_data.q_last + preprocessed_data.q_blind)) * - (V_L_shifted * h - V_L * g); - F_dfs[3] = zero_polynomial; + template + class placeholder_lookup_argument_verifier { + using transcript_hash_type = typename ParamsType::transcript_hash_type; + using transcript_type = transcript::fiat_shamir_heuristic_sequential; + using polynomial_dfs_type = math::polynomial_dfs; + using VariableType = plonk_variable; + using DfsVariableType = plonk_variable; + using commitment_scheme_type = CommitmentSchemeTypePermutation; - for( std::size_t i = 1; i < sorted.size(); i++){ - typename FieldType::value_type alpha = transcript.template challenge(); - math::polynomial_dfs sorted_shifted = math::polynomial_shift(sorted[i-1], preprocessed_data.common_data.usable_rows_amount , basic_domain->m); - F_dfs[3] += alpha * preprocessed_data.common_data.lagrange_0 * (sorted[i] - sorted_shifted); - } -/* for( std::size_t i = 0; i < basic_domain->m; i++){ - BOOST_CHECK( F_dfs[0].evaluate(basic_domain->get_domain_element(i)) == FieldType::value_type::zero() ); - BOOST_CHECK( F_dfs[1].evaluate(basic_domain->get_domain_element(i)) == FieldType::value_type::zero() ); - BOOST_CHECK( F_dfs[2].evaluate(basic_domain->get_domain_element(i)) == FieldType::value_type::zero() ); - BOOST_CHECK( F_dfs[3].evaluate(basic_domain->get_domain_element(i)) == FieldType::value_type::zero() ); - }*/ + static constexpr std::size_t argument_size = 4; - return { - F_dfs, - lookup_commitment - }; - } + typedef detail::placeholder_policy policy_type; - static inline std::array verify_eval( + public: + std::array verify_eval( const typename placeholder_public_preprocessor::preprocessed_data_type &preprocessed_data, const std::vector>> &lookup_gates, const std::vector> &lookup_tables, @@ -541,7 +665,6 @@ namespace nil { return F; } }; - } // namespace snark } // namespace zk } // namespace crypto3 diff --git a/include/nil/crypto3/zk/snark/systems/plonk/placeholder/preprocessor.hpp b/include/nil/crypto3/zk/snark/systems/plonk/placeholder/preprocessor.hpp index ba8f223a7..bfdaffa50 100644 --- a/include/nil/crypto3/zk/snark/systems/plonk/placeholder/preprocessor.hpp +++ b/include/nil/crypto3/zk/snark/systems/plonk/placeholder/preprocessor.hpp @@ -225,11 +225,12 @@ namespace nil { } struct cycle_representation { - typedef std::pair key_type; + // Using std::uint32_t reduces RAM usage a bit. Our table size (rows_amount * width) will never be > 2^32 elements. + typedef std::pair key_type; std::map _mapping; std::map _aux; - std::map _sizes; + std::map _sizes; cycle_representation( const plonk_constraint_system &constraint_system, @@ -367,9 +368,10 @@ namespace nil { S_id[i] = polynomial_dfs_type( domain->size() - 1, domain->size(), FieldType::value_type::zero()); - for (std::size_t j = 0; j < domain->size(); j++) { - S_id[i][j] = delta.pow(i) * omega.pow(j); - } + S_id[i][0] = delta.pow(i); + for (std::size_t j = 1; j < domain->size(); j++) { + S_id[i][j] = S_id[i][j-1] * omega; + } } return S_id; @@ -431,7 +433,7 @@ namespace nil { // TODO: columns_with_copy_constraints -- It should be extracted from constraint_system static inline preprocessed_data_type process( const plonk_constraint_system &constraint_system, - const typename policy_type::variable_assignment_type::public_table_type &public_assignment, + typename policy_type::variable_assignment_type::public_table_type public_assignment, const plonk_table_description &table_description, typename ParamsType::commitment_scheme_type &commitment_scheme, @@ -472,11 +474,11 @@ namespace nil { public_polynomial_table = plonk_public_polynomial_dfs_table( - detail::column_range_polynomial_dfs(public_assignment.public_inputs(), + detail::column_range_polynomial_dfs(public_assignment.move_public_inputs(), basic_domain), - detail::column_range_polynomial_dfs(public_assignment.constants(), + detail::column_range_polynomial_dfs(public_assignment.move_constants(), basic_domain), - detail::column_range_polynomial_dfs(public_assignment.selectors(), + detail::column_range_polynomial_dfs(public_assignment.move_selectors(), basic_domain)); // prepare commitments for short verifier @@ -508,7 +510,8 @@ namespace nil { typename preprocessed_data_type::verification_key vk = {circuit_hash, public_commitments.fixed_values}; typename preprocessed_data_type::common_data_type common_data ( - public_commitments, c_rotations, N_rows, table_description.usable_rows_amount, max_gates_degree, vk + std::move(public_commitments), std::move(c_rotations), + N_rows, table_description.usable_rows_amount, max_gates_degree, vk ); transcript_type transcript(std::vector({})); @@ -551,7 +554,7 @@ namespace nil { static inline preprocessed_data_type process( const plonk_constraint_system &constraint_system, - const typename policy_type::variable_assignment_type::private_table_type &private_assignment, + typename policy_type::variable_assignment_type::private_table_type private_assignment, const plonk_table_description &table_description ) { std::size_t N_rows = table_description.rows_amount; @@ -561,7 +564,7 @@ namespace nil { plonk_private_polynomial_dfs_table private_polynomial_table(detail::column_range_polynomial_dfs( - private_assignment.witnesses(), basic_domain)); + private_assignment.move_witnesses(), basic_domain)); return preprocessed_data_type({basic_domain, std::move(private_polynomial_table)}); } }; diff --git a/include/nil/crypto3/zk/snark/systems/plonk/placeholder/prover.hpp b/include/nil/crypto3/zk/snark/systems/plonk/placeholder/prover.hpp index 34085737c..907b40d1f 100644 --- a/include/nil/crypto3/zk/snark/systems/plonk/placeholder/prover.hpp +++ b/include/nil/crypto3/zk/snark/systems/plonk/placeholder/prover.hpp @@ -99,37 +99,35 @@ namespace nil { static inline placeholder_proof process( const typename public_preprocessor_type::preprocessed_data_type &preprocessed_public_data, - const typename private_preprocessor_type::preprocessed_data_type &preprocessed_private_data, + typename private_preprocessor_type::preprocessed_data_type preprocessed_private_data, const plonk_table_description &table_description, const plonk_constraint_system &constraint_system, - const typename policy_type::variable_assignment_type &assignments, commitment_scheme_type commitment_scheme ) { auto prover = placeholder_prover( - preprocessed_public_data, preprocessed_private_data, table_description, - constraint_system, assignments, commitment_scheme); + preprocessed_public_data, std::move(preprocessed_private_data), table_description, + constraint_system, commitment_scheme); return prover.process(); } placeholder_prover( const typename public_preprocessor_type::preprocessed_data_type &preprocessed_public_data, - const typename private_preprocessor_type::preprocessed_data_type &preprocessed_private_data, + typename private_preprocessor_type::preprocessed_data_type preprocessed_private_data, const plonk_table_description &table_description, const plonk_constraint_system &constraint_system, - const typename policy_type::variable_assignment_type &assignments, const commitment_scheme_type &commitment_scheme ) : preprocessed_public_data(preprocessed_public_data) - , preprocessed_private_data(preprocessed_private_data) , table_description(table_description) , constraint_system(constraint_system) - , assignments(assignments) , _commitment_scheme(commitment_scheme) - , _polynomial_table(preprocessed_private_data.private_polynomial_table, - preprocessed_public_data.public_polynomial_table) + , _polynomial_table(new plonk_polynomial_dfs_table( + std::move(preprocessed_private_data.private_polynomial_table), + preprocessed_public_data.public_polynomial_table)) + , _is_lookup_enabled(constraint_system.lookup_gates().size() > 0) , transcript(std::vector()) { @@ -156,8 +154,8 @@ namespace nil { PROFILE_PLACEHOLDER_SCOPE("Placeholder prover, total time"); // 2. Commit witness columns and public_input columns - _commitment_scheme.append_to_batch(VARIABLE_VALUES_BATCH, _polynomial_table.witnesses()); - _commitment_scheme.append_to_batch(VARIABLE_VALUES_BATCH, _polynomial_table.public_inputs()); + _commitment_scheme.append_to_batch(VARIABLE_VALUES_BATCH, _polynomial_table->witnesses()); + _commitment_scheme.append_to_batch(VARIABLE_VALUES_BATCH, _polynomial_table->public_inputs()); { PROFILE_PLACEHOLDER_SCOPE("variable_values_precommit_time"); _proof.commitments[VARIABLE_VALUES_BATCH] = _commitment_scheme.commit(VARIABLE_VALUES_BATCH); @@ -165,24 +163,28 @@ namespace nil { transcript(_proof.commitments[VARIABLE_VALUES_BATCH]); // 4. permutation_argument - auto permutation_argument = placeholder_permutation_argument::prove_eval( - constraint_system, - preprocessed_public_data, - table_description, - _polynomial_table, - _commitment_scheme, - transcript); - - _F_dfs[0] = std::move(permutation_argument.F_dfs[0]); - _F_dfs[1] = std::move(permutation_argument.F_dfs[1]); - _F_dfs[2] = std::move(permutation_argument.F_dfs[2]); + { + auto permutation_argument = placeholder_permutation_argument::prove_eval( + constraint_system, + preprocessed_public_data, + table_description, + *_polynomial_table, + _commitment_scheme, + transcript); + + _F_dfs[0] = std::move(permutation_argument.F_dfs[0]); + _F_dfs[1] = std::move(permutation_argument.F_dfs[1]); + _F_dfs[2] = std::move(permutation_argument.F_dfs[2]); + } // 5. lookup_argument - auto lookup_argument_result = lookup_argument(); - _F_dfs[3] = std::move(lookup_argument_result.F_dfs[0]); - _F_dfs[4] = std::move(lookup_argument_result.F_dfs[1]); - _F_dfs[5] = std::move(lookup_argument_result.F_dfs[2]); - _F_dfs[6] = std::move(lookup_argument_result.F_dfs[3]); + { + auto lookup_argument_result = lookup_argument(); + _F_dfs[3] = std::move(lookup_argument_result.F_dfs[0]); + _F_dfs[4] = std::move(lookup_argument_result.F_dfs[1]); + _F_dfs[5] = std::move(lookup_argument_result.F_dfs[2]); + _F_dfs[6] = std::move(lookup_argument_result.F_dfs[3]); + } _proof.commitments[PERMUTATION_BATCH] = _commitment_scheme.commit(PERMUTATION_BATCH); transcript(_proof.commitments[PERMUTATION_BATCH]); @@ -196,7 +198,7 @@ namespace nil { mask_polynomial -= preprocessed_public_data.q_last; mask_polynomial -= preprocessed_public_data.q_blind; _F_dfs[7] = placeholder_gates_argument::prove_eval( - constraint_system, _polynomial_table, + constraint_system, *_polynomial_table, preprocessed_public_data.common_data.basic_domain, preprocessed_public_data.common_data.max_gates_degree, mask_polynomial, @@ -208,11 +210,16 @@ namespace nil { placeholder_debug_output(); #endif + // _polynomial_table not needed, clean its memory + _polynomial_table.reset(nullptr); + // 7. Aggregate quotient polynomial - std::vector T_splitted_dfs = - quotient_polynomial_split_dfs(); + { + std::vector T_splitted_dfs = + quotient_polynomial_split_dfs(); - _proof.commitments[QUOTIENT_BATCH] = T_commit(T_splitted_dfs); + _proof.commitments[QUOTIENT_BATCH] = T_commit(T_splitted_dfs); + } transcript(_proof.commitments[QUOTIENT_BATCH]); // 8. Run evaluation proofs @@ -224,6 +231,7 @@ namespace nil { PROFILE_PLACEHOLDER_SCOPE("commitment scheme proof eval time"); _proof.eval_proof.eval_proof = _commitment_scheme.proof_eval(transcript); } + return _proof; } @@ -290,26 +298,30 @@ namespace nil { return T_consolidated; } - typename placeholder_lookup_argument::prover_lookup_result - lookup_argument() { - PROFILE_PLACEHOLDER_SCOPE("lookup_argument_time"); + typename placeholder_lookup_argument_prover::prover_lookup_result + lookup_argument() { + PROFILE_PLACEHOLDER_SCOPE("lookup_argument_time"); - typename placeholder_lookup_argument< + typename placeholder_lookup_argument_prover< FieldType, commitment_scheme_type, ParamsType>::prover_lookup_result lookup_argument_result; + lookup_argument_result.F_dfs[0] = polynomial_dfs_type(0, table_description.rows_amount, FieldType::value_type::zero()); lookup_argument_result.F_dfs[1] = polynomial_dfs_type(0, table_description.rows_amount, FieldType::value_type::zero()); lookup_argument_result.F_dfs[2] = polynomial_dfs_type(0, table_description.rows_amount, FieldType::value_type::zero()); lookup_argument_result.F_dfs[3] = polynomial_dfs_type(0, table_description.rows_amount, FieldType::value_type::zero()); - if( _is_lookup_enabled ){ - lookup_argument_result = placeholder_lookup_argument< FieldType, commitment_scheme_type, ParamsType>::prove_eval( + + if (_is_lookup_enabled) { + placeholder_lookup_argument_prover lookup_argument_prover( constraint_system, preprocessed_public_data, - _polynomial_table, + *_polynomial_table, _commitment_scheme, transcript ); +; + lookup_argument_result = lookup_argument_prover.prove_eval(); _proof.commitments[LOOKUP_BATCH] = lookup_argument_result.lookup_commitment; } return lookup_argument_result; @@ -336,7 +348,7 @@ namespace nil { for (std::size_t j = 0; j < gates[i].constraints.size(); j++) { polynomial_dfs_type constraint_result = gates[i].constraints[j].evaluate( - _polynomial_table, preprocessed_public_data.common_data.basic_domain) * + *_polynomial_table, preprocessed_public_data.common_data.basic_domain) * _polynomial_table.selector(gates[i].selector_index); // for (std::size_t k = 0; k < table_description.rows_amount; k++) { if (constraint_result.evaluate( @@ -374,7 +386,8 @@ namespace nil { if(_is_lookup_enabled){ _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 * _omega.pow(preprocessed_public_data.common_data.usable_rows_amount)); + _commitment_scheme.append_eval_point(LOOKUP_BATCH, _proof.eval_proof.challenge * + _omega.pow(preprocessed_public_data.common_data.usable_rows_amount)); } _commitment_scheme.append_eval_point(QUOTIENT_BATCH, _proof.eval_proof.challenge); @@ -450,13 +463,11 @@ namespace nil { private: // Structures passed from outside by reference. const typename public_preprocessor_type::preprocessed_data_type &preprocessed_public_data; - const typename private_preprocessor_type::preprocessed_data_type &preprocessed_private_data; const plonk_table_description &table_description; const plonk_constraint_system &constraint_system; - const typename policy_type::variable_assignment_type &assignments; // Members created during proof generation. - plonk_polynomial_dfs_table _polynomial_table; + std::unique_ptr> _polynomial_table; placeholder_proof _proof; std::array _F_dfs; transcript::fiat_shamir_heuristic_sequential transcript; diff --git a/include/nil/crypto3/zk/snark/systems/plonk/placeholder/verifier.hpp b/include/nil/crypto3/zk/snark/systems/plonk/placeholder/verifier.hpp index 98d126656..4c714e572 100644 --- a/include/nil/crypto3/zk/snark/systems/plonk/placeholder/verifier.hpp +++ b/include/nil/crypto3/zk/snark/systems/plonk/placeholder/verifier.hpp @@ -93,7 +93,7 @@ namespace nil { _commitment_scheme.append_eval_point(PERMUTATION_BATCH, challenge); _commitment_scheme.append_eval_point(PERMUTATION_BATCH, challenge * _omega); - if(_is_lookup_enabled){ + if (_is_lookup_enabled) { _commitment_scheme.append_eval_point(LOOKUP_BATCH, challenge); _commitment_scheme.append_eval_point(LOOKUP_BATCH, challenge * _omega); _commitment_scheme.append_eval_point(LOOKUP_BATCH, challenge * _omega.pow(preprocessed_public_data.common_data.usable_rows_amount)); @@ -273,11 +273,9 @@ namespace nil { // 6. lookup argument bool is_lookup_enabled = (constraint_system.lookup_gates().size() > 0); std::array lookup_argument; - if( is_lookup_enabled ){ - lookup_argument = placeholder_lookup_argument< - FieldType, commitment_scheme_type, - ParamsType - >::verify_eval( + if (is_lookup_enabled) { + placeholder_lookup_argument_verifier lookup_argument_verifier; + lookup_argument_verifier.verify_eval( preprocessed_public_data, constraint_system.lookup_gates(), constraint_system.lookup_tables(), diff --git a/test/systems/plonk/placeholder/placeholder.cpp b/test/systems/plonk/placeholder/placeholder.cpp index 25047cf75..3d92d1e1e 100644 --- a/test/systems/plonk/placeholder/placeholder.cpp +++ b/test/systems/plonk/placeholder/placeholder.cpp @@ -285,16 +285,16 @@ struct placeholder_test_fixture : public test_initializer { typename placeholder_public_preprocessor::preprocessed_data_type lpc_preprocessed_public_data = placeholder_public_preprocessor::process( - constraint_system, assignments.public_table(), desc, lpc_scheme, columns_with_copy_constraints.size() + constraint_system, assignments.move_public_table(), desc, lpc_scheme, columns_with_copy_constraints.size() ); typename placeholder_private_preprocessor::preprocessed_data_type lpc_preprocessed_private_data = placeholder_private_preprocessor::process( - constraint_system, assignments.private_table(), desc + constraint_system, assignments.move_private_table(), desc ); auto lpc_proof = placeholder_prover::process( - lpc_preprocessed_public_data, lpc_preprocessed_private_data, desc, constraint_system, assignments, lpc_scheme + lpc_preprocessed_public_data, std::move(lpc_preprocessed_private_data), desc, constraint_system, lpc_scheme ); bool verifier_res = placeholder_verifier::process( @@ -390,7 +390,7 @@ BOOST_FIXTURE_TEST_CASE(prover_test, test_initializer){ ); auto proof = placeholder_prover::process( - preprocessed_public_data, preprocessed_private_data, desc, constraint_system, assignments, commitment_scheme + preprocessed_public_data, std::move(preprocessed_private_data), desc, constraint_system, commitment_scheme ); verifier_res = placeholder_verifier::process( @@ -425,18 +425,20 @@ BOOST_FIXTURE_TEST_CASE(prover_test, test_initializer){ lpc_scheme_type lpc_scheme(fri_params); transcript_type lpc_transcript; + // Normally we would use "assignments.move_public_table()" here, but assignments are reused in this test. typename placeholder_public_preprocessor::preprocessed_data_type lpc_preprocessed_public_data = placeholder_public_preprocessor::process( constraint_system, assignments.public_table(), desc, lpc_scheme, columns_with_copy_constraints.size() ); + // Normally we would use "assignments.move_private_table()" here, but assignments are reused in this test. typename placeholder_private_preprocessor::preprocessed_data_type lpc_preprocessed_private_data = placeholder_private_preprocessor::process( constraint_system, assignments.private_table(), desc ); auto lpc_proof = placeholder_prover::process( - lpc_preprocessed_public_data, lpc_preprocessed_private_data, desc, constraint_system, assignments, lpc_scheme + lpc_preprocessed_public_data, std::move(lpc_preprocessed_private_data), desc, constraint_system, lpc_scheme ); verifier_res = placeholder_verifier::process( @@ -459,7 +461,7 @@ BOOST_FIXTURE_TEST_CASE(prover_test, test_initializer){ ); auto kzg_proof = placeholder_prover::process( - kzg_preprocessed_public_data, kzg_preprocessed_private_data, desc, constraint_system, assignments, kzg_scheme + kzg_preprocessed_public_data, std::move(kzg_preprocessed_private_data), desc, constraint_system, kzg_scheme ); verifier_res = placeholder_verifier::process( @@ -491,12 +493,12 @@ BOOST_AUTO_TEST_CASE(permutation_polynomials_test) { typename placeholder_public_preprocessor::preprocessed_data_type lpc_preprocessed_public_data = placeholder_public_preprocessor::process( - constraint_system, assignments.public_table(), desc, lpc_scheme, columns_with_copy_constraints.size() + constraint_system, assignments.move_public_table(), desc, lpc_scheme, columns_with_copy_constraints.size() ); typename placeholder_private_preprocessor::preprocessed_data_type lpc_preprocessed_private_data = placeholder_private_preprocessor::process( - constraint_system, assignments.private_table(), desc + constraint_system, assignments.move_private_table(), desc ); auto polynomial_table = @@ -587,12 +589,12 @@ BOOST_AUTO_TEST_CASE(permutation_argument_test) { typename placeholder_public_preprocessor::preprocessed_data_type preprocessed_public_data = placeholder_public_preprocessor::process( - constraint_system, assignments.public_table(), desc, lpc_scheme, permutation_size + constraint_system, assignments.move_public_table(), desc, lpc_scheme, permutation_size ); typename placeholder_private_preprocessor::preprocessed_data_type preprocessed_private_data = placeholder_private_preprocessor::process( - constraint_system, assignments.private_table(), desc + constraint_system, assignments.move_private_table(), desc ); auto polynomial_table = @@ -834,10 +836,9 @@ BOOST_AUTO_TEST_CASE(lookup_test) { transcript_type prover_transcript(init_blob); transcript_type verifier_transcript(init_blob); - auto prover_res = - placeholder_lookup_argument::prove_eval( - constraint_system, preprocessed_public_data, polynomial_table, lpc_scheme, prover_transcript - ); + placeholder_lookup_argument_prover lookup_prover( + constraint_system, preprocessed_public_data, polynomial_table, lpc_scheme, prover_transcript); + auto prover_res = lookup_prover.prove_eval(); auto omega = preprocessed_public_data.common_data.basic_domain->get_domain_element(1); // Challenge phase @@ -894,8 +895,8 @@ BOOST_AUTO_TEST_CASE(lookup_test) { preprocessed_public_data.q_blind.evaluate(y))); auto half = prover_res.F_dfs[2].evaluate(y) * special_selectors.inversed(); - std::array verifier_res = - placeholder_lookup_argument::verify_eval( + placeholder_lookup_argument_verifier lookup_verifier; + std::array verifier_res = lookup_verifier.verify_eval( preprocessed_public_data, constraint_system.lookup_gates(), constraint_system.lookup_tables(), @@ -1001,10 +1002,9 @@ BOOST_AUTO_TEST_CASE(lookup_test) { transcript_type prover_transcript(init_blob); transcript_type verifier_transcript(init_blob); - auto prover_res = - placeholder_lookup_argument::prove_eval( - constraint_system, preprocessed_public_data, polynomial_table, lpc_scheme, prover_transcript - ); + placeholder_lookup_argument_prover prover( + constraint_system, preprocessed_public_data, polynomial_table, lpc_scheme, prover_transcript); + auto prover_res = prover.prove_eval(); // Challenge phase auto omega = preprocessed_public_data.common_data.basic_domain->get_domain_element(1); @@ -1061,8 +1061,8 @@ BOOST_AUTO_TEST_CASE(lookup_test) { preprocessed_public_data.q_blind.evaluate(y))); auto half = prover_res.F_dfs[2].evaluate(y) * special_selectors.inversed(); - std::array verifier_res = - placeholder_lookup_argument::verify_eval( + placeholder_lookup_argument_verifier verifier; + std::array verifier_res = verifier.verify_eval( preprocessed_public_data, constraint_system.lookup_gates(), constraint_system.lookup_tables(),