From 8b3a464e2fe54fcbbf1e378db07eaba33dfe836c Mon Sep 17 00:00:00 2001 From: Mikhail Komarov Date: Wed, 20 Mar 2024 16:51:31 +0200 Subject: [PATCH] Various fixes and cleanups. Preaparations for the architecture refactoring #353 --- .../blueprint/algorithms/generate_circuit.hpp | 96 +- .../blueprint/blueprint/plonk/assignment.hpp | 101 +- .../blueprint/plonk/assignment_proxy.hpp | 132 +- .../blueprint/plonk/circuit_proxy.hpp | 74 +- .../nil/blueprint/blueprint/r1cs/circuit.hpp | 256 ++-- .../r1cs/blueprint_linear_combination.hpp | 388 +++-- .../r1cs/detail/r1cs/blueprint_variable.hpp | 255 ++- .../nil/blueprint/chips/plonk/bit_check.hpp | 43 +- .../chips/plonk/incomplete_addition.hpp | 50 +- include/nil/blueprint/component.hpp | 20 +- include/nil/blueprint/component_stretcher.hpp | 226 ++- .../curves/detail/r1cs/element_g1_affine.hpp | 151 +- .../curves/detail/r1cs/element_ops.hpp | 30 +- .../detail/r1cs/fixed_base_mul_zcash.hpp | 495 +++--- .../algebra/curves/detail/r1cs/mnt4.hpp | 56 +- .../algebra/curves/detail/r1cs/mnt6.hpp | 56 +- .../curves/edwards/r1cs/element_g1.hpp | 2 +- .../algebra/curves/montgomery/element_g1.hpp | 298 ++-- .../curves/pasta/plonk/endo_scalar.hpp | 593 ++++--- .../plonk/fixed_base_scalar_mul_15_wires.hpp | 2 +- .../pasta/plonk/multi_scalar_mul_15_wires.hpp | 256 ++-- .../algebra/curves/pasta/plonk/types.hpp | 22 +- ...variable_base_endo_scalar_mul_15_wires.hpp | 629 ++++---- .../pasta/plonk/variable_base_scalar_mul.hpp | 800 +++++----- .../curves/twisted_edwards/element_g1.hpp | 778 +++++----- .../curves/weierstrass/r1cs/element_g1.hpp | 2 +- .../algebra/fields/plonk/addition.hpp | 79 +- .../fields/plonk/combined_inner_product.hpp | 294 ++-- .../algebra/fields/plonk/division_or_zero.hpp | 99 +- .../algebra/fields/plonk/exponentiation.hpp | 543 ++++--- .../algebra/fields/plonk/multiplication.hpp | 79 +- .../plonk/multiplication_by_constant.hpp | 114 +- .../algebra/fields/r1cs/element_fp.hpp | 4 +- .../algebra/fields/r1cs/element_fp2.hpp | 2 +- .../algebra/fields/r1cs/element_fp3.hpp | 2 +- .../algebra/fields/r1cs/field_to_bits.hpp | 323 ++-- .../weierstrass/r1cs/final_exponentiation.hpp | 2 +- .../components/boolean/r1cs/comparison.hpp | 189 ++- .../components/boolean/r1cs/conjunction.hpp | 138 +- .../components/boolean/r1cs/disjunction.hpp | 129 +- .../components/boolean/r1cs/inner_product.hpp | 103 +- .../components/detail/r1cs/lookup_1bit.hpp | 99 +- .../detail/r1cs/lookup_signed_3bit.hpp | 158 +- .../detail/r1cs/loose_multiplexing.hpp | 149 +- .../components/detail/r1cs/packing.hpp | 494 +++--- .../hashes/digest_selector_component.hpp | 86 +- .../blueprint/components/hashes/hash_io.hpp | 263 ++-- .../hashes/knapsack/r1cs/knapsack.hpp | 2 +- .../blueprint/components/hashes/pedersen.hpp | 853 +++++------ .../hashes/poseidon/plonk/poseidon.hpp | 96 +- .../poseidon/plonk/poseidon_constants.hpp | 13 +- .../hashes/sha2/r1cs/sha256_aux.hpp | 548 ++++--- .../hashes/sha2/r1cs/sha256_component.hpp | 604 ++++---- .../hashes/sha2/r1cs/sha256_construction.hpp | 461 +++--- .../merkle_tree/r1cs/authentication_path.hpp | 13 +- .../merkle_tree/r1cs/check_update.hpp | 311 ++-- .../components/merkle_tree/r1cs/prove.hpp | 4 +- .../components/merkle_tree/r1cs/validate.hpp | 16 +- .../components/routing/r1cs/as_waksman.hpp | 2 +- .../components/routing/r1cs/benes.hpp | 2 +- .../batch_dlog_accumulator_check_base.hpp | 20 +- .../plonk/kimchi/batch_verify_base_field.hpp | 223 +-- .../kimchi/batch_verify_scalar_field.hpp | 490 +++--- .../detail/batch_scalar/prepare_scalars.hpp | 284 ++-- .../kimchi/detail/batch_scalar/random.hpp | 302 ++-- .../snark/plonk/kimchi/detail/binding.hpp | 73 +- .../snark/plonk/kimchi/detail/compare.hpp | 632 ++++---- .../detail/constraints/generic_scalars.hpp | 351 +++-- .../constraints/index_terms_scalars.hpp | 378 ++--- .../detail/constraints/perm_scalars.hpp | 326 ++-- .../detail/constraints/rpn_expression.hpp | 1345 ++++++++-------- .../detail/constraints/rpn_string_literal.hpp | 211 +-- .../unnormalized_lagrange_basis.hpp | 310 ++-- .../constraints/vanishes_on_last_4_rows.hpp | 363 +++-- .../plonk/kimchi/detail/inner_constants.hpp | 82 +- .../snark/plonk/kimchi/detail/limbs.hpp | 265 ++-- .../snark/plonk/kimchi/detail/map_fq.hpp | 216 +-- .../snark/plonk/kimchi/detail/map_fr.hpp | 2 +- .../kimchi/detail/oracles_scalar/b_poly.hpp | 283 ++-- .../oracles_scalar/b_poly_coefficients.hpp | 200 ++- .../oracles_scalar/combine_proof_evals.hpp | 319 ++-- .../detail/oracles_scalar/element_powers.hpp | 225 +-- .../kimchi/detail/oracles_scalar/ft_eval.hpp | 1077 +++++++------ .../oracles_scalar/lagrange_denominators.hpp | 273 ++-- .../detail/oracles_scalar/oracles_cip.hpp | 364 +++-- .../detail/oracles_scalar/prev_chal_evals.hpp | 398 ++--- .../oracles_scalar/public_evaluations.hpp | 348 ++--- .../snark/plonk/kimchi/detail/sponge.hpp | 325 ++-- .../plonk/kimchi/detail/table_commitment.hpp | 352 ++--- .../snark/plonk/kimchi/detail/to_group.hpp | 1021 ++++++------ .../plonk/kimchi/detail/transcript_fq.hpp | 494 +++--- .../plonk/kimchi/detail/transcript_fr.hpp | 458 +++--- .../snark/plonk/kimchi/detail/zk_w3.hpp | 223 +-- .../plonk/kimchi/detail/zkpm_evaluate.hpp | 349 +++-- .../snark/plonk/kimchi/oracles_scalar.hpp | 515 +++---- .../plonk/kimchi/prepare_batch_scalar.hpp | 283 ++-- .../batch_dlog_accumulator_check_scalar.hpp | 30 +- .../kimchi/scalar_details/derive_plonk.hpp | 22 +- .../scalar_details/evals_of_split_evals.hpp | 32 +- .../scalar_details/plonk_map_fields.hpp | 6 +- .../prepare_scalars_inversion.hpp | 12 +- .../kimchi/types/alpha_argument_type.hpp | 22 +- .../snark/plonk/kimchi/types/commitment.hpp | 22 +- .../plonk/kimchi/types/evaluation_proof.hpp | 66 +- .../plonk/kimchi/types/index_term_type.hpp | 22 +- .../snark/plonk/kimchi/types/proof.hpp | 214 ++- .../plonk/kimchi/types/verifier_index.hpp | 106 +- .../plonk/kimchi/verifier_base_field.hpp | 1364 ++++++++--------- .../plonk/kimchi/verify_heterogenous_base.hpp | 10 +- .../kimchi/verify_heterogenous_scalar.hpp | 36 +- .../snark/plonk/kimchi/verify_scalar.hpp | 2 +- .../snark/r1cs_pp_zksnark/verifier.hpp | 2 +- .../voting/r1cs/encrypted_input_voting.hpp | 205 ++- test/CMakeLists.txt | 11 +- .../plonk/variable_base_endo_scalar_mul.cpp | 58 +- test/algebra/curves/r1cs/test_utils.hpp | 2 +- .../fields/plonk/combined_inner_product.cpp | 14 +- test/algebra/fields/plonk/element_powers.cpp | 19 +- test/algebra/fields/plonk/exponentiation.cpp | 49 +- .../algebra/fields/plonk/field_operations.cpp | 203 +-- test/algebra/fields/plonk/logic_and_flag.cpp | 13 +- test/algebra/fields/plonk/logic_or_flag.cpp | 9 +- test/algebra/fields/plonk/range_check.cpp | 78 +- test/algebra/fields/plonk/sqrt.cpp | 13 +- test/basic_components_r1cs_gg_ppzksnark.cpp | 5 +- test/hashes/r1cs/pedersen.cpp | 40 +- test/merkle_tree_components.cpp | 330 ++-- test/test_plonk_component.hpp | 535 ++++--- test/verifiers/kimchi/demo_verifier.cpp | 6 +- test/verifiers/kimchi/detail/to_group.cpp | 8 +- .../index_terms_instances/chacha_test.hpp | 8 +- .../index_terms_instances/recursion_test.hpp | 8 +- test/verifiers/kimchi/sponge/aux_sponge.hpp | 2 +- .../kimchi/sponge/aux_transcript_fq.hpp | 2 +- .../kimchi/sponge/aux_transcript_fr.hpp | 2 +- test/verifiers/kimchi/table_commitment.cpp | 24 +- .../scalar_details/evals_of_split_evals.cpp | 12 +- .../pickles/verify_heterogenous_base.cpp | 10 +- .../pickles/verify_heterogenous_scalar.cpp | 10 +- test/verify_r1cs_scheme.hpp | 1 + test/voting/r1cs/encrypted_input_voting.cpp | 41 +- 141 files changed, 14540 insertions(+), 14611 deletions(-) diff --git a/include/nil/blueprint/algorithms/generate_circuit.hpp b/include/nil/blueprint/algorithms/generate_circuit.hpp index 0f74bc422..31a80e866 100644 --- a/include/nil/blueprint/algorithms/generate_circuit.hpp +++ b/include/nil/blueprint/algorithms/generate_circuit.hpp @@ -33,66 +33,62 @@ #include namespace nil { - namespace crypto3 { - namespace blueprint { - namespace components { + namespace blueprint { + namespace components { - BOOST_TTI_HAS_STATIC_MEMBER_FUNCTION(generate_circuit) + BOOST_TTI_HAS_STATIC_MEMBER_FUNCTION(generate_circuit) - template - typename std::enable_if< - (!(has_static_member_function_generate_circuit &, - blueprint_public_assignment_table &, - const typename ComponentType::params_type &, - const std::size_t>>::value)), - typename ComponentType::result_type>::type - generate_circuit( - blueprint &bp, - blueprint_public_assignment_table &assignment, - const typename ComponentType::params_type & params, - const std::size_t start_row_index){ + template + typename std::enable_if<(!(has_static_member_function_generate_circuit< + ComponentType, + typename ComponentType::result_type, + boost::mpl::vector &, + assignment &, + const typename ComponentType::params_type &, + const std::size_t>>::value)), + typename ComponentType::result_type>::type + generate_circuit(blueprint &bp, + assignment &assignment, + const typename ComponentType::params_type ¶ms, + const std::size_t start_row_index) { - auto selector_iterator = assignment.find_selector(ComponentType::selector_seed); - std::size_t first_selector_index; + auto selector_iterator = assignment.find_selector(ComponentType::selector_seed); + std::size_t first_selector_index; - if (selector_iterator == assignment.selectors_end()){ - first_selector_index = assignment.allocate_selector(ComponentType::selector_seed, - ComponentType::gates_amount); - ComponentType::generate_gates(bp, assignment, params, first_selector_index); - } else { - first_selector_index = selector_iterator->second; - } + if (selector_iterator == assignment.selectors_end()) { + first_selector_index = + assignment.allocate_selector(ComponentType::selector_seed, ComponentType::gates_amount); + ComponentType::generate_gates(bp, assignment, params, first_selector_index); + } else { + first_selector_index = selector_iterator->second; + } - assignment.enable_selector(first_selector_index, start_row_index); + assignment.enable_selector(first_selector_index, start_row_index); - ComponentType::generate_copy_constraints(bp, assignment, params, start_row_index); + ComponentType::generate_copy_constraints(bp, assignment, params, start_row_index); - return typename ComponentType::result_type(params, start_row_index); - } + return typename ComponentType::result_type(params, start_row_index); + } - template - typename std::enable_if< - (has_static_member_function_generate_circuit &, - blueprint_public_assignment_table &, - const typename ComponentType::params_type &, - const std::size_t>>::value), - typename ComponentType::result_type>::type - generate_circuit( - blueprint &bp, - blueprint_public_assignment_table &assignment, - const typename ComponentType::params_type & params, - const std::size_t start_row_index){ + template + typename std::enable_if<(has_static_member_function_generate_circuit< + ComponentType, + typename ComponentType::result_type, + boost::mpl::vector &, + assignment &, + const typename ComponentType::params_type &, + const std::size_t>>::value), + typename ComponentType::result_type>::type + generate_circuit(blueprint &bp, + assignment &assignment, + const typename ComponentType::params_type ¶ms, + const std::size_t start_row_index) { - return ComponentType::generate_circuit(bp, assignment, params, start_row_index); - } + return ComponentType::generate_circuit(bp, assignment, params, start_row_index); + } - } // namespace components - } // namespace blueprint - } // namespace crypto3 + } // namespace components + } // namespace blueprint } // namespace nil #endif // CRYPTO3_ZK_COMPONENTS_ALGORITHMS_GENERATE_CIRCUIT_HPP diff --git a/include/nil/blueprint/blueprint/plonk/assignment.hpp b/include/nil/blueprint/blueprint/plonk/assignment.hpp index f16ddaf2c..6e4e44179 100644 --- a/include/nil/blueprint/blueprint/plonk/assignment.hpp +++ b/include/nil/blueprint/blueprint/plonk/assignment.hpp @@ -50,7 +50,7 @@ namespace nil { template class assignment> - : public crypto3::zk::snark::plonk_assignment_table { + : public crypto3::zk::snark::plonk_assignment_table { using zk_type = crypto3::zk::snark::plonk_assignment_table; @@ -64,20 +64,20 @@ namespace nil { std::size_t next_selector_index = 0; std::uint32_t assignment_allocated_rows = 0; std::vector assignment_private_storage; - shared_container_type shared_storage; // results of the previously prover + shared_container_type shared_storage; // results of the previously prover std::set lookup_constant_cols; std::set lookup_selector_cols; + public: static constexpr const std::size_t private_storage_index = std::numeric_limits::max(); - assignment(std::size_t witness_amount, std::size_t public_input_amount, - std::size_t constant_amount, std::size_t selector_amount) - : zk_type(witness_amount, public_input_amount, constant_amount, selector_amount) { + assignment(std::size_t witness_amount, std::size_t public_input_amount, std::size_t constant_amount, + std::size_t selector_amount) : + zk_type(witness_amount, public_input_amount, constant_amount, selector_amount) { } - assignment(const crypto3::zk::snark::plonk_table_description &desc) - : zk_type(desc.witness_columns, desc.public_input_columns, - desc.constant_columns, desc.selector_columns) { + assignment(const crypto3::zk::snark::plonk_table_description &desc) : + zk_type(desc.witness_columns, desc.public_input_columns, desc.constant_columns, desc.selector_columns) { } virtual value_type &selector(std::size_t selector_index, std::uint32_t row_index) { @@ -98,7 +98,7 @@ namespace nil { return this->_public_table._selectors[selector_index][row_index]; } - virtual const column_type& selector(std::uint32_t index) const { + virtual const column_type &selector(std::uint32_t index) const { return zk_type::selector(index); } @@ -124,9 +124,9 @@ namespace nil { } virtual void enable_selector(const std::size_t selector_index, - const std::size_t begin_row_index, - const std::size_t end_row_index, - const std::size_t index_step = 1) { + const std::size_t begin_row_index, + const std::size_t end_row_index, + const std::size_t index_step = 1) { for (std::size_t row_index = begin_row_index; row_index <= end_row_index; row_index += index_step) { @@ -134,12 +134,12 @@ namespace nil { } } - void fill_selector(std::uint32_t index, const column_type& column) override { + void fill_selector(std::uint32_t index, const column_type &column) override { lookup_selector_cols.insert(index); zk_type::fill_selector(index, column); } - virtual const std::set& get_lookup_selector_cols() const { + virtual const std::set &get_lookup_selector_cols() const { return lookup_selector_cols; } @@ -167,7 +167,7 @@ namespace nil { return shared_storage.size(); } - virtual const column_type& shared(std::uint32_t index) const { + virtual const column_type &shared(std::uint32_t index) const { return shared_storage[index]; } @@ -196,12 +196,11 @@ namespace nil { return zk_type::witnesses_amount(); } - virtual const column_type& witness(std::uint32_t index) const { + virtual const column_type &witness(std::uint32_t index) const { return zk_type::witness(index); } - virtual value_type &public_input( - std::uint32_t public_input_index, std::uint32_t row_index) { + virtual value_type &public_input(std::uint32_t public_input_index, std::uint32_t row_index) { BLUEPRINT_ASSERT(public_input_index < zk_type::public_inputs_amount()); @@ -211,8 +210,7 @@ namespace nil { return this->_public_table._public_inputs[public_input_index][row_index]; } - virtual value_type public_input( - std::uint32_t public_input_index, std::uint32_t row_index) const { + virtual value_type public_input(std::uint32_t public_input_index, std::uint32_t row_index) const { BLUEPRINT_ASSERT(public_input_index < zk_type::public_inputs_amount()); BLUEPRINT_ASSERT(row_index < zk_type::public_input_column_size(public_input_index)); @@ -228,12 +226,11 @@ namespace nil { return zk_type::public_inputs_amount(); } - virtual const column_type& public_input(std::uint32_t index) const { + virtual const column_type &public_input(std::uint32_t index) const { return zk_type::public_input(index); } - virtual value_type &constant( - std::uint32_t constant_index, std::uint32_t row_index) { + virtual value_type &constant(std::uint32_t constant_index, std::uint32_t row_index) { BLUEPRINT_ASSERT(constant_index < zk_type::constants_amount()); @@ -244,8 +241,7 @@ namespace nil { return this->_public_table._constants[constant_index][row_index]; } - virtual value_type constant( - std::uint32_t constant_index, std::uint32_t row_index) const { + virtual value_type constant(std::uint32_t constant_index, std::uint32_t row_index) const { BLUEPRINT_ASSERT(constant_index < zk_type::constants_amount()); BLUEPRINT_ASSERT(row_index < zk_type::constant_column_size(constant_index)); @@ -253,16 +249,16 @@ namespace nil { return zk_type::constant(constant_index)[row_index]; } - virtual const column_type& constant(std::uint32_t index) const { + virtual const column_type &constant(std::uint32_t index) const { return zk_type::constant(index); } - void fill_constant(std::uint32_t index, const column_type& column) override { + void fill_constant(std::uint32_t index, const column_type &column) override { lookup_constant_cols.insert(index); zk_type::fill_constant(index, column); } - virtual const std::set& get_lookup_constant_cols() const { + virtual const std::set &get_lookup_constant_cols() const { return lookup_constant_cols; } @@ -303,24 +299,21 @@ namespace nil { return assignment_private_storage.size(); } - virtual void export_table(std::ostream& os, bool wide_export = false) const { + virtual void export_table(std::ostream &os, bool wide_export = false) const { // wide_export is for e.g. potentiall fuzzer: does fixed width elements std::ios_base::fmtflags os_flags(os.flags()); std::size_t witnesses_size = this->_private_table.witnesses_amount(), public_size = this->_public_table.public_inputs_amount(), constants_size = this->_public_table.constants_amount(), selectors_size = this->_public_table.selectors_amount(); - std::uint32_t max_size = 0, - max_witnesses_size = 0, - max_public_inputs_size = 0, - max_constants_size = 0, + std::uint32_t max_size = 0, max_witnesses_size = 0, max_public_inputs_size = 0, max_constants_size = 0, max_selectors_size = 0; for (std::uint32_t i = 0; i < witnesses_size; i++) { max_witnesses_size = std::max(max_witnesses_size, this->_private_table.witness_column_size(i)); } for (std::uint32_t i = 0; i < public_size; i++) { - max_public_inputs_size = std::max(max_public_inputs_size, - this->_public_table.public_input_column_size(i)); + max_public_inputs_size = + std::max(max_public_inputs_size, this->_public_table.public_input_column_size(i)); } for (std::uint32_t i = 0; i < constants_size; i++) { max_constants_size = std::max(max_constants_size, this->_public_table.constant_column_size(i)); @@ -329,10 +322,8 @@ namespace nil { max_selectors_size = std::max(max_selectors_size, this->_public_table.selector_column_size(i)); } os << std::dec; - max_size = std::max({max_witnesses_size, - max_public_inputs_size, - max_constants_size, - max_selectors_size}); + max_size = + std::max({max_witnesses_size, max_public_inputs_size, max_constants_size, max_selectors_size}); os << "witnesses_size: " << witnesses_size << " " << "public_inputs_size: " << public_size << " " << "constants_size: " << constants_size << " " @@ -344,29 +335,37 @@ namespace nil { for (std::uint32_t i = 0; i < max_size; i++) { for (std::uint32_t j = 0; j < witnesses_size; j++) { os << std::setw(width) - << (i < this->_private_table.witness_column_size(j) ? - this->_private_table.witness(j)[i] : 0).data << " "; + << (i < this->_private_table.witness_column_size(j) ? this->_private_table.witness(j)[i] : 0) + .data + << " "; } os << "| "; for (std::uint32_t j = 0; j < public_size; j++) { os << std::setw(width) - << (i < this->_public_table.public_input_column_size(j) ? - this->_public_table.public_input(j)[i] : 0).data << " "; + << (i < this->_public_table.public_input_column_size(j) ? + this->_public_table.public_input(j)[i] : + 0) + .data + << " "; } os << "| "; for (std::uint32_t j = 0; j < constants_size; j++) { os << std::setw(width) - << (i < this->_public_table.constant_column_size(j) ? - this->_public_table.constant(j)[i] : 0).data << " "; + << (i < this->_public_table.constant_column_size(j) ? this->_public_table.constant(j)[i] : 0) + .data + << " "; } os << "| "; // Selectors only need a single bit, so we do not renew the size here for (std::uint32_t j = 0; j < selectors_size - 1; j++) { - os << (i < this->_public_table.selector_column_size(j) ? - this->_public_table.selector(j)[i] : 0).data << " "; + os << (i < this->_public_table.selector_column_size(j) ? this->_public_table.selector(j)[i] : 0) + .data + << " "; } os << (i < this->_public_table.selector_column_size(selectors_size - 1) ? - this->_public_table.selector(selectors_size - 1)[i] : 0).data; + this->_public_table.selector(selectors_size - 1)[i] : + 0) + .data; os << "\n"; } os.flush(); @@ -376,8 +375,8 @@ namespace nil { template typename BlueprintFieldType::value_type var_value( - const assignment> &input_assignment, - const crypto3::zk::snark::plonk_variable &input_var) { + const assignment> &input_assignment, + const crypto3::zk::snark::plonk_variable &input_var) { using var_column_type = typename crypto3::zk::snark::plonk_variable::column_type; using assignment_type = assignment>; @@ -391,7 +390,7 @@ namespace nil { if (input_var.type == var_column_type::public_input && input_var.index > 0) { return input_assignment.shared(input_var.index - 1, input_var.rotation); } - switch(input_var.type){ + switch (input_var.type) { case var_column_type::witness: return input_assignment.witness(input_var.index, input_var.rotation); case var_column_type::public_input: diff --git a/include/nil/blueprint/blueprint/plonk/assignment_proxy.hpp b/include/nil/blueprint/blueprint/plonk/assignment_proxy.hpp index 0f26a6519..e7f0bee50 100644 --- a/include/nil/blueprint/blueprint/plonk/assignment_proxy.hpp +++ b/include/nil/blueprint/blueprint/plonk/assignment_proxy.hpp @@ -52,27 +52,25 @@ namespace nil { bool check; std::set used_rows; std::set used_selector_rows; + public: - assignment_proxy(std::shared_ptr> assignment_, - std::uint32_t _id) : + assignment_proxy(std::shared_ptr> assignment_, std::uint32_t _id) : assignment>( assignment_->witnesses_amount(), assignment_->public_inputs_amount(), assignment_->constants_amount(), assignment_->selectors_amount()), - assignment_ptr(assignment_), - id(_id), - check(false) { + assignment_ptr(assignment_), id(_id), check(false) { assert(assignment_ptr); } assignment_proxy() = delete; - const assignment& get() const { + const assignment &get() const { return *assignment_ptr; } - assignment& get() { + assignment &get() { return *assignment_ptr; } @@ -84,11 +82,11 @@ namespace nil { check = flag; } - const std::set& get_used_rows() const { + const std::set &get_used_rows() const { return used_rows; } - const std::set& get_used_selector_rows() const { + const std::set &get_used_selector_rows() const { return used_selector_rows; } @@ -111,14 +109,16 @@ namespace nil { const auto lookup_selector_cols = assignment_ptr->get_lookup_selector_cols(); if (lookup_selector_cols.find(selector_index) == lookup_selector_cols.end() && used_selector_rows.find(row_index) == used_selector_rows.end()) { - std::cout << id << ": Not found selector " << selector_index << " on row " << row_index << std::endl; + std::cout << id << ": Not found selector " << selector_index << " on row " << row_index + << std::endl; BLUEPRINT_ASSERT(false); } } - return std::const_pointer_cast>(assignment_ptr)->selector(selector_index, row_index); + return std::const_pointer_cast>(assignment_ptr) + ->selector(selector_index, row_index); } - const column_type& selector(std::uint32_t index) const override { + const column_type &selector(std::uint32_t index) const override { return assignment_ptr->selector(index); } @@ -145,11 +145,11 @@ namespace nil { } } - void fill_selector(std::uint32_t index, const column_type& column) override { + void fill_selector(std::uint32_t index, const column_type &column) override { assignment_ptr->fill_selector(index, column); } - const std::set& get_lookup_selector_cols() const override { + const std::set &get_lookup_selector_cols() const override { return assignment_ptr->get_lookup_selector_cols(); } @@ -161,19 +161,20 @@ namespace nil { return assignment_ptr->shared(shared_index, row_index); } - value_type shared(std::uint32_t shared_index, std::uint32_t row_index) const override{ + value_type shared(std::uint32_t shared_index, std::uint32_t row_index) const override { if (check && row_index >= assignment_ptr->shared_column_size(shared_index)) { std::cout << id << ": Not found shared " << shared_index << " on row " << row_index << std::endl; BLUEPRINT_ASSERT(false); } - return std::const_pointer_cast>(assignment_ptr)->shared(shared_index, row_index); + return std::const_pointer_cast>(assignment_ptr) + ->shared(shared_index, row_index); } std::uint32_t shared_column_size(std::uint32_t index) const override { return assignment_ptr->shared_column_size(index); } - const column_type& shared(std::uint32_t index) const override { + const column_type &shared(std::uint32_t index) const override { return assignment_ptr->shared(index); } @@ -191,10 +192,11 @@ namespace nil { std::cout << id << ": Not found witness " << witness_index << " on row " << row_index << std::endl; BLUEPRINT_ASSERT(false); } - return std::const_pointer_cast>(assignment_ptr)->witness(witness_index, row_index); + return std::const_pointer_cast>(assignment_ptr) + ->witness(witness_index, row_index); } - const column_type& witness(std::uint32_t index) const override { + const column_type &witness(std::uint32_t index) const override { return assignment_ptr->witness(index); } @@ -206,17 +208,16 @@ namespace nil { return assignment_ptr->witness_column_size(index); } - value_type &public_input( - std::uint32_t public_input_index, std::uint32_t row_index) override { + value_type &public_input(std::uint32_t public_input_index, std::uint32_t row_index) override { return assignment_ptr->public_input(public_input_index, row_index); } - value_type public_input( - std::uint32_t public_input_index, std::uint32_t row_index) const override { - return std::const_pointer_cast>(assignment_ptr)->public_input(public_input_index, row_index); + value_type public_input(std::uint32_t public_input_index, std::uint32_t row_index) const override { + return std::const_pointer_cast>(assignment_ptr) + ->public_input(public_input_index, row_index); } - const column_type& public_input(std::uint32_t index) const override { + const column_type &public_input(std::uint32_t index) const override { return assignment_ptr->public_input(index); } @@ -228,8 +229,7 @@ namespace nil { return assignment_ptr->public_input_column_size(index); } - value_type &constant( - std::uint32_t constant_index, std::uint32_t row_index) override { + value_type &constant(std::uint32_t constant_index, std::uint32_t row_index) override { used_rows.insert(row_index); return assignment_ptr->constant(constant_index, row_index); } @@ -239,11 +239,13 @@ namespace nil { const auto lookup_constant_cols = assignment_ptr->get_lookup_constant_cols(); if (lookup_constant_cols.find(constant_index) == lookup_constant_cols.end() && used_rows.find(row_index) == used_rows.end()) { - std::cout << id << ": Not found constant " << constant_index << " on row " << row_index << std::endl; + std::cout << id << ": Not found constant " << constant_index << " on row " << row_index + << std::endl; BLUEPRINT_ASSERT(false); } } - return std::const_pointer_cast>(assignment_ptr)->constant(constant_index, row_index); + return std::const_pointer_cast>(assignment_ptr) + ->constant(constant_index, row_index); } std::uint32_t constants_amount() const override { @@ -254,15 +256,15 @@ namespace nil { return assignment_ptr->constant_column_size(index); } - void fill_constant(std::uint32_t index, const column_type& column) override { + void fill_constant(std::uint32_t index, const column_type &column) override { assignment_ptr->fill_constant(index, column); } - const column_type& constant(std::uint32_t index) const override { + const column_type &constant(std::uint32_t index) const override { return assignment_ptr->constant(index); } - const std::set& get_lookup_constant_cols() const override { + const std::set &get_lookup_constant_cols() const override { return assignment_ptr->get_lookup_constant_cols(); } @@ -308,7 +310,7 @@ namespace nil { return assignment_ptr->private_storage_size(); } - void export_table(std::ostream& os, bool wide_export = false) const override { + void export_table(std::ostream &os, bool wide_export = false) const override { std::ios_base::fmtflags os_flags(os.flags()); std::uint32_t witnesses_size = witnesses_amount(); @@ -317,12 +319,8 @@ namespace nil { std::uint32_t constants_size = constants_amount(); std::uint32_t selectors_size = selectors_amount(); - std::uint32_t max_size = 0, - max_witnesses_size = 0, - max_shared_size = 0, - max_public_inputs_size = 0, - max_constants_size = 0, - max_selectors_size = 0; + std::uint32_t max_size = 0, max_witnesses_size = 0, max_shared_size = 0, max_public_inputs_size = 0, + max_constants_size = 0, max_selectors_size = 0; for (std::uint32_t i = 0; i < witnesses_size; i++) { max_witnesses_size = std::max(max_witnesses_size, witness_column_size(i)); } @@ -339,10 +337,8 @@ namespace nil { max_selectors_size = std::max(max_selectors_size, selector_column_size(i)); } - max_size = std::max({max_witnesses_size, - max_public_inputs_size, - max_constants_size, - max_selectors_size}); + max_size = + std::max({max_witnesses_size, max_public_inputs_size, max_constants_size, max_selectors_size}); os << "witnesses_size: " << witnesses_size << " " << "shared_size: " << shared_size << " " @@ -353,13 +349,13 @@ namespace nil { << "internal used rows size: " << used_rows.size() << "\n"; os << "internal used rows: "; - for (const auto& it : used_rows) { + for (const auto &it : used_rows) { os << it << " "; } os << "\n"; os << "internal used selector rows: "; - for (const auto& it : used_selector_rows) { + for (const auto &it : used_selector_rows) { os << it << " "; } os << "\n"; @@ -386,31 +382,33 @@ namespace nil { for (std::uint32_t j = 0; j < witnesses_size; j++) { os << std::setw(width) << (i < assignment_ptr->witness_column_size(j) && is_used_row ? - assignment_ptr->witness(j, i) : 0).data << " "; + assignment_ptr->witness(j, i) : + 0) + .data + << " "; } os << "| "; for (std::uint32_t j = 0; j < shared_size; j++) { - os << std::setw(width) - << (i < shared_column_size(j) ? - shared(j, i) : 0).data << " "; + os << std::setw(width) << (i < shared_column_size(j) ? shared(j, i) : 0).data << " "; } os << "| "; for (std::uint32_t j = 0; j < public_size; j++) { os << std::setw(width) - << (i < assignment_ptr->public_input_column_size(j) ? - assignment_ptr->public_input(j, i) : 0).data << " "; + << (i < assignment_ptr->public_input_column_size(j) ? assignment_ptr->public_input(j, i) : 0) + .data + << " "; } os << "| "; for (std::uint32_t j = 0; j < constants_size; j++) { os << std::setw(width) - << (i < assignment_ptr->constant_column_size(j) ? - assignment_ptr->constant(j, i) : 0).data << " "; + << (i < assignment_ptr->constant_column_size(j) ? assignment_ptr->constant(j, i) : 0).data + << " "; } os << "| "; // Selectors only need a single bit, so we do not renew the size here for (std::uint32_t j = 0; j < selectors_size - 1; j++) { - os << (i < assignment_ptr->selector_column_size(j) ? - assignment_ptr->selector(j, i) : 0).data << " "; + os << (i < assignment_ptr->selector_column_size(j) ? assignment_ptr->selector(j, i) : 0).data + << " "; } os << "\n"; } @@ -421,8 +419,8 @@ namespace nil { template crypto3::zk::snark::plonk_variable save_shared_var( - assignment_proxy> &input_assignment, - const crypto3::zk::snark::plonk_variable &input_var) { + assignment_proxy> &input_assignment, + const crypto3::zk::snark::plonk_variable &input_var) { using var = crypto3::zk::snark::plonk_variable; std::uint32_t row_index = input_assignment.shared_column_size(0); auto res = var(1, row_index, false, var::column_type::public_input); @@ -432,8 +430,9 @@ namespace nil { template std::vector> save_shared_var( - assignment_proxy> &input_assignment, - const std::vector> &input_vars) { + assignment_proxy> &input_assignment, + const std::vector> + &input_vars) { std::vector> res; for (const auto &it : input_vars) { res.push_back(save_shared_var(input_assignment, it)); @@ -442,18 +441,17 @@ namespace nil { } template - bool is_satisfied(const circuit_proxy> - &bp, - const assignment_proxy> - &assignments) { + bool is_satisfied( + const circuit_proxy> &bp, + const assignment_proxy> &assignments) { - const auto& used_gates = bp.get_used_gates(); + const auto &used_gates = bp.get_used_gates(); - const auto& used_lookup_gates = bp.get_used_lookup_gates(); + const auto &used_lookup_gates = bp.get_used_lookup_gates(); - const auto& used_copy_constraints = bp.get_used_copy_constraints(); + const auto &used_copy_constraints = bp.get_used_copy_constraints(); - const auto& selector_rows = assignments.get_used_selector_rows(); + const auto &selector_rows = assignments.get_used_selector_rows(); return is_satisfied(bp, assignments, used_gates, used_lookup_gates, used_copy_constraints, selector_rows); } diff --git a/include/nil/blueprint/blueprint/plonk/circuit_proxy.hpp b/include/nil/blueprint/blueprint/plonk/circuit_proxy.hpp index f77e67eee..cff79182a 100644 --- a/include/nil/blueprint/blueprint/plonk/circuit_proxy.hpp +++ b/include/nil/blueprint/blueprint/plonk/circuit_proxy.hpp @@ -41,11 +41,11 @@ namespace nil { : public circuit> { private: - typedef crypto3::zk::snark::plonk_constraint_system ArithmetizationType; using constraint_type = crypto3::zk::snark::plonk_constraint; using lookup_constraint_type = crypto3::zk::snark::plonk_lookup_constraint; - using lookup_table_definition = typename nil::crypto3::zk::snark::lookup_table_definition; + using lookup_table_definition = + typename nil::crypto3::zk::snark::lookup_table_definition; std::shared_ptr> circuit_ptr; std::uint32_t id; @@ -55,33 +55,36 @@ namespace nil { std::set used_lookup_tables; std::uint32_t get_gate_index(std::size_t selector_index) const { - const auto& gates = circuit_ptr->gates(); - auto it = std::find_if(gates.begin(), gates.end(), [selector_index](const typename ArithmetizationType::gates_container_type::value_type& gate) -> bool - { return selector_index == gate.selector_index; }); + const auto &gates = circuit_ptr->gates(); + auto it = std::find_if( + gates.begin(), gates.end(), + [selector_index](const typename ArithmetizationType::gates_container_type::value_type &gate) + -> bool { return selector_index == gate.selector_index; }); return it - gates.begin(); } std::uint32_t get_lookup_gate_index(std::size_t selector_index) const { - const auto& lookup_gates = circuit_ptr->lookup_gates(); - auto it = std::find_if(lookup_gates.begin(), lookup_gates.end(), - [selector_index](const typename ArithmetizationType::lookup_gates_container_type::value_type& lookup_gate) -> bool - { return selector_index == lookup_gate.tag_index; }); + const auto &lookup_gates = circuit_ptr->lookup_gates(); + auto it = std::find_if( + lookup_gates.begin(), lookup_gates.end(), + [selector_index]( + const typename ArithmetizationType::lookup_gates_container_type::value_type &lookup_gate) + -> bool { return selector_index == lookup_gate.tag_index; }); return it - lookup_gates.begin(); } public: - circuit_proxy(std::shared_ptr> circuit, std::uint32_t _id) : - circuit_ptr(circuit), - id(_id) {} + circuit_ptr(circuit), id(_id) { + } circuit_proxy() = delete; - const circuit& get() const { + const circuit &get() const { return *circuit_ptr; } - circuit& get() { + circuit &get() { return *circuit_ptr; } @@ -89,35 +92,35 @@ namespace nil { return id; } - const std::set& get_used_gates() const { + const std::set &get_used_gates() const { return used_gates; } - const typename ArithmetizationType::gates_container_type& gates() const override { + const typename ArithmetizationType::gates_container_type &gates() const override { return circuit_ptr->gates(); } - const std::set& get_used_copy_constraints() const { + const std::set &get_used_copy_constraints() const { return used_copy_constraints; } - const typename ArithmetizationType::copy_constraints_container_type& copy_constraints() const override { + const typename ArithmetizationType::copy_constraints_container_type ©_constraints() const override { return circuit_ptr->copy_constraints(); } - const std::set& get_used_lookup_gates() const { + const std::set &get_used_lookup_gates() const { return used_lookup_gates; } - const typename ArithmetizationType::lookup_gates_container_type& lookup_gates() const override { + const typename ArithmetizationType::lookup_gates_container_type &lookup_gates() const override { return circuit_ptr->lookup_gates(); } - const std::set& get_used_lookup_tables() const { + const std::set &get_used_lookup_tables() const { return used_lookup_tables; } - const typename ArithmetizationType::lookup_tables_type& lookup_tables() const override { + const typename ArithmetizationType::lookup_tables_type &lookup_tables() const override { return circuit_ptr->lookup_tables(); } @@ -183,21 +186,23 @@ namespace nil { used_lookup_tables.insert(idx); } - const typename lookup_library::left_reserved_type - &get_reserved_indices() const override { + const typename lookup_library::left_reserved_type & + get_reserved_indices() const override { return circuit_ptr->get_reserved_indices(); } const typename lookup_library::right_reserved_type & - get_reserved_indices_right() const override { + get_reserved_indices_right() const override { return circuit_ptr->get_reserved_indices_right(); } - const std::map> &get_reserved_tables() const override { + const std::map> & + get_reserved_tables() const override { return circuit_ptr->get_reserved_tables(); } - void add_copy_constraint(const crypto3::zk::snark::plonk_copy_constraint ©_constraint) override { + void add_copy_constraint( + const crypto3::zk::snark::plonk_copy_constraint ©_constraint) override { circuit_ptr->add_copy_constraint(copy_constraint); if (circuit_ptr->copy_constraints().size() > 0) { used_copy_constraints.insert(circuit_ptr->copy_constraints().size() - 1); @@ -208,7 +213,7 @@ namespace nil { return circuit_ptr->get_next_selector_index(); } - void export_circuit(std::ostream& os) const override { + void export_circuit(std::ostream &os) const override { std::ios_base::fmtflags os_flags(os.flags()); const auto gates = circuit_ptr->gates(); @@ -223,7 +228,7 @@ namespace nil { << "copy_constraints_size: " << copy_constraints.size() << " " << "lookup_gates_size: " << used_lookup_gates.size() << "\n"; - for (const auto& i : used_gates) { + for (const auto &i : used_gates) { os << i << ": selector: " << gates[i].selector_index << " constraints_size: " << gates[i].constraints.size() << "\n"; for (std::size_t j = 0; j < gates[i].constraints.size(); j++) { @@ -231,13 +236,12 @@ namespace nil { } } - for (const auto& i : used_copy_constraints) { - os << i << ": " << copy_constraints[i].first << " " - << copy_constraints[i].second << "\n"; + for (const auto &i : used_copy_constraints) { + os << i << ": " << copy_constraints[i].first << " " << copy_constraints[i].second << "\n"; } std::cout << "\nlookup gates:\n"; - for (const auto& i : used_lookup_gates) { + for (const auto &i : used_lookup_gates) { os << i << ": selector: " << lookup_gates[i].tag_index << " lookup constraints size: " << lookup_gates[i].constraints.size() << "\n"; for (std::size_t j = 0; j < lookup_gates[i].constraints.size(); j++) { @@ -252,9 +256,9 @@ namespace nil { } std::cout << "\nlookup tables:\n"; - for (const auto& i : used_lookup_tables) { + for (const auto &i : used_lookup_tables) { bool found = false; - for (const auto& it : lookup_table_indexes) { + for (const auto &it : lookup_table_indexes) { if (it.second == (i + 1)) { os << i << ": " << it.first << "\n"; found = true; diff --git a/include/nil/blueprint/blueprint/r1cs/circuit.hpp b/include/nil/blueprint/blueprint/r1cs/circuit.hpp index df959e60c..f8d5602a0 100644 --- a/include/nil/blueprint/blueprint/r1cs/circuit.hpp +++ b/include/nil/blueprint/blueprint/r1cs/circuit.hpp @@ -35,136 +35,136 @@ #include -#include #include namespace nil { - namespace crypto3 { - namespace blueprint { - - template - class blueprint; - - template - class blueprint> { - typedef zk::snark::r1cs_constraint_system ArithmetizationType; - - zk::snark::r1cs_variable_assignment> - values; /* values[0] will hold the value of the first - allocated variable of the blueprint, *NOT* constant 1 */ - typename BlueprintFieldType::value_type constant_term; - - typename math::linear_variable::index_type next_free_var; - typename detail::blueprint_linear_combination::index_type next_free_lc; - std::vector lc_values; - zk::snark::r1cs_constraint_system constraint_system; - - public: - // typedef BlueprintFieldType field_type; - - using value_type = detail::blueprint_variable; - - blueprint() { - constant_term = BlueprintFieldType::value_type::one(); - - next_free_var = 1; /* to account for constant 1 term */ - next_free_lc = 0; - } - - void clear_values() { - std::fill(values.begin(), values.end(), BlueprintFieldType::value_type::zero()); - } - - typename BlueprintFieldType::value_type &val(const value_type &var) { - assert(var.index <= values.size()); - return (var.index == 0 ? constant_term : values[var.index - 1]); - } - - typename BlueprintFieldType::value_type val(const value_type &var) const { - assert(var.index <= values.size()); - return (var.index == 0 ? constant_term : values[var.index - 1]); - } - - typename BlueprintFieldType::value_type & - lc_val(const detail::blueprint_linear_combination &lc) { - if (lc.is_variable) { - return this->val(value_type(lc.index)); - } else { - assert(lc.index < lc_values.size()); - return lc_values[lc.index]; - } - } - - typename BlueprintFieldType::value_type - lc_val(const detail::blueprint_linear_combination &lc) const { - if (lc.is_variable) { - return this->val(value_type(lc.index)); - } else { - assert(lc.index < lc_values.size()); - return lc_values[lc.index]; - } - } - - void add_r1cs_constraint(const zk::snark::r1cs_constraint &constr) { - constraint_system.constraints.emplace_back(constr); - } - - bool is_satisfied() const { - return constraint_system.is_satisfied(primary_input(), auxiliary_input()); - } - - std::size_t num_constraints() const { - return constraint_system.num_constraints(); - } - - std::size_t num_inputs() const { - return constraint_system.num_inputs(); - } - - std::size_t num_variables() const { - return next_free_var - 1; - } - - void set_input_sizes(const std::size_t primary_input_size) { - assert(primary_input_size <= num_variables()); - constraint_system.primary_input_size = primary_input_size; - constraint_system.auxiliary_input_size = num_variables() - primary_input_size; - } - - zk::snark::r1cs_variable_assignment> full_variable_assignment() const { - return values; - } - - zk::snark::r1cs_primary_input primary_input() const { - return zk::snark::r1cs_primary_input(values.begin(), - values.begin() + num_inputs()); - } - - zk::snark::r1cs_auxiliary_input auxiliary_input() const { - return zk::snark::r1cs_auxiliary_input(values.begin() + num_inputs(), - values.end()); - } - - zk::snark::r1cs_constraint_system get_constraint_system() const { - return constraint_system; - } - - friend class detail::blueprint_variable; - friend class detail::blueprint_linear_combination; - - private: - typename math::linear_variable::index_type allocate_var_index() { - ++constraint_system.auxiliary_input_size; - values.emplace_back(BlueprintFieldType::value_type::zero()); - return next_free_var++; - } - - typename detail::blueprint_linear_combination::index_type allocate_lc_index() { - lc_values.emplace_back(BlueprintFieldType::value_type::zero()); - return next_free_lc++; - } - }; - } // namespace blueprint - } // namespace crypto3 + namespace blueprint { + + template + class blueprint; + + template + class blueprint> { + typedef crypto3::zk::snark::r1cs_constraint_system ArithmetizationType; + + crypto3::zk::snark::r1cs_variable_assignment< + crypto3::zk::snark::plonk_constraint_system> + values; /* values[0] will hold the value of the first + allocated variable of the blueprint, *NOT* constant 1 */ + typename BlueprintFieldType::value_type constant_term; + + typename crypto3::math::linear_variable::index_type next_free_var; + typename detail::blueprint_linear_combination::index_type next_free_lc; + std::vector lc_values; + crypto3::zk::snark::r1cs_constraint_system constraint_system; + + public: + // typedef BlueprintFieldType field_type; + + using value_type = detail::blueprint_variable; + + blueprint() { + constant_term = BlueprintFieldType::value_type::one(); + + next_free_var = 1; /* to account for constant 1 term */ + next_free_lc = 0; + } + + void clear_values() { + std::fill(values.begin(), values.end(), BlueprintFieldType::value_type::zero()); + } + + typename BlueprintFieldType::value_type &val(const value_type &var) { + assert(var.index <= values.size()); + return (var.index == 0 ? constant_term : values[var.index - 1]); + } + + typename BlueprintFieldType::value_type val(const value_type &var) const { + assert(var.index <= values.size()); + return (var.index == 0 ? constant_term : values[var.index - 1]); + } + + typename BlueprintFieldType::value_type & + lc_val(const detail::blueprint_linear_combination &lc) { + if (lc.is_variable) { + return this->val(value_type(lc.index)); + } else { + assert(lc.index < lc_values.size()); + return lc_values[lc.index]; + } + } + + typename BlueprintFieldType::value_type + lc_val(const detail::blueprint_linear_combination &lc) const { + if (lc.is_variable) { + return this->val(value_type(lc.index)); + } else { + assert(lc.index < lc_values.size()); + return lc_values[lc.index]; + } + } + + void add_r1cs_constraint(const crypto3::zk::snark::r1cs_constraint &constr) { + constraint_system.constraints.emplace_back(constr); + } + + bool is_satisfied() const { + return constraint_system.is_satisfied(primary_input(), auxiliary_input()); + } + + std::size_t num_constraints() const { + return constraint_system.num_constraints(); + } + + std::size_t num_inputs() const { + return constraint_system.num_inputs(); + } + + std::size_t num_variables() const { + return next_free_var - 1; + } + + void set_input_sizes(const std::size_t primary_input_size) { + assert(primary_input_size <= num_variables()); + constraint_system.primary_input_size = primary_input_size; + constraint_system.auxiliary_input_size = num_variables() - primary_input_size; + } + + crypto3::zk::snark::r1cs_variable_assignment< + crypto3::zk::snark::plonk_constraint_system> + full_variable_assignment() const { + return values; + } + + crypto3::zk::snark::r1cs_primary_input primary_input() const { + return crypto3::zk::snark::r1cs_primary_input(values.begin(), + values.begin() + num_inputs()); + } + + crypto3::zk::snark::r1cs_auxiliary_input auxiliary_input() const { + return crypto3::zk::snark::r1cs_auxiliary_input(values.begin() + num_inputs(), + values.end()); + } + + crypto3::zk::snark::r1cs_constraint_system get_constraint_system() const { + return constraint_system; + } + + friend class detail::blueprint_variable; + friend class detail::blueprint_linear_combination; + + private: + typename crypto3::math::linear_variable::index_type allocate_var_index() { + ++constraint_system.auxiliary_input_size; + values.emplace_back(BlueprintFieldType::value_type::zero()); + return next_free_var++; + } + + typename detail::blueprint_linear_combination::index_type allocate_lc_index() { + lc_values.emplace_back(BlueprintFieldType::value_type::zero()); + return next_free_lc++; + } + }; + } // namespace blueprint } // namespace nil #endif // CRYPTO3_BLUEPRINT_COMPONENTS_BLUEPRINT_R1CS_HPP diff --git a/include/nil/blueprint/blueprint/r1cs/detail/r1cs/blueprint_linear_combination.hpp b/include/nil/blueprint/blueprint/r1cs/detail/r1cs/blueprint_linear_combination.hpp index 39b80cf82..d96eafb1d 100644 --- a/include/nil/blueprint/blueprint/r1cs/detail/r1cs/blueprint_linear_combination.hpp +++ b/include/nil/blueprint/blueprint/r1cs/detail/r1cs/blueprint_linear_combination.hpp @@ -34,252 +34,250 @@ #include +#include + namespace nil { - namespace crypto3 { - namespace blueprint { + namespace blueprint { - template - class blueprint; + template + class blueprint; - namespace detail { + namespace detail { - template - class blueprint_linear_combination; + template + class blueprint_linear_combination; - template - class blueprint_linear_combination> - : public math::linear_combination { + template + class blueprint_linear_combination> + : public crypto3::math::linear_combination { - typedef zk::snark::r1cs_constraint_system ArithmetizationType; - typedef BlueprintFieldType field_type; - typedef typename field_type::value_type field_value_type; + typedef crypto3::zk::snark::r1cs_constraint_system ArithmetizationType; + typedef BlueprintFieldType field_type; + typedef typename field_type::value_type field_value_type; - public: - using index_type = std::size_t; - bool is_variable; - index_type index; + public: + using index_type = std::size_t; + bool is_variable; + index_type index; - blueprint_linear_combination() { - this->is_variable = false; - } + blueprint_linear_combination() { + this->is_variable = false; + } + + blueprint_linear_combination(const blueprint_variable &var) { + this->is_variable = true; + this->index = var.index; + this->terms.emplace_back(crypto3::math::linear_term(var)); + } + + void assign(blueprint &bp, + const crypto3::math::linear_combination &lc) { + assert(this->is_variable == false); + this->index = bp.allocate_lc_index(); + this->terms = lc.terms; + } - blueprint_linear_combination(const blueprint_variable &var) { - this->is_variable = true; - this->index = var.index; - this->terms.emplace_back(math::linear_term(var)); + void evaluate(blueprint &bp) const { + if (this->is_variable) { + return; // do nothing } - void assign(blueprint &bp, const math::linear_combination &lc) { - assert(this->is_variable == false); - this->index = bp.allocate_lc_index(); - this->terms = lc.terms; + field_value_type sum = 0; + for (auto term : this->terms) { + sum += term.coeff * bp.val(blueprint_variable(term.index)); } - void evaluate(blueprint &bp) const { - if (this->is_variable) { - return; // do nothing - } + bp.lc_val(*this) = sum; + } - field_value_type sum = 0; + bool is_constant() const { + if (is_variable) { + return (index == 0); + } else { for (auto term : this->terms) { - sum += term.coeff * bp.val(blueprint_variable(term.index)); - } - - bp.lc_val(*this) = sum; - } - - bool is_constant() const { - if (is_variable) { - return (index == 0); - } else { - for (auto term : this->terms) { - if (term.index != 0) { - return false; - } + if (term.index != 0) { + return false; } - - return true; } + + return true; } + } - field_value_type constant_term() const { - if (is_variable) { - return (index == 0 ? field_value_type::one() : field_value_type::zero()); - } else { - field_value_type result = field_value_type::zero(); - for (auto term : this->terms) { - if (term.index == 0) { - result += term.coeff; - } + field_value_type constant_term() const { + if (is_variable) { + return (index == 0 ? field_value_type::one() : field_value_type::zero()); + } else { + field_value_type result = field_value_type::zero(); + for (auto term : this->terms) { + if (term.index == 0) { + result += term.coeff; } - return result; } + return result; } + } + }; + + template + class blueprint_linear_combination_vector; + + template + class blueprint_linear_combination_vector> + : private std::vector< + blueprint_linear_combination>> { + + typedef crypto3::zk::snark::r1cs_constraint_system ArithmetizationType; + typedef typename BlueprintFieldType::value_type field_value_type; + typedef std::vector> contents; + + public: + using typename contents::const_iterator; + using typename contents::const_reverse_iterator; + using typename contents::iterator; + using typename contents::reverse_iterator; + + using contents::begin; + using contents::emplace_back; + using contents::empty; + using contents::end; + using contents::insert; + using contents::rbegin; + using contents::rend; + using contents::reserve; + using contents::size; + using contents::operator[]; + using contents::resize; + + blueprint_linear_combination_vector() : contents() {}; + blueprint_linear_combination_vector(const blueprint_variable_vector &arr) { + for (auto &v : arr) + this->emplace_back(blueprint_linear_combination(v)); }; - - template - class blueprint_linear_combination_vector; - - template - class blueprint_linear_combination_vector< - crypto3::zk::snark::r1cs_constraint_system> - : private std::vector>> { - - typedef zk::snark::r1cs_constraint_system ArithmetizationType; - typedef typename BlueprintFieldType::value_type field_value_type; - typedef std::vector> contents; - - public: - using typename contents::const_iterator; - using typename contents::const_reverse_iterator; - using typename contents::iterator; - using typename contents::reverse_iterator; - - using contents::begin; - using contents::emplace_back; - using contents::empty; - using contents::end; - using contents::insert; - using contents::rbegin; - using contents::rend; - using contents::reserve; - using contents::size; - using contents::operator[]; - using contents::resize; - - blueprint_linear_combination_vector() : contents() {}; - blueprint_linear_combination_vector(const blueprint_variable_vector &arr) { - for (auto &v : arr) - this->emplace_back(blueprint_linear_combination(v)); - }; - blueprint_linear_combination_vector(std::size_t count) : contents(count) {}; - blueprint_linear_combination_vector( - std::size_t count, - const blueprint_linear_combination &value) : - contents(count, value) {}; - blueprint_linear_combination_vector(typename contents::const_iterator first, - typename contents::const_iterator last) : - contents(first, last) {}; - blueprint_linear_combination_vector(typename contents::const_reverse_iterator first, - typename contents::const_reverse_iterator last) : - contents(first, last) {}; - - void evaluate(blueprint &bp) const { - for (std::size_t i = 0; i < this->size(); ++i) { - (*this)[i].evaluate(bp); - } + blueprint_linear_combination_vector(std::size_t count) : contents(count) {}; + blueprint_linear_combination_vector(std::size_t count, + const blueprint_linear_combination &value) : + contents(count, value) {}; + blueprint_linear_combination_vector(typename contents::const_iterator first, + typename contents::const_iterator last) : contents(first, last) {}; + blueprint_linear_combination_vector(typename contents::const_reverse_iterator first, + typename contents::const_reverse_iterator last) : + contents(first, last) {}; + + void evaluate(blueprint &bp) const { + for (std::size_t i = 0; i < this->size(); ++i) { + (*this)[i].evaluate(bp); } + } - void fill_with_field_elements(blueprint &bp, - const std::vector &vals) const { - assert(this->size() == vals.size()); - for (std::size_t i = 0; i < vals.size(); ++i) { - bp.lc_val((*this)[i]) = vals[i]; - } + void fill_with_field_elements(blueprint &bp, + const std::vector &vals) const { + assert(this->size() == vals.size()); + for (std::size_t i = 0; i < vals.size(); ++i) { + bp.lc_val((*this)[i]) = vals[i]; } + } - void fill_with_bits(blueprint &bp, const std::vector &bits) const { - assert(this->size() == bits.size()); - for (std::size_t i = 0; i < bits.size(); ++i) { - bp.lc_val((*this)[i]) = (bits[i] ? field_value_type::one() : field_value_type::zero()); - } + void fill_with_bits(blueprint &bp, const std::vector &bits) const { + assert(this->size() == bits.size()); + for (std::size_t i = 0; i < bits.size(); ++i) { + bp.lc_val((*this)[i]) = (bits[i] ? field_value_type::one() : field_value_type::zero()); } + } - void fill_with_bits_of_ulong(blueprint &bp, const unsigned long i) const { - this->fill_with_bits_of_field_element(bp, field_value_type(i)); - } + void fill_with_bits_of_ulong(blueprint &bp, const unsigned long i) const { + this->fill_with_bits_of_field_element(bp, field_value_type(i)); + } - void fill_with_bits_of_field_element(blueprint &bp, - const field_value_type &r) const { - for (std::size_t i = 0; i < this->size(); ++i) { - bp.lc_val((*this)[i]) = multiprecision::bit_test(r.data, i) ? field_value_type::one() : - field_value_type::zero(); - } + void fill_with_bits_of_field_element(blueprint &bp, + const field_value_type &r) const { + for (std::size_t i = 0; i < this->size(); ++i) { + bp.lc_val((*this)[i]) = crypto3::multiprecision::bit_test(r.data, i) ? field_value_type::one() : + field_value_type::zero(); } + } - std::vector get_vals(const blueprint &bp) const { - std::vector result(this->size()); - for (std::size_t i = 0; i < this->size(); ++i) { - result[i] = bp.lc_val((*this)[i]); - } - return result; + std::vector get_vals(const blueprint &bp) const { + std::vector result(this->size()); + for (std::size_t i = 0; i < this->size(); ++i) { + result[i] = bp.lc_val((*this)[i]); } + return result; + } - std::vector get_bits(const blueprint &bp) const { - std::vector result; - for (std::size_t i = 0; i < this->size(); ++i) { - const field_value_type v = bp.lc_val((*this)[i]); - assert(v.is_zero() || v.is_one()); - result.push_back(v.is_one()); - } - return result; + std::vector get_bits(const blueprint &bp) const { + std::vector result; + for (std::size_t i = 0; i < this->size(); ++i) { + const field_value_type v = bp.lc_val((*this)[i]); + assert(v.is_zero() || v.is_one()); + result.push_back(v.is_one()); } + return result; + } - field_value_type get_field_element_from_bits(const blueprint &bp) const { - field_value_type result = field_value_type::zero(); - - for (std::size_t i = 0; i < this->size(); ++i) { - /* push in the new bit */ - const field_value_type v = bp.lc_val((*this)[this->size() - 1 - i]); - assert(v.is_zero() || v.is_one()); - result += result + v; - } + field_value_type get_field_element_from_bits(const blueprint &bp) const { + field_value_type result = field_value_type::zero(); - return result; + for (std::size_t i = 0; i < this->size(); ++i) { + /* push in the new bit */ + const field_value_type v = bp.lc_val((*this)[this->size() - 1 - i]); + assert(v.is_zero() || v.is_one()); + result += result + v; } - }; - template - math::linear_combination - blueprint_sum(const blueprint_linear_combination_vector &v) { + return result; + } + }; - math::linear_combination result; - for (auto &term : v) { - result = result + term; - } + template + crypto3::math::linear_combination + blueprint_sum(const blueprint_linear_combination_vector &v) { - return result; + crypto3::math::linear_combination result; + for (auto &term : v) { + result = result + term; } - template - math::linear_combination - blueprint_packing_sum(const blueprint_linear_combination_vector &v) { + return result; + } - typename FieldType::value_type twoi = - FieldType::value_type::one(); // will hold 2^i entering each iteration - std::vector> all_terms; - for (auto &lc : v) { - for (auto &term : lc.terms) { - all_terms.emplace_back(twoi * term); - } - twoi += twoi; - } + template + crypto3::math::linear_combination + blueprint_packing_sum(const blueprint_linear_combination_vector &v) { - return math::linear_combination(all_terms); + typename FieldType::value_type twoi = + FieldType::value_type::one(); // will hold 2^i entering each iteration + std::vector> all_terms; + for (auto &lc : v) { + for (auto &term : lc.terms) { + all_terms.emplace_back(twoi * term); + } + twoi += twoi; } - template - math::linear_combination - blueprint_coeff_sum(const blueprint_linear_combination_vector &v, - const std::vector &coeffs) { + return crypto3::math::linear_combination(all_terms); + } - assert(v.size() == coeffs.size()); - std::vector> all_terms; + template + crypto3::math::linear_combination + blueprint_coeff_sum(const blueprint_linear_combination_vector &v, + const std::vector &coeffs) { - auto coeff_it = coeffs.begin(); - for (auto &lc : v) { - for (auto &term : lc.terms) { - all_terms.emplace_back((*coeff_it) * term); - } - ++coeff_it; - } + assert(v.size() == coeffs.size()); + std::vector> all_terms; - return math::linear_combination(all_terms); + auto coeff_it = coeffs.begin(); + for (auto &lc : v) { + for (auto &term : lc.terms) { + all_terms.emplace_back((*coeff_it) * term); + } + ++coeff_it; } - } // namespace detail - } // namespace blueprint - } // namespace crypto3 + + return crypto3::math::linear_combination(all_terms); + } + } // namespace detail + } // namespace blueprint } // namespace nil #endif // CRYPTO3_BLUEPRINT_COMPONENTS_LINEAR_COMBINATION_HPP diff --git a/include/nil/blueprint/blueprint/r1cs/detail/r1cs/blueprint_variable.hpp b/include/nil/blueprint/blueprint/r1cs/detail/r1cs/blueprint_variable.hpp index 04823f36b..ca066e90c 100644 --- a/include/nil/blueprint/blueprint/r1cs/detail/r1cs/blueprint_variable.hpp +++ b/include/nil/blueprint/blueprint/r1cs/detail/r1cs/blueprint_variable.hpp @@ -41,153 +41,150 @@ #include namespace nil { - namespace crypto3 { - namespace blueprint { + namespace blueprint { - template - class blueprint; + template + class blueprint; - namespace detail { + namespace detail { - template - class blueprint_variable; - - // template class blueprint_variable; - - template - class blueprint_variable> - : public math::linear_variable { - public: - blueprint_variable(const typename math::linear_variable::index_type index = 0) : - math::linear_variable(index) {}; + template + class blueprint_variable; - template - void allocate(blueprint &bp) { - this->index = bp.allocate_var_index(); - } + // template class blueprint_variable; - static blueprint_variable constant() { - return blueprint_variable(0); - } - }; + template + class blueprint_variable> + : public crypto3::math::linear_variable { + public: + blueprint_variable(const typename crypto3::math::linear_variable::index_type index = + 0) : crypto3::math::linear_variable(index) {}; template - class blueprint_variable_vector; - - template - class blueprint_variable_vector> : - private std::vector>> { - - typedef zk::snark::r1cs_constraint_system ArithmetizationType; - typedef typename BlueprintFieldType::value_type field_value_type; - typedef std::vector> contents; - - public: - using typename contents::const_iterator; - using typename contents::const_reverse_iterator; - using typename contents::iterator; - using typename contents::reverse_iterator; - - using contents::begin; - using contents::emplace_back; - using contents::empty; - using contents::end; - using contents::erase; - using contents::insert; - using contents::rbegin; - using contents::rend; - using contents::reserve; - using contents::size; - using contents::operator[]; - using contents::resize; - - blueprint_variable_vector() : contents() {}; - blueprint_variable_vector(std::size_t count, const blueprint_variable &value) : - contents(count, value) {}; - blueprint_variable_vector(typename contents::const_iterator first, - typename contents::const_iterator last) : - contents(first, last) {}; - blueprint_variable_vector(typename contents::const_reverse_iterator first, - typename contents::const_reverse_iterator last) : - contents(first, last) {}; - - /* allocates blueprint_variable vector in MSB->LSB order */ - void allocate(blueprint &bp, const std::size_t n) { - (*this).resize(n); - - for (std::size_t i = 0; i < n; ++i) { - (*this)[i].allocate(bp); - } - } - - void fill_with_field_elements(blueprint &bp, - const std::vector &vals) const { - assert(this->size() == vals.size()); - for (std::size_t i = 0; i < vals.size(); ++i) { - bp.val((*this)[i]) = vals[i]; - } + void allocate(blueprint &bp) { + this->index = bp.allocate_var_index(); + } + + static blueprint_variable constant() { + return blueprint_variable(0); + } + }; + + template + class blueprint_variable_vector; + + template + class blueprint_variable_vector> + : private std::vector< + blueprint_variable>> { + + typedef crypto3::zk::snark::r1cs_constraint_system ArithmetizationType; + typedef typename BlueprintFieldType::value_type field_value_type; + typedef std::vector> contents; + + public: + using typename contents::const_iterator; + using typename contents::const_reverse_iterator; + using typename contents::iterator; + using typename contents::reverse_iterator; + + using contents::begin; + using contents::emplace_back; + using contents::empty; + using contents::end; + using contents::erase; + using contents::insert; + using contents::rbegin; + using contents::rend; + using contents::reserve; + using contents::size; + using contents::operator[]; + using contents::resize; + + blueprint_variable_vector() : contents() {}; + blueprint_variable_vector(std::size_t count, const blueprint_variable &value) : + contents(count, value) {}; + blueprint_variable_vector(typename contents::const_iterator first, + typename contents::const_iterator last) : contents(first, last) {}; + blueprint_variable_vector(typename contents::const_reverse_iterator first, + typename contents::const_reverse_iterator last) : contents(first, last) {}; + + /* allocates blueprint_variable vector in MSB->LSB order */ + void allocate(blueprint &bp, const std::size_t n) { + (*this).resize(n); + + for (std::size_t i = 0; i < n; ++i) { + (*this)[i].allocate(bp); } + } - template - typename std::enable_if::value_type>::value>::type - fill_with_bits(blueprint &bp, const InputRange &bits) const { - BOOST_RANGE_CONCEPT_ASSERT((boost::RandomAccessRangeConcept)); - assert(this->size() == bits.size()); - for (std::size_t i = 0; i < bits.size(); ++i) { - bp.val((*this)[i]) = (bits[i] ? field_value_type::one() : field_value_type::zero()); - } + void fill_with_field_elements(blueprint &bp, + const std::vector &vals) const { + assert(this->size() == vals.size()); + for (std::size_t i = 0; i < vals.size(); ++i) { + bp.val((*this)[i]) = vals[i]; } - - void fill_with_bits_of_ulong(blueprint &bp, const unsigned long i) const { - this->fill_with_bits_of_field_element(bp, field_value_type(i)); + } + + template + typename std::enable_if< + std::is_same::value_type>::value>::type + fill_with_bits(blueprint &bp, const InputRange &bits) const { + BOOST_RANGE_CONCEPT_ASSERT((boost::RandomAccessRangeConcept)); + assert(this->size() == bits.size()); + for (std::size_t i = 0; i < bits.size(); ++i) { + bp.val((*this)[i]) = (bits[i] ? field_value_type::one() : field_value_type::zero()); } - - void fill_with_bits_of_field_element(blueprint &bp, - const field_value_type &r) const { - for (std::size_t i = 0; i < this->size(); ++i) { - bp.val((*this)[i]) = nil::crypto3::multiprecision::bit_test(r.data, i) ? - field_value_type::one() : - field_value_type::zero(); - } + } + + void fill_with_bits_of_ulong(blueprint &bp, const unsigned long i) const { + this->fill_with_bits_of_field_element(bp, field_value_type(i)); + } + + void fill_with_bits_of_field_element(blueprint &bp, + const field_value_type &r) const { + for (std::size_t i = 0; i < this->size(); ++i) { + bp.val((*this)[i]) = nil::crypto3::multiprecision::bit_test(r.data, i) ? + field_value_type::one() : + field_value_type::zero(); } + } - std::vector values(const blueprint &bp) const { - std::vector result(this->size()); - for (std::size_t i = 0; i < this->size(); ++i) { - result[i] = bp.val((*this)[i]); - } - return result; + std::vector values(const blueprint &bp) const { + std::vector result(this->size()); + for (std::size_t i = 0; i < this->size(); ++i) { + result[i] = bp.val((*this)[i]); } - - std::vector bits(const blueprint &bp) const { - std::vector result; - for (std::size_t i = 0; i < this->size(); ++i) { - const field_value_type v = bp.val((*this)[i]); - assert(v.is_zero() || v.is_one()); - result.push_back(v.is_one()); - } - return result; + return result; + } + + std::vector bits(const blueprint &bp) const { + std::vector result; + for (std::size_t i = 0; i < this->size(); ++i) { + const field_value_type v = bp.val((*this)[i]); + assert(v.is_zero() || v.is_one()); + result.push_back(v.is_one()); } + return result; + } - field_value_type field_element_from_bits(const blueprint &bp) const { - field_value_type result = field_value_type::zero(); - - for (std::size_t i = 0; i < this->size(); ++i) { - /* push in the new bit */ - const field_value_type v = bp.val((*this)[this->size() - 1 - i]); - assert(v.is_zero() || v.is_one()); - result = result + (result + v); - } + field_value_type field_element_from_bits(const blueprint &bp) const { + field_value_type result = field_value_type::zero(); - return result; + for (std::size_t i = 0; i < this->size(); ++i) { + /* push in the new bit */ + const field_value_type v = bp.val((*this)[this->size() - 1 - i]); + assert(v.is_zero() || v.is_one()); + result = result + (result + v); } - }; - } // namespace detail - } // namespace blueprint - } // namespace crypto3 + + return result; + } + }; + } // namespace detail + } // namespace blueprint } // namespace nil #endif // CRYPTO3_BLUEPRINT_COMPONENTS_VARIABLE_HPP diff --git a/include/nil/blueprint/chips/plonk/bit_check.hpp b/include/nil/blueprint/chips/plonk/bit_check.hpp index 27df14f71..fa3c5d10d 100644 --- a/include/nil/blueprint/chips/plonk/bit_check.hpp +++ b/include/nil/blueprint/chips/plonk/bit_check.hpp @@ -34,36 +34,31 @@ #include namespace nil { - namespace crypto3 { - namespace blueprint { - namespace chips { + namespace blueprint { + namespace chips { - template - class bit_check; + template + class bit_check; - template - class bit_check< - snark::plonk_constraint_system>{ + template + class bit_check> { - typedef snark::plonk_constraint_system ArithmetizationType; + typedef crypto3::zk::snark::plonk_constraint_system + ArithmetizationType; - using var = snark::plonk_variable; - public: - constexpr static const std::size_t rows_amount = 0; + using var = crypto3::zk::snark::plonk_variable; - static snark::plonk_constraint generate( - blueprint &bp, - const var& X1) { + public: + constexpr static const std::size_t rows_amount = 0; - return bp.add_constraint(X1 * (X1 - 1)); - } - }; - } // namespace chips - } // namespace blueprint - } // namespace crypto3 + static crypto3::zk::snark::plonk_constraint + generate(blueprint &bp, const var &X1) { + + return bp.add_constraint(X1 * (X1 - 1)); + } + }; + } // namespace chips + } // namespace blueprint } // namespace nil #endif // CRYPTO3_BLUEPRINT_COMPONENTS_PLONK_BIT_CHECK_CHIP_HPP diff --git a/include/nil/blueprint/chips/plonk/incomplete_addition.hpp b/include/nil/blueprint/chips/plonk/incomplete_addition.hpp index cf03b5fe5..b91d09afc 100644 --- a/include/nil/blueprint/chips/plonk/incomplete_addition.hpp +++ b/include/nil/blueprint/chips/plonk/incomplete_addition.hpp @@ -34,41 +34,35 @@ #include namespace nil { - namespace crypto3 { - namespace blueprint { - namespace chips { + namespace blueprint { + namespace chips { - template - class incomplete_addition; + template + class incomplete_addition; - template - class incomplete_addition< - snark::plonk_constraint_system, - CurveType>{ + typename CurveType> + class incomplete_addition< + crypto3::zk::snark::plonk_constraint_system, CurveType> { - typedef snark::plonk_constraint_system ArithmetizationType; + typedef crypto3::zk::snark::plonk_constraint_system + ArithmetizationType; - using var = snark::plonk_variable; - public: - constexpr static const std::size_t rows_amount = 0; + using var = crypto3::zk::snark::plonk_variable; - static snark::plonk_constraint generate( - blueprint &bp, - blueprint_public_assignment_table &public_assignment, - const var& X1, const var& Y1, const var& X2, const var& Y2, - const var& X3, const var& Y3) { + public: + constexpr static const std::size_t rows_amount = 0; - return bp.add_constraint(); - } - }; - } // namespace chips - } // namespace blueprint - } // namespace crypto3 + static snark::plonk_constraint + generate(blueprint &bp, assignment &public_assignment, + const var &X1, const var &Y1, const var &X2, const var &Y2, const var &X3, const var &Y3) { + + return bp.add_constraint(); + } + }; + } // namespace chips + } // namespace blueprint } // namespace nil #endif // CRYPTO3_BLUEPRINT_COMPONENTS_PLONK_INCOMPLETE_ADDITION_CHIP_HPP diff --git a/include/nil/blueprint/component.hpp b/include/nil/blueprint/component.hpp index d9ac76f72..951de3713 100644 --- a/include/nil/blueprint/component.hpp +++ b/include/nil/blueprint/component.hpp @@ -30,6 +30,7 @@ #include #include + #include #include @@ -42,11 +43,10 @@ namespace nil { namespace components { template - class component{}; + class component { }; template - class plonk_component: - public component> { + class plonk_component : public component> { public: using manifest_type = nil::blueprint::plonk_component_manifest; using witness_container_type = std::vector; @@ -96,10 +96,10 @@ namespace nil { * @param[in] constant Container with constant columns global indices. * @param[in] public_input Container with public input columns global indices. */ - template + template plonk_component(WitnessContainerType witness, ConstantContainerType constant, - PublicInputContainerType public_input, const manifest_type &manifest) { + PublicInputContainerType public_input, const manifest_type &manifest) { _W.resize(witness.size()); _C.resize(constant.size()); _PI.resize(public_input.size()); @@ -124,11 +124,9 @@ namespace nil { }; template - class r1cs_component: - public component> { + class r1cs_component : public component> { protected: - typedef crypto3::zk::snark::r1cs_constraint_system - ArithmetizationType; + typedef crypto3::zk::snark::r1cs_constraint_system ArithmetizationType; blueprint &bp; @@ -137,7 +135,7 @@ namespace nil { } }; } // namespace components - } // namespace blueprint + } // namespace blueprint } // namespace nil #endif // CRYPTO3_BLUEPRINT_COMPONENT_HPP diff --git a/include/nil/blueprint/component_stretcher.hpp b/include/nil/blueprint/component_stretcher.hpp index 8f1118249..f7e879256 100644 --- a/include/nil/blueprint/component_stretcher.hpp +++ b/include/nil/blueprint/component_stretcher.hpp @@ -53,10 +53,10 @@ namespace nil { using gate_type = nil::crypto3::zk::snark::plonk_gate; zoning_info() = default; - zoning_info(std::size_t rows_amount_, std::size_t selector_amount_) - : rows_amount(rows_amount_), selector_amount(selector_amount_), - zones(rows_amount_ + selector_amount_ + 1), - constant_priority(rows_amount_, false) {} + zoning_info(std::size_t rows_amount_, std::size_t selector_amount_) : + rows_amount(rows_amount_), selector_amount(selector_amount_), + zones(rows_amount_ + selector_amount_ + 1), constant_priority(rows_amount_, false) { + } std::size_t rows_amount; std::size_t zones_amount; @@ -176,8 +176,8 @@ namespace nil { typedef typename ComponentType::result_type result_type; typedef zoning_info zone_type; using var = typename nil::crypto3::zk::snark::plonk_variable; - using gate_type = typename nil::crypto3::zk::snark::plonk_gate>; + using gate_type = typename nil::crypto3::zk::snark::plonk_gate< + BlueprintFieldType, nil::crypto3::zk::snark::plonk_constraint>; // overloading this because this isn't a proper component (not in the inheritance hierarchy) std::size_t witness_amount() const { @@ -192,35 +192,32 @@ namespace nil { using pow_operation = nil::crypto3::math::pow_operation; using binary_arithmetic_operation = nil::crypto3::math::binary_arithmetic_operation; - gate_mover(const component_stretcher *stretcher_, std::size_t selector_) - : stretcher(stretcher_), selector(selector_) {} + gate_mover(const component_stretcher *stretcher_, std::size_t selector_) : + stretcher(stretcher_), selector(selector_) { + } - expression visit(const expression& expr) { + expression visit(const expression &expr) { return boost::apply_visitor(*this, expr.get_expr()); } - expression operator()(const term_type& term) { + expression operator()(const term_type &term) { std::vector vars; auto coeff = term.get_coeff(); - for (const auto& var: term.get_vars()) { + for (const auto &var : term.get_vars()) { vars.emplace_back(stretcher->move_gate_var(var, selector)); } term_type result(vars, coeff); return result; } - expression operator()(const pow_operation& pow) { - expression base = boost::apply_visitor( - *this, pow.get_expr().get_expr()); + expression operator()(const pow_operation &pow) { + expression base = boost::apply_visitor(*this, pow.get_expr().get_expr()); return pow_operation(base, pow.get_power()); } - expression operator()( - const binary_arithmetic_operation& op) { - expression left = - boost::apply_visitor(*this, op.get_expr_left().get_expr()); - expression right = - boost::apply_visitor(*this, op.get_expr_right().get_expr()); + expression operator()(const binary_arithmetic_operation &op) { + expression left = boost::apply_visitor(*this, op.get_expr_left().get_expr()); + expression right = boost::apply_visitor(*this, op.get_expr_right().get_expr()); switch (op.get_op()) { case nil::crypto3::math::ArithmeticOperator::ADD: return left + right; @@ -232,6 +229,7 @@ namespace nil { __builtin_unreachable(); } } + private: const component_stretcher *stretcher; const std::size_t selector; @@ -252,16 +250,15 @@ namespace nil { mutable bool remapping_computed = false; void compute_remapping( - assignment> &assignment, - std::size_t old_witness_amount, - const input_type &instance_input) const { + assignment> &assignment, + std::size_t old_witness_amount, + const input_type &instance_input) const { circuit> tmp_circuit; - nil::blueprint::assignment> tmp_assignment( - assignment.witnesses_amount(), assignment.public_inputs_amount(), - assignment.constants_amount(), assignment.selectors_amount() - ); - auto converted_input = input_type_converter::convert(instance_input, assignment, - tmp_assignment); + nil::blueprint::assignment> + tmp_assignment(assignment.witnesses_amount(), assignment.public_inputs_amount(), + assignment.constants_amount(), assignment.selectors_amount()); + auto converted_input = + input_type_converter::convert(instance_input, assignment, tmp_assignment); generate_circuit(this->component, tmp_circuit, tmp_assignment, converted_input, 0); generate_assignments(this->component, tmp_assignment, converted_input, 0); zones = generate_zones(tmp_circuit, tmp_assignment, 0, this->component.rows_amount); @@ -312,7 +309,7 @@ namespace nil { } } else { // We rely on default remapping - constant_remapping[curr_var.rotation] = new_rotation; + constant_remapping[curr_var.rotation] = new_rotation; constant_assigned[new_rotation] = true; if (first_unassigned_const == new_rotation) { while (constant_assigned[first_unassigned_const]) { @@ -321,8 +318,10 @@ namespace nil { } } } - this->rows_amount = std::max_element(zones.zone_sizes.begin(), zones.zone_sizes.end(), - [](auto a, auto b) { return a.second < b.second; })->second; + this->rows_amount = + std::max_element(zones.zone_sizes.begin(), zones.zone_sizes.end(), [](auto a, auto b) { + return a.second < b.second; + })->second; this->remapping_computed = true; } @@ -331,24 +330,21 @@ namespace nil { switch (old.type) { case var::column_type::constant: // Assumes a single constant column - new_var = var( - old.index, - new_rotation, - old.relative, - var::column_type::constant); + new_var = var(old.index, new_rotation, old.relative, var::column_type::constant); break; case var::column_type::public_input: // public input is actually the original input variables new_var = input_type_converter::deconvert_var(input, old); break; case var::column_type::witness: - BOOST_ASSERT_MSG( - old.relative == false, - "We should not move relative variables with move_var, use move_gate_var for gate variables. Copy constraints should be absolute."); - new_var = var(zone_mapping[zones.zones.find_set(old.rotation)] * old_witness_amount + old.index, - new_rotation, - old.relative, - var::column_type::witness); + BOOST_ASSERT_MSG(old.relative == false, + "We should not move relative variables with move_var, use move_gate_var " + "for gate variables. Copy constraints should be absolute."); + new_var = + var(zone_mapping[zones.zones.find_set(old.rotation)] * old_witness_amount + old.index, + new_rotation, + old.relative, + var::column_type::witness); break; case var::column_type::selector: BOOST_ASSERT_MSG(false, "Selectors should be moved while moving gates."); @@ -365,19 +361,15 @@ namespace nil { break; case var::column_type::constant: // Assumes only a single constant column - new_var = var( - old.index, - old.rotation, - old.relative, - var::column_type::constant); + new_var = var(old.index, old.rotation, old.relative, var::column_type::constant); break; case var::column_type::witness: - new_var = var( - zone_mapping[zones.zones.find_set(this->component.rows_amount + selector)] * old_witness_amount + - old.index, - old.rotation, - old.relative, - var::column_type::witness); + new_var = var(zone_mapping[zones.zones.find_set(this->component.rows_amount + selector)] * + old_witness_amount + + old.index, + old.rotation, + old.relative, + var::column_type::witness); break; case var::column_type::selector: BOOST_ASSERT_MSG(false, "Selector columns should not be inside gates."); @@ -387,14 +379,10 @@ namespace nil { } void move_circuit( - const circuit> - &tmp_circuit, - assignment> - &tmp_assignment, - circuit> - &bp, - assignment> - &assignment, + const circuit> &tmp_circuit, + assignment> &tmp_assignment, + circuit> &bp, + assignment> &assignment, const input_type &instance_input, std::size_t start_row_index) const { // Need to do multiple things here: @@ -402,7 +390,7 @@ namespace nil { for (auto gate : tmp_circuit.gates()) { std::vector> new_constraints; gate_mover gate_displacer = gate_mover(this, gate.selector_index); - for (auto constraint: gate.constraints) { + for (auto constraint : gate.constraints) { auto new_constraint = gate_displacer.visit(constraint); new_constraints.push_back(new_constraint); } @@ -437,38 +425,30 @@ namespace nil { // 4) Move copy constraints for (auto constraint : tmp_circuit.copy_constraints()) { var new_first, new_second; - for (auto &[new_var, old_var] : - {std::make_pair(std::ref(new_first), constraint.first), - std::make_pair(std::ref(new_second), constraint.second)}) { + for (auto &[new_var, old_var] : {std::make_pair(std::ref(new_first), constraint.first), + std::make_pair(std::ref(new_second), constraint.second)}) { if (old_var.type == var::column_type::constant && constant_remapping.find(old_var.rotation) != constant_remapping.end()) { - new_var = move_var( - old_var, - start_row_index + constant_remapping[old_var.rotation], - instance_input); + new_var = move_var(old_var, start_row_index + constant_remapping[old_var.rotation], + instance_input); } else { - new_var = move_var( - old_var, - start_row_index + line_mapping[old_var.rotation], - instance_input); + new_var = + move_var(old_var, start_row_index + line_mapping[old_var.rotation], instance_input); } } if (constraint.first.type == var::column_type::constant || constraint.second.type == var::column_type::constant) { } - nil::crypto3::zk::snark::plonk_copy_constraint - new_constraint(new_first, new_second); + nil::crypto3::zk::snark::plonk_copy_constraint new_constraint(new_first, + new_second); bp.add_copy_constraint(new_constraint); } } void move_assignment( - const component_stretcher - &component, - const assignment> - &tmp_assignment, - assignment> - &assignment, + const component_stretcher &component, + const assignment> &tmp_assignment, + assignment> &assignment, std::size_t start_row_index) const { for (std::size_t i = 0; i < this->component.rows_amount; i++) { @@ -486,24 +466,20 @@ namespace nil { } component_stretcher(ComponentType &component_, - std::size_t old_witness_amount_, - std::size_t stretched_witness_amount_) - : component(component_), old_witness_amount(old_witness_amount_), - stretched_witness_amount(stretched_witness_amount_), - stretch_coeff(stretched_witness_amount_ / old_witness_amount_) {} + std::size_t old_witness_amount_, + std::size_t stretched_witness_amount_) : + component(component_), old_witness_amount(old_witness_amount_), + stretched_witness_amount(stretched_witness_amount_), + stretch_coeff(stretched_witness_amount_ / old_witness_amount_) { + } }; template typename ComponentType::result_type generate_circuit( - const component_stretcher - &component, - circuit> - &bp, - assignment> - &assignment, - const typename component_stretcher::input_type - &instance_input, + const component_stretcher &component, + circuit> &bp, + assignment> &assignment, + const typename component_stretcher::input_type &instance_input, const std::uint32_t start_row_index) { if (!component.remapping_computed) { @@ -512,46 +488,36 @@ namespace nil { nil::blueprint::assignment> tmp_assignment(assignment.witnesses_amount(), assignment.public_inputs_amount(), assignment.constants_amount(), assignment.selectors_amount()); - circuit> tmp_circuit; + circuit> tmp_circuit; - auto result = generate_circuit( - component.component, tmp_circuit, tmp_assignment, instance_input, 0); - component.move_circuit(tmp_circuit, tmp_assignment, bp, assignment, - instance_input, start_row_index); + auto result = generate_circuit(component.component, tmp_circuit, tmp_assignment, instance_input, 0); + component.move_circuit(tmp_circuit, tmp_assignment, bp, assignment, instance_input, start_row_index); return result_type_converter::convert(component, result, instance_input, start_row_index); } template typename ComponentType::result_type generate_assignments( - const component_stretcher - &component, - assignment> - &assignment, - const typename component_stretcher::input_type - &instance_input, + const component_stretcher &component, + assignment> &assignment, + const typename component_stretcher::input_type &instance_input, const std::uint32_t start_row_index) { if (!component.remapping_computed) { - component.compute_remapping(assignment, component.witness_amount(),instance_input); + component.compute_remapping(assignment, component.witness_amount(), instance_input); } - nil::blueprint::assignment> tmp_assignment( - assignment.witnesses_amount(), assignment.public_inputs_amount(), - assignment.constants_amount(), assignment.selectors_amount()); - circuit> tmp_circuit; + nil::blueprint::assignment> + tmp_assignment(assignment.witnesses_amount(), assignment.public_inputs_amount(), + assignment.constants_amount(), assignment.selectors_amount()); + circuit> tmp_circuit; - auto converted_input = input_type_converter::convert(instance_input, assignment, - tmp_assignment); + auto converted_input = + input_type_converter::convert(instance_input, assignment, tmp_assignment); // We need to generate a circuit here, because the constants are generated in generate_circuit. // The assignment might rely on the generated constants. - generate_circuit( - component.component, tmp_circuit, tmp_assignment, converted_input, 0); - auto result = generate_assignments( - component.component, tmp_assignment, converted_input, 0); + generate_circuit(component.component, tmp_circuit, tmp_assignment, converted_input, 0); + auto result = generate_assignments(component.component, tmp_assignment, converted_input, 0); component.move_assignment(component, tmp_assignment, assignment, start_row_index); return result_type_converter::convert(component, result, instance_input, @@ -559,16 +525,14 @@ namespace nil { } template - struct is_component_stretcher : std::false_type {}; + struct is_component_stretcher : std::false_type { }; template - struct is_component_stretcher< - BlueprintFieldType, - component_stretcher> - : std::true_type {}; + struct is_component_stretcher> + : std::true_type { }; - } // namespace components - } // namespace blueprint -} // namespace nil + } // namespace components + } // namespace blueprint +} // namespace nil -#endif // CRYPTO3_BLUEPRINT_PLONK_COMPONENT_STRETCHER_HPP +#endif // CRYPTO3_BLUEPRINT_PLONK_COMPONENT_STRETCHER_HPP diff --git a/include/nil/blueprint/components/algebra/curves/detail/r1cs/element_g1_affine.hpp b/include/nil/blueprint/components/algebra/curves/detail/r1cs/element_g1_affine.hpp index ffa08007a..6044056fc 100644 --- a/include/nil/blueprint/components/algebra/curves/detail/r1cs/element_g1_affine.hpp +++ b/include/nil/blueprint/components/algebra/curves/detail/r1cs/element_g1_affine.hpp @@ -29,89 +29,86 @@ #ifndef CRYPTO3_BLUEPRINT_COMPONENTS_G1_AFFINE_COMPONENT_HPP #define CRYPTO3_BLUEPRINT_COMPONENTS_G1_AFFINE_COMPONENT_HPP -#include -#include -#include +#include +#include +#include #include #include #include namespace nil { - namespace crypto3 { - namespace blueprint { - namespace components { - template - struct element_g1; - - /** - * @brief Component that represents a G1 element in affine coordinates. - */ - template - struct element_g1 - : public component { - using curve_type = Curve; - using form = Form; - using coordinates = algebra::curves::coordinates::affine; - using group_type = typename curve_type::template g1_type; - using field_type = typename curve_type::base_field_type; - using group_value_type = typename group_type::value_type; - using field_value_type = typename field_type::value_type; - - using underlying_element_type = algebra::fields::detail::element_fp; - - using addition_component = element_g1_addition; - using is_well_formed_component = element_g1_is_well_formed; - using to_twisted_edwards_component = element_g1_to_twisted_edwards; - using to_bits_component = element_g1_to_bits; - - underlying_element_type X; - underlying_element_type Y; - - element_g1(blueprint &bp) : component(bp) { - detail::blueprint_variable X_var, Y_var; - - X_var.allocate(bp); - Y_var.allocate(bp); - - X = X_var; - Y = Y_var; - } - - element_g1(blueprint &bp, const group_value_type &p) : element_g1(bp) { - bp.lc_val(X) = p.X.data; - bp.lc_val(Y) = p.Y.data; - } - - element_g1(blueprint &bp, const underlying_element_type &in_X, - const underlying_element_type &in_Y) : - component(bp), - X(in_X), Y(in_Y) { - } - - // TODO: maybe add is_well_formed constraints - void generate_gates() { - } - - void generate_assignments(const group_value_type &p) { - this->bp.lc_val(X) = p.X.data; - this->bp.lc_val(Y) = p.Y.data; - } - - // (See a comment in r1cs_ppzksnark_verifier_component.hpp about why - // we mark this function noinline.) TODO: remove later - static std::size_t BOOST_NOINLINE size_in_bits() { - return 2 * field_type::modulus_bits; // This probably should be value_bits, not - // modulus_bits - } - - static std::size_t num_variables() { - return 2; - } - }; - } // namespace components - } // namespace blueprint - } // namespace crypto3 + namespace blueprint { + namespace components { + template + struct element_g1; + + /** + * @brief Component that represents a G1 element in affine coordinates. + */ + template + struct element_g1 + : public component { + using curve_type = Curve; + using form = Form; + using coordinates = crypto3::algebra::curves::coordinates::affine; + using group_type = typename curve_type::template g1_type; + using field_type = typename curve_type::base_field_type; + using group_value_type = typename group_type::value_type; + using field_value_type = typename field_type::value_type; + + using underlying_element_type = + crypto3::algebra::fields::detail::element_fp>; + + using addition_component = element_g1_addition; + using is_well_formed_component = element_g1_is_well_formed; + using to_twisted_edwards_component = element_g1_to_twisted_edwards; + using to_bits_component = element_g1_to_bits; + + underlying_element_type X; + underlying_element_type Y; + + element_g1(blueprint &bp) : component(bp) { + detail::blueprint_variable X_var, Y_var; + + X_var.allocate(bp); + Y_var.allocate(bp); + + X = X_var; + Y = Y_var; + } + + element_g1(blueprint &bp, const group_value_type &p) : element_g1(bp) { + bp.lc_val(X) = p.X.data; + bp.lc_val(Y) = p.Y.data; + } + + element_g1(blueprint &bp, const underlying_element_type &in_X, + const underlying_element_type &in_Y) : component(bp), X(in_X), Y(in_Y) { + } + + // TODO: maybe add is_well_formed constraints + void generate_gates() { + } + + void generate_assignments(const group_value_type &p) { + this->bp.lc_val(X) = p.X.data; + this->bp.lc_val(Y) = p.Y.data; + } + + // (See a comment in r1cs_ppzksnark_verifier_component.hpp about why + // we mark this function noinline.) TODO: remove later + static std::size_t BOOST_NOINLINE size_in_bits() { + return 2 * field_type::modulus_bits; // This probably should be value_bits, not + // modulus_bits + } + + static std::size_t num_variables() { + return 2; + } + }; + } // namespace components + } // namespace blueprint } // namespace nil #endif // CRYPTO3_BLUEPRINT_COMPONENTS_G1_AFFINE_COMPONENT_HPP \ No newline at end of file diff --git a/include/nil/blueprint/components/algebra/curves/detail/r1cs/element_ops.hpp b/include/nil/blueprint/components/algebra/curves/detail/r1cs/element_ops.hpp index 1022ae5ec..d18b5d9e0 100644 --- a/include/nil/blueprint/components/algebra/curves/detail/r1cs/element_ops.hpp +++ b/include/nil/blueprint/components/algebra/curves/detail/r1cs/element_ops.hpp @@ -30,26 +30,24 @@ #define CRYPTO3_BLUEPRINT_COMPONENTS_ELEMENT_OPS_COMPONENT_HPP namespace nil { - namespace crypto3 { - namespace blueprint { - namespace components { - template - struct element_g1_is_well_formed { }; + namespace blueprint { + namespace components { + template + struct element_g1_is_well_formed { }; - template - struct element_g1_addition { }; + template + struct element_g1_addition { }; - template - struct element_g1_conditional_addition { }; + template + struct element_g1_conditional_addition { }; - template - struct element_g1_to_twisted_edwards { }; + template + struct element_g1_to_twisted_edwards { }; - template - struct element_g1_to_bits { }; - } // namespace components - } // namespace blueprint - } // namespace crypto3 + template + struct element_g1_to_bits { }; + } // namespace components + } // namespace blueprint } // namespace nil #endif // CRYPTO3_BLUEPRINT_COMPONENTS_ELEMENT_OPS_COMPONENT_HPP diff --git a/include/nil/blueprint/components/algebra/curves/detail/r1cs/fixed_base_mul_zcash.hpp b/include/nil/blueprint/components/algebra/curves/detail/r1cs/fixed_base_mul_zcash.hpp index 9c7d9bd81..a1f87ca52 100644 --- a/include/nil/blueprint/components/algebra/curves/detail/r1cs/fixed_base_mul_zcash.hpp +++ b/include/nil/blueprint/components/algebra/curves/detail/r1cs/fixed_base_mul_zcash.hpp @@ -40,294 +40,287 @@ #include -#include -#include -#include +#include +#include +#include -#include +#include -#include +#include #include #include namespace nil { - namespace crypto3 { - namespace blueprint { - namespace components { - template - struct fixed_base_mul_zcash : public component { - using curve_type = Curve; - using field_type = typename curve_type::base_field_type; - using field_value_type = typename field_type::value_type; - using montgomery_element_component = element_g1; - using twisted_edwards_element_component = - element_g1; - - static_assert(std::is_same::value); - static_assert( - std::is_same::value); - - using lookup_component = lookup_signed_3bit; - using result_type = twisted_edwards_element_component; - - /// See definition of \p c in https://zips.z.cash/protocol/protocol.pdf#concretepedersenhash - static constexpr std::size_t chunks_per_base_point = - nil::crypto3::hashes::detail::chunks_per_base_point( - lookup_component::chunk_bits); - - std::vector montgomery_adders; - std::vector point_converters; - std::vector edward_adders; - std::vector> m_windows_x; - std::vector m_windows_y; - result_type result; - - private: - template + struct fixed_base_mul_zcash : public component { + using curve_type = Curve; + using field_type = typename curve_type::base_field_type; + using field_value_type = typename field_type::value_type; + using montgomery_element_component = element_g1; + using twisted_edwards_element_component = + element_g1; + + static_assert(std::is_same::value); + static_assert(std::is_same::value); + + using lookup_component = lookup_signed_3bit; + using result_type = twisted_edwards_element_component; + + /// See definition of \p c in https://zips.z.cash/protocol/protocol.pdf#concretepedersenhash + static constexpr std::size_t chunks_per_base_point = + crypto3::hashes::detail::chunks_per_base_point( + lookup_component::chunk_bits); + + std::vector montgomery_adders; + std::vector point_converters; + std::vector edward_adders; + std::vector> m_windows_x; + std::vector m_windows_y; + result_type result; + + private: + template< + typename BasePoints, + typename std::enable_if< + std::is_same::value_type>::value, - bool>::type = true> - void init(const BasePoints &base_points, - const detail::blueprint_variable_vector &in_scalar) { - BOOST_RANGE_CONCEPT_ASSERT((boost::RandomAccessRangeConcept)); - assert(!in_scalar.empty()); - assert((in_scalar.size() % lookup_component::chunk_bits) == 0); - assert(basepoints_required(in_scalar.size()) <= base_points.size()); - - const std::size_t window_size_items = 1 << lookup_component::lookup_bits; - const std::size_t n_windows = in_scalar.size() / lookup_component::chunk_bits; - - typename twisted_edwards_element_component::group_value_type start = base_points[0]; - // Precompute values for all lookup window tables - for (std::size_t i = 0; i < n_windows; ++i) { - std::vector lookup_x; - std::vector lookup_y; - - lookup_x.reserve(window_size_items); - lookup_y.reserve(window_size_items); - - if (i % chunks_per_base_point == 0) { - start = base_points[i / chunks_per_base_point]; - } + bool>::type = true> + void init(const BasePoints &base_points, + const detail::blueprint_variable_vector &in_scalar) { + BOOST_RANGE_CONCEPT_ASSERT((boost::RandomAccessRangeConcept)); + assert(!in_scalar.empty()); + assert((in_scalar.size() % lookup_component::chunk_bits) == 0); + assert(basepoints_required(in_scalar.size()) <= base_points.size()); + + const std::size_t window_size_items = 1 << lookup_component::lookup_bits; + const std::size_t n_windows = in_scalar.size() / lookup_component::chunk_bits; + + typename twisted_edwards_element_component::group_value_type start = base_points[0]; + // Precompute values for all lookup window tables + for (std::size_t i = 0; i < n_windows; ++i) { + std::vector lookup_x; + std::vector lookup_y; + + lookup_x.reserve(window_size_items); + lookup_y.reserve(window_size_items); + + if (i % chunks_per_base_point == 0) { + start = base_points[i / chunks_per_base_point]; + } - // For each window, generate 4 points, in little endian: - // (0,0) = 0 = start = base*2^4i - // (1,0) = 1 = 2*start - // (0,1) = 2 = 3*start - // (1,1) = 3 = 4*start - typename twisted_edwards_element_component::group_value_type current = start; - for (std::size_t j = 0; j < window_size_items; ++j) { - if (j != 0) { - current = current + start; - } - const typename montgomery_element_component::group_value_type montgomery = - current.to_montgomery(); - lookup_x.emplace_back(montgomery.X); - lookup_y.emplace_back(montgomery.Y); - - assert(montgomery.to_twisted_edwards() == current); + // For each window, generate 4 points, in little endian: + // (0,0) = 0 = start = base*2^4i + // (1,0) = 1 = 2*start + // (0,1) = 2 = 3*start + // (1,1) = 3 = 4*start + typename twisted_edwards_element_component::group_value_type current = start; + for (std::size_t j = 0; j < window_size_items; ++j) { + if (j != 0) { + current = current + start; } + const typename montgomery_element_component::group_value_type montgomery = + current.to_montgomery(); + lookup_x.emplace_back(montgomery.X); + lookup_y.emplace_back(montgomery.Y); - const auto bits_begin = in_scalar.begin() + (i * lookup_component::chunk_bits); - const detail::blueprint_variable_vector window_bits_x( - bits_begin, bits_begin + lookup_component::lookup_bits); - const detail::blueprint_variable_vector window_bits_y( - bits_begin, bits_begin + lookup_component::chunk_bits); - this->m_windows_y.emplace_back(this->bp, lookup_y, window_bits_y); - - // Pass x lookup as a linear combination to avoid extra constraint. - // x_lc = c[0] + b[0] * (c[1]-c[0]) + b[1] * (c[2]-c[0]) + b[0]&b[1] * (c[3] - c[2] - c[1] + - // c[0]) - detail::blueprint_linear_combination x_lc; - x_lc.assign( - this->bp, - math::linear_term(detail::blueprint_variable(0), lookup_x[0]) + - math::linear_term(window_bits_x[0], (lookup_x[1] - lookup_x[0])) + - math::linear_term(window_bits_x[1], (lookup_x[2] - lookup_x[0])) + - math::linear_term( - this->m_windows_y.back().b0b1, - (lookup_x[3] - lookup_x[2] - lookup_x[1] + lookup_x[0]))); - this->m_windows_x.emplace_back(x_lc); - - // current is at 2^2 * start, for next iteration start needs to be 2^4 - start = current.doubled().doubled(); + assert(montgomery.to_twisted_edwards() == current); } - // Chain adders within one segment together via montgomery adders - for (std::size_t i = 0; i < n_windows; ++i) { - if (i % chunks_per_base_point == 0) { - if (i + 1 < n_windows) { - // 0th lookup will be used in the next iteration to connect - // the first two adders of a new base point. - continue; - } else { - // This is the last point. No need to add it to anything in its - // montgomery form, but we have to make sure it will be part of - // the final edwards addition at the end - this->point_converters.emplace_back( - this->bp, montgomery_element_component(this->bp, this->m_windows_x[i], - this->m_windows_y[i].result)); - } - } else if (i % chunks_per_base_point == 1) { - this->montgomery_adders.emplace_back( - this->bp, - montgomery_element_component(this->bp, this->m_windows_x[i - 1], - this->m_windows_y[i - 1].result), - montgomery_element_component(this->bp, this->m_windows_x[i], - this->m_windows_y[i].result)); + const auto bits_begin = in_scalar.begin() + (i * lookup_component::chunk_bits); + const detail::blueprint_variable_vector window_bits_x( + bits_begin, bits_begin + lookup_component::lookup_bits); + const detail::blueprint_variable_vector window_bits_y( + bits_begin, bits_begin + lookup_component::chunk_bits); + this->m_windows_y.emplace_back(this->bp, lookup_y, window_bits_y); + + // Pass x lookup as a linear combination to avoid extra constraint. + // x_lc = c[0] + b[0] * (c[1]-c[0]) + b[1] * (c[2]-c[0]) + b[0]&b[1] * (c[3] - c[2] - c[1] + + // c[0]) + detail::blueprint_linear_combination x_lc; + x_lc.assign( + this->bp, + crypto3::math::linear_term(detail::blueprint_variable(0), + lookup_x[0]) + + crypto3::math::linear_term(window_bits_x[0], (lookup_x[1] - lookup_x[0])) + + crypto3::math::linear_term(window_bits_x[1], (lookup_x[2] - lookup_x[0])) + + crypto3::math::linear_term( + this->m_windows_y.back().b0b1, + (lookup_x[3] - lookup_x[2] - lookup_x[1] + lookup_x[0]))); + this->m_windows_x.emplace_back(x_lc); + + // current is at 2^2 * start, for next iteration start needs to be 2^4 + start = current.doubled().doubled(); + } + + // Chain adders within one segment together via montgomery adders + for (std::size_t i = 0; i < n_windows; ++i) { + if (i % chunks_per_base_point == 0) { + if (i + 1 < n_windows) { + // 0th lookup will be used in the next iteration to connect + // the first two adders of a new base point. + continue; } else { - this->montgomery_adders.emplace_back( - this->bp, this->montgomery_adders.back().result, - montgomery_element_component(this->bp, this->m_windows_x[i], - this->m_windows_y[i].result)); + // This is the last point. No need to add it to anything in its + // montgomery form, but we have to make sure it will be part of + // the final edwards addition at the end + this->point_converters.emplace_back( + this->bp, montgomery_element_component(this->bp, this->m_windows_x[i], + this->m_windows_y[i].result)); } + } else if (i % chunks_per_base_point == 1) { + this->montgomery_adders.emplace_back( + this->bp, + montgomery_element_component(this->bp, this->m_windows_x[i - 1], + this->m_windows_y[i - 1].result), + montgomery_element_component(this->bp, this->m_windows_x[i], + this->m_windows_y[i].result)); + } else { + this->montgomery_adders.emplace_back( + this->bp, this->montgomery_adders.back().result, + montgomery_element_component(this->bp, this->m_windows_x[i], + this->m_windows_y[i].result)); } + } - // Convert every point at the end of a segment back to edwards format - const std::size_t segment_width = chunks_per_base_point - 1; - - for (std::size_t i = segment_width; i < this->montgomery_adders.size(); i += segment_width) { - this->point_converters.emplace_back(this->bp, this->montgomery_adders[i - 1].result); - } - // The last segment might be incomplete - if (n_windows > 1) { - this->point_converters.emplace_back(this->bp, this->montgomery_adders.back().result); - } + // Convert every point at the end of a segment back to edwards format + const std::size_t segment_width = chunks_per_base_point - 1; - // Chain adders of converted segment tails together - for (std::size_t i = 1; i < this->point_converters.size(); ++i) { - if (i == 1) { - this->edward_adders.emplace_back(this->bp, this->point_converters[i - 1].result, - this->point_converters[i].result); - } else { - this->edward_adders.emplace_back(this->bp, this->edward_adders[i - 2].result, - this->point_converters[i].result); - } - } + for (std::size_t i = segment_width; i < this->montgomery_adders.size(); i += segment_width) { + this->point_converters.emplace_back(this->bp, this->montgomery_adders[i - 1].result); + } + // The last segment might be incomplete + if (n_windows > 1) { + this->point_converters.emplace_back(this->bp, this->montgomery_adders.back().result); } - static detail::blueprint_variable_vector - pad_input(blueprint &bp, - const detail::blueprint_variable_vector &input) { - detail::blueprint_variable_vector padded_input = input; - for (std::size_t i = 0; - // TODO: simplify calculation of the padding length - i < (input.size() % lookup_component::chunk_bits ? - (lookup_component::chunk_bits - input.size() % lookup_component::chunk_bits) : - 0); - ++i) { - detail::blueprint_variable pad_i; - pad_i.allocate(bp); - bp.val(pad_i) = field_value_type::zero(); - padded_input.template emplace_back(pad_i); + // Chain adders of converted segment tails together + for (std::size_t i = 1; i < this->point_converters.size(); ++i) { + if (i == 1) { + this->edward_adders.emplace_back(this->bp, this->point_converters[i - 1].result, + this->point_converters[i].result); + } else { + this->edward_adders.emplace_back(this->bp, this->edward_adders[i - 2].result, + this->point_converters[i].result); } - return padded_input; } - - public: - /// Number of segments - static std::size_t basepoints_required(std::size_t n_bits) { - return std::ceil(n_bits / float(lookup_component::chunk_bits * chunks_per_base_point)); + } + + static detail::blueprint_variable_vector + pad_input(blueprint &bp, const detail::blueprint_variable_vector &input) { + detail::blueprint_variable_vector padded_input = input; + for (std::size_t i = 0; + // TODO: simplify calculation of the padding length + i < (input.size() % lookup_component::chunk_bits ? + (lookup_component::chunk_bits - input.size() % lookup_component::chunk_bits) : + 0); + ++i) { + detail::blueprint_variable pad_i; + pad_i.allocate(bp); + bp.val(pad_i) = field_value_type::zero(); + padded_input.template emplace_back(pad_i); } - - /// Auto allocation of the result - template - fixed_base_mul_zcash(blueprint &bp, - const BasePoints &base_points, - const detail::blueprint_variable_vector &in_scalar, - const bool do_pad_input = true) : - component(bp), - result(bp) { - init(base_points, do_pad_input ? pad_input(bp, in_scalar) : in_scalar); + return padded_input; + } + + public: + /// Number of segments + static std::size_t basepoints_required(std::size_t n_bits) { + return std::ceil(n_bits / float(lookup_component::chunk_bits * chunks_per_base_point)); + } + + /// Auto allocation of the result + template + fixed_base_mul_zcash(blueprint &bp, + const BasePoints &base_points, + const detail::blueprint_variable_vector &in_scalar, + const bool do_pad_input = true) : component(bp), result(bp) { + init(base_points, do_pad_input ? pad_input(bp, in_scalar) : in_scalar); + } + + /// Manual allocation of the result + template + fixed_base_mul_zcash(blueprint &bp, + const BasePoints &base_points, + const detail::blueprint_variable_vector &in_scalar, + const result_type &in_result, + const bool do_pad_input = true) : component(bp), result(in_result) { + init(base_points, do_pad_input ? pad_input(bp, in_scalar) : in_scalar); + } + + void generate_gates() { + for (auto &lut_y : this->m_windows_y) { + lut_y.generate_gates(); } - /// Manual allocation of the result - template - fixed_base_mul_zcash(blueprint &bp, - const BasePoints &base_points, - const detail::blueprint_variable_vector &in_scalar, - const result_type &in_result, - const bool do_pad_input = true) : - component(bp), - result(in_result) { - init(base_points, do_pad_input ? pad_input(bp, in_scalar) : in_scalar); + for (auto &adder : this->montgomery_adders) { + adder.generate_gates(); } - void generate_gates() { - for (auto &lut_y : this->m_windows_y) { - lut_y.generate_gates(); - } - - for (auto &adder : this->montgomery_adders) { - adder.generate_gates(); - } - - for (auto &converter : this->point_converters) { - converter.generate_gates(); - } + for (auto &converter : this->point_converters) { + converter.generate_gates(); + } - for (auto &adder : this->edward_adders) { - adder.generate_gates(); - } + for (auto &adder : this->edward_adders) { + adder.generate_gates(); + } - // formal check - if (!this->edward_adders.empty()) { - this->bp.add_r1cs_constraint(snark::r1cs_constraint( - {detail::blueprint_variable(0)}, {this->result.X}, - {this->edward_adders.back().result.X})); - this->bp.add_r1cs_constraint(snark::r1cs_constraint( - {detail::blueprint_variable(0)}, {this->result.Y}, - {this->edward_adders.back().result.Y})); - } else { - this->bp.add_r1cs_constraint(snark::r1cs_constraint( - {detail::blueprint_variable(0)}, {this->result.X}, - {this->point_converters.back().result.X})); - this->bp.add_r1cs_constraint(snark::r1cs_constraint( - {detail::blueprint_variable(0)}, {this->result.Y}, - {this->point_converters.back().result.Y})); - } + // formal check + if (!this->edward_adders.empty()) { + this->bp.add_r1cs_constraint(crypto3::zk::snark::r1cs_constraint( + {detail::blueprint_variable(0)}, {this->result.X}, + {this->edward_adders.back().result.X})); + this->bp.add_r1cs_constraint(crypto3::zk::snark::r1cs_constraint( + {detail::blueprint_variable(0)}, {this->result.Y}, + {this->edward_adders.back().result.Y})); + } else { + this->bp.add_r1cs_constraint(crypto3::zk::snark::r1cs_constraint( + {detail::blueprint_variable(0)}, {this->result.X}, + {this->point_converters.back().result.X})); + this->bp.add_r1cs_constraint(crypto3::zk::snark::r1cs_constraint( + {detail::blueprint_variable(0)}, {this->result.Y}, + {this->point_converters.back().result.Y})); } + } - void generate_assignments() { - // y lookups have to be solved first, because - // x depends on the `b0 && b1` constraint. - for (auto &lut_y : this->m_windows_y) { - lut_y.generate_assignments(); - } + void generate_assignments() { + // y lookups have to be solved first, because + // x depends on the `b0 && b1` constraint. + for (auto &lut_y : this->m_windows_y) { + lut_y.generate_assignments(); + } - for (auto &lut_x : this->m_windows_x) { - lut_x.evaluate(this->bp); - } + for (auto &lut_x : this->m_windows_x) { + lut_x.evaluate(this->bp); + } - for (auto &adder : this->montgomery_adders) { - adder.generate_assignments(); - } + for (auto &adder : this->montgomery_adders) { + adder.generate_assignments(); + } - for (auto &converter : this->point_converters) { - converter.generate_assignments(); - } + for (auto &converter : this->point_converters) { + converter.generate_assignments(); + } - for (auto &adder : this->edward_adders) { - adder.generate_assignments(); - } + for (auto &adder : this->edward_adders) { + adder.generate_assignments(); + } - if (!this->edward_adders.empty()) { - this->bp.lc_val(this->result.X) = this->bp.lc_val(this->edward_adders.back().result.X); - this->bp.lc_val(this->result.Y) = this->bp.lc_val(this->edward_adders.back().result.Y); - } else { - this->bp.lc_val(this->result.X) = this->bp.lc_val(this->point_converters.back().result.X); - this->bp.lc_val(this->result.Y) = this->bp.lc_val(this->point_converters.back().result.Y); - } + if (!this->edward_adders.empty()) { + this->bp.lc_val(this->result.X) = this->bp.lc_val(this->edward_adders.back().result.X); + this->bp.lc_val(this->result.Y) = this->bp.lc_val(this->edward_adders.back().result.Y); + } else { + this->bp.lc_val(this->result.X) = this->bp.lc_val(this->point_converters.back().result.X); + this->bp.lc_val(this->result.Y) = this->bp.lc_val(this->point_converters.back().result.Y); } - }; - } // namespace components - } // namespace blueprint - } // namespace crypto3 + } + }; + } // namespace components + } // namespace blueprint } // namespace nil #endif // CRYPTO3_BLUEPRINT_COMPONENTS_FIXED_BASE_MUL_ZCASH_COMPONENT_HPP diff --git a/include/nil/blueprint/components/algebra/curves/detail/r1cs/mnt4.hpp b/include/nil/blueprint/components/algebra/curves/detail/r1cs/mnt4.hpp index 108af2d4a..e25878189 100644 --- a/include/nil/blueprint/components/algebra/curves/detail/r1cs/mnt4.hpp +++ b/include/nil/blueprint/components/algebra/curves/detail/r1cs/mnt4.hpp @@ -37,43 +37,41 @@ #include namespace nil { - namespace crypto3 { - namespace blueprint { - namespace components { + namespace blueprint { + namespace components { - using namespace nil::crypto3::algebra; + using namespace nil::crypto3::algebra; - template - class basic_curve_component_policy; + template + class basic_curve_component_policy; - /** - * Specialization for MNT4. - */ - template - class basic_curve_component_policy> { - using curve_type = typename curves::mnt4; + /** + * Specialization for MNT4. + */ + template + class basic_curve_component_policy> { + using curve_type = typename curves::mnt4; - typedef typename curve_type::chained_on_curve_type chained_on_curve_type; // mnt6 + typedef typename curve_type::chained_on_curve_type chained_on_curve_type; // mnt6 - typedef typename chained_on_curve_type::pairing::fqe_type fqe_type; - typedef typename chained_on_curve_type::pairing::fqk_type fqk_type; + typedef typename chained_on_curve_type::pairing::fqe_type fqe_type; + typedef typename chained_on_curve_type::pairing::fqk_type fqk_type; - typedef typename curve_type::pairing::fp_type field_type; + typedef typename curve_type::pairing::fp_type field_type; - public: - typedef element_fp3 Fqe_variable_type; - typedef element_fp3_mul Fqe_mul_component_type; - typedef element_fp3_mul_by_lc Fqe_mul_by_lc_component_type; - typedef element_fp3_squared Fqe_sqr_component_type; + public: + typedef element_fp3 Fqe_variable_type; + typedef element_fp3_mul Fqe_mul_component_type; + typedef element_fp3_mul_by_lc Fqe_mul_by_lc_component_type; + typedef element_fp3_squared Fqe_sqr_component_type; - typedef element_fp6_2over3 Fqk_variable_type; - typedef element_fp6_2over3_mul Fqk_mul_component_type; - typedef element_fp6_2over3_mul_by_2345 Fqk_special_mul_component_type; - typedef element_fp6_2over3_squared Fqk_sqr_component_type; - }; - } // namespace components - } // namespace blueprint - } // namespace crypto3 + typedef element_fp6_2over3 Fqk_variable_type; + typedef element_fp6_2over3_mul Fqk_mul_component_type; + typedef element_fp6_2over3_mul_by_2345 Fqk_special_mul_component_type; + typedef element_fp6_2over3_squared Fqk_sqr_component_type; + }; + } // namespace components + } // namespace blueprint } // namespace nil #endif // CRYPTO3_BLUEPRINT_COMPONENTS_MNT4_BASIC_CURVE_COMPONENT_POLICY_HPP diff --git a/include/nil/blueprint/components/algebra/curves/detail/r1cs/mnt6.hpp b/include/nil/blueprint/components/algebra/curves/detail/r1cs/mnt6.hpp index c7c9a4c6e..857554d13 100644 --- a/include/nil/blueprint/components/algebra/curves/detail/r1cs/mnt6.hpp +++ b/include/nil/blueprint/components/algebra/curves/detail/r1cs/mnt6.hpp @@ -37,43 +37,41 @@ #include namespace nil { - namespace crypto3 { - namespace blueprint { - namespace components { + namespace blueprint { + namespace components { - using namespace nil::crypto3::algebra; + using namespace nil::crypto3::algebra; - template - class basic_curve_component_policy; + template + class basic_curve_component_policy; - /** - * Specialization for MNT6. - */ - template - class basic_curve_component_policy> { - using curve_type = typename curves::mnt6; + /** + * Specialization for MNT6. + */ + template + class basic_curve_component_policy> { + using curve_type = typename curves::mnt6; - typedef typename curve_type::chained_on_curve_type chained_on_curve_type; // mnt4 + typedef typename curve_type::chained_on_curve_type chained_on_curve_type; // mnt4 - typedef typename chained_on_curve_type::pairing::fqe_type fqe_type; - typedef typename chained_on_curve_type::pairing::fqk_type fqk_type; + typedef typename chained_on_curve_type::pairing::fqe_type fqe_type; + typedef typename chained_on_curve_type::pairing::fqk_type fqk_type; - typedef typename curve_type::pairing::fp_type field_type; + typedef typename curve_type::pairing::fp_type field_type; - public: - typedef element_fp2 Fqe_variable_type; - typedef element_fp2_mul Fqe_mul_component_type; - typedef element_fp2_mul_by_lc Fqe_mul_by_lc_component_type; - typedef element_fp2_squared Fqe_sqr_component_type; + public: + typedef element_fp2 Fqe_variable_type; + typedef element_fp2_mul Fqe_mul_component_type; + typedef element_fp2_mul_by_lc Fqe_mul_by_lc_component_type; + typedef element_fp2_squared Fqe_sqr_component_type; - typedef element_fp4 Fqk_variable_type; - typedef element_fp4_mul Fqk_mul_component_type; - typedef element_fp4_mul Fqk_special_mul_component_type; - typedef element_fp4_squared Fqk_sqr_component_type; - }; - } // namespace components - } // namespace blueprint - } // namespace crypto3 + typedef element_fp4 Fqk_variable_type; + typedef element_fp4_mul Fqk_mul_component_type; + typedef element_fp4_mul Fqk_special_mul_component_type; + typedef element_fp4_squared Fqk_sqr_component_type; + }; + } // namespace components + } // namespace blueprint } // namespace nil #endif // CRYPTO3_BLUEPRINT_COMPONENTS_MNT6_BASIC_CURVE_COMPONENT_POLICY_HPP diff --git a/include/nil/blueprint/components/algebra/curves/edwards/r1cs/element_g1.hpp b/include/nil/blueprint/components/algebra/curves/edwards/r1cs/element_g1.hpp index cbc9ea404..a5d10c027 100644 --- a/include/nil/blueprint/components/algebra/curves/edwards/r1cs/element_g1.hpp +++ b/include/nil/blueprint/components/algebra/curves/edwards/r1cs/element_g1.hpp @@ -33,7 +33,7 @@ #define CRYPTO3_BLUEPRINT_COMPONENTS_TWISTED_EDWARDS_G1_COMPONENT_HPP #include -#include +#include #include namespace nil { diff --git a/include/nil/blueprint/components/algebra/curves/montgomery/element_g1.hpp b/include/nil/blueprint/components/algebra/curves/montgomery/element_g1.hpp index 314e2854c..ebdc2e0cf 100644 --- a/include/nil/blueprint/components/algebra/curves/montgomery/element_g1.hpp +++ b/include/nil/blueprint/components/algebra/curves/montgomery/element_g1.hpp @@ -32,159 +32,155 @@ #ifndef CRYPTO3_BLUEPRINT_COMPONENTS_MONTGOMERY_G1_COMPONENT_HPP #define CRYPTO3_BLUEPRINT_COMPONENTS_MONTGOMERY_G1_COMPONENT_HPP -#include +#include namespace nil { - namespace crypto3 { - namespace blueprint { - namespace components { - /** - * @brief Component that creates constraints for the addition of two elements from G1. (if element from - * group G1 lies on the elliptic curve) - */ - template - struct element_g1_addition - : public component::field_type> { - using curve_type = Curve; - using form = algebra::curves::forms::montgomery; - using coordinates = algebra::curves::coordinates::affine; - - using element_component = element_g1; - - using field_type = typename element_component::field_type; - using group_type = typename element_component::group_type; - - using result_type = element_component; - - const element_component p1; - const element_component p2; - element_component result; - element_fp lambda; - - /// Auto allocation of the result - element_g1_addition(blueprint &bp, - const element_component &in_p1, - const element_component &in_p2) : - component(bp), - p1(in_p1), p2(in_p2), result(bp) { - detail::blueprint_variable lambda_var; - lambda_var.allocate(this->bp); - this->lambda = lambda_var; - } - - /// Manual allocation of the result - element_g1_addition(blueprint &bp, - const element_component &in_p1, - const element_component &in_p2, - const result_type &in_result) : - component(bp), - p1(in_p1), p2(in_p2), result(in_result) { - detail::blueprint_variable lambda_var; - lambda_var.allocate(this->bp); - this->lambda = lambda_var; - } - - void generate_gates() { - // lambda = (y' - y) / (x' - x) - this->bp.add_r1cs_constraint(snark::r1cs_constraint( - {this->p2.X - this->p1.X}, {this->lambda}, {this->p2.Y - this->p1.Y})); - // (lambda) * (lambda) = (A + x + x' + x'') - this->bp.add_r1cs_constraint(snark::r1cs_constraint( - {this->lambda}, - {this->lambda}, - {group_type::params_type::A + this->p1.X + this->p2.X + this->result.X})); - // y'' = -(y + lambda(x'' - x)) - this->bp.add_r1cs_constraint(snark::r1cs_constraint( - {this->p1.X - this->result.X}, this->lambda, {this->result.Y + this->p1.Y})); - } - - void generate_assignments() { - this->bp.lc_val(this->lambda) = - (this->bp.lc_val(this->p2.Y) - this->bp.lc_val(this->p1.Y)) * - (this->bp.lc_val(this->p2.X) - this->bp.lc_val(this->p1.X)).inversed(); - this->bp.lc_val(this->result.X) = this->bp.lc_val(this->lambda).squared() - - group_type::params_type::A - this->bp.lc_val(this->p1.X) - - this->bp.lc_val(this->p2.X); - this->bp.lc_val(this->result.Y) = - -(this->bp.lc_val(this->p1.Y) + - (this->bp.lc_val(this->lambda) * - (this->bp.lc_val(this->result.X) - this->bp.lc_val(this->p1.X)))); - } - }; - - /** - * Gadget to convert affine Montgomery coordinates into affine twisted Edwards coordinates. - */ - template - struct element_g1_to_twisted_edwards - : public component::field_type> { - using curve_type = Curve; - using form = algebra::curves::forms::montgomery; - using coordinates = algebra::curves::coordinates::affine; - - using element_component = element_g1; - using to_element_component = - element_g1; - - using field_type = typename element_component::field_type; - using group_type = typename element_component::group_type; - using to_group_type = typename to_element_component::group_type; - - using result_type = to_element_component; - - // Input point - const element_component p; - // Output point - result_type result; - // Intermediate variables - typename field_type::value_type scale; - - /// Auto allocation of the result - element_g1_to_twisted_edwards(blueprint &bp, const element_component &in_p) : - component(bp), p(in_p), result(bp), - scale((static_cast(4) / - (static_cast(to_group_type::params_type::a) - - static_cast(to_group_type::params_type::d)) / - static_cast(group_type::params_type::B)) - .sqrt()) { - } - - /// Manual allocation of the result - element_g1_to_twisted_edwards(blueprint &bp, const element_component &in_p, - const result_type &in_result) : - component(bp), - p(in_p), result(in_result), - scale((static_cast(4) / - (static_cast(to_group_type::params_type::a) - - static_cast(to_group_type::params_type::d)) / - static_cast(group_type::params_type::B)) - .sqrt()) { - } - - void generate_gates() { - this->bp.add_r1cs_constraint(snark::r1cs_constraint({this->p.Y}, {this->result.X}, - {this->p.X * this->scale})); - this->bp.add_r1cs_constraint( - snark::r1cs_constraint({this->p.X + field_type::value_type::one()}, - {this->result.Y}, - {this->p.X - field_type::value_type::one()})); - } - - void generate_assignments() { - typename to_group_type::value_type p_to_XY = - typename group_type::value_type(this->bp.lc_val(p.X), this->bp.lc_val(p.Y)) - .to_twisted_edwards(); - this->bp.lc_val(result.X) = p_to_XY.X; - this->bp.lc_val(result.Y) = p_to_XY.Y; - } - }; - } // namespace components - } // namespace blueprint - } // namespace crypto3 + namespace blueprint { + namespace components { + /** + * @brief Component that creates constraints for the addition of two elements from G1. (if element from + * group G1 lies on the elliptic curve) + */ + template + struct element_g1_addition + : public component::field_type> { + using curve_type = Curve; + using form = crypto3::algebra::curves::forms::montgomery; + using coordinates = crypto3::algebra::curves::coordinates::affine; + + using element_component = element_g1; + + using field_type = typename element_component::field_type; + using group_type = typename element_component::group_type; + + using result_type = element_component; + + const element_component p1; + const element_component p2; + element_component result; + element_fp lambda; + + /// Auto allocation of the result + element_g1_addition(blueprint &bp, + const element_component &in_p1, + const element_component &in_p2) : + component(bp), p1(in_p1), p2(in_p2), result(bp) { + detail::blueprint_variable lambda_var; + lambda_var.allocate(this->bp); + this->lambda = lambda_var; + } + + /// Manual allocation of the result + element_g1_addition(blueprint &bp, + const element_component &in_p1, + const element_component &in_p2, + const result_type &in_result) : + component(bp), p1(in_p1), p2(in_p2), result(in_result) { + detail::blueprint_variable lambda_var; + lambda_var.allocate(this->bp); + this->lambda = lambda_var; + } + + void generate_gates() { + // lambda = (y' - y) / (x' - x) + this->bp.add_r1cs_constraint(crypto3::zk::snark::r1cs_constraint( + {this->p2.X - this->p1.X}, {this->lambda}, {this->p2.Y - this->p1.Y})); + // (lambda) * (lambda) = (A + x + x' + x'') + this->bp.add_r1cs_constraint(crypto3::zk::snark::r1cs_constraint( + {this->lambda}, + {this->lambda}, + {group_type::params_type::A + this->p1.X + this->p2.X + this->result.X})); + // y'' = -(y + lambda(x'' - x)) + this->bp.add_r1cs_constraint(crypto3::zk::snark::r1cs_constraint( + {this->p1.X - this->result.X}, this->lambda, {this->result.Y + this->p1.Y})); + } + + void generate_assignments() { + this->bp.lc_val(this->lambda) = + (this->bp.lc_val(this->p2.Y) - this->bp.lc_val(this->p1.Y)) * + (this->bp.lc_val(this->p2.X) - this->bp.lc_val(this->p1.X)).inversed(); + this->bp.lc_val(this->result.X) = this->bp.lc_val(this->lambda).squared() - + group_type::params_type::A - this->bp.lc_val(this->p1.X) - + this->bp.lc_val(this->p2.X); + this->bp.lc_val(this->result.Y) = + -(this->bp.lc_val(this->p1.Y) + + (this->bp.lc_val(this->lambda) * + (this->bp.lc_val(this->result.X) - this->bp.lc_val(this->p1.X)))); + } + }; + + /** + * Gadget to convert affine Montgomery coordinates into affine twisted Edwards coordinates. + */ + template + struct element_g1_to_twisted_edwards + : public component::field_type> { + using curve_type = Curve; + using form = crypto3::algebra::curves::forms::montgomery; + using coordinates = crypto3::algebra::curves::coordinates::affine; + + using element_component = element_g1; + using to_element_component = + element_g1; + + using field_type = typename element_component::field_type; + using group_type = typename element_component::group_type; + using to_group_type = typename to_element_component::group_type; + + using result_type = to_element_component; + + // Input point + const element_component p; + // Output point + result_type result; + // Intermediate variables + typename field_type::value_type scale; + + /// Auto allocation of the result + element_g1_to_twisted_edwards(blueprint &bp, const element_component &in_p) : + component(bp), p(in_p), result(bp), + scale((static_cast(4) / + (static_cast(to_group_type::params_type::a) - + static_cast(to_group_type::params_type::d)) / + static_cast(group_type::params_type::B)) + .sqrt()) { + } + + /// Manual allocation of the result + element_g1_to_twisted_edwards(blueprint &bp, const element_component &in_p, + const result_type &in_result) : + component(bp), p(in_p), result(in_result), + scale((static_cast(4) / + (static_cast(to_group_type::params_type::a) - + static_cast(to_group_type::params_type::d)) / + static_cast(group_type::params_type::B)) + .sqrt()) { + } + + void generate_gates() { + this->bp.add_r1cs_constraint(crypto3::zk::snark::r1cs_constraint( + {this->p.Y}, {this->result.X}, {this->p.X * this->scale})); + this->bp.add_r1cs_constraint( + crypto3::zk::snark::r1cs_constraint({this->p.X + field_type::value_type::one()}, + + {this->result.Y}, + {this->p.X - field_type::value_type::one()})); + } + + void generate_assignments() { + typename to_group_type::value_type p_to_XY = + typename group_type::value_type(this->bp.lc_val(p.X), this->bp.lc_val(p.Y)) + .to_twisted_edwards(); + this->bp.lc_val(result.X) = p_to_XY.X; + this->bp.lc_val(result.Y) = p_to_XY.Y; + } + }; + } // namespace components + } // namespace blueprint } // namespace nil #endif // CRYPTO3_BLUEPRINT_COMPONENTS_MONTGOMERY_G1_COMPONENT_HPP diff --git a/include/nil/blueprint/components/algebra/curves/pasta/plonk/endo_scalar.hpp b/include/nil/blueprint/components/algebra/curves/pasta/plonk/endo_scalar.hpp index 9fe33d84f..c6051db22 100644 --- a/include/nil/blueprint/components/algebra/curves/pasta/plonk/endo_scalar.hpp +++ b/include/nil/blueprint/components/algebra/curves/pasta/plonk/endo_scalar.hpp @@ -45,329 +45,318 @@ #include namespace nil { - namespace blueprint { - namespace components { - - template - class endo_scalar; - // Input: x - // Output: y - // Such as: - // mul(x, G) = endomul(y, G), for G \in E(F) - - template - struct endo_scalar_params; - - template<> - struct endo_scalar_params { - using curve_type = nil::crypto3::algebra::curves::vesta; - using scalar_field_type = typename curve_type::scalar_field_type; - using base_field_type = typename curve_type::base_field_type; - constexpr static const typename scalar_field_type::value_type endo_r = - 0x12CCCA834ACDBA712CAAD5DC57AAB1B01D1F8BD237AD31491DAD5EBDFDFE4AB9_cppui255; - constexpr static const typename base_field_type::value_type endo_q = - 0x2D33357CB532458ED3552A23A8554E5005270D29D19FC7D27B7FD22F0201B547_cppui255; + namespace blueprint { + namespace components { + + template + class endo_scalar; + // Input: x + // Output: y + // Such as: + // mul(x, G) = endomul(y, G), for G \in E(F) + + template + struct endo_scalar_params; + + template<> + struct endo_scalar_params { + using curve_type = nil::crypto3::algebra::curves::vesta; + using scalar_field_type = typename curve_type::scalar_field_type; + using base_field_type = typename curve_type::base_field_type; + constexpr static const typename scalar_field_type::value_type endo_r = + 0x12CCCA834ACDBA712CAAD5DC57AAB1B01D1F8BD237AD31491DAD5EBDFDFE4AB9_cppui255; + constexpr static const typename base_field_type::value_type endo_q = + 0x2D33357CB532458ED3552A23A8554E5005270D29D19FC7D27B7FD22F0201B547_cppui255; + }; + + template<> + struct endo_scalar_params { + using curve_type = nil::crypto3::algebra::curves::pallas; + using scalar_field_type = typename curve_type::scalar_field_type; + using base_field_type = typename curve_type::base_field_type; + constexpr static const typename scalar_field_type::value_type endo_r = + 0x397E65A7D7C1AD71AEE24B27E308F0A61259527EC1D4752E619D1840AF55F1B1_cppui255; + constexpr static const typename base_field_type::value_type endo_q = + 0x2D33357CB532458ED3552A23A8554E5005270D29D19FC7D27B7FD22F0201B547_cppui255; + }; + + template + class endo_scalar, CurveType> + : public plonk_component { + + using endo_params = endo_scalar_params; + + public: + using component_type = plonk_component; + + using var = typename component_type::var; + using manifest_type = nil::blueprint::plonk_component_manifest; + + class gate_manifest_type : public component_gate_manifest { + public: + std::uint32_t gates_amount() const override { + return endo_scalar::gates_amount; + } }; - template<> - struct endo_scalar_params { - using curve_type = nil::crypto3::algebra::curves::pallas; - using scalar_field_type = typename curve_type::scalar_field_type; - using base_field_type = typename curve_type::base_field_type; - constexpr static const typename scalar_field_type::value_type endo_r = - 0x397E65A7D7C1AD71AEE24B27E308F0A61259527EC1D4752E619D1840AF55F1B1_cppui255; - constexpr static const typename base_field_type::value_type endo_q = - 0x2D33357CB532458ED3552A23A8554E5005270D29D19FC7D27B7FD22F0201B547_cppui255; - }; + static gate_manifest get_gate_manifest(std::size_t witness_amount, std::size_t lookup_column_amount) { + static gate_manifest manifest = gate_manifest(gate_manifest_type()); + return manifest; + } - template - class endo_scalar, CurveType>: - public plonk_component { + static manifest_type get_manifest() { + static manifest_type manifest = + manifest_type(std::shared_ptr(new manifest_single_value_param(15)), false); + return manifest; + } - using endo_params = endo_scalar_params; + constexpr static std::size_t get_rows_amount(std::size_t witness_amount, + std::size_t lookup_column_amount) { + return 8; + } - public: - using component_type = plonk_component; + const std::size_t scalar_size; - using var = typename component_type::var; - using manifest_type = nil::blueprint::plonk_component_manifest; + const std::size_t rows_amount = get_rows_amount(this->witness_amount(), 0); + static constexpr std::size_t gates_amount = 2; - class gate_manifest_type : public component_gate_manifest { - public: - std::uint32_t gates_amount() const override { - return endo_scalar::gates_amount; - } - }; + constexpr static const typename BlueprintFieldType::value_type endo_r = endo_params::endo_r; + constexpr static const typename CurveType::base_field_type::value_type endo_q = endo_params::endo_q; - static gate_manifest get_gate_manifest(std::size_t witness_amount, - std::size_t lookup_column_amount) { - static gate_manifest manifest = gate_manifest(gate_manifest_type()); - return manifest; - } + struct input_type { + var scalar; - static manifest_type get_manifest() { - static manifest_type manifest = manifest_type( - std::shared_ptr(new manifest_single_value_param(15)), - false - ); - return manifest; + std::vector> all_vars() { + return {scalar}; } + }; - constexpr static std::size_t get_rows_amount(std::size_t witness_amount, - std::size_t lookup_column_amount) { - return 8; + struct result_type { + var output = var(0, 0, false); + result_type(const endo_scalar &component, const input_type ¶ms, std::size_t start_row_index) { + output = var(component.W(6), start_row_index + component.rows_amount - 1, false, + var::column_type::witness); } - const std::size_t scalar_size; - - const std::size_t rows_amount = get_rows_amount(this->witness_amount(), 0); - static constexpr std::size_t gates_amount = 2; - - constexpr static const typename BlueprintFieldType::value_type endo_r = endo_params::endo_r; - constexpr static const typename CurveType::base_field_type::value_type endo_q = endo_params::endo_q; - - struct input_type { - var scalar; - - std::vector> all_vars() { - return {scalar}; - } - }; - - struct result_type { - var output = var(0, 0, false); - result_type(const endo_scalar &component, const input_type ¶ms, std::size_t start_row_index) { - output = var(component.W(6), start_row_index + component.rows_amount - 1, - false, var::column_type::witness); - } - - std::vector> all_vars() { - return {output}; - } - }; - - template - endo_scalar(ContainerType witness, std::size_t scalar_size_): - component_type(witness, {}, {}, get_manifest()), - scalar_size(scalar_size_) {}; - - template - endo_scalar(WitnessContainerType witness, ConstantContainerType constant, PublicInputContainerType public_input, std::size_t scalar_size_): - component_type(witness, constant, public_input, get_manifest()), - scalar_size(scalar_size_) {}; - - endo_scalar( - std::initializer_list witnesses, - std::initializer_list constants, - std::initializer_list - public_inputs, - std::size_t scalar_size_): - component_type(witnesses, constants, public_inputs, get_manifest()), - scalar_size(scalar_size_) {}; - + std::vector> all_vars() { + return {output}; + } }; - template - using plonk_endo_scalar = - endo_scalar< - crypto3::zk::snark::plonk_constraint_system, - CurveType - >; - - template - typename plonk_endo_scalar::result_type - generate_circuit( - const plonk_endo_scalar &component, - circuit> &bp, - assignment> &assignment, - const typename plonk_endo_scalar::input_type instance_input, - const std::uint32_t start_row_index) { - - std::array selector_indices = - generate_gates(component, bp, assignment, instance_input); - - std::size_t j = start_row_index; - assignment.enable_selector(selector_indices[0], j, j + component.rows_amount - 1); - assignment.enable_selector(selector_indices[1], j + component.rows_amount - 1); - - generate_copy_constraints(component, bp, assignment, instance_input, start_row_index); - - return typename plonk_endo_scalar::result_type(component, instance_input, start_row_index); + template + endo_scalar(ContainerType witness, std::size_t scalar_size_) : + component_type(witness, {}, {}, get_manifest()), scalar_size(scalar_size_) {}; + + template + endo_scalar(WitnessContainerType witness, ConstantContainerType constant, + PublicInputContainerType public_input, std::size_t scalar_size_) : + component_type(witness, constant, public_input, get_manifest()), scalar_size(scalar_size_) {}; + + endo_scalar(std::initializer_list + witnesses, + std::initializer_list + constants, + std::initializer_list + public_inputs, + std::size_t scalar_size_) : + component_type(witnesses, constants, public_inputs, get_manifest()), scalar_size(scalar_size_) {}; + }; + + template + using plonk_endo_scalar = + endo_scalar, CurveType>; + + template + typename plonk_endo_scalar::result_type generate_circuit( + const plonk_endo_scalar &component, + circuit> &bp, + assignment> &assignment, + const typename plonk_endo_scalar::input_type instance_input, + const std::uint32_t start_row_index) { + + std::array selector_indices = generate_gates(component, bp, assignment, instance_input); + + std::size_t j = start_row_index; + assignment.enable_selector(selector_indices[0], j, j + component.rows_amount - 1); + assignment.enable_selector(selector_indices[1], j + component.rows_amount - 1); + + generate_copy_constraints(component, bp, assignment, instance_input, start_row_index); + + return typename plonk_endo_scalar::result_type(component, instance_input, + start_row_index); + } + + template + typename plonk_endo_scalar::result_type generate_assignments( + const plonk_endo_scalar &component, + assignment> &assignment, + const typename plonk_endo_scalar::input_type instance_input, + const std::uint32_t start_row_index) { + + std::size_t row = start_row_index; + + const std::size_t crumbs_per_row = 8; + const std::size_t bits_per_crumb = 2; + const std::size_t bits_per_row = + bits_per_crumb * crumbs_per_row; // we suppose that scalar_size % bits_per_row = 0 + + typename BlueprintFieldType::value_type scalar = var_value(assignment, instance_input.scalar); + typename BlueprintFieldType::integral_type integral_scalar = + typename BlueprintFieldType::integral_type(scalar.data); + std::vector bits_msb(component.scalar_size); + { + nil::marshalling::status_type status; + assert(component.scalar_size <= BlueprintFieldType::modulus_bits); + + std::array bits_msb_all = + nil::marshalling::pack(integral_scalar, status); + + assert(status == nil::marshalling::status_type::success); + + std::copy(bits_msb_all.end() - component.scalar_size, bits_msb_all.end(), bits_msb.begin()); + + for (std::size_t i = 0; i < BlueprintFieldType::modulus_bits - component.scalar_size; ++i) { + assert(bits_msb_all[i] == false); } - - template - typename plonk_endo_scalar::result_type - generate_assignments( - const plonk_endo_scalar &component, - assignment> &assignment, - const typename plonk_endo_scalar::input_type instance_input, - const std::uint32_t start_row_index) { - - std::size_t row = start_row_index; - - const std::size_t crumbs_per_row = 8; - const std::size_t bits_per_crumb = 2; - const std::size_t bits_per_row = - bits_per_crumb * crumbs_per_row; // we suppose that scalar_size % bits_per_row = 0 - - typename BlueprintFieldType::value_type scalar = var_value(assignment, instance_input.scalar); - typename BlueprintFieldType::integral_type integral_scalar = - typename BlueprintFieldType::integral_type(scalar.data); - std::vector bits_msb(component.scalar_size); - { - nil::marshalling::status_type status; - assert(component.scalar_size <= BlueprintFieldType::modulus_bits); - - std::array bits_msb_all = - nil::marshalling::pack(integral_scalar, status); - - assert(status == nil::marshalling::status_type::success); - - std::copy(bits_msb_all.end() - component.scalar_size, bits_msb_all.end(), bits_msb.begin()); - - for(std::size_t i = 0; i < BlueprintFieldType::modulus_bits - component.scalar_size; ++i) { - assert(bits_msb_all[i] == false); - } - } - typename BlueprintFieldType::value_type a = 2; - typename BlueprintFieldType::value_type b = 2; - typename BlueprintFieldType::value_type n = 0; - - assert (component.scalar_size % bits_per_row == 0); - for (std::size_t chunk_start = 0; chunk_start < bits_msb.size(); chunk_start += bits_per_row) { - assignment.witness(component.W(0), row) = n; - assignment.witness(component.W(2), row) = a; - assignment.witness(component.W(3), row) = b; - - for (std::size_t j = 0; j < crumbs_per_row; j++) { - std::size_t crumb = chunk_start + j * bits_per_crumb; - typename BlueprintFieldType::value_type b0 = static_cast(bits_msb[crumb + 1]); - typename BlueprintFieldType::value_type b1 = static_cast(bits_msb[crumb + 0]); - - typename BlueprintFieldType::value_type crumb_value = b0 + b1.doubled(); - assignment.witness(component.W(7 + j), row) = crumb_value; - - a = a.doubled(); - b = b.doubled(); - - typename BlueprintFieldType::value_type s = - (b0 == BlueprintFieldType::value_type::one()) ? 1 : -1; - - if (b1 == BlueprintFieldType::value_type::zero()) { - b += s; - } else { - a += s; - } - - n = (n.doubled()).doubled(); - n += crumb_value; - } - - assignment.witness(component.W(1), row) = n; - assignment.witness(component.W(4), row) = a; - assignment.witness(component.W(5), row) = b; - row++; + } + typename BlueprintFieldType::value_type a = 2; + typename BlueprintFieldType::value_type b = 2; + typename BlueprintFieldType::value_type n = 0; + + assert(component.scalar_size % bits_per_row == 0); + for (std::size_t chunk_start = 0; chunk_start < bits_msb.size(); chunk_start += bits_per_row) { + assignment.witness(component.W(0), row) = n; + assignment.witness(component.W(2), row) = a; + assignment.witness(component.W(3), row) = b; + + for (std::size_t j = 0; j < crumbs_per_row; j++) { + std::size_t crumb = chunk_start + j * bits_per_crumb; + typename BlueprintFieldType::value_type b0 = static_cast(bits_msb[crumb + 1]); + typename BlueprintFieldType::value_type b1 = static_cast(bits_msb[crumb + 0]); + + typename BlueprintFieldType::value_type crumb_value = b0 + b1.doubled(); + assignment.witness(component.W(7 + j), row) = crumb_value; + + a = a.doubled(); + b = b.doubled(); + + typename BlueprintFieldType::value_type s = + (b0 == BlueprintFieldType::value_type::one()) ? 1 : -1; + + if (b1 == BlueprintFieldType::value_type::zero()) { + b += s; + } else { + a += s; } - auto res = a * component.endo_r + b; - assignment.witness(component.W(6), row - 1) = res; - return typename plonk_endo_scalar::result_type(component, instance_input, start_row_index); - } - template - std::array generate_gates( - const plonk_endo_scalar &component, - circuit> &bp, - assignment> &assignment, - const typename plonk_endo_scalar::input_type instance_input) { - - using F = typename BlueprintFieldType::value_type; - using var = - typename plonk_endo_scalar::var; - - auto c_f = [](var x) { - return (F(11) * F(6).inversed()) * x + (-F(5) * F(2).inversed()) * x * x + - (F(2) * F(3).inversed()) * x * x * x; - }; - - auto d_f = [](var x) { - return -F::one() + (F(29) * F(6).inversed()) * x + (-F(7) * F(2).inversed()) * x * x + - (F(2) * F(3).inversed()) * x * x * x; - }; - - auto constraint_1 = - var(component.W(7), 0) * (var(component.W(7), 0) - 1) * - (var(component.W(7), 0) - 2) * (var(component.W(7), 0) - 3); - auto constraint_2 = - var(component.W(8), 0) * - (var(component.W(8), 0) - 1) * (var(component.W(8), 0) - 2) * (var(component.W(8), 0) - 3); - auto constraint_3 = - var(component.W(9), 0) * (var(component.W(9), 0) - 1) * - (var(component.W(9), 0) - 2) * (var(component.W(9), 0) - 3); - auto constraint_4 = - var(component.W(10), 0) * (var(component.W(10), 0) - 1) * - (var(component.W(10), 0) - 2) * (var(component.W(10), 0) - 3); - auto constraint_5 = - var(component.W(11), 0) * (var(component.W(11), 0) - 1) * - (var(component.W(11), 0) - 2) * (var(component.W(11), 0) - 3); - auto constraint_6 = - var(component.W(12), 0) * (var(component.W(12), 0) - 1) * - (var(component.W(12), 0) - 2) * (var(component.W(12), 0) - 3); - auto constraint_7 = - var(component.W(13), 0) * (var(component.W(13), 0) - 1) * - (var(component.W(13), 0) - 2) * (var(component.W(13), 0) - 3); - auto constraint_8 = - var(component.W(14), 0) * (var(component.W(14), 0) - 1) * - (var(component.W(14), 0) - 2) * (var(component.W(14), 0) - 3); - auto constraint_9 = - var(component.W(4), 0) - (256 * var(component.W(2), 0) + 128 * c_f(var(component.W(7), 0)) + 64 * c_f(var(component.W(8), 0)) + - 32 * c_f(var(component.W(9), 0)) + 16 * c_f(var(component.W(10), 0)) + 8 * c_f(var(component.W(11), 0)) + - 4 * c_f(var(component.W(12), 0)) + 2 * c_f(var(component.W(13), 0)) + c_f(var(component.W(14), 0))); - auto constraint_10 = - var(component.W(5), 0) - (256 * var(component.W(3), 0) + 128 * d_f(var(component.W(7), 0)) + 64 * d_f(var(component.W(8), 0)) + - 32 * d_f(var(component.W(9), 0)) + 16 * d_f(var(component.W(10), 0)) + 8 * d_f(var(component.W(11), 0)) + - 4 * d_f(var(component.W(12), 0)) + 2 * d_f(var(component.W(13), 0)) + d_f(var(component.W(14), 0))); - auto constraint_11 = - var(component.W(1), 0) - ((1 << 16) * var(component.W(0), 0) + (1 << 14) * var(component.W(7), 0) + (1 << 12) * var(component.W(8), 0) + - (1 << 10) * var(component.W(9), 0) + (1 << 8) * var(component.W(10), 0) + (1 << 6) * var(component.W(11), 0) + - (1 << 4) * var(component.W(12), 0) + (1 << 2) * var(component.W(13), 0) + var(component.W(14), 0)); - - auto constraint_12 = var(component.W(6), 0) - - (component.endo_r * var(component.W(4), 0) + var(component.W(5), 0)); - - std::size_t selector_index_1 = bp.add_gate( - {constraint_1, constraint_2, constraint_3, constraint_4, constraint_5, constraint_6, - constraint_7, constraint_8, constraint_9, constraint_10, constraint_11}); - - std::size_t selector_index_2 = bp.add_gate({constraint_12}); - - return {selector_index_1, selector_index_2}; + n = (n.doubled()).doubled(); + n += crumb_value; } - template - void generate_copy_constraints( - const plonk_endo_scalar &component, - circuit> &bp, - assignment> &assignment, - const typename plonk_endo_scalar::input_type instance_input, - const std::uint32_t start_row_index) { - - std::size_t j = start_row_index; - - for (std::size_t z = 1; z < component.rows_amount; z++) { - bp.add_copy_constraint( - {{component.W(0), static_cast(j + z), false}, {component.W(1), static_cast(j + z - 1), false}}); - bp.add_copy_constraint( - {{component.W(2), static_cast(j + z), false}, {component.W(4), static_cast(j + z - 1), false}}); - bp.add_copy_constraint( - {{component.W(3), static_cast(j + z), false}, {component.W(5), static_cast(j + z - 1), false}}); - } + assignment.witness(component.W(1), row) = n; + assignment.witness(component.W(4), row) = a; + assignment.witness(component.W(5), row) = b; + row++; + } + auto res = a * component.endo_r + b; + assignment.witness(component.W(6), row - 1) = res; + return typename plonk_endo_scalar::result_type(component, instance_input, + start_row_index); + } + + template + std::array generate_gates( + const plonk_endo_scalar &component, + circuit> &bp, + assignment> &assignment, + const typename plonk_endo_scalar::input_type instance_input) { + + using F = typename BlueprintFieldType::value_type; + using var = typename plonk_endo_scalar::var; + + auto c_f = [](var x) { + return (F(11) * F(6).inversed()) * x + (-F(5) * F(2).inversed()) * x * x + + (F(2) * F(3).inversed()) * x * x * x; + }; - // check that the recalculated n is equal to the input challenge - bp.add_copy_constraint({{component.W(1), static_cast(j + component.rows_amount - 1), false}, instance_input.scalar}); - } - } // namespace components - } // namespace blueprint + auto d_f = [](var x) { + return -F::one() + (F(29) * F(6).inversed()) * x + (-F(7) * F(2).inversed()) * x * x + + (F(2) * F(3).inversed()) * x * x * x; + }; + + auto constraint_1 = var(component.W(7), 0) * (var(component.W(7), 0) - 1) * + (var(component.W(7), 0) - 2) * (var(component.W(7), 0) - 3); + auto constraint_2 = var(component.W(8), 0) * (var(component.W(8), 0) - 1) * + (var(component.W(8), 0) - 2) * (var(component.W(8), 0) - 3); + auto constraint_3 = var(component.W(9), 0) * (var(component.W(9), 0) - 1) * + (var(component.W(9), 0) - 2) * (var(component.W(9), 0) - 3); + auto constraint_4 = var(component.W(10), 0) * (var(component.W(10), 0) - 1) * + (var(component.W(10), 0) - 2) * (var(component.W(10), 0) - 3); + auto constraint_5 = var(component.W(11), 0) * (var(component.W(11), 0) - 1) * + (var(component.W(11), 0) - 2) * (var(component.W(11), 0) - 3); + auto constraint_6 = var(component.W(12), 0) * (var(component.W(12), 0) - 1) * + (var(component.W(12), 0) - 2) * (var(component.W(12), 0) - 3); + auto constraint_7 = var(component.W(13), 0) * (var(component.W(13), 0) - 1) * + (var(component.W(13), 0) - 2) * (var(component.W(13), 0) - 3); + auto constraint_8 = var(component.W(14), 0) * (var(component.W(14), 0) - 1) * + (var(component.W(14), 0) - 2) * (var(component.W(14), 0) - 3); + auto constraint_9 = + var(component.W(4), 0) - (256 * var(component.W(2), 0) + 128 * c_f(var(component.W(7), 0)) + + 64 * c_f(var(component.W(8), 0)) + 32 * c_f(var(component.W(9), 0)) + + 16 * c_f(var(component.W(10), 0)) + 8 * c_f(var(component.W(11), 0)) + + 4 * c_f(var(component.W(12), 0)) + 2 * c_f(var(component.W(13), 0)) + + c_f(var(component.W(14), 0))); + auto constraint_10 = + var(component.W(5), 0) - (256 * var(component.W(3), 0) + 128 * d_f(var(component.W(7), 0)) + + 64 * d_f(var(component.W(8), 0)) + 32 * d_f(var(component.W(9), 0)) + + 16 * d_f(var(component.W(10), 0)) + 8 * d_f(var(component.W(11), 0)) + + 4 * d_f(var(component.W(12), 0)) + 2 * d_f(var(component.W(13), 0)) + + d_f(var(component.W(14), 0))); + auto constraint_11 = + var(component.W(1), 0) - + ((1 << 16) * var(component.W(0), 0) + (1 << 14) * var(component.W(7), 0) + + (1 << 12) * var(component.W(8), 0) + (1 << 10) * var(component.W(9), 0) + + (1 << 8) * var(component.W(10), 0) + (1 << 6) * var(component.W(11), 0) + + (1 << 4) * var(component.W(12), 0) + (1 << 2) * var(component.W(13), 0) + var(component.W(14), 0)); + + auto constraint_12 = + var(component.W(6), 0) - (component.endo_r * var(component.W(4), 0) + var(component.W(5), 0)); + + std::size_t selector_index_1 = + bp.add_gate({constraint_1, constraint_2, constraint_3, constraint_4, constraint_5, constraint_6, + constraint_7, constraint_8, constraint_9, constraint_10, constraint_11}); + + std::size_t selector_index_2 = bp.add_gate({constraint_12}); + + return {selector_index_1, selector_index_2}; + } + + template + void generate_copy_constraints( + const plonk_endo_scalar &component, + circuit> &bp, + assignment> &assignment, + const typename plonk_endo_scalar::input_type instance_input, + const std::uint32_t start_row_index) { + + std::size_t j = start_row_index; + + for (std::size_t z = 1; z < component.rows_amount; z++) { + bp.add_copy_constraint({{component.W(0), static_cast(j + z), false}, + {component.W(1), static_cast(j + z - 1), false}}); + bp.add_copy_constraint({{component.W(2), static_cast(j + z), false}, + {component.W(4), static_cast(j + z - 1), false}}); + bp.add_copy_constraint({{component.W(3), static_cast(j + z), false}, + {component.W(5), static_cast(j + z - 1), false}}); + } + + // check that the recalculated n is equal to the input challenge + bp.add_copy_constraint( + {{component.W(1), static_cast(j + component.rows_amount - 1), false}, instance_input.scalar}); + } + } // namespace components + } // namespace blueprint } // namespace nil #endif // CRYPTO3_BLUEPRINT_COMPONENTS_PLONK_CURVE_ELEMENT_ENDO_SCALAR_COMPONENT_15_WIRES_HPP diff --git a/include/nil/blueprint/components/algebra/curves/pasta/plonk/fixed_base_scalar_mul_15_wires.hpp b/include/nil/blueprint/components/algebra/curves/pasta/plonk/fixed_base_scalar_mul_15_wires.hpp index 912af771a..ea2187339 100644 --- a/include/nil/blueprint/components/algebra/curves/pasta/plonk/fixed_base_scalar_mul_15_wires.hpp +++ b/include/nil/blueprint/components/algebra/curves/pasta/plonk/fixed_base_scalar_mul_15_wires.hpp @@ -35,7 +35,7 @@ #include #include #include -#include +#include namespace nil { namespace crypto3 { diff --git a/include/nil/blueprint/components/algebra/curves/pasta/plonk/multi_scalar_mul_15_wires.hpp b/include/nil/blueprint/components/algebra/curves/pasta/plonk/multi_scalar_mul_15_wires.hpp index 6bb15615a..06178dde9 100644 --- a/include/nil/blueprint/components/algebra/curves/pasta/plonk/multi_scalar_mul_15_wires.hpp +++ b/include/nil/blueprint/components/algebra/curves/pasta/plonk/multi_scalar_mul_15_wires.hpp @@ -35,137 +35,157 @@ #include #include -#include +#include #include #include #include namespace nil { - namespace crypto3 { - namespace blueprint { - namespace components { - - template - class element_g1_multi_scalar_mul; - - template - class element_g1_multi_scalar_mul< - snark::plonk_constraint_system, CurveType, PointsAmount, - W0, W1, W2, W3, W4, W5, W6, W7, W8, W9, W10, W11, W12, W13, W14> { - - typedef snark::plonk_constraint_system - ArithmetizationType; - - using scalar_mul_component = - zk::components::curve_element_variable_base_scalar_mul; - using add_component = - zk::components::curve_element_unified_addition; - - using var = snark::plonk_variable; - using var_ec_point = typename zk::components::var_ec_point; - - public: - constexpr static const std::size_t selector_seed = 0x0f07; - constexpr static const std::size_t rows_amount = - PointsAmount * (scalar_mul_component::rows_amount + add_component::rows_amount); - constexpr static const std::size_t gates_amount = 0; - - struct params_type { - std::array scalars; - std::array bases; - }; - - struct result_type { - var_ec_point output; - - result_type(const params_type ¶ms, std::size_t start_row_index) { - } - }; - - static result_type - generate_circuit(blueprint &bp, - blueprint_public_assignment_table &assignment, - const params_type ¶ms, - const std::size_t start_row_index) { - - std::size_t row = start_row_index; - std::array res; - for (std::size_t i = 0; i < PointsAmount; i++) { - auto multiplied = scalar_mul_component::generate_circuit( - bp, assignment, {{params.bases[i].X, params.bases[i].Y}, params.scalars[i]}, row); - row += scalar_mul_component::rows_amount; - if (i == 0) { - res[0] = multiplied.X; - res[1] = multiplied.Y; - } else { - components::generate_circuit( - bp, assignment, {{res[0], res[1]}, {multiplied.X, multiplied.Y}}, row); - typename add_component::result_type added( - {{res[0], res[1]}, {multiplied.X, multiplied.Y}}, row); - res[0] = added.X; - res[1] = added.Y; - row += add_component::rows_amount; - } - } + namespace blueprint { + namespace components { + + template + class element_g1_multi_scalar_mul; + + template + class element_g1_multi_scalar_mul, + CurveType, + PointsAmount, + W0, + W1, + W2, + W3, + W4, + W5, + W6, + W7, + W8, + W9, + W10, + W11, + W12, + W13, + W14> { + + typedef crypto3::zk::snark::plonk_constraint_system ArithmetizationType; + + using scalar_mul_component = curve_element_variable_base_scalar_mul; + using add_component = unified_addition; + + using var = crypto3::zk::snark::plonk_variable; + using var_ec_point = var_ec_point; + + public: + constexpr static const std::size_t selector_seed = 0x0f07; + constexpr static const std::size_t rows_amount = + PointsAmount * (scalar_mul_component::rows_amount + add_component::rows_amount); + constexpr static const std::size_t gates_amount = 0; + + struct params_type { + std::array scalars; + std::array bases; + }; - auto result = result_type(params, start_row_index); - result.output.X = res[0]; - result.output.Y = res[1]; - return result; - } + struct result_type { + var_ec_point output; - static void - generate_gates(blueprint &bp, - blueprint_public_assignment_table &public_assignment, - const params_type ¶ms, - std::size_t component_start_row) { + result_type(const params_type ¶ms, std::size_t start_row_index) { } + }; - static void generate_copy_constraints( - blueprint &bp, - blueprint_public_assignment_table &public_assignment, - const params_type ¶ms, - std::size_t component_start_row) { + static result_type generate_circuit(blueprint &bp, + assignment &assignment, + const params_type ¶ms, + const std::size_t start_row_index) { + + std::size_t row = start_row_index; + std::array res; + for (std::size_t i = 0; i < PointsAmount; i++) { + auto multiplied = scalar_mul_component::generate_circuit( + bp, assignment, {{params.bases[i].X, params.bases[i].Y}, params.scalars[i]}, row); + row += scalar_mul_component::rows_amount; + if (i == 0) { + res[0] = multiplied.X; + res[1] = multiplied.Y; + } else { + components::generate_circuit( + bp, assignment, {{res[0], res[1]}, {multiplied.X, multiplied.Y}}, row); + typename add_component::result_type added({{res[0], res[1]}, {multiplied.X, multiplied.Y}}, + row); + res[0] = added.X; + res[1] = added.Y; + row += add_component::rows_amount; + } } - static result_type generate_assignments(blueprint_assignment_table &assignment, - const params_type ¶ms, - const std::size_t start_row_index) { - - std::size_t row = start_row_index; - std::array res; - for (std::size_t i = 0; i < PointsAmount; i++) { - auto multiplied = scalar_mul_component::generate_assignments( - assignment, {{params.bases[i].X, params.bases[i].Y}, params.scalars[i]}, row); - row += scalar_mul_component::rows_amount; - if (i == 0) { - res[0] = multiplied.X; - res[1] = multiplied.Y; - } else { - auto added = add_component::generate_assignments( - assignment, {{res[0], res[1]}, {multiplied.X, multiplied.Y}}, row); - res[0] = added.X; - res[1] = added.Y; - row += add_component::rows_amount; - } + auto result = result_type(params, start_row_index); + result.output.X = res[0]; + result.output.Y = res[1]; + return result; + } + + static void generate_gates(blueprint &bp, + assignment &public_assignment, + const params_type ¶ms, + std::size_t component_start_row) { + } + + static void generate_copy_constraints(blueprint &bp, + assignment &public_assignment, + const params_type ¶ms, + std::size_t component_start_row) { + } + + static result_type generate_assignments(assignment &assignment, + const params_type ¶ms, + const std::size_t start_row_index) { + + std::size_t row = start_row_index; + std::array res; + for (std::size_t i = 0; i < PointsAmount; i++) { + auto multiplied = scalar_mul_component::generate_assignments( + assignment, {{params.bases[i].X, params.bases[i].Y}, params.scalars[i]}, row); + row += scalar_mul_component::rows_amount; + if (i == 0) { + res[0] = multiplied.X; + res[1] = multiplied.Y; + } else { + auto added = add_component::generate_assignments( + assignment, {{res[0], res[1]}, {multiplied.X, multiplied.Y}}, row); + res[0] = added.X; + res[1] = added.Y; + row += add_component::rows_amount; } - - auto result = result_type(params, start_row_index); - result.output.X = res[0]; - result.output.Y = res[1]; - return result; } - }; - } // namespace components - } // namespace blueprint - } // namespace crypto3 + + auto result = result_type(params, start_row_index); + result.output.X = res[0]; + result.output.Y = res[1]; + return result; + } + }; + } // namespace components + } // namespace blueprint } // namespace nil #endif // CRYPTO3_BLUEPRINT_COMPONENTS_PLONK_CURVE_ELEMENT_MULTI_SCALAR_MUL_COMPONENT_15_WIRES_HPP diff --git a/include/nil/blueprint/components/algebra/curves/pasta/plonk/types.hpp b/include/nil/blueprint/components/algebra/curves/pasta/plonk/types.hpp index 4ca1920d4..a717a701f 100644 --- a/include/nil/blueprint/components/algebra/curves/pasta/plonk/types.hpp +++ b/include/nil/blueprint/components/algebra/curves/pasta/plonk/types.hpp @@ -33,19 +33,17 @@ #include namespace nil { - namespace crypto3 { - namespace blueprint { - namespace components { + namespace blueprint { + namespace components { - template - struct var_ec_point { - using var = snark::plonk_variable; - var X; - var Y; - }; - } // namespace components - } // namespace blueprint - } // namespace crypto3 + template + struct var_ec_point { + using var = crypto3::zk::snark::plonk_variable; + var X; + var Y; + }; + } // namespace components + } // namespace blueprint } // namespace nil #endif // CRYPTO3_BLUEPRINT_COMPONENTS_PLONK_TYPES_HPP \ No newline at end of file diff --git a/include/nil/blueprint/components/algebra/curves/pasta/plonk/variable_base_endo_scalar_mul_15_wires.hpp b/include/nil/blueprint/components/algebra/curves/pasta/plonk/variable_base_endo_scalar_mul_15_wires.hpp index 36e71e98c..dd217f66a 100644 --- a/include/nil/blueprint/components/algebra/curves/pasta/plonk/variable_base_endo_scalar_mul_15_wires.hpp +++ b/include/nil/blueprint/components/algebra/curves/pasta/plonk/variable_base_endo_scalar_mul_15_wires.hpp @@ -37,347 +37,326 @@ #include #include -#include +#include #include namespace nil { - namespace crypto3 { - namespace blueprint { - namespace components { - - template - class curve_element_variable_base_endo_scalar_mul; - - template - class curve_element_variable_base_endo_scalar_mul< - snark::plonk_constraint_system, - CurveType, - W0, - W1, - W2, - W3, - W4, - W5, - W6, - W7, - W8, - W9, - W10, - W11, - W12, - W13, - W14> { - typedef snark::plonk_constraint_system - ArithmetizationType; - - using var = snark::plonk_variable; - - using multiplication_component = zk::components::multiplication; - - using unified_addition_component = - zk::components::curve_element_unified_addition; - - public: - constexpr static const typename BlueprintFieldType::value_type endo = - typename BlueprintFieldType::value_type( - algebra::fields::arithmetic_params::multiplicative_generator) - .pow(typename BlueprintFieldType::integral_type( - ((BlueprintFieldType::value_type::zero() - BlueprintFieldType::value_type::one()) * - (typename BlueprintFieldType::value_type(3)).inversed()) - .data)); - constexpr static const std::size_t selector_seed = 0x0f02; - constexpr static const std::size_t rows_amount = - 33 + multiplication_component::rows_amount + unified_addition_component::rows_amount * 2; - constexpr static const std::size_t gates_amount = 1; - - struct params_type { - struct var_ec_point { - var x; - var y; - }; - - var_ec_point T; - var b; + namespace blueprint { + namespace components { + + template + class curve_element_variable_base_endo_scalar_mul; + + template + class curve_element_variable_base_endo_scalar_mul< + crypto3::zk::snark::plonk_constraint_system, + CurveType, + W0, + W1, + W2, + W3, + W4, + W5, + W6, + W7, + W8, + W9, + W10, + W11, + W12, + W13, + W14> { + typedef crypto3::zk::snark::plonk_constraint_system ArithmetizationType; + + using var = crypto3::zk::snark::plonk_variable; + + using multiplication_component = multiplication>; + + using unified_addition_component = unified_addition; + + public: + constexpr static const typename BlueprintFieldType::value_type endo = + typename BlueprintFieldType::value_type( + crypto3::algebra::fields::arithmetic_params::multiplicative_generator) + .pow(typename BlueprintFieldType::integral_type( + ((BlueprintFieldType::value_type::zero() - BlueprintFieldType::value_type::one()) * + (typename BlueprintFieldType::value_type(3)).inversed()) + .data)); + constexpr static const std::size_t selector_seed = 0x0f02; + constexpr static const std::size_t rows_amount = + 33 + multiplication_component::rows_amount + unified_addition_component::rows_amount * 2; + constexpr static const std::size_t gates_amount = 1; + + struct params_type { + struct var_ec_point { + var x; + var y; }; - struct result_type { - var X; - var Y; - result_type(std::size_t start_row_index) { - X = var(W4, start_row_index + rows_amount - 1, false); - Y = var(W5, start_row_index + rows_amount - 1, false); - } - }; - - static result_type generate_assignments(blueprint_assignment_table &assignment, - const params_type ¶ms, - const std::size_t start_row_index) { - - std::size_t j = start_row_index; - typename multiplication_component::params_type multiplication_params = { - params.T.x, var(W0, j + 1, false, var::column_type::constant)}; - auto mul_res = - multiplication_component::generate_assignments(assignment, multiplication_params, j); - j++; - - typename unified_addition_component::params_type addition_params = { - {params.T.x, params.T.y}, {mul_res.output, params.T.y}}; - auto add_res = unified_addition_component::generate_assignments(assignment, addition_params, j); - j++; - - typename unified_addition_component::params_type double_params = {{add_res.X, add_res.Y}, - {add_res.X, add_res.Y}}; - unified_addition_component::generate_assignments(assignment, double_params, j); - j++; - - typename BlueprintFieldType::value_type b = assignment.var_value(params.b); - typename BlueprintFieldType::value_type T_x = assignment.var_value(params.T.x); - typename BlueprintFieldType::value_type T_y = assignment.var_value(params.T.y); - typename CurveType::template g1_type::value_type T(T_x, - T_y); - - typename CurveType::template g1_type::value_type P; - - typename CurveType::template g1_type::value_type R; - typename CurveType::template g1_type::value_type Q; - typename CurveType::scalar_field_type::integral_type integral_b = - typename CurveType::scalar_field_type::integral_type(b.data); - - std::array bits = {false}; - { - nil::marshalling::status_type status; - std::array bits_all = - nil::marshalling::pack(integral_b, status); - std::copy(bits_all.end() - 128, bits_all.end(), bits.begin()); - } - - typename ArithmetizationType::field_type::value_type n = 0; - typename ArithmetizationType::field_type::value_type n_next = 0; - typename ArithmetizationType::field_type::value_type s1 = 0; - typename ArithmetizationType::field_type::value_type s3 = 0; - for (std::size_t i = j; i < j + 32; i++) { - assignment.witness(W0)[i] = T.X; - assignment.witness(W1)[i] = T.Y; - if (i == j) { - Q.X = endo * T.X; - Q.Y = T.Y; - P = T + (T + Q) + Q; - assignment.witness(W4)[i] = P.X; - assignment.witness(W5)[i] = P.Y; - assignment.witness(W6)[i] = n; - } else { - Q.X = (1 + (endo - 1) * bits[(i - j) * 4 - 2]) * T.X; - Q.Y = (2 * bits[(i - j) * 4 - 1] - 1) * T.Y; - /*s4 = 2 * R.Y * (2*R.X + Q.X - s3 * s3).inversed() - s3; - P.X = Q.X + s4*s4 - s3*s3; - P.Y = (R.X - P.X)*s4 -R.Y;*/ - P = 2 * R + Q; - assignment.witness(W4)[i] = P.X; - assignment.witness(W5)[i] = P.Y; - n_next = n * 16 + bits[(i - j) * 4 - 4] * 8 + bits[(i - j) * 4 - 3] * 4 + - bits[(i - j) * 4 - 2] * 2 + bits[(i - j) * 4 - 1]; - assignment.witness(W6)[i] = n_next; - n = n_next; - } - assignment.witness(W11)[i] = bits[(i - j) * 4]; - assignment.witness(W12)[i] = bits[(i - j) * 4 + 1]; - assignment.witness(W13)[i] = bits[(i - j) * 4 + 2]; - assignment.witness(W14)[i] = bits[(i - j) * 4 + 3]; - Q.X = (1 + (endo - 1) * bits[(i - j) * 4]) * T.X; - Q.Y = (2 * bits[(i - j) * 4 + 1] - 1) * T.Y; - s1 = (Q.Y - P.Y) * (Q.X - P.X).inversed(); - // s2 = 2 * P.Y * (2*P.X + Q.X - s1 * s1).inversed() - s1; - - assignment.witness(W9)[i] = s1; - /*R.X = Q.X + s2*s2 - s1*s1; - R.Y = (P.X - R.X)*s2 -P.Y;*/ - R = 2 * P + Q; - s3 = ((2 * bits[(i - j) * 4 + 3] - 1) * T.Y - R.Y) * - ((1 + (endo - 1) * bits[(i - j) * 4 + 2]) * T.X - R.X).inversed(); - assignment.witness(W10)[i] = s3; - assignment.witness(W7)[i] = R.X; - assignment.witness(W8)[i] = R.Y; - } + var_ec_point T; + var b; + }; - Q.X = (1 + (endo - 1) * bits[126]) * T.X; - Q.Y = (2 * bits[127] - 1) * T.Y; - /*s4 = 2 * R.Y * (2*R.X + Q.X - s3 * s3).inversed() - s3; - P.X = Q.X + s4*s4 - s3*s3; - P.Y = (R.X - P.X)*s4 -R.Y; */ - P = R + Q + R; - assignment.witness(W4)[j + 32] = P.X; - assignment.witness(W5)[j + 32] = P.Y; - n_next = n * 16 + bits[124] * 8 + bits[125] * 4 + bits[126] * 2 + bits[127]; - assignment.witness(W6)[j + 32] = n_next; + struct result_type { + var X; + var Y; + result_type(std::size_t start_row_index) { + X = var(W4, start_row_index + rows_amount - 1, false); + Y = var(W5, start_row_index + rows_amount - 1, false); } + }; - static result_type - generate_circuit(blueprint &bp, - blueprint_public_assignment_table &assignment, - const params_type ¶ms, - const std::size_t start_row_index) { - - generate_assignments_constant(bp, assignment, params, start_row_index); + static result_type generate_assignments(assignment &assignment, + const params_type ¶ms, + const std::size_t start_row_index) { + + std::size_t j = start_row_index; + typename multiplication_component::params_type multiplication_params = { + params.T.x, var(W0, j + 1, false, var::column_type::constant)}; + auto mul_res = multiplication_component::generate_assignments(assignment, multiplication_params, j); + j++; + + typename unified_addition_component::params_type addition_params = {{params.T.x, params.T.y}, + {mul_res.output, params.T.y}}; + auto add_res = unified_addition_component::generate_assignments(assignment, addition_params, j); + j++; + + typename unified_addition_component::params_type double_params = {{add_res.X, add_res.Y}, + {add_res.X, add_res.Y}}; + unified_addition_component::generate_assignments(assignment, double_params, j); + j++; + + typename BlueprintFieldType::value_type b = assignment.var_value(params.b); + typename BlueprintFieldType::value_type T_x = assignment.var_value(params.T.x); + typename BlueprintFieldType::value_type T_y = assignment.var_value(params.T.y); + typename CurveType::template g1_type::value_type T( + T_x, T_y); + + typename CurveType::template g1_type::value_type P; + + typename CurveType::template g1_type::value_type R; + typename CurveType::template g1_type::value_type Q; + typename CurveType::scalar_field_type::integral_type integral_b = + typename CurveType::scalar_field_type::integral_type(b.data); + + std::array bits = {false}; + { + nil::marshalling::status_type status; + std::array bits_all = + nil::marshalling::pack(integral_b, status); + std::copy(bits_all.end() - 128, bits_all.end(), bits.begin()); + } - auto selector_iterator = assignment.find_selector(selector_seed); - std::size_t first_selector_index; - if (selector_iterator == assignment.selectors_end()) { - first_selector_index = assignment.allocate_selector(selector_seed, gates_amount); - generate_gates(bp, assignment, params, first_selector_index); + typename ArithmetizationType::field_type::value_type n = 0; + typename ArithmetizationType::field_type::value_type n_next = 0; + typename ArithmetizationType::field_type::value_type s1 = 0; + typename ArithmetizationType::field_type::value_type s3 = 0; + for (std::size_t i = j; i < j + 32; i++) { + assignment.witness(W0)[i] = T.X; + assignment.witness(W1)[i] = T.Y; + if (i == j) { + Q.X = endo * T.X; + Q.Y = T.Y; + P = T + (T + Q) + Q; + assignment.witness(W4)[i] = P.X; + assignment.witness(W5)[i] = P.Y; + assignment.witness(W6)[i] = n; } else { - first_selector_index = selector_iterator->second; + Q.X = (1 + (endo - 1) * bits[(i - j) * 4 - 2]) * T.X; + Q.Y = (2 * bits[(i - j) * 4 - 1] - 1) * T.Y; + /*s4 = 2 * R.Y * (2*R.X + Q.X - s3 * s3).inversed() - s3; + P.X = Q.X + s4*s4 - s3*s3; + P.Y = (R.X - P.X)*s4 -R.Y;*/ + P = 2 * R + Q; + assignment.witness(W4)[i] = P.X; + assignment.witness(W5)[i] = P.Y; + n_next = n * 16 + bits[(i - j) * 4 - 4] * 8 + bits[(i - j) * 4 - 3] * 4 + + bits[(i - j) * 4 - 2] * 2 + bits[(i - j) * 4 - 1]; + assignment.witness(W6)[i] = n_next; + n = n_next; } - std::size_t j = start_row_index; - typename multiplication_component::params_type multiplication_params = { - params.T.x, var(W0, j + 1, false, var::column_type::constant)}; - zk::components::generate_circuit( - bp, assignment, multiplication_params, start_row_index); - typename multiplication_component::result_type mul_res(multiplication_params, j); - j++; - - typename unified_addition_component::params_type addition_params = { - {params.T.x, params.T.y}, {mul_res.output, params.T.y}}; - zk::components::generate_circuit( - bp, assignment, addition_params, j); - typename unified_addition_component::result_type add_res(addition_params, j); - j++; - - typename unified_addition_component::params_type double_params = {{add_res.X, add_res.Y}, - {add_res.X, add_res.Y}}; - zk::components::generate_circuit(bp, assignment, double_params, j); - j++; - - assignment.enable_selector(first_selector_index, j, j + 31); - - generate_copy_constraints(bp, assignment, params, start_row_index); - return result_type(start_row_index); + assignment.witness(W11)[i] = bits[(i - j) * 4]; + assignment.witness(W12)[i] = bits[(i - j) * 4 + 1]; + assignment.witness(W13)[i] = bits[(i - j) * 4 + 2]; + assignment.witness(W14)[i] = bits[(i - j) * 4 + 3]; + Q.X = (1 + (endo - 1) * bits[(i - j) * 4]) * T.X; + Q.Y = (2 * bits[(i - j) * 4 + 1] - 1) * T.Y; + s1 = (Q.Y - P.Y) * (Q.X - P.X).inversed(); + // s2 = 2 * P.Y * (2*P.X + Q.X - s1 * s1).inversed() - s1; + + assignment.witness(W9)[i] = s1; + /*R.X = Q.X + s2*s2 - s1*s1; + R.Y = (P.X - R.X)*s2 -P.Y;*/ + R = 2 * P + Q; + s3 = ((2 * bits[(i - j) * 4 + 3] - 1) * T.Y - R.Y) * + ((1 + (endo - 1) * bits[(i - j) * 4 + 2]) * T.X - R.X).inversed(); + assignment.witness(W10)[i] = s3; + assignment.witness(W7)[i] = R.X; + assignment.witness(W8)[i] = R.Y; } - static void generate_gates(blueprint &bp, - blueprint_public_assignment_table &assignment, - const params_type ¶ms, - const std::size_t first_selector_index) { - - auto bit_check_1 = bp.add_bit_check(var(W11, 0)); - auto bit_check_2 = bp.add_bit_check(var(W12, 0)); - auto bit_check_3 = bp.add_bit_check(var(W13, 0)); - auto bit_check_4 = bp.add_bit_check(var(W14, 0)); - - auto constraint_1 = - bp.add_constraint(((1 + (endo - 1) * var(W11, 0)) * var(W0, 0) - var(W4, 0)) * var(W9, 0) - - 2 * var(W12, 0) * var(W1, 0) + var(W1, 0) + var(W5, 0)); - auto constraint_2 = bp.add_constraint( - (2 * var(W4, 0) - var(W9, 0) * var(W9, 0) + (1 + (endo - 1) * var(W11, 0)) * var(W0, 0)) * - ((var(W4, 0) - var(W7, 0)) * var(W9, 0) + var(W8, 0) + var(W5, 0)) - - ((var(W4, 0) - var(W7, 0)) * 2 * var(W5, 0))); - auto constraint_3 = bp.add_constraint( - (var(W8, 0) + var(W5, 0)) * (var(W8, 0) + var(W5, 0)) - - ((var(W4, 0) - var(W7, 0)) * (var(W4, 0) - var(W7, 0)) * - (var(W9, 0) * var(W9, 0) - (1 + (endo - 1) * var(W11, 0)) * var(W0, 0) + var(W7, 0)))); - auto constraint_4 = - bp.add_constraint(((1 + (endo - 1) * var(W13, 0)) * var(W0, 0) - var(W7, 0)) * var(W10, 0) - - 2 * var(W14, 0) * var(W1, 0) + var(W1, 0) + var(W8, 0)); - auto constraint_5 = bp.add_constraint( - (2 * var(W7, 0) - var(W10, 0) * var(W10, 0) + (1 + (endo - 1) * var(W13, 0)) * var(W0, 0)) * - ((var(W7, 0) - var(W4, +1)) * var(W10, 0) + var(W5, +1) + var(W8, 0)) - - ((var(W7, 0) - var(W4, +1)) * 2 * var(W8, 0))); - auto constraint_6 = bp.add_constraint( - (var(W5, +1) + var(W8, 0)) * (var(W5, +1) + var(W8, 0)) - - ((var(W7, 0) - var(W4, +1)) * (var(W7, 0) - var(W4, +1)) * - (var(W10, 0) * var(W10, 0) - (1 + (endo - 1) * var(W13, 0)) * var(W0, 0) + var(W4, +1)))); - auto constraint_7 = - bp.add_constraint(var(W6, +1) - (16 * var(W6, 0) + 8 * var(W11, 0) + 4 * var(W12, 0) + - 2 * var(W13, 0) + var(W14, 0))); - - bp.add_gate(first_selector_index, - {bit_check_1, bit_check_2, bit_check_3, bit_check_4, constraint_1, constraint_2, - constraint_3, constraint_4, constraint_5, constraint_6, constraint_7}); + Q.X = (1 + (endo - 1) * bits[126]) * T.X; + Q.Y = (2 * bits[127] - 1) * T.Y; + /*s4 = 2 * R.Y * (2*R.X + Q.X - s3 * s3).inversed() - s3; + P.X = Q.X + s4*s4 - s3*s3; + P.Y = (R.X - P.X)*s4 -R.Y; */ + P = R + Q + R; + assignment.witness(W4)[j + 32] = P.X; + assignment.witness(W5)[j + 32] = P.Y; + n_next = n * 16 + bits[124] * 8 + bits[125] * 4 + bits[126] * 2 + bits[127]; + assignment.witness(W6)[j + 32] = n_next; + } + + static result_type generate_circuit(blueprint &bp, + assignment &assignment, + const params_type ¶ms, + const std::size_t start_row_index) { + + generate_assignments_constant(bp, assignment, params, start_row_index); + + auto selector_iterator = assignment.find_selector(selector_seed); + std::size_t first_selector_index; + if (selector_iterator == assignment.selectors_end()) { + first_selector_index = assignment.allocate_selector(selector_seed, gates_amount); + generate_gates(bp, assignment, params, first_selector_index); + } else { + first_selector_index = selector_iterator->second; } - - static void - generate_copy_constraints(blueprint &bp, - blueprint_public_assignment_table &assignment, - const params_type ¶ms, - const std::size_t start_row_index) { - - std::size_t j = start_row_index; - - typename multiplication_component::params_type multiplication_params = { - params.T.x, var(0, j, false, var::column_type::constant)}; - typename multiplication_component::result_type mul_res(multiplication_params, start_row_index); - j++; - - typename unified_addition_component::params_type addition_params = { - {params.T.x, params.T.y}, {mul_res.output, params.T.y}}; - typename unified_addition_component::result_type add_res(addition_params, j); - j++; - - typename unified_addition_component::params_type double_params = {{add_res.X, add_res.Y}, - {add_res.X, add_res.Y}}; - typename unified_addition_component::result_type double_res(double_params, j); - j++; - - bp.add_copy_constraint({{W4, (std::int32_t)(j), false}, double_res.X}); - bp.add_copy_constraint({{W5, (std::int32_t)(j), false}, double_res.Y}); - - for (int z = 0; z < 31; z++) { - bp.add_copy_constraint( - {{W0, (std::int32_t)(j + z), false}, {W0, (std::int32_t)(j + z + 1), false}}); - bp.add_copy_constraint( - {{W1, (std::int32_t)(j + z), false}, {W1, (std::int32_t)(j + z + 1), false}}); - } + std::size_t j = start_row_index; + typename multiplication_component::params_type multiplication_params = { + params.T.x, var(W0, j + 1, false, var::column_type::constant)}; + ::nil::blueprint::components::generate_circuit(bp, assignment, multiplication_params, start_row_index); + typename multiplication_component::result_type mul_res(multiplication_params, j); + j++; + + typename unified_addition_component::params_type addition_params = {{params.T.x, params.T.y}, + {mul_res.output, params.T.y}}; + ::nil::blueprint::components::generate_circuit(bp, assignment, addition_params, j); + typename unified_addition_component::result_type add_res(addition_params, j); + j++; + + typename unified_addition_component::params_type double_params = {{add_res.X, add_res.Y}, + {add_res.X, add_res.Y}}; + ::nil::blueprint::components::generate_circuit(bp, assignment, double_params, j); + j++; + + assignment.enable_selector(first_selector_index, j, j + 31); + + generate_copy_constraints(bp, assignment, params, start_row_index); + return result_type(start_row_index); + } + + static void generate_gates(blueprint &bp, + assignment &assignment, + const params_type ¶ms, + const std::size_t first_selector_index) { + + auto bit_check_1 = bp.add_bit_check(var(W11, 0)); + auto bit_check_2 = bp.add_bit_check(var(W12, 0)); + auto bit_check_3 = bp.add_bit_check(var(W13, 0)); + auto bit_check_4 = bp.add_bit_check(var(W14, 0)); + + auto constraint_1 = + bp.add_constraint(((1 + (endo - 1) * var(W11, 0)) * var(W0, 0) - var(W4, 0)) * var(W9, 0) - + 2 * var(W12, 0) * var(W1, 0) + var(W1, 0) + var(W5, 0)); + auto constraint_2 = bp.add_constraint( + (2 * var(W4, 0) - var(W9, 0) * var(W9, 0) + (1 + (endo - 1) * var(W11, 0)) * var(W0, 0)) * + ((var(W4, 0) - var(W7, 0)) * var(W9, 0) + var(W8, 0) + var(W5, 0)) - + ((var(W4, 0) - var(W7, 0)) * 2 * var(W5, 0))); + auto constraint_3 = bp.add_constraint( + (var(W8, 0) + var(W5, 0)) * (var(W8, 0) + var(W5, 0)) - + ((var(W4, 0) - var(W7, 0)) * (var(W4, 0) - var(W7, 0)) * + (var(W9, 0) * var(W9, 0) - (1 + (endo - 1) * var(W11, 0)) * var(W0, 0) + var(W7, 0)))); + auto constraint_4 = + bp.add_constraint(((1 + (endo - 1) * var(W13, 0)) * var(W0, 0) - var(W7, 0)) * var(W10, 0) - + 2 * var(W14, 0) * var(W1, 0) + var(W1, 0) + var(W8, 0)); + auto constraint_5 = bp.add_constraint( + (2 * var(W7, 0) - var(W10, 0) * var(W10, 0) + (1 + (endo - 1) * var(W13, 0)) * var(W0, 0)) * + ((var(W7, 0) - var(W4, +1)) * var(W10, 0) + var(W5, +1) + var(W8, 0)) - + ((var(W7, 0) - var(W4, +1)) * 2 * var(W8, 0))); + auto constraint_6 = bp.add_constraint( + (var(W5, +1) + var(W8, 0)) * (var(W5, +1) + var(W8, 0)) - + ((var(W7, 0) - var(W4, +1)) * (var(W7, 0) - var(W4, +1)) * + (var(W10, 0) * var(W10, 0) - (1 + (endo - 1) * var(W13, 0)) * var(W0, 0) + var(W4, +1)))); + auto constraint_7 = + bp.add_constraint(var(W6, +1) - (16 * var(W6, 0) + 8 * var(W11, 0) + 4 * var(W12, 0) + + 2 * var(W13, 0) + var(W14, 0))); + + bp.add_gate(first_selector_index, + {bit_check_1, bit_check_2, bit_check_3, bit_check_4, constraint_1, constraint_2, + constraint_3, constraint_4, constraint_5, constraint_6, constraint_7}); + } + + static void generate_copy_constraints(blueprint &bp, + assignment &assignment, + const params_type ¶ms, + const std::size_t start_row_index) { + + std::size_t j = start_row_index; + + typename multiplication_component::params_type multiplication_params = { + params.T.x, var(0, j, false, var::column_type::constant)}; + typename multiplication_component::result_type mul_res(multiplication_params, start_row_index); + j++; + + typename unified_addition_component::params_type addition_params = {{params.T.x, params.T.y}, + {mul_res.output, params.T.y}}; + typename unified_addition_component::result_type add_res(addition_params, j); + j++; + + typename unified_addition_component::params_type double_params = {{add_res.X, add_res.Y}, + {add_res.X, add_res.Y}}; + typename unified_addition_component::result_type double_res(double_params, j); + j++; + + bp.add_copy_constraint({{W4, (std::int32_t)(j), false}, double_res.X}); + bp.add_copy_constraint({{W5, (std::int32_t)(j), false}, double_res.Y}); + + for (int z = 0; z < 31; z++) { bp.add_copy_constraint( - {{W6, (std::int32_t)(j + 0), false}, - {0, (std::int32_t)(start_row_index + 1), false, var::column_type::constant}}); - - // TODO link to params.b - - bp.add_copy_constraint({{W6, (std::int32_t)(j + 32), false}, params.b}); - } - - static void generate_assignments_constant( - blueprint &bp, - blueprint_public_assignment_table &assignment, - const params_type ¶ms, - std::size_t component_start_row) { - std::size_t row = component_start_row; - - assignment.constant(0)[row] = ArithmetizationType::field_type::value_type::zero(); - assignment.constant(0)[row + 1] = endo; + {{W0, (std::int32_t)(j + z), false}, {W0, (std::int32_t)(j + z + 1), false}}); + bp.add_copy_constraint( + {{W1, (std::int32_t)(j + z), false}, {W1, (std::int32_t)(j + z + 1), false}}); } - }; - } // namespace components - } // namespace blueprint - } // namespace crypto3 + bp.add_copy_constraint( + {{W6, (std::int32_t)(j + 0), false}, + {0, (std::int32_t)(start_row_index + 1), false, var::column_type::constant}}); + + // TODO link to params.b + + bp.add_copy_constraint({{W6, (std::int32_t)(j + 32), false}, params.b}); + } + + static void generate_assignments_constant(blueprint &bp, + assignment &assignment, + const params_type ¶ms, + std::size_t component_start_row) { + std::size_t row = component_start_row; + + assignment.constant(0)[row] = ArithmetizationType::field_type::value_type::zero(); + assignment.constant(0)[row + 1] = endo; + } + }; + } // namespace components + } // namespace blueprint } // namespace nil #endif // CRYPTO3_BLUEPRINT_COMPONENTS_PLONK_CURVE_ELEMENT_VARIABLE_BASE_SCALAR_MUL_COMPONENT_15_WIRES_HPP diff --git a/include/nil/blueprint/components/algebra/curves/pasta/plonk/variable_base_scalar_mul.hpp b/include/nil/blueprint/components/algebra/curves/pasta/plonk/variable_base_scalar_mul.hpp index d68042280..277f2cbeb 100644 --- a/include/nil/blueprint/components/algebra/curves/pasta/plonk/variable_base_scalar_mul.hpp +++ b/include/nil/blueprint/components/algebra/curves/pasta/plonk/variable_base_scalar_mul.hpp @@ -35,6 +35,7 @@ #include #include #include +#include #include #include @@ -52,8 +53,9 @@ namespace nil { // Output: y * P, where x = (y - 2^255) (if x is -1, 0, 1) // Pallas curve: // Input: x, x_high_bit \in F_p, P \in E(F_p) - // Output: y * P, where x + 2^254 * x_high_bit = (y - 2^255 - 1) / 2 (if (x + 2^254 * x_high_bit) is not -1, 0, 1) - // Output: y * P, where x + 2^254 * x_high_bit = (y - 2^255) (if (x + 2^254 * x_high_bit) is -1, 0, 1) + // Output: y * P, where x + 2^254 * x_high_bit = (y - 2^255 - 1) / 2 (if (x + 2^254 * x_high_bit) is not + // -1, 0, 1) Output: y * P, where x + 2^254 * x_high_bit = (y - 2^255) (if (x + 2^254 * x_high_bit) + // is -1, 0, 1) // clang-format off // _____________________________________________________________________________________________________________________________________________________ @@ -85,18 +87,24 @@ namespace nil { struct variable_base_scalar_mul_shifted_consts { using FieldType = nil::crypto3::algebra::fields::pallas_base_field; - constexpr static const typename FieldType::value_type shifted_minus_one = 0x224698fc0994a8dd8c46eb2100000000_cppui255; - constexpr static const typename FieldType::value_type shifted_zero = 0x200000000000000000000000000000003369e57a0e5efd4c526a60b180000001_cppui255; - constexpr static const typename FieldType::value_type shifted_one = 0x224698fc0994a8dd8c46eb2100000001_cppui255; + constexpr static const typename FieldType::value_type shifted_minus_one = + 0x224698fc0994a8dd8c46eb2100000000_cppui255; + constexpr static const typename FieldType::value_type shifted_zero = + 0x200000000000000000000000000000003369e57a0e5efd4c526a60b180000001_cppui255; + constexpr static const typename FieldType::value_type shifted_one = + 0x224698fc0994a8dd8c46eb2100000001_cppui255; }; template<> struct variable_base_scalar_mul_shifted_consts { using FieldType = nil::crypto3::algebra::fields::vesta_base_field; - constexpr static const typename FieldType::value_type shifted_minus_one = 0x448d31f81299f237325a61da00000001_cppui255; - constexpr static const typename FieldType::value_type shifted_zero = 0x448d31f81299f237325a61da00000002_cppui255; - constexpr static const typename FieldType::value_type shifted_one = 0x448d31f81299f237325a61da00000003_cppui255; + constexpr static const typename FieldType::value_type shifted_minus_one = + 0x448d31f81299f237325a61da00000001_cppui255; + constexpr static const typename FieldType::value_type shifted_zero = + 0x448d31f81299f237325a61da00000002_cppui255; + constexpr static const typename FieldType::value_type shifted_one = + 0x448d31f81299f237325a61da00000003_cppui255; }; //////////////////////////////// @@ -105,9 +113,8 @@ namespace nil { template class curve_element_variable_base_scalar_mul< - crypto3::zk::snark::plonk_constraint_system, - CurveType - >: public plonk_component { + crypto3::zk::snark::plonk_constraint_system, CurveType> + : public plonk_component { public: using component_type = plonk_component; @@ -115,7 +122,7 @@ namespace nil { using var = typename component_type::var; using manifest_type = plonk_component_manifest; using add_component = - nil::blueprint::components::unified_addition, CurveType>; + unified_addition, CurveType>; class gate_manifest_type : public component_gate_manifest { public: @@ -124,43 +131,51 @@ namespace nil { } }; - static gate_manifest get_gate_manifest(std::size_t witness_amount, - std::size_t lookup_column_amount) { + static gate_manifest get_gate_manifest(std::size_t witness_amount, std::size_t lookup_column_amount) { static gate_manifest manifest = gate_manifest(gate_manifest_type()) - .merge_with(add_component::get_gate_manifest(witness_amount, lookup_column_amount)); + .merge_with(add_component::get_gate_manifest(witness_amount, lookup_column_amount)); return manifest; } static manifest_type get_manifest() { - static manifest_type manifest = manifest_type( - std::shared_ptr(new manifest_single_value_param(15)), - true - ).merge_with(add_component::get_manifest()); + static manifest_type manifest = + manifest_type(std::shared_ptr(new manifest_single_value_param(15)), true) + .merge_with(add_component::get_manifest()); return manifest; } constexpr static std::size_t get_rows_amount(std::size_t witness_amount, - std::size_t lookup_column_amount) { + std::size_t lookup_column_amount) { return rows_amount; } constexpr static const std::size_t mul_rows_amount = 102; - constexpr static const std::size_t add_component_rows_amount = - add_component::get_rows_amount(11, 0); + constexpr static const std::size_t add_component_rows_amount = add_component::get_rows_amount(11, 0); constexpr static const std::size_t rows_amount = add_component_rows_amount + mul_rows_amount + 1; constexpr static const std::size_t gates_amount = 3; - const std::string component_name = "native curve multiplication by shifted const (https://arxiv.org/pdf/math/0208038.pdf)"; + const std::string component_name = + "native curve multiplication by shifted const (https://arxiv.org/pdf/math/0208038.pdf)"; constexpr static const std::size_t aux_bits_rows_amount = 44; - constexpr static const std::size_t aux_bits_start_row = rows_amount - aux_bits_rows_amount - 1; // = 59 - - constexpr static const typename BlueprintFieldType::value_type shifted_minus_one = variable_base_scalar_mul_shifted_consts::shifted_minus_one; - constexpr static const typename BlueprintFieldType::value_type shifted_zero = variable_base_scalar_mul_shifted_consts::shifted_zero; - constexpr static const typename BlueprintFieldType::value_type shifted_one = variable_base_scalar_mul_shifted_consts::shifted_one; - - constexpr static const typename BlueprintFieldType::value_type t_q = 0x224698fc0994a8dd8c46eb2100000001_cppui255; // q = 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001_cppui255 = 2**254 + t_q - constexpr static const typename BlueprintFieldType::value_type t_p = 0x224698fc094cf91b992d30ed00000001_cppui255; // p = 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000001_cppui255 = 2**254 + t_p (q > p) + constexpr static const std::size_t aux_bits_start_row = + rows_amount - aux_bits_rows_amount - 1; // = 59 + + constexpr static const typename BlueprintFieldType::value_type shifted_minus_one = + variable_base_scalar_mul_shifted_consts::shifted_minus_one; + constexpr static const typename BlueprintFieldType::value_type shifted_zero = + variable_base_scalar_mul_shifted_consts::shifted_zero; + constexpr static const typename BlueprintFieldType::value_type shifted_one = + variable_base_scalar_mul_shifted_consts::shifted_one; + + constexpr static const typename BlueprintFieldType::value_type t_q = + 0x224698fc0994a8dd8c46eb2100000001_cppui255; // q = + // 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001_cppui255 + // = 2**254 + t_q + constexpr static const typename BlueprintFieldType::value_type t_p = + 0x224698fc094cf91b992d30ed00000001_cppui255; // p = + // 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000001_cppui255 + // = 2**254 + t_p (q > p) constexpr static const typename BlueprintFieldType::value_type two = 2; struct input_type { @@ -172,11 +187,11 @@ namespace nil { var_ec_point T; var b; var b_high; - input_type(var_ec_point _T, var _b): T(_T), b(_b) {}; - input_type(var_ec_point _T, var _b, var _b_high): T(_T), b(_b), b_high(_b_high) {}; + input_type(var_ec_point _T, var _b) : T(_T), b(_b) {}; + input_type(var_ec_point _T, var _b, var _b_high) : T(_T), b(_b), b_high(_b_high) {}; std::vector> all_vars() { - if (std::is_same::value) { + if (std::is_same::value) { return {T.x, T.y, b, b_high}; } else { return {T.x, T.y, b}; @@ -187,13 +202,18 @@ namespace nil { struct result_type { var X; var Y; - result_type(const curve_element_variable_base_scalar_mul &component, input_type ¶ms, std::size_t start_row_index) { - X = var(component.W(0), start_row_index + component.rows_amount - 1, false, var::column_type::witness); - Y = var(component.W(1), start_row_index + component.rows_amount - 1, false, var::column_type::witness); + result_type(const curve_element_variable_base_scalar_mul &component, input_type ¶ms, + std::size_t start_row_index) { + X = var(component.W(0), start_row_index + component.rows_amount - 1, false, + var::column_type::witness); + Y = var(component.W(1), start_row_index + component.rows_amount - 1, false, + var::column_type::witness); } result_type(const curve_element_variable_base_scalar_mul &component, std::size_t start_row_index) { - X = var(component.W(0), start_row_index + component.rows_amount - 1, false, var::column_type::witness); - Y = var(component.W(1), start_row_index + component.rows_amount - 1, false, var::column_type::witness); + X = var(component.W(0), start_row_index + component.rows_amount - 1, false, + var::column_type::witness); + Y = var(component.W(1), start_row_index + component.rows_amount - 1, false, + var::column_type::witness); } std::vector> all_vars() { @@ -201,41 +221,45 @@ namespace nil { } }; - template - curve_element_variable_base_scalar_mul(ContainerType witness): - component_type(witness, {}, {}, get_manifest()){}; - - template - curve_element_variable_base_scalar_mul(WitnessContainerType witness, ConstantContainerType constant, PublicInputContainerType public_input): - component_type(witness, constant, public_input, get_manifest()){}; - - curve_element_variable_base_scalar_mul(std::initializer_list witnesses, - std::initializer_list constants, - std::initializer_list public_inputs): - component_type(witnesses, constants, public_inputs, get_manifest()){}; + template + curve_element_variable_base_scalar_mul(ContainerType witness) : + component_type(witness, {}, {}, get_manifest()) {}; + + template + curve_element_variable_base_scalar_mul(WitnessContainerType witness, ConstantContainerType constant, + PublicInputContainerType public_input) : + component_type(witness, constant, public_input, get_manifest()) {}; + + curve_element_variable_base_scalar_mul( + std::initializer_list + witnesses, + std::initializer_list + constants, + std::initializer_list + public_inputs) : component_type(witnesses, constants, public_inputs, get_manifest()) {}; }; template using plonk_curve_element_variable_base_scalar_mul = - curve_element_variable_base_scalar_mul< - crypto3::zk::snark::plonk_constraint_system, - CurveType - >; + curve_element_variable_base_scalar_mul, + CurveType>; template typename plonk_curve_element_variable_base_scalar_mul::result_type generate_assignments( const plonk_curve_element_variable_base_scalar_mul &component, assignment> &assignment, - const typename plonk_curve_element_variable_base_scalar_mul::input_type instance_input, + const typename plonk_curve_element_variable_base_scalar_mul::input_type instance_input, const std::uint32_t start_row_index) { - using add_component = typename plonk_curve_element_variable_base_scalar_mul< - BlueprintFieldType, CurveType>::add_component; + using add_component = + typename plonk_curve_element_variable_base_scalar_mul::add_component; typename BlueprintFieldType::value_type b = var_value(assignment, instance_input.b); typename BlueprintFieldType::value_type b_high; - if (std::is_same::value) { + if (std::is_same::value) { b_high = var_value(assignment, instance_input.b_high); } else { b_high = 0; @@ -243,7 +267,7 @@ namespace nil { typename BlueprintFieldType::value_type T_x = var_value(assignment, instance_input.T.x); typename BlueprintFieldType::value_type T_y = var_value(assignment, instance_input.T.y); typename CurveType::template g1_type::value_type T(T_x, - T_y); + T_y); std::array< typename CurveType::template g1_type::value_type, 6> @@ -259,10 +283,11 @@ namespace nil { typename BlueprintFieldType::value_type z_n2; typename BlueprintFieldType::value_type aux; - if (std::is_same::value) { + if (std::is_same::value) { z_n2 = integral_b; aux = z_n2 - component.t_q + component.two.pow(130); - typename BlueprintFieldType::integral_type intehral_b_high = typename BlueprintFieldType::integral_type(b_high.data); + typename BlueprintFieldType::integral_type intehral_b_high = + typename BlueprintFieldType::integral_type(b_high.data); if (intehral_b_high == 1) { bits[0] = 1; } @@ -279,18 +304,17 @@ namespace nil { typename BlueprintFieldType::value_type n = 0; typename BlueprintFieldType::value_type n_next = 0; - add_component unified_addition_instance( - {component.W(0), component.W(1), component.W(2), component.W(3), component.W(4), - component.W(5), component.W(6), component.W(7), component.W(8), component.W(9), - component.W(10)},{},{}); + add_component unified_addition_instance({component.W(0), component.W(1), component.W(2), component.W(3), + component.W(4), component.W(5), component.W(6), component.W(7), + component.W(8), component.W(9), component.W(10)}, + {}, {}); typename add_component::input_type addition_input = {{instance_input.T.x, instance_input.T.y}, - {instance_input.T.x, instance_input.T.y}}; + {instance_input.T.x, instance_input.T.y}}; typename add_component::result_type addition_res = generate_assignments(unified_addition_instance, assignment, addition_input, start_row_index); - typename CurveType::template g1_type::value_type T_doubled(var_value(assignment, addition_res.X), var_value(assignment, addition_res.Y)); @@ -309,8 +333,8 @@ namespace nil { assignment.witness(component.W(3), i) = P[0].Y; assignment.witness(component.W(4), i) = n; n_next = 32 * n + 16 * bits[((i - j) / 2) * 5] + 8 * bits[((i - j) / 2) * 5 + 1] + - 4 * bits[((i - j) / 2) * 5 + 2] + 2 * bits[((i - j) / 2) * 5 + 3] + - bits[((i - j) / 2) * 5 + 4]; + 4 * bits[((i - j) / 2) * 5 + 2] + 2 * bits[((i - j) / 2) * 5 + 3] + + bits[((i - j) / 2) * 5 + 4]; assignment.witness(component.W(5), i) = n_next; Q.X = T.X; Q.Y = (2 * bits[((i - j) / 2) * 5] - 1) * T.Y; @@ -345,33 +369,40 @@ namespace nil { assignment.witness(component.W(6), i + 1) = bits[((i - j) / 2) * 5 + 4]; } - // assign additional bits of aux for the range check (integral_b < q) or (b_high * 2^254 + integral_b < q) + // assign additional bits of aux for the range check (integral_b < q) or (b_high * 2^254 + integral_b < + // q) typename BlueprintFieldType::value_type u_next = 0; typename BlueprintFieldType::value_type u0, u1; - for (std::size_t i = start_row_index + component.aux_bits_start_row; i <= start_row_index + component.aux_bits_start_row + component.aux_bits_rows_amount - 3; i = i + 2) { + for (std::size_t i = start_row_index + component.aux_bits_start_row; + i <= start_row_index + component.aux_bits_start_row + component.aux_bits_rows_amount - 3; + i = i + 2) { assignment.witness(component.W(6), i) = u_next; const std::size_t ind = 125 + ((i - component.aux_bits_start_row - start_row_index) / 2) * 6; - u0 = 4 * aux_bits[ind] + 2 * aux_bits[ind+1] + aux_bits[ind+2]; - u1 = 4 * aux_bits[ind+3] + 2 * aux_bits[ind+4] + aux_bits[ind+5]; + u0 = 4 * aux_bits[ind] + 2 * aux_bits[ind + 1] + aux_bits[ind + 2]; + u1 = 4 * aux_bits[ind + 3] + 2 * aux_bits[ind + 4] + aux_bits[ind + 5]; u_next = 64 * u_next + 8 * u0 + u1; - assignment.witness(component.W(12), i+1) = u0; - assignment.witness(component.W(13), i+1) = u1; - assignment.witness(component.W(14), i+1) = u_next; + assignment.witness(component.W(12), i + 1) = u0; + assignment.witness(component.W(13), i + 1) = u1; + assignment.witness(component.W(14), i + 1) = u_next; } - assignment.witness(component.W(6), start_row_index + component.aux_bits_start_row + component.aux_bits_rows_amount - 2) = u_next; + assignment.witness(component.W(6), start_row_index + component.aux_bits_start_row + + component.aux_bits_rows_amount - 2) = u_next; const std::size_t ind = 125 + (component.aux_bits_rows_amount / 2 - 1) * 6; - u0 = 4 * aux_bits[ind] + 2 * aux_bits[ind+1] + aux_bits[ind+2]; - u1 = aux_bits[ind+3]; + u0 = 4 * aux_bits[ind] + 2 * aux_bits[ind + 1] + aux_bits[ind + 2]; + u1 = aux_bits[ind + 3]; u_next = 16 * u_next + 2 * u0 + u1; - assignment.witness(component.W(12), start_row_index + component.aux_bits_start_row + component.aux_bits_rows_amount - 1) = u0; - assignment.witness(component.W(13), start_row_index + component.aux_bits_start_row + component.aux_bits_rows_amount - 1) = u1; - assignment.witness(component.W(14), start_row_index + component.aux_bits_start_row + component.aux_bits_rows_amount - 1) = u_next; + assignment.witness(component.W(12), start_row_index + component.aux_bits_start_row + + component.aux_bits_rows_amount - 1) = u0; + assignment.witness(component.W(13), start_row_index + component.aux_bits_start_row + + component.aux_bits_rows_amount - 1) = u1; + assignment.witness(component.W(14), start_row_index + component.aux_bits_start_row + + component.aux_bits_rows_amount - 1) = u_next; assignment.witness(component.W(9), start_row_index + component.rows_amount - 1) = bits[0]; typename BlueprintFieldType::value_type e2 = 0; typename BlueprintFieldType::value_type cur_pow = 1; for (std::size_t l = 130; l <= 254; l = l + 1) { - e2 += + bits[254-l] * cur_pow; + e2 += +bits[254 - l] * cur_pow; cur_pow = cur_pow * 2; } assignment.witness(component.W(10), start_row_index + component.rows_amount - 1) = e2; @@ -379,17 +410,21 @@ namespace nil { assignment.witness(component.W(12), start_row_index + component.rows_amount - 1) = aux; // assign last 3 rows - typename BlueprintFieldType::value_type m = ((n_next - component.shifted_minus_one)* - (n_next - component.shifted_zero)*(n_next - component.shifted_one)); - typename BlueprintFieldType::value_type t0 = ( m == 0 ? 0 : m.inversed()); - typename BlueprintFieldType::value_type t1 = ((n_next - component.shifted_minus_one) == 0) ? 0 : (n_next - component.shifted_minus_one).inversed(); - typename BlueprintFieldType::value_type t2 = ((n_next - component.shifted_one) == 0) ? 0 : (n_next - component.shifted_one).inversed(); + typename BlueprintFieldType::value_type m = + ((n_next - component.shifted_minus_one) * (n_next - component.shifted_zero) * + (n_next - component.shifted_one)); + typename BlueprintFieldType::value_type t0 = (m == 0 ? 0 : m.inversed()); + typename BlueprintFieldType::value_type t1 = ((n_next - component.shifted_minus_one) == 0) ? + 0 : + (n_next - component.shifted_minus_one).inversed(); + typename BlueprintFieldType::value_type t2 = + ((n_next - component.shifted_one) == 0) ? 0 : (n_next - component.shifted_one).inversed(); typename BlueprintFieldType::value_type x; typename BlueprintFieldType::value_type y; if (n_next == component.shifted_minus_one) { x = T.X; y = -T.Y; - } else { + } else { if (n_next == component.shifted_zero) { x = 0; y = 0; @@ -413,7 +448,9 @@ namespace nil { assignment.witness(component.W(0), start_row_index + component.rows_amount - 1) = x; assignment.witness(component.W(1), start_row_index + component.rows_amount - 1) = y; - return typename plonk_curve_element_variable_base_scalar_mul::result_type(component, start_row_index); + return + typename plonk_curve_element_variable_base_scalar_mul::result_type( + component, start_row_index); } template @@ -422,42 +459,47 @@ namespace nil { const plonk_curve_element_variable_base_scalar_mul &component, circuit> &bp, assignment> &assignment, - const typename plonk_curve_element_variable_base_scalar_mul::input_type &instance_input, + const typename plonk_curve_element_variable_base_scalar_mul::input_type &instance_input, const std::uint32_t start_row_index) { - using add_component = typename plonk_curve_element_variable_base_scalar_mul< - BlueprintFieldType, CurveType>::add_component; + using add_component = + typename plonk_curve_element_variable_base_scalar_mul::add_component; generate_assignments_constants(component, bp, assignment, instance_input, start_row_index); auto selectors = generate_gates(component, bp, assignment, instance_input); assignment.enable_selector(selectors[0], start_row_index + component.add_component_rows_amount, - start_row_index + component.rows_amount - 4, 2); + start_row_index + component.rows_amount - 4, 2); assignment.enable_selector(selectors[1], start_row_index + component.rows_amount - 2); - assignment.enable_selector(selectors[2], start_row_index + component.aux_bits_start_row, - start_row_index + component.aux_bits_start_row + component.aux_bits_rows_amount - 4, 2); + assignment.enable_selector( + selectors[2], start_row_index + component.aux_bits_start_row, + start_row_index + component.aux_bits_start_row + component.aux_bits_rows_amount - 4, 2); typename add_component::input_type addition_input = {{instance_input.T.x, instance_input.T.y}, - {instance_input.T.x, instance_input.T.y}}; + {instance_input.T.x, instance_input.T.y}}; - add_component unified_addition_instance( - {component.W(0), component.W(1), component.W(2), component.W(3), component.W(4), - component.W(5), component.W(6), component.W(7), component.W(8), component.W(9), - component.W(10)}, {}, {}); + add_component unified_addition_instance({component.W(0), component.W(1), component.W(2), component.W(3), + component.W(4), component.W(5), component.W(6), component.W(7), + component.W(8), component.W(9), component.W(10)}, + {}, {}); generate_circuit(unified_addition_instance, bp, assignment, addition_input, start_row_index); generate_copy_constraints(component, bp, assignment, instance_input, start_row_index); - return typename plonk_curve_element_variable_base_scalar_mul::result_type(component, start_row_index); + return + typename plonk_curve_element_variable_base_scalar_mul::result_type( + component, start_row_index); } template - std::array generate_gates( - const plonk_curve_element_variable_base_scalar_mul &component, - circuit> &bp, - assignment> &assignment, - const typename plonk_curve_element_variable_base_scalar_mul::input_type instance_input) { + std::array generate_gates( + const plonk_curve_element_variable_base_scalar_mul &component, + circuit> &bp, + assignment> &assignment, + const typename plonk_curve_element_variable_base_scalar_mul::input_type + instance_input) { using ArithmetizationType = crypto3::zk::snark::plonk_constraint_system; using var = typename curve_element_variable_base_scalar_mul::var; @@ -485,75 +527,91 @@ namespace nil { (var(component.W(14), 0) - (2 * var(component.W(6), +1) - 1) * var(component.W(1), 0)); auto constraint_6 = - (2 * var(component.W(3), 0) - var(component.W(7), 1) * (2 * var(component.W(2), 0) - - var(component.W(7), 1).pow(2) + var(component.W(0), 0))) * - (2 * var(component.W(3), 0) - var(component.W(7), 1) * (2 * var(component.W(2), 0) - - var(component.W(7), 1).pow(2) + var(component.W(0), 0))) - + (2 * var(component.W(3), 0) - + var(component.W(7), 1) * + (2 * var(component.W(2), 0) - var(component.W(7), 1).pow(2) + var(component.W(0), 0))) * + (2 * var(component.W(3), 0) - + var(component.W(7), 1) * + (2 * var(component.W(2), 0) - var(component.W(7), 1).pow(2) + var(component.W(0), 0))) - ((2 * var(component.W(2), 0) - var(component.W(7), 1).pow(2) + var(component.W(0), 0)) * (2 * var(component.W(2), 0) - var(component.W(7), 1).pow(2) + var(component.W(0), 0)) * (var(component.W(7), 0) - var(component.W(0), 0) + var(component.W(7), 1).pow(2))); auto constraint_7 = - (2 * var(component.W(8), 0) - var(component.W(8), 1) * (2 * var(component.W(7), 0) - - var(component.W(8), 1).pow(2) + var(component.W(0), 0))) * - (2 * var(component.W(8), 0) - var(component.W(8), 1) * (2 * var(component.W(7), 0) - - var(component.W(8), 1).pow(2) + var(component.W(0), 0))) - + (2 * var(component.W(8), 0) - + var(component.W(8), 1) * + (2 * var(component.W(7), 0) - var(component.W(8), 1).pow(2) + var(component.W(0), 0))) * + (2 * var(component.W(8), 0) - + var(component.W(8), 1) * + (2 * var(component.W(7), 0) - var(component.W(8), 1).pow(2) + var(component.W(0), 0))) - ((2 * var(component.W(7), 0) - var(component.W(8), 1).pow(2) + var(component.W(0), 0)) * (2 * var(component.W(7), 0) - var(component.W(8), 1).pow(2) + var(component.W(0), 0)) * (var(component.W(9), 0) - var(component.W(0), 0) + var(component.W(8), 1).pow(2))); auto constraint_8 = - (2 * var(component.W(10), 0) - var(component.W(9), 1) * (2 * var(component.W(9), 0) - - var(component.W(9), 1).pow(2) + var(component.W(0), 0))) * - (2 * var(component.W(10), 0) - var(component.W(9), 1) * (2 * var(component.W(9), 0) - - var(component.W(9), 1).pow(2) + var(component.W(0), 0))) - + (2 * var(component.W(10), 0) - + var(component.W(9), 1) * + (2 * var(component.W(9), 0) - var(component.W(9), 1).pow(2) + var(component.W(0), 0))) * + (2 * var(component.W(10), 0) - + var(component.W(9), 1) * + (2 * var(component.W(9), 0) - var(component.W(9), 1).pow(2) + var(component.W(0), 0))) - ((2 * var(component.W(9), 0) - var(component.W(9), 1).pow(2) + var(component.W(0), 0)) * (2 * var(component.W(9), 0) - var(component.W(9), 1).pow(2) + var(component.W(0), 0)) * (var(component.W(11), 0) - var(component.W(0), 0) + var(component.W(9), 1).pow(2))); auto constraint_9 = - (2 * var(component.W(12), 0) - var(component.W(10), +1) * (2 * var(component.W(11), 0) - - var(component.W(10), +1).pow(2) + var(component.W(0), 0))) * - (2 * var(component.W(12), 0) - var(component.W(10), +1) * (2 * var(component.W(11), 0) - - var(component.W(10), +1).pow(2) + var(component.W(0), 0))) - + (2 * var(component.W(12), 0) - + var(component.W(10), +1) * + (2 * var(component.W(11), 0) - var(component.W(10), +1).pow(2) + var(component.W(0), 0))) * + (2 * var(component.W(12), 0) - + var(component.W(10), +1) * + (2 * var(component.W(11), 0) - var(component.W(10), +1).pow(2) + var(component.W(0), 0))) - ((2 * var(component.W(11), 0) - var(component.W(10), +1).pow(2) + var(component.W(0), 0)) * (2 * var(component.W(11), 0) - var(component.W(10), +1).pow(2) + var(component.W(0), 0)) * (var(component.W(13), 0) - var(component.W(0), 0) + var(component.W(10), +1).pow(2))); auto constraint_10 = - (2 * var(component.W(14), 0) - var(component.W(11), +1) * (2 * var(component.W(13), 0) - - var(component.W(11), +1).pow(2) + var(component.W(0), 0))) * - (2 * var(component.W(14), 0) - var(component.W(11), +1) * (2 * var(component.W(13), 0) - - var(component.W(11), +1).pow(2) + var(component.W(0), 0))) - + (2 * var(component.W(14), 0) - + var(component.W(11), +1) * + (2 * var(component.W(13), 0) - var(component.W(11), +1).pow(2) + var(component.W(0), 0))) * + (2 * var(component.W(14), 0) - + var(component.W(11), +1) * + (2 * var(component.W(13), 0) - var(component.W(11), +1).pow(2) + var(component.W(0), 0))) - ((2 * var(component.W(13), 0) - var(component.W(11), +1).pow(2) + var(component.W(0), 0)) * (2 * var(component.W(13), 0) - var(component.W(11), +1).pow(2) + var(component.W(0), 0)) * (var(component.W(0), 1) - var(component.W(0), 0) + var(component.W(11), +1).pow(2))); auto constraint_11 = - (var(component.W(8), 0) + var(component.W(3), 0)) * (2 * var(component.W(2), 0) - var(component.W(7), +1).pow(2) + var(component.W(0), 0)) - + (var(component.W(8), 0) + var(component.W(3), 0)) * + (2 * var(component.W(2), 0) - var(component.W(7), +1).pow(2) + var(component.W(0), 0)) - ((var(component.W(2), 0) - var(component.W(7), 0)) * - (2 * var(component.W(3), 0) - var(component.W(7), +1) * (2 * var(component.W(2), 0) - - var(component.W(7), +1).pow(2) + var(component.W(0), 0)))); + (2 * var(component.W(3), 0) - + var(component.W(7), +1) * + (2 * var(component.W(2), 0) - var(component.W(7), +1).pow(2) + var(component.W(0), 0)))); auto constraint_12 = - (var(component.W(10), 0) + var(component.W(8), 0)) * (2 * var(component.W(7), 0) - - var(component.W(8), +1).pow(2) + var(component.W(0), 0)) - + (var(component.W(10), 0) + var(component.W(8), 0)) * + (2 * var(component.W(7), 0) - var(component.W(8), +1).pow(2) + var(component.W(0), 0)) - ((var(component.W(7), 0) - var(component.W(9), 0)) * - (2 * var(component.W(8), 0) - var(component.W(8), +1) * - (2 * var(component.W(7), 0) - var(component.W(8), +1).pow(2) + var(component.W(0), 0)))); + (2 * var(component.W(8), 0) - + var(component.W(8), +1) * + (2 * var(component.W(7), 0) - var(component.W(8), +1).pow(2) + var(component.W(0), 0)))); auto constraint_13 = - (var(component.W(12), 0) + var(component.W(10), 0)) * (2 * var(component.W(9), 0) - - var(component.W(9), +1).pow(2) + var(component.W(0), 0)) - - ((var(component.W(9), 0) - var(component.W(11), 0)) * - (2 * var(component.W(10), 0) - var(component.W(9), +1) * (2 * var(component.W(9), 0) - - var(component.W(9), +1).pow(2) + var(component.W(0), 0)))); + (var(component.W(12), 0) + var(component.W(10), 0)) * + (2 * var(component.W(9), 0) - var(component.W(9), +1).pow(2) + var(component.W(0), 0)) - + ((var(component.W(9), 0) - var(component.W(11), 0)) * + (2 * var(component.W(10), 0) - + var(component.W(9), +1) * + (2 * var(component.W(9), 0) - var(component.W(9), +1).pow(2) + var(component.W(0), 0)))); auto constraint_14 = - (var(component.W(14), 0) + var(component.W(12), 0)) * (2 * var(component.W(11), 0) - - var(component.W(10), +1).pow(2) + var(component.W(0), 0)) - + (var(component.W(14), 0) + var(component.W(12), 0)) * + (2 * var(component.W(11), 0) - var(component.W(10), +1).pow(2) + var(component.W(0), 0)) - ((var(component.W(11), 0) - var(component.W(13), 0)) * - (2 * var(component.W(12), 0) - var(component.W(10), +1) * - (2 * var(component.W(11), 0) - var(component.W(10), +1).pow(2) + var(component.W(0), 0)))); + (2 * var(component.W(12), 0) - + var(component.W(10), +1) * + (2 * var(component.W(11), 0) - var(component.W(10), +1).pow(2) + var(component.W(0), 0)))); auto constraint_15 = - (var(component.W(1), +1) + var(component.W(14), 0)) * (2 * var(component.W(13), 0) - - var(component.W(11), +1).pow(2) + var(component.W(0), 0)) - + (var(component.W(1), +1) + var(component.W(14), 0)) * + (2 * var(component.W(13), 0) - var(component.W(11), +1).pow(2) + var(component.W(0), 0)) - ((var(component.W(13), 0) - var(component.W(0), +1)) * - (2 * var(component.W(14), 0) - var(component.W(11), +1) * (2 * var(component.W(13), 0) - - var(component.W(11), +1).pow(2) + var(component.W(0), 0)))); + (2 * var(component.W(14), 0) - + var(component.W(11), +1) * + (2 * var(component.W(13), 0) - var(component.W(11), +1).pow(2) + var(component.W(0), 0)))); auto constraint_16 = var(component.W(5), 0) - @@ -561,11 +619,10 @@ namespace nil { 4 * var(component.W(4), +1) + 2 * var(component.W(5), +1) + var(component.W(6), +1)); std::size_t selector_index_1 = bp.add_gate( - {bit_check_1, bit_check_2, bit_check_3, bit_check_4, bit_check_5, - constraint_1, constraint_2, constraint_3, constraint_4, constraint_5, - constraint_6, constraint_7, constraint_8, constraint_9, constraint_10, - constraint_11, constraint_12, constraint_13, constraint_14, constraint_15, - constraint_16}); + {bit_check_1, bit_check_2, bit_check_3, bit_check_4, bit_check_5, constraint_1, + constraint_2, constraint_3, constraint_4, constraint_5, constraint_6, constraint_7, + constraint_8, constraint_9, constraint_10, constraint_11, constraint_12, constraint_13, + constraint_14, constraint_15, constraint_16}); bit_check_1 = var(component.W(2), 0) * (1 - var(component.W(2), 0)); bit_check_2 = var(component.W(3), 0) * (1 - var(component.W(3), 0)); @@ -573,139 +630,158 @@ namespace nil { bit_check_4 = var(component.W(5), 0) * (1 - var(component.W(5), 0)); bit_check_5 = var(component.W(6), 0) * (1 - var(component.W(6), 0)); - constraint_1 = - (var(component.W(2), -1) - var(component.W(0), -1)) * var(component.W(7), 0) - - (var(component.W(3), -1) - (2 * var(component.W(2), 0) - 1) * var(component.W(1), -1)); - constraint_2 = - (var(component.W(7), -1) - var(component.W(0), -1)) * var(component.W(8), 0) - - (var(component.W(8), -1) - (2 * var(component.W(3), 0) - 1) * var(component.W(1), -1)); - constraint_3 = - (var(component.W(9), -1) - var(component.W(0), -1)) * var(component.W(9), 0) - - (var(component.W(10), -1) - (2 * var(component.W(4), 0) - 1) * var(component.W(1), -1)); - constraint_4 = - (var(component.W(11), -1) - var(component.W(0), -1)) * var(component.W(10), 0) - - (var(component.W(12), -1) - (2 * var(component.W(5), 0) - 1) * var(component.W(1), -1)); - constraint_5 = - (var(component.W(13), -1) - var(component.W(0), -1)) * var(component.W(11), 0) - - (var(component.W(14), -1) - (2 * var(component.W(6), 0) - 1) * var(component.W(1), -1)); + constraint_1 = (var(component.W(2), -1) - var(component.W(0), -1)) * var(component.W(7), 0) - + (var(component.W(3), -1) - (2 * var(component.W(2), 0) - 1) * var(component.W(1), -1)); + constraint_2 = (var(component.W(7), -1) - var(component.W(0), -1)) * var(component.W(8), 0) - + (var(component.W(8), -1) - (2 * var(component.W(3), 0) - 1) * var(component.W(1), -1)); + constraint_3 = (var(component.W(9), -1) - var(component.W(0), -1)) * var(component.W(9), 0) - + (var(component.W(10), -1) - (2 * var(component.W(4), 0) - 1) * var(component.W(1), -1)); + constraint_4 = (var(component.W(11), -1) - var(component.W(0), -1)) * var(component.W(10), 0) - + (var(component.W(12), -1) - (2 * var(component.W(5), 0) - 1) * var(component.W(1), -1)); + constraint_5 = (var(component.W(13), -1) - var(component.W(0), -1)) * var(component.W(11), 0) - + (var(component.W(14), -1) - (2 * var(component.W(6), 0) - 1) * var(component.W(1), -1)); constraint_6 = - (2 * var(component.W(3), -1) - var(component.W(7), 0) * (2 * var(component.W(2), -1) - - var(component.W(7), 0).pow(2) + var(component.W(0), -1))) * - (2 * var(component.W(3), -1) - var(component.W(7), 0) * (2 * var(component.W(2), -1) - - var(component.W(7), 0).pow(2) + var(component.W(0), -1))) - + (2 * var(component.W(3), -1) - + var(component.W(7), 0) * + (2 * var(component.W(2), -1) - var(component.W(7), 0).pow(2) + var(component.W(0), -1))) * + (2 * var(component.W(3), -1) - + var(component.W(7), 0) * + (2 * var(component.W(2), -1) - var(component.W(7), 0).pow(2) + var(component.W(0), -1))) - ((2 * var(component.W(2), -1) - var(component.W(7), 0).pow(2) + var(component.W(0), -1)) * (2 * var(component.W(2), -1) - var(component.W(7), 0).pow(2) + var(component.W(0), -1)) * (var(component.W(7), -1) - var(component.W(0), -1) + var(component.W(7), 0).pow(2))); constraint_7 = - (2 * var(component.W(8), -1) - var(component.W(8), 0) * (2 * var(component.W(7), -1) - - var(component.W(8), 0).pow(2) + var(component.W(0), -1))) * - (2 * var(component.W(8), -1) - var(component.W(8), 0) * (2 * var(component.W(7), -1) - - var(component.W(8), 0).pow(2) + var(component.W(0), -1))) - + (2 * var(component.W(8), -1) - + var(component.W(8), 0) * + (2 * var(component.W(7), -1) - var(component.W(8), 0).pow(2) + var(component.W(0), -1))) * + (2 * var(component.W(8), -1) - + var(component.W(8), 0) * + (2 * var(component.W(7), -1) - var(component.W(8), 0).pow(2) + var(component.W(0), -1))) - ((2 * var(component.W(7), -1) - var(component.W(8), 0).pow(2) + var(component.W(0), -1)) * (2 * var(component.W(7), -1) - var(component.W(8), 0).pow(2) + var(component.W(0), -1)) * (var(component.W(9), -1) - var(component.W(0), -1) + var(component.W(8), 0).pow(2))); constraint_8 = - (2 * var(component.W(10), -1) - var(component.W(9), 0) * (2 * var(component.W(9), -1) - - var(component.W(9), 0).pow(2) + var(component.W(0), -1))) * - (2 * var(component.W(10), -1) - var(component.W(9), 0) * (2 * var(component.W(9), -1) - - var(component.W(9), 0).pow(2) + var(component.W(0), -1))) - + (2 * var(component.W(10), -1) - + var(component.W(9), 0) * + (2 * var(component.W(9), -1) - var(component.W(9), 0).pow(2) + var(component.W(0), -1))) * + (2 * var(component.W(10), -1) - + var(component.W(9), 0) * + (2 * var(component.W(9), -1) - var(component.W(9), 0).pow(2) + var(component.W(0), -1))) - ((2 * var(component.W(9), -1) - var(component.W(9), 0).pow(2) + var(component.W(0), -1)) * (2 * var(component.W(9), -1) - var(component.W(9), 0).pow(2) + var(component.W(0), -1)) * (var(component.W(11), -1) - var(component.W(0), -1) + var(component.W(9), 0).pow(2))); constraint_9 = - ((2 * var(component.W(12), -1) - var(component.W(10), 0) * (2 * var(component.W(11), -1) - - var(component.W(10), 0).pow(2) + var(component.W(0), -1))) * - (2 * var(component.W(12), -1) - var(component.W(10), 0) * (2 * var(component.W(11), -1) - - var(component.W(10), 0).pow(2) + var(component.W(0), -1))) - - ((2 * var(component.W(11), -1) - var(component.W(10), 0).pow(2) + var(component.W(0), -1)) * - (2 * var(component.W(11), -1) - var(component.W(10), 0).pow(2) + var(component.W(0), -1)) * - (var(component.W(13), -1) - var(component.W(0), -1) + var(component.W(10), 0).pow(2)))) * - var(component.W(8), +1) * var(component.W(2), +1); + ((2 * var(component.W(12), -1) - + var(component.W(10), 0) * + (2 * var(component.W(11), -1) - var(component.W(10), 0).pow(2) + var(component.W(0), -1))) * + (2 * var(component.W(12), -1) - + var(component.W(10), 0) * (2 * var(component.W(11), -1) - var(component.W(10), 0).pow(2) + + var(component.W(0), -1))) - + ((2 * var(component.W(11), -1) - var(component.W(10), 0).pow(2) + var(component.W(0), -1)) * + (2 * var(component.W(11), -1) - var(component.W(10), 0).pow(2) + var(component.W(0), -1)) * + (var(component.W(13), -1) - var(component.W(0), -1) + var(component.W(10), 0).pow(2)))) * + var(component.W(8), +1) * var(component.W(2), +1); constraint_10 = - ((2 * var(component.W(14), -1) - var(component.W(11), 0) * (2 * var(component.W(13), -1) - - var(component.W(11), 0).pow(2) + var(component.W(0), -1))) * - (2 * var(component.W(14), -1) - var(component.W(11), 0) * (2 * var(component.W(13), -1) - - var(component.W(11), 0).pow(2) + var(component.W(0), -1))) - - ((2 * var(component.W(13), -1) - var(component.W(11), 0).pow(2) + var(component.W(0), -1)) * - (2 * var(component.W(13), -1) - var(component.W(11), 0).pow(2) + var(component.W(0), -1)) * - (var(component.W(0), 0) - var(component.W(0), -1) + var(component.W(11), 0).pow(2)))) * + ((2 * var(component.W(14), -1) - + var(component.W(11), 0) * + (2 * var(component.W(13), -1) - var(component.W(11), 0).pow(2) + var(component.W(0), -1))) * + (2 * var(component.W(14), -1) - + var(component.W(11), 0) * (2 * var(component.W(13), -1) - var(component.W(11), 0).pow(2) + + var(component.W(0), -1))) - + ((2 * var(component.W(13), -1) - var(component.W(11), 0).pow(2) + var(component.W(0), -1)) * + (2 * var(component.W(13), -1) - var(component.W(11), 0).pow(2) + var(component.W(0), -1)) * + (var(component.W(0), 0) - var(component.W(0), -1) + var(component.W(11), 0).pow(2)))) * var(component.W(8), +1) * var(component.W(2), +1); constraint_11 = (var(component.W(8), -1) + var(component.W(3), -1)) * - (2 * var(component.W(2), -1) - var(component.W(7), 0).pow(2) + var(component.W(0), -1)) - + (2 * var(component.W(2), -1) - var(component.W(7), 0).pow(2) + var(component.W(0), -1)) - ((var(component.W(2), -1) - var(component.W(7), -1)) * - (2 * var(component.W(3), -1) - var(component.W(7), 0) * (2 * var(component.W(2), -1) - - var(component.W(7), 0).pow(2) + var(component.W(0), -1)))); + (2 * var(component.W(3), -1) - + var(component.W(7), 0) * + (2 * var(component.W(2), -1) - var(component.W(7), 0).pow(2) + var(component.W(0), -1)))); constraint_12 = - (var(component.W(10), -1) + var(component.W(8), -1)) * (2 * var(component.W(7), -1) - - var(component.W(8), 0).pow(2) + var(component.W(0), -1)) - + (var(component.W(10), -1) + var(component.W(8), -1)) * + (2 * var(component.W(7), -1) - var(component.W(8), 0).pow(2) + var(component.W(0), -1)) - ((var(component.W(7), -1) - var(component.W(9), -1)) * - (2 * var(component.W(8), -1) - var(component.W(8), 0) * (2 * var(component.W(7), -1) - - var(component.W(8), 0).pow(2) + var(component.W(0), -1)))); + (2 * var(component.W(8), -1) - + var(component.W(8), 0) * + (2 * var(component.W(7), -1) - var(component.W(8), 0).pow(2) + var(component.W(0), -1)))); constraint_13 = - (var(component.W(12), -1) + var(component.W(10), -1)) * (2 * var(component.W(9), -1) - - var(component.W(9), 0).pow(2) + var(component.W(0), -1)) - + (var(component.W(12), -1) + var(component.W(10), -1)) * + (2 * var(component.W(9), -1) - var(component.W(9), 0).pow(2) + var(component.W(0), -1)) - ((var(component.W(9), -1) - var(component.W(11), -1)) * - (2 * var(component.W(10), -1) - var(component.W(9), 0) * (2 * var(component.W(9), -1) - - var(component.W(9), 0).pow(2) + var(component.W(0), -1)))); + (2 * var(component.W(10), -1) - + var(component.W(9), 0) * + (2 * var(component.W(9), -1) - var(component.W(9), 0).pow(2) + var(component.W(0), -1)))); constraint_14 = - ((var(component.W(14), -1) + var(component.W(12), -1)) * (2 * var(component.W(11), -1) - - var(component.W(10), 0).pow(2) + var(component.W(0), -1)) - - ((var(component.W(11), -1) - var(component.W(13), -1)) * - (2 * var(component.W(12), -1) - - var(component.W(10), 0) * (2 * var(component.W(11), -1) - var(component.W(10), 0).pow(2) + var(component.W(0), -1))))) * + ((var(component.W(14), -1) + var(component.W(12), -1)) * + (2 * var(component.W(11), -1) - var(component.W(10), 0).pow(2) + var(component.W(0), -1)) - + ((var(component.W(11), -1) - var(component.W(13), -1)) * + (2 * var(component.W(12), -1) - + var(component.W(10), 0) * (2 * var(component.W(11), -1) - var(component.W(10), 0).pow(2) + + var(component.W(0), -1))))) * var(component.W(8), +1) * var(component.W(2), +1); constraint_15 = - ((var(component.W(1), 0) + var(component.W(14), -1)) * (2 * var(component.W(13), -1) - var(component.W(11), 0).pow(2) + var(component.W(0), -1)) - - ((var(component.W(13), -1) - var(component.W(0), 0)) * - (2 * var(component.W(14), -1) - - var(component.W(11), 0) * (2 * var(component.W(13), -1) - var(component.W(11), 0).pow(2) + var(component.W(0), -1))))) * + ((var(component.W(1), 0) + var(component.W(14), -1)) * + (2 * var(component.W(13), -1) - var(component.W(11), 0).pow(2) + var(component.W(0), -1)) - + ((var(component.W(13), -1) - var(component.W(0), 0)) * + (2 * var(component.W(14), -1) - + var(component.W(11), 0) * (2 * var(component.W(13), -1) - var(component.W(11), 0).pow(2) + + var(component.W(0), -1))))) * var(component.W(8), +1) * var(component.W(2), +1); constraint_16 = - var(component.W(5), -1) - (32 * (var(component.W(4), -1)) + 16 * var(component.W(2), 0) + 8 * var(component.W(3), 0) + - 4 * var(component.W(4), 0) + 2 * var(component.W(5), 0) + var(component.W(6), 0)); - - auto constraint_17 = (var(component.W(8), +1)*var(component.W(2), +1) - 1) * var(component.W(8), +1); - auto constraint_18 = ((var(component.W(5), +1) - component.shifted_minus_one) - *var(component.W(3), +1) - 1) * (var(component.W(5), +1) - component.shifted_minus_one); - auto constraint_19 = ((var(component.W(5), +1) - component.shifted_one) - *var(component.W(4), +1) - 1) * (var(component.W(5), +1) - component.shifted_one); - auto constraint_20 = (var(component.W(8), +1)*var(component.W(2), +1)*var(component.W(0), 0)) + - ((var(component.W(5), +1) - component.shifted_minus_one) - *var(component.W(3), +1) - (var(component.W(5), +1) - component.shifted_one) - *var(component.W(4), +1))* ((var(component.W(5), +1) - component.shifted_minus_one) - *var(component.W(3), +1) - (var(component.W(5), +1) - component.shifted_one) - *var(component.W(4), +1)) * var(component.W(6), +1) - var(component.W(0), +1); - auto constraint_21 = (var(component.W(8), +1)*var(component.W(2), +1)*var(component.W(1), 0)) + - ((var(component.W(5), +1) - component.shifted_minus_one) - *var(component.W(3), +1) - (var(component.W(5), +1) - component.shifted_one) - *var(component.W(4), +1)) * var(component.W(7), +1) - var(component.W(1), +1); - auto constraint_22 = var(component.W(8), +1) - ((var(component.W(5), +1) - component.shifted_minus_one) - *(var(component.W(5), +1) - component.shifted_zero)* - (var(component.W(5), +1) - component.shifted_one)); + var(component.W(5), -1) - + (32 * (var(component.W(4), -1)) + 16 * var(component.W(2), 0) + 8 * var(component.W(3), 0) + + 4 * var(component.W(4), 0) + 2 * var(component.W(5), 0) + var(component.W(6), 0)); + + auto constraint_17 = (var(component.W(8), +1) * var(component.W(2), +1) - 1) * var(component.W(8), +1); + auto constraint_18 = + ((var(component.W(5), +1) - component.shifted_minus_one) * var(component.W(3), +1) - 1) * + (var(component.W(5), +1) - component.shifted_minus_one); + auto constraint_19 = ((var(component.W(5), +1) - component.shifted_one) * var(component.W(4), +1) - 1) * + (var(component.W(5), +1) - component.shifted_one); + auto constraint_20 = + (var(component.W(8), +1) * var(component.W(2), +1) * var(component.W(0), 0)) + + ((var(component.W(5), +1) - component.shifted_minus_one) * var(component.W(3), +1) - + (var(component.W(5), +1) - component.shifted_one) * var(component.W(4), +1)) * + ((var(component.W(5), +1) - component.shifted_minus_one) * var(component.W(3), +1) - + (var(component.W(5), +1) - component.shifted_one) * var(component.W(4), +1)) * + var(component.W(6), +1) - + var(component.W(0), +1); + auto constraint_21 = + (var(component.W(8), +1) * var(component.W(2), +1) * var(component.W(1), 0)) + + ((var(component.W(5), +1) - component.shifted_minus_one) * var(component.W(3), +1) - + (var(component.W(5), +1) - component.shifted_one) * var(component.W(4), +1)) * + var(component.W(7), +1) - + var(component.W(1), +1); + auto constraint_22 = + var(component.W(8), +1) - ((var(component.W(5), +1) - component.shifted_minus_one) * + (var(component.W(5), +1) - component.shifted_zero) * + (var(component.W(5), +1) - component.shifted_one)); // additional range-check constraints: // check u_0 = 3-bit chunk of aux - auto constraint_23 = - var(component.W(12), 0) * (var(component.W(12), 0) - 1) * (var(component.W(12), 0) - 2) * (var(component.W(12), 0) - 3) - * (var(component.W(12), 0) - 4) * (var(component.W(12), 0) - 5) * (var(component.W(12), 0) - 6) * (var(component.W(12), 0) - 7); + auto constraint_23 = var(component.W(12), 0) * (var(component.W(12), 0) - 1) * + (var(component.W(12), 0) - 2) * (var(component.W(12), 0) - 3) * + (var(component.W(12), 0) - 4) * (var(component.W(12), 0) - 5) * + (var(component.W(12), 0) - 6) * (var(component.W(12), 0) - 7); // check u_1 = 1-bit chunk of aux auto constraint_24 = var(component.W(13), 0) * (var(component.W(13), 0) - 1); // check accumalator(u_i) - auto constraint_25 = - var(component.W(14), 0) - 16 * var(component.W(6), -1) - 2 * var(component.W(12), 0) - - var(component.W(13), 0); + auto constraint_25 = var(component.W(14), 0) - 16 * var(component.W(6), -1) - + 2 * var(component.W(12), 0) - var(component.W(13), 0); // check aux = z_{n-2} - t_p + 2^130 auto constraint_28 = var(component.W(9), 0) - (var(component.W(9), 0)); - if (std::is_same::value) { + if (std::is_same::value) { constraint_28 = - var(component.W(12), +1) - var(component.W(11), +1) + component.t_q - component.two.pow(130); + var(component.W(12), +1) - var(component.W(11), +1) + component.t_q - component.two.pow(130); } else { - constraint_28 = - var(component.W(12), +1) - var(component.W(11), +1) + var(component.W(9), +1) * component.two.pow(254) + component.t_p - component.two.pow(130); + constraint_28 = var(component.W(12), +1) - var(component.W(11), +1) + + var(component.W(9), +1) * component.two.pow(254) + component.t_p - + component.two.pow(130); } // check (bits[0] = 1) => accumalator(u_i) = aux auto constraint_26 = var(component.W(9), +1) * (var(component.W(14), 0) - var(component.W(12), +1)); @@ -715,55 +791,55 @@ namespace nil { // check b_high * 2^254 + b = accamulator(b_i) (mod p) // (b_high = 1) => b < 2^254 auto constraint_29 = var(component.W(9), 0) - var(component.W(9), 0); - if (std::is_same::value) { - constraint_29 = - var(component.W(5), -1) - var(component.W(11), +1) - - var(component.W(9), +1) * component.two.pow(254); + if (std::is_same::value) { + constraint_29 = var(component.W(5), -1) - var(component.W(11), +1) - + var(component.W(9), +1) * component.two.pow(254); } std::size_t selector_index_2 = bp.add_gate( - {bit_check_1, bit_check_2, bit_check_3, bit_check_4, bit_check_5, - constraint_1, constraint_2, constraint_3, constraint_4, constraint_5, - constraint_6, constraint_7, constraint_8, constraint_9, constraint_10, - constraint_11, constraint_12, constraint_13, constraint_14, constraint_15, - constraint_16, constraint_17, constraint_18, constraint_19, constraint_20, - constraint_21, constraint_22, - constraint_23, constraint_24, constraint_25, constraint_26, constraint_27, - constraint_28, constraint_29}); + {bit_check_1, bit_check_2, bit_check_3, bit_check_4, bit_check_5, constraint_1, + constraint_2, constraint_3, constraint_4, constraint_5, constraint_6, constraint_7, + constraint_8, constraint_9, constraint_10, constraint_11, constraint_12, constraint_13, + constraint_14, constraint_15, constraint_16, constraint_17, constraint_18, constraint_19, + constraint_20, constraint_21, constraint_22, constraint_23, constraint_24, constraint_25, + constraint_26, constraint_27, constraint_28, constraint_29}); // check u_0 = 3-bit chunk of aux - constraint_1 = - var(component.W(12), +1) * (var(component.W(12), +1) - 1) * (var(component.W(12), +1) - 2) * (var(component.W(12), +1) - 3) - * (var(component.W(12), +1) - 4) * (var(component.W(12), +1) - 5) * (var(component.W(12), +1) - 6) * (var(component.W(12), +1) - 7); + constraint_1 = var(component.W(12), +1) * (var(component.W(12), +1) - 1) * + (var(component.W(12), +1) - 2) * (var(component.W(12), +1) - 3) * + (var(component.W(12), +1) - 4) * (var(component.W(12), +1) - 5) * + (var(component.W(12), +1) - 6) * (var(component.W(12), +1) - 7); // check u_1 = 3-bit chunk of aux - constraint_2 = - var(component.W(13), +1) * (var(component.W(13), +1) - 1) * (var(component.W(13), +1) - 2) * (var(component.W(13), +1) - 3) - * (var(component.W(13), +1) - 4) * (var(component.W(13), +1) - 5) * (var(component.W(13), +1) - 6) * (var(component.W(13), +1) - 7); + constraint_2 = var(component.W(13), +1) * (var(component.W(13), +1) - 1) * + (var(component.W(13), +1) - 2) * (var(component.W(13), +1) - 3) * + (var(component.W(13), +1) - 4) * (var(component.W(13), +1) - 5) * + (var(component.W(13), +1) - 6) * (var(component.W(13), +1) - 7); // check u_next = intermediate accumalator(u_i) - constraint_3 = - var(component.W(14), +1) - 64 * var(component.W(6), 0) - 8 * var(component.W(12), +1) - var(component.W(13), +1); + constraint_3 = var(component.W(14), +1) - 64 * var(component.W(6), 0) - 8 * var(component.W(12), +1) - + var(component.W(13), +1); std::size_t selector_index_3 = bp.add_gate({constraint_1, constraint_2, constraint_3}); return {selector_index_1, selector_index_2, selector_index_3}; } template - void generate_copy_constraints( - const plonk_curve_element_variable_base_scalar_mul &component, - circuit> &bp, - assignment> &assignment, - const typename plonk_curve_element_variable_base_scalar_mul::input_type instance_input, - const std::uint32_t start_row_index) { + void generate_copy_constraints( + const plonk_curve_element_variable_base_scalar_mul &component, + circuit> &bp, + assignment> &assignment, + const typename plonk_curve_element_variable_base_scalar_mul::input_type + instance_input, + const std::uint32_t start_row_index) { std::size_t j = start_row_index + component.add_component_rows_amount; using var = typename plonk_curve_element_variable_base_scalar_mul::var; - using add_component = typename plonk_curve_element_variable_base_scalar_mul< - BlueprintFieldType, CurveType>::add_component; + using add_component = + typename plonk_curve_element_variable_base_scalar_mul::add_component; - add_component unified_addition_instance( - {component.W(0), component.W(1), component.W(2), component.W(3), component.W(4), - component.W(5), component.W(6), component.W(7), component.W(8), component.W(9), - component.W(10)},{},{}); + add_component unified_addition_instance({component.W(0), component.W(1), component.W(2), component.W(3), + component.W(4), component.W(5), component.W(6), component.W(7), + component.W(8), component.W(9), component.W(10)}, + {}, {}); typename add_component::result_type addition_res(unified_addition_instance, start_row_index); @@ -773,66 +849,69 @@ namespace nil { // main algorithm for (int z = 0; z < component.mul_rows_amount - 2; z += 2) { - bp.add_copy_constraint( - {{component.W(0), (std::int32_t)(j + z), false}, {component.W(0), (std::int32_t)(j + z + 2), false}}); - bp.add_copy_constraint( - {{component.W(1), (std::int32_t)(j + z), false}, {component.W(1), (std::int32_t)(j + z + 2), false}}); + bp.add_copy_constraint({{component.W(0), (std::int32_t)(j + z), false}, + {component.W(0), (std::int32_t)(j + z + 2), false}}); + bp.add_copy_constraint({{component.W(1), (std::int32_t)(j + z), false}, + {component.W(1), (std::int32_t)(j + z + 2), false}}); } for (int z = 2; z < component.mul_rows_amount; z += 2) { - bp.add_copy_constraint( - {{component.W(2), (std::int32_t)(j + z), false}, {component.W(0), (std::int32_t)(j + z - 1), false}}); - bp.add_copy_constraint( - {{component.W(3), (std::int32_t)(j + z), false}, {component.W(1), (std::int32_t)(j + z - 1), false}}); + bp.add_copy_constraint({{component.W(2), (std::int32_t)(j + z), false}, + {component.W(0), (std::int32_t)(j + z - 1), false}}); + bp.add_copy_constraint({{component.W(3), (std::int32_t)(j + z), false}, + {component.W(1), (std::int32_t)(j + z - 1), false}}); } for (int z = 2; z < component.mul_rows_amount; z += 2) { - bp.add_copy_constraint( - {{component.W(4), (std::int32_t)(j + z), false}, {component.W(5), (std::int32_t)(j + z - 2), false}}); + bp.add_copy_constraint({{component.W(4), (std::int32_t)(j + z), false}, + {component.W(5), (std::int32_t)(j + z - 2), false}}); } - bp.add_copy_constraint({{component.W(5), (std::int32_t)(start_row_index + component.rows_amount - 1), false}, - {component.W(5), (std::int32_t)(start_row_index + component.rows_amount - 3), false}}); - bp.add_copy_constraint({{component.W(6), (std::int32_t)(start_row_index + component.rows_amount - 1), false}, - {component.W(0), (std::int32_t)(start_row_index + component.rows_amount - 3), false}}); - bp.add_copy_constraint({{component.W(7), (std::int32_t)(start_row_index + component.rows_amount - 1), false}, - {component.W(1), (std::int32_t)(start_row_index + component.rows_amount - 3), false}}); + bp.add_copy_constraint( + {{component.W(5), (std::int32_t)(start_row_index + component.rows_amount - 1), false}, + {component.W(5), (std::int32_t)(start_row_index + component.rows_amount - 3), false}}); + bp.add_copy_constraint( + {{component.W(6), (std::int32_t)(start_row_index + component.rows_amount - 1), false}, + {component.W(0), (std::int32_t)(start_row_index + component.rows_amount - 3), false}}); + bp.add_copy_constraint( + {{component.W(7), (std::int32_t)(start_row_index + component.rows_amount - 1), false}, + {component.W(1), (std::int32_t)(start_row_index + component.rows_amount - 3), false}}); bp.add_copy_constraint({{component.W(4), (std::int32_t)(j), false}, {component.W(0), (std::int32_t)(j), false, var::column_type::constant}}); // bp.add_copy_constraint( - // {instance_input.b, {component.W(5), (std::int32_t)(j + component.rows_amount - 4), false}}); // scalar value check + // {instance_input.b, {component.W(5), (std::int32_t)(j + component.rows_amount - 4), false}}); // + // scalar value check // additional range-checks copy constraints - if (std::is_same::value) { - bp.add_copy_constraint( - {instance_input.b_high, {component.W(2), (std::int32_t)(j + 1), false}}); + if (std::is_same::value) { + bp.add_copy_constraint({instance_input.b_high, {component.W(2), (std::int32_t)(j + 1), false}}); } else { - bp.add_copy_constraint( - {instance_input.b, {component.W(5), (std::int32_t)(j + component.rows_amount - 4), false}}); // scalar value check + bp.add_copy_constraint({instance_input.b, + {component.W(5), (std::int32_t)(j + component.rows_amount - 4), + false}}); // scalar value check } - bp.add_copy_constraint( - {{component.C(0), (std::int32_t)(j), false, var::column_type::constant}, {component.W(6), (std::int32_t)(j + 58), false}}); + bp.add_copy_constraint({{component.C(0), (std::int32_t)(j), false, var::column_type::constant}, + {component.W(6), (std::int32_t)(j + 58), false}}); for (int z = 0; z < 40; z += 2) { - bp.add_copy_constraint( - {{component.W(14), (std::int32_t)(j + 58 + z + 1), false}, {component.W(6), (std::int32_t)(j + 58 + z + 2), false}}); + bp.add_copy_constraint({{component.W(14), (std::int32_t)(j + 58 + z + 1), false}, + {component.W(6), (std::int32_t)(j + 58 + z + 2), false}}); } bp.add_copy_constraint( - {{component.W(2), (std::int32_t)(j + 1), false}, {component.W(9), (std::int32_t)(j + 102), false}}); - bp.add_copy_constraint( - {{component.W(5), (std::int32_t)(j + 48), false}, {component.W(10), (std::int32_t)(j + 102), false}}); - bp.add_copy_constraint( - {instance_input.b, {component.W(11), (std::int32_t)(j + 102), false}}); - + {{component.W(2), (std::int32_t)(j + 1), false}, {component.W(9), (std::int32_t)(j + 102), false}}); + bp.add_copy_constraint({{component.W(5), (std::int32_t)(j + 48), false}, + {component.W(10), (std::int32_t)(j + 102), false}}); + bp.add_copy_constraint({instance_input.b, {component.W(11), (std::int32_t)(j + 102), false}}); } template - void generate_assignments_constants( - const plonk_curve_element_variable_base_scalar_mul &component, - circuit> &bp, - assignment> &assignment, - const typename plonk_curve_element_variable_base_scalar_mul::input_type instance_input, - const std::uint32_t start_row_index) { + void generate_assignments_constants( + const plonk_curve_element_variable_base_scalar_mul &component, + circuit> &bp, + assignment> &assignment, + const typename plonk_curve_element_variable_base_scalar_mul::input_type + instance_input, + const std::uint32_t start_row_index) { std::size_t row = start_row_index + component.add_component_rows_amount; assignment.constant(component.C(0), row) = BlueprintFieldType::value_type::zero(); @@ -845,98 +924,87 @@ namespace nil { class result_type_converter; template - class input_type_converter< - plonk_curve_element_variable_base_scalar_mul> { + class input_type_converter> { - using component_type = - plonk_curve_element_variable_base_scalar_mul; + using component_type = plonk_curve_element_variable_base_scalar_mul; using input_type = typename component_type::input_type; using var = typename nil::crypto3::zk::snark::plonk_variable; + public: - static input_type convert( - const input_type &input, - nil::blueprint::assignment> - &assignment, - nil::blueprint::assignment> - &tmp_assignment) { + static input_type + convert(const input_type &input, + nil::blueprint::assignment> + &assignment, + nil::blueprint::assignment> + &tmp_assignment) { tmp_assignment.public_input(0, 0) = var_value(assignment, input.T.x); tmp_assignment.public_input(0, 1) = var_value(assignment, input.T.y); tmp_assignment.public_input(0, 2) = var_value(assignment, input.b); - if (std::is_same::value) { + if (std::is_same::value) { tmp_assignment.public_input(0, 3) = var_value(assignment, input.b_high); } - if (std::is_same::value) { - input_type new_input( - {var(0, 0, false, var::column_type::public_input), - var(0, 1, false, var::column_type::public_input)}, - var(0, 2, false, var::column_type::public_input), - var(0, 3, false, var::column_type::public_input) - ); + if (std::is_same::value) { + input_type new_input({var(0, 0, false, var::column_type::public_input), + var(0, 1, false, var::column_type::public_input)}, + var(0, 2, false, var::column_type::public_input), + var(0, 3, false, var::column_type::public_input)); return new_input; } else { - input_type new_input( - {var(0, 0, false, var::column_type::public_input), - var(0, 1, false, var::column_type::public_input)}, - var(0, 2, false, var::column_type::public_input) - ); + input_type new_input({var(0, 0, false, var::column_type::public_input), + var(0, 1, false, var::column_type::public_input)}, + var(0, 2, false, var::column_type::public_input)); return new_input; } } - static var deconvert_var(const input_type &input, - var variable) { + static var deconvert_var(const input_type &input, var variable) { BOOST_ASSERT(variable.type == var::column_type::public_input); var new_var; switch (variable.rotation) { - case 0: - new_var = input.T.x; - break; - case 1: - new_var = input.T.y; - break; - case 2: - new_var = input.b; - break; - case 3: - new_var = input.b_high; - break; - default: - BOOST_ASSERT_MSG(false, "Incorrect variable passed to deconvert_var"); + case 0: + new_var = input.T.x; + break; + case 1: + new_var = input.T.y; + break; + case 2: + new_var = input.b; + break; + case 3: + new_var = input.b_high; + break; + default: + BOOST_ASSERT_MSG(false, "Incorrect variable passed to deconvert_var"); } return new_var; } }; template - class result_type_converter< - plonk_curve_element_variable_base_scalar_mul> { + class result_type_converter> { - using component_type = - plonk_curve_element_variable_base_scalar_mul; + using component_type = plonk_curve_element_variable_base_scalar_mul; using input_type = typename component_type::input_type; using result_type = typename component_type::result_type; using stretcher_type = component_stretcher; + public: static result_type convert(const stretcher_type &component, const result_type old_result, const input_type &instance_input, std::size_t start_row_index) { result_type new_result(component.component, start_row_index); new_result.X = component.move_var( - old_result.X, - start_row_index + component.line_mapping[old_result.X.rotation], - instance_input); + old_result.X, start_row_index + component.line_mapping[old_result.X.rotation], instance_input); new_result.Y = component.move_var( - old_result.Y, - start_row_index + component.line_mapping[old_result.Y.rotation], - instance_input); + old_result.Y, start_row_index + component.line_mapping[old_result.Y.rotation], instance_input); return new_result; } }; } // namespace components - } // namespace blueprint + } // namespace blueprint } // namespace nil #endif // CRYPTO3_ZK_BLUEPRINT_PLONK_CURVE_ELEMENT_VARIABLE_BASE_SCALAR_MUL_COMPONENT_HPP \ No newline at end of file diff --git a/include/nil/blueprint/components/algebra/curves/twisted_edwards/element_g1.hpp b/include/nil/blueprint/components/algebra/curves/twisted_edwards/element_g1.hpp index 799ed1022..331d9a549 100644 --- a/include/nil/blueprint/components/algebra/curves/twisted_edwards/element_g1.hpp +++ b/include/nil/blueprint/components/algebra/curves/twisted_edwards/element_g1.hpp @@ -32,407 +32,397 @@ #ifndef CRYPTO3_BLUEPRINT_COMPONENTS_TWISTED_EDWARDS_G1_COMPONENT_HPP #define CRYPTO3_BLUEPRINT_COMPONENTS_TWISTED_EDWARDS_G1_COMPONENT_HPP -#include -#include +#include +#include namespace nil { - namespace crypto3 { - namespace blueprint { - namespace components { - /** - * @brief Component that creates constraints for the addition of two elements from G1. - */ - template - struct element_g1_addition - : public component::field_type> { - using curve_type = Curve; - using form = algebra::curves::forms::twisted_edwards; - using coordinates = algebra::curves::coordinates::affine; - - using element_component = element_g1; - - using field_type = typename element_component::field_type; - using group_type = typename element_component::group_type; - - using result_type = element_component; - - const element_component p1; - const element_component p2; - result_type result; - - // Intermediate variables - element_fp X1X2; - element_fp X1Y2; - element_fp Y1Y2; - element_fp Y1X2; - element_fp X1X2Y1Y2; - element_fp dX1X2Y1Y2; - element_fp aX1X2; - - private: - void init() { - detail::blueprint_variable X1X2_var, X1Y2_var, Y1Y2_var, Y1X2_var, X1X2Y1Y2_var, - dX1X2Y1Y2_var, aX1X2_var; - - X1X2_var.allocate(this->bp); - X1Y2_var.allocate(this->bp); - Y1Y2_var.allocate(this->bp); - Y1X2_var.allocate(this->bp); - X1X2Y1Y2_var.allocate(this->bp); - dX1X2Y1Y2_var.allocate(this->bp); - aX1X2_var.allocate(this->bp); - - this->X1X2 = X1X2_var; - this->X1Y2 = X1Y2_var; - this->Y1Y2 = Y1Y2_var; - this->Y1X2 = Y1X2_var; - this->X1X2Y1Y2 = X1X2Y1Y2_var; - this->dX1X2Y1Y2 = dX1X2Y1Y2_var; - this->aX1X2 = aX1X2_var; - } - - public: - /// Auto allocation of the result - element_g1_addition(blueprint &bp, - const element_component &in_p1, - const element_component &in_p2) : - component(bp), - p1(in_p1), p2(in_p2), result(bp) { - init(); - } - - /// Manual allocation of the result - element_g1_addition(blueprint &bp, - const element_component &in_p1, - const element_component &in_p2, - const result_type &in_result) : - component(bp), - p1(in_p1), p2(in_p2), result(in_result) { - init(); - } - - void generate_gates() { - // X3 = (X1*Y2 + Y1*X2) / (Fq.ONE + D*X1*X2*Y1*Y2) - // y3 = (Y1*Y2 - A*X1*X2) / (Fq.ONE - D*X1*X2*Y1*Y2) - this->bp.add_r1cs_constraint( - snark::r1cs_constraint({this->p1.Y}, {this->p2.X}, {this->Y1X2})); - this->bp.add_r1cs_constraint( - snark::r1cs_constraint({this->p1.X}, {this->p2.Y}, {this->X1Y2})); - this->bp.add_r1cs_constraint( - snark::r1cs_constraint({this->p1.X}, {this->p2.X}, {this->X1X2})); - this->bp.add_r1cs_constraint( - snark::r1cs_constraint({this->p1.Y}, {this->p2.Y}, {this->Y1Y2})); - this->bp.add_r1cs_constraint( - snark::r1cs_constraint({this->X1X2}, {this->Y1Y2}, {this->X1X2Y1Y2})); - this->bp.add_r1cs_constraint(snark::r1cs_constraint( - {group_type::params_type::d}, {this->X1X2Y1Y2}, {this->dX1X2Y1Y2})); - this->bp.add_r1cs_constraint(snark::r1cs_constraint( - {group_type::params_type::a}, {this->X1X2}, {this->aX1X2})); - this->bp.add_r1cs_constraint( - snark::r1cs_constraint({this->result.Y}, - {field_type::value_type::one(), -(this->dX1X2Y1Y2)}, - {this->Y1Y2, -(this->aX1X2)})); - this->bp.add_r1cs_constraint( - snark::r1cs_constraint({this->result.X}, - {field_type::value_type::one(), this->dX1X2Y1Y2}, - {this->X1Y2, this->Y1X2})); - } - - void generate_assignments() { - const typename field_type::value_type &x1 = this->bp.lc_val(this->p1.X); - const typename field_type::value_type &y1 = this->bp.lc_val(this->p1.Y); - const typename field_type::value_type &x2 = this->bp.lc_val(this->p2.X); - const typename field_type::value_type &y2 = this->bp.lc_val(this->p2.Y); - - this->bp.lc_val(X1X2) = x1 * x2; - this->bp.lc_val(X1Y2) = x1 * y2; - this->bp.lc_val(Y1Y2) = y1 * y2; - this->bp.lc_val(Y1X2) = y1 * x2; - this->bp.lc_val(X1X2Y1Y2) = this->bp.lc_val(X1X2) * this->bp.lc_val(Y1Y2); - this->bp.lc_val(dX1X2Y1Y2) = - static_cast(group_type::params_type::d) * - this->bp.lc_val(X1X2Y1Y2); - this->bp.lc_val(aX1X2) = - static_cast(group_type::params_type::a) * - this->bp.lc_val(X1X2); - this->bp.lc_val(this->result.X) = - (this->bp.lc_val(X1Y2) + this->bp.lc_val(Y1X2)) * - (field_type::value_type::one() + this->bp.lc_val(dX1X2Y1Y2)).inversed(); - this->bp.lc_val(this->result.Y) = - (this->bp.lc_val(Y1Y2) - this->bp.lc_val(aX1X2)) * - (field_type::value_type::one() - this->bp.lc_val(dX1X2Y1Y2)).inversed(); - } - }; - - /** - * @brief Component that creates constraints for the validity of a G1 element. (if element from group G1 - * lies on the elliptic curve) - */ - template - struct element_g1_is_well_formed - : public component::field_type> { - using curve_type = Curve; - using form = algebra::curves::forms::twisted_edwards; - using coordinates = algebra::curves::coordinates::affine; - - using element_component = element_g1; - - using field_type = typename element_component::field_type; - using group_type = typename element_component::group_type; - - const element_component p; - - // Intermediate variables - element_fp XX; - element_fp aXX; - element_fp dXX; - element_fp YY; - element_fp dXXYY; - element_fp lhs; - element_fp rhs; - - element_g1_is_well_formed(blueprint &bp, const element_component &in_p) : - component(bp), p(in_p) { - detail::blueprint_variable XX_var, aXX_var, dXX_var, YY_var, dXXYY_var, lhs_var, rhs_var; - - XX_var.allocate(this->bp); - aXX_var.allocate(this->bp); - dXX_var.allocate(this->bp); - YY_var.allocate(this->bp); - dXXYY_var.allocate(this->bp); - lhs_var.allocate(this->bp); - rhs_var.allocate(this->bp); - - this->XX = XX_var; - this->aXX = aXX_var; - this->dXX = dXX_var; - this->YY = YY_var; - this->dXXYY = dXXYY_var; - this->lhs = lhs_var; - this->rhs = rhs_var; - } - - void generate_gates() { - // a*X*X + Y*Y = 1 + d*X*X*Y*Y - this->bp.add_r1cs_constraint( - snark::r1cs_constraint({this->p.X}, {this->p.X}, {this->XX})); - this->bp.add_r1cs_constraint( - snark::r1cs_constraint({this->p.Y}, {this->p.Y}, {this->YY})); - this->bp.add_r1cs_constraint( - snark::r1cs_constraint({group_type::params_type::a}, {this->XX}, {this->aXX})); - this->bp.add_r1cs_constraint(snark::r1cs_constraint( - {this->aXX, this->YY}, {field_type::value_type::one()}, {this->lhs})); - this->bp.add_r1cs_constraint( - snark::r1cs_constraint({group_type::params_type::d}, {this->XX}, {this->dXX})); - this->bp.add_r1cs_constraint( - snark::r1cs_constraint({this->dXX}, {this->YY}, {this->dXXYY})); - this->bp.add_r1cs_constraint( - snark::r1cs_constraint({this->dXXYY, field_type::value_type::one()}, - {field_type::value_type::one()}, - {this->rhs})); - this->bp.add_r1cs_constraint(snark::r1cs_constraint( - {this->lhs}, {field_type::value_type::one()}, {this->rhs})); - } - - void generate_assignments() { - const typename field_type::value_type &x = this->bp.lc_val(this->p.X); - const typename field_type::value_type &y = this->bp.lc_val(this->p.Y); - - this->bp.lc_val(this->XX) = x * x; - this->bp.lc_val(this->YY) = y * y; - this->bp.lc_val(this->aXX) = - static_cast(group_type::params_type::a) * - this->bp.lc_val(this->XX); - this->bp.lc_val(this->lhs) = this->bp.lc_val(this->aXX) + this->bp.lc_val(this->YY); - this->bp.lc_val(this->dXX) = - static_cast(group_type::params_type::d) * - this->bp.lc_val(this->XX); - this->bp.lc_val(this->dXXYY) = this->bp.lc_val(this->dXX) * this->bp.lc_val(this->YY); - this->bp.lc_val(this->rhs) = this->bp.lc_val(this->dXXYY) + field_type::value_type::one(); - } - }; - - /** - * @brief Component that creates constraints for the point serialization into the bit sequence - * according to https://zips.z.cash/protocol/protocol.pdf#concreteextractorjubjub - */ - template - struct element_g1_to_bits - : public component::field_type> { - using curve_type = Curve; - using form = algebra::curves::forms::twisted_edwards; - using coordinates = algebra::curves::coordinates::affine; - - using element_component = element_g1; - - using field_type = typename element_component::field_type; - using group_type = typename element_component::group_type; - - using field_to_bits_component = field_to_bits_strict; - using result_type = typename field_to_bits_component::result_type; - - field_to_bits_component field_to_bits_converter; - result_type &result; - - /// Auto allocation of the result - element_g1_to_bits(blueprint &bp, const element_component &in_p) : - component(bp), field_to_bits_converter(bp, in_p.X), - result(field_to_bits_converter.result) { - } - - /// Manual allocation of the result - element_g1_to_bits(blueprint &bp, - const element_component &in_p, - const result_type &in_result) : - component(bp), - field_to_bits_converter(bp, in_p.X, in_result), result(field_to_bits_converter.result) { - } - - void generate_gates() { - this->field_to_bits_converter.generate_gates(); - } - - void generate_assignments() { - this->field_to_bits_converter.generate_assignments(); - } - }; - - /** - * @brief Component that creates constraints for the addition of two elements from G1. - */ - // TODO: fixme - template - struct element_g1_conditional_addition - : public component::field_type> { - using curve_type = Curve; - using form = algebra::curves::forms::twisted_edwards; - using coordinates = algebra::curves::coordinates::affine; - - using element_component = element_g1; - - using field_type = typename element_component::field_type; - using group_type = typename element_component::group_type; - - const element_component p1; - const element_component p2; - element_component result; - - const detail::blueprint_variable can_add; - - // intermediate variables - element_component p_to_add; - element_fp Y_intermediate_to_add1; - element_fp Y_intermediate_to_add2; - detail::blueprint_variable cannot_add; + namespace blueprint { + namespace components { + /** + * @brief Component that creates constraints for the addition of two elements from G1. + */ + template + struct element_g1_addition + : public component::field_type> { + using curve_type = Curve; + using form = crypto3::algebra::curves::forms::twisted_edwards; + using coordinates = crypto3::algebra::curves::coordinates::affine; + + using element_component = element_g1; + + using field_type = typename element_component::field_type; + using group_type = typename element_component::group_type; + + using result_type = element_component; + + const element_component p1; + const element_component p2; + result_type result; + + // Intermediate variables + element_fp X1X2; + element_fp X1Y2; + element_fp Y1Y2; + element_fp Y1X2; + element_fp X1X2Y1Y2; + element_fp dX1X2Y1Y2; + element_fp aX1X2; + + private: + void init() { + detail::blueprint_variable X1X2_var, X1Y2_var, Y1Y2_var, Y1X2_var, X1X2Y1Y2_var, + dX1X2Y1Y2_var, aX1X2_var; + + X1X2_var.allocate(this->bp); + X1Y2_var.allocate(this->bp); + Y1Y2_var.allocate(this->bp); + Y1X2_var.allocate(this->bp); + X1X2Y1Y2_var.allocate(this->bp); + dX1X2Y1Y2_var.allocate(this->bp); + aX1X2_var.allocate(this->bp); + + this->X1X2 = X1X2_var; + this->X1Y2 = X1Y2_var; + this->Y1Y2 = Y1Y2_var; + this->Y1X2 = Y1X2_var; + this->X1X2Y1Y2 = X1X2Y1Y2_var; + this->dX1X2Y1Y2 = dX1X2Y1Y2_var; + this->aX1X2 = aX1X2_var; + } + + public: + /// Auto allocation of the result + element_g1_addition(blueprint &bp, + const element_component &in_p1, + const element_component &in_p2) : + component(bp), p1(in_p1), p2(in_p2), result(bp) { + init(); + } + + /// Manual allocation of the result + element_g1_addition(blueprint &bp, + const element_component &in_p1, + const element_component &in_p2, + const result_type &in_result) : + component(bp), p1(in_p1), p2(in_p2), result(in_result) { + init(); + } + + void generate_gates() { + // X3 = (X1*Y2 + Y1*X2) / (Fq.ONE + D*X1*X2*Y1*Y2) + // y3 = (Y1*Y2 - A*X1*X2) / (Fq.ONE - D*X1*X2*Y1*Y2) + this->bp.add_r1cs_constraint( + crypto3::zk::snark::r1cs_constraint({this->p1.Y}, {this->p2.X}, {this->Y1X2})); + this->bp.add_r1cs_constraint( + crypto3::zk::snark::r1cs_constraint({this->p1.X}, {this->p2.Y}, {this->X1Y2})); + this->bp.add_r1cs_constraint( + crypto3::zk::snark::r1cs_constraint({this->p1.X}, {this->p2.X}, {this->X1X2})); + this->bp.add_r1cs_constraint( + crypto3::zk::snark::r1cs_constraint({this->p1.Y}, {this->p2.Y}, {this->Y1Y2})); + this->bp.add_r1cs_constraint( + crypto3::zk::snark::r1cs_constraint({this->X1X2}, {this->Y1Y2}, {this->X1X2Y1Y2})); + this->bp.add_r1cs_constraint(crypto3::zk::snark::r1cs_constraint( + {group_type::params_type::d}, {this->X1X2Y1Y2}, {this->dX1X2Y1Y2})); + this->bp.add_r1cs_constraint(crypto3::zk::snark::r1cs_constraint( + {group_type::params_type::a}, {this->X1X2}, {this->aX1X2})); + this->bp.add_r1cs_constraint(crypto3::zk::snark::r1cs_constraint( + {this->result.Y}, + {field_type::value_type::one(), -(this->dX1X2Y1Y2)}, + {this->Y1Y2, -(this->aX1X2)})); + this->bp.add_r1cs_constraint(crypto3::zk::snark::r1cs_constraint( + {this->result.X}, {field_type::value_type::one(), this->dX1X2Y1Y2}, {this->X1Y2, this->Y1X2})); + } + + void generate_assignments() { + const typename field_type::value_type &x1 = this->bp.lc_val(this->p1.X); + const typename field_type::value_type &y1 = this->bp.lc_val(this->p1.Y); + const typename field_type::value_type &x2 = this->bp.lc_val(this->p2.X); + const typename field_type::value_type &y2 = this->bp.lc_val(this->p2.Y); + + this->bp.lc_val(X1X2) = x1 * x2; + this->bp.lc_val(X1Y2) = x1 * y2; + this->bp.lc_val(Y1Y2) = y1 * y2; + this->bp.lc_val(Y1X2) = y1 * x2; + this->bp.lc_val(X1X2Y1Y2) = this->bp.lc_val(X1X2) * this->bp.lc_val(Y1Y2); + this->bp.lc_val(dX1X2Y1Y2) = + static_cast(group_type::params_type::d) * + this->bp.lc_val(X1X2Y1Y2); + this->bp.lc_val(aX1X2) = static_cast(group_type::params_type::a) * + this->bp.lc_val(X1X2); + this->bp.lc_val(this->result.X) = + (this->bp.lc_val(X1Y2) + this->bp.lc_val(Y1X2)) * + (field_type::value_type::one() + this->bp.lc_val(dX1X2Y1Y2)).inversed(); + this->bp.lc_val(this->result.Y) = + (this->bp.lc_val(Y1Y2) - this->bp.lc_val(aX1X2)) * + (field_type::value_type::one() - this->bp.lc_val(dX1X2Y1Y2)).inversed(); + } + }; + + /** + * @brief Component that creates constraints for the validity of a G1 element. (if element from group G1 + * lies on the elliptic curve) + */ + template + struct element_g1_is_well_formed + : public component::field_type> { + using curve_type = Curve; + using form = crypto3::algebra::curves::forms::twisted_edwards; + using coordinates = crypto3::algebra::curves::coordinates::affine; + + using element_component = element_g1; + + using field_type = typename element_component::field_type; + using group_type = typename element_component::group_type; + + const element_component p; + + // Intermediate variables + element_fp XX; + element_fp aXX; + element_fp dXX; + element_fp YY; + element_fp dXXYY; + element_fp lhs; + element_fp rhs; + + element_g1_is_well_formed(blueprint &bp, const element_component &in_p) : + component(bp), p(in_p) { + detail::blueprint_variable XX_var, aXX_var, dXX_var, YY_var, dXXYY_var, lhs_var, + rhs_var; + + XX_var.allocate(this->bp); + aXX_var.allocate(this->bp); + dXX_var.allocate(this->bp); + YY_var.allocate(this->bp); + dXXYY_var.allocate(this->bp); + lhs_var.allocate(this->bp); + rhs_var.allocate(this->bp); + + this->XX = XX_var; + this->aXX = aXX_var; + this->dXX = dXX_var; + this->YY = YY_var; + this->dXXYY = dXXYY_var; + this->lhs = lhs_var; + this->rhs = rhs_var; + } + + void generate_gates() { + // a*X*X + Y*Y = 1 + d*X*X*Y*Y + this->bp.add_r1cs_constraint( + crypto3::zk::snark::r1cs_constraint({this->p.X}, {this->p.X}, {this->XX})); + this->bp.add_r1cs_constraint( + crypto3::zk::snark::r1cs_constraint({this->p.Y}, {this->p.Y}, {this->YY})); + this->bp.add_r1cs_constraint(crypto3::zk::snark::r1cs_constraint( + {group_type::params_type::a}, {this->XX}, {this->aXX})); + this->bp.add_r1cs_constraint(crypto3::zk::snark::r1cs_constraint( + {this->aXX, this->YY}, {field_type::value_type::one()}, {this->lhs})); + this->bp.add_r1cs_constraint(crypto3::zk::snark::r1cs_constraint( + {group_type::params_type::d}, {this->XX}, {this->dXX})); + this->bp.add_r1cs_constraint( + crypto3::zk::snark::r1cs_constraint({this->dXX}, {this->YY}, {this->dXXYY})); + this->bp.add_r1cs_constraint(crypto3::zk::snark::r1cs_constraint( + {this->dXXYY, field_type::value_type::one()}, {field_type::value_type::one()}, {this->rhs})); + this->bp.add_r1cs_constraint(crypto3::zk::snark::r1cs_constraint( + {this->lhs}, {field_type::value_type::one()}, {this->rhs})); + } + + void generate_assignments() { + const typename field_type::value_type &x = this->bp.lc_val(this->p.X); + const typename field_type::value_type &y = this->bp.lc_val(this->p.Y); + + this->bp.lc_val(this->XX) = x * x; + this->bp.lc_val(this->YY) = y * y; + this->bp.lc_val(this->aXX) = + static_cast(group_type::params_type::a) * + this->bp.lc_val(this->XX); + this->bp.lc_val(this->lhs) = this->bp.lc_val(this->aXX) + this->bp.lc_val(this->YY); + this->bp.lc_val(this->dXX) = + static_cast(group_type::params_type::d) * + this->bp.lc_val(this->XX); + this->bp.lc_val(this->dXXYY) = this->bp.lc_val(this->dXX) * this->bp.lc_val(this->YY); + this->bp.lc_val(this->rhs) = this->bp.lc_val(this->dXXYY) + field_type::value_type::one(); + } + }; + + /** + * @brief Component that creates constraints for the point serialization into the bit sequence + * according to https://zips.z.cash/protocol/protocol.pdf#concreteextractorjubjub + */ + template + struct element_g1_to_bits + : public component::field_type> { + using curve_type = Curve; + using form = crypto3::algebra::curves::forms::twisted_edwards; + using coordinates = crypto3::algebra::curves::coordinates::affine; + + using element_component = element_g1; + + using field_type = typename element_component::field_type; + using group_type = typename element_component::group_type; + + using field_to_bits_component = field_to_bits_strict; + using result_type = typename field_to_bits_component::result_type; + + field_to_bits_component field_to_bits_converter; + result_type &result; + + /// Auto allocation of the result + element_g1_to_bits(blueprint &bp, const element_component &in_p) : + component(bp), field_to_bits_converter(bp, in_p.X), + result(field_to_bits_converter.result) { + } + + /// Manual allocation of the result + element_g1_to_bits(blueprint &bp, + const element_component &in_p, + const result_type &in_result) : + component(bp), field_to_bits_converter(bp, in_p.X, in_result), + result(field_to_bits_converter.result) { + } + + void generate_gates() { + this->field_to_bits_converter.generate_gates(); + } + + void generate_assignments() { + this->field_to_bits_converter.generate_assignments(); + } + }; + + /** + * @brief Component that creates constraints for the addition of two elements from G1. + */ + // TODO: fixme + template + struct element_g1_conditional_addition + : public component::field_type> { + using curve_type = Curve; + using form = crypto3::algebra::curves::forms::twisted_edwards; + using coordinates = crypto3::algebra::curves::coordinates::affine; + + using element_component = element_g1; + + using field_type = typename element_component::field_type; + using group_type = typename element_component::group_type; + + const element_component p1; + const element_component p2; + element_component result; + + const detail::blueprint_variable can_add; + + // intermediate variables + element_component p_to_add; + element_fp Y_intermediate_to_add1; + element_fp Y_intermediate_to_add2; + detail::blueprint_variable cannot_add; + + // TODO: refactor + // std::shared_ptr> el_add; + + element_g1_conditional_addition(blueprint &bp, + const element_component &in_p1, + const element_component &in_p2, + const detail::blueprint_variable &in_can_add, + const element_component &in_result) : + component(bp), p1(in_p1), p2(in_p2), can_add(in_can_add), p_to_add(bp), + result(in_result) { + detail::blueprint_variable Y_intermediate_to_add1_var, Y_intermediate_to_add2_var; + + Y_intermediate_to_add1_var.allocate(this->bp); + Y_intermediate_to_add2_var.allocate(this->bp); + cannot_add.allocate(this->bp); + + this->Y_intermediate_to_add1 = Y_intermediate_to_add1_var; + this->Y_intermediate_to_add2 = Y_intermediate_to_add2_var; // TODO: refactor - // std::shared_ptr> el_add; - - element_g1_conditional_addition(blueprint &bp, - const element_component &in_p1, - const element_component &in_p2, - const detail::blueprint_variable &in_can_add, - const element_component &in_result) : - component(bp), - p1(in_p1), p2(in_p2), can_add(in_can_add), p_to_add(bp), result(in_result) { - detail::blueprint_variable Y_intermediate_to_add1_var, Y_intermediate_to_add2_var; - - Y_intermediate_to_add1_var.allocate(this->bp); - Y_intermediate_to_add2_var.allocate(this->bp); - cannot_add.allocate(this->bp); - - this->Y_intermediate_to_add1 = Y_intermediate_to_add1_var; - this->Y_intermediate_to_add2 = Y_intermediate_to_add2_var; - - // TODO: refactor - // el_add.reset(new element_g1_add(this->bp, a, d, p1, P_toAdd, p1pp2)); - } + // el_add.reset(new element_g1_add(this->bp, a, d, p1, P_toAdd, p1pp2)); + } + + void generate_gates() { + // if coef == 1 then x_ret[i] + x_base + // x_add[i] = coef[i] * x_base; + this->bp.add_r1cs_constraint(crypto3::zk::snark::r1cs_constraint( + {this->p2.X}, {this->can_add}, {this->p_to_add.X})); + + // else do nothing. Ie add the zero point (0, 1) + // y_add[i] = coef[i] * y_base + !coef[i]; + this->bp.add_r1cs_constraint(crypto3::zk::snark::r1cs_constraint( + {this->p2.Y}, {this->can_add}, {this->Y_intermediate_to_add1})); + + // not coef + // make sure canAdd == 0 or canAdd == 1 + this->bp.add_r1cs_constraint(crypto3::zk::snark::r1cs_constraint( + this->can_add, field_type::value_type::one() - this->can_add, field_type::value_type::zero())); + + // make sure not_canAdd == 0 or not_canAdd == 1 + this->bp.add_r1cs_constraint(crypto3::zk::snark::r1cs_constraint( + this->cannot_add, + field_type::value_type::one() - this->cannot_add, + field_type::value_type::zero())); + + // make sure that the sum of canAdd, not_canAdd == 1 which means canAdd!=not_canAdd + this->bp.add_r1cs_constraint( + crypto3::zk::snark::r1cs_constraint({this->cannot_add, this->can_add}, + {field_type::value_type::one()}, + {field_type::value_type::one()})); + + // because the are bool and because they are not equal we know that the inverse of one is the + // other. + this->bp.add_r1cs_constraint(crypto3::zk::snark::r1cs_constraint( + {this->cannot_add}, {field_type::value_type::one()}, {this->Y_intermediate_to_add2})); + + this->bp.add_r1cs_constraint(crypto3::zk::snark::r1cs_constraint( + {this->Y_intermediate_to_add1, this->Y_intermediate_to_add2}, + {field_type::value_type::one()}, + {this->p_to_add.Y})); - void generate_gates() { - // if coef == 1 then x_ret[i] + x_base - // x_add[i] = coef[i] * x_base; - this->bp.add_r1cs_constraint( - snark::r1cs_constraint({this->p2.X}, {this->can_add}, {this->p_to_add.X})); - - // else do nothing. Ie add the zero point (0, 1) - // y_add[i] = coef[i] * y_base + !coef[i]; - this->bp.add_r1cs_constraint(snark::r1cs_constraint( - {this->p2.Y}, {this->can_add}, {this->Y_intermediate_to_add1})); - - // not coef - // make sure canAdd == 0 or canAdd == 1 - this->bp.add_r1cs_constraint( - snark::r1cs_constraint(this->can_add, - field_type::value_type::one() - this->can_add, - field_type::value_type::zero())); - - // make sure not_canAdd == 0 or not_canAdd == 1 - this->bp.add_r1cs_constraint( - snark::r1cs_constraint(this->cannot_add, - field_type::value_type::one() - this->cannot_add, - field_type::value_type::zero())); - - // make sure that the sum of canAdd, not_canAdd == 1 which means canAdd!=not_canAdd - this->bp.add_r1cs_constraint( - snark::r1cs_constraint({this->cannot_add, this->can_add}, - {field_type::value_type::one()}, - {field_type::value_type::one()})); - - // because the are bool and because they are not equal we know that the inverse of one is the - // other. - this->bp.add_r1cs_constraint(snark::r1cs_constraint( - {this->cannot_add}, {field_type::value_type::one()}, {this->Y_intermediate_to_add2})); - - this->bp.add_r1cs_constraint(snark::r1cs_constraint( - {this->Y_intermediate_to_add1, this->Y_intermediate_to_add2}, - {field_type::value_type::one()}, - {this->p_to_add.Y})); - - // TODO: refactor - // do the addition of either y1 , y1 plus x2, y2 if canAdd == true else x1 , y1 + 0 - // el_add->generate_gates(); + // TODO: refactor + // do the addition of either y1 , y1 plus x2, y2 if canAdd == true else x1 , y1 + 0 + // el_add->generate_gates(); + } + + void generate_assignments() { + this->bp.lc_val(this->p_to_add.X) = this->bp.lc_val(this->p2.X) * this->bp.val(this->can_add); + this->bp.lc_val(this->Y_intermediate_to_add1) = + this->bp.lc_val(this->p2.Y) * this->bp.val(this->can_add); + + if (this->bp.val(this->can_add) == field_type::value_type::one()) { + this->bp.val(this->cannot_add) = field_type::value_type::zero(); + this->bp.lc_val(this->Y_intermediate_to_add2) = + this->bp.val(this->cannot_add) * field_type::value_type::one(); + this->bp.lc_val(this->p_to_add.Y) = this->bp.lc_val(this->Y_intermediate_to_add1); + } else { + this->bp.val(this->cannot_add) = field_type::value_type::one(); + this->bp.lc_val(this->Y_intermediate_to_add2) = + this->bp.val(this->cannot_add) * field_type::value_type::one(); + this->bp.lc_val(this->p_to_add.Y) = field_type::value_type::one(); } - void generate_assignments() { - this->bp.lc_val(this->p_to_add.X) = this->bp.lc_val(this->p2.X) * this->bp.val(this->can_add); - this->bp.lc_val(this->Y_intermediate_to_add1) = - this->bp.lc_val(this->p2.Y) * this->bp.val(this->can_add); - - if (this->bp.val(this->can_add) == field_type::value_type::one()) { - this->bp.val(this->cannot_add) = field_type::value_type::zero(); - this->bp.lc_val(this->Y_intermediate_to_add2) = - this->bp.val(this->cannot_add) * field_type::value_type::one(); - this->bp.lc_val(this->p_to_add.Y) = this->bp.lc_val(this->Y_intermediate_to_add1); - } else { - this->bp.val(this->cannot_add) = field_type::value_type::one(); - this->bp.lc_val(this->Y_intermediate_to_add2) = - this->bp.val(this->cannot_add) * field_type::value_type::one(); - this->bp.lc_val(this->p_to_add.Y) = field_type::value_type::one(); - } - - // TODO: refactor - // el_add->generate_assignments(); - } - }; - } // namespace components - } // namespace blueprint - } // namespace crypto3 + // TODO: refactor + // el_add->generate_assignments(); + } + }; + } // namespace components + } // namespace blueprint } // namespace nil #endif // CRYPTO3_BLUEPRINT_COMPONENTS_TWISTED_EDWARDS_G1_COMPONENT_HPP diff --git a/include/nil/blueprint/components/algebra/curves/weierstrass/r1cs/element_g1.hpp b/include/nil/blueprint/components/algebra/curves/weierstrass/r1cs/element_g1.hpp index 2c177f7e5..e140217ed 100644 --- a/include/nil/blueprint/components/algebra/curves/weierstrass/r1cs/element_g1.hpp +++ b/include/nil/blueprint/components/algebra/curves/weierstrass/r1cs/element_g1.hpp @@ -32,7 +32,7 @@ #define CRYPTO3_BLUEPRINT_COMPONENTS_WEIERSTRASS_G1_COMPONENT_HPP #include -#include +#include #include namespace nil { diff --git a/include/nil/blueprint/components/algebra/fields/plonk/addition.hpp b/include/nil/blueprint/components/algebra/fields/plonk/addition.hpp index d3aa1a1bd..8d360f966 100644 --- a/include/nil/blueprint/components/algebra/fields/plonk/addition.hpp +++ b/include/nil/blueprint/components/algebra/fields/plonk/addition.hpp @@ -51,9 +51,8 @@ namespace nil { class addition; template - class addition, - BlueprintFieldType, NonNativePolicyType> - : public plonk_component { + class addition, BlueprintFieldType, + NonNativePolicyType> : public plonk_component { public: using component_type = plonk_component; @@ -68,17 +67,14 @@ namespace nil { } }; - static gate_manifest get_gate_manifest(std::size_t witness_amount, - std::size_t lookup_column_amount) { + static gate_manifest get_gate_manifest(std::size_t witness_amount, std::size_t lookup_column_amount) { static gate_manifest manifest = gate_manifest(gate_manifest_type()); return manifest; } static manifest_type get_manifest() { - static manifest_type manifest = manifest_type( - std::shared_ptr(new manifest_single_value_param(3)), - false - ); + static manifest_type manifest = + manifest_type(std::shared_ptr(new manifest_single_value_param(3)), false); return manifest; } @@ -132,8 +128,7 @@ namespace nil { std::initializer_list constants, std::initializer_list - public_inputs) : - component_type(witnesses, constants, public_inputs, get_manifest()) {}; + public_inputs) : component_type(witnesses, constants, public_inputs, get_manifest()) {}; static typename BlueprintFieldType::value_type calculate(typename BlueprintFieldType::value_type x, typename BlueprintFieldType::value_type y) { @@ -142,19 +137,15 @@ namespace nil { }; template - using plonk_native_addition = - addition, - BlueprintFieldType, basic_non_native_policy>; + using plonk_native_addition = addition, + BlueprintFieldType, basic_non_native_policy>; template - typename plonk_native_addition::result_type - generate_assignments( - const plonk_native_addition &component, - assignment> - &assignment, - const typename plonk_native_addition::input_type - instance_input, - const std::uint32_t start_row_index) { + typename plonk_native_addition::result_type generate_assignments( + const plonk_native_addition &component, + assignment> &assignment, + const typename plonk_native_addition::input_type instance_input, + const std::uint32_t start_row_index) { const std::size_t j = start_row_index; @@ -162,34 +153,28 @@ namespace nil { assignment.witness(component.W(1), j) = var_value(assignment, instance_input.y); assignment.witness(component.W(2), j) = var_value(assignment, instance_input.x) + var_value(assignment, instance_input.y); - return typename plonk_native_addition::result_type( - component, start_row_index); + return typename plonk_native_addition::result_type(component, start_row_index); } template - typename plonk_native_addition::result_type - generate_empty_assignments( - const plonk_native_addition &component, - assignment> - &assignment, - const typename plonk_native_addition::input_type - instance_input, - const std::uint32_t start_row_index) { + typename plonk_native_addition::result_type generate_empty_assignments( + const plonk_native_addition &component, + assignment> &assignment, + const typename plonk_native_addition::input_type instance_input, + const std::uint32_t start_row_index) { using component_type = plonk_native_addition; assignment.witness(component.W(2), start_row_index) = component_type::calculate( var_value(assignment, instance_input.x), var_value(assignment, instance_input.y)); - return typename plonk_native_addition::result_type( - component, start_row_index); + return typename plonk_native_addition::result_type(component, start_row_index); } template - std::size_t generate_gates( - const plonk_native_addition &component, - circuit> &bp, - assignment> &assignment, - const typename plonk_native_addition::input_type - &instance_input) { + std::size_t + generate_gates(const plonk_native_addition &component, + circuit> &bp, + assignment> &assignment, + const typename plonk_native_addition::input_type &instance_input) { using var = typename plonk_native_addition::var; @@ -202,10 +187,8 @@ namespace nil { void generate_copy_constraints( const plonk_native_addition &component, circuit> &bp, - assignment> - &assignment, - const typename plonk_native_addition::input_type - &instance_input, + assignment> &assignment, + const typename plonk_native_addition::input_type &instance_input, const std::size_t start_row_index) { using var = typename plonk_native_addition::var; @@ -222,8 +205,7 @@ namespace nil { const plonk_native_addition &component, circuit> &bp, assignment> &assignment, - const typename plonk_native_addition::input_type - &instance_input, + const typename plonk_native_addition::input_type &instance_input, const std::size_t start_row_index) { std::size_t selector_index = generate_gates(component, bp, assignment, instance_input); @@ -232,11 +214,10 @@ namespace nil { generate_copy_constraints(component, bp, assignment, instance_input, start_row_index); - return typename plonk_native_addition::result_type( - component, start_row_index); + return typename plonk_native_addition::result_type(component, start_row_index); } } // namespace components - } // namespace blueprint + } // namespace blueprint } // namespace nil #endif // CRYPTO3_BLUEPRINT_PLONK_FIELD_ADDITION_HPP diff --git a/include/nil/blueprint/components/algebra/fields/plonk/combined_inner_product.hpp b/include/nil/blueprint/components/algebra/fields/plonk/combined_inner_product.hpp index b2fb8b0d3..0ad9a65ab 100644 --- a/include/nil/blueprint/components/algebra/fields/plonk/combined_inner_product.hpp +++ b/include/nil/blueprint/components/algebra/fields/plonk/combined_inner_product.hpp @@ -40,180 +40,176 @@ #include namespace nil { - namespace crypto3 { - namespace blueprint { - namespace components { + namespace blueprint { + namespace components { - template - class combined_inner_product; + template + class combined_inner_product; - template - class combined_inner_product, - k, W0, W1, W2, W3, W4, W5, W6, W7, W8, W9, W10, W11, W12, W13, W14> { + template + class combined_inner_product, k, W0, W1, W2, + W3, W4, W5, W6, W7, W8, W9, W10, W11, W12, W13, W14> { - typedef snark::plonk_constraint_system - ArithmetizationType; + typedef crypto3::zk::snark::plonk_constraint_system ArithmetizationType; - using var = snark::plonk_variable; + using var = crypto3::zk::snark::plonk_variable; - constexpr static const std::size_t selector_seed = 0xff70; + constexpr static const std::size_t selector_seed = 0xff70; - constexpr static const std::size_t witness_per_row = 5; + constexpr static const std::size_t witness_per_row = 5; - constexpr static const std::size_t main_rows = - (k + ((witness_per_row - (k % witness_per_row)) % witness_per_row)) / witness_per_row; + constexpr static const std::size_t main_rows = + (k + ((witness_per_row - (k % witness_per_row)) % witness_per_row)) / witness_per_row; - public: - constexpr static const std::size_t rows_amount = 1 + main_rows; - constexpr static const std::size_t gates_amount = 1; + public: + constexpr static const std::size_t rows_amount = 1 + main_rows; + constexpr static const std::size_t gates_amount = 1; - struct params_type { - std::array f_zeta1; - std::array f_zeta2; - var xi; - var r; - }; - - struct result_type { - var output; - - result_type(const params_type ¶ms, std::size_t component_start_row) { - output = var(W2, component_start_row + rows_amount - 1, false); - } - }; - - static result_type - generate_circuit(blueprint &bp, - blueprint_public_assignment_table &assignment, - const params_type ¶ms, - std::size_t start_row_index) { + struct params_type { + std::array f_zeta1; + std::array f_zeta2; + var xi; + var r; + }; - generate_assignments_constant(bp, assignment, params, start_row_index); + struct result_type { + var output; - auto selector_iterator = assignment.find_selector(selector_seed); - std::size_t first_selector_index; + result_type(const params_type ¶ms, std::size_t component_start_row) { + output = var(W2, component_start_row + rows_amount - 1, false); + } + }; - if (selector_iterator == assignment.selectors_end()) { - first_selector_index = assignment.allocate_selector(selector_seed, gates_amount); - generate_gates(bp, assignment, params, first_selector_index); - } else { - first_selector_index = selector_iterator->second; - } + static result_type generate_circuit(blueprint &bp, + assignment &assignment, + const params_type ¶ms, + std::size_t start_row_index) { - assignment.enable_selector(first_selector_index, start_row_index, - start_row_index + rows_amount - 2); + generate_assignments_constant(bp, assignment, params, start_row_index); - generate_copy_constraints(bp, assignment, params, start_row_index); + auto selector_iterator = assignment.find_selector(selector_seed); + std::size_t first_selector_index; - return result_type(params, start_row_index); + if (selector_iterator == assignment.selectors_end()) { + first_selector_index = assignment.allocate_selector(selector_seed, gates_amount); + generate_gates(bp, assignment, params, first_selector_index); + } else { + first_selector_index = selector_iterator->second; } - static result_type generate_assignments(blueprint_assignment_table &assignment, - const params_type ¶ms, - std::size_t start_row_index) { - std::size_t row = start_row_index; - typename BlueprintFieldType::value_type xi = assignment.var_value(params.xi); - typename BlueprintFieldType::value_type r = assignment.var_value(params.r); - constexpr static const std::size_t rem = k % witness_per_row; - constexpr static const std::size_t k_size = k + ((witness_per_row - rem) % witness_per_row); - std::array f_zeta1; - std::array f_zeta2; - for (std::size_t i = 0; i < k_size; i++) { - if (i < k) { - f_zeta1[i] = assignment.var_value(params.f_zeta1[i]); - f_zeta2[i] = assignment.var_value(params.f_zeta2[i]); - } else { - f_zeta1[i] = 0; - f_zeta2[i] = 0; - } - } - typename BlueprintFieldType::value_type s = 0; - typename BlueprintFieldType::value_type acc_xi = 1; - - for (std::size_t i = row; i < row + rows_amount - 1; i++) { - assignment.witness(W0)[i] = r; - assignment.witness(W1)[i] = acc_xi; - assignment.witness(W2)[i] = s; - for (std::size_t j = 0; j < witness_per_row; j++) { - s += acc_xi * (f_zeta1[(i - row) * witness_per_row + j] + - r * f_zeta2[(i - row) * witness_per_row + j]); - acc_xi *= xi; - assignment.witness(3 + j * 2)[i] = f_zeta1[(i - row) * witness_per_row + j]; - assignment.witness(4 + j * 2)[i] = f_zeta2[(i - row) * witness_per_row + j]; - } - assignment.witness(W13)[i] = xi; + assignment.enable_selector(first_selector_index, start_row_index, + start_row_index + rows_amount - 2); + + generate_copy_constraints(bp, assignment, params, start_row_index); + + return result_type(params, start_row_index); + } + + static result_type generate_assignments(assignment &assignment, + const params_type ¶ms, + std::size_t start_row_index) { + std::size_t row = start_row_index; + typename BlueprintFieldType::value_type xi = assignment.var_value(params.xi); + typename BlueprintFieldType::value_type r = assignment.var_value(params.r); + constexpr static const std::size_t rem = k % witness_per_row; + constexpr static const std::size_t k_size = k + ((witness_per_row - rem) % witness_per_row); + std::array f_zeta1; + std::array f_zeta2; + for (std::size_t i = 0; i < k_size; i++) { + if (i < k) { + f_zeta1[i] = assignment.var_value(params.f_zeta1[i]); + f_zeta2[i] = assignment.var_value(params.f_zeta2[i]); + } else { + f_zeta1[i] = 0; + f_zeta2[i] = 0; } - assignment.witness(W0)[row + rows_amount - 1] = r; - assignment.witness(W1)[row + rows_amount - 1] = acc_xi; - assignment.witness(W2)[row + rows_amount - 1] = s; - assignment.witness(W13)[row + rows_amount - 1] = xi; - - return result_type(params, start_row_index); } + typename BlueprintFieldType::value_type s = 0; + typename BlueprintFieldType::value_type acc_xi = 1; - private: - static void generate_gates(blueprint &bp, - blueprint_public_assignment_table &assignment, - const params_type ¶ms, - const std::size_t first_selector_index) { - - auto constraint_1 = bp.add_constraint(var(W0, 0) - var(W0, +1)); - auto constraint_2 = bp.add_constraint(var(W13, 0) - var(W13, +1)); - snark::plonk_constraint xi_deg = var(W13, +1); - for (int i = 0; i < witness_per_row - 1; i++) { - xi_deg = xi_deg * var(W13, +1); - } - auto constraint_3 = bp.add_constraint(var(W1, +1) - var(W1, 0) * xi_deg); - snark::plonk_constraint s = var(W2, 0); - snark::plonk_constraint acc_xi = var(W1, 0); + for (std::size_t i = row; i < row + rows_amount - 1; i++) { + assignment.witness(W0)[i] = r; + assignment.witness(W1)[i] = acc_xi; + assignment.witness(W2)[i] = s; for (std::size_t j = 0; j < witness_per_row; j++) { - s = s + acc_xi * (var(3 + j * 2, 0) + var(W0, 0) * var(4 + j * 2, 0)); - acc_xi = acc_xi * var(W13, 0); + s += acc_xi * (f_zeta1[(i - row) * witness_per_row + j] + + r * f_zeta2[(i - row) * witness_per_row + j]); + acc_xi *= xi; + assignment.witness(3 + j * 2)[i] = f_zeta1[(i - row) * witness_per_row + j]; + assignment.witness(4 + j * 2)[i] = f_zeta2[(i - row) * witness_per_row + j]; } - auto constraint_4 = bp.add_constraint(var(W2, +1) - s); - - bp.add_gate(first_selector_index, {constraint_1, constraint_2, constraint_3, constraint_4}); + assignment.witness(W13)[i] = xi; } - - static void - generate_copy_constraints(blueprint &bp, - blueprint_public_assignment_table &assignment, - const params_type ¶ms, - std::size_t component_start_row) { - bp.add_copy_constraint({{W0, static_cast(component_start_row), false}, params.r}); - bp.add_copy_constraint({{W13, static_cast(component_start_row), false}, params.xi}); - bp.add_copy_constraint({{W1, static_cast(component_start_row), false}, - {0, static_cast(component_start_row + 1), false, var::column_type::constant}}); - bp.add_copy_constraint({{W2, static_cast(component_start_row), false}, - {0, static_cast(component_start_row), false, var::column_type::constant}}); - - for (std::size_t i = 0; i < k; i++) { - bp.add_copy_constraint( - {{3 + (2 * i) % 10, static_cast(component_start_row + (i / 5)), false}, - params.f_zeta1[i]}); - bp.add_copy_constraint( - {{4 + (2 * i) % 10, static_cast(component_start_row + (i / 5)), false}, - params.f_zeta2[i]}); - } + assignment.witness(W0)[row + rows_amount - 1] = r; + assignment.witness(W1)[row + rows_amount - 1] = acc_xi; + assignment.witness(W2)[row + rows_amount - 1] = s; + assignment.witness(W13)[row + rows_amount - 1] = xi; + + return result_type(params, start_row_index); + } + + private: + static void generate_gates(blueprint &bp, + assignment &assignment, + const params_type ¶ms, + const std::size_t first_selector_index) { + + auto constraint_1 = bp.add_constraint(var(W0, 0) - var(W0, +1)); + auto constraint_2 = bp.add_constraint(var(W13, 0) - var(W13, +1)); + crypto3::zk::snark::plonk_constraint xi_deg = var(W13, +1); + for (int i = 0; i < witness_per_row - 1; i++) { + xi_deg = xi_deg * var(W13, +1); } - - static void generate_assignments_constant( - blueprint &bp, - blueprint_public_assignment_table &assignment, - const params_type ¶ms, - std::size_t component_start_row) { - std::size_t row = component_start_row; - - assignment.constant(0)[row] = 0; - assignment.constant(0)[row + 1] = 1; + auto constraint_3 = bp.add_constraint(var(W1, +1) - var(W1, 0) * xi_deg); + crypto3::zk::snark::plonk_constraint s = var(W2, 0); + crypto3::zk::snark::plonk_constraint acc_xi = var(W1, 0); + for (std::size_t j = 0; j < witness_per_row; j++) { + s = s + acc_xi * (var(3 + j * 2, 0) + var(W0, 0) * var(4 + j * 2, 0)); + acc_xi = acc_xi * var(W13, 0); } - }; - } // namespace components - } // namespace blueprint - } // namespace crypto3 + auto constraint_4 = bp.add_constraint(var(W2, +1) - s); + + bp.add_gate(first_selector_index, {constraint_1, constraint_2, constraint_3, constraint_4}); + } + + static void generate_copy_constraints(blueprint &bp, + assignment &assignment, + const params_type ¶ms, + std::size_t component_start_row) { + bp.add_copy_constraint({{W0, static_cast(component_start_row), false}, params.r}); + bp.add_copy_constraint({{W13, static_cast(component_start_row), false}, params.xi}); + bp.add_copy_constraint( + {{W1, static_cast(component_start_row), false}, + {0, static_cast(component_start_row + 1), false, var::column_type::constant}}); + bp.add_copy_constraint( + {{W2, static_cast(component_start_row), false}, + {0, static_cast(component_start_row), false, var::column_type::constant}}); + + for (std::size_t i = 0; i < k; i++) { + bp.add_copy_constraint( + {{3 + (2 * i) % 10, static_cast(component_start_row + (i / 5)), false}, + params.f_zeta1[i]}); + bp.add_copy_constraint( + {{4 + (2 * i) % 10, static_cast(component_start_row + (i / 5)), false}, + params.f_zeta2[i]}); + } + } + + static void generate_assignments_constant(blueprint &bp, + assignment &assignment, + const params_type ¶ms, + std::size_t component_start_row) { + std::size_t row = component_start_row; + + assignment.constant(0)[row] = 0; + assignment.constant(0)[row + 1] = 1; + } + }; + } // namespace components + } // namespace blueprint } // namespace nil #endif // CRYPTO3_BLUEPRINT_COMPONENTS_PLONK_FIELD_COMBINED_INNER_PRODUCT_HPP \ No newline at end of file diff --git a/include/nil/blueprint/components/algebra/fields/plonk/division_or_zero.hpp b/include/nil/blueprint/components/algebra/fields/plonk/division_or_zero.hpp index 6c9e56c33..4e44cb6c5 100644 --- a/include/nil/blueprint/components/algebra/fields/plonk/division_or_zero.hpp +++ b/include/nil/blueprint/components/algebra/fields/plonk/division_or_zero.hpp @@ -49,8 +49,7 @@ namespace nil { class division_or_zero; template - class division_or_zero, - BlueprintFieldType> + class division_or_zero, BlueprintFieldType> : public plonk_component { public: @@ -63,8 +62,7 @@ namespace nil { } }; - static gate_manifest get_gate_manifest(std::size_t witness_amount, - std::size_t lookup_column_amount) { + static gate_manifest get_gate_manifest(std::size_t witness_amount, std::size_t lookup_column_amount) { static gate_manifest manifest = gate_manifest(gate_manifest_type()); return manifest; } @@ -85,10 +83,8 @@ namespace nil { using manifest_type = plonk_component_manifest; static manifest_type get_manifest() { - static manifest_type manifest = manifest_type( - std::shared_ptr(new manifest_single_value_param(5)), - false - ); + static manifest_type manifest = + manifest_type(std::shared_ptr(new manifest_single_value_param(5)), false); return manifest; } @@ -116,23 +112,22 @@ namespace nil { } }; - template - division_or_zero(ContainerType witness): - component_type(witness, {}, {}, get_manifest()){}; + template + division_or_zero(ContainerType witness) : component_type(witness, {}, {}, get_manifest()) {}; - template + template division_or_zero(WitnessContainerType witness, ConstantContainerType constant, - PublicInputContainerType public_input): - component_type(witness, constant, public_input, get_manifest()){}; + PublicInputContainerType public_input) : + component_type(witness, constant, public_input, get_manifest()) {}; - division_or_zero(std::initializer_list< - typename component_type::witness_container_type::value_type> witnesses, - std::initializer_list< - typename component_type::constant_container_type::value_type> constants, - std::initializer_list< - typename component_type::public_input_container_type::value_type> public_inputs): - component_type(witnesses, constants, public_inputs, get_manifest()){}; + division_or_zero(std::initializer_list + witnesses, + std::initializer_list + constants, + std::initializer_list + public_inputs) : + component_type(witnesses, constants, public_inputs, get_manifest()) {}; static typename BlueprintFieldType::value_type calculate(typename BlueprintFieldType::value_type x, typename BlueprintFieldType::value_type y) { @@ -142,41 +137,40 @@ namespace nil { template using plonk_division_or_zero = - division_or_zero, - BlueprintFieldType>; + division_or_zero, BlueprintFieldType>; template - typename plonk_division_or_zero::result_type - generate_assignments( - const plonk_division_or_zero &component, - assignment> &assignment, - const typename plonk_division_or_zero::input_type instance_input, - const std::uint32_t start_row_index) { + typename plonk_division_or_zero::result_type generate_assignments( + const plonk_division_or_zero &component, + assignment> &assignment, + const typename plonk_division_or_zero::input_type instance_input, + const std::uint32_t start_row_index) { const std::size_t j = start_row_index; assignment.witness(component.W(0), j) = var_value(assignment, instance_input.x); assignment.witness(component.W(1), j) = var_value(assignment, instance_input.y); if (var_value(assignment, instance_input.y) != 0) { - assignment.witness(component.W(2), j) = var_value(assignment, instance_input.x) / - var_value(assignment, instance_input.y); + assignment.witness(component.W(2), j) = + var_value(assignment, instance_input.x) / var_value(assignment, instance_input.y); } else { assignment.witness(component.W(2), j) = 0; } assignment.witness(component.W(3), j) = (var_value(assignment, instance_input.y) == 0) ? - 0 : var_value(assignment, instance_input.y).inversed(); - assignment.witness(component.W(4), j) = var_value(assignment, instance_input.y) * assignment.witness(component.W(3), j); + 0 : + var_value(assignment, instance_input.y).inversed(); + assignment.witness(component.W(4), j) = + var_value(assignment, instance_input.y) * assignment.witness(component.W(3), j); return typename plonk_division_or_zero::result_type(component, start_row_index); } template - typename plonk_division_or_zero::result_type - generate_empty_assignments( - const plonk_division_or_zero &component, - assignment> &assignment, - const typename plonk_division_or_zero::input_type instance_input, - const std::uint32_t start_row_index) { + typename plonk_division_or_zero::result_type generate_empty_assignments( + const plonk_division_or_zero &component, + assignment> &assignment, + const typename plonk_division_or_zero::input_type instance_input, + const std::uint32_t start_row_index) { using component_type = plonk_division_or_zero; assignment.witness(component.W(2), start_row_index) = component_type::calculate( @@ -186,11 +180,11 @@ namespace nil { } template - std::size_t generate_gates( - const plonk_division_or_zero &component, - circuit> &bp, - assignment> &assignment, - const typename plonk_division_or_zero::input_type &instance_input) { + std::size_t + generate_gates(const plonk_division_or_zero &component, + circuit> &bp, + assignment> &assignment, + const typename plonk_division_or_zero::input_type &instance_input) { using var = typename plonk_division_or_zero::var; @@ -220,13 +214,12 @@ namespace nil { } template - typename plonk_division_or_zero::result_type - generate_circuit( - const plonk_division_or_zero &component, - circuit> &bp, - assignment> &assignment, - const typename plonk_division_or_zero::input_type &instance_input, - const std::size_t start_row_index){ + typename plonk_division_or_zero::result_type generate_circuit( + const plonk_division_or_zero &component, + circuit> &bp, + assignment> &assignment, + const typename plonk_division_or_zero::input_type &instance_input, + const std::size_t start_row_index) { std::size_t selector_index = generate_gates(component, bp, assignment, instance_input); @@ -237,7 +230,7 @@ namespace nil { return typename plonk_division_or_zero::result_type(component, start_row_index); } } // namespace components - } // namespace blueprint + } // namespace blueprint } // namespace nil #endif // CRYPTO3_BLUEPRINT_COMPONENTS_PLONK_FIELD_DIVISION_OR_ZERO_HPP diff --git a/include/nil/blueprint/components/algebra/fields/plonk/exponentiation.hpp b/include/nil/blueprint/components/algebra/fields/plonk/exponentiation.hpp index e16406257..223a9099d 100644 --- a/include/nil/blueprint/components/algebra/fields/plonk/exponentiation.hpp +++ b/include/nil/blueprint/components/algebra/fields/plonk/exponentiation.hpp @@ -43,15 +43,15 @@ #include namespace nil { - namespace blueprint { - namespace components { + namespace blueprint { + namespace components { - // Input: exponent, base \in Fp - // Output: base**exponent - template - class exponentiation; + // Input: exponent, base \in Fp + // Output: base**exponent + template + class exponentiation; - // clang-format off + // clang-format off // res = base.pow(exponent) // _______________________________________________________________________________________________________________________________________________ // | W0 | W1 | W2 | W3 | W4 | W5 | W6 | W7 | W8 | W9 | W10 | W11 | W12 | W13 | W14 | @@ -60,309 +60,306 @@ namespace nil { // | ... | // | ... | ... | ... | ... | ... | ... | res | ... | ... | ... | ... | ... | ... | ... | ... | // ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾ - // clang-format on + // clang-format on - template - class exponentiation< - crypto3::zk::snark::plonk_constraint_system, - BlueprintFieldType, - ExponentSize - >: - public plonk_component { + template + class exponentiation, BlueprintFieldType, + ExponentSize> : public plonk_component { - constexpr static const std::size_t reserved_witnesses = 2; // base, accumulated_n + constexpr static const std::size_t reserved_witnesses = 2; // base, accumulated_n - static std::size_t intermediate_results_per_row_intenal(std::size_t witness_amount) { - return (witness_amount - reserved_witnesses) / (bits_per_intermediate_result + 1); - } - - static std::size_t bits_per_row_internal(std::size_t witness_amount) { - return intermediate_results_per_row_intenal(witness_amount) * bits_per_intermediate_result; - } - - static std::size_t main_rows_amount_internal(std::size_t witness_amount) { - return (ExponentSize + bits_per_row_internal(witness_amount) - 1) / - bits_per_row_internal(witness_amount); - } - - static std::size_t padded_exponent_size_internal(std::size_t witness_amount) { - return main_rows_amount_internal(witness_amount) * bits_per_row_internal(witness_amount); - } + static std::size_t intermediate_results_per_row_intenal(std::size_t witness_amount) { + return (witness_amount - reserved_witnesses) / (bits_per_intermediate_result + 1); + } - static std::size_t rows_amount_internal(std::size_t witness_amount) { - return main_rows_amount_internal(witness_amount) + 1; - } - public: - using component_type = plonk_component; + static std::size_t bits_per_row_internal(std::size_t witness_amount) { + return intermediate_results_per_row_intenal(witness_amount) * bits_per_intermediate_result; + } - using var = typename component_type::var; - using manifest_type = plonk_component_manifest; + static std::size_t main_rows_amount_internal(std::size_t witness_amount) { + return (ExponentSize + bits_per_row_internal(witness_amount) - 1) / + bits_per_row_internal(witness_amount); + } - class gate_manifest_type : public component_gate_manifest { - public: - std::uint32_t gates_amount() const override { - return exponentiation::gates_amount; - } - }; + static std::size_t padded_exponent_size_internal(std::size_t witness_amount) { + return main_rows_amount_internal(witness_amount) * bits_per_row_internal(witness_amount); + } - static gate_manifest get_gate_manifest(std::size_t witness_amount, - std::size_t lookup_column_amount) { - static gate_manifest manifest = gate_manifest(gate_manifest_type()); - return manifest; - } + static std::size_t rows_amount_internal(std::size_t witness_amount) { + return main_rows_amount_internal(witness_amount) + 1; + } + public: + using component_type = plonk_component; - static manifest_type get_manifest() { - static manifest_type manifest = manifest_type( - std::shared_ptr(new manifest_single_value_param(15)), - true - ); - return manifest; - } + using var = typename component_type::var; + using manifest_type = plonk_component_manifest; - constexpr static std::size_t get_rows_amount(std::size_t witness_amount, - std::size_t lookup_column_amount) { - return rows_amount_internal(witness_amount); + class gate_manifest_type : public component_gate_manifest { + public: + std::uint32_t gates_amount() const override { + return exponentiation::gates_amount; } + }; - constexpr static const std::size_t intermediate_start = 0 + reserved_witnesses; - constexpr static const std::size_t bits_per_intermediate_result = - 2; // defines - // max degree of the constraints - // 2 ** bits_per_intermediate_result - const std::size_t intermediate_results_per_row = - intermediate_results_per_row_intenal(this->witness_amount()); - const std::size_t bits_per_row = - bits_per_row_internal(this->witness_amount()); - const std::size_t main_rows = main_rows_amount_internal(this->witness_amount()); - const std::size_t padded_exponent_size = padded_exponent_size_internal(this->witness_amount()); - - const std::size_t rows_amount = rows_amount_internal(this->witness_amount()); - constexpr static const std::size_t gates_amount = 1; - struct input_type { - var base; - var exponent; - - std::vector> all_vars() { - return {base, exponent}; - } - }; + static gate_manifest get_gate_manifest(std::size_t witness_amount, std::size_t lookup_column_amount) { + static gate_manifest manifest = gate_manifest(gate_manifest_type()); + return manifest; + } - struct result_type { - var output = var(0, 0); + static manifest_type get_manifest() { + static manifest_type manifest = + manifest_type(std::shared_ptr(new manifest_single_value_param(15)), true); + return manifest; + } - result_type(const exponentiation &component, input_type ¶ms, std::size_t start_row_index) { - output = var(component.W(intermediate_start + component.intermediate_results_per_row - 1), - start_row_index + component.rows_amount - 1, false); - } + constexpr static std::size_t get_rows_amount(std::size_t witness_amount, + std::size_t lookup_column_amount) { + return rows_amount_internal(witness_amount); + } - result_type(const exponentiation &component, std::size_t start_row_index) { - output = var(component.W(intermediate_start + component.intermediate_results_per_row - 1), - start_row_index + component.rows_amount - 1, false); - } + constexpr static const std::size_t intermediate_start = 0 + reserved_witnesses; + constexpr static const std::size_t bits_per_intermediate_result = + 2; // defines + // max degree of the constraints + // 2 ** bits_per_intermediate_result + const std::size_t intermediate_results_per_row = + intermediate_results_per_row_intenal(this->witness_amount()); + const std::size_t bits_per_row = bits_per_row_internal(this->witness_amount()); + const std::size_t main_rows = main_rows_amount_internal(this->witness_amount()); + const std::size_t padded_exponent_size = padded_exponent_size_internal(this->witness_amount()); + + const std::size_t rows_amount = rows_amount_internal(this->witness_amount()); + constexpr static const std::size_t gates_amount = 1; + struct input_type { + var base; + var exponent; + + std::vector> all_vars() { + return {base, exponent}; + } + }; - std::vector> all_vars() { - return {output}; - } - }; + struct result_type { + var output = var(0, 0); - template - exponentiation(WitnessContainerType witness, ConstantContainerType constant, PublicInputContainerType public_input): - component_type(witness, constant, public_input, get_manifest()){}; + result_type(const exponentiation &component, input_type ¶ms, std::size_t start_row_index) { + output = var(component.W(intermediate_start + component.intermediate_results_per_row - 1), + start_row_index + component.rows_amount - 1, false); + } - exponentiation( - std::initializer_list witnesses, - std::initializer_list constants, - std::initializer_list public_inputs): - component_type(witnesses, constants, public_inputs, get_manifest()){}; + result_type(const exponentiation &component, std::size_t start_row_index) { + output = var(component.W(intermediate_start + component.intermediate_results_per_row - 1), + start_row_index + component.rows_amount - 1, false); + } + std::vector> all_vars() { + return {output}; + } }; - template - using plonk_exponentiation = - exponentiation< - crypto3::zk::snark::plonk_constraint_system, - BlueprintFieldType, - ExponentSize - >; - - template - typename plonk_exponentiation::result_type - generate_circuit( - const plonk_exponentiation &component, - circuit> &bp, - assignment> &assignment, - const typename plonk_exponentiation::input_type &instance_input, - const std::uint32_t start_row_index) { - - std::size_t selector_index = generate_gates(component, bp, assignment, instance_input); - assignment.enable_selector( - selector_index, start_row_index + 1, start_row_index + 1 + component.main_rows - 1); - - generate_copy_constraints(component, bp, assignment, instance_input, start_row_index); - generate_assignments_constants(component, bp, assignment, instance_input, start_row_index); - - return typename plonk_exponentiation::result_type(component, start_row_index); + template + exponentiation(WitnessContainerType witness, ConstantContainerType constant, + PublicInputContainerType public_input) : + component_type(witness, constant, public_input, get_manifest()) {}; + + exponentiation(std::initializer_list + witnesses, + std::initializer_list + constants, + std::initializer_list + public_inputs) : + component_type(witnesses, constants, public_inputs, get_manifest()) {}; + }; + + template + using plonk_exponentiation = exponentiation, + BlueprintFieldType, ExponentSize>; + + template + typename plonk_exponentiation::result_type generate_circuit( + const plonk_exponentiation &component, + circuit> &bp, + assignment> &assignment, + const typename plonk_exponentiation::input_type &instance_input, + const std::uint32_t start_row_index) { + + std::size_t selector_index = generate_gates(component, bp, assignment, instance_input); + assignment.enable_selector(selector_index, start_row_index + 1, + start_row_index + 1 + component.main_rows - 1); + + generate_copy_constraints(component, bp, assignment, instance_input, start_row_index); + generate_assignments_constants(component, bp, assignment, instance_input, start_row_index); + + return typename plonk_exponentiation::result_type(component, + start_row_index); + } + + template + typename plonk_exponentiation::result_type generate_assignments( + const plonk_exponentiation &component, + assignment> &assignment, + const typename plonk_exponentiation::input_type &instance_input, + const std::uint32_t start_row_index) { + + typename BlueprintFieldType::value_type base = var_value(assignment, instance_input.base); + typename BlueprintFieldType::value_type exponent = var_value(assignment, instance_input.exponent); + + std::vector bits(component.padded_exponent_size, false); + { + std::vector bbb; + auto data = exponent.data; + while (data != 0) { + bbb.push_back((data - (data >> 1 << 1)) != 0); + data = data >> 1; + } + for (std::uint32_t i = 1; i < component.padded_exponent_size - bbb.size(); ++i) { + bits[i] = false; + } + for (std::uint32_t i = 0; i < bbb.size(); ++i) { + bits[component.padded_exponent_size - 1 - i] = bbb[i]; } + } - template - typename plonk_exponentiation::result_type - generate_assignments( - const plonk_exponentiation &component, - assignment> &assignment, - const typename plonk_exponentiation::input_type &instance_input, - const std::uint32_t start_row_index) { - - typename BlueprintFieldType::value_type base = var_value(assignment, instance_input.base); - typename BlueprintFieldType::value_type exponent = var_value(assignment, instance_input.exponent); - - std::vector bits(component.padded_exponent_size, false); - { - std::vector bbb; - auto data = exponent.data; - while (data != 0) { - bbb.push_back((data - (data >> 1 << 1)) != 0); - data = data >> 1; - } - for (std::uint32_t i = 1; i < component.padded_exponent_size - bbb.size(); ++i) { - bits[i] = false; - } - for (std::uint32_t i = 0; i < bbb.size(); ++i) { - bits[component.padded_exponent_size - 1 - i] = bbb[i]; + typename BlueprintFieldType::value_type accumulated_n = 0; + typename BlueprintFieldType::value_type acc1 = 1; + + // we use first empty row to unify first row gate with others + assignment.witness(component.W(1), start_row_index) = 0; + assignment.witness(component.intermediate_start + component.intermediate_results_per_row - 1, + start_row_index) = 1; + std::size_t start_row_padded = start_row_index + 1; + + std::size_t current_bit = 0; + for (std::size_t row = start_row_padded; row < start_row_padded + component.main_rows; row++) { + assignment.witness(component.W(0), row) = base; + + for (std::size_t j = 0; j < component.intermediate_results_per_row; j++) { + typename BlueprintFieldType::value_type intermediate_exponent = 0; + for (std::size_t bit_column = 0; bit_column < component.bits_per_intermediate_result; + bit_column++) { + std::size_t column_idx = 14 - j * (component.bits_per_intermediate_result) - bit_column; + assignment.witness(component.W(column_idx), row) = bits[current_bit] ? 1 : 0; + // wierd stuff is here for oracles scalar + // std::cout<<"column_idx "<::result_type(component, start_row_index); - + accumulated_n = + (accumulated_n * (1 << component.bits_per_intermediate_result)) + intermediate_exponent; + assignment.witness(component.W(component.intermediate_start + j), row) = acc1; } + assignment.witness(component.W(1), row) = accumulated_n; + } - template - std::size_t generate_gates( - const plonk_exponentiation &component, - circuit> &bp, - assignment> &assignment, - const typename plonk_exponentiation::input_type instance_input) { - - using var = typename plonk_exponentiation::var; - - typename BlueprintFieldType::value_type exponent_shift = 2; - exponent_shift = power(exponent_shift, component.bits_per_row); - - std::vector> constraints; - - nil::crypto3::zk::snark::plonk_constraint accumulated_n_constraint; - for (std::size_t j = 0; j < component.intermediate_results_per_row; j++) { - nil::crypto3::zk::snark::plonk_constraint intermediate_result_constraint = - j == 0 ? var(component.W(component.intermediate_start + component.intermediate_results_per_row - 1), -1) : - var(component.W(component.intermediate_start + j - 1), 0); - - for (std::size_t bit_column = 0; bit_column < component.bits_per_intermediate_result; bit_column++) { - std::size_t column_idx = 14 - j * (component.bits_per_intermediate_result)-bit_column; - constraints.emplace_back( - var(component.W(column_idx), 0) * - (1 - var(component.W(column_idx), 0))); // fail on oracles scalar - - nil::crypto3::zk::snark::plonk_constraint bit_res = - var(component.W(0), 0) * var(component.W(column_idx), 0); - if (j == 0 && bit_column == 0) { - accumulated_n_constraint = var(component.W(column_idx), 0); - } else { - accumulated_n_constraint = 2 * accumulated_n_constraint + var(component.W(column_idx), 0); - } - intermediate_result_constraint = intermediate_result_constraint * - intermediate_result_constraint * - (bit_res + (1 - var(component.W(column_idx), 0))); - } - - intermediate_result_constraint = - intermediate_result_constraint - var(component.W(component.intermediate_start + j), 0); - constraints.push_back(intermediate_result_constraint); // fail on oracles scalar + return typename plonk_exponentiation::result_type(component, + start_row_index); + } + + template + std::size_t generate_gates( + const plonk_exponentiation &component, + circuit> &bp, + assignment> &assignment, + const typename plonk_exponentiation::input_type instance_input) { + + using var = typename plonk_exponentiation::var; + + typename BlueprintFieldType::value_type exponent_shift = 2; + exponent_shift = power(exponent_shift, component.bits_per_row); + + std::vector> constraints; + + nil::crypto3::zk::snark::plonk_constraint accumulated_n_constraint; + for (std::size_t j = 0; j < component.intermediate_results_per_row; j++) { + nil::crypto3::zk::snark::plonk_constraint intermediate_result_constraint = + j == 0 ? + var(component.W(component.intermediate_start + component.intermediate_results_per_row - 1), + -1) : + var(component.W(component.intermediate_start + j - 1), 0); + + for (std::size_t bit_column = 0; bit_column < component.bits_per_intermediate_result; + bit_column++) { + std::size_t column_idx = 14 - j * (component.bits_per_intermediate_result) - bit_column; + constraints.emplace_back(var(component.W(column_idx), 0) * + (1 - var(component.W(column_idx), 0))); // fail on oracles scalar + + nil::crypto3::zk::snark::plonk_constraint bit_res = + var(component.W(0), 0) * var(component.W(column_idx), 0); + if (j == 0 && bit_column == 0) { + accumulated_n_constraint = var(component.W(column_idx), 0); + } else { + accumulated_n_constraint = 2 * accumulated_n_constraint + var(component.W(column_idx), 0); } + intermediate_result_constraint = intermediate_result_constraint * + intermediate_result_constraint * + (bit_res + (1 - var(component.W(column_idx), 0))); + } - accumulated_n_constraint = accumulated_n_constraint + exponent_shift * var(component.W(1), -1) - var(component.W(1), 0); + intermediate_result_constraint = + intermediate_result_constraint - var(component.W(component.intermediate_start + j), 0); + constraints.push_back(intermediate_result_constraint); // fail on oracles scalar + } - constraints.push_back(accumulated_n_constraint); - return bp.add_gate(constraints); - } + accumulated_n_constraint = + accumulated_n_constraint + exponent_shift * var(component.W(1), -1) - var(component.W(1), 0); - template - void generate_copy_constraints( - const plonk_exponentiation &component, - circuit> &bp, - assignment> &assignment, - const typename plonk_exponentiation::input_type &instance_input, - const std::uint32_t start_row_index) { + constraints.push_back(accumulated_n_constraint); + return bp.add_gate(constraints); + } - using var = typename plonk_exponentiation::var; + template + void generate_copy_constraints( + const plonk_exponentiation &component, + circuit> &bp, + assignment> &assignment, + const typename plonk_exponentiation::input_type &instance_input, + const std::uint32_t start_row_index) { - var zero(component.W(0), start_row_index, false, var::column_type::constant); - var one(component.W(0), start_row_index + 1, false, var::column_type::constant); + using var = typename plonk_exponentiation::var; - for (std::size_t row = start_row_index + 1; row < start_row_index + component.rows_amount; row++) { - bp.add_copy_constraint({{component.W(0), static_cast(row), false}, instance_input.base}); - } - bp.add_copy_constraint({{component.W(1), static_cast(start_row_index), false}, zero}); - bp.add_copy_constraint({{component.W(component.intermediate_start + component.intermediate_results_per_row - 1), - static_cast(start_row_index), false}, - one}); - // check that the recalculated n is equal to the input challenge - bp.add_copy_constraint( - {{component.W(1), static_cast(start_row_index + component.rows_amount - 1), false}, instance_input.exponent}); // fail on oracles scalar - } + var zero(component.W(0), start_row_index, false, var::column_type::constant); + var one(component.W(0), start_row_index + 1, false, var::column_type::constant); - template - void generate_assignments_constants( - const plonk_exponentiation &component, - circuit> &bp, - assignment> &assignment, - const typename plonk_exponentiation::input_type &instance_input, - const std::uint32_t start_row_index) { - - std::size_t row = start_row_index; - assignment.constant(component.C(0), row) = 0; - row++; - assignment.constant(component.C(0), row) = 1; - row++; + for (std::size_t row = start_row_index + 1; row < start_row_index + component.rows_amount; row++) { + bp.add_copy_constraint({{component.W(0), static_cast(row), false}, instance_input.base}); } - } // namespace components - } // namespace blueprint + bp.add_copy_constraint({{component.W(1), static_cast(start_row_index), false}, zero}); + bp.add_copy_constraint( + {{component.W(component.intermediate_start + component.intermediate_results_per_row - 1), + static_cast(start_row_index), false}, + one}); + // check that the recalculated n is equal to the input challenge + bp.add_copy_constraint( + {{component.W(1), static_cast(start_row_index + component.rows_amount - 1), false}, + instance_input.exponent}); // fail on oracles scalar + } + + template + void generate_assignments_constants( + const plonk_exponentiation &component, + circuit> &bp, + assignment> &assignment, + const typename plonk_exponentiation::input_type &instance_input, + const std::uint32_t start_row_index) { + + std::size_t row = start_row_index; + assignment.constant(component.C(0), row) = 0; + row++; + assignment.constant(component.C(0), row) = 1; + row++; + } + } // namespace components + } // namespace blueprint } // namespace nil #endif // CRYPTO3_ZK_BLUEPRINT_PLONK_FIELD_EXPONENTIATION_HPP \ No newline at end of file diff --git a/include/nil/blueprint/components/algebra/fields/plonk/multiplication.hpp b/include/nil/blueprint/components/algebra/fields/plonk/multiplication.hpp index eb727e079..dc54a8925 100644 --- a/include/nil/blueprint/components/algebra/fields/plonk/multiplication.hpp +++ b/include/nil/blueprint/components/algebra/fields/plonk/multiplication.hpp @@ -52,9 +52,8 @@ namespace nil { class multiplication; template - class multiplication, - BlueprintFieldType, NonNativePolicyType> - : public plonk_component { + class multiplication, BlueprintFieldType, + NonNativePolicyType> : public plonk_component { public: using component_type = plonk_component; @@ -69,17 +68,14 @@ namespace nil { } }; - static gate_manifest get_gate_manifest(std::size_t witness_amount, - std::size_t lookup_column_amount) { + static gate_manifest get_gate_manifest(std::size_t witness_amount, std::size_t lookup_column_amount) { static gate_manifest manifest = gate_manifest(gate_manifest_type()); return manifest; } static manifest_type get_manifest() { - static manifest_type manifest = manifest_type( - std::shared_ptr(new manifest_single_value_param(3)), - false - ); + static manifest_type manifest = + manifest_type(std::shared_ptr(new manifest_single_value_param(3)), false); return manifest; } @@ -145,18 +141,15 @@ namespace nil { template using plonk_multiplication = - multiplication, - BlueprintFieldType, basic_non_native_policy>; + multiplication, BlueprintFieldType, + basic_non_native_policy>; template - typename plonk_multiplication::result_type - generate_assignments( - const plonk_multiplication &component, - assignment> - &assignment, - const typename plonk_multiplication::input_type - instance_input, - const std::uint32_t start_row_index) { + typename plonk_multiplication::result_type generate_assignments( + const plonk_multiplication &component, + assignment> &assignment, + const typename plonk_multiplication::input_type instance_input, + const std::uint32_t start_row_index) { const std::size_t j = start_row_index; @@ -164,36 +157,29 @@ namespace nil { assignment.witness(component.W(1), j) = var_value(assignment, instance_input.y); assignment.witness(component.W(2), j) = var_value(assignment, instance_input.x) * var_value(assignment, instance_input.y); - return typename plonk_multiplication::result_type( - component, start_row_index); + return typename plonk_multiplication::result_type(component, start_row_index); } template - typename plonk_multiplication::result_type - generate_empty_assignments( - const plonk_multiplication &component, - assignment> - &assignment, - const typename plonk_multiplication::input_type - instance_input, - const std::uint32_t start_row_index) { + typename plonk_multiplication::result_type generate_empty_assignments( + const plonk_multiplication &component, + assignment> &assignment, + const typename plonk_multiplication::input_type instance_input, + const std::uint32_t start_row_index) { using component_type = plonk_multiplication; const std::size_t j = start_row_index; assignment.witness(component.W(2), j) = component_type::calculate( var_value(assignment, instance_input.x), var_value(assignment, instance_input.y)); - return typename plonk_multiplication::result_type( - component, start_row_index); + return typename plonk_multiplication::result_type(component, start_row_index); } template - std::size_t generate_gates( - const plonk_multiplication &component, - circuit> &bp, - assignment> - &assignment, - const typename plonk_multiplication::input_type - &instance_input) { + std::size_t + generate_gates(const plonk_multiplication &component, + circuit> &bp, + assignment> &assignment, + const typename plonk_multiplication::input_type &instance_input) { using var = typename plonk_multiplication::var; @@ -206,10 +192,8 @@ namespace nil { void generate_copy_constraints( const plonk_multiplication &component, circuit> &bp, - assignment> - &assignment, - const typename plonk_multiplication::input_type - &instance_input, + assignment> &assignment, + const typename plonk_multiplication::input_type &instance_input, const std::size_t start_row_index) { using var = typename plonk_multiplication::var; @@ -225,10 +209,8 @@ namespace nil { typename plonk_multiplication::result_type generate_circuit( const plonk_multiplication &component, circuit> &bp, - assignment> - &assignment, - const typename plonk_multiplication::input_type - &instance_input, + assignment> &assignment, + const typename plonk_multiplication::input_type &instance_input, const std::size_t start_row_index) { std::size_t selector_index = generate_gates(component, bp, assignment, instance_input); @@ -237,11 +219,10 @@ namespace nil { generate_copy_constraints(component, bp, assignment, instance_input, start_row_index); - return typename plonk_multiplication::result_type( - component, start_row_index); + return typename plonk_multiplication::result_type(component, start_row_index); } } // namespace components - } // namespace blueprint + } // namespace blueprint } // namespace nil #endif // CRYPTO3_BLUEPRINT_COMPONENTS_PLONK_FIELD_MULTIPLICATION_HPP diff --git a/include/nil/blueprint/components/algebra/fields/plonk/multiplication_by_constant.hpp b/include/nil/blueprint/components/algebra/fields/plonk/multiplication_by_constant.hpp index 9fc78769c..dff77d7ff 100644 --- a/include/nil/blueprint/components/algebra/fields/plonk/multiplication_by_constant.hpp +++ b/include/nil/blueprint/components/algebra/fields/plonk/multiplication_by_constant.hpp @@ -50,9 +50,8 @@ namespace nil { class mul_by_constant; template - class mul_by_constant, - BlueprintFieldType>: - public plonk_component { + class mul_by_constant, BlueprintFieldType> + : public plonk_component { public: using component_type = plonk_component; @@ -64,8 +63,7 @@ namespace nil { } }; - static gate_manifest get_gate_manifest(std::size_t witness_amount, - std::size_t lookup_column_amount) { + static gate_manifest get_gate_manifest(std::size_t witness_amount, std::size_t lookup_column_amount) { static gate_manifest manifest = gate_manifest(gate_manifest_type()); return manifest; } @@ -79,10 +77,8 @@ namespace nil { using manifest_type = plonk_component_manifest; static manifest_type get_manifest() { - static manifest_type manifest = manifest_type( - std::shared_ptr(new manifest_single_value_param(2)), - true - ); + static manifest_type manifest = + manifest_type(std::shared_ptr(new manifest_single_value_param(2)), true); return manifest; } @@ -119,71 +115,67 @@ namespace nil { } }; - template + template mul_by_constant(WitnessContainerType witness, ConstantContainerType constant, - PublicInputContainerType public_input, value_type constant_): - component_type(witness, constant, public_input, get_manifest()), - constant(constant_) {}; - - mul_by_constant(std::initializer_list< - typename component_type::witness_container_type::value_type> witnesses, - std::initializer_list< - typename component_type::constant_container_type::value_type> constants, - std::initializer_list< - typename component_type::public_input_container_type::value_type> public_inputs, - value_type constant_): - component_type(witnesses, constants, public_inputs, get_manifest()), - constant(constant_) {}; - - static typename BlueprintFieldType::value_type calculate(typename BlueprintFieldType::value_type x, - typename BlueprintFieldType::value_type constant) { + PublicInputContainerType public_input, value_type constant_) : + component_type(witness, constant, public_input, get_manifest()), constant(constant_) {}; + + mul_by_constant(std::initializer_list + witnesses, + std::initializer_list + constants, + std::initializer_list + public_inputs, + value_type constant_) : + component_type(witnesses, constants, public_inputs, get_manifest()), constant(constant_) {}; + + static typename BlueprintFieldType::value_type + calculate(typename BlueprintFieldType::value_type x, + typename BlueprintFieldType::value_type constant) { return x * constant; } }; template using plonk_mul_by_constant = - mul_by_constant, - BlueprintFieldType>; + mul_by_constant, BlueprintFieldType>; template - typename plonk_mul_by_constant::result_type - generate_assignments( - const plonk_mul_by_constant &component, - assignment> &assignment, - const typename plonk_mul_by_constant::input_type instance_input, - const std::uint32_t start_row_index) { + typename plonk_mul_by_constant::result_type generate_assignments( + const plonk_mul_by_constant &component, + assignment> &assignment, + const typename plonk_mul_by_constant::input_type instance_input, + const std::uint32_t start_row_index) { const std::size_t j = start_row_index; assignment.witness(component.W(0), j) = var_value(assignment, instance_input.x); - assignment.witness(component.W(1), j) = component.constant * - var_value(assignment, instance_input.x); + assignment.witness(component.W(1), j) = component.constant * var_value(assignment, instance_input.x); return typename plonk_mul_by_constant::result_type(component, start_row_index); } template - typename plonk_mul_by_constant::result_type - generate_empty_assignments( - const plonk_mul_by_constant &component, - assignment> &assignment, - const typename plonk_mul_by_constant::input_type instance_input, - const std::uint32_t start_row_index) { + typename plonk_mul_by_constant::result_type generate_empty_assignments( + const plonk_mul_by_constant &component, + assignment> &assignment, + const typename plonk_mul_by_constant::input_type instance_input, + const std::uint32_t start_row_index) { using component_type = plonk_mul_by_constant; - assignment.witness(component.W(1), start_row_index) = component_type::calculate(var_value(assignment, instance_input.x), component.constant); + assignment.witness(component.W(1), start_row_index) = + component_type::calculate(var_value(assignment, instance_input.x), component.constant); return typename plonk_mul_by_constant::result_type(component, start_row_index); } template - std::size_t generate_gates( - const plonk_mul_by_constant &component, - circuit> &bp, - assignment> &assignment, - const typename plonk_mul_by_constant::input_type &instance_input) { + std::size_t + generate_gates(const plonk_mul_by_constant &component, + circuit> &bp, + assignment> &assignment, + const typename plonk_mul_by_constant::input_type &instance_input) { using var = typename plonk_mul_by_constant::var; @@ -209,13 +201,12 @@ namespace nil { } template - typename plonk_mul_by_constant::result_type - generate_circuit( - const plonk_mul_by_constant &component, - circuit> &bp, - assignment> &assignment, - const typename plonk_mul_by_constant::input_type &instance_input, - const std::size_t start_row_index) { + typename plonk_mul_by_constant::result_type generate_circuit( + const plonk_mul_by_constant &component, + circuit> &bp, + assignment> &assignment, + const typename plonk_mul_by_constant::input_type &instance_input, + const std::size_t start_row_index) { std::size_t selector_index = generate_gates(component, bp, assignment, instance_input); @@ -229,18 +220,15 @@ namespace nil { template void generate_assignments_constant( - const plonk_mul_by_constant - &component, - assignment> - &assignment, - const typename plonk_mul_by_constant::input_type - &instance_input, + const plonk_mul_by_constant &component, + assignment> &assignment, + const typename plonk_mul_by_constant::input_type &instance_input, const std::size_t start_row_index) { assignment.constant(component.C(0), start_row_index) = component.constant; } } // namespace components - } // namespace blueprint + } // namespace blueprint } // namespace nil #endif // CRYPTO3_BLUEPRINT_COMPONENTS_PLONK_FIELD_MULTIPLICATION_BY_CONSTANT_HPP diff --git a/include/nil/blueprint/components/algebra/fields/r1cs/element_fp.hpp b/include/nil/blueprint/components/algebra/fields/r1cs/element_fp.hpp index b2060c01d..b0369e6ba 100644 --- a/include/nil/blueprint/components/algebra/fields/r1cs/element_fp.hpp +++ b/include/nil/blueprint/components/algebra/fields/r1cs/element_fp.hpp @@ -31,10 +31,9 @@ #ifndef CRYPTO3_BLUEPRINT_COMPONENTS_FP_COMPONENTS_HPP #define CRYPTO3_BLUEPRINT_COMPONENTS_FP_COMPONENTS_HPP -#include +#include namespace nil { - namespace crypto3 { namespace blueprint { namespace components { @@ -47,7 +46,6 @@ namespace nil { using element_fp = detail::blueprint_linear_combination; } // namespace components } // namespace blueprint - } // namespace crypto3 } // namespace nil #endif // CRYPTO3_BLUEPRINT_COMPONENTS_FP_COMPONENTS_HPP diff --git a/include/nil/blueprint/components/algebra/fields/r1cs/element_fp2.hpp b/include/nil/blueprint/components/algebra/fields/r1cs/element_fp2.hpp index 316b03ce9..d13d25010 100644 --- a/include/nil/blueprint/components/algebra/fields/r1cs/element_fp2.hpp +++ b/include/nil/blueprint/components/algebra/fields/r1cs/element_fp2.hpp @@ -34,7 +34,7 @@ #include #include -#include +#include #include namespace nil { diff --git a/include/nil/blueprint/components/algebra/fields/r1cs/element_fp3.hpp b/include/nil/blueprint/components/algebra/fields/r1cs/element_fp3.hpp index 50edd8b6b..a7d33a85d 100644 --- a/include/nil/blueprint/components/algebra/fields/r1cs/element_fp3.hpp +++ b/include/nil/blueprint/components/algebra/fields/r1cs/element_fp3.hpp @@ -34,7 +34,7 @@ #include #include -#include +#include #include namespace nil { diff --git a/include/nil/blueprint/components/algebra/fields/r1cs/field_to_bits.hpp b/include/nil/blueprint/components/algebra/fields/r1cs/field_to_bits.hpp index 10ce4c67c..e74fd060f 100644 --- a/include/nil/blueprint/components/algebra/fields/r1cs/field_to_bits.hpp +++ b/include/nil/blueprint/components/algebra/fields/r1cs/field_to_bits.hpp @@ -30,184 +30,175 @@ #include #include -#include - -#include -#include -#include -#include -#include +#include +#include +#include +#include namespace nil { - namespace crypto3 { - namespace blueprint { - namespace components { - /** - * Converts a field element to bits, with strict validation that - * ensures it's less than the (hard-coded) field modulus. - * - * This allows the 254th bit to be decoded. - * - * Given an array of variable bits and an equal length array of fixed bits - * verify that the variable bits are lower than the fixed bits. - * - * Starting with the MSB, continuing to the LSB, for each pair of bits: - * - * If fixed bit is 1 and variable bit is 1, state is 'equal' - * If fixed bit is 0 and variable bit is 0, state is 'equal' - * If fixed bit is 1 and variable bit is 0, state is 'less' - * If fixed bit is 0 and variable bit is 1, state is 'greater' - * - * The comparison continues until the state 'less' or 'greater' occurs - * any further comparisons are ignored and don't affect the result. - * The first differing bit determines the result, the default is 'equal'. - * - * The result must be 'less' for success to ensure congruency between - * the bits and the field element. - * - * f = fixed bit - * v = variable bit - * - * F(f,v) = LUT [f v] -> [equal, greater, less, equal] - * - * 0 0 -> equal - * 0 1 -> greater - * 1 0 -> less - * 1 1 -> equal - * - * This gives us the bit-by-bit comparison, but what's necessary is - * to terminate the comparison upon the less or greater states. - * One constraint at the end must enforce the final result being 'less' or 'equal' - * - * When the desired result is less or equal to `q-1`, then 3 states can be merged - * into one, where the 'greater' state zeros any further states. This makes an - * accumulator of sorts, where the result of the next comparison is AND'd by the - * previous result. This means the current result can be multiplied by the previous - * assuming the state `greater` maps to zero, and all others are mapped to `1`. - * - * The final state will be `1` if it's less or equal than `F_q`, otherwise 0. - * The constraints necessary for this are: - * - * current * previous = result - * - * Where if `previous` is 0 then `result` will be 0, and all following results - * will be zero. - */ - template - struct field_to_bits_strict : public component { - using field_type = Field; - using field_value_type = typename field_type::value_type; - using result_type = detail::blueprint_variable_vector; - - // Output bits - result_type result; - - // Intermediate variables & components - packing packer; - detail::blueprint_variable_vector results; - std::vector> comparisons; - - private: - void init() { - // Constant bit is 0 - const std::vector table_cmp_0 = { - field_value_type::zero(), // 0, equal - field_value_type::one() // 1, greater - }; - - // Constant bit is 1 - const std::vector table_cmp_1 = { - field_value_type::one(), // 0, less - field_value_type::one() // 1, equal - }; - - const typename field_type::integral_type largest_value = field_type::modulus - 1; - - for (size_t i = 0; i < field_type::value_bits; ++i) { - if (multiprecision::bit_test(largest_value, i)) { - this->comparisons.emplace_back(this->bp, table_cmp_1, this->result[i]); - } else { - this->comparisons.emplace_back(this->bp, table_cmp_0, this->result[i]); - } + namespace blueprint { + namespace components { + /** + * Converts a field element to bits, with strict validation that + * ensures it's less than the (hard-coded) field modulus. + * + * This allows the 254th bit to be decoded. + * + * Given an array of variable bits and an equal length array of fixed bits + * verify that the variable bits are lower than the fixed bits. + * + * Starting with the MSB, continuing to the LSB, for each pair of bits: + * + * If fixed bit is 1 and variable bit is 1, state is 'equal' + * If fixed bit is 0 and variable bit is 0, state is 'equal' + * If fixed bit is 1 and variable bit is 0, state is 'less' + * If fixed bit is 0 and variable bit is 1, state is 'greater' + * + * The comparison continues until the state 'less' or 'greater' occurs + * any further comparisons are ignored and don't affect the result. + * The first differing bit determines the result, the default is 'equal'. + * + * The result must be 'less' for success to ensure congruency between + * the bits and the field element. + * + * f = fixed bit + * v = variable bit + * + * F(f,v) = LUT [f v] -> [equal, greater, less, equal] + * + * 0 0 -> equal + * 0 1 -> greater + * 1 0 -> less + * 1 1 -> equal + * + * This gives us the bit-by-bit comparison, but what's necessary is + * to terminate the comparison upon the less or greater states. + * One constraint at the end must enforce the final result being 'less' or 'equal' + * + * When the desired result is less or equal to `q-1`, then 3 states can be merged + * into one, where the 'greater' state zeros any further states. This makes an + * accumulator of sorts, where the result of the next comparison is AND'd by the + * previous result. This means the current result can be multiplied by the previous + * assuming the state `greater` maps to zero, and all others are mapped to `1`. + * + * The final state will be `1` if it's less or equal than `F_q`, otherwise 0. + * The constraints necessary for this are: + * + * current * previous = result + * + * Where if `previous` is 0 then `result` will be 0, and all following results + * will be zero. + */ + template + struct field_to_bits_strict : public component { + using field_type = Field; + using field_value_type = typename field_type::value_type; + using result_type = detail::blueprint_variable_vector; + + // Output bits + result_type result; + + // Intermediate variables & components + packing packer; + detail::blueprint_variable_vector results; + std::vector> comparisons; + + private: + void init() { + // Constant bit is 0 + const std::vector table_cmp_0 = { + field_value_type::zero(), // 0, equal + field_value_type::one() // 1, greater + }; + + // Constant bit is 1 + const std::vector table_cmp_1 = { + field_value_type::one(), // 0, less + field_value_type::one() // 1, equal + }; + + const typename field_type::integral_type largest_value = field_type::modulus - 1; + + for (size_t i = 0; i < field_type::value_bits; ++i) { + if (crypto3::multiprecision::bit_test(largest_value, i)) { + this->comparisons.emplace_back(this->bp, table_cmp_1, this->result[i]); + } else { + this->comparisons.emplace_back(this->bp, table_cmp_0, this->result[i]); } } - - public: - /// Auto allocation of the result - field_to_bits_strict(blueprint &bp, - const detail::blueprint_linear_combination &in_field_element) : - component(bp), - result([&]() { - detail::blueprint_variable_vector r; - r.allocate(bp, field_type::value_bits); - return r; - }()), - packer(bp, result, in_field_element), results([&]() { - detail::blueprint_variable_vector r; - r.allocate(bp, field_type::value_bits - 1); - return r; - }()) { - init(); + } + + public: + /// Auto allocation of the result + field_to_bits_strict(blueprint &bp, + const detail::blueprint_linear_combination &in_field_element) : + component(bp), result([&]() { + detail::blueprint_variable_vector r; + r.allocate(bp, field_type::value_bits); + return r; + }()), + packer(bp, result, in_field_element), results([&]() { + detail::blueprint_variable_vector r; + r.allocate(bp, field_type::value_bits - 1); + return r; + }()) { + init(); + } + + /// Manual allocation of the result + field_to_bits_strict(blueprint &bp, + const detail::blueprint_linear_combination &in_field_element, + const result_type &in_result) : + component(bp), result(in_result), packer(bp, result, in_field_element), results([&]() { + detail::blueprint_variable_vector r; + r.allocate(bp, field_type::value_bits - 1); + return r; + }()) { + init(); + } + + void generate_gates() { + this->packer.generate_gates(true); + + for (auto &component_it : this->comparisons) { + component_it.generate_gates(); } - /// Manual allocation of the result - field_to_bits_strict(blueprint &bp, - const detail::blueprint_linear_combination &in_field_element, - const result_type &in_result) : - component(bp), - result(in_result), packer(bp, result, in_field_element), results([&]() { - detail::blueprint_variable_vector r; - r.allocate(bp, field_type::value_bits - 1); - return r; - }()) { - init(); - } - - void generate_gates() { - this->packer.generate_gates(true); - - for (auto &component_it : this->comparisons) { - component_it.generate_gates(); - } - - // AND all of the comparisons - std::size_t last_bit = field_type::value_bits - 1; - for (std::size_t i = last_bit; i > 0; --i) { - if (i == last_bit) { - this->bp.add_r1cs_constraint( - snark::r1cs_constraint(this->comparisons[i - 1].result, - this->comparisons[i].result, - this->results[i - 1])); - } else { - this->bp.add_r1cs_constraint(snark::r1cs_constraint( - this->comparisons[i - 1].result, this->results[i], this->results[i - 1])); - } + // AND all of the comparisons + std::size_t last_bit = field_type::value_bits - 1; + for (std::size_t i = last_bit; i > 0; --i) { + if (i == last_bit) { + this->bp.add_r1cs_constraint(crypto3::zk::snark::r1cs_constraint( + this->comparisons[i - 1].result, this->comparisons[i].result, this->results[i - 1])); + } else { + this->bp.add_r1cs_constraint(crypto3::zk::snark::r1cs_constraint( + this->comparisons[i - 1].result, this->results[i], this->results[i - 1])); } } + } - void generate_assignments() { - this->packer.generate_assignments_from_packed(); + void generate_assignments() { + this->packer.generate_assignments_from_packed(); - for (auto &component_it : this->comparisons) { - component_it.generate_assignments(); - } + for (auto &component_it : this->comparisons) { + component_it.generate_assignments(); + } - // Iterate from MSB to LSB - std::size_t last_bit = (field_type::value_bits - 1); - for (std::size_t i = last_bit; i > 0; --i) { - // current * previous = result - if (i == last_bit) { - this->bp.val(this->results[i - 1]) = this->bp.val(this->comparisons[i - 1].result) * - this->bp.val(this->comparisons[i].result); - } else { - this->bp.val(this->results[i - 1]) = - this->bp.val(this->results[i]) * this->bp.val(this->comparisons[i - 1].result); - } + // Iterate from MSB to LSB + std::size_t last_bit = (field_type::value_bits - 1); + for (std::size_t i = last_bit; i > 0; --i) { + // current * previous = result + if (i == last_bit) { + this->bp.val(this->results[i - 1]) = this->bp.val(this->comparisons[i - 1].result) * + this->bp.val(this->comparisons[i].result); + } else { + this->bp.val(this->results[i - 1]) = + this->bp.val(this->results[i]) * this->bp.val(this->comparisons[i - 1].result); } } - }; - } // namespace components - } // namespace blueprint - } // namespace crypto3 + } + }; + } // namespace components + } // namespace blueprint } // namespace nil #endif // CRYPTO3_BLUEPRINT_COMPONENTS_FIELD_TO_BITS_COMPONENTS_HPP diff --git a/include/nil/blueprint/components/algebra/pairing/weierstrass/r1cs/final_exponentiation.hpp b/include/nil/blueprint/components/algebra/pairing/weierstrass/r1cs/final_exponentiation.hpp index 3e53bced5..a6ee8a735 100644 --- a/include/nil/blueprint/components/algebra/pairing/weierstrass/r1cs/final_exponentiation.hpp +++ b/include/nil/blueprint/components/algebra/pairing/weierstrass/r1cs/final_exponentiation.hpp @@ -35,7 +35,7 @@ #include -#include +#include #include #include #include diff --git a/include/nil/blueprint/components/boolean/r1cs/comparison.hpp b/include/nil/blueprint/components/boolean/r1cs/comparison.hpp index 499309a1e..4aca23f72 100644 --- a/include/nil/blueprint/components/boolean/r1cs/comparison.hpp +++ b/include/nil/blueprint/components/boolean/r1cs/comparison.hpp @@ -37,101 +37,100 @@ #include namespace nil { - namespace crypto3 { - namespace blueprint { - namespace components { - - /* - the components below are Fp specific: - I * X = R - (1-R) * X = 0 - - if X = 0 then R = 0 - if X != 0 then R = 1 and I = X^{-1} - */ - template - class comparison : public nil::blueprint::components::component { - private: - detail::blueprint_variable_vector alpha; - detail::blueprint_variable alpha_packed; - std::shared_ptr> pack_alpha; - - std::shared_ptr> all_zeros_test; - detail::blueprint_variable not_all_zeros; - - public: - const std::size_t n; - const detail::blueprint_linear_combination A; - const detail::blueprint_linear_combination B; - const detail::blueprint_variable less; - const detail::blueprint_variable less_or_eq; - - comparison(blueprint &bp, - std::size_t n, - const detail::blueprint_linear_combination &A, - const detail::blueprint_linear_combination &B, - const detail::blueprint_variable &less, - const detail::blueprint_variable &less_or_eq) : - nil::blueprint::components::component(bp), - n(n), A(A), B(B), less(less), less_or_eq(less_or_eq) { - alpha.allocate(bp, n); - alpha.emplace_back(less_or_eq); // alpha[n] is less_or_eq - - alpha_packed.allocate(bp); - not_all_zeros.allocate(bp); - - pack_alpha.reset(new packing(bp, alpha, alpha_packed)); - - all_zeros_test.reset(new disjunction( - bp, detail::blueprint_variable_vector(alpha.begin(), alpha.begin() + n), not_all_zeros)); - }; - - void generate_gates() { - /* - packed(alpha) = 2^n + B - A - - not_all_zeros = \bigvee_{i=0}^{n-1} alpha_i - - if B - A > 0, then 2^n + B - A > 2^n, - so alpha_n = 1 and not_all_zeros = 1 - if B - A = 0, then 2^n + B - A = 2^n, - so alpha_n = 1 and not_all_zeros = 0 - if B - A < 0, then 2^n + B - A \in {0, 1, \ldots, 2^n-1}, - so alpha_n = 0 - - therefore alpha_n = less_or_eq and alpha_n * not_all_zeros = less - */ - - /* not_all_zeros to be Boolean, alpha_i are Boolean by packing component */ - generate_boolean_r1cs_constraint(this->bp, not_all_zeros); - - /* constraints for packed(alpha) = 2^n + B - A */ - pack_alpha->generate_gates(true); - this->bp.add_r1cs_constraint(zk::snark::r1cs_constraint( - 1, (typename FieldType::value_type(0x02).pow(n)) + B - A, alpha_packed)); - - /* compute result */ - all_zeros_test->generate_gates(); - this->bp.add_r1cs_constraint( - zk::snark::r1cs_constraint(less_or_eq, not_all_zeros, less)); - } - - void generate_assignments() { - A.evaluate(this->bp); - B.evaluate(this->bp); - - /* unpack 2^n + B - A into alpha_packed */ - this->bp.val(alpha_packed) = - (typename FieldType::value_type(0x02).pow(n)) + this->bp.lc_val(B) - this->bp.lc_val(A); - pack_alpha->generate_assignments_from_packed(); - - /* compute result */ - all_zeros_test->generate_assignments(); - this->bp.val(less) = this->bp.val(less_or_eq) * this->bp.val(not_all_zeros); - } + namespace blueprint { + namespace components { + + /* + the components below are Fp specific: + I * X = R + (1-R) * X = 0 + + if X = 0 then R = 0 + if X != 0 then R = 1 and I = X^{-1} + */ + template + class comparison : public nil::blueprint::components::component { + private: + detail::blueprint_variable_vector alpha; + detail::blueprint_variable alpha_packed; + std::shared_ptr> pack_alpha; + + std::shared_ptr> all_zeros_test; + detail::blueprint_variable not_all_zeros; + + public: + const std::size_t n; + const detail::blueprint_linear_combination A; + const detail::blueprint_linear_combination B; + const detail::blueprint_variable less; + const detail::blueprint_variable less_or_eq; + + comparison(blueprint &bp, + std::size_t n, + const detail::blueprint_linear_combination &A, + const detail::blueprint_linear_combination &B, + const detail::blueprint_variable &less, + const detail::blueprint_variable &less_or_eq) : + component(bp), n(n), A(A), B(B), less(less), less_or_eq(less_or_eq) { + alpha.allocate(bp, n); + alpha.emplace_back(less_or_eq); // alpha[n] is less_or_eq + + alpha_packed.allocate(bp); + not_all_zeros.allocate(bp); + + pack_alpha.reset(new packing(bp, alpha, alpha_packed)); + + all_zeros_test.reset(new disjunction( + bp, + detail::blueprint_variable_vector(alpha.begin(), alpha.begin() + n), + not_all_zeros)); }; - } // namespace components - } // namespace blueprint - } // namespace crypto3 + + void generate_gates() { + /* + packed(alpha) = 2^n + B - A + + not_all_zeros = \bigvee_{i=0}^{n-1} alpha_i + + if B - A > 0, then 2^n + B - A > 2^n, + so alpha_n = 1 and not_all_zeros = 1 + if B - A = 0, then 2^n + B - A = 2^n, + so alpha_n = 1 and not_all_zeros = 0 + if B - A < 0, then 2^n + B - A \in {0, 1, \ldots, 2^n-1}, + so alpha_n = 0 + + therefore alpha_n = less_or_eq and alpha_n * not_all_zeros = less + */ + + /* not_all_zeros to be Boolean, alpha_i are Boolean by packing component */ + generate_boolean_r1cs_constraint(this->bp, not_all_zeros); + + /* constraints for packed(alpha) = 2^n + B - A */ + pack_alpha->generate_gates(true); + this->bp.add_r1cs_constraint(crypto3::zk::snark::r1cs_constraint( + 1, (typename FieldType::value_type(0x02).pow(n)) + B - A, alpha_packed)); + + /* compute result */ + all_zeros_test->generate_gates(); + this->bp.add_r1cs_constraint( + crypto3::zk::snark::r1cs_constraint(less_or_eq, not_all_zeros, less)); + } + + void generate_assignments() { + A.evaluate(this->bp); + B.evaluate(this->bp); + + /* unpack 2^n + B - A into alpha_packed */ + this->bp.val(alpha_packed) = + (typename FieldType::value_type(0x02).pow(n)) + this->bp.lc_val(B) - this->bp.lc_val(A); + pack_alpha->generate_assignments_from_packed(); + + /* compute result */ + all_zeros_test->generate_assignments(); + this->bp.val(less) = this->bp.val(less_or_eq) * this->bp.val(not_all_zeros); + } + }; + } // namespace components + } // namespace blueprint } // namespace nil #endif // CRYPTO3_BLUEPRINT_COMPONENTS_COMPARISON_COMPONENT_HPP diff --git a/include/nil/blueprint/components/boolean/r1cs/conjunction.hpp b/include/nil/blueprint/components/boolean/r1cs/conjunction.hpp index 4331fa9bf..c4594130b 100644 --- a/include/nil/blueprint/components/boolean/r1cs/conjunction.hpp +++ b/include/nil/blueprint/components/boolean/r1cs/conjunction.hpp @@ -30,83 +30,83 @@ #include #include +#include +#include #include + #include namespace nil { - namespace crypto3 { - namespace blueprint { - namespace components { - - /* - the components below are Fp specific: - I * X = R - (1-R) * X = 0 - - if X = 0 then R = 0 - if X != 0 then R = 1 and I = X^{-1} - */ - template - class conjunction : public nil::blueprint::components::component { - private: - detail::blueprint_variable inv; - - public: - const detail::blueprint_variable_vector inputs; - const detail::blueprint_variable output; - - conjunction(blueprint &bp, - const detail::blueprint_variable_vector &inputs, - const detail::blueprint_variable &output) : - nil::blueprint::components::component(bp), - inputs(inputs), output(output) { - assert(inputs.size() >= 1); - inv.allocate(bp); + namespace blueprint { + namespace components { + + /* + the components below are Fp specific: + I * X = R + (1-R) * X = 0 + + if X = 0 then R = 0 + if X != 0 then R = 1 and I = X^{-1} + */ + template + class conjunction : public component { + private: + detail::blueprint_variable inv; + + public: + const detail::blueprint_variable_vector inputs; + const detail::blueprint_variable output; + + conjunction(blueprint &bp, + const detail::blueprint_variable_vector &inputs, + const detail::blueprint_variable &output) : + nil::blueprint::components::component(bp), inputs(inputs), output(output) { + assert(inputs.size() >= 1); + inv.allocate(bp); + } + + void generate_gates() { + /* inv * (n-sum) = 1-output */ + crypto3::math::non_linear_combination a1, b1, c1; + a1.add_term(inv); + b1.add_term(detail::blueprint_variable(0), inputs.size()); + for (std::size_t i = 0; i < inputs.size(); ++i) { + b1.add_term(inputs[i], -1); } + c1.add_term(detail::blueprint_variable(0)); + c1.add_term(output, -1); - void generate_gates() { - /* inv * (n-sum) = 1-output */ - math::non_linear_combination a1, b1, c1; - a1.add_term(inv); - b1.add_term(detail::blueprint_variable(0), inputs.size()); - for (std::size_t i = 0; i < inputs.size(); ++i) { - b1.add_term(inputs[i], -1); - } - c1.add_term(detail::blueprint_variable(0)); - c1.add_term(output, -1); - - this->bp.add_r1cs_constraint(zk::snark::r1cs_constraint(a1, b1, c1)); - - /* output * (n-sum) = 0 */ - math::non_linear_combination a2, b2, c2; - a2.add_term(output); - b2.add_term(detail::blueprint_variable(0), inputs.size()); - for (std::size_t i = 0; i < inputs.size(); ++i) { - b2.add_term(inputs[i], -1); - } - c2.add_term(detail::blueprint_variable(0), 0); - - this->bp.add_r1cs_constraint(zk::snark::r1cs_constraint(a2, b2, c2)); + this->bp.add_r1cs_constraint(crypto3::zk::snark::r1cs_constraint(a1, b1, c1)); + + /* output * (n-sum) = 0 */ + crypto3::math::non_linear_combination a2, b2, c2; + a2.add_term(output); + b2.add_term(detail::blueprint_variable(0), inputs.size()); + for (std::size_t i = 0; i < inputs.size(); ++i) { + b2.add_term(inputs[i], -1); } - void generate_assignments() { - typename FieldType::value_type sum = typename FieldType::value_type(inputs.size()); - - for (std::size_t i = 0; i < inputs.size(); ++i) { - sum -= this->bp.val(inputs[i]); - } - - if (sum.is_zero()) { - this->bp.val(inv) = FieldType::value_type::zero(); - this->bp.val(output) = FieldType::value_type::one(); - } else { - this->bp.val(inv) = sum.inversed(); - this->bp.val(output) = FieldType::value_type::zero(); - } + c2.add_term(detail::blueprint_variable(0), 0); + + this->bp.add_r1cs_constraint(crypto3::zk::snark::r1cs_constraint(a2, b2, c2)); + } + void generate_assignments() { + typename FieldType::value_type sum = typename FieldType::value_type(inputs.size()); + + for (std::size_t i = 0; i < inputs.size(); ++i) { + sum -= this->bp.val(inputs[i]); + } + + if (sum.is_zero()) { + this->bp.val(inv) = FieldType::value_type::zero(); + this->bp.val(output) = FieldType::value_type::one(); + } else { + this->bp.val(inv) = sum.inversed(); + this->bp.val(output) = FieldType::value_type::zero(); } - }; - } // namespace components - } // namespace blueprint - } // namespace crypto3 + } + }; + } // namespace components + } // namespace blueprint } // namespace nil #endif // CRYPTO3_BLUEPRINT_COMPONENTS_CONJUNCTION_COMPONENT_HPP diff --git a/include/nil/blueprint/components/boolean/r1cs/disjunction.hpp b/include/nil/blueprint/components/boolean/r1cs/disjunction.hpp index a1153d350..df28363e0 100644 --- a/include/nil/blueprint/components/boolean/r1cs/disjunction.hpp +++ b/include/nil/blueprint/components/boolean/r1cs/disjunction.hpp @@ -35,79 +35,76 @@ #include namespace nil { - namespace crypto3 { - namespace blueprint { - namespace components { - - /* - the components below are Fp specific: - I * X = R - (1-R) * X = 0 - - if X = 0 then R = 0 - if X != 0 then R = 1 and I = X^{-1} - */ - - template - class disjunction : public nil::blueprint::components::component { - private: - detail::blueprint_variable inv; - - public: - const detail::blueprint_variable_vector inputs; - const detail::blueprint_variable output; - - disjunction(blueprint &bp, - const detail::blueprint_variable_vector &inputs, - const detail::blueprint_variable &output) : - nil::blueprint::components::component(bp), - inputs(inputs), output(output) { - assert(inputs.size() >= 1); - inv.allocate(bp); + namespace blueprint { + namespace components { + + /* + the components below are Fp specific: + I * X = R + (1-R) * X = 0 + + if X = 0 then R = 0 + if X != 0 then R = 1 and I = X^{-1} + */ + + template + class disjunction : public component { + private: + detail::blueprint_variable inv; + + public: + const detail::blueprint_variable_vector inputs; + const detail::blueprint_variable output; + + disjunction(blueprint &bp, + const detail::blueprint_variable_vector &inputs, + const detail::blueprint_variable &output) : + component(bp), inputs(inputs), output(output) { + assert(inputs.size() >= 1); + inv.allocate(bp); + } + + void generate_gates() { + /* inv * sum = output */ + crypto3::math::non_linear_combination a1, b1, c1; + a1.add_term(inv); + for (std::size_t i = 0; i < inputs.size(); ++i) { + b1.add_term(inputs[i]); } + c1.add_term(output); - void generate_gates() { - /* inv * sum = output */ - math::non_linear_combination a1, b1, c1; - a1.add_term(inv); - for (std::size_t i = 0; i < inputs.size(); ++i) { - b1.add_term(inputs[i]); - } - c1.add_term(output); - - this->bp.add_r1cs_constraint(zk::snark::r1cs_constraint(a1, b1, c1)); - - /* (1-output) * sum = 0 */ - math::non_linear_combination a2, b2, c2; - a2.add_term(detail::blueprint_variable(0)); - a2.add_term(output, -1); - for (std::size_t i = 0; i < inputs.size(); ++i) { - b2.add_term(inputs[i]); - } - c2.add_term(detail::blueprint_variable(0), 0); - - this->bp.add_r1cs_constraint(zk::snark::r1cs_constraint(a2, b2, c2)); + this->bp.add_r1cs_constraint(crypto3::zk::snark::r1cs_constraint(a1, b1, c1)); + + /* (1-output) * sum = 0 */ + crypto3::math::non_linear_combination a2, b2, c2; + a2.add_term(detail::blueprint_variable(0)); + a2.add_term(output, -1); + for (std::size_t i = 0; i < inputs.size(); ++i) { + b2.add_term(inputs[i]); } + c2.add_term(detail::blueprint_variable(0), 0); + + this->bp.add_r1cs_constraint(crypto3::zk::snark::r1cs_constraint(a2, b2, c2)); + } - void generate_assignments() { - typename FieldType::value_type sum = FieldType::value_type::zero(); + void generate_assignments() { + typename FieldType::value_type sum = FieldType::value_type::zero(); - for (std::size_t i = 0; i < inputs.size(); ++i) { - sum += this->bp.val(inputs[i]); - } + for (std::size_t i = 0; i < inputs.size(); ++i) { + sum += this->bp.val(inputs[i]); + } - if (sum.is_zero()) { - this->bp.val(inv) = FieldType::value_type::zero(); - this->bp.val(output) = FieldType::value_type::zero(); - } else { - this->bp.val(inv) = sum.inversed(); - this->bp.val(output) = FieldType::value_type::one(); - } + if (sum.is_zero()) { + this->bp.val(inv) = FieldType::value_type::zero(); + this->bp.val(output) = FieldType::value_type::zero(); + } else { + this->bp.val(inv) = sum.inversed(); + this->bp.val(output) = FieldType::value_type::one(); } - }; + } + }; - } // namespace components - } // namespace blueprint - } // namespace crypto3 + } // namespace components + } // namespace blueprint } // namespace nil #endif // CRYPTO3_BLUEPRINT_COMPONENTS_DISJUNCTION_COMPONENT_HPP diff --git a/include/nil/blueprint/components/boolean/r1cs/inner_product.hpp b/include/nil/blueprint/components/boolean/r1cs/inner_product.hpp index 1da775bb2..956515dfe 100644 --- a/include/nil/blueprint/components/boolean/r1cs/inner_product.hpp +++ b/include/nil/blueprint/components/boolean/r1cs/inner_product.hpp @@ -35,69 +35,66 @@ #include namespace nil { - namespace crypto3 { - namespace blueprint { - namespace components { + namespace blueprint { + namespace components { - /* - the components below are Fp specific: - I * X = R - (1-R) * X = 0 + /* + the components below are Fp specific: + I * X = R + (1-R) * X = 0 - if X = 0 then R = 0 - if X != 0 then R = 1 and I = X^{-1} - */ - template - class inner_product : public nil::blueprint::components::component { - private: - /* S_i = \sum_{k=0}^{i+1} A[i] * B[i] */ - detail::blueprint_variable_vector S; + if X = 0 then R = 0 + if X != 0 then R = 1 and I = X^{-1} + */ + template + class inner_product : public component { + private: + /* S_i = \sum_{k=0}^{i+1} A[i] * B[i] */ + detail::blueprint_variable_vector S; - public: - const detail::blueprint_linear_combination_vector A; - const detail::blueprint_linear_combination_vector B; - const detail::blueprint_variable result; + public: + const detail::blueprint_linear_combination_vector A; + const detail::blueprint_linear_combination_vector B; + const detail::blueprint_variable result; - inner_product(blueprint &bp, - const detail::blueprint_linear_combination_vector &A, - const detail::blueprint_linear_combination_vector &B, - const detail::blueprint_variable &result) : - nil::blueprint::components::component(bp), - A(A), B(B), result(result) { - assert(A.size() >= 1); - assert(A.size() == B.size()); + inner_product(blueprint &bp, + const detail::blueprint_linear_combination_vector &A, + const detail::blueprint_linear_combination_vector &B, + const detail::blueprint_variable &result) : + component(bp), A(A), B(B), result(result) { + assert(A.size() >= 1); + assert(A.size() == B.size()); - S.allocate(bp, A.size() - 1); - } + S.allocate(bp, A.size() - 1); + } - void generate_gates() { - /* - S_i = \sum_{k=0}^{i+1} A[i] * B[i] - S[0] = A[0] * B[0] - S[i+1] - S[i] = A[i] * B[i] - */ - for (std::size_t i = 0; i < A.size(); ++i) { - this->bp.add_r1cs_constraint(zk::snark::r1cs_constraint( - A[i], B[i], - (i == A.size() - 1 ? result : S[i]) + - (i == 0 ? 0 * detail::blueprint_variable(0) : -S[i - 1]))); - } + void generate_gates() { + /* + S_i = \sum_{k=0}^{i+1} A[i] * B[i] + S[0] = A[0] * B[0] + S[i+1] - S[i] = A[i] * B[i] + */ + for (std::size_t i = 0; i < A.size(); ++i) { + this->bp.add_r1cs_constraint(crypto3::zk::snark::r1cs_constraint( + A[i], B[i], + (i == A.size() - 1 ? result : S[i]) + + (i == 0 ? 0 * detail::blueprint_variable(0) : -S[i - 1]))); } + } - void generate_assignments() { - typename FieldType::value_type total = FieldType::value_type::zero(); - for (std::size_t i = 0; i < A.size(); ++i) { - A[i].evaluate(this->bp); - B[i].evaluate(this->bp); + void generate_assignments() { + typename FieldType::value_type total = FieldType::value_type::zero(); + for (std::size_t i = 0; i < A.size(); ++i) { + A[i].evaluate(this->bp); + B[i].evaluate(this->bp); - total += this->bp.lc_val(A[i]) * this->bp.lc_val(B[i]); - this->bp.val(i == A.size() - 1 ? result : S[i]) = total; - } + total += this->bp.lc_val(A[i]) * this->bp.lc_val(B[i]); + this->bp.val(i == A.size() - 1 ? result : S[i]) = total; } - }; + } + }; - } // namespace components - } // namespace blueprint - } // namespace crypto3 + } // namespace components + } // namespace blueprint } // namespace nil #endif // CRYPTO3_BLUEPRINT_COMPONENTS_INNER_PRODUCT_COMPONENT_HPP diff --git a/include/nil/blueprint/components/detail/r1cs/lookup_1bit.hpp b/include/nil/blueprint/components/detail/r1cs/lookup_1bit.hpp index 87ff602c9..0bd6985a1 100644 --- a/include/nil/blueprint/components/detail/r1cs/lookup_1bit.hpp +++ b/include/nil/blueprint/components/detail/r1cs/lookup_1bit.hpp @@ -27,65 +27,60 @@ #ifndef CRYPTO3_BLUEPRINT_COMPONENTS_DETAIL_LOOKUP_1BIT_HPP #define CRYPTO3_BLUEPRINT_COMPONENTS_DETAIL_LOOKUP_1BIT_HPP -#include -#include -#include +#include +#include +#include namespace nil { - namespace crypto3 { - namespace blueprint { - namespace components { - /** - * One-bit window lookup table using one constraint - */ - template - struct lookup_1bit : public component { - using field_type = Field; - using field_value_type = typename Field::value_type; - using result_type = detail::blueprint_variable; + namespace blueprint { + namespace components { + /** + * One-bit window lookup table using one constraint + */ + template + struct lookup_1bit : public component { + using field_type = Field; + using field_value_type = typename Field::value_type; + using result_type = detail::blueprint_variable; - const std::vector constants; - const detail::blueprint_variable bit; - result_type result; + const std::vector constants; + const detail::blueprint_variable bit; + result_type result; - /// Auto allocation of the result - template - lookup_1bit(blueprint &bp, - const Constants &in_constants, - const detail::blueprint_variable &in_bit) : - component(bp), - constants(std::cbegin(in_constants), std::cend(in_constants)), bit(in_bit) { - assert(this->constants.size() == 2); - this->result.allocate(this->bp); - } + /// Auto allocation of the result + template + lookup_1bit(blueprint &bp, + const Constants &in_constants, + const detail::blueprint_variable &in_bit) : + component(bp), constants(std::cbegin(in_constants), std::cend(in_constants)), bit(in_bit) { + assert(this->constants.size() == 2); + this->result.allocate(this->bp); + } - /// Manual allocation of the result - template - lookup_1bit(blueprint &bp, - const Constants &in_constants, - const detail::blueprint_variable &in_bit, - const result_type &in_result) : - component(bp), - constants(std::cbegin(in_constants), std::cend(in_constants)), bit(in_bit), result(in_result) { - assert(this->constants.size() == 2); - } + /// Manual allocation of the result + template + lookup_1bit(blueprint &bp, + const Constants &in_constants, + const detail::blueprint_variable &in_bit, + const result_type &in_result) : + component(bp), constants(std::cbegin(in_constants), std::cend(in_constants)), bit(in_bit), + result(in_result) { + assert(this->constants.size() == 2); + } - void generate_gates() { - this->bp.add_r1cs_constraint(snark::r1cs_constraint( - {constants[0] + bit * constants[1] - (bit * constants[0])}, - {field_value_type::one()}, - result)); - } + void generate_gates() { + this->bp.add_r1cs_constraint(crypto3::zk::snark::r1cs_constraint( + {constants[0] + bit * constants[1] - (bit * constants[0])}, {field_value_type::one()}, result)); + } - void generate_assignments() { - std::size_t i = static_cast( - static_cast((this->bp.val(bit)).data)); - this->bp.val(result) = constants[i]; - } - }; - } // namespace components - } // namespace blueprint - } // namespace crypto3 + void generate_assignments() { + std::size_t i = static_cast( + static_cast((this->bp.val(bit)).data)); + this->bp.val(result) = constants[i]; + } + }; + } // namespace components + } // namespace blueprint } // namespace nil #endif // CRYPTO3_BLUEPRINT_COMPONENTS_DETAIL_LOOKUP_1BIT_HPP diff --git a/include/nil/blueprint/components/detail/r1cs/lookup_signed_3bit.hpp b/include/nil/blueprint/components/detail/r1cs/lookup_signed_3bit.hpp index 0fa9746fb..2095cd552 100644 --- a/include/nil/blueprint/components/detail/r1cs/lookup_signed_3bit.hpp +++ b/include/nil/blueprint/components/detail/r1cs/lookup_signed_3bit.hpp @@ -35,97 +35,95 @@ #include #include -#include -#include -#include +#include +#include +#include namespace nil { - namespace crypto3 { - namespace blueprint { - namespace components { - template - struct lookup_signed_3bit : public component { - using field_type = Field; - using field_value_type = typename field_type::value_type; + namespace blueprint { + namespace components { + template + struct lookup_signed_3bit : public component { + using field_type = Field; + using field_value_type = typename field_type::value_type; - static constexpr std::size_t chunk_bits = 3; - static constexpr std::size_t lookup_bits = 2; + static constexpr std::size_t chunk_bits = 3; + static constexpr std::size_t lookup_bits = 2; - // Input variables - std::vector c; - const detail::blueprint_variable_vector b; - // Intermediate variable - detail::blueprint_variable b0b1; - // Output variable - detail::blueprint_variable result; + // Input variables + std::vector c; + const detail::blueprint_variable_vector b; + // Intermediate variable + detail::blueprint_variable b0b1; + // Output variable + detail::blueprint_variable result; - /// Auto allocation of the result - template::value_type>::value, - bool>::type = true> - lookup_signed_3bit(blueprint &bp, - const Constants &in_constants, - const detail::blueprint_variable_vector &in_bits) : - component(bp), - b(in_bits) { - this->b0b1.allocate(this->bp); - this->result.allocate(this->bp); - std::copy(std::cbegin(in_constants), std::cend(in_constants), std::back_inserter(this->c)); - } + /// Auto allocation of the result + template< + typename Constants, + typename std::enable_if< + std::is_same::value_type>::value, + bool>::type = true> + lookup_signed_3bit(blueprint &bp, + const Constants &in_constants, + const detail::blueprint_variable_vector &in_bits) : + component(bp), b(in_bits) { + this->b0b1.allocate(this->bp); + this->result.allocate(this->bp); + std::copy(std::cbegin(in_constants), std::cend(in_constants), std::back_inserter(this->c)); + } - /// Manual allocation of the result - template::value_type>::value, - bool>::type = true> - lookup_signed_3bit(blueprint &bp, - const Constants &in_constants, - const detail::blueprint_variable_vector &in_bits, - const detail::blueprint_variable &in_result) : - component(bp), - b(in_bits), result(in_result) { - this->b0b1.allocate(this->bp); - std::copy(std::cbegin(in_constants), std::cend(in_constants), std::back_inserter(this->c)); - } + /// Manual allocation of the result + template< + typename Constants, + typename std::enable_if< + std::is_same::value_type>::value, + bool>::type = true> + lookup_signed_3bit(blueprint &bp, + const Constants &in_constants, + const detail::blueprint_variable_vector &in_bits, + const detail::blueprint_variable &in_result) : + component(bp), b(in_bits), result(in_result) { + this->b0b1.allocate(this->bp); + std::copy(std::cbegin(in_constants), std::cend(in_constants), std::back_inserter(this->c)); + } - void generate_gates() { - /// b0b1 = b[0] * b[1] - this->bp.add_r1cs_constraint( - snark::r1cs_constraint(this->b[0], this->b[1], this->b0b1)); + void generate_gates() { + /// b0b1 = b[0] * b[1] + this->bp.add_r1cs_constraint( + crypto3::zk::snark::r1cs_constraint(this->b[0], this->b[1], this->b0b1)); - /// y_lc = c[0] + b[0] * (c[1]-c0) + b[1] * (c[2]-c[0]) + b[0]&b[1] * (c[3] - c[2] - c[1] + - /// c[0]) - detail::blueprint_linear_combination y_lc; - y_lc.assign( - this->bp, - math::linear_term(detail::blueprint_variable(0), this->c[0]) + - math::linear_term(this->b[0], this->c[1] - this->c[0]) + - math::linear_term(this->b[1], this->c[2] - this->c[0]) + - math::linear_term(this->b0b1, - this->c[3] - this->c[2] - this->c[1] + this->c[0])); + /// y_lc = c[0] + b[0] * (c[1]-c0) + b[1] * (c[2]-c[0]) + b[0]&b[1] * (c[3] - c[2] - c[1] + + /// c[0]) + detail::blueprint_linear_combination y_lc; + y_lc.assign( + this->bp, + crypto3::math::linear_term(detail::blueprint_variable(0), this->c[0]) + + crypto3::math::linear_term(this->b[0], this->c[1] - this->c[0]) + + crypto3::math::linear_term(this->b[1], this->c[2] - this->c[0]) + + crypto3::math::linear_term(this->b0b1, + this->c[3] - this->c[2] - this->c[1] + this->c[0])); - /// (y_lc + y_lc) * b[2] == y_lc - result - this->bp.add_r1cs_constraint( - snark::r1cs_constraint({y_lc + y_lc}, this->b[2], {y_lc - this->result})); - } + /// (y_lc + y_lc) * b[2] == y_lc - result + this->bp.add_r1cs_constraint(crypto3::zk::snark::r1cs_constraint( + {y_lc + y_lc}, this->b[2], {y_lc - this->result})); + } - void generate_assignments() { - auto i = static_cast(static_cast( - this->b.get_field_element_from_bits(this->bp).data)); - field_value_type result = this->c[i & 3]; - if (i > 3) { - result = result * (-field_value_type::one()); - } - this->bp.val(this->b0b1) = this->bp.val(this->b[0]) * this->bp.val(this->b[1]); - this->bp.val(this->result) = result; + void generate_assignments() { + auto i = static_cast(static_cast( + this->b.get_field_element_from_bits(this->bp).data)); + field_value_type result = this->c[i & 3]; + if (i > 3) { + result = result * (-field_value_type::one()); } - }; - } // namespace components - } // namespace blueprint - } // namespace crypto3 + this->bp.val(this->b0b1) = this->bp.val(this->b[0]) * this->bp.val(this->b[1]); + this->bp.val(this->result) = result; + } + }; + } // namespace components + } // namespace blueprint } // namespace nil #endif // CRYPTO3_BLUEPRINT_COMPONENTS_LOOKUP_SIGNED_3BIT_COMPONENT_HPP diff --git a/include/nil/blueprint/components/detail/r1cs/loose_multiplexing.hpp b/include/nil/blueprint/components/detail/r1cs/loose_multiplexing.hpp index 4d475cdbb..da6dfe32c 100644 --- a/include/nil/blueprint/components/detail/r1cs/loose_multiplexing.hpp +++ b/include/nil/blueprint/components/detail/r1cs/loose_multiplexing.hpp @@ -37,92 +37,91 @@ #include namespace nil { - namespace crypto3 { - namespace blueprint { - namespace components { - - /* - loose_multiplexing implements loose multiplexer: - index not in bounds -> success_flag = 0 - index in bounds && success_flag = 1 -> result is correct - however if index is in bounds we can also set success_flag to 0 (and then result will be forced to - be 0) - */ - template - class loose_multiplexing : public nil::blueprint::components::component { - public: - detail::blueprint_variable_vector alpha; - - private: - std::shared_ptr> compute_result; - - public: - const detail::blueprint_linear_combination_vector arr; - const detail::blueprint_variable index; - const detail::blueprint_variable result; - const detail::blueprint_variable success_flag; - - loose_multiplexing(blueprint &bp, - const detail::blueprint_linear_combination_vector &arr, - const detail::blueprint_variable &index, - const detail::blueprint_variable &result, - const detail::blueprint_variable &success_flag) : - nil::blueprint::components::component(bp), - arr(arr), index(index), result(result), success_flag(success_flag) { - alpha.allocate(bp, arr.size()); - compute_result.reset(new inner_product(bp, alpha, arr, result)); - }; - - void generate_gates() { - /* \alpha_i (index - i) = 0 */ - for (std::size_t i = 0; i < arr.size(); ++i) { - this->bp.add_r1cs_constraint(zk::snark::r1cs_constraint(alpha[i], index - i, 0)); - } - - /* 1 * (\sum \alpha_i) = success_flag */ - detail::blueprint_linear_combination a, b, c; - a.add_term(detail::blueprint_variable(0)); - for (std::size_t i = 0; i < arr.size(); ++i) { - b.add_term(alpha[i]); - } - c.add_term(success_flag); - this->bp.add_r1cs_constraint(zk::snark::r1cs_constraint(a, b, c)); + namespace blueprint { + namespace components { + + /* + loose_multiplexing implements loose multiplexer: + index not in bounds -> success_flag = 0 + index in bounds && success_flag = 1 -> result is correct + however if index is in bounds we can also set success_flag to 0 (and then result will be forced to + be 0) + */ + template + class loose_multiplexing : public component { + public: + detail::blueprint_variable_vector alpha; + + private: + std::shared_ptr> compute_result; + + public: + const detail::blueprint_linear_combination_vector arr; + const detail::blueprint_variable index; + const detail::blueprint_variable result; + const detail::blueprint_variable success_flag; + + loose_multiplexing(blueprint &bp, + const detail::blueprint_linear_combination_vector &arr, + const detail::blueprint_variable &index, + const detail::blueprint_variable &result, + const detail::blueprint_variable &success_flag) : + nil::blueprint::components::component(bp), arr(arr), index(index), result(result), + success_flag(success_flag) { + alpha.allocate(bp, arr.size()); + compute_result.reset(new inner_product(bp, alpha, arr, result)); + }; - /* now success_flag is constrained to either 0 (if index is out of - range) or \alpha_i. constrain it and \alpha_i to zero */ - generate_boolean_r1cs_constraint(this->bp, success_flag); + void generate_gates() { + /* \alpha_i (index - i) = 0 */ + for (std::size_t i = 0; i < arr.size(); ++i) { + this->bp.add_r1cs_constraint( + crypto3::zk::snark::r1cs_constraint(alpha[i], index - i, 0)); + } - /* compute result */ - compute_result->generate_gates(); + /* 1 * (\sum \alpha_i) = success_flag */ + detail::blueprint_linear_combination a, b, c; + a.add_term(detail::blueprint_variable(0)); + for (std::size_t i = 0; i < arr.size(); ++i) { + b.add_term(alpha[i]); } + c.add_term(success_flag); + this->bp.add_r1cs_constraint(crypto3::zk::snark::r1cs_constraint(a, b, c)); - void generate_assignments() { + /* now success_flag is constrained to either 0 (if index is out of + range) or \alpha_i. constrain it and \alpha_i to zero */ + generate_boolean_r1cs_constraint(this->bp, success_flag); - /* assumes that idx can be fit in ulong; true for our purposes for now */ - const typename FieldType::value_type valint = this->bp.val(index); + /* compute result */ + compute_result->generate_gates(); + } - unsigned long idx = static_cast(typename FieldType::integral_type(valint.data)); + void generate_assignments() { - if (idx >= arr.size() || typename FieldType::integral_type(valint.data) >= arr.size()) { - for (std::size_t i = 0; i < arr.size(); ++i) { - this->bp.val(alpha[i]) = FieldType::value_type::zero(); - } + /* assumes that idx can be fit in ulong; true for our purposes for now */ + const typename FieldType::value_type valint = this->bp.val(index); - this->bp.val(success_flag) = FieldType::value_type::zero(); - } else { - for (std::size_t i = 0; i < arr.size(); ++i) { - this->bp.val(alpha[i]) = - (i == idx ? FieldType::value_type::one() : FieldType::value_type::zero()); - } + unsigned long idx = static_cast(typename FieldType::integral_type(valint.data)); - this->bp.val(success_flag) = FieldType::value_type::one(); + if (idx >= arr.size() || typename FieldType::integral_type(valint.data) >= arr.size()) { + for (std::size_t i = 0; i < arr.size(); ++i) { + this->bp.val(alpha[i]) = FieldType::value_type::zero(); + } + + this->bp.val(success_flag) = FieldType::value_type::zero(); + } else { + for (std::size_t i = 0; i < arr.size(); ++i) { + this->bp.val(alpha[i]) = + (i == idx ? FieldType::value_type::one() : FieldType::value_type::zero()); } - compute_result->generate_assignments(); + this->bp.val(success_flag) = FieldType::value_type::one(); } - }; - } // namespace components - } // namespace blueprint - } // namespace crypto3 + + compute_result->generate_assignments(); + } + }; + } // namespace components + } // namespace blueprint } // namespace nil #endif // CRYPTO3_BLUEPRINT_COMPONENTS_LOOSE_MULTIPLEXING_COMPONENT_HPP diff --git a/include/nil/blueprint/components/detail/r1cs/packing.hpp b/include/nil/blueprint/components/detail/r1cs/packing.hpp index f05bc4b96..f2a0458c8 100644 --- a/include/nil/blueprint/components/detail/r1cs/packing.hpp +++ b/include/nil/blueprint/components/detail/r1cs/packing.hpp @@ -32,311 +32,299 @@ #include #include -#include #include namespace nil { - namespace crypto3 { - namespace blueprint { - namespace components { - /* forces lc to take value 0 or 1 by adding constraint lc * (1-lc) = 0 */ - template - void generate_boolean_r1cs_constraint(blueprint &bp, - const math::non_linear_combination &lc) { - bp.add_r1cs_constraint(zk::snark::r1cs_constraint(lc, Field::value_type::one() - lc, - Field::value_type::zero())); + namespace blueprint { + namespace components { + /* forces lc to take value 0 or 1 by adding constraint lc * (1-lc) = 0 */ + template + void generate_boolean_r1cs_constraint(blueprint &bp, + const crypto3::math::non_linear_combination &lc) { + bp.add_r1cs_constraint(crypto3::zk::snark::r1cs_constraint(lc, Field::value_type::one() - lc, + Field::value_type::zero())); + } + + template + void generate_r1cs_equals_const_constraint(blueprint &bp, + const crypto3::math::non_linear_combination &lc, + const typename Field::value_type &c) { + bp.add_r1cs_constraint(crypto3::zk::snark::r1cs_constraint(Field::value_type::one(), lc, c)); + } + + template + struct packing : public nil::blueprint::components::component { + using field_type = Field; + using field_value_type = typename field_type::value_type; + + const detail::blueprint_linear_combination_vector bits; + const detail::blueprint_linear_combination packed; + + packing(blueprint &bp, + const detail::blueprint_linear_combination_vector &bits, + const detail::blueprint_linear_combination &packed) : + nil::blueprint::components::component(bp), bits(bits), packed(packed) { } - - template - void generate_r1cs_equals_const_constraint(blueprint &bp, - const math::non_linear_combination &lc, - const typename Field::value_type &c) { - bp.add_r1cs_constraint(zk::snark::r1cs_constraint(Field::value_type::one(), lc, c)); + explicit packing(const detail::blueprint_linear_combination_vector &bits) : bits(bits) { } - template - struct packing : public nil::blueprint::components::component { - using field_type = Field; - using field_value_type = typename field_type::value_type; - - const detail::blueprint_linear_combination_vector bits; - const detail::blueprint_linear_combination packed; + /* adds constraint result = \sum bits[i] * 2^i */ + void generate_gates(bool enforce_bitness) { + this->bp.add_r1cs_constraint(crypto3::zk::snark::r1cs_constraint( + field_type::value_type::one(), detail::blueprint_packing_sum(bits), packed)); - packing(blueprint &bp, - const detail::blueprint_linear_combination_vector &bits, - const detail::blueprint_linear_combination &packed) : - nil::blueprint::components::component(bp), - bits(bits), packed(packed) { - } - explicit packing(const detail::blueprint_linear_combination_vector &bits) : bits(bits) { - } - - /* adds constraint result = \sum bits[i] * 2^i */ - void generate_gates(bool enforce_bitness) { - this->bp.add_r1cs_constraint(zk::snark::r1cs_constraint( - field_type::value_type::one(), detail::blueprint_packing_sum(bits), packed)); - - if (enforce_bitness) { - for (std::size_t i = 0; i < bits.size(); ++i) { - generate_boolean_r1cs_constraint(this->bp, bits[i]); - } + if (enforce_bitness) { + for (std::size_t i = 0; i < bits.size(); ++i) { + generate_boolean_r1cs_constraint(this->bp, bits[i]); } } + } - void generate_assignments_from_packed() { - packed.evaluate(this->bp); + void generate_assignments_from_packed() { + packed.evaluate(this->bp); - // `bits` is large enough to represent this packed value - assert(multiprecision::msb( - static_cast(this->bp.lc_val(packed).data)) + - 1 <= - bits.size()); - bits.fill_with_bits_of_field_element(this->bp, this->bp.lc_val(packed)); - } + // `bits` is large enough to represent this packed value + assert(multiprecision::msb( + static_cast(this->bp.lc_val(packed).data)) + + 1 <= + bits.size()); + bits.fill_with_bits_of_field_element(this->bp, this->bp.lc_val(packed)); + } - void generate_assignments_from_bits() { - bits.evaluate(this->bp); - this->bp.lc_val(packed) = bits.get_field_element_from_bits(this->bp); - } - }; - - template - class multipacking_component : public nil::blueprint::components::component { - private: - std::vector> packers; - - public: - const detail::blueprint_linear_combination_vector bits; - const detail::blueprint_linear_combination_vector packed_vars; - - const std::size_t chunk_size; - const std::size_t num_chunks; - // const std::size_t last_chunk_size; - - // last_chunk_size(bits.size() - (num_chunks-1) * chunk_size) - multipacking_component(blueprint &bp, - const detail::blueprint_linear_combination_vector &bits, - const detail::blueprint_linear_combination_vector &packed_vars, - std::size_t chunk_size) : - nil::blueprint::components::component(bp), - bits(bits), packed_vars(packed_vars), chunk_size(chunk_size), - num_chunks((bits.size() + (chunk_size - 1)) / chunk_size) { - - assert(packed_vars.size() == num_chunks); - for (std::size_t i = 0; i < num_chunks; ++i) { - packers.emplace_back( - packing(this->bp, - detail::blueprint_linear_combination_vector( - bits.begin() + i * chunk_size, - bits.begin() + std::min((i + 1) * chunk_size, bits.size())), - packed_vars[i])); - } + void generate_assignments_from_bits() { + bits.evaluate(this->bp); + this->bp.lc_val(packed) = bits.get_field_element_from_bits(this->bp); + } + }; + + template + class multipacking_component : public nil::blueprint::components::component { + private: + std::vector> packers; + + public: + const detail::blueprint_linear_combination_vector bits; + const detail::blueprint_linear_combination_vector packed_vars; + + const std::size_t chunk_size; + const std::size_t num_chunks; + // const std::size_t last_chunk_size; + + // last_chunk_size(bits.size() - (num_chunks-1) * chunk_size) + multipacking_component(blueprint &bp, + const detail::blueprint_linear_combination_vector &bits, + const detail::blueprint_linear_combination_vector &packed_vars, + std::size_t chunk_size) : + nil::blueprint::components::component(bp), bits(bits), packed_vars(packed_vars), + chunk_size(chunk_size), num_chunks((bits.size() + (chunk_size - 1)) / chunk_size) { + + assert(packed_vars.size() == num_chunks); + for (std::size_t i = 0; i < num_chunks; ++i) { + packers.emplace_back( + packing(this->bp, + detail::blueprint_linear_combination_vector( + bits.begin() + i * chunk_size, + bits.begin() + std::min((i + 1) * chunk_size, bits.size())), + packed_vars[i])); } + } - void generate_gates(const bool enforce_bitness) { - for (std::size_t i = 0; i < num_chunks; ++i) { - packers[i].generate_gates(enforce_bitness); - } + void generate_gates(const bool enforce_bitness) { + for (std::size_t i = 0; i < num_chunks; ++i) { + packers[i].generate_gates(enforce_bitness); } + } - void generate_assignments_from_packed() { - for (std::size_t i = 0; i < num_chunks; ++i) { - packers[i].generate_assignments_from_packed(); - } + void generate_assignments_from_packed() { + for (std::size_t i = 0; i < num_chunks; ++i) { + packers[i].generate_assignments_from_packed(); } + } - void generate_assignments_from_bits() { - for (std::size_t i = 0; i < num_chunks; ++i) { - packers[i].generate_assignments_from_bits(); - } + void generate_assignments_from_bits() { + for (std::size_t i = 0; i < num_chunks; ++i) { + packers[i].generate_assignments_from_bits(); } - }; - - template - class field_vector_copy_component : public nil::blueprint::components::component { - public: - const detail::blueprint_variable_vector source; - const detail::blueprint_variable_vector target; - const detail::blueprint_linear_combination do_copy; - - field_vector_copy_component(blueprint &bp, - const detail::blueprint_variable_vector &source, - const detail::blueprint_variable_vector &target, - const detail::blueprint_linear_combination &do_copy) : - nil::blueprint::components::component(bp), - source(source), target(target), do_copy(do_copy) { - - assert(source.size() == target.size()); - } - void generate_gates() { - for (std::size_t i = 0; i < source.size(); ++i) { - this->bp.add_r1cs_constraint( - zk::snark::r1cs_constraint(do_copy, source[i] - target[i], 0)); - } + } + }; + + template + class field_vector_copy_component : public nil::blueprint::components::component { + public: + const detail::blueprint_variable_vector source; + const detail::blueprint_variable_vector target; + const detail::blueprint_linear_combination do_copy; + + field_vector_copy_component(blueprint &bp, + const detail::blueprint_variable_vector &source, + const detail::blueprint_variable_vector &target, + const detail::blueprint_linear_combination &do_copy) : + nil::blueprint::components::component(bp), source(source), target(target), do_copy(do_copy) { + + assert(source.size() == target.size()); + } + void generate_gates() { + for (std::size_t i = 0; i < source.size(); ++i) { + this->bp.add_r1cs_constraint( + crypto3::zk::snark::r1cs_constraint(do_copy, source[i] - target[i], 0)); } + } - void generate_assignments() { - do_copy.evaluate(this->bp); - assert(this->bp.lc_val(do_copy) == Field::value_type::one() || - this->bp.lc_val(do_copy) == Field::value_type::zero()); - if (this->bp.lc_val(do_copy) != Field::value_type::zero()) { - for (std::size_t i = 0; i < source.size(); ++i) { - this->bp.val(target[i]) = this->bp.val(source[i]); - } + void generate_assignments() { + do_copy.evaluate(this->bp); + assert(this->bp.lc_val(do_copy) == Field::value_type::one() || + this->bp.lc_val(do_copy) == Field::value_type::zero()); + if (this->bp.lc_val(do_copy) != Field::value_type::zero()) { + for (std::size_t i = 0; i < source.size(); ++i) { + this->bp.val(target[i]) = this->bp.val(source[i]); } } - }; + } + }; - template - class bit_vector_copy_component : public nil::blueprint::components::component { - public: - const detail::blueprint_variable_vector source_bits; - const detail::blueprint_variable_vector target_bits; - const detail::blueprint_linear_combination do_copy; + template + class bit_vector_copy_component : public nil::blueprint::components::component { + public: + const detail::blueprint_variable_vector source_bits; + const detail::blueprint_variable_vector target_bits; + const detail::blueprint_linear_combination do_copy; - detail::blueprint_variable_vector packed_source; - detail::blueprint_variable_vector packed_target; + detail::blueprint_variable_vector packed_source; + detail::blueprint_variable_vector packed_target; - std::shared_ptr> pack_source; - std::shared_ptr> pack_target; - std::shared_ptr> copier; + std::shared_ptr> pack_source; + std::shared_ptr> pack_target; + std::shared_ptr> copier; - const std::size_t chunk_size; - const std::size_t num_chunks; + const std::size_t chunk_size; + const std::size_t num_chunks; - bit_vector_copy_component(blueprint &bp, - const detail::blueprint_variable_vector &source_bits, - const detail::blueprint_variable_vector &target_bits, - const detail::blueprint_linear_combination &do_copy, - std::size_t chunk_size) : - nil::blueprint::components::component(bp), - source_bits(source_bits), target_bits(target_bits), do_copy(do_copy), chunk_size(chunk_size), - num_chunks((source_bits.size() + (chunk_size - 1)) / chunk_size) { + bit_vector_copy_component(blueprint &bp, + const detail::blueprint_variable_vector &source_bits, + const detail::blueprint_variable_vector &target_bits, + const detail::blueprint_linear_combination &do_copy, + std::size_t chunk_size) : + nil::blueprint::components::component(bp), source_bits(source_bits), + target_bits(target_bits), do_copy(do_copy), chunk_size(chunk_size), + num_chunks((source_bits.size() + (chunk_size - 1)) / chunk_size) { - assert(source_bits.size() == target_bits.size()); + assert(source_bits.size() == target_bits.size()); - packed_source.allocate(bp, num_chunks); - pack_source.reset( - new multipacking_component(bp, source_bits, packed_source, chunk_size)); + packed_source.allocate(bp, num_chunks); + pack_source.reset(new multipacking_component(bp, source_bits, packed_source, chunk_size)); - packed_target.allocate(bp, num_chunks); - pack_target.reset( - new multipacking_component(bp, target_bits, packed_target, chunk_size)); + packed_target.allocate(bp, num_chunks); + pack_target.reset(new multipacking_component(bp, target_bits, packed_target, chunk_size)); - copier.reset(new field_vector_copy_component(bp, packed_source, packed_target, do_copy)); - } + copier.reset(new field_vector_copy_component(bp, packed_source, packed_target, do_copy)); + } - void generate_gates(bool enforce_source_bitness, bool enforce_target_bitness) { - pack_source->generate_gates(enforce_source_bitness); - pack_target->generate_gates(enforce_target_bitness); + void generate_gates(bool enforce_source_bitness, bool enforce_target_bitness) { + pack_source->generate_gates(enforce_source_bitness); + pack_target->generate_gates(enforce_target_bitness); - copier->generate_gates(); - } + copier->generate_gates(); + } - void generate_assignments() { - do_copy.evaluate(this->bp); - assert(this->bp.lc_val(do_copy) == Field::value_type::zero() || - this->bp.lc_val(do_copy) == Field::value_type::one()); - if (this->bp.lc_val(do_copy) == Field::value_type::one()) { - for (std::size_t i = 0; i < source_bits.size(); ++i) { - this->bp.val(target_bits[i]) = this->bp.val(source_bits[i]); - } + void generate_assignments() { + do_copy.evaluate(this->bp); + assert(this->bp.lc_val(do_copy) == Field::value_type::zero() || + this->bp.lc_val(do_copy) == Field::value_type::one()); + if (this->bp.lc_val(do_copy) == Field::value_type::one()) { + for (std::size_t i = 0; i < source_bits.size(); ++i) { + this->bp.val(target_bits[i]) = this->bp.val(source_bits[i]); } - - pack_source->generate_assignments_from_bits(); - pack_target->generate_assignments_from_bits(); - } - }; - - template - class dual_variable_component : public nil::blueprint::components::component { - private: - std::shared_ptr> consistency_check; - - public: - detail::blueprint_variable packed; - detail::blueprint_variable_vector bits; - - dual_variable_component(blueprint &bp, std::size_t width) : - nil::blueprint::components::component(bp) { - packed.allocate(bp); - bits.allocate(bp, width); - consistency_check.reset(new packing(bp, bits, packed)); } - dual_variable_component(blueprint &bp, - const detail::blueprint_variable_vector &bits) : - nil::blueprint::components::component(bp), - bits(bits) { - packed.allocate(bp); - consistency_check.reset(new packing(bp, bits, packed)); - } - - dual_variable_component(blueprint &bp, const detail::blueprint_variable &packed, - std::size_t width) : - nil::blueprint::components::component(bp), - packed(packed) { - bits.allocate(bp, width); - consistency_check.reset(new packing(bp, bits, packed)); - } + pack_source->generate_assignments_from_bits(); + pack_target->generate_assignments_from_bits(); + } + }; + + template + class dual_variable_component : public nil::blueprint::components::component { + private: + std::shared_ptr> consistency_check; + + public: + detail::blueprint_variable packed; + detail::blueprint_variable_vector bits; + + dual_variable_component(blueprint &bp, std::size_t width) : + nil::blueprint::components::component(bp) { + packed.allocate(bp); + bits.allocate(bp, width); + consistency_check.reset(new packing(bp, bits, packed)); + } - void generate_gates(bool enforce_bitness) { - consistency_check->generate_gates(enforce_bitness); - } + dual_variable_component(blueprint &bp, const detail::blueprint_variable_vector &bits) : + nil::blueprint::components::component(bp), bits(bits) { + packed.allocate(bp); + consistency_check.reset(new packing(bp, bits, packed)); + } - void generate_assignments_from_packed() { - consistency_check->generate_assignments_from_packed(); - } - void generate_assignments_from_bits() { - consistency_check->generate_assignments_from_bits(); - } - }; + dual_variable_component(blueprint &bp, const detail::blueprint_variable &packed, + std::size_t width) : + nil::blueprint::components::component(bp), packed(packed) { + bits.allocate(bp, width); + consistency_check.reset(new packing(bp, bits, packed)); + } - template - void create_linear_combination_constraints( - blueprint &bp, - const std::vector &base, - const std::vector> &v, - const VarT &target) { + void generate_gates(bool enforce_bitness) { + consistency_check->generate_gates(enforce_bitness); + } - for (std::size_t i = 0; i < base.size(); ++i) { - detail::blueprint_linear_combination a, b, c; + void generate_assignments_from_packed() { + consistency_check->generate_assignments_from_packed(); + } + void generate_assignments_from_bits() { + consistency_check->generate_assignments_from_bits(); + } + }; - a.add_term(detail::blueprint_variable(0)); - b.add_term(detail::blueprint_variable(0), base[i]); + template + void + create_linear_combination_constraints(blueprint &bp, + const std::vector &base, + const std::vector> &v, + const VarT &target) { - for (auto &p : v) { - b.add_term(p.first.all_vars[i], p.second); - } + for (std::size_t i = 0; i < base.size(); ++i) { + detail::blueprint_linear_combination a, b, c; - c.add_term(target.all_vars[i]); + a.add_term(detail::blueprint_variable(0)); + b.add_term(detail::blueprint_variable(0), base[i]); - bp.add_r1cs_constraint(zk::snark::r1cs_constraint(a, b, c)); + for (auto &p : v) { + b.add_term(p.first.all_vars[i], p.second); } - } - template - void - create_linear_combination_witness(blueprint &bp, - const std::vector &base, - const std::vector> &v, - const VarT &target) { - for (std::size_t i = 0; i < base.size(); ++i) { - bp.val(target.all_vars[i]) = base[i]; + c.add_term(target.all_vars[i]); - for (auto &p : v) { - bp.val(target.all_vars[i]) += p.second * bp.val(p.first.all_vars[i]); - } + bp.add_r1cs_constraint(crypto3::zk::snark::r1cs_constraint(a, b, c)); + } + } + + template + void create_linear_combination_witness(blueprint &bp, + const std::vector &base, + const std::vector> &v, + const VarT &target) { + for (std::size_t i = 0; i < base.size(); ++i) { + bp.val(target.all_vars[i]) = base[i]; + + for (auto &p : v) { + bp.val(target.all_vars[i]) += p.second * bp.val(p.first.all_vars[i]); } } + } - template - std::size_t multipacking_num_chunks(const std::size_t num_bits) { - return (num_bits + (Field::capacity()) - 1) / Field::capacity(); - } + template + std::size_t multipacking_num_chunks(const std::size_t num_bits) { + return (num_bits + (Field::capacity()) - 1) / Field::capacity(); + } - } // namespace components - } // namespace blueprint - } // namespace crypto3 + } // namespace components + } // namespace blueprint } // namespace nil #endif // CRYPTO3_BLUEPRINT_COMPONENTS_BASIC_COMPONENTS_HPP diff --git a/include/nil/blueprint/components/hashes/digest_selector_component.hpp b/include/nil/blueprint/components/hashes/digest_selector_component.hpp index 52a3c2a52..31b972282 100644 --- a/include/nil/blueprint/components/hashes/digest_selector_component.hpp +++ b/include/nil/blueprint/components/hashes/digest_selector_component.hpp @@ -32,58 +32,56 @@ #include namespace nil { - namespace crypto3 { - namespace blueprint { - namespace components { + namespace blueprint { + namespace components { - template - class digest_selector_component : public component { - public: - std::size_t digest_size; - digest_variable input; - detail::blueprint_linear_combination is_right; - digest_variable left; - digest_variable right; + template + class digest_selector_component : public component { + public: + std::size_t digest_size; + digest_variable input; + detail::blueprint_linear_combination is_right; + digest_variable left; + digest_variable right; - digest_selector_component(blueprint &bp, - const std::size_t digest_size, - const digest_variable &input, - const detail::blueprint_linear_combination &is_right, - const digest_variable &left, - const digest_variable &right) : - component(bp), - digest_size(digest_size), input(input), is_right(is_right), left(left), right(right) { + digest_selector_component(blueprint &bp, + const std::size_t digest_size, + const digest_variable &input, + const detail::blueprint_linear_combination &is_right, + const digest_variable &left, + const digest_variable &right) : + component(bp), digest_size(digest_size), input(input), is_right(is_right), left(left), + right(right) { + } + + void generate_gates() { + for (std::size_t i = 0; i < digest_size; ++i) { + /* + input = is_right * right + (1-is_right) * left + input - left = is_right(right - left) + */ + this->bp.add_r1cs_constraint(crypto3::zk::snark::r1cs_constraint( + is_right, right.bits[i] - left.bits[i], input.bits[i] - left.bits[i])); } + } + void generate_assignments() { + is_right.evaluate(this->bp); - void generate_gates() { + assert(this->bp.lc_val(is_right) == FieldType::value_type::one() || + this->bp.lc_val(is_right) == FieldType::value_type::zero()); + if (this->bp.lc_val(is_right) == FieldType::value_type::one()) { for (std::size_t i = 0; i < digest_size; ++i) { - /* - input = is_right * right + (1-is_right) * left - input - left = is_right(right - left) - */ - this->bp.add_r1cs_constraint(snark::r1cs_constraint( - is_right, right.bits[i] - left.bits[i], input.bits[i] - left.bits[i])); + this->bp.val(right.bits[i]) = this->bp.val(input.bits[i]); } - } - void generate_assignments() { - is_right.evaluate(this->bp); - - assert(this->bp.lc_val(is_right) == FieldType::value_type::one() || - this->bp.lc_val(is_right) == FieldType::value_type::zero()); - if (this->bp.lc_val(is_right) == FieldType::value_type::one()) { - for (std::size_t i = 0; i < digest_size; ++i) { - this->bp.val(right.bits[i]) = this->bp.val(input.bits[i]); - } - } else { - for (std::size_t i = 0; i < digest_size; ++i) { - this->bp.val(left.bits[i]) = this->bp.val(input.bits[i]); - } + } else { + for (std::size_t i = 0; i < digest_size; ++i) { + this->bp.val(left.bits[i]) = this->bp.val(input.bits[i]); } } - }; - } // namespace components - } // namespace blueprint - } // namespace crypto3 + } + }; + } // namespace components + } // namespace blueprint } // namespace nil #endif // CRYPTO3_BLUEPRINT_COMPONENTS_DIGEST_SELECTOR_COMPONENT_HPP diff --git a/include/nil/blueprint/components/hashes/hash_io.hpp b/include/nil/blueprint/components/hashes/hash_io.hpp index 98b3df0d3..6ec846804 100644 --- a/include/nil/blueprint/components/hashes/hash_io.hpp +++ b/include/nil/blueprint/components/hashes/hash_io.hpp @@ -29,151 +29,146 @@ #include #include -#include +#include #include -#include +#include namespace nil { - namespace crypto3 { - namespace blueprint { - namespace components { - - template - class digest_variable : public component { - public: - std::size_t digest_size; - detail::blueprint_variable_vector bits; - - digest_variable(blueprint &bp, std::size_t digest_size) : - component(bp), digest_size(digest_size) { - - bits.allocate(bp, digest_size); - } - - digest_variable(blueprint &bp, - std::size_t digest_size, - const detail::blueprint_variable_vector &partial_bits, - const detail::blueprint_variable &padding) : - component(bp), - digest_size(digest_size) { - - assert(bits.size() <= digest_size); - bits = partial_bits; - while (bits.size() != digest_size) { - bits.emplace_back(padding); - } - } - - void generate_gates() { - for (std::size_t i = 0; i < digest_size; ++i) { - generate_boolean_r1cs_constraint(this->bp, bits[i]); - } - } - - void generate_assignments(const std::vector &contents) { - bits.fill_with_bits(this->bp, contents); - } - - std::vector get_digest() const { - return bits.bits(this->bp); - } - }; - - template - class block_variable : public component { - public: - std::size_t block_size; - detail::blueprint_variable_vector bits; - - block_variable(blueprint &bp, std::size_t block_size) : - component(bp), block_size(block_size) { - bits.allocate(bp, block_size); + namespace blueprint { + namespace components { + + template + class digest_variable : public component { + public: + std::size_t digest_size; + detail::blueprint_variable_vector bits; + + digest_variable(blueprint &bp, std::size_t digest_size) : + component(bp), digest_size(digest_size) { + + bits.allocate(bp, digest_size); + } + + digest_variable(blueprint &bp, + std::size_t digest_size, + const detail::blueprint_variable_vector &partial_bits, + const detail::blueprint_variable &padding) : + component(bp), digest_size(digest_size) { + + assert(bits.size() <= digest_size); + bits = partial_bits; + while (bits.size() != digest_size) { + bits.emplace_back(padding); } + } - block_variable(blueprint &bp, - const std::vector> &parts) : - component(bp) { - - for (auto &part : parts) { - bits.insert(bits.end(), part.begin(), part.end()); - } - block_size = bits.size(); + void generate_gates() { + for (std::size_t i = 0; i < digest_size; ++i) { + generate_boolean_r1cs_constraint(this->bp, bits[i]); } - - block_variable(blueprint &bp, - const digest_variable &left, - const digest_variable &right) : - component(bp) { - - assert(left.bits.size() == right.bits.size()); - block_size = 2 * left.bits.size(); - bits.insert(bits.end(), left.bits.begin(), left.bits.end()); - bits.insert(bits.end(), right.bits.begin(), right.bits.end()); + } + + void generate_assignments(const std::vector &contents) { + bits.fill_with_bits(this->bp, contents); + } + + std::vector get_digest() const { + return bits.bits(this->bp); + } + }; + + template + class block_variable : public component { + public: + std::size_t block_size; + detail::blueprint_variable_vector bits; + + block_variable(blueprint &bp, std::size_t block_size) : + component(bp), block_size(block_size) { + bits.allocate(bp, block_size); + } + + block_variable(blueprint &bp, + const std::vector> &parts) : + component(bp) { + + for (auto &part : parts) { + bits.insert(bits.end(), part.begin(), part.end()); } - - void generate_gates() { - for (std::size_t i = 0; i < block_size; ++i) { - generate_boolean_r1cs_constraint(this->bp, bits[i]); - } + block_size = bits.size(); + } + + block_variable(blueprint &bp, + const digest_variable &left, + const digest_variable &right) : component(bp) { + + assert(left.bits.size() == right.bits.size()); + block_size = 2 * left.bits.size(); + bits.insert(bits.end(), left.bits.begin(), left.bits.end()); + bits.insert(bits.end(), right.bits.begin(), right.bits.end()); + } + + void generate_gates() { + for (std::size_t i = 0; i < block_size; ++i) { + generate_boolean_r1cs_constraint(this->bp, bits[i]); } - - template - void generate_assignments(const InputRange &contents) { - bits.fill_with_bits(this->bp, contents); - } - - std::vector get_block() const { - return bits.bits(this->bp); - } - }; - - template - class merkle_damagard_padding : public component { - public: - detail::blueprint_variable_vector bits; - detail::blueprint_variable one; - detail::blueprint_variable zero; - - merkle_damagard_padding(blueprint &bp, - size_t message_length, - size_t message_length_bits_size, - size_t block_bits) : - component(bp) { - assert(message_length_bits_size <= block_bits); - one.allocate(bp); - zero.allocate(bp); - std::size_t message_remainder = message_length % block_bits; - size_t padding_length = 2 * block_bits - message_remainder - message_length_bits_size; - padding_length = padding_length % block_bits; - - bits.resize(padding_length + message_length_bits_size); - if (padding_length > 0) { - bits[0] = one; - for (size_t i = 1; i < padding_length; ++i) { - bits[i] = zero; - } + } + + template + void generate_assignments(const InputRange &contents) { + bits.fill_with_bits(this->bp, contents); + } + + std::vector get_block() const { + return bits.bits(this->bp); + } + }; + + template + class merkle_damagard_padding : public component { + public: + detail::blueprint_variable_vector bits; + detail::blueprint_variable one; + detail::blueprint_variable zero; + + merkle_damagard_padding(blueprint &bp, + size_t message_length, + size_t message_length_bits_size, + size_t block_bits) : component(bp) { + assert(message_length_bits_size <= block_bits); + one.allocate(bp); + zero.allocate(bp); + std::size_t message_remainder = message_length % block_bits; + size_t padding_length = 2 * block_bits - message_remainder - message_length_bits_size; + padding_length = padding_length % block_bits; + + bits.resize(padding_length + message_length_bits_size); + if (padding_length > 0) { + bits[0] = one; + for (size_t i = 1; i < padding_length; ++i) { + bits[i] = zero; } - - unsigned long long message_length_iter = message_length; - for (int i = message_length_bits_size - 1; i >= 0; --i) { - bits[padding_length + i] = (message_length_iter & 1 ? one : zero); - message_length_iter = message_length_iter >> 1; - } - assert(message_length_iter == 0); - } - - void generate_gates() { - generate_r1cs_equals_const_constraint(this->bp, one, FieldType::value_type::one()); - generate_r1cs_equals_const_constraint(this->bp, zero, FieldType::value_type::zero()); } - void generate_assignments() { - this->bp.val(one) = 1; - this->bp.val(zero) = 0; + unsigned long long message_length_iter = message_length; + for (int i = message_length_bits_size - 1; i >= 0; --i) { + bits[padding_length + i] = (message_length_iter & 1 ? one : zero); + message_length_iter = message_length_iter >> 1; } - }; - } // namespace components - } // namespace blueprint - } // namespace crypto3 + assert(message_length_iter == 0); + } + + void generate_gates() { + generate_r1cs_equals_const_constraint(this->bp, one, FieldType::value_type::one()); + generate_r1cs_equals_const_constraint(this->bp, zero, FieldType::value_type::zero()); + } + + void generate_assignments() { + this->bp.val(one) = 1; + this->bp.val(zero) = 0; + } + }; + } // namespace components + } // namespace blueprint } // namespace nil #endif // CRYPTO3_BLUEPRINT_COMPONENTS_HASH_IO_HPP diff --git a/include/nil/blueprint/components/hashes/knapsack/r1cs/knapsack.hpp b/include/nil/blueprint/components/hashes/knapsack/r1cs/knapsack.hpp index dbe3f67dc..3224dba50 100644 --- a/include/nil/blueprint/components/hashes/knapsack/r1cs/knapsack.hpp +++ b/include/nil/blueprint/components/hashes/knapsack/r1cs/knapsack.hpp @@ -65,7 +65,7 @@ #include -#include +#include #include namespace nil { diff --git a/include/nil/blueprint/components/hashes/pedersen.hpp b/include/nil/blueprint/components/hashes/pedersen.hpp index 06c89d001..2e414c800 100644 --- a/include/nil/blueprint/components/hashes/pedersen.hpp +++ b/include/nil/blueprint/components/hashes/pedersen.hpp @@ -32,469 +32,446 @@ #include #include -#include +#include #include namespace nil { - namespace crypto3 { - namespace blueprint { - namespace components { - /** - * Windowed hash function using elliptic curves point multiplication - * - * For a given input of scalars, create an equivalent set of base points within a namespace. - */ - template, - typename HashParams = hashes::find_group_hash_default_params> - struct pedersen_to_point : public component { - using curve_type = Curve; - using commitment_component = fixed_base_mul_zcash; - using field_type = typename commitment_component::field_type; - using element_component = typename commitment_component::twisted_edwards_element_component; - - using result_type = element_component; - - // hash_type is corresponding to the component hash policy - // void means there is no implementation of the corresponding hash algorithm - using hash_type = void; - - commitment_component m_commitment; - result_type result; - - static std::vector get_base_points(std::size_t n) { - using group_hash_type = hashes::find_group_hash; - assert(n > 0); - std::vector basepoints; - for (std::uint32_t i = 0; i < n; ++i) { - basepoints.emplace_back(hash({ - i, - })); + namespace blueprint { + namespace components { + /** + * Windowed hash function using elliptic curves point multiplication + * + * For a given input of scalars, create an equivalent set of base points within a namespace. + */ + template, + typename HashParams = crypto3::hashes::find_group_hash_default_params> + struct pedersen_to_point : public component { + using curve_type = Curve; + using commitment_component = fixed_base_mul_zcash; + using field_type = typename commitment_component::field_type; + using element_component = typename commitment_component::twisted_edwards_element_component; + + using result_type = element_component; + + // hash_type is corresponding to the component hash policy + // void means there is no implementation of the corresponding hash algorithm + using hash_type = void; + + commitment_component m_commitment; + result_type result; + + static std::vector get_base_points(std::size_t n) { + using group_hash_type = crypto3::hashes::find_group_hash; + assert(n > 0); + std::vector basepoints; + for (std::uint32_t i = 0; i < n; ++i) { + basepoints.emplace_back(crypto3::hash({i})); + } + return basepoints; + } + + /// Auto allocation of the result. + /// Take in_bits as blueprint_variable_vector. + pedersen_to_point(blueprint &bp, + const detail::blueprint_variable_vector &in_bits) : + component(bp), + m_commitment(bp, get_base_points(commitment_component::basepoints_required(in_bits.size())), + in_bits), + result(m_commitment.result) { + } + + /// Auto allocation of the result. + /// Take in_bits as block_variable. + pedersen_to_point(blueprint &bp, const block_variable &in_block) : + pedersen_to_point(bp, in_block.bits) { + } + + /// Auto allocation of the result. + /// Take in_bits as digest_variable. + pedersen_to_point(blueprint &bp, const digest_variable &in_digest) : + pedersen_to_point(bp, in_digest.bits) { + } + + /// Auto allocation of the result. + /// Take in_bits as container of block_variable. + template, + typename std::iterator_traits::value_type>::value, + bool>::type = true> + pedersen_to_point(blueprint &bp, const Blocks &in_blocks) : + pedersen_to_point(bp, [&]() { + detail::blueprint_variable_vector in_bits; + for (const auto &in_block : in_blocks) { + in_bits.insert(std::end(in_bits), std::cbegin(in_block.bits), std::cend(in_block.bits)); } - return basepoints; - } - - /// Auto allocation of the result. - /// Take in_bits as blueprint_variable_vector. - pedersen_to_point(blueprint &bp, - const detail::blueprint_variable_vector &in_bits) : - component(bp), - m_commitment(bp, get_base_points(commitment_component::basepoints_required(in_bits.size())), - in_bits), - result(m_commitment.result) { - } - - /// Auto allocation of the result. - /// Take in_bits as block_variable. - pedersen_to_point(blueprint &bp, const block_variable &in_block) : - pedersen_to_point(bp, in_block.bits) { - } - - /// Auto allocation of the result. - /// Take in_bits as digest_variable. - pedersen_to_point(blueprint &bp, const digest_variable &in_digest) : - pedersen_to_point(bp, in_digest.bits) { - } - - /// Auto allocation of the result. - /// Take in_bits as container of block_variable. - template< - typename Blocks, - typename std::enable_if< - std::is_same, - typename std::iterator_traits::value_type>::value, - bool>::type = true> - pedersen_to_point(blueprint &bp, const Blocks &in_blocks) : - pedersen_to_point(bp, [&]() { + return in_bits; + }()) { + } + + /// Auto allocation of the result. + /// Take in_bits as container of digest_variable. + template, + typename std::iterator_traits::value_type>::value, + bool>::type = true> + pedersen_to_point(blueprint &bp, const Digests &in_digests) : + pedersen_to_point(bp, [&]() { + detail::blueprint_variable_vector in_bits; + for (const auto &in_digest : in_digests) { + in_bits.insert(std::end(in_bits), std::cbegin(in_digest.bits), std::cend(in_digest.bits)); + } + return in_bits; + }()) { + } + + /// Manual allocation of the result + /// Take in_bits as blueprint_variable_vector. + pedersen_to_point(blueprint &bp, + const detail::blueprint_variable_vector &in_bits, + const result_type &in_result) : + component(bp), + m_commitment(bp, get_base_points(commitment_component::basepoints_required(in_bits.size())), + in_bits, in_result), + result(m_commitment.result) { + } + + /// Manual allocation of the result + /// Take in_bits as block_variable. + pedersen_to_point(blueprint &bp, const block_variable &in_block, + const result_type &in_result) : pedersen_to_point(bp, in_block.bits, in_result) { + } + + /// Manual allocation of the result + /// Take in_bits as digest_variable. + pedersen_to_point(blueprint &bp, const digest_variable &in_digest, + const result_type &in_result) : pedersen_to_point(bp, in_digest.bits, in_result) { + } + + /// Manual allocation of the result + /// Take in_bits as container of block_variable. + template, + typename std::iterator_traits::value_type>::value, + bool>::type = true> + pedersen_to_point(blueprint &bp, const Blocks &in_blocks, const result_type &in_result) : + pedersen_to_point( + bp, + [&]() { detail::blueprint_variable_vector in_bits; for (const auto &in_block : in_blocks) { in_bits.insert(std::end(in_bits), std::cbegin(in_block.bits), std::cend(in_block.bits)); } return in_bits; - }()) { - } - - /// Auto allocation of the result. - /// Take in_bits as container of digest_variable. - template< - typename Digests, - typename std::enable_if< - std::is_same, - typename std::iterator_traits::value_type>::value, - bool>::type = true> - pedersen_to_point(blueprint &bp, const Digests &in_digests) : - pedersen_to_point(bp, [&]() { + }(), + in_result) { + } + + /// Manual allocation of the result + /// Take in_bits as container of digest_variable. + template, + typename std::iterator_traits::value_type>::value, + bool>::type = true> + pedersen_to_point(blueprint &bp, const Digests &in_digests, const result_type &in_result) : + pedersen_to_point( + bp, + [&]() { detail::blueprint_variable_vector in_bits; for (const auto &in_digest : in_digests) { in_bits.insert(std::end(in_bits), std::cbegin(in_digest.bits), std::cend(in_digest.bits)); } return in_bits; - }()) { - } - - /// Manual allocation of the result - /// Take in_bits as blueprint_variable_vector. - pedersen_to_point(blueprint &bp, - const detail::blueprint_variable_vector &in_bits, - const result_type &in_result) : - component(bp), - m_commitment(bp, get_base_points(commitment_component::basepoints_required(in_bits.size())), - in_bits, in_result), - result(m_commitment.result) { - } - - /// Manual allocation of the result - /// Take in_bits as block_variable. - pedersen_to_point(blueprint &bp, const block_variable &in_block, - const result_type &in_result) : - pedersen_to_point(bp, in_block.bits, in_result) { - } - - /// Manual allocation of the result - /// Take in_bits as digest_variable. - pedersen_to_point(blueprint &bp, const digest_variable &in_digest, - const result_type &in_result) : - pedersen_to_point(bp, in_digest.bits, in_result) { - } - - /// Manual allocation of the result - /// Take in_bits as container of block_variable. - template< - typename Blocks, - typename std::enable_if< - std::is_same, - typename std::iterator_traits::value_type>::value, - bool>::type = true> - pedersen_to_point(blueprint &bp, const Blocks &in_blocks, - const result_type &in_result) : - pedersen_to_point( - bp, - [&]() { - detail::blueprint_variable_vector in_bits; - for (const auto &in_block : in_blocks) { - in_bits.insert(std::end(in_bits), std::cbegin(in_block.bits), - std::cend(in_block.bits)); - } - return in_bits; - }(), - in_result) { - } - - /// Manual allocation of the result - /// Take in_bits as container of digest_variable. - template< - typename Digests, - typename std::enable_if< - std::is_same, - typename std::iterator_traits::value_type>::value, - bool>::type = true> - pedersen_to_point(blueprint &bp, const Digests &in_digests, - const result_type &in_result) : - pedersen_to_point( - bp, - [&]() { - detail::blueprint_variable_vector in_bits; - for (const auto &in_digest : in_digests) { - in_bits.insert(std::end(in_bits), std::cbegin(in_digest.bits), - std::cend(in_digest.bits)); - } - return in_bits; - }(), - in_result) { - } - - // TODO: ignored for now, enforce bitness checking constrains - void generate_gates(bool ensure_output_bitness = false) { - this->m_commitment.generate_gates(); - } - - void generate_assignments() { - this->m_commitment.generate_assignments(); - } - }; - - template, - typename HashParams = hashes::find_group_hash_default_params> - struct pedersen : public component { - using curve_type = Curve; - using hash_component = pedersen_to_point; - using field_type = typename hash_component::field_type; - using element_component = typename hash_component::element_component; - using to_bits_component = typename element_component::to_bits_component; - - using result_type = digest_variable; - - // hash_type is corresponding to the component hash policy - using hash_type = nil::crypto3::hashes::pedersen; - // TODO: retrieve digest_bits from hash_type - static constexpr std::size_t digest_bits = field_type::value_bits; - - hash_component hasher; - to_bits_component to_bits_converter; - result_type result; - - /// Auto allocation of the result. - /// Take in_bits as blueprint_variable_vector. - pedersen(blueprint &bp, const detail::blueprint_variable_vector &in_bits) : - component(bp), hasher(bp, in_bits), to_bits_converter(bp, hasher.result), - result(bp, digest_bits, to_bits_converter.result, 0) { - assert(this->result.digest_size == digest_bits); - } - - /// Auto allocation of the result. - /// Take in_bits as block_variable. - pedersen(blueprint &bp, const block_variable &in_block) : - pedersen(bp, in_block.bits) { - } - - /// Auto allocation of the result. - /// Take in_bits as digest_variable. - pedersen(blueprint &bp, const digest_variable &in_digest) : - pedersen(bp, in_digest.bits) { - } - - /// Auto allocation of the result. - /// Take in_bits as container of block_variable. - template< - typename Blocks, - typename std::enable_if< - std::is_same, - typename std::iterator_traits::value_type>::value, - bool>::type = true> - pedersen(blueprint &bp, const Blocks &in_blocks) : - pedersen(bp, [&]() { + }(), + in_result) { + } + + // TODO: ignored for now, enforce bitness checking constrains + void generate_gates(bool ensure_output_bitness = false) { + this->m_commitment.generate_gates(); + } + + void generate_assignments() { + this->m_commitment.generate_assignments(); + } + }; + + template, + typename HashParams = crypto3::hashes::find_group_hash_default_params> + struct pedersen : public component { + using curve_type = Curve; + using hash_component = pedersen_to_point; + using field_type = typename hash_component::field_type; + using element_component = typename hash_component::element_component; + using to_bits_component = typename element_component::to_bits_component; + + using result_type = digest_variable; + + // hash_type is corresponding to the component hash policy + using hash_type = nil::crypto3::hashes::pedersen; + // TODO: retrieve digest_bits from hash_type + static constexpr std::size_t digest_bits = field_type::value_bits; + + hash_component hasher; + to_bits_component to_bits_converter; + result_type result; + + /// Auto allocation of the result. + /// Take in_bits as blueprint_variable_vector. + pedersen(blueprint &bp, const detail::blueprint_variable_vector &in_bits) : + component(bp), hasher(bp, in_bits), to_bits_converter(bp, hasher.result), + result(bp, digest_bits, to_bits_converter.result, 0) { + assert(this->result.digest_size == digest_bits); + } + + /// Auto allocation of the result. + /// Take in_bits as block_variable. + pedersen(blueprint &bp, const block_variable &in_block) : + pedersen(bp, in_block.bits) { + } + + /// Auto allocation of the result. + /// Take in_bits as digest_variable. + pedersen(blueprint &bp, const digest_variable &in_digest) : + pedersen(bp, in_digest.bits) { + } + + /// Auto allocation of the result. + /// Take in_bits as container of block_variable. + template, + typename std::iterator_traits::value_type>::value, + bool>::type = true> + pedersen(blueprint &bp, const Blocks &in_blocks) : + pedersen(bp, [&]() { + detail::blueprint_variable_vector in_bits; + for (const auto &in_block : in_blocks) { + in_bits.insert(std::end(in_bits), std::cbegin(in_block.bits), std::cend(in_block.bits)); + } + return in_bits; + }()) { + } + + /// Auto allocation of the result. + /// Take in_bits as container of digest_variable. + template, + typename std::iterator_traits::value_type>::value, + bool>::type = true> + pedersen(blueprint &bp, const Digests &in_digests) : + pedersen(bp, [&]() { + detail::blueprint_variable_vector in_bits; + for (const auto &in_digest : in_digests) { + in_bits.insert(std::end(in_bits), std::cbegin(in_digest.bits), std::cend(in_digest.bits)); + } + return in_bits; + }()) { + } + + /// Manual allocation of the result. + /// Take in_bits as blueprint_variable_vector. + pedersen(blueprint &bp, const detail::blueprint_variable_vector &in_bits, + const result_type &in_result) : + component(bp), hasher(bp, in_bits), + to_bits_converter(bp, hasher.result, in_result.bits), result(in_result) { + assert(this->result.digest_size == digest_bits); + } + + /// Manual allocation of the result. + /// Take in_bits as block_variable. + pedersen(blueprint &bp, const block_variable &in_block, + const result_type &in_result) : pedersen(bp, in_block.bits, in_result) { + } + + /// Manual allocation of the result. + /// Take in_bits as digest_variable. + pedersen(blueprint &bp, const digest_variable &in_digest, + const result_type &in_result) : pedersen(bp, in_digest.bits, in_result) { + } + + /// Manual allocation of the result. + /// Take in_bits as container of block_variable. + template, + typename std::iterator_traits::value_type>::value, + bool>::type = true> + pedersen(blueprint &bp, const Blocks &in_blocks, const result_type &in_result) : + pedersen( + bp, + [&]() { detail::blueprint_variable_vector in_bits; for (const auto &in_block : in_blocks) { in_bits.insert(std::end(in_bits), std::cbegin(in_block.bits), std::cend(in_block.bits)); } return in_bits; - }()) { - } - - /// Auto allocation of the result. - /// Take in_bits as container of digest_variable. - template< - typename Digests, - typename std::enable_if< - std::is_same, - typename std::iterator_traits::value_type>::value, - bool>::type = true> - pedersen(blueprint &bp, const Digests &in_digests) : - pedersen(bp, [&]() { + }(), + in_result) { + } + + /// Manual allocation of the result. + /// Take in_bits as container of digest_variable. + template, + typename std::iterator_traits::value_type>::value, + bool>::type = true> + pedersen(blueprint &bp, const Digests &in_digests, const result_type &in_result) : + pedersen( + bp, + [&]() { detail::blueprint_variable_vector in_bits; for (const auto &in_digest : in_digests) { in_bits.insert(std::end(in_bits), std::cbegin(in_digest.bits), std::cend(in_digest.bits)); } return in_bits; - }()) { - } - - /// Manual allocation of the result. - /// Take in_bits as blueprint_variable_vector. - pedersen(blueprint &bp, const detail::blueprint_variable_vector &in_bits, - const result_type &in_result) : - component(bp), - hasher(bp, in_bits), to_bits_converter(bp, hasher.result, in_result.bits), result(in_result) { - assert(this->result.digest_size == digest_bits); - } - - /// Manual allocation of the result. - /// Take in_bits as block_variable. - pedersen(blueprint &bp, const block_variable &in_block, - const result_type &in_result) : - pedersen(bp, in_block.bits, in_result) { - } - - /// Manual allocation of the result. - /// Take in_bits as digest_variable. - pedersen(blueprint &bp, const digest_variable &in_digest, - const result_type &in_result) : - pedersen(bp, in_digest.bits, in_result) { - } - - /// Manual allocation of the result. - /// Take in_bits as container of block_variable. - template< - typename Blocks, - typename std::enable_if< - std::is_same, - typename std::iterator_traits::value_type>::value, - bool>::type = true> - pedersen(blueprint &bp, const Blocks &in_blocks, const result_type &in_result) : - pedersen( - bp, - [&]() { - detail::blueprint_variable_vector in_bits; - for (const auto &in_block : in_blocks) { - in_bits.insert(std::end(in_bits), std::cbegin(in_block.bits), - std::cend(in_block.bits)); - } - return in_bits; - }(), - in_result) { - } - - /// Manual allocation of the result. - /// Take in_bits as container of digest_variable. - template< - typename Digests, - typename std::enable_if< - std::is_same, - typename std::iterator_traits::value_type>::value, - bool>::type = true> - pedersen(blueprint &bp, const Digests &in_digests, const result_type &in_result) : - pedersen( - bp, - [&]() { - detail::blueprint_variable_vector in_bits; - for (const auto &in_digest : in_digests) { - in_bits.insert(std::end(in_bits), std::cbegin(in_digest.bits), - std::cend(in_digest.bits)); - } - return in_bits; - }(), - in_result) { - } - - // TODO: ignored for now, enforce bitness checking constrains - void generate_gates(bool ensure_output_bitness = false) { - this->hasher.generate_gates(ensure_output_bitness); - this->to_bits_converter.generate_gates(); - this->result.generate_gates(); - } - - void generate_assignments() { - this->hasher.generate_assignments(); - // to_bits_converter generate witness also for result - this->to_bits_converter.generate_assignments(); - } - - static std::size_t get_digest_len() { - return digest_bits; - } - }; - - /// @brief See https://zips.z.cash/protocol/protocol.pdf#concretewindowedcommit - template, - typename HashParams = hashes::find_group_hash_default_params> - struct pedersen_commitment_to_point : public component { - using hash_component = pedersen_to_point; - using element_component = typename hash_component::element_component; - using addition_component = typename element_component::addition_component; - - using field_type = typename hash_component::field_type; - using result_type = typename hash_component::result_type; - - public: - result_type result; - - private: - hash_component hasher; - element_component random_point; - addition_component adder; - - /// Auto allocation of the result - /// Take in_bits as blueprint_variable_vector. - pedersen_commitment_to_point(blueprint &bp, - const detail::blueprint_variable_vector &in_bits) : - component(bp), - // public field - result(bp), - // private fields - hasher(bp, in_bits), random_point(bp), adder(bp, hasher.result, random_point, result) { - } - - /// Manual allocation of the result - /// Take in_bits as blueprint_variable_vector. - pedersen_commitment_to_point(blueprint &bp, - const detail::blueprint_variable_vector &in_bits, - const result_type &result) : - component(bp), - // public field - result(result), - // private fields - hasher(bp, in_bits), random_point(bp), adder(bp, hasher.result, random_point, result) { - } - - void generate_gates(bool ensure_output_bitness = false) { - hasher.generate_gates(ensure_output_bitness); - adder.generate_gates(); - } - - void generate_assignments(const typename field_type::value_type &r) { - using group_hash_type = hashes::find_group_hash; - - hasher.generate_assignments(); - random_point.generate_assignments(r * hash(std::vector { - 'r', - })); - adder.generate_assignments(); - } - }; - - template, - typename HashParams = hashes::find_group_hash_default_params> - struct pedersen_commitment : public component { - using commitment_component = - pedersen_commitment_to_point; - using element_component = typename commitment_component::element_component; - using to_bits_component = typename element_component::to_bits_component; - - using field_type = typename commitment_component::field_type; - using result_type = digest_variable; - - private: - commitment_component commiter; - to_bits_component to_bits_converter; - - public: - result_type result; - - /// Auto allocation of the result - /// Take in_bits as blueprint_variable_vector. - pedersen_commitment(blueprint &bp, - const detail::blueprint_variable_vector &in_bits) : - component(bp), - // private fields - commiter(bp, in_bits), to_bits_converter(bp, commiter.result), - // public field - result(bp, field_type::value_bits, to_bits_converter.result, 0) { - } - - /// Manual allocation of the result - /// Take in_bits as blueprint_variable_vector. - pedersen_commitment(blueprint &bp, - const detail::blueprint_variable_vector &in_bits, - const result_type &result) : - component(bp), - // private fields - commiter(bp, in_bits), to_bits_converter(bp, commiter.result, result.bits), - // public field - result(result) { - } - - void generate_gates(bool ensure_output_bitness = false) { - commiter.generate_gates(ensure_output_bitness); - to_bits_converter.generate_gates(); - } - - void generate_assignments(const typename field_type::value_type &r) { - commiter.generate_assignments(r); - // to_bits_converter generate witness also for result - to_bits_converter.generate_assignments(); - result.generate_gates(); - } - }; - } // namespace components - } // namespace blueprint - } // namespace crypto3 + }(), + in_result) { + } + + // TODO: ignored for now, enforce bitness checking constrains + void generate_gates(bool ensure_output_bitness = false) { + this->hasher.generate_gates(ensure_output_bitness); + this->to_bits_converter.generate_gates(); + this->result.generate_gates(); + } + + void generate_assignments() { + this->hasher.generate_assignments(); + // to_bits_converter generate witness also for result + this->to_bits_converter.generate_assignments(); + } + + static std::size_t get_digest_len() { + return digest_bits; + } + }; + + /// @brief See https://zips.z.cash/protocol/protocol.pdf#concretewindowedcommit + template, + typename HashParams = crypto3::hashes::find_group_hash_default_params> + struct pedersen_commitment_to_point : public component { + using hash_component = pedersen_to_point; + using element_component = typename hash_component::element_component; + using addition_component = typename element_component::addition_component; + + using field_type = typename hash_component::field_type; + using result_type = typename hash_component::result_type; + + public: + result_type result; + + private: + hash_component hasher; + element_component random_point; + addition_component adder; + + /// Auto allocation of the result + /// Take in_bits as blueprint_variable_vector. + pedersen_commitment_to_point(blueprint &bp, + const detail::blueprint_variable_vector &in_bits) : + component(bp), + // public field + result(bp), + // private fields + hasher(bp, in_bits), random_point(bp), adder(bp, hasher.result, random_point, result) { + } + + /// Manual allocation of the result + /// Take in_bits as blueprint_variable_vector. + pedersen_commitment_to_point(blueprint &bp, + const detail::blueprint_variable_vector &in_bits, + const result_type &result) : + component(bp), + // public field + result(result), + // private fields + hasher(bp, in_bits), random_point(bp), adder(bp, hasher.result, random_point, result) { + } + + void generate_gates(bool ensure_output_bitness = false) { + hasher.generate_gates(ensure_output_bitness); + adder.generate_gates(); + } + + void generate_assignments(const typename field_type::value_type &r) { + using group_hash_type = crypto3::hashes::find_group_hash; + + hasher.generate_assignments(); + random_point.generate_assignments(r * crypto3::hash(std::vector { + 'r', + })); + adder.generate_assignments(); + } + }; + + template, + typename HashParams = crypto3::hashes::find_group_hash_default_params> + struct pedersen_commitment : public component { + using commitment_component = pedersen_commitment_to_point; + using element_component = typename commitment_component::element_component; + using to_bits_component = typename element_component::to_bits_component; + + using field_type = typename commitment_component::field_type; + using result_type = digest_variable; + + private: + commitment_component commiter; + to_bits_component to_bits_converter; + + public: + result_type result; + + /// Auto allocation of the result + /// Take in_bits as blueprint_variable_vector. + pedersen_commitment(blueprint &bp, + const detail::blueprint_variable_vector &in_bits) : + component(bp), + // private fields + commiter(bp, in_bits), to_bits_converter(bp, commiter.result), + // public field + result(bp, field_type::value_bits, to_bits_converter.result, 0) { + } + + /// Manual allocation of the result + /// Take in_bits as blueprint_variable_vector. + pedersen_commitment(blueprint &bp, + const detail::blueprint_variable_vector &in_bits, + const result_type &result) : + component(bp), + // private fields + commiter(bp, in_bits), to_bits_converter(bp, commiter.result, result.bits), + // public field + result(result) { + } + + void generate_gates(bool ensure_output_bitness = false) { + commiter.generate_gates(ensure_output_bitness); + to_bits_converter.generate_gates(); + } + + void generate_assignments(const typename field_type::value_type &r) { + commiter.generate_assignments(r); + // to_bits_converter generate witness also for result + to_bits_converter.generate_assignments(); + result.generate_gates(); + } + }; + } // namespace components + } // namespace blueprint } // namespace nil #endif // CRYPTO3_BLUEPRINT_COMPONENTS_HASHES_PEDERSEN_HPP \ No newline at end of file diff --git a/include/nil/blueprint/components/hashes/poseidon/plonk/poseidon.hpp b/include/nil/blueprint/components/hashes/poseidon/plonk/poseidon.hpp index d3fe2c8c9..7e5ff2673 100644 --- a/include/nil/blueprint/components/hashes/poseidon/plonk/poseidon.hpp +++ b/include/nil/blueprint/components/hashes/poseidon/plonk/poseidon.hpp @@ -29,7 +29,8 @@ #include -#include +#include + #include #include #include @@ -50,8 +51,7 @@ namespace nil { class poseidon; template - class poseidon, - FieldType> + class poseidon, FieldType> : public plonk_component { public: @@ -84,20 +84,16 @@ namespace nil { } }; - static gate_manifest get_gate_manifest(std::size_t witness_amount, - std::size_t lookup_column_amount) { + static gate_manifest get_gate_manifest(std::size_t witness_amount, std::size_t lookup_column_amount) { static gate_manifest manifest = gate_manifest(gate_manifest_type()); return manifest; } - static manifest_type get_manifest() { using manifest_param = nil::blueprint::manifest_param; using manifest_single_value_param = nil::blueprint::manifest_single_value_param; - static manifest_type manifest = manifest_type( - std::shared_ptr(new manifest_single_value_param(15)), - false - ); + static manifest_type manifest = + manifest_type(std::shared_ptr(new manifest_single_value_param(15)), false); return manifest; } @@ -149,24 +145,18 @@ namespace nil { std::initializer_list constants, std::initializer_list - public_inputs) : - component_type(witnesses, constants, public_inputs, get_manifest()) {}; + public_inputs) : component_type(witnesses, constants, public_inputs, get_manifest()) {}; }; template - using plonk_poseidon = - poseidon, - FieldType>; + using plonk_poseidon = poseidon, FieldType>; template - typename plonk_poseidon::result_type - generate_assignments( - const plonk_poseidon &component, - assignment> - &assignment, - const typename plonk_poseidon::input_type - instance_input, - const std::uint32_t start_row_index) { + typename plonk_poseidon::result_type generate_assignments( + const plonk_poseidon &component, + assignment> &assignment, + const typename plonk_poseidon::input_type instance_input, + const std::uint32_t start_row_index) { using component_type = plonk_poseidon; @@ -239,21 +229,17 @@ namespace nil { state = next_state; } - return typename plonk_poseidon::result_type( - component, start_row_index); + return typename plonk_poseidon::result_type(component, start_row_index); } template - std::array::rounds_amount / - plonk_poseidon::rounds_per_row> - generate_gates( - const plonk_poseidon &component, - circuit> &bp, - assignment> - &assignment, - const typename plonk_poseidon::input_type - &instance_input) { + std::array::rounds_amount / + plonk_poseidon::rounds_per_row> + generate_gates( + const plonk_poseidon &component, + circuit> &bp, + assignment> &assignment, + const typename plonk_poseidon::input_type &instance_input) { using component_type = plonk_poseidon; using var = typename component_type::var; @@ -357,10 +343,10 @@ namespace nil { var(component.W(13), 0).pow(component_type::sbox_alpha) * component_type::mds[2][1] + var(component.W(14), 0).pow(component_type::sbox_alpha) * component_type::mds[2][2] + component_type::round_constant[z + 4][2]); - selectors[j] = bp.add_gate( - {constraint_1, constraint_2, constraint_3, constraint_4, constraint_5, constraint_6, - constraint_7, constraint_8, constraint_9, constraint_10, constraint_11, constraint_12, - constraint_13, constraint_14, constraint_15}); + selectors[j] = + bp.add_gate({constraint_1, constraint_2, constraint_3, constraint_4, constraint_5, constraint_6, + constraint_7, constraint_8, constraint_9, constraint_10, constraint_11, + constraint_12, constraint_13, constraint_14, constraint_15}); j++; } return selectors; @@ -370,10 +356,8 @@ namespace nil { void generate_copy_constraints( const plonk_poseidon &component, circuit> &bp, - assignment> - &assignment, - const typename plonk_poseidon::input_type - &instance_input, + assignment> &assignment, + const typename plonk_poseidon::input_type &instance_input, const std::size_t start_row_index) { // CRITICAL: these copy constraints might not be sufficient, but are definitely required. @@ -386,30 +370,24 @@ namespace nil { } template - typename plonk_poseidon::result_type - generate_circuit( - const plonk_poseidon &component, - circuit> &bp, - assignment> - &assignment, - const typename plonk_poseidon::input_type - &instance_input, - const std::size_t start_row_index) { + typename plonk_poseidon::result_type generate_circuit( + const plonk_poseidon &component, + circuit> &bp, + assignment> &assignment, + const typename plonk_poseidon::input_type &instance_input, + const std::size_t start_row_index) { auto selector_indices = generate_gates(component, bp, assignment, instance_input); - for (std::size_t z = 0, i = 0; - z < plonk_poseidon::rounds_amount; - z += plonk_poseidon::rounds_per_row, - i++) { + for (std::size_t z = 0, i = 0; z < plonk_poseidon::rounds_amount; + z += plonk_poseidon::rounds_per_row, i++) { assignment.enable_selector(selector_indices[i], start_row_index + i); } generate_copy_constraints(component, bp, assignment, instance_input, start_row_index); - return typename plonk_poseidon::result_type( - component, start_row_index); + return typename plonk_poseidon::result_type(component, start_row_index); } } // namespace components - } // namespace blueprint + } // namespace blueprint } // namespace nil #endif // CRYPTO3_BLUEPRINT_PLONK_POSEIDON_HPP diff --git a/include/nil/blueprint/components/hashes/poseidon/plonk/poseidon_constants.hpp b/include/nil/blueprint/components/hashes/poseidon/plonk/poseidon_constants.hpp index bf120fa65..f4152da26 100644 --- a/include/nil/blueprint/components/hashes/poseidon/plonk/poseidon_constants.hpp +++ b/include/nil/blueprint/components/hashes/poseidon/plonk/poseidon_constants.hpp @@ -27,7 +27,8 @@ #ifndef CRYPTO3_BLUEPRINT_PLONK_DETAIL_POSEIDON_CONSTANTS_HPP #define CRYPTO3_BLUEPRINT_PLONK_DETAIL_POSEIDON_CONSTANTS_HPP -#include +#include + #include #include @@ -37,13 +38,12 @@ namespace nil { namespace blueprint { namespace components { namespace detail { - + template struct poseidon_constants; template - struct poseidon_constants { using FieldType = nil::crypto3::algebra::fields::pallas_base_field; @@ -233,8 +233,7 @@ namespace nil { }; template - struct poseidon_constants { using FieldType = nil::crypto3::algebra::fields::vesta_base_field; @@ -541,7 +540,7 @@ namespace nil { } // namespace detail } // namespace components - } // namespace blueprint + } // namespace blueprint } // namespace nil #endif // CRYPTO3_BLUEPRINT_PLONK_DETAIL_POSEIDON_CONSTANTS_HPP diff --git a/include/nil/blueprint/components/hashes/sha2/r1cs/sha256_aux.hpp b/include/nil/blueprint/components/hashes/sha2/r1cs/sha256_aux.hpp index 39ec1c5f1..13eee1a3f 100644 --- a/include/nil/blueprint/components/hashes/sha2/r1cs/sha256_aux.hpp +++ b/include/nil/blueprint/components/hashes/sha2/r1cs/sha256_aux.hpp @@ -28,318 +28,308 @@ #ifndef CRYPTO3_BLUEPRINT_COMPONENTS_SHA256_AUX_HPP #define CRYPTO3_BLUEPRINT_COMPONENTS_SHA256_AUX_HPP -#include -#include +#include +#include namespace nil { - namespace crypto3 { - namespace blueprint { - namespace components { - - template - class lastbits_component : public component { - public: - blueprint_variable X; - std::size_t X_bits; - blueprint_variable result; - blueprint_linear_combination_vector result_bits; - - blueprint_linear_combination_vector full_bits; - std::shared_ptr> unpack_bits; - std::shared_ptr> pack_result; - - lastbits_component(blueprint &bp, - const blueprint_variable &X, - std::size_t X_bits, - const blueprint_variable &result, - const blueprint_linear_combination_vector &result_bits) : - component(bp), - X(X), X_bits(X_bits), result(result), result_bits(result_bits) { - - full_bits = result_bits; - for (std::size_t i = result_bits.size(); i < X_bits; ++i) { - blueprint_variable full_bits_overflow; - full_bits_overflow.allocate(bp); - full_bits.emplace_back(full_bits_overflow); - } - - unpack_bits.reset(new packing(bp, full_bits, X)); - pack_result.reset(new packing(bp, result_bits, result)); + namespace blueprint { + namespace components { + + template + class lastbits_component : public component { + public: + detail::blueprint_variable X; + std::size_t X_bits; + detail::blueprint_variable result; + detail::blueprint_linear_combination_vector result_bits; + + detail::blueprint_linear_combination_vector full_bits; + std::shared_ptr> unpack_bits; + std::shared_ptr> pack_result; + + lastbits_component(blueprint &bp, + const detail::blueprint_variable &X, + std::size_t X_bits, + const detail::blueprint_variable &result, + const detail::blueprint_linear_combination_vector &result_bits) : + component(bp), X(X), X_bits(X_bits), result(result), result_bits(result_bits) { + + full_bits = result_bits; + for (std::size_t i = result_bits.size(); i < X_bits; ++i) { + detail::blueprint_variable full_bits_overflow; + full_bits_overflow.allocate(bp); + full_bits.emplace_back(full_bits_overflow); } - void generate_gates() { - unpack_bits->generate_gates(true); - pack_result->generate_gates(false); + unpack_bits.reset(new packing(bp, full_bits, X)); + pack_result.reset(new packing(bp, result_bits, result)); + } + + void generate_gates() { + unpack_bits->generate_gates(true); + pack_result->generate_gates(false); + } + + void generate_assignments() { + unpack_bits->generate_assignments_from_packed(); + pack_result->generate_assignments_from_bits(); + } + }; + + template + class XOR3_component : public component { + private: + detail::blueprint_variable tmp; + + public: + detail::blueprint_linear_combination A; + detail::blueprint_linear_combination B; + detail::blueprint_linear_combination C; + bool assume_C_is_zero; + detail::blueprint_linear_combination out; + + XOR3_component(blueprint &bp, + const detail::blueprint_linear_combination &A, + const detail::blueprint_linear_combination &B, + const detail::blueprint_linear_combination &C, + bool assume_C_is_zero, + const detail::blueprint_linear_combination &out) : + component(bp), A(A), B(B), C(C), assume_C_is_zero(assume_C_is_zero), out(out) { + if (!assume_C_is_zero) { + tmp.allocate(bp); } - - void generate_assignments() { - unpack_bits->generate_assignments_from_packed(); - pack_result->generate_assignments_from_bits(); - } - }; - - template - class XOR3_component : public component { - private: - blueprint_variable tmp; - - public: - blueprint_linear_combination A; - blueprint_linear_combination B; - blueprint_linear_combination C; - bool assume_C_is_zero; - blueprint_linear_combination out; - - XOR3_component(blueprint &bp, - const blueprint_linear_combination &A, - const blueprint_linear_combination &B, - const blueprint_linear_combination &C, - bool assume_C_is_zero, - const blueprint_linear_combination &out) : - component(bp), - A(A), B(B), C(C), assume_C_is_zero(assume_C_is_zero), out(out) { - if (!assume_C_is_zero) { - tmp.allocate(bp); - } + } + + void generate_gates() { + /* + tmp = A + B - 2AB i.e. tmp = A xor B + out = tmp + C - 2tmp C i.e. out = tmp xor C + */ + if (assume_C_is_zero) { + this->bp.add_r1cs_constraint( + crypto3::zk::snark::r1cs_constraint(2 * A, B, A + B - out)); + } else { + this->bp.add_r1cs_constraint( + crypto3::zk::snark::r1cs_constraint(2 * A, B, A + B - tmp)); + this->bp.add_r1cs_constraint( + crypto3::zk::snark::r1cs_constraint(2 * tmp, C, tmp + C - out)); } - - void generate_gates() { - /* - tmp = A + B - 2AB i.e. tmp = A xor B - out = tmp + C - 2tmp C i.e. out = tmp xor C - */ - if (assume_C_is_zero) { - this->bp.add_r1cs_constraint(snark::r1cs_constraint(2 * A, B, A + B - out)); - } else { - this->bp.add_r1cs_constraint(snark::r1cs_constraint(2 * A, B, A + B - tmp)); - this->bp.add_r1cs_constraint(snark::r1cs_constraint(2 * tmp, C, tmp + C - out)); - } + } + + void generate_assignments() { + if (assume_C_is_zero) { + this->bp.lc_val(out) = + this->bp.lc_val(A) + this->bp.lc_val(B) - + typename FieldType::value_type(0x02) * this->bp.lc_val(A) * this->bp.lc_val(B); + } else { + this->bp.val(tmp) = + this->bp.lc_val(A) + this->bp.lc_val(B) - + typename FieldType::value_type(0x02) * this->bp.lc_val(A) * this->bp.lc_val(B); + this->bp.lc_val(out) = + this->bp.val(tmp) + this->bp.lc_val(C) - + typename FieldType::value_type(0x02) * this->bp.val(tmp) * this->bp.lc_val(C); } - - void generate_assignments() { - if (assume_C_is_zero) { - this->bp.lc_val(out) = - this->bp.lc_val(A) + this->bp.lc_val(B) - - typename FieldType::value_type(0x02) * this->bp.lc_val(A) * this->bp.lc_val(B); - } else { - this->bp.val(tmp) = - this->bp.lc_val(A) + this->bp.lc_val(B) - - typename FieldType::value_type(0x02) * this->bp.lc_val(A) * this->bp.lc_val(B); - this->bp.lc_val(out) = - this->bp.val(tmp) + this->bp.lc_val(C) - - typename FieldType::value_type(0x02) * this->bp.val(tmp) * this->bp.lc_val(C); - } - } - }; + } + }; #define SHA256_COMPONENT_ROTR(A, i, k) A[((i) + (k)) % 32] - /* Page 10 of http://csrc.nist.gov/publications/fips/fips180-4/fips-180-4.pdf */ - template - class small_sigma_component : public component { - private: - blueprint_variable_vector W; - blueprint_variable result; - - public: - blueprint_variable_vector result_bits; - std::vector>> compute_bits; - std::shared_ptr> pack_result; - - small_sigma_component(blueprint &bp, - const blueprint_variable_vector &W, - const blueprint_variable &result, - std::size_t rot1, - std::size_t rot2, - std::size_t shift) : - component(bp), - W(W), result(result) { - - result_bits.allocate(bp, 32); - compute_bits.resize(32); - for (std::size_t i = 0; i < 32; ++i) { - compute_bits[i].reset(new XOR3_component( - bp, SHA256_COMPONENT_ROTR(W, i, rot1), SHA256_COMPONENT_ROTR(W, i, rot2), - (i + shift < 32 ? W[i + shift] : blueprint_variable(0)), (i + shift >= 32), - result_bits[i])); - } - pack_result.reset(new packing(bp, result_bits, result)); + /* Page 10 of http://csrc.nist.gov/publications/fips/fips180-4/fips-180-4.pdf */ + template + class small_sigma_component : public component { + private: + detail::blueprint_variable_vector W; + detail::blueprint_variable result; + + public: + detail::blueprint_variable_vector result_bits; + std::vector>> compute_bits; + std::shared_ptr> pack_result; + + small_sigma_component(blueprint &bp, + const detail::blueprint_variable_vector &W, + const detail::blueprint_variable &result, + std::size_t rot1, + std::size_t rot2, + std::size_t shift) : component(bp), W(W), result(result) { + + result_bits.allocate(bp, 32); + compute_bits.resize(32); + for (std::size_t i = 0; i < 32; ++i) { + compute_bits[i].reset(new XOR3_component( + bp, SHA256_COMPONENT_ROTR(W, i, rot1), SHA256_COMPONENT_ROTR(W, i, rot2), + (i + shift < 32 ? W[i + shift] : detail::blueprint_variable(0)), + (i + shift >= 32), result_bits[i])); } + pack_result.reset(new packing(bp, result_bits, result)); + } - void generate_gates() { - for (std::size_t i = 0; i < 32; ++i) { - compute_bits[i]->generate_gates(); - } - - pack_result->generate_gates(false); + void generate_gates() { + for (std::size_t i = 0; i < 32; ++i) { + compute_bits[i]->generate_gates(); } - void generate_assignments() { - for (std::size_t i = 0; i < 32; ++i) { - compute_bits[i]->generate_assignments(); - } + pack_result->generate_gates(false); + } - pack_result->generate_assignments_from_bits(); - } - }; - - /* Page 10 of http://csrc.nist.gov/publications/fips/fips180-4/fips-180-4.pdf */ - template - class big_sigma_component : public component { - private: - blueprint_linear_combination_vector W; - blueprint_variable result; - - public: - blueprint_variable_vector result_bits; - std::vector>> compute_bits; - std::shared_ptr> pack_result; - - big_sigma_component(blueprint &bp, - const blueprint_linear_combination_vector &W, - const blueprint_variable &result, - std::size_t rot1, - std::size_t rot2, - std::size_t rot3) : - component(bp), - W(W), result(result) { - - result_bits.allocate(bp, 32); - compute_bits.resize(32); - for (std::size_t i = 0; i < 32; ++i) { - compute_bits[i].reset(new XOR3_component( - bp, SHA256_COMPONENT_ROTR(W, i, rot1), SHA256_COMPONENT_ROTR(W, i, rot2), - SHA256_COMPONENT_ROTR(W, i, rot3), false, result_bits[i])); - } - - pack_result.reset(new packing(bp, result_bits, result)); + void generate_assignments() { + for (std::size_t i = 0; i < 32; ++i) { + compute_bits[i]->generate_assignments(); } - void generate_gates() { - for (std::size_t i = 0; i < 32; ++i) { - compute_bits[i]->generate_gates(); - } - - pack_result->generate_gates(false); + pack_result->generate_assignments_from_bits(); + } + }; + + /* Page 10 of http://csrc.nist.gov/publications/fips/fips180-4/fips-180-4.pdf */ + template + class big_sigma_component : public component { + private: + detail::blueprint_linear_combination_vector W; + detail::blueprint_variable result; + + public: + detail::blueprint_variable_vector result_bits; + std::vector>> compute_bits; + std::shared_ptr> pack_result; + + big_sigma_component(blueprint &bp, + const detail::blueprint_linear_combination_vector &W, + const detail::blueprint_variable &result, + std::size_t rot1, + std::size_t rot2, + std::size_t rot3) : component(bp), W(W), result(result) { + + result_bits.allocate(bp, 32); + compute_bits.resize(32); + for (std::size_t i = 0; i < 32; ++i) { + compute_bits[i].reset(new XOR3_component( + bp, SHA256_COMPONENT_ROTR(W, i, rot1), SHA256_COMPONENT_ROTR(W, i, rot2), + SHA256_COMPONENT_ROTR(W, i, rot3), false, result_bits[i])); } - void generate_assignments() { - for (std::size_t i = 0; i < 32; ++i) { - compute_bits[i]->generate_assignments(); - } + pack_result.reset(new packing(bp, result_bits, result)); + } - pack_result->generate_assignments_from_bits(); - } - }; - - /* Page 10 of http://csrc.nist.gov/publications/fips/fips180-4/fips-180-4.pdf */ - template - class choice_component : public component { - private: - blueprint_variable_vector result_bits; - - public: - blueprint_linear_combination_vector X; - blueprint_linear_combination_vector Y; - blueprint_linear_combination_vector Z; - blueprint_variable result; - std::shared_ptr> pack_result; - - choice_component(blueprint &bp, - const blueprint_linear_combination_vector &X, - const blueprint_linear_combination_vector &Y, - const blueprint_linear_combination_vector &Z, - const blueprint_variable &result) : - component(bp), - X(X), Y(Y), Z(Z), result(result) { - - result_bits.allocate(bp, 32); - pack_result.reset(new packing(bp, result_bits, result)); + void generate_gates() { + for (std::size_t i = 0; i < 32; ++i) { + compute_bits[i]->generate_gates(); } - void generate_gates() { - for (std::size_t i = 0; i < 32; ++i) { - /* - result = x * y + (1-x) * z - result - z = x * (y - z) - */ - this->bp.add_r1cs_constraint( - snark::r1cs_constraint(X[i], Y[i] - Z[i], result_bits[i] - Z[i])); - } - pack_result->generate_gates(false); + pack_result->generate_gates(false); + } + + void generate_assignments() { + for (std::size_t i = 0; i < 32; ++i) { + compute_bits[i]->generate_assignments(); } - void generate_assignments() { - for (std::size_t i = 0; i < 32; ++i) { - this->bp.val(result_bits[i]) = - this->bp.lc_val(X[i]) * this->bp.lc_val(Y[i]) + - (FieldType::value_type::one() - this->bp.lc_val(X[i])) * this->bp.lc_val(Z[i]); - } - pack_result->generate_assignments_from_bits(); + pack_result->generate_assignments_from_bits(); + } + }; + + /* Page 10 of http://csrc.nist.gov/publications/fips/fips180-4/fips-180-4.pdf */ + template + class choice_component : public component { + private: + detail::blueprint_variable_vector result_bits; + + public: + detail::blueprint_linear_combination_vector X; + detail::blueprint_linear_combination_vector Y; + detail::blueprint_linear_combination_vector Z; + detail::blueprint_variable result; + std::shared_ptr> pack_result; + + choice_component(blueprint &bp, + const detail::blueprint_linear_combination_vector &X, + const detail::blueprint_linear_combination_vector &Y, + const detail::blueprint_linear_combination_vector &Z, + const detail::blueprint_variable &result) : + component(bp), X(X), Y(Y), Z(Z), result(result) { + + result_bits.allocate(bp, 32); + pack_result.reset(new packing(bp, result_bits, result)); + } + + void generate_gates() { + for (std::size_t i = 0; i < 32; ++i) { + /* + result = x * y + (1-x) * z + result - z = x * (y - z) + */ + this->bp.add_r1cs_constraint( + crypto3::zk::snark::r1cs_constraint(X[i], Y[i] - Z[i], result_bits[i] - Z[i])); } - }; - - /* Page 10 of http://csrc.nist.gov/publications/fips/fips180-4/fips-180-4.pdf */ - template - class majority_component : public component { - private: - blueprint_variable_vector result_bits; - std::shared_ptr> pack_result; - - public: - blueprint_linear_combination_vector X; - blueprint_linear_combination_vector Y; - blueprint_linear_combination_vector Z; - blueprint_variable result; - - majority_component(blueprint &bp, - const blueprint_linear_combination_vector &X, - const blueprint_linear_combination_vector &Y, - const blueprint_linear_combination_vector &Z, - const blueprint_variable &result) : - component(bp), - X(X), Y(Y), Z(Z), result(result) { - result_bits.allocate(bp, 32); - pack_result.reset(new packing(bp, result_bits, result)); + pack_result->generate_gates(false); + } + + void generate_assignments() { + for (std::size_t i = 0; i < 32; ++i) { + this->bp.val(result_bits[i]) = + this->bp.lc_val(X[i]) * this->bp.lc_val(Y[i]) + + (FieldType::value_type::one() - this->bp.lc_val(X[i])) * this->bp.lc_val(Z[i]); } - - void generate_gates() { - for (std::size_t i = 0; i < 32; ++i) { - /* - 2*result + aux = x + y + z - x, y, z, aux -- bits - aux = x + y + z - 2*result - */ - generate_boolean_r1cs_constraint(this->bp, result_bits[i]); - this->bp.add_r1cs_constraint( - snark::r1cs_constraint(X[i] + Y[i] + Z[i] - 2 * result_bits[i], - 1 - (X[i] + Y[i] + Z[i] - 2 * result_bits[i]), 0)); - } - pack_result->generate_gates(false); + pack_result->generate_assignments_from_bits(); + } + }; + + /* Page 10 of http://csrc.nist.gov/publications/fips/fips180-4/fips-180-4.pdf */ + template + class majority_component : public component { + private: + detail::blueprint_variable_vector result_bits; + std::shared_ptr> pack_result; + + public: + detail::blueprint_linear_combination_vector X; + detail::blueprint_linear_combination_vector Y; + detail::blueprint_linear_combination_vector Z; + detail::blueprint_variable result; + + majority_component(blueprint &bp, + const detail::blueprint_linear_combination_vector &X, + const detail::blueprint_linear_combination_vector &Y, + const detail::blueprint_linear_combination_vector &Z, + const detail::blueprint_variable &result) : + component(bp), X(X), Y(Y), Z(Z), result(result) { + result_bits.allocate(bp, 32); + pack_result.reset(new packing(bp, result_bits, result)); + } + + void generate_gates() { + for (std::size_t i = 0; i < 32; ++i) { + /* + 2*result + aux = x + y + z + x, y, z, aux -- bits + aux = x + y + z - 2*result + */ + generate_boolean_r1cs_constraint(this->bp, result_bits[i]); + this->bp.add_r1cs_constraint(crypto3::zk::snark::r1cs_constraint( + X[i] + Y[i] + Z[i] - 2 * result_bits[i], 1 - (X[i] + Y[i] + Z[i] - 2 * result_bits[i]), 0)); } + pack_result->generate_gates(false); + } - void generate_assignments() { - - // temporary added until fixed-precision modular adaptor is ready: - typedef nil::crypto3::multiprecision::number< - nil::crypto3::multiprecision::backends::cpp_int_backend<>> - non_fixed_precision_integral_type; + void generate_assignments() { - using integral_type = typename FieldType::integral_type; + // temporary added until fixed-precision modular adaptor is ready: + typedef crypto3::multiprecision::number> + non_fixed_precision_integral_type; - for (std::size_t i = 0; i < 32; ++i) { - const non_fixed_precision_integral_type v = non_fixed_precision_integral_type( - (this->bp.lc_val(X[i]) + this->bp.lc_val(Y[i]) + this->bp.lc_val(Z[i])).data); - this->bp.val(result_bits[i]) = typename FieldType::value_type(integral_type(v / 2)); - } + using integral_type = typename FieldType::integral_type; - pack_result->generate_assignments_from_bits(); + for (std::size_t i = 0; i < 32; ++i) { + const non_fixed_precision_integral_type v = non_fixed_precision_integral_type( + (this->bp.lc_val(X[i]) + this->bp.lc_val(Y[i]) + this->bp.lc_val(Z[i])).data); + this->bp.val(result_bits[i]) = typename FieldType::value_type(integral_type(v / 2)); } - }; - } // namespace components - } // namespace blueprint - } // namespace crypto3 + pack_result->generate_assignments_from_bits(); + } + }; + } // namespace components + } // namespace blueprint } // namespace nil #endif // CRYPTO3_BLUEPRINT_COMPONENTS_SHA256_AUX_HPP diff --git a/include/nil/blueprint/components/hashes/sha2/r1cs/sha256_component.hpp b/include/nil/blueprint/components/hashes/sha2/r1cs/sha256_component.hpp index d05d86db4..626aaeacb 100644 --- a/include/nil/blueprint/components/hashes/sha2/r1cs/sha256_component.hpp +++ b/include/nil/blueprint/components/hashes/sha2/r1cs/sha256_component.hpp @@ -28,346 +28,338 @@ #ifndef CRYPTO3_BLUEPRINT_COMPONENTS_SHA256_COMPONENT_HPP #define CRYPTO3_BLUEPRINT_COMPONENTS_SHA256_COMPONENT_HPP -#include +#include #include + #include namespace nil { - namespace crypto3 { - namespace blueprint { - namespace components { - - /** - * Component for the SHA256 compression function. - */ - template - class sha256_compression_function_component : public component { - public: - std::vector> round_a; - std::vector> round_b; - std::vector> round_c; - std::vector> round_d; - std::vector> round_e; - std::vector> round_f; - std::vector> round_g; - std::vector> round_h; - - blueprint_variable_vector packed_W; - std::shared_ptr> message_schedule; - std::vector> round_functions; - - blueprint_variable_vector unreduced_output; - blueprint_variable_vector reduced_output; - std::vector> reduce_output; - - public: - blueprint_linear_combination_vector prev_output; - blueprint_variable_vector new_block; - digest_variable output; - - sha256_compression_function_component( - blueprint &bp, - const blueprint_linear_combination_vector &prev_output, - const blueprint_variable_vector &new_block, - const digest_variable &output) : - component(bp), - prev_output(prev_output), new_block(new_block), output(output) { - - /* message schedule and inputs for it */ - packed_W.allocate(bp, block::detail::shacal2_policy<256>::rounds); - message_schedule.reset( - new sha256_message_schedule_component(bp, new_block, packed_W)); - - /* initalize */ - round_a.push_back(blueprint_linear_combination_vector( - prev_output.rbegin() + 7 * hashes::sha2<256>::word_bits, - prev_output.rbegin() + 8 * hashes::sha2<256>::word_bits)); - round_b.push_back(blueprint_linear_combination_vector( - prev_output.rbegin() + 6 * hashes::sha2<256>::word_bits, - prev_output.rbegin() + 7 * hashes::sha2<256>::word_bits)); - round_c.push_back(blueprint_linear_combination_vector( - prev_output.rbegin() + 5 * hashes::sha2<256>::word_bits, - prev_output.rbegin() + 6 * hashes::sha2<256>::word_bits)); - round_d.push_back(blueprint_linear_combination_vector( - prev_output.rbegin() + 4 * hashes::sha2<256>::word_bits, - prev_output.rbegin() + 5 * hashes::sha2<256>::word_bits)); - round_e.push_back(blueprint_linear_combination_vector( - prev_output.rbegin() + 3 * hashes::sha2<256>::word_bits, - prev_output.rbegin() + 4 * hashes::sha2<256>::word_bits)); - round_f.push_back(blueprint_linear_combination_vector( - prev_output.rbegin() + 2 * hashes::sha2<256>::word_bits, - prev_output.rbegin() + 3 * hashes::sha2<256>::word_bits)); - round_g.push_back(blueprint_linear_combination_vector( - prev_output.rbegin() + 1 * hashes::sha2<256>::word_bits, - prev_output.rbegin() + 2 * hashes::sha2<256>::word_bits)); - round_h.push_back(blueprint_linear_combination_vector( - prev_output.rbegin() + 0 * hashes::sha2<256>::word_bits, - prev_output.rbegin() + 1 * hashes::sha2<256>::word_bits)); - - /* do the rounds */ - for (std::size_t i = 0; i < block::detail::shacal2_policy<256>::rounds; ++i) { - round_h.push_back(round_g[i]); - round_g.push_back(round_f[i]); - round_f.push_back(round_e[i]); - round_d.push_back(round_c[i]); - round_c.push_back(round_b[i]); - round_b.push_back(round_a[i]); - - blueprint_variable_vector new_round_a_variables; - new_round_a_variables.allocate(bp, hashes::sha2<256>::word_bits); - round_a.emplace_back(new_round_a_variables); - - blueprint_variable_vector new_round_e_variables; - new_round_e_variables.allocate(bp, hashes::sha2<256>::word_bits); - round_e.emplace_back(new_round_e_variables); - - round_functions.push_back(sha256_round_function_component( - bp, round_a[i], round_b[i], round_c[i], round_d[i], round_e[i], round_f[i], round_g[i], - round_h[i], packed_W[i], block::detail::shacal2_policy<256>::constants[i], - round_a[i + 1], round_e[i + 1])); - } - - /* finalize */ - unreduced_output.allocate(bp, 8); - reduced_output.allocate(bp, 8); - for (std::size_t i = 0; i < 8; ++i) { - reduce_output.push_back(lastbits_component( - bp, - unreduced_output[i], - hashes::sha2<256>::word_bits + 1, - reduced_output[i], - blueprint_variable_vector( - output.bits.rbegin() + (7 - i) * hashes::sha2<256>::word_bits, - output.bits.rbegin() + (8 - i) * hashes::sha2<256>::word_bits))); - } + namespace blueprint { + namespace components { + + /** + * Component for the SHA256 compression function. + */ + template + class sha256_compression_function_component : public component { + public: + std::vector> round_a; + std::vector> round_b; + std::vector> round_c; + std::vector> round_d; + std::vector> round_e; + std::vector> round_f; + std::vector> round_g; + std::vector> round_h; + + detail::blueprint_variable_vector packed_W; + std::shared_ptr> message_schedule; + std::vector> round_functions; + + detail::blueprint_variable_vector unreduced_output; + detail::blueprint_variable_vector reduced_output; + std::vector> reduce_output; + + public: + detail::blueprint_linear_combination_vector prev_output; + detail::blueprint_variable_vector new_block; + digest_variable output; + + sha256_compression_function_component( + blueprint &bp, + const detail::blueprint_linear_combination_vector &prev_output, + const detail::blueprint_variable_vector &new_block, + const digest_variable &output) : + component(bp), prev_output(prev_output), new_block(new_block), output(output) { + + /* message schedule and inputs for it */ + packed_W.allocate(bp, crypto3::block::detail::shacal2_policy<256>::rounds); + message_schedule.reset(new sha256_message_schedule_component(bp, new_block, packed_W)); + + /* initalize */ + round_a.push_back(detail::blueprint_linear_combination_vector( + prev_output.rbegin() + 7 * crypto3::hashes::sha2<256>::word_bits, + prev_output.rbegin() + 8 * crypto3::hashes::sha2<256>::word_bits)); + round_b.push_back(detail::blueprint_linear_combination_vector( + prev_output.rbegin() + 6 * crypto3::hashes::sha2<256>::word_bits, + prev_output.rbegin() + 7 * crypto3::hashes::sha2<256>::word_bits)); + round_c.push_back(detail::blueprint_linear_combination_vector( + prev_output.rbegin() + 5 * crypto3::hashes::sha2<256>::word_bits, + prev_output.rbegin() + 6 * crypto3::hashes::sha2<256>::word_bits)); + round_d.push_back(detail::blueprint_linear_combination_vector( + prev_output.rbegin() + 4 * crypto3::hashes::sha2<256>::word_bits, + prev_output.rbegin() + 5 * crypto3::hashes::sha2<256>::word_bits)); + round_e.push_back(detail::blueprint_linear_combination_vector( + prev_output.rbegin() + 3 * crypto3::hashes::sha2<256>::word_bits, + prev_output.rbegin() + 4 * crypto3::hashes::sha2<256>::word_bits)); + round_f.push_back(detail::blueprint_linear_combination_vector( + prev_output.rbegin() + 2 * crypto3::hashes::sha2<256>::word_bits, + prev_output.rbegin() + 3 * crypto3::hashes::sha2<256>::word_bits)); + round_g.push_back(detail::blueprint_linear_combination_vector( + prev_output.rbegin() + 1 * crypto3::hashes::sha2<256>::word_bits, + prev_output.rbegin() + 2 * crypto3::hashes::sha2<256>::word_bits)); + round_h.push_back(detail::blueprint_linear_combination_vector( + prev_output.rbegin() + 0 * crypto3::hashes::sha2<256>::word_bits, + prev_output.rbegin() + 1 * crypto3::hashes::sha2<256>::word_bits)); + + /* do the rounds */ + for (std::size_t i = 0; i < crypto3::block::detail::shacal2_policy<256>::rounds; ++i) { + round_h.push_back(round_g[i]); + round_g.push_back(round_f[i]); + round_f.push_back(round_e[i]); + round_d.push_back(round_c[i]); + round_c.push_back(round_b[i]); + round_b.push_back(round_a[i]); + + detail::blueprint_variable_vector new_round_a_variables; + new_round_a_variables.allocate(bp, crypto3::hashes::sha2<256>::word_bits); + round_a.emplace_back(new_round_a_variables); + + detail::blueprint_variable_vector new_round_e_variables; + new_round_e_variables.allocate(bp, crypto3::hashes::sha2<256>::word_bits); + round_e.emplace_back(new_round_e_variables); + + round_functions.push_back(sha256_round_function_component( + bp, round_a[i], round_b[i], round_c[i], round_d[i], round_e[i], round_f[i], round_g[i], + round_h[i], packed_W[i], crypto3::block::detail::shacal2_policy<256>::constants[i], + round_a[i + 1], round_e[i + 1])); } - void generate_gates() { - message_schedule->generate_gates(); - for (std::size_t i = 0; i < block::detail::shacal2_policy<256>::rounds; ++i) { - round_functions[i].generate_gates(); - } - - for (std::size_t i = 0; i < 4; ++i) { - this->bp.add_r1cs_constraint(snark::r1cs_constraint( - 1, - round_functions[3 - i].packed_d + round_functions[63 - i].packed_new_a, - unreduced_output[i])); - - this->bp.add_r1cs_constraint(snark::r1cs_constraint( - 1, - round_functions[3 - i].packed_h + round_functions[63 - i].packed_new_e, - unreduced_output[4 + i])); - } - for (std::size_t i = 0; i < 8; ++i) { - reduce_output[i].generate_gates(); - } + /* finalize */ + unreduced_output.allocate(bp, 8); + reduced_output.allocate(bp, 8); + for (std::size_t i = 0; i < 8; ++i) { + reduce_output.push_back(lastbits_component( + bp, + unreduced_output[i], + crypto3::hashes::sha2<256>::word_bits + 1, + reduced_output[i], + detail::blueprint_variable_vector( + output.bits.rbegin() + (7 - i) * crypto3::hashes::sha2<256>::word_bits, + output.bits.rbegin() + (8 - i) * crypto3::hashes::sha2<256>::word_bits))); + } + } + void generate_gates() { + message_schedule->generate_gates(); + for (std::size_t i = 0; i < crypto3::block::detail::shacal2_policy<256>::rounds; ++i) { + round_functions[i].generate_gates(); } - void generate_assignments() { - message_schedule->generate_assignments(); - - for (std::size_t i = 0; i < block::detail::shacal2_policy<256>::rounds; ++i) { - round_functions[i].generate_assignments(); - } - for (std::size_t i = 0; i < 4; ++i) { - this->bp.val(unreduced_output[i]) = this->bp.val(round_functions[3 - i].packed_d) + - this->bp.val(round_functions[63 - i].packed_new_a); - this->bp.val(unreduced_output[4 + i]) = this->bp.val(round_functions[3 - i].packed_h) + - this->bp.val(round_functions[63 - i].packed_new_e); - } + for (std::size_t i = 0; i < 4; ++i) { + this->bp.add_r1cs_constraint(crypto3::zk::snark::r1cs_constraint( + 1, + round_functions[3 - i].packed_d + round_functions[63 - i].packed_new_a, + unreduced_output[i])); - for (std::size_t i = 0; i < 8; ++i) { - reduce_output[i].generate_assignments(); - } - } - }; - - /** - * Component for the SHA256 compression function, viewed as a 2-to-1 hash - * function, and using the same initialization vector as in SHA256 - * specification. Thus, any collision for - * sha256_two_to_one_hash_component trivially extends to a collision for - * full SHA256 (by appending the same padding). - */ - template - class sha256_two_to_one_hash_component : public component { - public: - typedef std::vector hash_value_type; - typedef digest_variable hash_variable_type; - typedef snark::merkle_authentication_path merkle_authentication_path_type; - - std::shared_ptr> f; - - sha256_two_to_one_hash_component(blueprint &bp, - const digest_variable &left, - const digest_variable &right, - const digest_variable &output) : - component(bp) { - - /* concatenate block = left || right */ - blueprint_variable_vector block; - block.insert(block.end(), left.bits.begin(), left.bits.end()); - block.insert(block.end(), right.bits.begin(), right.bits.end()); - - /* compute the hash itself */ - f.reset(new sha256_compression_function_component( - bp, SHA256_default_IV(bp), block, output)); - } - sha256_two_to_one_hash_component(blueprint &bp, - std::size_t block_length, - const block_variable &input_block, - const digest_variable &output) : - component(bp) { - - assert(block_length == hashes::sha2<256>::block_bits); - assert(input_block.bits.size() == block_length); - f.reset(new sha256_compression_function_component( - bp, SHA256_default_IV(bp), input_block.bits, output)); + this->bp.add_r1cs_constraint(crypto3::zk::snark::r1cs_constraint( + 1, + round_functions[3 - i].packed_h + round_functions[63 - i].packed_new_e, + unreduced_output[4 + i])); } - void generate_gates(bool ensure_output_bitness = true) { // TODO: ignored for now - f->generate_gates(); + for (std::size_t i = 0; i < 8; ++i) { + reduce_output[i].generate_gates(); } + } + void generate_assignments() { + message_schedule->generate_assignments(); - void generate_assignments() { - f->generate_assignments(); + for (std::size_t i = 0; i < crypto3::block::detail::shacal2_policy<256>::rounds; ++i) { + round_functions[i].generate_assignments(); } - static std::size_t get_block_len() { - return hashes::sha2<256>::block_bits; + for (std::size_t i = 0; i < 4; ++i) { + this->bp.val(unreduced_output[i]) = this->bp.val(round_functions[3 - i].packed_d) + + this->bp.val(round_functions[63 - i].packed_new_a); + this->bp.val(unreduced_output[4 + i]) = this->bp.val(round_functions[3 - i].packed_h) + + this->bp.val(round_functions[63 - i].packed_new_e); } - static std::size_t get_digest_len() { - return hashes::sha2<256>::digest_bits; + for (std::size_t i = 0; i < 8; ++i) { + reduce_output[i].generate_assignments(); } - - static std::vector get_hash(const std::vector &input) { - blueprint bp; - - block_variable input_variable(bp, hashes::sha2<256>::block_bits); - digest_variable output_variable(bp, hashes::sha2<256>::digest_bits); - sha256_two_to_one_hash_component f(bp, hashes::sha2<256>::block_bits, input_variable, - output_variable); - - input_variable.generate_assignments(input); - f.generate_assignments(); - - return output_variable.get_digest(); + } + }; + + /** + * Component for the SHA256 compression function, viewed as a 2-to-1 hash + * function, and using the same initialization vector as in SHA256 + * specification. Thus, any collision for + * sha256_two_to_one_hash_component trivially extends to a collision for + * full SHA256 (by appending the same padding). + */ + template + class sha256_two_to_one_hash_component : public component { + public: + typedef std::vector hash_value_type; + typedef digest_variable hash_variable_type; + typedef crypto3::containers::merkle_proof, 2> merkle_authentication_path_type; + + std::shared_ptr> f; + + sha256_two_to_one_hash_component(blueprint &bp, + const digest_variable &left, + const digest_variable &right, + const digest_variable &output) : component(bp) { + + /* concatenate block = left || right */ + detail::blueprint_variable_vector block; + block.insert(block.end(), left.bits.begin(), left.bits.end()); + block.insert(block.end(), right.bits.begin(), right.bits.end()); + + /* compute the hash itself */ + f.reset(new sha256_compression_function_component(bp, SHA256_default_IV(bp), + block, output)); + } + sha256_two_to_one_hash_component(blueprint &bp, + std::size_t block_length, + const block_variable &input_block, + const digest_variable &output) : component(bp) { + + assert(block_length == hashes::sha2<256>::block_bits); + assert(input_block.bits.size() == block_length); + f.reset(new sha256_compression_function_component(bp, SHA256_default_IV(bp), + input_block.bits, output)); + } + + void generate_gates(bool ensure_output_bitness = true) { // TODO: ignored for now + f->generate_gates(); + } + + void generate_assignments() { + f->generate_assignments(); + } + + static std::size_t get_block_len() { + return crypto3::hashes::sha2<256>::block_bits; + } + + static std::size_t get_digest_len() { + return crypto3::hashes::sha2<256>::digest_bits; + } + + static std::vector get_hash(const std::vector &input) { + blueprint bp; + + block_variable input_variable(bp, crypto3::hashes::sha2<256>::block_bits); + digest_variable output_variable(bp, crypto3::hashes::sha2<256>::digest_bits); + sha256_two_to_one_hash_component f(bp, crypto3::hashes::sha2<256>::block_bits, + input_variable, output_variable); + + input_variable.generate_assignments(input); + f.generate_assignments(); + + return output_variable.get_digest(); + } + + static std::size_t expected_constraints(bool ensure_output_bitness = true) { // TODO: ignored for now + return 27280; /* hardcoded for now */ + } + }; + + /** + * Component for arbitary length sha256 hash based on + * Merkle-Damagard padding. (i.e. standard sha256). + */ + template + class sha256_hash_component : public component { + public: + typedef std::vector hash_value_type; + typedef digest_variable hash_variable_type; + typedef crypto3::containers::merkle_proof, 2> merkle_authentication_path_type; + + std::vector>> blocks_components; + std::vector> blocks_bits; + std::vector>> intermediate_outputs; + std::shared_ptr> padding; + + sha256_hash_component(blueprint &bp, + std::size_t input_len, + const block_variable &block_input, + const digest_variable &output) : component(bp) { + + assert(input_len == block_input.block_size); + const int length_bits_size = 64; + + padding.reset(new merkle_damagard_padding(bp, input_len, length_bits_size, + crypto3::hashes::sha2<256>::block_bits)); + detail::blueprint_variable_vector bits = block_input.bits; + bits.insert(bits.end(), padding->bits.begin(), padding->bits.end()); + assert(bits.size() % crypto3::hashes::sha2<256>::block_bits == 0); + std::size_t num_blocks = bits.size() / crypto3::hashes::sha2<256>::block_bits; + + intermediate_outputs.resize(num_blocks - 1); + blocks_components.resize(num_blocks); + blocks_bits.resize(num_blocks); + + const std::size_t chunk = crypto3::hashes::sha2<256>::block_bits; + + for (std::size_t i = 0; i < num_blocks; ++i) { + blocks_bits[i] = detail::blueprint_variable_vector(bits.begin() + i * chunk, + bits.begin() + (i + 1) * chunk); } - static std::size_t - expected_constraints(bool ensure_output_bitness = true) { // TODO: ignored for now - return 27280; /* hardcoded for now */ + for (std::size_t i = 0; i < num_blocks - 1; ++i) { + intermediate_outputs[i].reset( + new digest_variable(bp, crypto3::hashes::sha2<256>::digest_bits)); } - }; - - /** - * Component for arbitary length sha256 hash based on - * Merkle-Damagard padding. (i.e. standard sha256). - */ - template - class sha256_hash_component : public component { - public: - typedef std::vector hash_value_type; - typedef digest_variable hash_variable_type; - typedef snark::merkle_authentication_path merkle_authentication_path_type; - - std::vector>> blocks_components; - std::vector> blocks_bits; - std::vector>> intermediate_outputs; - std::shared_ptr> padding; - - sha256_hash_component(blueprint &bp, - std::size_t input_len, - const block_variable &block_input, - const digest_variable &output) : - component(bp) { - - assert(input_len == block_input.block_size); - const int length_bits_size = 64; - - padding.reset(new merkle_damagard_padding(bp, input_len, length_bits_size, - hashes::sha2<256>::block_bits)); - blueprint_variable_vector bits = block_input.bits; - bits.insert(bits.end(), padding->bits.begin(), padding->bits.end()); - assert(bits.size() % hashes::sha2<256>::block_bits == 0); - std::size_t num_blocks = bits.size() / hashes::sha2<256>::block_bits; - - intermediate_outputs.resize(num_blocks - 1); - blocks_components.resize(num_blocks); - blocks_bits.resize(num_blocks); - - const std::size_t chunk = hashes::sha2<256>::block_bits; - - for (std::size_t i = 0; i < num_blocks; ++i) { - blocks_bits[i] = blueprint_variable_vector(bits.begin() + i * chunk, - bits.begin() + (i + 1) * chunk); - } - - for (std::size_t i = 0; i < num_blocks - 1; ++i) { - intermediate_outputs[i].reset( - new digest_variable(bp, hashes::sha2<256>::digest_bits)); - } - if (num_blocks == 1) { - blocks_components[0].reset(new sha256_compression_function_component( - bp, SHA256_default_IV(bp), blocks_bits[0], output)); - } else { - blocks_components[0].reset(new sha256_compression_function_component( - bp, SHA256_default_IV(bp), blocks_bits[0], *intermediate_outputs[0])); - for (std::size_t i = 1; i < num_blocks - 1; ++i) { - blueprint_linear_combination_vector lcv(intermediate_outputs[i - 1]->bits); - blocks_components[i].reset(new sha256_compression_function_component( - bp, lcv, blocks_bits[i], *intermediate_outputs[i])); - } - blueprint_linear_combination_vector lcv( - intermediate_outputs[num_blocks - 2]->bits); - blocks_components[num_blocks - 1].reset( - new sha256_compression_function_component( - bp, lcv, blocks_bits[num_blocks - 1], output)); + if (num_blocks == 1) { + blocks_components[0].reset(new sha256_compression_function_component( + bp, SHA256_default_IV(bp), blocks_bits[0], output)); + } else { + blocks_components[0].reset(new sha256_compression_function_component( + bp, SHA256_default_IV(bp), blocks_bits[0], *intermediate_outputs[0])); + for (std::size_t i = 1; i < num_blocks - 1; ++i) { + detail::blueprint_linear_combination_vector lcv( + intermediate_outputs[i - 1]->bits); + blocks_components[i].reset(new sha256_compression_function_component( + bp, lcv, blocks_bits[i], *intermediate_outputs[i])); } + detail::blueprint_linear_combination_vector lcv( + intermediate_outputs[num_blocks - 2]->bits); + blocks_components[num_blocks - 1].reset(new sha256_compression_function_component( + bp, lcv, blocks_bits[num_blocks - 1], output)); } + } - void generate_gates(bool ensure_output_bitness = true) { // TODO: ignored for now - padding->generate_gates(); - for (auto f : blocks_components) { - f->generate_gates(); - } + void generate_gates(bool ensure_output_bitness = true) { // TODO: ignored for now + padding->generate_gates(); + for (auto f : blocks_components) { + f->generate_gates(); } + } - void generate_assignments() { - padding->generate_assignments(); - for (auto f : blocks_components) { - f->generate_assignments(); - } + void generate_assignments() { + padding->generate_assignments(); + for (auto f : blocks_components) { + f->generate_assignments(); } + } - static std::size_t get_block_len() { - return hashes::sha2<256>::block_bits; - } + static std::size_t get_block_len() { + return crypto3::hashes::sha2<256>::block_bits; + } - static std::size_t get_digest_len() { - return hashes::sha2<256>::digest_bits; - } + static std::size_t get_digest_len() { + return crypto3::hashes::sha2<256>::digest_bits; + } - static std::vector get_hash(const std::vector &input) { - blueprint bp; + static std::vector get_hash(const std::vector &input) { + blueprint bp; - block_variable input_variable(bp, input.size()); - digest_variable output_variable(bp, hashes::sha2<256>::digest_bits); - sha256_hash_component f(bp, input_variable.block_size, input_variable, - output_variable); + block_variable input_variable(bp, input.size()); + digest_variable output_variable(bp, crypto3::hashes::sha2<256>::digest_bits); + sha256_hash_component f(bp, input_variable.block_size, input_variable, output_variable); - input_variable.generate_assignments(input); - f.generate_assignments(); + input_variable.generate_assignments(input); + f.generate_assignments(); - return output_variable.get_digest(); - } - }; - } // namespace components - } // namespace blueprint - } // namespace crypto3 + return output_variable.get_digest(); + } + }; + } // namespace components + } // namespace blueprint } // namespace nil #endif // CRYPTO3_BLUEPRINT_COMPONENTS_SHA256_COMPONENT_HPP diff --git a/include/nil/blueprint/components/hashes/sha2/r1cs/sha256_construction.hpp b/include/nil/blueprint/components/hashes/sha2/r1cs/sha256_construction.hpp index acc0bbd0c..0341b64ac 100644 --- a/include/nil/blueprint/components/hashes/sha2/r1cs/sha256_construction.hpp +++ b/include/nil/blueprint/components/hashes/sha2/r1cs/sha256_construction.hpp @@ -30,271 +30,266 @@ #include -#include +#include #include -#include -#include +#include + +#include namespace nil { - namespace crypto3 { - namespace blueprint { - namespace components { - - template - class sha256_message_schedule_component : public component { - public: - std::vector> W_bits; - std::vector>> pack_W; - - std::vector> sigma0; - std::vector> sigma1; - std::vector>> compute_sigma0; - std::vector>> compute_sigma1; - std::vector> unreduced_W; - std::vector>> mod_reduce_W; - - public: - blueprint_variable_vector M; - blueprint_variable_vector packed_W; - sha256_message_schedule_component(blueprint &bp, - const blueprint_variable_vector &M, - const blueprint_variable_vector &packed_W) : - component(bp), - M(M), packed_W(packed_W) { - - W_bits.resize(64); - - pack_W.resize(16); - for (std::size_t i = 0; i < 16; ++i) { - W_bits[i] = blueprint_variable_vector( - M.rbegin() + (15 - i) * hashes::sha2<256>::word_bits, - M.rbegin() + (16 - i) * hashes::sha2<256>::word_bits); - - pack_W[i].reset(new packing(bp, W_bits[i], packed_W[i])); - } - - /* NB: some of those will be un-allocated */ - sigma0.resize(64); - sigma1.resize(64); - compute_sigma0.resize(64); - compute_sigma1.resize(64); - unreduced_W.resize(64); - mod_reduce_W.resize(64); - - for (std::size_t i = 16; i < block::detail::shacal2_policy<256>::rounds; ++i) { - /* allocate result variables for sigma0/sigma1 invocations */ - sigma0[i].allocate(bp); - sigma1[i].allocate(bp); - - /* compute sigma0/sigma1 */ - compute_sigma0[i].reset( - new small_sigma_component(bp, W_bits[i - 15], sigma0[i], 7, 18, 3)); - compute_sigma1[i].reset( - new small_sigma_component(bp, W_bits[i - 2], sigma1[i], 17, 19, 10)); - - /* unreduced_W = sigma0(W_{i-15}) + sigma1(W_{i-2}) + W_{i-7} + W_{i-16} before modulo - * 2^32 - */ - unreduced_W[i].allocate(bp); - - /* allocate the bit representation of packed_W[i] */ - W_bits[i].allocate(bp, hashes::sha2<256>::word_bits); - - /* and finally reduce this into packed and bit representations */ - mod_reduce_W[i].reset(new lastbits_component( - bp, unreduced_W[i], hashes::sha2<256>::word_bits + 2, packed_W[i], W_bits[i])); - } + namespace blueprint { + namespace components { + + template + class sha256_message_schedule_component : public component { + public: + std::vector> W_bits; + std::vector>> pack_W; + + std::vector> sigma0; + std::vector> sigma1; + std::vector>> compute_sigma0; + std::vector>> compute_sigma1; + std::vector> unreduced_W; + std::vector>> mod_reduce_W; + + public: + detail::blueprint_variable_vector M; + detail::blueprint_variable_vector packed_W; + sha256_message_schedule_component(blueprint &bp, + const detail::blueprint_variable_vector &M, + const detail::blueprint_variable_vector &packed_W) : + component(bp), M(M), packed_W(packed_W) { + + W_bits.resize(64); + + pack_W.resize(16); + for (std::size_t i = 0; i < 16; ++i) { + W_bits[i] = detail::blueprint_variable_vector( + M.rbegin() + (15 - i) * crypto3::hashes::sha2<256>::word_bits, + M.rbegin() + (16 - i) * crypto3::hashes::sha2<256>::word_bits); + + pack_W[i].reset(new packing(bp, W_bits[i], packed_W[i])); } - void generate_gates() { - for (std::size_t i = 0; i < 16; ++i) { - pack_W[i]->generate_gates( - false); // do not enforce bitness here; caller be aware. - } + /* NB: some of those will be un-allocated */ + sigma0.resize(64); + sigma1.resize(64); + compute_sigma0.resize(64); + compute_sigma1.resize(64); + unreduced_W.resize(64); + mod_reduce_W.resize(64); + + for (std::size_t i = 16; i < crypto3::block::detail::shacal2_policy<256>::rounds; ++i) { + /* allocate result variables for sigma0/sigma1 invocations */ + sigma0[i].allocate(bp); + sigma1[i].allocate(bp); + + /* compute sigma0/sigma1 */ + compute_sigma0[i].reset( + new small_sigma_component(bp, W_bits[i - 15], sigma0[i], 7, 18, 3)); + compute_sigma1[i].reset( + new small_sigma_component(bp, W_bits[i - 2], sigma1[i], 17, 19, 10)); + + /* unreduced_W = sigma0(W_{i-15}) + sigma1(W_{i-2}) + W_{i-7} + W_{i-16} before modulo + * 2^32 + */ + unreduced_W[i].allocate(bp); + + /* allocate the bit representation of packed_W[i] */ + W_bits[i].allocate(bp, crypto3::hashes::sha2<256>::word_bits); + + /* and finally reduce this into packed and bit representations */ + mod_reduce_W[i].reset(new lastbits_component( + bp, unreduced_W[i], crypto3::hashes::sha2<256>::word_bits + 2, packed_W[i], W_bits[i])); + } + } + + void generate_gates() { + for (std::size_t i = 0; i < 16; ++i) { + pack_W[i]->generate_gates(false); // do not enforce bitness here; caller be aware. + } - for (std::size_t i = 16; i < block::detail::shacal2_policy<256>::rounds; ++i) { - compute_sigma0[i]->generate_gates(); - compute_sigma1[i]->generate_gates(); + for (std::size_t i = 16; i < crypto3::block::detail::shacal2_policy<256>::rounds; ++i) { + compute_sigma0[i]->generate_gates(); + compute_sigma1[i]->generate_gates(); - this->bp.add_r1cs_constraint(snark::r1cs_constraint( - 1, sigma0[i] + sigma1[i] + packed_W[i - 16] + packed_W[i - 7], unreduced_W[i])); + this->bp.add_r1cs_constraint(crypto3::zk::snark::r1cs_constraint( + 1, sigma0[i] + sigma1[i] + packed_W[i - 16] + packed_W[i - 7], unreduced_W[i])); - mod_reduce_W[i]->generate_gates(); - } + mod_reduce_W[i]->generate_gates(); } + } - void generate_assignments() { - for (std::size_t i = 0; i < 16; ++i) { - pack_W[i]->generate_assignments_from_bits(); - } + void generate_assignments() { + for (std::size_t i = 0; i < 16; ++i) { + pack_W[i]->generate_assignments_from_bits(); + } - for (std::size_t i = 16; i < block::detail::shacal2_policy<256>::rounds; ++i) { - compute_sigma0[i]->generate_assignments(); - compute_sigma1[i]->generate_assignments(); + for (std::size_t i = 16; i < crypto3::block::detail::shacal2_policy<256>::rounds; ++i) { + compute_sigma0[i]->generate_assignments(); + compute_sigma1[i]->generate_assignments(); - this->bp.val(unreduced_W[i]) = this->bp.val(sigma0[i]) + this->bp.val(sigma1[i]) + - this->bp.val(packed_W[i - 16]) + - this->bp.val(packed_W[i - 7]); + this->bp.val(unreduced_W[i]) = this->bp.val(sigma0[i]) + this->bp.val(sigma1[i]) + + this->bp.val(packed_W[i - 16]) + this->bp.val(packed_W[i - 7]); - mod_reduce_W[i]->generate_assignments(); - } + mod_reduce_W[i]->generate_assignments(); } - }; - - template - class sha256_round_function_component : public component { - public: - blueprint_variable sigma0; - blueprint_variable sigma1; - std::shared_ptr> compute_sigma0; - std::shared_ptr> compute_sigma1; - blueprint_variable choice; - blueprint_variable majority; - std::shared_ptr> compute_choice; - std::shared_ptr> compute_majority; - blueprint_variable packed_d; - std::shared_ptr> pack_d; - blueprint_variable packed_h; - std::shared_ptr> pack_h; - blueprint_variable unreduced_new_a; - blueprint_variable unreduced_new_e; - std::shared_ptr> mod_reduce_new_a; - std::shared_ptr> mod_reduce_new_e; - blueprint_variable packed_new_a; - blueprint_variable packed_new_e; - - public: - blueprint_linear_combination_vector a; - blueprint_linear_combination_vector b; - blueprint_linear_combination_vector c; - blueprint_linear_combination_vector d; - blueprint_linear_combination_vector e; - blueprint_linear_combination_vector f; - blueprint_linear_combination_vector g; - blueprint_linear_combination_vector h; - blueprint_variable W; - long K; - blueprint_linear_combination_vector new_a; - blueprint_linear_combination_vector new_e; - - sha256_round_function_component(blueprint &bp, - const blueprint_linear_combination_vector &a, - const blueprint_linear_combination_vector &b, - const blueprint_linear_combination_vector &c, - const blueprint_linear_combination_vector &d, - const blueprint_linear_combination_vector &e, - const blueprint_linear_combination_vector &f, - const blueprint_linear_combination_vector &g, - const blueprint_linear_combination_vector &h, - const blueprint_variable &W, - const long &K, - const blueprint_linear_combination_vector &new_a, - const blueprint_linear_combination_vector &new_e) : - component(bp), - a(a), b(b), c(c), d(d), e(e), f(f), g(g), h(h), W(W), K(K), new_a(new_a), new_e(new_e) { - - /* compute sigma0 and sigma1 */ - sigma0.allocate(bp); - sigma1.allocate(bp); - compute_sigma0.reset(new big_sigma_component(bp, a, sigma0, 2, 13, 22)); - compute_sigma1.reset(new big_sigma_component(bp, e, sigma1, 6, 11, 25)); - - /* compute choice */ - choice.allocate(bp); - compute_choice.reset(new choice_component(bp, e, f, g, choice)); - - /* compute majority */ - majority.allocate(bp); - compute_majority.reset(new majority_component(bp, a, b, c, majority)); - - /* pack d */ - packed_d.allocate(bp); - pack_d.reset(new packing(bp, d, packed_d)); - - /* pack h */ - packed_h.allocate(bp); - pack_h.reset(new packing(bp, h, packed_h)); - - /* compute the actual results for the round */ - unreduced_new_a.allocate(bp); - unreduced_new_e.allocate(bp); - - packed_new_a.allocate(bp); - packed_new_e.allocate(bp); - - mod_reduce_new_a.reset(new lastbits_component( - bp, unreduced_new_a, hashes::sha2<256>::word_bits + 3, packed_new_a, new_a)); - mod_reduce_new_e.reset(new lastbits_component( - bp, unreduced_new_e, hashes::sha2<256>::word_bits + 3, packed_new_e, new_e)); - } - - void generate_gates() { - compute_sigma0->generate_gates(); - compute_sigma1->generate_gates(); + } + }; + + template + class sha256_round_function_component : public component { + public: + detail::blueprint_variable sigma0; + detail::blueprint_variable sigma1; + std::shared_ptr> compute_sigma0; + std::shared_ptr> compute_sigma1; + detail::blueprint_variable choice; + detail::blueprint_variable majority; + std::shared_ptr> compute_choice; + std::shared_ptr> compute_majority; + detail::blueprint_variable packed_d; + std::shared_ptr> pack_d; + detail::blueprint_variable packed_h; + std::shared_ptr> pack_h; + detail::blueprint_variable unreduced_new_a; + detail::blueprint_variable unreduced_new_e; + std::shared_ptr> mod_reduce_new_a; + std::shared_ptr> mod_reduce_new_e; + detail::blueprint_variable packed_new_a; + detail::blueprint_variable packed_new_e; + + public: + detail::blueprint_linear_combination_vector a; + detail::blueprint_linear_combination_vector b; + detail::blueprint_linear_combination_vector c; + detail::blueprint_linear_combination_vector d; + detail::blueprint_linear_combination_vector e; + detail::blueprint_linear_combination_vector f; + detail::blueprint_linear_combination_vector g; + detail::blueprint_linear_combination_vector h; + detail::blueprint_variable W; + long K; + detail::blueprint_linear_combination_vector new_a; + detail::blueprint_linear_combination_vector new_e; + + sha256_round_function_component(blueprint &bp, + const detail::blueprint_linear_combination_vector &a, + const detail::blueprint_linear_combination_vector &b, + const detail::blueprint_linear_combination_vector &c, + const detail::blueprint_linear_combination_vector &d, + const detail::blueprint_linear_combination_vector &e, + const detail::blueprint_linear_combination_vector &f, + const detail::blueprint_linear_combination_vector &g, + const detail::blueprint_linear_combination_vector &h, + const detail::blueprint_variable &W, + const long &K, + const detail::blueprint_linear_combination_vector &new_a, + const detail::blueprint_linear_combination_vector &new_e) : + component(bp), a(a), b(b), c(c), d(d), e(e), f(f), g(g), h(h), W(W), K(K), new_a(new_a), + new_e(new_e) { + + /* compute sigma0 and sigma1 */ + sigma0.allocate(bp); + sigma1.allocate(bp); + compute_sigma0.reset(new big_sigma_component(bp, a, sigma0, 2, 13, 22)); + compute_sigma1.reset(new big_sigma_component(bp, e, sigma1, 6, 11, 25)); + + /* compute choice */ + choice.allocate(bp); + compute_choice.reset(new choice_component(bp, e, f, g, choice)); + + /* compute majority */ + majority.allocate(bp); + compute_majority.reset(new majority_component(bp, a, b, c, majority)); + + /* pack d */ + packed_d.allocate(bp); + pack_d.reset(new packing(bp, d, packed_d)); + + /* pack h */ + packed_h.allocate(bp); + pack_h.reset(new packing(bp, h, packed_h)); + + /* compute the actual results for the round */ + unreduced_new_a.allocate(bp); + unreduced_new_e.allocate(bp); + + packed_new_a.allocate(bp); + packed_new_e.allocate(bp); + + mod_reduce_new_a.reset(new lastbits_component( + bp, unreduced_new_a, crypto3::hashes::sha2<256>::word_bits + 3, packed_new_a, new_a)); + mod_reduce_new_e.reset(new lastbits_component( + bp, unreduced_new_e, crypto3::hashes::sha2<256>::word_bits + 3, packed_new_e, new_e)); + } - compute_choice->generate_gates(); - compute_majority->generate_gates(); + void generate_gates() { + compute_sigma0->generate_gates(); + compute_sigma1->generate_gates(); - pack_d->generate_gates(false); - pack_h->generate_gates(false); + compute_choice->generate_gates(); + compute_majority->generate_gates(); - this->bp.add_r1cs_constraint(snark::r1cs_constraint( - 1, packed_h + sigma1 + choice + K + W + sigma0 + majority, unreduced_new_a)); + pack_d->generate_gates(false); + pack_h->generate_gates(false); - this->bp.add_r1cs_constraint(snark::r1cs_constraint( - 1, packed_d + packed_h + sigma1 + choice + K + W, unreduced_new_e)); + this->bp.add_r1cs_constraint(crypto3::zk::snark::r1cs_constraint( + 1, packed_h + sigma1 + choice + K + W + sigma0 + majority, unreduced_new_a)); - mod_reduce_new_a->generate_gates(); - mod_reduce_new_e->generate_gates(); - } + this->bp.add_r1cs_constraint(crypto3::zk::snark::r1cs_constraint( + 1, packed_d + packed_h + sigma1 + choice + K + W, unreduced_new_e)); - void generate_assignments() { - compute_sigma0->generate_assignments(); - compute_sigma1->generate_assignments(); + mod_reduce_new_a->generate_gates(); + mod_reduce_new_e->generate_gates(); + } - compute_choice->generate_assignments(); - compute_majority->generate_assignments(); - pack_d->generate_assignments_from_bits(); - pack_h->generate_assignments_from_bits(); + void generate_assignments() { + compute_sigma0->generate_assignments(); + compute_sigma1->generate_assignments(); - this->bp.val(unreduced_new_a) = this->bp.val(packed_h) + this->bp.val(sigma1) + - this->bp.val(choice) + typename FieldType::value_type(K) + - this->bp.val(W) + this->bp.val(sigma0) + this->bp.val(majority); - this->bp.val(unreduced_new_e) = this->bp.val(packed_d) + this->bp.val(packed_h) + - this->bp.val(sigma1) + this->bp.val(choice) + - typename FieldType::value_type(K) + this->bp.val(W); + compute_choice->generate_assignments(); + compute_majority->generate_assignments(); + pack_d->generate_assignments_from_bits(); + pack_h->generate_assignments_from_bits(); - mod_reduce_new_a->generate_assignments(); - mod_reduce_new_e->generate_assignments(); - } - }; + this->bp.val(unreduced_new_a) = this->bp.val(packed_h) + this->bp.val(sigma1) + + this->bp.val(choice) + typename FieldType::value_type(K) + + this->bp.val(W) + this->bp.val(sigma0) + this->bp.val(majority); + this->bp.val(unreduced_new_e) = this->bp.val(packed_d) + this->bp.val(packed_h) + + this->bp.val(sigma1) + this->bp.val(choice) + + typename FieldType::value_type(K) + this->bp.val(W); - template - blueprint_linear_combination_vector SHA256_default_IV(blueprint &bp) { - using namespace hashes::detail; + mod_reduce_new_a->generate_assignments(); + mod_reduce_new_e->generate_assignments(); + } + }; - typename sha2_policy<256>::state_type iv = sha2_policy<256>::iv_generator()(); + template + detail::blueprint_linear_combination_vector SHA256_default_IV(blueprint &bp) { + using namespace crypto3::hashes::detail; - blueprint_linear_combination_vector result; - result.reserve(hashes::sha2<256>::digest_bits); + typename sha2_policy<256>::state_type iv = sha2_policy<256>::iv_generator()(); - for (std::size_t i = 0; i < hashes::sha2<256>::digest_bits; ++i) { - int iv_val = - iv[i / hashes::sha2<256>::word_bits] >> (31 - (i % hashes::sha2<256>::word_bits)) & 1; + detail::blueprint_linear_combination_vector result; + result.reserve(crypto3::hashes::sha2<256>::digest_bits); - blueprint_linear_combination iv_element; - iv_element.assign(bp, iv_val * blueprint_variable(0)); - iv_element.evaluate(bp); + for (std::size_t i = 0; i < crypto3::hashes::sha2<256>::digest_bits; ++i) { + int iv_val = iv[i / crypto3::hashes::sha2<256>::word_bits] >> (31 - (i % crypto3::hashes::sha2<256>::word_bits)) & 1; - result.emplace_back(iv_element); - } + detail::blueprint_linear_combination iv_element; + iv_element.assign(bp, iv_val * detail::blueprint_variable(0)); + iv_element.evaluate(bp); - return result; + result.emplace_back(iv_element); } - } // namespace components - } // namespace blueprint - } // namespace crypto3 + return result; + } + + } // namespace components + } // namespace blueprint } // namespace nil #endif // CRYPTO3_BLUEPRINT_COMPONENTS_SHA256_COMPONENTS_HPP diff --git a/include/nil/blueprint/components/merkle_tree/r1cs/authentication_path.hpp b/include/nil/blueprint/components/merkle_tree/r1cs/authentication_path.hpp index c157a7132..b4b67e372 100644 --- a/include/nil/blueprint/components/merkle_tree/r1cs/authentication_path.hpp +++ b/include/nil/blueprint/components/merkle_tree/r1cs/authentication_path.hpp @@ -29,7 +29,7 @@ #ifndef CRYPTO3_BLUEPRINT_COMPONENTS_MERKLE_AUTHENTICATION_PATH_VARIABLE_HPP #define CRYPTO3_BLUEPRINT_COMPONENTS_MERKLE_AUTHENTICATION_PATH_VARIABLE_HPP -#include +#include #include #include @@ -59,8 +59,9 @@ namespace nil { } } + template void generate_assignments(const std::size_t address, - const snark::merkle_authentication_path &path) { + const crypto3::containers::merkle_proof &path) { assert(path.size() == tree_depth); for (std::size_t i = 0; i < tree_depth; ++i) { @@ -72,8 +73,10 @@ namespace nil { } } - snark::merkle_authentication_path get_authentication_path(const std::size_t address) const { - snark::merkle_authentication_path result; + template + crypto3::containers::merkle_proof + get_authentication_path(const std::size_t address) const { + crypto3::containers::merkle_proof result; for (std::size_t i = 0; i < tree_depth; ++i) { if (address & (1ul << (tree_depth - 1 - i))) { result.emplace_back(left_digests[i].get_digest()); @@ -86,7 +89,7 @@ namespace nil { } }; } // namespace components - } // namespace blueprint + } // namespace blueprint } // namespace nil #endif // CRYPTO3_BLUEPRINT_COMPONENTS_MERKLE_AUTHENTICATION_PATH_VARIABLE_HPP diff --git a/include/nil/blueprint/components/merkle_tree/r1cs/check_update.hpp b/include/nil/blueprint/components/merkle_tree/r1cs/check_update.hpp index 5f2e0e24a..8aad5deed 100644 --- a/include/nil/blueprint/components/merkle_tree/r1cs/check_update.hpp +++ b/include/nil/blueprint/components/merkle_tree/r1cs/check_update.hpp @@ -34,184 +34,179 @@ #ifndef CRYPTO3_BLUEPRINT_COMPONENTS_MERKLE_TREE_CHECK_UPDATE_COMPONENT_HPP #define CRYPTO3_BLUEPRINT_COMPONENTS_MERKLE_TREE_CHECK_UPDATE_COMPONENT_HPP -#include +#include #include #include -#include -#include +#include +#include namespace nil { - namespace crypto3 { - namespace blueprint { - namespace components { - - template, typename FieldType = typename HashComponent::field_type, - std::size_t Arity = 2> - class merkle_proof_update : public component { - using hash_type = typename HashComponent::hash_type; - - static_assert(std::is_same, typename HashComponent::result_type>::value); - // TODO: add support of the trees with arity more than 2 - static_assert(Arity == 2); - - std::vector prev_hashers; - std::vector> prev_hasher_inputs; - std::vector> prev_propagators; - std::vector> prev_internal_output; - - std::vector next_hashers; - std::vector> next_hasher_inputs; - std::vector> next_propagators; - std::vector> next_internal_output; - - std::shared_ptr> computed_next_root; - std::shared_ptr> check_next_root; - - public: - const std::size_t digest_size; - const std::size_t tree_depth; - - blueprint_variable_vector address_bits; - digest_variable prev_leaf_digest; - digest_variable prev_root_digest; - merkle_proof prev_path; - digest_variable next_leaf_digest; - digest_variable next_root_digest; - merkle_proof next_path; - blueprint_linear_combination update_successful; - - /* Note that while it is necessary to generate R1CS constraints - for prev_path, it is not necessary to do so for next_path. See - comment in the implementation of generate_gates() */ - - merkle_proof_update(blueprint &bp, - const std::size_t tree_depth, - const blueprint_variable_vector &address_bits, - const digest_variable &prev_leaf_digest, - const digest_variable &prev_root_digest, - const merkle_proof &prev_path, - const digest_variable &next_leaf_digest, - const digest_variable &next_root_digest, - const merkle_proof &next_path, - const blueprint_linear_combination &update_successful) : - component(bp), - digest_size(hash_type::digest_bits), tree_depth(tree_depth), address_bits(address_bits), - prev_leaf_digest(prev_leaf_digest), prev_root_digest(prev_root_digest), prev_path(prev_path), - next_leaf_digest(next_leaf_digest), next_root_digest(next_root_digest), next_path(next_path), - update_successful(update_successful) { - assert(tree_depth > 0); - assert(tree_depth == address_bits.size()); - - for (std::size_t i = 0; i < tree_depth - 1; ++i) { - prev_internal_output.emplace_back(digest_variable(bp, digest_size)); - next_internal_output.emplace_back(digest_variable(bp, digest_size)); - } + namespace blueprint { + namespace components { + + template, typename FieldType = typename HashComponent::field_type, + std::size_t Arity = 2> + class merkle_proof_update : public component { + using hash_type = typename HashComponent::hash_type; + + static_assert(std::is_same, typename HashComponent::result_type>::value); + // TODO: add support of the trees with arity more than 2 + static_assert(Arity == 2); + + std::vector prev_hashers; + std::vector> prev_hasher_inputs; + std::vector> prev_propagators; + std::vector> prev_internal_output; + + std::vector next_hashers; + std::vector> next_hasher_inputs; + std::vector> next_propagators; + std::vector> next_internal_output; + + std::shared_ptr> computed_next_root; + std::shared_ptr> check_next_root; + + public: + const std::size_t digest_size; + const std::size_t tree_depth; + + detail::blueprint_variable_vector address_bits; + digest_variable prev_leaf_digest; + digest_variable prev_root_digest; + crypto3::containers::merkle_proof prev_path; + digest_variable next_leaf_digest; + digest_variable next_root_digest; + crypto3::containers::merkle_proof next_path; + detail::blueprint_linear_combination update_successful; + + /* Note that while it is necessary to generate R1CS constraints + for prev_path, it is not necessary to do so for next_path. See + comment in the implementation of generate_gates() */ + + merkle_proof_update(blueprint &bp, + const std::size_t tree_depth, + const detail::blueprint_variable_vector &address_bits, + const digest_variable &prev_leaf_digest, + const digest_variable &prev_root_digest, + const merkle_proof &prev_path, + const digest_variable &next_leaf_digest, + const digest_variable &next_root_digest, + const merkle_proof &next_path, + const detail::blueprint_linear_combination &update_successful) : + component(bp), digest_size(hash_type::digest_bits), tree_depth(tree_depth), + address_bits(address_bits), prev_leaf_digest(prev_leaf_digest), prev_root_digest(prev_root_digest), + prev_path(prev_path), next_leaf_digest(next_leaf_digest), next_root_digest(next_root_digest), + next_path(next_path), update_successful(update_successful) { + assert(tree_depth > 0); + assert(tree_depth == address_bits.size()); + + for (std::size_t i = 0; i < tree_depth - 1; ++i) { + prev_internal_output.emplace_back(digest_variable(bp, digest_size)); + next_internal_output.emplace_back(digest_variable(bp, digest_size)); + } - computed_next_root.reset(new digest_variable(bp, digest_size)); + computed_next_root.reset(new digest_variable(bp, digest_size)); - for (std::size_t i = 0; i < tree_depth; ++i) { - // TODO: generalize for Arity > 2 - block_variable prev_inp(bp, prev_path.path[i][0], prev_path.path[i][1]); - prev_hasher_inputs.emplace_back(prev_inp); - prev_hashers.emplace_back( - HashComponent(bp, prev_inp, (i == 0 ? prev_root_digest : prev_internal_output[i - 1]))); + for (std::size_t i = 0; i < tree_depth; ++i) { + // TODO: generalize for Arity > 2 + block_variable prev_inp(bp, prev_path.path[i][0], prev_path.path[i][1]); + prev_hasher_inputs.emplace_back(prev_inp); + prev_hashers.emplace_back( + HashComponent(bp, prev_inp, (i == 0 ? prev_root_digest : prev_internal_output[i - 1]))); - // TODO: generalize for Arity > 2 - block_variable next_inp(bp, next_path.path[i][0], next_path.path[i][1]); - next_hasher_inputs.emplace_back(next_inp); - next_hashers.emplace_back(HashComponent( - bp, next_inp, (i == 0 ? *computed_next_root : next_internal_output[i - 1]))); - } + // TODO: generalize for Arity > 2 + block_variable next_inp(bp, next_path.path[i][0], next_path.path[i][1]); + next_hasher_inputs.emplace_back(next_inp); + next_hashers.emplace_back( + HashComponent(bp, next_inp, (i == 0 ? *computed_next_root : next_internal_output[i - 1]))); + } - for (std::size_t i = 0; i < tree_depth; ++i) { - // TODO: generalize for Arity > 2 - prev_propagators.emplace_back(digest_selector_component( - bp, digest_size, i < tree_depth - 1 ? prev_internal_output[i] : prev_leaf_digest, - address_bits[tree_depth - 1 - i], prev_path.path[i][0], prev_path.path[i][1])); - // TODO: generalize for Arity > 2 - next_propagators.emplace_back(digest_selector_component( - bp, digest_size, i < tree_depth - 1 ? next_internal_output[i] : next_leaf_digest, - address_bits[tree_depth - 1 - i], next_path.path[i][0], next_path.path[i][1])); - } + for (std::size_t i = 0; i < tree_depth; ++i) { + // TODO: generalize for Arity > 2 + prev_propagators.emplace_back(digest_selector_component( + bp, digest_size, i < tree_depth - 1 ? prev_internal_output[i] : prev_leaf_digest, + address_bits[tree_depth - 1 - i], prev_path.path[i][0], prev_path.path[i][1])); + // TODO: generalize for Arity > 2 + next_propagators.emplace_back(digest_selector_component( + bp, digest_size, i < tree_depth - 1 ? next_internal_output[i] : next_leaf_digest, + address_bits[tree_depth - 1 - i], next_path.path[i][0], next_path.path[i][1])); + } - check_next_root.reset(new bit_vector_copy_component( - bp, computed_next_root->bits, next_root_digest.bits, update_successful, - FieldType::value_bits - 1)); + check_next_root.reset( + new bit_vector_copy_component(bp, computed_next_root->bits, next_root_digest.bits, + update_successful, FieldType::value_bits - 1)); + } + + void generate_gates() { + /* ensure correct hash computations */ + for (std::size_t i = 0; i < tree_depth; ++i) { + prev_hashers[i].generate_gates( + false); // we check root outside and prev_left/prev_right above + next_hashers[i].generate_gates(true); // however we must check right side hashes } - void generate_gates() { - /* ensure correct hash computations */ - for (std::size_t i = 0; i < tree_depth; ++i) { - prev_hashers[i].generate_gates( - false); // we check root outside and prev_left/prev_right above - next_hashers[i].generate_gates( - true); // however we must check right side hashes - } + /* ensure consistency of internal_left/internal_right with internal_output */ + for (std::size_t i = 0; i < tree_depth; ++i) { + prev_propagators[i].generate_gates(); + next_propagators[i].generate_gates(); + } - /* ensure consistency of internal_left/internal_right with internal_output */ - for (std::size_t i = 0; i < tree_depth; ++i) { - prev_propagators[i].generate_gates(); - next_propagators[i].generate_gates(); + /* ensure that prev auxiliary input and next auxiliary input match */ + for (std::size_t i = 0; i < tree_depth; ++i) { + for (std::size_t j = 0; j < digest_size; ++j) { + /* + addr * (prev_left - next_left) + (1 - addr) * (prev_right - next_right) = 0 + addr * (prev_left - next_left - prev_right + next_right) = next_right - prev_right + */ + this->bp.add_r1cs_constraint(crypto3::zk::snark::r1cs_constraint( + address_bits[tree_depth - 1 - i], + prev_path.left_digests[i].bits[j] - next_path.left_digests[i].bits[j] - + prev_path.right_digests[i].bits[j] + next_path.right_digests[i].bits[j], + next_path.right_digests[i].bits[j] - prev_path.right_digests[i].bits[j])); } + } - /* ensure that prev auxiliary input and next auxiliary input match */ - for (std::size_t i = 0; i < tree_depth; ++i) { - for (std::size_t j = 0; j < digest_size; ++j) { - /* - addr * (prev_left - next_left) + (1 - addr) * (prev_right - next_right) = 0 - addr * (prev_left - next_left - prev_right + next_right) = next_right - prev_right - */ - this->bp.add_r1cs_constraint(snark::r1cs_constraint( - address_bits[tree_depth - 1 - i], - prev_path.left_digests[i].bits[j] - next_path.left_digests[i].bits[j] - - prev_path.right_digests[i].bits[j] + next_path.right_digests[i].bits[j], - next_path.right_digests[i].bits[j] - prev_path.right_digests[i].bits[j])); - } + /* Note that while it is necessary to generate R1CS constraints + for prev_path, it is not necessary to do so for next_path. + + This holds, because { next_path.left_inputs[i], + next_path.right_inputs[i] } is a pair { hash_output, + auxiliary_input }. The bitness for hash_output is enforced + above by next_hashers[i].generate_gates. + + Because auxiliary input is the same for prev_path and next_path + (enforced above), we have that auxiliary_input part is also + constrained to be boolean, because prev_path is *all* + constrained to be all boolean. */ + + check_next_root->generate_gates(false, false); + } + + void generate_assignments() { + /* do the hash computations bottom-up */ + for (int i = tree_depth - 1; i >= 0; --i) { + /* ensure consistency of prev_path and next_path */ + if (this->bp.val(address_bits[tree_depth - 1 - i]) == FieldType::value_type::zero()) { + next_path.left_digests[i].generate_assignments(prev_path.left_digests[i].get_digest()); + } else { + next_path.right_digests[i].generate_assignments(prev_path.right_digests[i].get_digest()); } - /* Note that while it is necessary to generate R1CS constraints - for prev_path, it is not necessary to do so for next_path. - - This holds, because { next_path.left_inputs[i], - next_path.right_inputs[i] } is a pair { hash_output, - auxiliary_input }. The bitness for hash_output is enforced - above by next_hashers[i].generate_gates. + /* propagate previous input */ + prev_propagators[i].generate_assignments(); + next_propagators[i].generate_assignments(); - Because auxiliary input is the same for prev_path and next_path - (enforced above), we have that auxiliary_input part is also - constrained to be boolean, because prev_path is *all* - constrained to be all boolean. */ - - check_next_root->generate_gates(false, false); + /* compute hash */ + prev_hashers[i].generate_assignments(); + next_hashers[i].generate_assignments(); } - void generate_assignments() { - /* do the hash computations bottom-up */ - for (int i = tree_depth - 1; i >= 0; --i) { - /* ensure consistency of prev_path and next_path */ - if (this->bp.val(address_bits[tree_depth - 1 - i]) == FieldType::value_type::zero()) { - next_path.left_digests[i].generate_assignments(prev_path.left_digests[i].get_digest()); - } else { - next_path.right_digests[i].generate_assignments( - prev_path.right_digests[i].get_digest()); - } - - /* propagate previous input */ - prev_propagators[i].generate_assignments(); - next_propagators[i].generate_assignments(); - - /* compute hash */ - prev_hashers[i].generate_assignments(); - next_hashers[i].generate_assignments(); - } - - check_next_root->generate_assignments(); - } - }; + check_next_root->generate_assignments(); + } + }; - } // namespace components - } // namespace blueprint - } // namespace crypto3 + } // namespace components + } // namespace blueprint } // namespace nil #endif // CRYPTO3_BLUEPRINT_COMPONENTS_MERKLE_TREE_CHECK_UPDATE_COMPONENT_HPP diff --git a/include/nil/blueprint/components/merkle_tree/r1cs/prove.hpp b/include/nil/blueprint/components/merkle_tree/r1cs/prove.hpp index 26df8676b..626dba904 100644 --- a/include/nil/blueprint/components/merkle_tree/r1cs/prove.hpp +++ b/include/nil/blueprint/components/merkle_tree/r1cs/prove.hpp @@ -39,7 +39,7 @@ namespace nil { namespace blueprint { namespace components { - template, + template, typename FieldType = typename HashComponent::field_type, std::size_t Arity = 2> struct merkle_proof : public component { using merkle_tree_container = @@ -116,7 +116,7 @@ namespace nil { } }; } // namespace components - } // namespace blueprint + } // namespace blueprint } // namespace nil #endif // CRYPTO3_BLUEPRINT_COMPONENTS_MERKLE_AUTHENTICATION_PATH_VARIABLE_HPP diff --git a/include/nil/blueprint/components/merkle_tree/r1cs/validate.hpp b/include/nil/blueprint/components/merkle_tree/r1cs/validate.hpp index 80c26064c..8766e8a1c 100644 --- a/include/nil/blueprint/components/merkle_tree/r1cs/validate.hpp +++ b/include/nil/blueprint/components/merkle_tree/r1cs/validate.hpp @@ -36,13 +36,13 @@ #include #include #include -#include +#include namespace nil { namespace blueprint { namespace components { - template, typename Field = typename HashComponent::field_type, - std::size_t Arity = 2> + template, + typename Field = typename HashComponent::field_type, std::size_t Arity = 2> struct merkle_proof_validate : public component { static constexpr std::size_t arity = Arity; @@ -52,8 +52,7 @@ namespace nil { // TODO: add support of the trees with arity more than 2 static_assert(arity == 2); - static_assert( - std::is_same, typename HashComponent::result_type>::value); + static_assert(std::is_same, typename HashComponent::result_type>::value); private: std::vector hashers; @@ -80,9 +79,8 @@ namespace nil { const digest_variable &root, const merkle_proof_component &path, const detail::blueprint_linear_combination &read_successful) : - component(bp), - digest_size(HashComponent::digest_bits), tree_depth(tree_depth), address_bits(address_bits), - leaf(leaf), root(root), path(path), read_successful(read_successful) { + component(bp), digest_size(HashComponent::digest_bits), tree_depth(tree_depth), + address_bits(address_bits), leaf(leaf), root(root), path(path), read_successful(read_successful) { /* The tricky part here is ordering. For Merkle tree authentication paths, path[0] corresponds to one layer below @@ -155,7 +153,7 @@ namespace nil { } }; } // namespace components - } // namespace blueprint + } // namespace blueprint } // namespace nil #endif // CRYPTO3_BLUEPRINT_COMPONENTS_MERKLE_TREE_CHECK_READ_COMPONENT_HPP diff --git a/include/nil/blueprint/components/routing/r1cs/as_waksman.hpp b/include/nil/blueprint/components/routing/r1cs/as_waksman.hpp index 760f2052e..f636beac0 100644 --- a/include/nil/blueprint/components/routing/r1cs/as_waksman.hpp +++ b/include/nil/blueprint/components/routing/r1cs/as_waksman.hpp @@ -34,7 +34,7 @@ #include #include -#include +#include #include namespace nil { diff --git a/include/nil/blueprint/components/routing/r1cs/benes.hpp b/include/nil/blueprint/components/routing/r1cs/benes.hpp index 0d40caa9d..67bc0a3c0 100644 --- a/include/nil/blueprint/components/routing/r1cs/benes.hpp +++ b/include/nil/blueprint/components/routing/r1cs/benes.hpp @@ -33,7 +33,7 @@ #include -#include +#include #include namespace nil { diff --git a/include/nil/blueprint/components/systems/snark/plonk/kimchi/base_details/batch_dlog_accumulator_check_base.hpp b/include/nil/blueprint/components/systems/snark/plonk/kimchi/base_details/batch_dlog_accumulator_check_base.hpp index a3c9c56e7..fc6da61f9 100644 --- a/include/nil/blueprint/components/systems/snark/plonk/kimchi/base_details/batch_dlog_accumulator_check_base.hpp +++ b/include/nil/blueprint/components/systems/snark/plonk/kimchi/base_details/batch_dlog_accumulator_check_base.hpp @@ -26,17 +26,17 @@ #ifndef CRYPTO3_ZK_BLUEPRINT_PLONK_PICKLES_BASE_DETAILS_BATCH_DGLOG_ACCUMULATOR_CHECK_BASE_HPP #define CRYPTO3_ZK_BLUEPRINT_PLONK_PICKLES_BASE_DETAILS_BATCH_DGLOG_ACCUMULATOR_CHECK_BASE_HPP -#include +#include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include namespace nil { namespace crypto3 { diff --git a/include/nil/blueprint/components/systems/snark/plonk/kimchi/batch_verify_base_field.hpp b/include/nil/blueprint/components/systems/snark/plonk/kimchi/batch_verify_base_field.hpp index 14984f482..6a1d47cda 100644 --- a/include/nil/blueprint/components/systems/snark/plonk/kimchi/batch_verify_base_field.hpp +++ b/include/nil/blueprint/components/systems/snark/plonk/kimchi/batch_verify_base_field.hpp @@ -35,7 +35,7 @@ #include #include #include -#include +#include #include #include @@ -48,14 +48,15 @@ namespace nil { // Input: list of batch evaluation proofs // https://github.com/o1-labs/proof-systems/blob/1f8532ec1b8d43748a372632bd854be36b371afe/kimchi/src/verifier.rs#L881-L888 // Output: - - template class batch_verify_base_field; template class batch_verify_base_field, - CurveType, - KimchiParamsType, - KimchiCommitmentParamsType, - BatchSize, - W0, - W1, - W2, - W3, - W4, - W5, - W6, - W7, - W8, - W9, - W10, - W11, - W12, - W13, - W14 > { - - typedef crypto3::zk::snark::plonk_constraint_system ArithmetizationType; - + CurveType, + KimchiParamsType, + KimchiCommitmentParamsType, + BatchSize, + W0, + W1, + W2, + W3, + W4, + W5, + W6, + W7, + W8, + W9, + W10, + W11, + W12, + W13, + W14> { + + typedef crypto3::zk::snark::plonk_constraint_system ArithmetizationType; using var = crypto3::zk::snark::plonk_variable; - using sub_component = subtraction; + using sub_component = + subtraction>; using kimchi_constants = kimchi_inner_constants; @@ -109,38 +109,65 @@ namespace nil { constexpr static const std::size_t final_msm_size = kimchi_constants::final_msm_size(BatchSize); - using msm_component = element_g1_multi_scalar_mul< ArithmetizationType, CurveType, final_msm_size, - W0, W1, W2, W3, W4, W5, W6, W7, W8, W9, W10, W11, W12, W13, W14>; - - using to_group_component = to_group; - - using var_ec_point = typename var_ec_point; - - using opening_proof_type = typename + using msm_component = element_g1_multi_scalar_mul; + + using to_group_component = + to_group; + + using var_ec_point = var_ec_point; + + using opening_proof_type = kimchi_opening_proof_base; - using batch_proof_type = typename - batch_evaluation_proof_base; - - using verifier_index_type = kimchi_verifier_index_base; - - using proof_binding = typename binding; - - using transcript_type = kimchi_transcript_fq; + using batch_proof_type = batch_evaluation_proof_base; + + using verifier_index_type = kimchi_verifier_index_base; + + using proof_binding = binding; + + using transcript_type = kimchi_transcript_fq; constexpr static const std::size_t selector_seed = 0xff91; public: - constexpr static const std::size_t rows_amount = transcript_type::absorb_fr_rows - + transcript_type::challenge_rows - + 1 + msm_component::rows_amount; + constexpr static const std::size_t rows_amount = + transcript_type::absorb_fr_rows + transcript_type::challenge_rows + 1 + msm_component::rows_amount; constexpr static const std::size_t gates_amount = 0; @@ -156,7 +183,7 @@ namespace nil { } }; - static result_type generate_assignments(blueprint_assignment_table &assignment, + static result_type generate_assignments(assignment &assignment, const params_type ¶ms, std::size_t start_row_index) { std::size_t row = start_row_index; @@ -169,7 +196,7 @@ namespace nil { bases[bases_idx++] = params.verifier_index.H; - for(std::size_t i = 0; i < KimchiCommitmentParamsType::srs_len; i++) { + for (std::size_t i = 0; i < KimchiCommitmentParamsType::srs_len; i++) { bases[bases_idx++] = params.verifier_index.G[i]; } for (std::size_t i = 0; i < padding_size; i++) { @@ -183,29 +210,30 @@ namespace nil { var t = transcript.challenge_fq_assignment(assignment, row); row += transcript_type::challenge_rows; - //var_ec_point U = to_group_component:: + // var_ec_point U = to_group_component:: - //U = transcript.squeeze.to_group() - typename CurveType::template g1_type::value_type U_value = - algebra::random_element>(); + // U = transcript.squeeze.to_group() + typename CurveType::template g1_type::value_type + U_value = crypto3::algebra::random_element< + typename CurveType::template g1_type>(); assignment.witness(W0)[row] = U_value.X; assignment.witness(W1)[row] = U_value.Y; var_ec_point U = {var(0, row), var(1, row)}; row++; - //params.proofs[i].transcript.absorb_assignment(assignment, params.proofs[i].o.delta.x, row); - //params.proofs[i].transcript.absorb_assignment(assignment, params.proofs[i].o.delta.y, row); + // params.proofs[i].transcript.absorb_assignment(assignment, params.proofs[i].o.delta.x, row); + // params.proofs[i].transcript.absorb_assignment(assignment, params.proofs[i].o.delta.y, row); bases[bases_idx++] = params.proofs[i].opening_proof.G; bases[bases_idx++] = U; - for (std::size_t j = 0 ; j < params.proofs[i].opening_proof.L.size(); j++) { + for (std::size_t j = 0; j < params.proofs[i].opening_proof.L.size(); j++) { bases[bases_idx++] = params.proofs[i].opening_proof.L[j]; bases[bases_idx++] = params.proofs[i].opening_proof.R[j]; } std::size_t unshifted_size = 0; - for (std::size_t j = 0 ; j < params.proofs[i].comm.size(); j++) { + for (std::size_t j = 0; j < params.proofs[i].comm.size(); j++) { unshifted_size = params.proofs[i].comm[j].parts.size(); - for (std::size_t k =0; k< unshifted_size; k++){ + for (std::size_t k = 0; k < unshifted_size; k++) { bases[bases_idx++] = params.proofs[i].comm[j].parts[k]; } } @@ -223,12 +251,11 @@ namespace nil { } static result_type generate_circuit(blueprint &bp, - blueprint_public_assignment_table &assignment, - const params_type ¶ms, - const std::size_t start_row_index){ + assignment &assignment, + const params_type ¶ms, + const std::size_t start_row_index) { - generate_assignments_constant(bp, assignment, - params, start_row_index); + generate_assignments_constant(bp, assignment, params, start_row_index); std::size_t row = start_row_index; var two_pow_255(0, row, false, var::column_type::constant); @@ -240,7 +267,7 @@ namespace nil { std::size_t bases_idx = 0; bases[bases_idx++] = params.verifier_index.H; - for(std::size_t i = 0; i < KimchiCommitmentParamsType::srs_len; i ++) { + for (std::size_t i = 0; i < KimchiCommitmentParamsType::srs_len; i++) { bases[bases_idx++] = params.verifier_index.G[i]; } for (std::size_t i = 0; i < padding_size; i++) { @@ -253,24 +280,24 @@ namespace nil { row += transcript_type::absorb_fr_rows; var t = transcript.challenge_fq_circuit(bp, assignment, row); row += transcript_type::challenge_rows; - //U = transcript.squeeze.to_group() + // U = transcript.squeeze.to_group() var_ec_point U = {var(0, row), var(1, row)}; row++; - //params.proofs[i].transcript.absorb_assignment(assignment, params.proofs[i].o.delta.x, row); - //params.proofs[i].transcript.absorb_assignment(assignment, params.proofs[i].o.delta.y, row); + // params.proofs[i].transcript.absorb_assignment(assignment, params.proofs[i].o.delta.x, row); + // params.proofs[i].transcript.absorb_assignment(assignment, params.proofs[i].o.delta.y, row); bases[bases_idx++] = params.proofs[i].opening_proof.G; bases[bases_idx++] = U; - for (std::size_t j = 0 ; j < params.proofs[i].opening_proof.L.size(); j++) { + for (std::size_t j = 0; j < params.proofs[i].opening_proof.L.size(); j++) { bases[bases_idx++] = params.proofs[i].opening_proof.L[j]; bases[bases_idx++] = params.proofs[i].opening_proof.R[j]; } std::size_t unshifted_size = 0; - for (std::size_t j = 0 ; j < params.proofs[i].comm.size(); j++) { + for (std::size_t j = 0; j < params.proofs[i].comm.size(); j++) { unshifted_size = params.proofs[i].comm[j].parts.size(); - for (std::size_t k =0; k < unshifted_size; k++){ + for (std::size_t k = 0; k < unshifted_size; k++) { bases[bases_idx++] = params.proofs[i].comm[j].parts[k]; } } @@ -289,38 +316,32 @@ namespace nil { } private: - - static void generate_gates( - blueprint &bp, - blueprint_public_assignment_table &public_assignment, - const params_type ¶ms, - const std::size_t first_selector_index) { - + static void generate_gates(blueprint &bp, + assignment &public_assignment, + const params_type ¶ms, + const std::size_t first_selector_index) { } static void generate_copy_constraints(blueprint &bp, - blueprint_public_assignment_table &assignment, - const params_type ¶ms, - const std::size_t start_row_index) { + assignment &assignment, + const params_type ¶ms, + const std::size_t start_row_index) { std::size_t row = start_row_index; - } - static void - generate_assignments_constant(blueprint &bp, - blueprint_public_assignment_table &assignment, - const params_type ¶ms, - std::size_t start_row_index) { - std::size_t row = start_row_index; - typename BlueprintFieldType::integral_type tmp = 1; - assignment.constant(0)[row] = (tmp << 255); - row++; - assignment.constant(0)[row] = 0; + static void generate_assignments_constant(blueprint &bp, + assignment &assignment, + const params_type ¶ms, + std::size_t start_row_index) { + std::size_t row = start_row_index; + typename BlueprintFieldType::integral_type tmp = 1; + assignment.constant(0)[row] = (tmp << 255); + row++; + assignment.constant(0)[row] = 0; } }; - } // namespace components - } // namespace blueprint + } // namespace blueprint } // namespace nil #endif // CRYPTO3_BLUEPRINT_COMPONENTS_VARIABLE_BASE_MULTIPLICATION_EDWARD25519_HPP \ No newline at end of file diff --git a/include/nil/blueprint/components/systems/snark/plonk/kimchi/batch_verify_scalar_field.hpp b/include/nil/blueprint/components/systems/snark/plonk/kimchi/batch_verify_scalar_field.hpp index 6f70e9e36..0630c64fc 100644 --- a/include/nil/blueprint/components/systems/snark/plonk/kimchi/batch_verify_scalar_field.hpp +++ b/include/nil/blueprint/components/systems/snark/plonk/kimchi/batch_verify_scalar_field.hpp @@ -30,9 +30,11 @@ #include #include -#include +#include -#include +#include +#include +#include #include #include #include @@ -54,83 +56,42 @@ namespace nil { // Input: list of batch evaluation proofs // https://github.com/o1-labs/proof-systems/blob/1f8532ec1b8d43748a372632bd854be36b371afe/kimchi/src/verifier.rs#L881-L888 // Output: list of scalars for MSM in batch verify base - template + template class batch_verify_scalar_field; - template - class batch_verify_scalar_field, - CurveType, - KimchiParamsType, - KimchiCommitmentParamsType, - BatchSize, - W0, - W1, - W2, - W3, - W4, - W5, - W6, - W7, - W8, - W9, - W10, - W11, - W12, - W13, - W14 > { - - typedef crypto3::zk::snark::plonk_constraint_system ArithmetizationType; + template + class batch_verify_scalar_field, CurveType, + KimchiParamsType, KimchiCommitmentParamsType, BatchSize, W0, W1, W2, W3, W4, + W5, W6, W7, W8, W9, W10, W11, W12, W13, W14> { + + typedef crypto3::zk::snark::plonk_constraint_system ArithmetizationType; using var = crypto3::zk::snark::plonk_variable; - using mul_component = multiplication; - using sub_component = subtraction; - using add_component = addition; - using mul_by_const_component = mul_by_constant; + using mul_component = multiplication>; + using sub_component = + subtraction>; + using add_component = + addition>; + using mul_by_const_component = mul_by_constant; - using random_component = random; + using random_component = random; - using endo_scalar_component = - endo_scalar; + using endo_scalar_component = endo_scalar; - using b_poly_component = b_poly; - using b_poly_coeff_component = b_poly_coefficients; + using b_poly_component = b_poly; + using b_poly_coeff_component = + b_poly_coefficients; using kimchi_constants = kimchi_inner_constants; @@ -139,12 +100,11 @@ namespace nil { } using prepare_scalars_component = - prepare_scalars; + prepare_scalars; - using batch_proof = batch_evaluation_proof_scalar; + using batch_proof = batch_evaluation_proof_scalar; constexpr static const std::size_t selector_seed = 0x0f28; @@ -206,8 +166,8 @@ namespace nil { for (std::size_t i = 0; i < kimchi_constants::evaluations_in_batch_size; i++) { for (std::size_t j = 0; - j < KimchiParamsType::commitment_params_type::shifted_commitment_split + 1; - j++) { + j < KimchiParamsType::commitment_params_type::shifted_commitment_split + 1; + j++) { row += mul_component::rows_amount; row += mul_component::rows_amount; @@ -243,9 +203,9 @@ namespace nil { }; static result_type generate_circuit(blueprint &bp, - blueprint_public_assignment_table &assignment, - const params_type ¶ms, - const std::size_t start_row_index){ + assignment &assignment, + const params_type ¶ms, + const std::size_t start_row_index) { generate_assignments_constant(bp, assignment, params, start_row_index); @@ -255,20 +215,17 @@ namespace nil { var one = var(0, start_row_index + 1, false, var::column_type::constant); std::array scalars; - std::size_t scalar_idx = KimchiCommitmentParamsType::srs_len - + kimchi_constants::srs_padding_size(); + std::size_t scalar_idx = KimchiCommitmentParamsType::srs_len + kimchi_constants::srs_padding_size(); for (std::size_t i = 0; - i < KimchiCommitmentParamsType::srs_len + kimchi_constants::srs_padding_size(); - i++) { - scalars[i] = zero; + i < KimchiCommitmentParamsType::srs_len + kimchi_constants::srs_padding_size(); + i++) { + scalars[i] = zero; } - var rand_base = random_component::generate_circuit( - bp, assignment, {params.batches}, row).output; + var rand_base = random_component::generate_circuit(bp, assignment, {params.batches}, row).output; row += random_component::rows_amount; - var sg_rand_base = random_component::generate_circuit( - bp, assignment, {params.batches}, row).output; + var sg_rand_base = random_component::generate_circuit(bp, assignment, {params.batches}, row).output; row += random_component::rows_amount; var rand_base_i = one; @@ -279,118 +236,117 @@ namespace nil { std::array, 2> challenges; for (std::size_t j = 0; j < eval_rounds; j++) { - challenges[0][j] = endo_scalar_component::generate_circuit( - bp, assignment, - {params.batches[batch_id].fq_output.challenges[j]}, - row).output; + challenges[0][j] = + endo_scalar_component::generate_circuit( + bp, assignment, {params.batches[batch_id].fq_output.challenges[j]}, row) + .output; row += endo_scalar_component::rows_amount; - challenges[1][j] = generate_circuit( - bp, assignment, {zero, challenges[0][j]}, row).output; + challenges[1][j] = ::nil::blueprint::components::generate_circuit( + bp, assignment, {zero, challenges[0][j]}, row) + .output; row += sub_component::rows_amount; } - var c = endo_scalar_component::generate_circuit( - bp, assignment, - {params.batches[batch_id].fq_output.c}, - row).output; + var c = endo_scalar_component::generate_circuit(bp, assignment, + {params.batches[batch_id].fq_output.c}, row) + .output; row += endo_scalar_component::rows_amount; var b0_scale = one; var b0 = zero; for (std::size_t i = 0; i < KimchiParamsType::eval_points_amount; i++) { - var term = b_poly_component::generate_circuit( - bp, assignment, - {challenges[0], params.batches[batch_id].eval_points[i], - one}, row).output; + var term = + b_poly_component::generate_circuit( + bp, assignment, {challenges[0], params.batches[batch_id].eval_points[i], one}, row) + .output; row += b_poly_component::rows_amount; - var tmp = generate_circuit( - bp, assignment, {b0_scale, term}, row).output; + var tmp = ::nil::blueprint::components::generate_circuit( + bp, assignment, {b0_scale, term}, row) + .output; row += mul_component::rows_amount; - b0 = generate_circuit( - bp, assignment, {b0, tmp}, row).output; + b0 = ::nil::blueprint::components::generate_circuit(bp, assignment, + {b0, tmp}, row) + .output; row += add_component::rows_amount; - b0_scale = generate_circuit( - bp, assignment, {b0_scale, params.batches[batch_id].r}, row).output; + b0_scale = ::nil::blueprint::components::generate_circuit( + bp, assignment, {b0_scale, params.batches[batch_id].r}, row) + .output; row += mul_component::rows_amount; } - auto s = b_poly_coeff_component::generate_circuit( - bp, assignment, {challenges[0], one}, row).output; + auto s = + b_poly_coeff_component::generate_circuit(bp, assignment, {challenges[0], one}, row).output; row += b_poly_coeff_component::rows_amount; - var neg_rand_base_i = - generate_circuit( - bp, assignment, {rand_base_i, -1}, row).output; + var neg_rand_base_i = ::nil::blueprint::components::generate_circuit( + bp, assignment, {rand_base_i, -1}, row) + .output; row += mul_by_const_component::rows_amount; // neg_rand_base_i * opening.z1 - sg_rand_base_i - var tmp = generate_circuit(bp, - assignment, {neg_rand_base_i, params.batches[batch_id].opening.z1}, - row).output; + var tmp = ::nil::blueprint::components::generate_circuit( + bp, assignment, {neg_rand_base_i, params.batches[batch_id].opening.z1}, row) + .output; row += mul_component::rows_amount; - tmp = generate_circuit(bp, - assignment, {tmp, sg_rand_base_i}, row).output; + tmp = ::nil::blueprint::components::generate_circuit(bp, assignment, + {tmp, sg_rand_base_i}, row) + .output; row += sub_component::rows_amount; scalars[scalar_idx++] = tmp; for (std::size_t i = 0; i < s.size(); i++) { - var sg_s = generate_circuit( - bp, assignment, {sg_rand_base_i, s[i]}, - row).output; + var sg_s = ::nil::blueprint::components::generate_circuit( + bp, assignment, {sg_rand_base_i, s[i]}, row) + .output; row += mul_component::rows_amount; - scalars[i] = generate_circuit( - bp, assignment, {scalars[i], sg_s}, row).output; + scalars[i] = ::nil::blueprint::components::generate_circuit( + bp, assignment, {scalars[i], sg_s}, row) + .output; row += add_component::rows_amount; } - var rand_base_z2 = generate_circuit( - bp, assignment, {rand_base_i, - params.batches[batch_id].opening.z2}, - row).output; + var rand_base_z2 = ::nil::blueprint::components::generate_circuit( + bp, assignment, {rand_base_i, params.batches[batch_id].opening.z2}, row) + .output; row += mul_component::rows_amount; - scalars[0] = generate_circuit( - bp, assignment, {scalars[0], rand_base_z2}, - row).output; + scalars[0] = ::nil::blueprint::components::generate_circuit( + bp, assignment, {scalars[0], rand_base_z2}, row) + .output; row += sub_component::rows_amount; // neg_rand_base_i * (opening.z1 * b0) - var z1_b0 = generate_circuit( - bp, assignment, {b0, - params.batches[batch_id].opening.z1}, - row).output; + var z1_b0 = ::nil::blueprint::components::generate_circuit( + bp, assignment, {b0, params.batches[batch_id].opening.z1}, row) + .output; row += mul_component::rows_amount; - scalars[scalar_idx++] = generate_circuit( - bp, assignment, {z1_b0, - neg_rand_base_i}, - row).output; + scalars[scalar_idx++] = ::nil::blueprint::components::generate_circuit( + bp, assignment, {z1_b0, neg_rand_base_i}, row) + .output; row += mul_component::rows_amount; - var c_rand_base_i = generate_circuit( - bp, assignment, {c, - rand_base_i}, - row).output; + var c_rand_base_i = ::nil::blueprint::components::generate_circuit( + bp, assignment, {c, rand_base_i}, row) + .output; row += mul_component::rows_amount; for (std::size_t i = 0; i < eval_rounds; i++) { // rand_base_i_c_i * u_inv - scalars[scalar_idx++] = generate_circuit( - bp, assignment, {challenges[1][i], - c_rand_base_i}, - row).output; + scalars[scalar_idx++] = ::nil::blueprint::components::generate_circuit( + bp, assignment, {challenges[1][i], c_rand_base_i}, row) + .output; row += mul_component::rows_amount; // rand_base_i_c_i * u - scalars[scalar_idx++] = generate_circuit( - bp, assignment, {challenges[0][i], - c_rand_base_i}, - row).output; + scalars[scalar_idx++] = ::nil::blueprint::components::generate_circuit( + bp, assignment, {challenges[0][i], c_rand_base_i}, row) + .output; row += mul_component::rows_amount; } @@ -398,46 +354,42 @@ namespace nil { for (std::size_t i = 0; i < kimchi_constants::evaluations_in_batch_size; i++) { // iterating over the polynomial segments + shifted part for (std::size_t j = 0; - j < KimchiParamsType::commitment_params_type::shifted_commitment_split + 1; - j++) { + j < KimchiParamsType::commitment_params_type::shifted_commitment_split + 1; + j++) { // rand_base_i_c_i * xi_i - scalars[scalar_idx++] = generate_circuit( - bp, assignment, {xi_i, - c_rand_base_i}, - row).output; + scalars[scalar_idx++] = ::nil::blueprint::components::generate_circuit( + bp, assignment, {xi_i, c_rand_base_i}, row) + .output; row += mul_component::rows_amount; - xi_i = generate_circuit( - bp, assignment, {xi_i, - params.batches[batch_id].xi}, - row).output; + xi_i = ::nil::blueprint::components::generate_circuit( + bp, assignment, {xi_i, params.batches[batch_id].xi}, row) + .output; row += mul_component::rows_amount; } } // rand_base_i_c_i * combined_inner_product0 - scalars[scalar_idx++] = generate_circuit( - bp, assignment, {cip, - c_rand_base_i}, - row).output; + scalars[scalar_idx++] = ::nil::blueprint::components::generate_circuit( + bp, assignment, {cip, c_rand_base_i}, row) + .output; row += mul_component::rows_amount; scalars[scalar_idx++] = rand_base_i; - rand_base_i = generate_circuit( - bp, assignment, - {rand_base_i, rand_base}, row).output; + rand_base_i = ::nil::blueprint::components::generate_circuit( + bp, assignment, {rand_base_i, rand_base}, row) + .output; row += mul_component::rows_amount; - sg_rand_base_i = generate_circuit( - bp, assignment, - {sg_rand_base_i, sg_rand_base}, row).output; + sg_rand_base_i = ::nil::blueprint::components::generate_circuit( + bp, assignment, {sg_rand_base_i, sg_rand_base}, row) + .output; row += mul_component::rows_amount; } - scalars = prepare_scalars_component::generate_circuit(bp, assignment, - {scalars}, row).output; + scalars = prepare_scalars_component::generate_circuit(bp, assignment, {scalars}, row).output; row += prepare_scalars_component::rows_amount; assert(row == start_row_index + rows_amount); @@ -448,7 +400,7 @@ namespace nil { return res; } - static result_type generate_assignments(blueprint_assignment_table &assignment, + static result_type generate_assignments(assignment &assignment, const params_type ¶ms, std::size_t start_row_index) { std::size_t row = start_row_index; @@ -461,20 +413,17 @@ namespace nil { var one = var(0, start_row_index + 1, false, var::column_type::constant); std::array scalars; - std::size_t scalar_idx = KimchiCommitmentParamsType::srs_len - + kimchi_constants::srs_padding_size(); + std::size_t scalar_idx = KimchiCommitmentParamsType::srs_len + kimchi_constants::srs_padding_size(); for (std::size_t i = 0; - i < KimchiCommitmentParamsType::srs_len + kimchi_constants::srs_padding_size(); - i++) { - scalars[i] = zero; + i < KimchiCommitmentParamsType::srs_len + kimchi_constants::srs_padding_size(); + i++) { + scalars[i] = zero; } - var rand_base = random_component::generate_assignments( - assignment, {params.batches}, row).output; + var rand_base = random_component::generate_assignments(assignment, {params.batches}, row).output; row += random_component::rows_amount; - var sg_rand_base = random_component::generate_assignments( - assignment, {params.batches}, row).output; + var sg_rand_base = random_component::generate_assignments(assignment, {params.batches}, row).output; row += random_component::rows_amount; var rand_base_i = one; @@ -486,116 +435,102 @@ namespace nil { std::array, 2> challenges; for (std::size_t j = 0; j < eval_rounds; j++) { challenges[0][j] = endo_scalar_component::generate_assignments( - assignment, - {params.batches[batch_id].fq_output.challenges[j]}, - row).output; + assignment, {params.batches[batch_id].fq_output.challenges[j]}, row) + .output; row += endo_scalar_component::rows_amount; - challenges[1][j] = sub_component::generate_assignments( - assignment, {zero, challenges[0][j]}, row).output; + challenges[1][j] = + sub_component::generate_assignments(assignment, {zero, challenges[0][j]}, row).output; row += sub_component::rows_amount; } - var c = endo_scalar_component::generate_assignments( - assignment, - {params.batches[batch_id].fq_output.c}, - row).output; + var c = endo_scalar_component::generate_assignments(assignment, + {params.batches[batch_id].fq_output.c}, row) + .output; row += endo_scalar_component::rows_amount; var b0_scale = one; var b0 = zero; for (std::size_t i = 0; i < KimchiParamsType::eval_points_amount; i++) { - var term = b_poly_component::generate_assignments( - assignment, - {challenges[0], params.batches[batch_id].eval_points[i], - one}, row).output; + var term = + b_poly_component::generate_assignments( + assignment, {challenges[0], params.batches[batch_id].eval_points[i], one}, row) + .output; row += b_poly_component::rows_amount; - var tmp = mul_component::generate_assignments( - assignment, {b0_scale, term}, row).output; + var tmp = mul_component::generate_assignments(assignment, {b0_scale, term}, row).output; row += mul_component::rows_amount; - b0 = add_component::generate_assignments( - assignment, {b0, tmp}, row).output; + b0 = add_component::generate_assignments(assignment, {b0, tmp}, row).output; row += add_component::rows_amount; - b0_scale = mul_component::generate_assignments( - assignment, {b0_scale, params.batches[batch_id].r}, row).output; + b0_scale = mul_component::generate_assignments(assignment, + {b0_scale, params.batches[batch_id].r}, row) + .output; row += mul_component::rows_amount; } - auto s = b_poly_coeff_component::generate_assignments( - assignment, {challenges[0], one}, row).output; + auto s = + b_poly_coeff_component::generate_assignments(assignment, {challenges[0], one}, row).output; row += b_poly_coeff_component::rows_amount; - var neg_rand_base_i = mul_by_const_component::generate_assignments( - assignment, {rand_base_i, -1}, row).output; + var neg_rand_base_i = + mul_by_const_component::generate_assignments(assignment, {rand_base_i, -1}, row).output; row += mul_by_const_component::rows_amount; // neg_rand_base_i * opening.z1 - sg_rand_base_i var tmp = mul_component::generate_assignments( - assignment, {neg_rand_base_i, params.batches[batch_id].opening.z1}, - row).output; + assignment, {neg_rand_base_i, params.batches[batch_id].opening.z1}, row) + .output; row += mul_component::rows_amount; - tmp = sub_component::generate_assignments( - assignment, {tmp, sg_rand_base_i}, row).output; + tmp = sub_component::generate_assignments(assignment, {tmp, sg_rand_base_i}, row).output; row += sub_component::rows_amount; scalars[scalar_idx++] = tmp; for (std::size_t i = 0; i < s.size(); i++) { - var sg_s = mul_component::generate_assignments( - assignment, {sg_rand_base_i, s[i]}, - row).output; + var sg_s = + mul_component::generate_assignments(assignment, {sg_rand_base_i, s[i]}, row).output; row += mul_component::rows_amount; - scalars[i] = add_component::generate_assignments( - assignment, {scalars[i], sg_s}, row).output; + scalars[i] = + add_component::generate_assignments(assignment, {scalars[i], sg_s}, row).output; row += add_component::rows_amount; } var rand_base_z2 = mul_component::generate_assignments( - assignment, {rand_base_i, - params.batches[batch_id].opening.z2}, - row).output; + assignment, {rand_base_i, params.batches[batch_id].opening.z2}, row) + .output; row += mul_component::rows_amount; - scalars[0] = sub_component::generate_assignments( - assignment, {scalars[0], rand_base_z2}, - row).output; + scalars[0] = + sub_component::generate_assignments(assignment, {scalars[0], rand_base_z2}, row).output; row += sub_component::rows_amount; // neg_rand_base_i * (opening.z1 * b0) - var z1_b0 = mul_component::generate_assignments( - assignment, {b0, - params.batches[batch_id].opening.z1}, - row).output; + var z1_b0 = mul_component::generate_assignments(assignment, + {b0, params.batches[batch_id].opening.z1}, row) + .output; row += mul_component::rows_amount; - scalars[scalar_idx++] = mul_component::generate_assignments( - assignment, {z1_b0, - neg_rand_base_i}, - row).output; + scalars[scalar_idx++] = + mul_component::generate_assignments(assignment, {z1_b0, neg_rand_base_i}, row).output; row += mul_component::rows_amount; - var c_rand_base_i = mul_component::generate_assignments( - assignment, {c, - rand_base_i}, - row).output; + var c_rand_base_i = + mul_component::generate_assignments(assignment, {c, rand_base_i}, row).output; row += mul_component::rows_amount; for (std::size_t i = 0; i < eval_rounds; i++) { // rand_base_i_c_i * u_inv - scalars[scalar_idx++] = mul_component::generate_assignments( - assignment, {challenges[1][i], - c_rand_base_i}, - row).output; + scalars[scalar_idx++] = + mul_component::generate_assignments(assignment, {challenges[1][i], c_rand_base_i}, row) + .output; row += mul_component::rows_amount; // rand_base_i_c_i * u - scalars[scalar_idx++] = mul_component::generate_assignments( - assignment, {challenges[0][i], - c_rand_base_i}, - row).output; + scalars[scalar_idx++] = + mul_component::generate_assignments(assignment, {challenges[0][i], c_rand_base_i}, row) + .output; row += mul_component::rows_amount; } @@ -603,44 +538,38 @@ namespace nil { for (std::size_t i = 0; i < kimchi_constants::evaluations_in_batch_size; i++) { // iterating over the polynomial segments + shifted part for (std::size_t j = 0; - j < KimchiParamsType::commitment_params_type::shifted_commitment_split + 1; - j++) { + j < KimchiParamsType::commitment_params_type::shifted_commitment_split + 1; + j++) { // rand_base_i_c_i * xi_i - scalars[scalar_idx++] = mul_component::generate_assignments( - assignment, {xi_i, - c_rand_base_i}, - row).output; + scalars[scalar_idx++] = + mul_component::generate_assignments(assignment, {xi_i, c_rand_base_i}, row).output; row += mul_component::rows_amount; - xi_i = mul_component::generate_assignments( - assignment, {xi_i, - params.batches[batch_id].xi}, - row).output; + xi_i = mul_component::generate_assignments(assignment, + {xi_i, params.batches[batch_id].xi}, row) + .output; row += mul_component::rows_amount; } } // rand_base_i_c_i * combined_inner_product0 - scalars[scalar_idx++] = mul_component::generate_assignments( - assignment, {cip, - c_rand_base_i}, - row).output; + scalars[scalar_idx++] = + mul_component::generate_assignments(assignment, {cip, c_rand_base_i}, row).output; row += mul_component::rows_amount; scalars[scalar_idx++] = rand_base_i; - rand_base_i = mul_component::generate_assignments(assignment, - {rand_base_i, rand_base}, row).output; + rand_base_i = + mul_component::generate_assignments(assignment, {rand_base_i, rand_base}, row).output; row += mul_component::rows_amount; - sg_rand_base_i = mul_component::generate_assignments(assignment, - {sg_rand_base_i, sg_rand_base}, row).output; + sg_rand_base_i = + mul_component::generate_assignments(assignment, {sg_rand_base_i, sg_rand_base}, row).output; row += mul_component::rows_amount; } - scalars = prepare_scalars_component::generate_assignments(assignment, - {scalars}, row).output; + scalars = prepare_scalars_component::generate_assignments(assignment, {scalars}, row).output; row += prepare_scalars_component::rows_amount; assert(row == start_row_index + rows_amount); @@ -652,38 +581,33 @@ namespace nil { } private: - - static void generate_gates( - blueprint &bp, - blueprint_public_assignment_table &public_assignment, - const params_type ¶ms, - const std::size_t first_selector_index) { - + static void generate_gates(blueprint &bp, + assignment &public_assignment, + const params_type ¶ms, + const std::size_t first_selector_index) { } static void generate_copy_constraints(blueprint &bp, - blueprint_public_assignment_table &assignment, - const params_type ¶ms, - const std::size_t start_row_index) { + assignment &assignment, + const params_type ¶ms, + const std::size_t start_row_index) { std::size_t row = start_row_index; - } - static void - generate_assignments_constant(blueprint &bp, - blueprint_public_assignment_table &assignment, - const params_type ¶ms, - std::size_t component_start_row) { - std::size_t row = component_start_row; - assignment.constant(0)[row] = 0; - row++; - assignment.constant(0)[row] = 1; - row++; + static void generate_assignments_constant(blueprint &bp, + assignment &assignment, + const params_type ¶ms, + std::size_t component_start_row) { + std::size_t row = component_start_row; + assignment.constant(0)[row] = 0; + row++; + assignment.constant(0)[row] = 1; + row++; } }; } // namespace components - } // namespace blueprint + } // namespace blueprint } // namespace nil #endif // CRYPTO3_BLUEPRINT_COMPONENTS_BATCH_VERIFY_SCALAR_FIELD_HPP \ No newline at end of file diff --git a/include/nil/blueprint/components/systems/snark/plonk/kimchi/detail/batch_scalar/prepare_scalars.hpp b/include/nil/blueprint/components/systems/snark/plonk/kimchi/detail/batch_scalar/prepare_scalars.hpp index dcdce99e3..acf7c836f 100644 --- a/include/nil/blueprint/components/systems/snark/plonk/kimchi/detail/batch_scalar/prepare_scalars.hpp +++ b/include/nil/blueprint/components/systems/snark/plonk/kimchi/detail/batch_scalar/prepare_scalars.hpp @@ -32,153 +32,183 @@ // #include -#include -#include +#include +#include +#include namespace nil { - namespace crypto3 { - namespace blueprint { - namespace components { - - // shift scalars for scalar multiplication input - // f(X) = X -> X - 2^255 when the scalar field is larger than the base field and // TODO: "larger scalar - // field is depricated case" f(X) = X -> (X - 2^255 - 1) / 2 otherwise Input: [x_0, ..., x_InputSize] - // Output: [f(x_0), ..., f(x_InputSize)] - template - class prepare_scalars; - - template - class prepare_scalars, - CurveType, InputSize, W0, W1, W2, W3, W4, W5, W6, W7, W8, W9, W10, W11, W12, W13, W14> { - - typedef snark::plonk_constraint_system - ArithmetizationType; - - using var = snark::plonk_variable; - - using mul_component = zk::components::multiplication; - using add_component = zk::components::addition; - - constexpr static const std::size_t selector_seed = 0x0f2C; - - constexpr static bool scalar_larger() { - using ScalarField = typename CurveType::scalar_field_type; - using BaseField = typename CurveType::base_field_type; - - auto n1 = ScalarField::modulus; - auto n2 = BaseField::modulus; - - return n1 > n2; - } - - public: - constexpr static const std::size_t rows_amount = - InputSize * (add_component::rows_amount + mul_component::rows_amount); - constexpr static const std::size_t gates_amount = 0; - - struct params_type { - std::array scalars; - }; - - struct result_type { - std::array output; - }; - - static result_type - generate_circuit(blueprint &bp, - blueprint_public_assignment_table &assignment, - const params_type ¶ms, - const std::size_t start_row_index) { + namespace blueprint { + namespace components { + + // shift scalars for scalar multiplication input + // f(X) = X -> X - 2^255 when the scalar field is larger than the base field and // TODO: "larger scalar + // field is depricated case" f(X) = X -> (X - 2^255 - 1) / 2 otherwise Input: [x_0, ..., x_InputSize] + // Output: [f(x_0), ..., f(x_InputSize)] + template + class prepare_scalars; + + template + class prepare_scalars, + CurveType, + InputSize, + W0, + W1, + W2, + W3, + W4, + W5, + W6, + W7, + W8, + W9, + W10, + W11, + W12, + W13, + W14> { + + typedef crypto3::zk::snark::plonk_constraint_system ArithmetizationType; + + using var = crypto3::zk::snark::plonk_variable; + + using mul_component = multiplication>; + using add_component = + addition>; + + constexpr static const std::size_t selector_seed = 0x0f2C; + + constexpr static bool scalar_larger() { + using ScalarField = typename CurveType::scalar_field_type; + using BaseField = typename CurveType::base_field_type; + + auto n1 = ScalarField::modulus; + auto n2 = BaseField::modulus; + + return n1 > n2; + } + + public: + constexpr static const std::size_t rows_amount = + InputSize * (add_component::rows_amount + mul_component::rows_amount); + constexpr static const std::size_t gates_amount = 0; + + struct params_type { + std::array scalars; + }; - generate_assignments_constants(bp, assignment, params, start_row_index); + struct result_type { + std::array output; + }; - var shift = var(0, start_row_index, false, var::column_type::constant); - var coef = var(0, start_row_index + 1, false, var::column_type::constant); + static result_type generate_circuit(blueprint &bp, + assignment &assignment, + const params_type ¶ms, + const std::size_t start_row_index) { - std::size_t row = start_row_index; + generate_assignments_constants(bp, assignment, params, start_row_index); - std::array shifted; - result_type result; + var shift = var(0, start_row_index, false, var::column_type::constant); + var coef = var(0, start_row_index + 1, false, var::column_type::constant); - for (std::size_t i = 0; i < InputSize; ++i) { - shifted[i] = zk::components::generate_circuit( - bp, assignment, {params.scalars[i], shift}, row) - .output; - row += add_component::rows_amount; - result.output[i] = - zk::components::generate_circuit(bp, assignment, {shifted[i], coef}, row) - .output; - row += mul_component::rows_amount; - } + std::size_t row = start_row_index; - generate_copy_constraints(bp, assignment, params, start_row_index); + std::array shifted; + result_type result; - return result; + for (std::size_t i = 0; i < InputSize; ++i) { + shifted[i] = ::nil::blueprint::components::generate_circuit( + bp, assignment, {params.scalars[i], shift}, row) + .output; + row += add_component::rows_amount; + result.output[i] = ::nil::blueprint::components::generate_circuit( + bp, assignment, {shifted[i], coef}, row) + .output; + row += mul_component::rows_amount; } - static result_type generate_assignments(blueprint_assignment_table &assignment, - const params_type ¶ms, - const std::size_t start_row_index) { + generate_copy_constraints(bp, assignment, params, start_row_index); - var shift = var(0, start_row_index, false, var::column_type::constant); - var coef = var(0, start_row_index + 1, false, var::column_type::constant); + return result; + } - std::size_t row = start_row_index; + static result_type generate_assignments(assignment &assignment, + const params_type ¶ms, + const std::size_t start_row_index) { - std::array shifted; - result_type result; + var shift = var(0, start_row_index, false, var::column_type::constant); + var coef = var(0, start_row_index + 1, false, var::column_type::constant); - for (std::size_t i = 0; i < InputSize; ++i) { - shifted[i] = - add_component::generate_assignments(assignment, {params.scalars[i], shift}, row).output; - row += add_component::rows_amount; - result.output[i] = - mul_component::generate_assignments(assignment, {shifted[i], coef}, row).output; - row += mul_component::rows_amount; - } + std::size_t row = start_row_index; - return result; - } + std::array shifted; + result_type result; - private: - static void generate_gates(blueprint &bp, - blueprint_public_assignment_table &assignment, - const params_type ¶ms, - const std::size_t first_selector_index) { + for (std::size_t i = 0; i < InputSize; ++i) { + shifted[i] = + add_component::generate_assignments(assignment, {params.scalars[i], shift}, row).output; + row += add_component::rows_amount; + result.output[i] = + mul_component::generate_assignments(assignment, {shifted[i], coef}, row).output; + row += mul_component::rows_amount; } - static void - generate_copy_constraints(blueprint &bp, - blueprint_public_assignment_table &assignment, - const params_type ¶ms, - const std::size_t start_row_index) { + return result; + } + + private: + static void generate_gates(blueprint &bp, + assignment &assignment, + const params_type ¶ms, + const std::size_t first_selector_index) { + } + + static void generate_copy_constraints(blueprint &bp, + assignment &assignment, + const params_type ¶ms, + const std::size_t start_row_index) { + } + + static void generate_assignments_constants(blueprint &bp, + assignment &assignment, + const params_type ¶ms, + const std::size_t start_row_index) { + std::size_t row = start_row_index; + typename BlueprintFieldType::value_type base = 2; + if (scalar_larger()) { + assignment.constant(0)[row] = -base.pow(255); + row++; + assignment.constant(0)[row] = 1; + } else { + assignment.constant(0)[row] = -base.pow(255) - 1; + row++; + assignment.constant(0)[row] = 1 / base; } - - static void generate_assignments_constants( - blueprint &bp, - blueprint_public_assignment_table &assignment, - const params_type ¶ms, - const std::size_t start_row_index) { - std::size_t row = start_row_index; - typename BlueprintFieldType::value_type base = 2; - if (scalar_larger()) { - assignment.constant(0)[row] = -base.pow(255); - row++; - assignment.constant(0)[row] = 1; - } else { - assignment.constant(0)[row] = -base.pow(255) - 1; - row++; - assignment.constant(0)[row] = 1 / base; - } - } - }; - } // namespace components - } // namespace blueprint - } // namespace crypto3 + } + }; + } // namespace components + } // namespace blueprint } // namespace nil #endif // CRYPTO3_BLUEPRINT_COMPONENTS_PLONK_KIMCHI_DETAIL_BATCH_SCALAR_PREPARE_SCALARS_HPP \ No newline at end of file diff --git a/include/nil/blueprint/components/systems/snark/plonk/kimchi/detail/batch_scalar/random.hpp b/include/nil/blueprint/components/systems/snark/plonk/kimchi/detail/batch_scalar/random.hpp index 85fe30921..aa9875d3b 100644 --- a/include/nil/blueprint/components/systems/snark/plonk/kimchi/detail/batch_scalar/random.hpp +++ b/include/nil/blueprint/components/systems/snark/plonk/kimchi/detail/batch_scalar/random.hpp @@ -33,162 +33,196 @@ #include #include -#include +#include namespace nil { - namespace crypto3 { - namespace blueprint { - namespace components { - - // pseudo-random element generation - // it's used for randomization here: - // https://github.com/o1-labs/proof-systems/blob/1f8532ec1b8d43748a372632bd854be36b371afe/poly-commitment/src/commitment.rs#L656 - // Input: - - // Output: x \in F_r - template - class random; - - template - class random, - KimchiParamsType, BatchSize, W0, W1, W2, W3, W4, W5, W6, W7, W8, W9, W10, - W11, W12, W13, W14> { - - typedef snark::plonk_constraint_system - ArithmetizationType; - - using var = snark::plonk_variable; - - using transcript_type = kimchi_transcript_fr; - - using batch_proof = - batch_evaluation_proof_scalar; - - constexpr static const std::size_t selector_seed = 0x0f29; - - public: - constexpr static const std::size_t rows_amount = - transcript_type::init_rows + - BatchSize * (transcript_type::state_size * transcript_type::absorb_rows + - 3 * transcript_type::absorb_rows) + - transcript_type::challenge_rows; - constexpr static const std::size_t gates_amount = 0; - - struct params_type { - std::array batches; - }; - - struct result_type { - var output; - }; - - static result_type - generate_circuit(blueprint &bp, - blueprint_public_assignment_table &assignment, - const params_type ¶ms, - const std::size_t start_row_index) { - - std::size_t row = start_row_index; - - var zero(0, start_row_index, false, var::column_type::constant); - - transcript_type transcript; - transcript.init_circuit(bp, assignment, zero, row); - row += transcript_type::init_rows; - - for (auto batched_proof : params.batches) { - // the most part of the data that influences the results is accumulated in the transcript - auto state = batched_proof.transcript.state(); - for (std::size_t i = 0; i < state.size(); i++) { - transcript.absorb_circuit(bp, assignment, state[i], row); - row += transcript_type::absorb_rows; - } - - transcript.absorb_circuit(bp, assignment, batched_proof.cip, row); - row += transcript_type::absorb_rows; + namespace blueprint { + namespace components { + + // pseudo-random element generation + // it's used for randomization here: + // https://github.com/o1-labs/proof-systems/blob/1f8532ec1b8d43748a372632bd854be36b371afe/poly-commitment/src/commitment.rs#L656 + // Input: - + // Output: x \in F_r + template + class random; + + template + class random, + KimchiParamsType, + BatchSize, + W0, + W1, + W2, + W3, + W4, + W5, + W6, + W7, + W8, + W9, + W10, + W11, + W12, + W13, + W14> { + + typedef crypto3::zk::snark::plonk_constraint_system ArithmetizationType; + + using var = crypto3::zk::snark::plonk_variable; + + using transcript_type = kimchi_transcript_fr; + + using batch_proof = batch_evaluation_proof_scalar; + + constexpr static const std::size_t selector_seed = 0x0f29; + + public: + constexpr static const std::size_t rows_amount = + transcript_type::init_rows + + BatchSize * (transcript_type::state_size * transcript_type::absorb_rows + + 3 * transcript_type::absorb_rows) + + transcript_type::challenge_rows; + constexpr static const std::size_t gates_amount = 0; + + struct params_type { + std::array batches; + }; - transcript.absorb_circuit(bp, assignment, batched_proof.opening.z1, row); - row += transcript_type::absorb_rows; - transcript.absorb_circuit(bp, assignment, batched_proof.opening.z2, row); + struct result_type { + var output; + }; + + static result_type generate_circuit(blueprint &bp, + assignment &assignment, + const params_type ¶ms, + const std::size_t start_row_index) { + + std::size_t row = start_row_index; + + var zero(0, start_row_index, false, var::column_type::constant); + + transcript_type transcript; + transcript.init_circuit(bp, assignment, zero, row); + row += transcript_type::init_rows; + + for (auto batched_proof : params.batches) { + // the most part of the data that influences the results is accumulated in the transcript + auto state = batched_proof.transcript.state(); + for (std::size_t i = 0; i < state.size(); i++) { + transcript.absorb_circuit(bp, assignment, state[i], row); row += transcript_type::absorb_rows; } - var output = transcript.challenge_circuit(bp, assignment, row); - row += transcript_type::challenge_rows; + transcript.absorb_circuit(bp, assignment, batched_proof.cip, row); + row += transcript_type::absorb_rows; - assert(row == start_row_index + rows_amount); + transcript.absorb_circuit(bp, assignment, batched_proof.opening.z1, row); + row += transcript_type::absorb_rows; + transcript.absorb_circuit(bp, assignment, batched_proof.opening.z2, row); + row += transcript_type::absorb_rows; + } - generate_assignments_constants(assignment, params, start_row_index); + var output = transcript.challenge_circuit(bp, assignment, row); + row += transcript_type::challenge_rows; - result_type res = {output}; - return res; - } + assert(row == start_row_index + rows_amount); - static result_type generate_assignments(blueprint_assignment_table &assignment, - const params_type ¶ms, - const std::size_t start_row_index) { + generate_assignments_constants(assignment, params, start_row_index); - std::size_t row = start_row_index; + result_type res = {output}; + return res; + } - var zero(0, start_row_index, false, var::column_type::constant); + static result_type generate_assignments(assignment &assignment, + const params_type ¶ms, + const std::size_t start_row_index) { - transcript_type transcript; - transcript.init_assignment(assignment, zero, row); - row += transcript_type::init_rows; + std::size_t row = start_row_index; - for (auto batched_proof : params.batches) { - // the most part of the data that influences the results is accumulated in the transcript - auto state = batched_proof.transcript.state(); - for (std::size_t i = 0; i < state.size(); i++) { - transcript.absorb_assignment(assignment, state[i], row); - row += transcript_type::absorb_rows; - } + var zero(0, start_row_index, false, var::column_type::constant); - transcript.absorb_assignment(assignment, batched_proof.cip, row); - row += transcript_type::absorb_rows; + transcript_type transcript; + transcript.init_assignment(assignment, zero, row); + row += transcript_type::init_rows; - transcript.absorb_assignment(assignment, batched_proof.opening.z1, row); - row += transcript_type::absorb_rows; - transcript.absorb_assignment(assignment, batched_proof.opening.z2, row); + for (auto batched_proof : params.batches) { + // the most part of the data that influences the results is accumulated in the transcript + auto state = batched_proof.transcript.state(); + for (std::size_t i = 0; i < state.size(); i++) { + transcript.absorb_assignment(assignment, state[i], row); row += transcript_type::absorb_rows; } - var output = transcript.challenge_assignment(assignment, row); - row += transcript_type::challenge_rows; - - assert(row == start_row_index + rows_amount); + transcript.absorb_assignment(assignment, batched_proof.cip, row); + row += transcript_type::absorb_rows; - result_type res = {output}; - return res; + transcript.absorb_assignment(assignment, batched_proof.opening.z1, row); + row += transcript_type::absorb_rows; + transcript.absorb_assignment(assignment, batched_proof.opening.z2, row); + row += transcript_type::absorb_rows; } - private: - static void generate_assignments_constants( - blueprint_public_assignment_table &assignment, - const params_type ¶ms, - const std::size_t start_row_index) { - std::size_t row = start_row_index; - assignment.constant(0)[row] = 0; - } - }; - } // namespace components - } // namespace blueprint - } // namespace crypto3 + var output = transcript.challenge_assignment(assignment, row); + row += transcript_type::challenge_rows; + + assert(row == start_row_index + rows_amount); + + result_type res = {output}; + return res; + } + + private: + static void generate_assignments_constants(assignment &assignment, + const params_type ¶ms, + const std::size_t start_row_index) { + std::size_t row = start_row_index; + assignment.constant(0)[row] = 0; + } + }; + } // namespace components + } // namespace blueprint } // namespace nil #endif // CRYPTO3_BLUEPRINT_COMPONENTS_PLONK_KIMCHI_DETAIL_BATCH_SCALAR_RANDOM_HPP \ No newline at end of file diff --git a/include/nil/blueprint/components/systems/snark/plonk/kimchi/detail/binding.hpp b/include/nil/blueprint/components/systems/snark/plonk/kimchi/detail/binding.hpp index 0a714b099..c7f74fe95 100644 --- a/include/nil/blueprint/components/systems/snark/plonk/kimchi/detail/binding.hpp +++ b/include/nil/blueprint/components/systems/snark/plonk/kimchi/detail/binding.hpp @@ -37,51 +37,50 @@ #include namespace nil { - namespace crypto3 { - namespace blueprint { - namespace components { + namespace blueprint { + namespace components { - template - struct binding { - using var = snark::plonk_variable; - using commitment_parms_type = typename KimchiParamsType::commitment_params_type; - using kimchi_constants = zk::components::kimchi_inner_constants; + template + struct binding { + using var = crypto3::zk::snark::plonk_variable; + using commitment_parms_type = typename KimchiParamsType::commitment_params_type; + using kimchi_constants = kimchi_inner_constants; - template - struct fr_data { - private: - constexpr static const std::size_t f_comm_msm_size = kimchi_constants::f_comm_msm_size; - constexpr static const std::size_t lookup_columns = KimchiParamsType::circuit_params::lookup_columns; + template + struct fr_data { + private: + constexpr static const std::size_t f_comm_msm_size = kimchi_constants::f_comm_msm_size; + constexpr static const std::size_t lookup_columns = + KimchiParamsType::circuit_params::lookup_columns; - public: - std::array scalars; - std::array, BatchSize> f_comm_scalars; - std::array cip_shifted; + public: + std::array scalars; + std::array, BatchSize> f_comm_scalars; + std::array cip_shifted; - std::array neg_pub; - std::array zeta_to_srs_len; - var zeta_to_domain_size_minus_1; + std::array neg_pub; + std::array zeta_to_srs_len; + var zeta_to_domain_size_minus_1; - std::array joint_combiner_powers_prepared; - }; + std::array joint_combiner_powers_prepared; + }; - template - struct fq_data { }; + template + struct fq_data { }; - struct fq_sponge_output { - var joint_combiner; - var beta; // beta and gamma can be combined from limbs in the base circuit - var gamma; - var alpha; - var zeta; - var fq_digest; // TODO overflow check - std::array challenges; - var c; - }; + struct fq_sponge_output { + var joint_combiner; + var beta; // beta and gamma can be combined from limbs in the base circuit + var gamma; + var alpha; + var zeta; + var fq_digest; // TODO overflow check + std::array challenges; + var c; }; - } // namespace components - } // namespace blueprint - } // namespace crypto3 + }; + } // namespace components + } // namespace blueprint } // namespace nil #endif // CRYPTO3_BLUEPRINT_COMPONENTS_PLONK_KIMCHI_BINDING_HPP \ No newline at end of file diff --git a/include/nil/blueprint/components/systems/snark/plonk/kimchi/detail/compare.hpp b/include/nil/blueprint/components/systems/snark/plonk/kimchi/detail/compare.hpp index 435fbaeb0..e4fda596c 100644 --- a/include/nil/blueprint/components/systems/snark/plonk/kimchi/detail/compare.hpp +++ b/include/nil/blueprint/components/systems/snark/plonk/kimchi/detail/compare.hpp @@ -37,356 +37,358 @@ #include -#include +#include +#include +#include +#include +#include #include #include #include namespace nil { - namespace crypto3 { - namespace blueprint { - namespace components { - - ///////////////// Compare Value with Constant //////////////////////////////// - // Constant is pallas base field modulus - // Return 0, if value >= constant - // Return 1 otherwise - template - class compare_with_const; - - template - class compare_with_const, - CurveType, - W0, - W1, - W2> { - - typedef snark::plonk_constraint_system - ArithmetizationType; - - using sub_component = zk::components::subtraction; - using mul_component = zk::components::multiplication; - using add_component = zk::components::addition; - using div_component = zk::components::division; - using mul_by_const_component = zk::components::mul_by_constant; - - using var = snark::plonk_variable; - - constexpr static const std::size_t selector_seed = 0x0ff8; - - public: - constexpr static const std::size_t rows_amount = 15 + 8 * 87; - constexpr static const std::size_t gates_amount = 0; - - struct params_type { - var value; - params_type(var val) : value(val) { - } - }; - - struct result_type { - var output; - - result_type(std::size_t row) { - output = var(W2, static_cast(row), false, var::column_type::witness); - } - }; - - static result_type - generate_circuit(blueprint &bp, - blueprint_public_assignment_table &assignment, - const params_type ¶ms, - const std::size_t component_start_row) { - - generate_assignments_constants(bp, assignment, params, component_start_row); - - std::size_t row = component_start_row; - - var k = var(0, component_start_row, false, var::column_type::constant); - var power87 = var(0, component_start_row + 1, false, var::column_type::constant); - var zero = var(0, component_start_row + 2, false, var::column_type::constant); - var one = var(0, component_start_row + 3, false, var::column_type::constant); - - var c_var = - zk::components::generate_circuit(bp, assignment, {zero, params.value}, row) - .output; - row++; + namespace blueprint { + namespace components { + + ///////////////// Compare Value with Constant //////////////////////////////// + // Constant is pallas base field modulus + // Return 0, if value >= constant + // Return 1 otherwise + template + class compare_with_const; + + template + class compare_with_const, + CurveType, + W0, + W1, + W2> { + + typedef crypto3::zk::snark::plonk_constraint_system ArithmetizationType; + + using sub_component = + subtraction>; + using mul_component = multiplication>; + using add_component = + addition>; + using div_component = + division>; + using mul_by_const_component = mul_by_constant; + + using var = crypto3::zk::snark::plonk_variable; + + constexpr static const std::size_t selector_seed = 0x0ff8; + + public: + constexpr static const std::size_t rows_amount = 15 + 8 * 87; + constexpr static const std::size_t gates_amount = 0; + + struct params_type { + var value; + params_type(var val) : value(val) { + } + }; - var b_var = - zk::components::generate_circuit(bp, assignment, {power87, k}, row).output; - row++; - b_var = - zk::components::generate_circuit(bp, assignment, {b_var, one}, row).output; - row++; - b_var = - zk::components::generate_circuit(bp, assignment, {b_var, c_var}, row).output; - row++; - var c1_var = zero; - var b1_var = zero; - var bit_var; - typename BlueprintFieldType::value_type times = 1; - - for (int i = 0; i < 87; ++i) { - bit_var = var(W1, row, false); - var bit_check_c = - zk::components::generate_circuit(bp, assignment, {one, bit_var}, row) - .output; - row++; - bit_check_c = zk::components::generate_circuit( - bp, assignment, {bit_var, bit_check_c}, row) - .output; - row++; - bit_var = zk::components::generate_circuit( - bp, assignment, {bit_var, times}, row) - .output; - row++; - c1_var = - zk::components::generate_circuit(bp, assignment, {bit_var, c1_var}, row) - .output; - row++; - bit_var = var(W1, row, false); - var bit_check_b = - zk::components::generate_circuit(bp, assignment, {one, bit_var}, row) - .output; - row++; - bit_check_b = zk::components::generate_circuit( - bp, assignment, {bit_var, bit_check_b}, row) - .output; - row++; - bit_var = zk::components::generate_circuit( - bp, assignment, {bit_var, times}, row) - .output; - row++; - b1_var = - zk::components::generate_circuit(bp, assignment, {bit_var, b1_var}, row) - .output; - row++; - times *= 2; - } + struct result_type { + var output; - var delta_b_var = - zk::components::generate_circuit(bp, assignment, {b_var, b1_var}, row) - .output; - row++; - var b1_inv_var = var(W1, row, false); - var inv_check_b1 = zk::components::generate_circuit( - bp, assignment, {delta_b_var, b1_inv_var}, row) - .output; - row++; - var inv_check_one = - zk::components::generate_circuit(bp, assignment, {one, inv_check_b1}, row) + result_type(std::size_t row) { + output = var(W2, static_cast(row), false, var::column_type::witness); + } + }; + + static result_type generate_circuit(blueprint &bp, + assignment &assignment, + const params_type ¶ms, + const std::size_t component_start_row) { + + generate_assignments_constants(bp, assignment, params, component_start_row); + + std::size_t row = component_start_row; + + var k = var(0, component_start_row, false, var::column_type::constant); + var power87 = var(0, component_start_row + 1, false, var::column_type::constant); + var zero = var(0, component_start_row + 2, false, var::column_type::constant); + var one = var(0, component_start_row + 3, false, var::column_type::constant); + + var c_var = ::nil::blueprint::components::generate_circuit( + bp, assignment, {zero, params.value}, row) + .output; + row++; + + var b_var = + ::nil::blueprint::components::generate_circuit(bp, assignment, {power87, k}, row) + .output; + row++; + b_var = + ::nil::blueprint::components::generate_circuit(bp, assignment, {b_var, one}, row) + .output; + row++; + b_var = ::nil::blueprint::components::generate_circuit( + bp, assignment, {b_var, c_var}, row) .output; + row++; + var c1_var = zero; + var b1_var = zero; + var bit_var; + typename BlueprintFieldType::value_type times = 1; + + for (int i = 0; i < 87; ++i) { + bit_var = var(W1, row, false); + var bit_check_c = ::nil::blueprint::components::generate_circuit( + bp, assignment, {one, bit_var}, row) + .output; row++; - var inv_check = zk::components::generate_circuit( - bp, assignment, {inv_check_one, delta_b_var}, row) - .output; + bit_check_c = ::nil::blueprint::components::generate_circuit( + bp, assignment, {bit_var, bit_check_c}, row) + .output; row++; - - var delta_c_var = - zk::components::generate_circuit(bp, assignment, {c_var, c1_var}, row) - .output; + bit_var = ::nil::blueprint::components::generate_circuit( + bp, assignment, {bit_var, times}, row) + .output; row++; - var c1_inv_var = var(W1, row, false); - var inv_check_c1 = zk::components::generate_circuit( - bp, assignment, {delta_c_var, c1_inv_var}, row) - .output; + c1_var = ::nil::blueprint::components::generate_circuit( + bp, assignment, {bit_var, c1_var}, row) + .output; row++; - inv_check_one = - zk::components::generate_circuit(bp, assignment, {one, inv_check_c1}, row) - .output; + bit_var = var(W1, row, false); + var bit_check_b = ::nil::blueprint::components::generate_circuit( + bp, assignment, {one, bit_var}, row) + .output; row++; - inv_check = zk::components::generate_circuit( - bp, assignment, {inv_check_one, delta_c_var}, row) - .output; + bit_check_b = ::nil::blueprint::components::generate_circuit( + bp, assignment, {bit_var, bit_check_b}, row) + .output; row++; - - var result_check_mul = zk::components::generate_circuit( - bp, assignment, {inv_check_c1, inv_check_b1}, row) - .output; + bit_var = ::nil::blueprint::components::generate_circuit( + bp, assignment, {bit_var, times}, row) + .output; row++; - var result_check_sum = zk::components::generate_circuit( - bp, assignment, {inv_check_c1, inv_check_b1}, row) - .output; + b1_var = ::nil::blueprint::components::generate_circuit( + bp, assignment, {bit_var, b1_var}, row) + .output; row++; - var result_check = zk::components::generate_circuit( - bp, assignment, {result_check_sum, result_check_mul}, row) - .output; - return result_type(row); + times *= 2; } - static result_type generate_assignments(blueprint_assignment_table &assignment, - const params_type ¶ms, - const std::size_t component_start_row) { - std::size_t row = component_start_row; - - var k = var(0, component_start_row, false, var::column_type::constant); - var power87 = var(0, component_start_row + 1, false, var::column_type::constant); - var zero = var(0, component_start_row + 2, false, var::column_type::constant); - var one = var(0, component_start_row + 3, false, var::column_type::constant); - - var c_var = sub_component::generate_assignments(assignment, {zero, params.value}, row).output; - row++; + var delta_b_var = ::nil::blueprint::components::generate_circuit( + bp, assignment, {b_var, b1_var}, row) + .output; + row++; + var b1_inv_var = var(W1, row, false); + var inv_check_b1 = ::nil::blueprint::components::generate_circuit( + bp, assignment, {delta_b_var, b1_inv_var}, row) + .output; + row++; + var inv_check_one = ::nil::blueprint::components::generate_circuit( + bp, assignment, {one, inv_check_b1}, row) + .output; + row++; + var inv_check = ::nil::blueprint::components::generate_circuit( + bp, assignment, {inv_check_one, delta_b_var}, row) + .output; + row++; - var b_var = sub_component::generate_assignments(assignment, {power87, k}, row).output; - row++; - b_var = sub_component::generate_assignments(assignment, {b_var, one}, row).output; - row++; - b_var = add_component::generate_assignments(assignment, {b_var, c_var}, row).output; - row++; + var delta_c_var = ::nil::blueprint::components::generate_circuit( + bp, assignment, {c_var, c1_var}, row) + .output; + row++; + var c1_inv_var = var(W1, row, false); + var inv_check_c1 = ::nil::blueprint::components::generate_circuit( + bp, assignment, {delta_c_var, c1_inv_var}, row) + .output; + row++; + inv_check_one = ::nil::blueprint::components::generate_circuit( + bp, assignment, {one, inv_check_c1}, row) + .output; + row++; + inv_check = ::nil::blueprint::components::generate_circuit( + bp, assignment, {inv_check_one, delta_c_var}, row) + .output; + row++; - auto b_for_bits = assignment.var_value(b_var).data; - auto c_for_bits = assignment.var_value(c_var).data; - typename BlueprintFieldType::value_type bit; - - typename BlueprintFieldType::value_type times = 1; - var c1_var = zero; - var b1_var = zero; - var bit_var; - - for (int i = 0; i < 87; ++i) { - bit.data = c_for_bits - (c_for_bits >> 1 << 1); - assignment.witness(W1)[row] = bit; - bit_var = var(W1, row, false); - var bit_check_c = - sub_component::generate_assignments(assignment, {one, bit_var}, row).output; - row++; - bit_check_c = - mul_component::generate_assignments(assignment, {bit_var, bit_check_c}, row).output; - row++; - c_for_bits = c_for_bits >> 1; - bit_var = - mul_by_const_component::generate_assignments(assignment, {bit_var, times}, row).output; - row++; - c1_var = add_component::generate_assignments(assignment, {bit_var, c1_var}, row).output; - row++; - - bit.data = b_for_bits - (b_for_bits >> 1 << 1); - assignment.witness(W1)[row] = bit; - bit_var = var(W1, row, false); - var bit_check_b = - sub_component::generate_assignments(assignment, {one, bit_var}, row).output; - row++; - bit_check_b = - mul_component::generate_assignments(assignment, {bit_var, bit_check_b}, row).output; - row++; - b_for_bits = b_for_bits >> 1; - bit_var = - mul_by_const_component::generate_assignments(assignment, {bit_var, times}, row).output; - row++; - b1_var = add_component::generate_assignments(assignment, {bit_var, b1_var}, row).output; - row++; - times *= 2; - } - - var delta_b_var = sub_component::generate_assignments(assignment, {b_var, b1_var}, row).output; + var result_check_mul = ::nil::blueprint::components::generate_circuit( + bp, assignment, {inv_check_c1, inv_check_b1}, row) + .output; + row++; + var result_check_sum = ::nil::blueprint::components::generate_circuit( + bp, assignment, {inv_check_c1, inv_check_b1}, row) + .output; + row++; + var result_check = ::nil::blueprint::components::generate_circuit( + bp, assignment, {result_check_sum, result_check_mul}, row) + .output; + return result_type(row); + } + + static result_type generate_assignments(assignment &assignment, + const params_type ¶ms, + const std::size_t component_start_row) { + std::size_t row = component_start_row; + + var k = var(0, component_start_row, false, var::column_type::constant); + var power87 = var(0, component_start_row + 1, false, var::column_type::constant); + var zero = var(0, component_start_row + 2, false, var::column_type::constant); + var one = var(0, component_start_row + 3, false, var::column_type::constant); + + var c_var = sub_component::generate_assignments(assignment, {zero, params.value}, row).output; + row++; + + var b_var = sub_component::generate_assignments(assignment, {power87, k}, row).output; + row++; + b_var = sub_component::generate_assignments(assignment, {b_var, one}, row).output; + row++; + b_var = add_component::generate_assignments(assignment, {b_var, c_var}, row).output; + row++; + + auto b_for_bits = assignment.var_value(b_var).data; + auto c_for_bits = assignment.var_value(c_var).data; + typename BlueprintFieldType::value_type bit; + + typename BlueprintFieldType::value_type times = 1; + var c1_var = zero; + var b1_var = zero; + var bit_var; + + for (int i = 0; i < 87; ++i) { + bit.data = c_for_bits - (c_for_bits >> 1 << 1); + assignment.witness(W1)[row] = bit; + bit_var = var(W1, row, false); + var bit_check_c = sub_component::generate_assignments(assignment, {one, bit_var}, row).output; row++; - typename BlueprintFieldType::value_type b1_inv; - if (assignment.var_value(delta_b_var) != 0) { - b1_inv = assignment.var_value(delta_b_var).inversed(); - } else { - b1_inv = 0; - } - assignment.witness(W1)[row] = b1_inv; - var b1_inv_var = var(W1, row, false); - var inv_check_b1 = - mul_component::generate_assignments(assignment, {delta_b_var, b1_inv_var}, row).output; + bit_check_c = + mul_component::generate_assignments(assignment, {bit_var, bit_check_c}, row).output; row++; - var inv_check_one = - sub_component::generate_assignments(assignment, {one, inv_check_b1}, row).output; + c_for_bits = c_for_bits >> 1; + bit_var = + mul_by_const_component::generate_assignments(assignment, {bit_var, times}, row).output; row++; - var inv_check = - mul_component::generate_assignments(assignment, {inv_check_one, delta_b_var}, row).output; + c1_var = add_component::generate_assignments(assignment, {bit_var, c1_var}, row).output; row++; - var delta_c_var = sub_component::generate_assignments(assignment, {c_var, c1_var}, row).output; - row++; - typename BlueprintFieldType::value_type c1_inv; - if (assignment.var_value(delta_c_var) != 0) { - c1_inv = assignment.var_value(delta_c_var).inversed(); - } else { - c1_inv = 0; - } - assignment.witness(W1)[row] = c1_inv; - var c1_inv_var = var(W1, row, false); - var inv_check_c1 = - mul_component::generate_assignments(assignment, {delta_c_var, c1_inv_var}, row).output; - row++; - inv_check_one = - sub_component::generate_assignments(assignment, {one, inv_check_c1}, row).output; + bit.data = b_for_bits - (b_for_bits >> 1 << 1); + assignment.witness(W1)[row] = bit; + bit_var = var(W1, row, false); + var bit_check_b = sub_component::generate_assignments(assignment, {one, bit_var}, row).output; row++; - inv_check = - mul_component::generate_assignments(assignment, {inv_check_one, delta_c_var}, row).output; + bit_check_b = + mul_component::generate_assignments(assignment, {bit_var, bit_check_b}, row).output; row++; - - var result_check_mul = - mul_component::generate_assignments(assignment, {inv_check_c1, inv_check_b1}, row).output; + b_for_bits = b_for_bits >> 1; + bit_var = + mul_by_const_component::generate_assignments(assignment, {bit_var, times}, row).output; row++; - var result_check_sum = - add_component::generate_assignments(assignment, {inv_check_c1, inv_check_b1}, row).output; + b1_var = add_component::generate_assignments(assignment, {bit_var, b1_var}, row).output; row++; - var result_check = - sub_component::generate_assignments(assignment, {result_check_sum, result_check_mul}, row) - .output; - return result_type(row); + times *= 2; } - private: - static void generate_gates(blueprint &bp, - blueprint_public_assignment_table &assignment, - const params_type ¶ms, - const std::size_t first_selector_index) { + var delta_b_var = sub_component::generate_assignments(assignment, {b_var, b1_var}, row).output; + row++; + typename BlueprintFieldType::value_type b1_inv; + if (assignment.var_value(delta_b_var) != 0) { + b1_inv = assignment.var_value(delta_b_var).inversed(); + } else { + b1_inv = 0; } - - static void - generate_copy_constraints(blueprint &bp, - blueprint_public_assignment_table &assignment, - const params_type ¶ms, - std::size_t component_start_row = 0) { - - var zero = var(0, component_start_row + 2, false, var::column_type::constant); - - std::size_t row = component_start_row + 5; - var bit_check; - for (int i = 0; i < 87; ++i) { - bit_check = typename mul_component::result_type(row).output; - bp.add_copy_constraint({bit_check, zero}); - row += 4; - bit_check = typename mul_component::result_type(row).output; - bp.add_copy_constraint({bit_check, zero}); - row += 4; - } - row += 2; - var inv_check = typename mul_component::result_type(row).output; - bp.add_copy_constraint({inv_check, zero}); - row += 4; - inv_check = typename mul_component::result_type(row).output; - bp.add_copy_constraint({inv_check, zero}); + assignment.witness(W1)[row] = b1_inv; + var b1_inv_var = var(W1, row, false); + var inv_check_b1 = + mul_component::generate_assignments(assignment, {delta_b_var, b1_inv_var}, row).output; + row++; + var inv_check_one = + sub_component::generate_assignments(assignment, {one, inv_check_b1}, row).output; + row++; + var inv_check = + mul_component::generate_assignments(assignment, {inv_check_one, delta_b_var}, row).output; + row++; + + var delta_c_var = sub_component::generate_assignments(assignment, {c_var, c1_var}, row).output; + row++; + typename BlueprintFieldType::value_type c1_inv; + if (assignment.var_value(delta_c_var) != 0) { + c1_inv = assignment.var_value(delta_c_var).inversed(); + } else { + c1_inv = 0; } - - static void generate_assignments_constants( - blueprint &bp, - blueprint_public_assignment_table &assignment, - const params_type ¶ms, - const std::size_t component_start_row) { - std::size_t row = component_start_row; - typename BlueprintFieldType::value_type base = 2; - assignment.constant(0)[row] = - 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001_cppui255 - - 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000001_cppui255; - row++; - assignment.constant(0)[row] = base.pow(87); - row++; - assignment.constant(0)[row] = 0; - row++; - assignment.constant(0)[row] = 1; + assignment.witness(W1)[row] = c1_inv; + var c1_inv_var = var(W1, row, false); + var inv_check_c1 = + mul_component::generate_assignments(assignment, {delta_c_var, c1_inv_var}, row).output; + row++; + inv_check_one = sub_component::generate_assignments(assignment, {one, inv_check_c1}, row).output; + row++; + inv_check = + mul_component::generate_assignments(assignment, {inv_check_one, delta_c_var}, row).output; + row++; + + var result_check_mul = + mul_component::generate_assignments(assignment, {inv_check_c1, inv_check_b1}, row).output; + row++; + var result_check_sum = + add_component::generate_assignments(assignment, {inv_check_c1, inv_check_b1}, row).output; + row++; + var result_check = + sub_component::generate_assignments(assignment, {result_check_sum, result_check_mul}, row) + .output; + return result_type(row); + } + + private: + static void generate_gates(blueprint &bp, + assignment &assignment, + const params_type ¶ms, + const std::size_t first_selector_index) { + } + + static void generate_copy_constraints(blueprint &bp, + assignment &assignment, + const params_type ¶ms, + std::size_t component_start_row = 0) { + + var zero = var(0, component_start_row + 2, false, var::column_type::constant); + + std::size_t row = component_start_row + 5; + var bit_check; + for (int i = 0; i < 87; ++i) { + bit_check = typename mul_component::result_type(row).output; + bp.add_copy_constraint({bit_check, zero}); + row += 4; + bit_check = typename mul_component::result_type(row).output; + bp.add_copy_constraint({bit_check, zero}); + row += 4; } - }; - - } // namespace components - } // namespace blueprint - } // namespace crypto3 + row += 2; + var inv_check = typename mul_component::result_type(row).output; + bp.add_copy_constraint({inv_check, zero}); + row += 4; + inv_check = typename mul_component::result_type(row).output; + bp.add_copy_constraint({inv_check, zero}); + } + + static void generate_assignments_constants(blueprint &bp, + assignment &assignment, + const params_type ¶ms, + const std::size_t component_start_row) { + std::size_t row = component_start_row; + typename BlueprintFieldType::value_type base = 2; + assignment.constant(0)[row] = + 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001_cppui255 - + 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000001_cppui255; + row++; + assignment.constant(0)[row] = base.pow(87); + row++; + assignment.constant(0)[row] = 0; + row++; + assignment.constant(0)[row] = 1; + } + }; + + } // namespace components + } // namespace blueprint } // namespace nil #endif // CRYPTO3_BLUEPRINT_COMPONENTS_PLONK_CURVE_ELEMENT_ORACLES_DETAIL_COMPONENT_15_WIRES_HPP diff --git a/include/nil/blueprint/components/systems/snark/plonk/kimchi/detail/constraints/generic_scalars.hpp b/include/nil/blueprint/components/systems/snark/plonk/kimchi/detail/constraints/generic_scalars.hpp index ec6e66575..d2f6b5e08 100644 --- a/include/nil/blueprint/components/systems/snark/plonk/kimchi/detail/constraints/generic_scalars.hpp +++ b/include/nil/blueprint/components/systems/snark/plonk/kimchi/detail/constraints/generic_scalars.hpp @@ -35,209 +35,230 @@ #include #include -#include -#include +#include +#include namespace nil { - namespace crypto3 { - namespace blueprint { - namespace components { - - // generic constraint scalars - // https://github.com/o1-labs/proof-systems/blob/1f8532ec1b8d43748a372632bd854be36b371afe/kimchi/src/circuits/polynomials/generic.rs#L242 - // Input: - // Output: generic-gate-related scalar x for linearization - template - class generic_scalars; - - template - class generic_scalars, - KimchiParamsType, W0, W1, W2, W3, W4, W5, W6, W7, W8, W9, W10, W11, W12, W13, - W14> { - - typedef snark::plonk_constraint_system - ArithmetizationType; - - using var = snark::plonk_variable; - - using mul_component = zk::components::multiplication; - - constexpr static const std::size_t selector_seed = 0x0f26; - - constexpr static const std::size_t generic_registers = 3; - - public: - constexpr static const std::size_t rows_amount = 12 * mul_component::rows_amount; - constexpr static const std::size_t gates_amount = 0; - - constexpr static const std::size_t output_size = 10; - - struct params_type { - std::array, - KimchiParamsType::eval_points_amount> - evals; - std::array alphas; - std::size_t start_idx; - }; - - struct result_type { - std::array output; - - result_type(std::size_t start_row_index) { - std::size_t row = start_row_index; - - constexpr std::size_t parts = 2; - - for (std::size_t i = 0; i < parts; i++) { - var alpha_generic = typename mul_component::result_type(row).output; - row += mul_component::rows_amount; - - // addition part - // alpha_generic * w_zeta[register_offset + j] - for (std::size_t j = 0; j < 3; j++) { - output[5 * i + j] = typename mul_component::result_type(row).output; - row += mul_component::rows_amount; - } - - // multiplication - var tmp = typename mul_component::result_type(row).output; - row += mul_component::rows_amount; - output[5 * i + 3] = typename mul_component::result_type(row).output; - row += mul_component::rows_amount; - - // constant - output[5 * i + 4] = alpha_generic; - } - } - }; + namespace blueprint { + namespace components { + + // generic constraint scalars + // https://github.com/o1-labs/proof-systems/blob/1f8532ec1b8d43748a372632bd854be36b371afe/kimchi/src/circuits/polynomials/generic.rs#L242 + // Input: + // Output: generic-gate-related scalar x for linearization + template + class generic_scalars; + + template + class generic_scalars, + KimchiParamsType, + W0, + W1, + W2, + W3, + W4, + W5, + W6, + W7, + W8, + W9, + W10, + W11, + W12, + W13, + W14> { + + typedef crypto3::zk::snark::plonk_constraint_system ArithmetizationType; + + using var = crypto3::zk::snark::plonk_variable; + + using mul_component = multiplication>; + + constexpr static const std::size_t selector_seed = 0x0f26; + + constexpr static const std::size_t generic_registers = 3; + + public: + constexpr static const std::size_t rows_amount = 12 * mul_component::rows_amount; + constexpr static const std::size_t gates_amount = 0; + + constexpr static const std::size_t output_size = 10; + + struct params_type { + std::array, + KimchiParamsType::eval_points_amount> + evals; + std::array alphas; + std::size_t start_idx; + }; - static result_type - generate_circuit(blueprint &bp, - blueprint_public_assignment_table &assignment, - const params_type ¶ms, - const std::size_t start_row_index) { + struct result_type { + std::array output; + result_type(std::size_t start_row_index) { std::size_t row = start_row_index; - std::array output; constexpr std::size_t parts = 2; - std::array alpha_pows = { - params.alphas[params.start_idx], - params.alphas[params.start_idx + 1], - }; - std::array offsets = {0, generic_registers}; - for (std::size_t i = 0; i < parts; i++) { - var alpha_generic = - zk::components::generate_circuit( - bp, assignment, {alpha_pows[i], params.evals[0].generic_selector}, row) - .output; + var alpha_generic = typename mul_component::result_type(row).output; row += mul_component::rows_amount; // addition part // alpha_generic * w_zeta[register_offset + j] for (std::size_t j = 0; j < 3; j++) { - output[5 * i + j] = - zk::components::generate_circuit( - bp, assignment, {alpha_generic, params.evals[0].w[offsets[i] + j]}, row) - .output; + output[5 * i + j] = typename mul_component::result_type(row).output; row += mul_component::rows_amount; } // multiplication - var tmp = zk::components::generate_circuit( - bp, assignment, - {params.evals[0].w[offsets[i]], params.evals[0].w[offsets[i] + 1]}, row) - .output; + var tmp = typename mul_component::result_type(row).output; row += mul_component::rows_amount; - output[5 * i + 3] = zk::components::generate_circuit( - bp, assignment, {alpha_generic, tmp}, row) - .output; + output[5 * i + 3] = typename mul_component::result_type(row).output; row += mul_component::rows_amount; // constant output[5 * i + 4] = alpha_generic; } - - generate_copy_constraints(bp, assignment, params, start_row_index); - return result_type(start_row_index); } + }; - static result_type generate_assignments(blueprint_assignment_table &assignment, - const params_type ¶ms, - const std::size_t start_row_index) { - std::size_t row = start_row_index; - std::array output; - - constexpr std::size_t parts = 2; + static result_type generate_circuit(blueprint &bp, + assignment &assignment, + const params_type ¶ms, + const std::size_t start_row_index) { - std::array alpha_pows = { - params.alphas[params.start_idx], - params.alphas[params.start_idx + 1], - }; - std::array offsets = {0, generic_registers}; + std::size_t row = start_row_index; + std::array output; - for (std::size_t i = 0; i < parts; i++) { - var alpha_generic = mul_component::generate_assignments( - assignment, {alpha_pows[i], params.evals[0].generic_selector}, row) - .output; - row += mul_component::rows_amount; + constexpr std::size_t parts = 2; - // addition part - // alpha_generic * w_zeta[register_offset + j] - for (std::size_t j = 0; j < 3; j++) { - output[5 * i + j] = - mul_component::generate_assignments( - assignment, {alpha_generic, params.evals[0].w[offsets[i] + j]}, row) - .output; - row += mul_component::rows_amount; - } - - // multiplication - var tmp = - mul_component::generate_assignments( - assignment, {params.evals[0].w[offsets[i]], params.evals[0].w[offsets[i] + 1]}, row) + std::array alpha_pows = { + params.alphas[params.start_idx], + params.alphas[params.start_idx + 1], + }; + std::array offsets = {0, generic_registers}; + + for (std::size_t i = 0; i < parts; i++) { + var alpha_generic = ::nil::blueprint::components::generate_circuit( + bp, assignment, {alpha_pows[i], params.evals[0].generic_selector}, row) + .output; + row += mul_component::rows_amount; + + // addition part + // alpha_generic * w_zeta[register_offset + j] + for (std::size_t j = 0; j < 3; j++) { + output[5 * i + j] = + ::nil::blueprint::components::generate_circuit( + bp, assignment, {alpha_generic, params.evals[0].w[offsets[i] + j]}, row) .output; row += mul_component::rows_amount; - output[5 * i + 3] = - mul_component::generate_assignments(assignment, {alpha_generic, tmp}, row).output; - row += mul_component::rows_amount; - - // constant - output[5 * i + 4] = alpha_generic; } - return result_type(start_row_index); + // multiplication + var tmp = + ::nil::blueprint::components::generate_circuit( + bp, assignment, {params.evals[0].w[offsets[i]], params.evals[0].w[offsets[i] + 1]}, row) + .output; + row += mul_component::rows_amount; + output[5 * i + 3] = ::nil::blueprint::components::generate_circuit( + bp, assignment, {alpha_generic, tmp}, row) + .output; + row += mul_component::rows_amount; + + // constant + output[5 * i + 4] = alpha_generic; } - private: - static void generate_gates(blueprint &bp, - blueprint_public_assignment_table &assignment, - const params_type ¶ms, - const std::size_t first_selector_index) { - } + generate_copy_constraints(bp, assignment, params, start_row_index); + return result_type(start_row_index); + } - static void - generate_copy_constraints(blueprint &bp, - blueprint_public_assignment_table &assignment, - const params_type ¶ms, - const std::size_t start_row_index) { - } + static result_type generate_assignments(assignment &assignment, + const params_type ¶ms, + const std::size_t start_row_index) { + std::size_t row = start_row_index; + std::array output; + + constexpr std::size_t parts = 2; - static void generate_assignments_constants( - blueprint &bp, - blueprint_public_assignment_table &assignment, - const params_type ¶ms, - const std::size_t start_row_index) { + std::array alpha_pows = { + params.alphas[params.start_idx], + params.alphas[params.start_idx + 1], + }; + std::array offsets = {0, generic_registers}; + + for (std::size_t i = 0; i < parts; i++) { + var alpha_generic = mul_component::generate_assignments( + assignment, {alpha_pows[i], params.evals[0].generic_selector}, row) + .output; + row += mul_component::rows_amount; + + // addition part + // alpha_generic * w_zeta[register_offset + j] + for (std::size_t j = 0; j < 3; j++) { + output[5 * i + j] = mul_component::generate_assignments( + assignment, {alpha_generic, params.evals[0].w[offsets[i] + j]}, row) + .output; + row += mul_component::rows_amount; + } + + // multiplication + var tmp = + mul_component::generate_assignments( + assignment, {params.evals[0].w[offsets[i]], params.evals[0].w[offsets[i] + 1]}, row) + .output; + row += mul_component::rows_amount; + output[5 * i + 3] = + mul_component::generate_assignments(assignment, {alpha_generic, tmp}, row).output; + row += mul_component::rows_amount; + + // constant + output[5 * i + 4] = alpha_generic; } - }; - } // namespace components - } // namespace blueprint - } // namespace crypto3 + + return result_type(start_row_index); + } + + private: + static void generate_gates(blueprint &bp, + assignment &assignment, + const params_type ¶ms, + const std::size_t first_selector_index) { + } + + static void generate_copy_constraints(blueprint &bp, + assignment &assignment, + const params_type ¶ms, + const std::size_t start_row_index) { + } + + static void generate_assignments_constants(blueprint &bp, + assignment &assignment, + const params_type ¶ms, + const std::size_t start_row_index) { + } + }; + } // namespace components + } // namespace blueprint } // namespace nil #endif // CRYPTO3_BLUEPRINT_COMPONENTS_PLONK_KIMCHI_DETAIL_GENERIC_SCALARS_HPP \ No newline at end of file diff --git a/include/nil/blueprint/components/systems/snark/plonk/kimchi/detail/constraints/index_terms_scalars.hpp b/include/nil/blueprint/components/systems/snark/plonk/kimchi/detail/constraints/index_terms_scalars.hpp index a3a51dca8..773860b2f 100644 --- a/include/nil/blueprint/components/systems/snark/plonk/kimchi/detail/constraints/index_terms_scalars.hpp +++ b/include/nil/blueprint/components/systems/snark/plonk/kimchi/detail/constraints/index_terms_scalars.hpp @@ -34,198 +34,222 @@ #include -#include -#include +#include +#include +#include namespace nil { - namespace crypto3 { - namespace blueprint { - namespace components { - - template - constexpr void constexpr_for(F &&f) { - if constexpr (Start < End) { - f(std::integral_constant()); - constexpr_for(f); - } + namespace blueprint { + namespace components { + + template + constexpr void constexpr_for(F &&f) { + if constexpr (Start < End) { + f(std::integral_constant()); + constexpr_for(f); } + } + + // constraints scalars (exluding generic constraint) + // https://github.com/o1-labs/proof-systems/blob/1f8532ec1b8d43748a372632bd854be36b371afe/kimchi/src/verifier.rs#L568-L673 + // Input: constraint + // Output: constraint-related scalar x for linearization + template + class index_terms_scalars; + + template + class index_terms_scalars, + KimchiParamsType, + W0, + W1, + W2, + W3, + W4, + W5, + W6, + W7, + W8, + W9, + W10, + W11, + W12, + W13, + W14> { + + typedef crypto3::zk::snark::plonk_constraint_system ArithmetizationType; + + using var = crypto3::zk::snark::plonk_variable; + + using mul_component = multiplication>; + using add_component = + addition>; + + using evaluations_type = kimchi_proof_evaluations; + + constexpr static const std::size_t selector_seed = 0x0f27; + + using index_terms_list = typename KimchiParamsType::circuit_params::index_terms_list; + + constexpr static std::size_t rows() { + std::size_t n = 0; + + for (std::size_t i = 0; i < index_terms_list::size; i++) { + n += index_terms_list::terms[i].rows_amount; + } - // constraints scalars (exluding generic constraint) - // https://github.com/o1-labs/proof-systems/blob/1f8532ec1b8d43748a372632bd854be36b371afe/kimchi/src/verifier.rs#L568-L673 - // Input: constraint - // Output: constraint-related scalar x for linearization - template - class index_terms_scalars; - - template - class index_terms_scalars, - KimchiParamsType, W0, W1, W2, W3, - W4, W5, W6, W7, W8, W9, W10, W11, W12, W13, W14> { - - typedef snark::plonk_constraint_system - ArithmetizationType; - - using var = snark::plonk_variable; - - using mul_component = zk::components::multiplication; - using add_component = zk::components::addition; + return n; + } - using evaluations_type = - typename zk::components::kimchi_proof_evaluations; + public: + constexpr static const std::size_t rows_amount = rows(); + constexpr static const std::size_t gates_amount = 0; - constexpr static const std::size_t selector_seed = 0x0f27; + struct params_type { + var eval_point; // zeta - using index_terms_list = typename KimchiParamsType::circuit_params::index_terms_list; + var alpha; + var beta; + var gamma; + var joint_combiner; - constexpr static std::size_t rows() { - std::size_t n = 0; + std::array evaluations; - for (std::size_t i = 0; i < index_terms_list::size; i++) { - n += index_terms_list::terms[i].rows_amount; - } + var group_gen; + std::size_t domain_size; + }; - return n; - } + struct result_type { + std::array output; - public: - constexpr static const std::size_t rows_amount = rows(); - constexpr static const std::size_t gates_amount = 0; - - struct params_type { - var eval_point; // zeta - - var alpha; - var beta; - var gamma; - var joint_combiner; - - std::array evaluations; - - var group_gen; - std::size_t domain_size; - }; - - struct result_type { - std::array output; - - result_type(std::size_t start_row_index) { - } - - result_type() { - } - }; - - static result_type - generate_circuit(blueprint &bp, - blueprint_public_assignment_table &assignment, - const params_type ¶ms, - const std::size_t start_row_index) { - - std::size_t row = start_row_index; - - std::array output; - - std::size_t output_idx = 0; - - constexpr static const std::size_t end = index_terms_list::size; - - constexpr_for<0, end, 1>([&row, &output_idx, &output, ¶ms, &bp, &assignment](auto i) { - using component_type = - zk::components::rpn_expression; - output[output_idx++] = component_type::generate_circuit( - bp, - assignment, - {index_terms_list::terms[i].str_repr, params.eval_point, - params.alpha, params.beta, params.gamma, params.joint_combiner, - params.evaluations, params.group_gen, params.domain_size}, - row) - .output; - row += component_type::rows_amount; - }); - - assert(output_idx == KimchiParamsType::index_term_size()); - assert(row == start_row_index + rows_amount); - - result_type res; - res.output = output; - - return res; + result_type(std::size_t start_row_index) { } - static result_type generate_assignments(blueprint_assignment_table &assignment, - const params_type ¶ms, - const std::size_t start_row_index) { - - std::size_t row = start_row_index; - - std::array output; - - std::size_t output_idx = 0; - - constexpr static const std::size_t end = index_terms_list::size; - constexpr_for<0, end, 1>([&row, &output_idx, &output, ¶ms, &assignment](auto i) { - using component_type = - zk::components::rpn_expression; - output[output_idx++] = component_type::generate_assignments( - assignment, - {index_terms_list::terms[i].str_repr, params.eval_point, - params.alpha, params.beta, params.gamma, params.joint_combiner, - params.evaluations, params.group_gen, params.domain_size}, - row) - .output; - row += component_type::rows_amount; - }); - - assert(output_idx == KimchiParamsType::index_term_size()); - assert(row == start_row_index + rows_amount); - - result_type res; - res.output = output; - - return res; + result_type() { } }; - } // namespace components - } // namespace blueprint - } // namespace crypto3 + + static result_type generate_circuit(blueprint &bp, + assignment &assignment, + const params_type ¶ms, + const std::size_t start_row_index) { + + std::size_t row = start_row_index; + + std::array output; + + std::size_t output_idx = 0; + + constexpr static const std::size_t end = index_terms_list::size; + + constexpr_for<0, end, 1>([&row, &output_idx, &output, ¶ms, &bp, &assignment](auto i) { + using component_type = rpn_expression; + output[output_idx++] = component_type::generate_circuit( + bp, + assignment, + {index_terms_list::terms[i].str_repr, params.eval_point, + params.alpha, params.beta, params.gamma, params.joint_combiner, + params.evaluations, params.group_gen, params.domain_size}, + row) + .output; + row += component_type::rows_amount; + }); + + assert(output_idx == KimchiParamsType::index_term_size()); + assert(row == start_row_index + rows_amount); + + result_type res; + res.output = output; + + return res; + } + + static result_type generate_assignments(assignment &assignment, + const params_type ¶ms, + const std::size_t start_row_index) { + + std::size_t row = start_row_index; + + std::array output; + + std::size_t output_idx = 0; + + constexpr static const std::size_t end = index_terms_list::size; + constexpr_for<0, end, 1>([&row, &output_idx, &output, ¶ms, &assignment](auto i) { + using component_type = rpn_expression; + output[output_idx++] = component_type::generate_assignments( + assignment, + {index_terms_list::terms[i].str_repr, params.eval_point, + params.alpha, params.beta, params.gamma, params.joint_combiner, + params.evaluations, params.group_gen, params.domain_size}, + row) + .output; + row += component_type::rows_amount; + }); + + assert(output_idx == KimchiParamsType::index_term_size()); + assert(row == start_row_index + rows_amount); + + result_type res; + res.output = output; + + return res; + } + }; + } // namespace components + } // namespace blueprint } // namespace nil #endif // CRYPTO3_BLUEPRINT_COMPONENTS_PLONK_KIMCHI_DETAIL_INDEX_TERMS_SCALARS_HPP \ No newline at end of file diff --git a/include/nil/blueprint/components/systems/snark/plonk/kimchi/detail/constraints/perm_scalars.hpp b/include/nil/blueprint/components/systems/snark/plonk/kimchi/detail/constraints/perm_scalars.hpp index 758f3d0a7..187bfcd70 100644 --- a/include/nil/blueprint/components/systems/snark/plonk/kimchi/detail/constraints/perm_scalars.hpp +++ b/include/nil/blueprint/components/systems/snark/plonk/kimchi/detail/constraints/perm_scalars.hpp @@ -34,162 +34,194 @@ #include -#include -#include +#include +#include +#include +#include +#include namespace nil { - namespace crypto3 { - namespace blueprint { - namespace components { - - // permutation argument scalars - // https://github.com/o1-labs/proof-systems/blob/1f8532ec1b8d43748a372632bd854be36b371afe/kimchi/src/circuits/polynomials/permutation.rs#L325 - // Input: - // Output: permutation-related scalar x for linearization - template - class perm_scalars; - - template - class perm_scalars, - KimchiParamsType, W0, W1, W2, W3, W4, W5, W6, W7, W8, W9, W10, W11, W12, W13, W14> { - - typedef snark::plonk_constraint_system - ArithmetizationType; - - using var = snark::plonk_variable; - - using mul_component = zk::components::multiplication; - using mul_const_component = zk::components::mul_by_constant; - using add_component = zk::components::addition; - - constexpr static const std::size_t selector_seed = 0x0f2E; - - constexpr static const std::size_t scalar_rows = KimchiParamsType::permut_size - 1; - - public: - constexpr static const std::size_t rows_amount = - 3 * mul_component::rows_amount + - scalar_rows * (2 * mul_component::rows_amount + 2 * add_component::rows_amount) + - mul_const_component::rows_amount; - constexpr static const std::size_t gates_amount = 0; - - struct params_type { - std::array, - KimchiParamsType::eval_points_amount> - evals; - std::array alphas; - std::size_t start_idx; - - var beta; - var gamma; - var zkp_zeta; - }; - - struct result_type { - var output; - - result_type(std::size_t start_row_index) { - output = {var(W1, start_row_index + rows_amount - 1, false)}; - } - }; - - static result_type - generate_circuit(blueprint &bp, - blueprint_public_assignment_table &assignment, - const params_type ¶ms, - const std::size_t start_row_index) { - - std::size_t row = start_row_index; - std::array w; - for (std::size_t i = 0; i < KimchiParamsType::witness_columns; i++) { - w[i] = params.evals[0].w[i]; - } - std::array s; - for (std::size_t i = 0; i < KimchiParamsType::permut_size - 1; i++) { - s[i] = params.evals[0].s[i]; - } - var z = params.evals[1].z; - std::size_t size = KimchiParamsType::permut_size - 1; - - zk::components::generate_circuit(bp, assignment, {z, params.beta}, row); - auto res = typename mul_component::result_type({z, params.beta}, row); - row += mul_component::rows_amount; - zk::components::generate_circuit( - bp, assignment, {res.output, params.alphas[params.start_idx]}, row); - res = typename mul_component::result_type({res.output, params.alphas[params.start_idx]}, row); - row += mul_component::rows_amount; - zk::components::generate_circuit( - bp, assignment, {res.output, params.zkp_zeta}, row); - res = typename mul_component::result_type({res.output, params.zkp_zeta}, row); - row += mul_component::rows_amount; + namespace blueprint { + namespace components { + + // permutation argument scalars + // https://github.com/o1-labs/proof-systems/blob/1f8532ec1b8d43748a372632bd854be36b371afe/kimchi/src/circuits/polynomials/permutation.rs#L325 + // Input: + // Output: permutation-related scalar x for linearization + template + class perm_scalars; + + template + class perm_scalars, + KimchiParamsType, + W0, + W1, + W2, + W3, + W4, + W5, + W6, + W7, + W8, + W9, + W10, + W11, + W12, + W13, + W14> { + + typedef crypto3::zk::snark::plonk_constraint_system ArithmetizationType; + + using var = crypto3::zk::snark::plonk_variable; + + using mul_component = multiplication>; + using mul_const_component = mul_by_constant; + using add_component = + addition>; + + constexpr static const std::size_t selector_seed = 0x0f2E; + + constexpr static const std::size_t scalar_rows = KimchiParamsType::permut_size - 1; + + public: + constexpr static const std::size_t rows_amount = + 3 * mul_component::rows_amount + + scalar_rows * (2 * mul_component::rows_amount + 2 * add_component::rows_amount) + + mul_const_component::rows_amount; + constexpr static const std::size_t gates_amount = 0; + + struct params_type { + std::array, + KimchiParamsType::eval_points_amount> + evals; + std::array alphas; + std::size_t start_idx; + + var beta; + var gamma; + var zkp_zeta; + }; - for (std::size_t i = 0; i < size; i++) { - zk::components::generate_circuit(bp, assignment, {s[i], params.beta}, row); - auto tmp = typename mul_component::result_type({s[i], params.beta}, row); - row += mul_component::rows_amount; - zk::components::generate_circuit( - bp, assignment, {tmp.output, params.gamma}, row); - auto add_tmp = typename add_component::result_type({tmp.output, params.gamma}, row); - row += add_component::rows_amount; - zk::components::generate_circuit( - bp, assignment, {add_tmp.output, w[i]}, row); - add_tmp = typename add_component::result_type({add_tmp.output, w[i]}, row); - row += add_component::rows_amount; - zk::components::generate_circuit( - bp, assignment, {add_tmp.output, res.output}, row); - res = typename mul_component::result_type({add_tmp.output, res.output}, row); - row += mul_component::rows_amount; - } - zk::components::generate_circuit(bp, assignment, {res.output, -1}, row); - auto const_res = typename mul_const_component::result_type({res.output, -1}, row); - return result_type(start_row_index); + struct result_type { + var output; + + result_type(std::size_t start_row_index) { + output = {var(W1, start_row_index + rows_amount - 1, false)}; } + }; + + static result_type generate_circuit(blueprint &bp, + assignment &assignment, + const params_type ¶ms, + const std::size_t start_row_index) { - static result_type generate_assignments(blueprint_assignment_table &assignment, - const params_type ¶ms, - const std::size_t start_row_index) { - - std::size_t row = start_row_index; - std::array w; - for (std::size_t i = 0; i < KimchiParamsType::witness_columns; i++) { - w[i] = params.evals[0].w[i]; - } - std::array s; - for (std::size_t i = 0; i < KimchiParamsType::permut_size - 1; i++) { - s[i] = params.evals[0].s[i]; - } - var z = params.evals[1].z; - std::size_t size = KimchiParamsType::permut_size - 1; - - auto res = mul_component::generate_assignments(assignment, {z, params.beta}, row); + std::size_t row = start_row_index; + std::array w; + for (std::size_t i = 0; i < KimchiParamsType::witness_columns; i++) { + w[i] = params.evals[0].w[i]; + } + std::array s; + for (std::size_t i = 0; i < KimchiParamsType::permut_size - 1; i++) { + s[i] = params.evals[0].s[i]; + } + var z = params.evals[1].z; + std::size_t size = KimchiParamsType::permut_size - 1; + + ::nil::blueprint::components::generate_circuit( + bp, assignment, {z, params.beta}, row); + auto res = typename mul_component::result_type({z, params.beta}, row); + row += mul_component::rows_amount; + ::nil::blueprint::components::generate_circuit( + bp, assignment, {res.output, params.alphas[params.start_idx]}, row); + res = typename mul_component::result_type({res.output, params.alphas[params.start_idx]}, row); + row += mul_component::rows_amount; + ::nil::blueprint::components::generate_circuit( + bp, assignment, {res.output, params.zkp_zeta}, row); + res = typename mul_component::result_type({res.output, params.zkp_zeta}, row); + row += mul_component::rows_amount; + + for (std::size_t i = 0; i < size; i++) { + ::nil::blueprint::components::generate_circuit( + bp, assignment, {s[i], params.beta}, row); + auto tmp = typename mul_component::result_type({s[i], params.beta}, row); row += mul_component::rows_amount; - res = mul_component::generate_assignments( - assignment, {res.output, params.alphas[params.start_idx]}, row); + ::nil::blueprint::components::generate_circuit( + bp, assignment, {tmp.output, params.gamma}, row); + auto add_tmp = typename add_component::result_type({tmp.output, params.gamma}, row); + row += add_component::rows_amount; + ::nil::blueprint::components::generate_circuit( + bp, assignment, {add_tmp.output, w[i]}, row); + add_tmp = typename add_component::result_type({add_tmp.output, w[i]}, row); + row += add_component::rows_amount; + ::nil::blueprint::components::generate_circuit( + bp, assignment, {add_tmp.output, res.output}, row); + res = typename mul_component::result_type({add_tmp.output, res.output}, row); row += mul_component::rows_amount; - res = mul_component::generate_assignments(assignment, {res.output, params.zkp_zeta}, row); + } + ::nil::blueprint::components::generate_circuit( + bp, assignment, {res.output, -1}, row); + auto const_res = typename mul_const_component::result_type({res.output, -1}, row); + return result_type(start_row_index); + } + + static result_type generate_assignments(assignment &assignment, + const params_type ¶ms, + const std::size_t start_row_index) { + + std::size_t row = start_row_index; + std::array w; + for (std::size_t i = 0; i < KimchiParamsType::witness_columns; i++) { + w[i] = params.evals[0].w[i]; + } + std::array s; + for (std::size_t i = 0; i < KimchiParamsType::permut_size - 1; i++) { + s[i] = params.evals[0].s[i]; + } + var z = params.evals[1].z; + std::size_t size = KimchiParamsType::permut_size - 1; + + auto res = mul_component::generate_assignments(assignment, {z, params.beta}, row); + row += mul_component::rows_amount; + res = mul_component::generate_assignments( + assignment, {res.output, params.alphas[params.start_idx]}, row); + row += mul_component::rows_amount; + res = mul_component::generate_assignments(assignment, {res.output, params.zkp_zeta}, row); + row += mul_component::rows_amount; + + for (std::size_t i = 0; i < size; i++) { + auto tmp = mul_component::generate_assignments(assignment, {s[i], params.beta}, row); row += mul_component::rows_amount; - - for (std::size_t i = 0; i < size; i++) { - auto tmp = mul_component::generate_assignments(assignment, {s[i], params.beta}, row); - row += mul_component::rows_amount; - auto add_tmp = - add_component::generate_assignments(assignment, {tmp.output, params.gamma}, row); - row += add_component::rows_amount; - add_tmp = add_component::generate_assignments(assignment, {add_tmp.output, w[i]}, row); - row += add_component::rows_amount; - res = mul_component::generate_assignments(assignment, {add_tmp.output, res.output}, row); - row += add_component::rows_amount; - } - auto const_res = mul_const_component::generate_assignments(assignment, {res.output, -1}, row); - return result_type(start_row_index); + auto add_tmp = add_component::generate_assignments(assignment, {tmp.output, params.gamma}, row); + row += add_component::rows_amount; + add_tmp = add_component::generate_assignments(assignment, {add_tmp.output, w[i]}, row); + row += add_component::rows_amount; + res = mul_component::generate_assignments(assignment, {add_tmp.output, res.output}, row); + row += add_component::rows_amount; } - }; - } // namespace components - } // namespace blueprint - } // namespace crypto3 + auto const_res = mul_const_component::generate_assignments(assignment, {res.output, -1}, row); + return result_type(start_row_index); + } + }; + } // namespace components + } // namespace blueprint } // namespace nil #endif // CRYPTO3_BLUEPRINT_COMPONENTS_PLONK_KIMCHI_DETAIL_PERM_SCALAR_HPP \ No newline at end of file diff --git a/include/nil/blueprint/components/systems/snark/plonk/kimchi/detail/constraints/rpn_expression.hpp b/include/nil/blueprint/components/systems/snark/plonk/kimchi/detail/constraints/rpn_expression.hpp index 9b1360a52..66a78a485 100644 --- a/include/nil/blueprint/components/systems/snark/plonk/kimchi/detail/constraints/rpn_expression.hpp +++ b/include/nil/blueprint/components/systems/snark/plonk/kimchi/detail/constraints/rpn_expression.hpp @@ -37,7 +37,9 @@ #include -#include +#include +#include +#include #include #include #include @@ -45,742 +47,713 @@ #include #include -#include +#include namespace nil { - namespace crypto3 { - namespace blueprint { - namespace components { - - // Evaluate an RPN expression - // https://github.com/o1-labs/proof-systems/blob/1f8532ec1b8d43748a372632bd854be36b371afe/kimchi/src/circuits/expr.rs#L467 - // Input: RPN expression E, variables values V - // Output: E(V) \in F_r - template - class rpn_expression; - - template - class rpn_expression, - KimchiParamsType, NRows, W0, W1, W2, W3, W4, W5, W6, W7, W8, W9, W10, W11, W12, - W13, W14> { - - typedef snark::plonk_constraint_system - ArithmetizationType; - - using var = snark::plonk_variable; - - using mul_component = zk::components::multiplication; - using add_component = zk::components::addition; - using sub_component = zk::components::subtraction; - using endo_scalar_component = zk::components::endo_scalar; - - using poseidon_component = zk::components::poseidon; - - using exponentiation_component = zk::components::exponentiation; - - using vanishes_on_last_4_rows_component = - zk::components::vanishes_on_last_4_rows; - - using unnormalized_lagrange_basis_component = - zk::components::unnormalized_lagrange_basis; - - using evaluations_type = - typename zk::components::kimchi_proof_evaluations; - - constexpr static const std::size_t selector_seed = 0x0f31; - - constexpr static const std::size_t mds_size = 3; - - static std::array, mds_size> mds_vars(const std::size_t start_row) { - std::array, mds_size> result; - std::size_t mds_start_row = start_row; - - for (std::size_t i = 0; i < mds_size; ++i) { - for (std::size_t j = 0; j < mds_size; ++j) { - result[i][j] = - var(0, mds_start_row + i * mds_size + j, false, var::column_type::constant); - } + namespace blueprint { + namespace components { + + // Evaluate an RPN expression + // https://github.com/o1-labs/proof-systems/blob/1f8532ec1b8d43748a372632bd854be36b371afe/kimchi/src/circuits/expr.rs#L467 + // Input: RPN expression E, variables values V + // Output: E(V) \in F_r + template + class rpn_expression; + + template + class rpn_expression, + KimchiParamsType, + NRows, + W0, + W1, + W2, + W3, + W4, + W5, + W6, + W7, + W8, + W9, + W10, + W11, + W12, + W13, + W14> { + + typedef crypto3::zk::snark::plonk_constraint_system ArithmetizationType; + + using var = crypto3::zk::snark::plonk_variable; + + using mul_component = multiplication>; + using add_component = + addition>; + using sub_component = + subtraction>; + using endo_scalar_component = endo_scalar; + + using poseidon_component = poseidon; + + using exponentiation_component = exponentiation; + + using vanishes_on_last_4_rows_component = vanishes_on_last_4_rows; + + using unnormalized_lagrange_basis_component = unnormalized_lagrange_basis; + + using evaluations_type = kimchi_proof_evaluations; + + constexpr static const std::size_t selector_seed = 0x0f31; + + constexpr static const std::size_t mds_size = 3; + + static std::array, mds_size> mds_vars(const std::size_t start_row) { + std::array, mds_size> result; + std::size_t mds_start_row = start_row; + + for (std::size_t i = 0; i < mds_size; ++i) { + for (std::size_t j = 0; j < mds_size; ++j) { + result[i][j] = var(0, mds_start_row + i * mds_size + j, false, var::column_type::constant); } - return result; + } + return result; + } + + static var + var_from_evals(const std::array evaluations, + const std::size_t var_column, + const std::size_t var_row) { + auto evals = evaluations[var_row]; + + /// 0 - witness_columns: witnesses + /// witness_columns + 1: z + /// witness_columns + 2: PoseidonSelector + /// witness_columns + 3: GenericSelector + /// witness_columns + 4: LookupAggreg + /// witness_columns + 5: LookupTable + /// witness_columns + 6: LookupRuntimeTable + /// witness_columns + 7+: LookupSorted + + if (var_column < KimchiParamsType::witness_columns) { + return evals.w[var_column]; } - static var var_from_evals(const std::array - evaluations, - const std::size_t var_column, - const std::size_t var_row) { - auto evals = evaluations[var_row]; - - /// 0 - witness_columns: witnesses - /// witness_columns + 1: z - /// witness_columns + 2: PoseidonSelector - /// witness_columns + 3: GenericSelector - /// witness_columns + 4: LookupAggreg - /// witness_columns + 5: LookupTable - /// witness_columns + 6: LookupRuntimeTable - /// witness_columns + 7+: LookupSorted - - if (var_column < KimchiParamsType::witness_columns) { - return evals.w[var_column]; - } + switch (var_column) { + case KimchiParamsType::witness_columns + 1: + return evals.z; + case KimchiParamsType::witness_columns + 2: + return evals.poseidon_selector; + case KimchiParamsType::witness_columns + 3: + return evals.generic_selector; + case KimchiParamsType::witness_columns + 4: + return evals.lookup.aggreg; + case KimchiParamsType::witness_columns + 5: + return evals.lookup.table; + case KimchiParamsType::witness_columns + 6: + return evals.lookup.runtime; + default: + break; + } - switch (var_column) { - case KimchiParamsType::witness_columns + 1: - return evals.z; - case KimchiParamsType::witness_columns + 2: - return evals.poseidon_selector; - case KimchiParamsType::witness_columns + 3: - return evals.generic_selector; - case KimchiParamsType::witness_columns + 4: - return evals.lookup.aggreg; - case KimchiParamsType::witness_columns + 5: - return evals.lookup.table; - case KimchiParamsType::witness_columns + 6: - return evals.lookup.runtime; - default: - break; - } + assert(var_column <= + KimchiParamsType::witness_columns + 6 + KimchiParamsType::circuit_params::lookup_columns); + + return evals.lookup.sorted[var_column - KimchiParamsType::witness_columns - 7]; + } + + enum token_type { + alpha, + beta, + gamma, + joint_combiner, + endo_coefficient, + mds, + literal, + cell, + dup, + pow, + add, + mul, + sub, + vanishes_on_last_4_rows, + unnormalized_lagrange_basis, + store, + load + }; - assert(var_column <= KimchiParamsType::witness_columns + 6 + - KimchiParamsType::circuit_params::lookup_columns); + struct token_value_type { + token_type type; + std::pair value; + int int_data = 0; + }; - return evals.lookup.sorted[var_column - KimchiParamsType::witness_columns - 7]; + static std::vector rpn_from_string(const std::string_view expression) { + + std::vector tokens_str; + boost::split(tokens_str, expression, boost::is_any_of(";")); + for (std::size_t i = 0; i < tokens_str.size(); i++) { + boost::trim(tokens_str[i]); } - enum token_type { - alpha, - beta, - gamma, - joint_combiner, - endo_coefficient, - mds, - literal, - cell, - dup, - pow, - add, - mul, - sub, - vanishes_on_last_4_rows, - unnormalized_lagrange_basis, - store, - load - }; - - struct token_value_type { - token_type type; - std::pair - value; - int int_data; - }; - - static std::vector rpn_from_string(const std::string_view expression) { - - std::vector tokens_str; - boost::split(tokens_str, expression, boost::is_any_of(";")); - for (std::size_t i = 0; i < tokens_str.size(); i++) { - boost::trim(tokens_str[i]); - } + std::vector tokens {}; + for (std::size_t i = 0; i < tokens_str.size(); i++) { - std::vector tokens; - for (std::size_t i = 0; i < tokens_str.size(); i++) { + std::string token_str = tokens_str[i]; + if (token_str.empty()) { + continue; + } - std::string token_str = tokens_str[i]; - if (token_str.empty()) { - continue; + token_value_type token; + + if (token_str.find("Alpha") != std::string::npos) { + token.type = token_type::alpha; + } else if (token_str.find("Beta") != std::string::npos) { + token.type = token_type::beta; + } else if (token_str.find("Gamma") != std::string::npos) { + token.type = token_type::gamma; + } else if (token_str.find("JointCombiner") != std::string::npos) { + token.type = token_type::joint_combiner; + } else if (token_str.find("EndoCoefficient") != std::string::npos) { + token.type = token_type::endo_coefficient; + } else if (token_str.find("Mds") != std::string::npos) { + token.type = token_type::mds; + std::size_t row_pos = token_str.find("row"); + row_pos += 5; + std::size_t row_end_pos = token_str.find(" ", row_pos); + std::string row_str = token_str.substr(row_pos, row_end_pos - row_pos); + token.value.first = std::stoi(row_str); + + std::size_t col_pos = token_str.find("col"); + col_pos += 5; + std::size_t col_end_pos = token_str.find(" ", col_pos); + std::string col_str = token_str.substr(col_pos, col_end_pos - col_pos); + token.value.second = std::stoi(col_str); + } else if (token_str.find("Literal") != std::string::npos) { + token.type = token_type::literal; + std::size_t value_start_pos = token_str.find("Literal") + 8; + std::size_t value_end_pos = token_str.find(";", value_start_pos); + std::string value_str = token_str.substr(value_start_pos, value_end_pos - value_start_pos); + token.value.first = crypto3::multiprecision::cpp_int("0x" + value_str); + } else if (token_str.find("Cell") != std::string::npos) { + token.type = token_type::cell; + + std::size_t row_pos = token_str.find("row"); + std::size_t row; + if (token_str.find("Curr", row_pos) != std::string::npos) { + row = 0; + } else { // Next + row = 1; } - token_value_type token; - - if (token_str.find("Alpha") != std::string::npos) { - token.type = token_type::alpha; - } else if (token_str.find("Beta") != std::string::npos) { - token.type = token_type::beta; - } else if (token_str.find("Gamma") != std::string::npos) { - token.type = token_type::gamma; - } else if (token_str.find("JointCombiner") != std::string::npos) { - token.type = token_type::joint_combiner; - } else if (token_str.find("EndoCoefficient") != std::string::npos) { - token.type = token_type::endo_coefficient; - } else if (token_str.find("Mds") != std::string::npos) { - token.type = token_type::mds; - std::size_t row_pos = token_str.find("row"); - row_pos += 5; - std::size_t row_end_pos = token_str.find(" ", row_pos); - std::string row_str = token_str.substr(row_pos, row_end_pos - row_pos); - token.value.first = std::stoi(row_str); - - std::size_t col_pos = token_str.find("col"); - col_pos += 5; - std::size_t col_end_pos = token_str.find(" ", col_pos); - std::string col_str = token_str.substr(col_pos, col_end_pos - col_pos); - token.value.second = std::stoi(col_str); - } else if (token_str.find("Literal") != std::string::npos) { - token.type = token_type::literal; - std::size_t value_start_pos = token_str.find("Literal") + 8; - std::size_t value_end_pos = token_str.find(";", value_start_pos); - std::string value_str = - token_str.substr(value_start_pos, value_end_pos - value_start_pos); - token.value.first = multiprecision::cpp_int("0x" + value_str); - } else if (token_str.find("Cell") != std::string::npos) { - token.type = token_type::cell; - - std::size_t row_pos = token_str.find("row"); - std::size_t row; - if (token_str.find("Curr", row_pos) != std::string::npos) { - row = 0; - } else { // Next - row = 1; - } - - std::size_t col_pos = token_str.find("col"); - std::size_t col; - if (token_str.find("Witness", col_pos) != std::string::npos) { - // Witness(col) - std::size_t witness_pos = token_str.find("Witness", col_pos); - std::size_t col_start_pow = witness_pos + 8; - std::size_t col_end_pow = token_str.find(")", col_start_pow); - std::string col_str = token_str.substr(col_start_pow, col_end_pow - col_start_pow); - col = std::stoi(col_str); - } else { - std::array column_types = {"Z", "Poseidon", - "Generic", "LookupAggreg", - "LookupTable", "LookupRuntimeTable"}; - for (std::size_t i = 0; i < column_types.size(); i++) { - if (token_str.find(column_types[i]) != std::string::npos) { - col = KimchiParamsType::witness_columns + i + 1; - break; - } - } - - // lookup_sorted - if (token_str.find("LookupSorted") != std::string::npos) { - std::size_t col_start_pos = token_str.find("LookupSorted", col_pos) + 14; - std::size_t col_end_pos = token_str.find(")", col_start_pos); - std::string col_str = - token_str.substr(col_start_pos, col_end_pos - col_start_pos); - col = KimchiParamsType::witness_columns + 7 + std::stoi(col_str); + std::size_t col_pos = token_str.find("col"); + std::size_t col; + if (token_str.find("Witness", col_pos) != std::string::npos) { + // Witness(col) + std::size_t witness_pos = token_str.find("Witness", col_pos); + std::size_t col_start_pow = witness_pos + 8; + std::size_t col_end_pow = token_str.find(")", col_start_pow); + std::string col_str = token_str.substr(col_start_pow, col_end_pow - col_start_pow); + col = std::stoi(col_str); + } else { + std::array column_types = { + "Z", "Poseidon", "Generic", "LookupAggreg", "LookupTable", "LookupRuntimeTable"}; + for (std::size_t i = 0; i < column_types.size(); i++) { + if (token_str.find(column_types[i]) != std::string::npos) { + col = KimchiParamsType::witness_columns + i + 1; + break; } } - token.value.first = col; - token.value.second = row; - } else if (token_str.find("Dup") != std::string::npos) { - token.type = token_type::dup; - } else if (token_str.find("Pow") != std::string::npos) { - token.type = token_type::pow; - - std::size_t exp_start_pos = token_str.find("Pow") + 4; - std::size_t exp_end_pos = token_str.find(")", exp_start_pos); - std::string exp_str = token_str.substr(exp_start_pos, exp_end_pos - exp_start_pos); - token.value.first = std::stoi(exp_str); - } else if (token_str.find("Add") != std::string::npos) { - token.type = token_type::add; - } else if (token_str.find("Mul") != std::string::npos) { - token.type = token_type::mul; - } else if (token_str.find("Sub") != std::string::npos) { - token.type = token_type::sub; - } else if (token_str.find("VanishesOnLast4Rows") != std::string::npos) { - token.type = token_type::vanishes_on_last_4_rows; - } else if (token_str.find("UnnormalizedLagrangeBasis") != std::string::npos) { - token.type = token_type::unnormalized_lagrange_basis; - - std::size_t exp_start_pos = token_str.find("UnnormalizedLagrangeBasis"); - exp_start_pos = token_str.find("(", exp_start_pos) + 1; - std::size_t exp_end_pos = token_str.find(")", exp_start_pos); - std::string exp_str = token_str.substr(exp_start_pos, exp_end_pos - exp_start_pos); - token.int_data = std::stoi(exp_str); - } else if (token_str.find("Store") != std::string::npos) { - token.type = token_type::store; - } else if (token_str.find("Load") != std::string::npos) { - token.type = token_type::load; - - std::size_t idx_start_pos = token_str.find("Load") + 5; - std::size_t idx_end_pos = token_str.find(")", idx_start_pos); - std::string idx_str = token_str.substr(idx_start_pos, idx_end_pos - idx_start_pos); - token.value.first = std::stoi(idx_str); - } else { - throw std::runtime_error("Unknown token type"); + // lookup_sorted + if (token_str.find("LookupSorted") != std::string::npos) { + std::size_t col_start_pos = token_str.find("LookupSorted", col_pos) + 14; + std::size_t col_end_pos = token_str.find(")", col_start_pos); + std::string col_str = token_str.substr(col_start_pos, col_end_pos - col_start_pos); + col = KimchiParamsType::witness_columns + 7 + std::stoi(col_str); + } } - tokens.push_back(token); + token.value.first = col; + token.value.second = row; + } else if (token_str.find("Dup") != std::string::npos) { + token.type = token_type::dup; + } else if (token_str.find("Pow") != std::string::npos) { + token.type = token_type::pow; + + std::size_t exp_start_pos = token_str.find("Pow") + 4; + std::size_t exp_end_pos = token_str.find(")", exp_start_pos); + std::string exp_str = token_str.substr(exp_start_pos, exp_end_pos - exp_start_pos); + token.value.first = std::stoi(exp_str); + } else if (token_str.find("Add") != std::string::npos) { + token.type = token_type::add; + } else if (token_str.find("Mul") != std::string::npos) { + token.type = token_type::mul; + } else if (token_str.find("Sub") != std::string::npos) { + token.type = token_type::sub; + } else if (token_str.find("VanishesOnLast4Rows") != std::string::npos) { + token.type = token_type::vanishes_on_last_4_rows; + } else if (token_str.find("UnnormalizedLagrangeBasis") != std::string::npos) { + token.type = token_type::unnormalized_lagrange_basis; + + std::size_t exp_start_pos = token_str.find("UnnormalizedLagrangeBasis"); + exp_start_pos = token_str.find("(", exp_start_pos) + 1; + std::size_t exp_end_pos = token_str.find(")", exp_start_pos); + std::string exp_str = token_str.substr(exp_start_pos, exp_end_pos - exp_start_pos); + token.int_data = std::stoi(exp_str); + } else if (token_str.find("Store") != std::string::npos) { + token.type = token_type::store; + } else if (token_str.find("Load") != std::string::npos) { + token.type = token_type::load; + + std::size_t idx_start_pos = token_str.find("Load") + 5; + std::size_t idx_end_pos = token_str.find(")", idx_start_pos); + std::string idx_str = token_str.substr(idx_start_pos, idx_end_pos - idx_start_pos); + token.value.first = std::stoi(idx_str); + } else { + throw std::runtime_error("Unknown token type"); } - return tokens; + tokens.push_back(token); } - public: - constexpr static const std::size_t rows_amount = NRows; - constexpr static const std::size_t gates_amount = 0; + return tokens; + } - struct params_type { - std::string_view expression; + public: + constexpr static const std::size_t rows_amount = NRows; + constexpr static const std::size_t gates_amount = 0; - var eval_point; // zeta + struct params_type { + std::string_view expression; - var alpha; - var beta; - var gamma; - var joint_combiner; + var eval_point; // zeta - std::array evaluations; + var alpha; + var beta; + var gamma; + var joint_combiner; - var group_gen; - std::size_t domain_size; - }; + std::array evaluations; - struct result_type { - var output; + var group_gen; + std::size_t domain_size; + }; - result_type(std::size_t start_row_index) { - std::size_t row = start_row_index; - } + struct result_type { + var output; - result_type() { - } - }; + result_type(std::size_t start_row_index) { + std::size_t row = start_row_index; + } - static result_type - generate_circuit(blueprint &bp, - blueprint_public_assignment_table &assignment, - const params_type ¶ms, - const std::size_t start_row_index) { + result_type() { + } + }; - std::size_t row = start_row_index; - generate_assignments_constants(assignment, params, start_row_index); - - std::vector tokens = rpn_from_string(params.expression); - - std::vector stack; - std::vector cache; - - var endo_factor(0, row, false, var::column_type::constant); - row++; - - auto mds = mds_vars(row); - row += mds_size * mds_size; - - for (token_value_type t : tokens) { - switch (t.type) { - case token_type::alpha: - stack.emplace_back(params.alpha); - break; - case token_type::beta: - stack.emplace_back(params.beta); - break; - case token_type::gamma: - stack.emplace_back(params.gamma); - break; - case token_type::joint_combiner: - stack.emplace_back(params.joint_combiner); - break; - case token_type::endo_coefficient: - stack.emplace_back(endo_factor); - break; - case token_type::mds: { - std::size_t mds_row = (std::size_t) - typename BlueprintFieldType::integral_type(t.value.first.data); - std::size_t mds_col = (std::size_t) - typename BlueprintFieldType::integral_type(t.value.second.data); - stack.emplace_back(mds[mds_row][mds_col]); - break; - } - case token_type::literal: { - var literal(0, row, false, var::column_type::constant); - stack.emplace_back(literal); - row++; - break; - } - case token_type::cell: { - std::size_t cell_col = (std::size_t) - typename BlueprintFieldType::integral_type(t.value.first.data); - std::size_t cell_row = (std::size_t) - typename BlueprintFieldType::integral_type(t.value.second.data); - var cell_val = var_from_evals(params.evaluations, cell_col, cell_row); - stack.emplace_back(cell_val); - break; - } - case token_type::dup: - stack.emplace_back(stack.back()); - break; - case token_type::pow: { - var exponent(0, row, false, var::column_type::constant); - row++; - - var res = zk::components::generate_circuit( - bp, assignment, {stack.back(), exponent}, row) - .output; - row += exponentiation_component::rows_amount; - stack[stack.size() - 1] = res; - break; - } - case token_type::add: { - var x = stack.back(); - stack.pop_back(); - var y = stack.back(); - stack.pop_back(); - var res = - zk::components::generate_circuit(bp, assignment, {x, y}, row) - .output; - row += add_component::rows_amount; - stack.push_back(res); - break; - } - case token_type::mul: { - var x = stack.back(); - stack.pop_back(); - var y = stack.back(); - stack.pop_back(); - var res = - zk::components::generate_circuit(bp, assignment, {x, y}, row) - .output; - row += mul_component::rows_amount; - stack.push_back(res); - break; - } - case token_type::sub: { - var x = stack.back(); - stack.pop_back(); - var y = stack.back(); - stack.pop_back(); - var res = - zk::components::generate_circuit(bp, assignment, {y, x}, row) - .output; - row += sub_component::rows_amount; - stack.push_back(res); - break; - } - case token_type::vanishes_on_last_4_rows: { - var res = vanishes_on_last_4_rows_component::generate_circuit( - bp, - assignment, - {params.group_gen, params.domain_size, params.eval_point}, - row) - .output; - row += vanishes_on_last_4_rows_component::rows_amount; - stack.push_back(res); - break; - } - case token_type::unnormalized_lagrange_basis: { - var res = unnormalized_lagrange_basis_component::generate_circuit( - bp, - assignment, - {params.group_gen, params.domain_size, params.eval_point, t.int_data}, - row) - .output; - row += unnormalized_lagrange_basis_component::rows_amount; - stack.push_back(res); - break; - } - case token_type::store: { - var x = stack.back(); - cache.emplace_back(x); - break; - } - case token_type::load: { - std::size_t idx = (std::size_t) typename BlueprintFieldType::integral_type(t.value.first.data); - stack.push_back(cache[idx]); - break; - } - } - } + static result_type generate_circuit(blueprint &bp, + assignment &assignment, + const params_type ¶ms, + const std::size_t start_row_index) { - assert(row == start_row_index + rows_amount); + std::size_t row = start_row_index; + generate_assignments_constants(assignment, params, start_row_index); - result_type res; - res.output = stack[stack.size() - 1]; - return res; - } + std::vector tokens = rpn_from_string(params.expression); - static result_type generate_assignments(blueprint_assignment_table &assignment, - const params_type ¶ms, - const std::size_t start_row_index) { + std::vector stack; + std::vector cache; - std::size_t row = start_row_index; + var endo_factor(0, row, false, var::column_type::constant); + row++; - std::vector tokens = rpn_from_string(params.expression); - - std::vector stack; - std::vector cache; - - var endo_factor(0, row, false, var::column_type::constant); - row += 1; - - auto mds = mds_vars(row); - row += mds_size * mds_size; - - for (token_value_type t : tokens) { - switch (t.type) { - case token_type::alpha: - stack.emplace_back(params.alpha); - break; - case token_type::beta: - stack.emplace_back(params.beta); - break; - case token_type::gamma: - stack.emplace_back(params.gamma); - break; - case token_type::joint_combiner: - stack.emplace_back(params.joint_combiner); - break; - case token_type::endo_coefficient: - stack.emplace_back(endo_factor); - break; - case token_type::mds: { - std::size_t mds_row = (std::size_t) - typename BlueprintFieldType::integral_type(t.value.first.data); - std::size_t mds_col = (std::size_t) - typename BlueprintFieldType::integral_type(t.value.second.data); - stack.emplace_back(mds[mds_row][mds_col]); - break; - } - case token_type::literal: { - var literal(0, row, false, var::column_type::constant); - stack.emplace_back(literal); - row++; - break; - } - case token_type::cell: { - std::size_t cell_col = (std::size_t) - typename BlueprintFieldType::integral_type(t.value.first.data); - std::size_t cell_row = (std::size_t) - typename BlueprintFieldType::integral_type(t.value.second.data); - var cell_val = var_from_evals(params.evaluations, cell_col, cell_row); - stack.emplace_back(cell_val); - break; - } - case token_type::dup: - stack.emplace_back(stack.back()); - break; - case token_type::pow: { - var exponent(0, row, false, var::column_type::constant); - row++; - - var res = exponentiation_component::generate_assignments( - assignment, {stack.back(), exponent}, row) - .output; - row += exponentiation_component::rows_amount; - - stack[stack.size() - 1] = res; - break; - } - case token_type::add: { - var x = stack.back(); - stack.pop_back(); - var y = stack.back(); - stack.pop_back(); - var res = add_component::generate_assignments(assignment, {x, y}, row).output; - row += add_component::rows_amount; - stack.push_back(res); - break; - } - case token_type::mul: { - var x = stack.back(); - stack.pop_back(); - var y = stack.back(); - stack.pop_back(); - var res = mul_component::generate_assignments(assignment, {x, y}, row).output; - row += mul_component::rows_amount; - stack.push_back(res); - break; - } - case token_type::sub: { - var x = stack.back(); - stack.pop_back(); - var y = stack.back(); - stack.pop_back(); - var res = sub_component::generate_assignments(assignment, {y, x}, row).output; - row += sub_component::rows_amount; - stack.push_back(res); - break; - } - case token_type::vanishes_on_last_4_rows: { - var res = - vanishes_on_last_4_rows_component::generate_assignments( - assignment, {params.group_gen, params.domain_size, params.eval_point}, row) - .output; - row += vanishes_on_last_4_rows_component::rows_amount; - stack.push_back(res); - break; - } - case token_type::unnormalized_lagrange_basis: { - var res = unnormalized_lagrange_basis_component::generate_assignments( - assignment, - {params.group_gen, params.domain_size, params.eval_point, t.int_data}, - row) - .output; - row += unnormalized_lagrange_basis_component::rows_amount; - stack.push_back(res); - break; - } - case token_type::store: { - var x = stack.back(); - cache.emplace_back(x); - break; - } - case token_type::load: { - std::size_t idx = (std::size_t) typename BlueprintFieldType::integral_type(t.value.first.data); - stack.push_back(cache[idx]); - break; - } + auto mds = mds_vars(row); + row += mds_size * mds_size; + + for (token_value_type t : tokens) { + switch (t.type) { + case token_type::alpha: + stack.emplace_back(params.alpha); + break; + case token_type::beta: + stack.emplace_back(params.beta); + break; + case token_type::gamma: + stack.emplace_back(params.gamma); + break; + case token_type::joint_combiner: + stack.emplace_back(params.joint_combiner); + break; + case token_type::endo_coefficient: + stack.emplace_back(endo_factor); + break; + case token_type::mds: { + std::size_t mds_row = + (std::size_t) typename BlueprintFieldType::integral_type(t.value.first.data); + std::size_t mds_col = + (std::size_t) typename BlueprintFieldType::integral_type(t.value.second.data); + stack.emplace_back(mds[mds_row][mds_col]); + break; + } + case token_type::literal: { + var literal(0, row, false, var::column_type::constant); + stack.emplace_back(literal); + row++; + break; + } + case token_type::cell: { + std::size_t cell_col = + (std::size_t) typename BlueprintFieldType::integral_type(t.value.first.data); + std::size_t cell_row = + (std::size_t) typename BlueprintFieldType::integral_type(t.value.second.data); + var cell_val = var_from_evals(params.evaluations, cell_col, cell_row); + stack.emplace_back(cell_val); + break; + } + case token_type::dup: + stack.emplace_back(stack.back()); + break; + case token_type::pow: { + var exponent(0, row, false, var::column_type::constant); + row++; + + var res = ::nil::blueprint::components::generate_circuit( + bp, assignment, {stack.back(), exponent}, row) + .output; + row += exponentiation_component::rows_amount; + stack[stack.size() - 1] = res; + break; + } + case token_type::add: { + var x = stack.back(); + stack.pop_back(); + var y = stack.back(); + stack.pop_back(); + var res = ::nil::blueprint::components::generate_circuit( + bp, assignment, {x, y}, row) + .output; + row += add_component::rows_amount; + stack.push_back(res); + break; + } + case token_type::mul: { + var x = stack.back(); + stack.pop_back(); + var y = stack.back(); + stack.pop_back(); + var res = ::nil::blueprint::components::generate_circuit( + bp, assignment, {x, y}, row) + .output; + row += mul_component::rows_amount; + stack.push_back(res); + break; + } + case token_type::sub: { + var x = stack.back(); + stack.pop_back(); + var y = stack.back(); + stack.pop_back(); + var res = ::nil::blueprint::components::generate_circuit( + bp, assignment, {y, x}, row) + .output; + row += sub_component::rows_amount; + stack.push_back(res); + break; + } + case token_type::vanishes_on_last_4_rows: { + var res = + vanishes_on_last_4_rows_component::generate_circuit( + bp, assignment, {params.group_gen, params.domain_size, params.eval_point}, row) + .output; + row += vanishes_on_last_4_rows_component::rows_amount; + stack.push_back(res); + break; + } + case token_type::unnormalized_lagrange_basis: { + var res = unnormalized_lagrange_basis_component::generate_circuit( + bp, + assignment, + {params.group_gen, params.domain_size, params.eval_point, t.int_data}, + row) + .output; + row += unnormalized_lagrange_basis_component::rows_amount; + stack.push_back(res); + break; + } + case token_type::store: { + var x = stack.back(); + cache.emplace_back(x); + break; + } + case token_type::load: { + std::size_t idx = + (std::size_t) typename BlueprintFieldType::integral_type(t.value.first.data); + stack.push_back(cache[idx]); + break; } } + } - assert(row == start_row_index + rows_amount); + assert(row == start_row_index + rows_amount); - result_type res; - res.output = stack[stack.size() - 1]; - return res; - } + result_type res; + res.output = stack[stack.size() - 1]; + return res; + } - private: - static void generate_assignments_constants( - blueprint_public_assignment_table &assignment, - const params_type ¶ms, - const std::size_t start_row_index) { - std::size_t row = start_row_index; - typename KimchiParamsType::curve_type::base_field_type::integral_type endo_integral_base = - typename KimchiParamsType::curve_type::base_field_type::integral_type( - endo_scalar_component::endo_q.data); - typename BlueprintFieldType::integral_type endo_integral = endo_integral_base; - assignment.constant(0)[row] = typename BlueprintFieldType::value_type(endo_integral); - row++; - - std::array, mds_size> mds = - poseidon_component::mds_constants(); - for (std::size_t i = 0; i < mds_size; i++) { - for (std::size_t j = 0; j < mds_size; j++) { - assignment.constant(0)[row] = mds[i][j]; + static result_type generate_assignments(assignment &assignment, + const params_type ¶ms, + const std::size_t start_row_index) { + + std::size_t row = start_row_index; + + std::vector tokens = rpn_from_string(params.expression); + + std::vector stack; + std::vector cache; + + var endo_factor(0, row, false, var::column_type::constant); + row += 1; + + auto mds = mds_vars(row); + row += mds_size * mds_size; + + for (token_value_type t : tokens) { + switch (t.type) { + case token_type::alpha: + stack.emplace_back(params.alpha); + break; + case token_type::beta: + stack.emplace_back(params.beta); + break; + case token_type::gamma: + stack.emplace_back(params.gamma); + break; + case token_type::joint_combiner: + stack.emplace_back(params.joint_combiner); + break; + case token_type::endo_coefficient: + stack.emplace_back(endo_factor); + break; + case token_type::mds: { + std::size_t mds_row = + (std::size_t) typename BlueprintFieldType::integral_type(t.value.first.data); + std::size_t mds_col = + (std::size_t) typename BlueprintFieldType::integral_type(t.value.second.data); + stack.emplace_back(mds[mds_row][mds_col]); + break; + } + case token_type::literal: { + var literal(0, row, false, var::column_type::constant); + stack.emplace_back(literal); + row++; + break; + } + case token_type::cell: { + std::size_t cell_col = + (std::size_t) typename BlueprintFieldType::integral_type(t.value.first.data); + std::size_t cell_row = + (std::size_t) typename BlueprintFieldType::integral_type(t.value.second.data); + var cell_val = var_from_evals(params.evaluations, cell_col, cell_row); + stack.emplace_back(cell_val); + break; + } + case token_type::dup: + stack.emplace_back(stack.back()); + break; + case token_type::pow: { + var exponent(0, row, false, var::column_type::constant); row++; + + var res = exponentiation_component::generate_assignments( + assignment, {stack.back(), exponent}, row) + .output; + row += exponentiation_component::rows_amount; + + stack[stack.size() - 1] = res; + break; + } + case token_type::add: { + var x = stack.back(); + stack.pop_back(); + var y = stack.back(); + stack.pop_back(); + var res = add_component::generate_assignments(assignment, {x, y}, row).output; + row += add_component::rows_amount; + stack.push_back(res); + break; + } + case token_type::mul: { + var x = stack.back(); + stack.pop_back(); + var y = stack.back(); + stack.pop_back(); + var res = mul_component::generate_assignments(assignment, {x, y}, row).output; + row += mul_component::rows_amount; + stack.push_back(res); + break; + } + case token_type::sub: { + var x = stack.back(); + stack.pop_back(); + var y = stack.back(); + stack.pop_back(); + var res = sub_component::generate_assignments(assignment, {y, x}, row).output; + row += sub_component::rows_amount; + stack.push_back(res); + break; + } + case token_type::vanishes_on_last_4_rows: { + var res = + vanishes_on_last_4_rows_component::generate_assignments( + assignment, {params.group_gen, params.domain_size, params.eval_point}, row) + .output; + row += vanishes_on_last_4_rows_component::rows_amount; + stack.push_back(res); + break; + } + case token_type::unnormalized_lagrange_basis: { + var res = unnormalized_lagrange_basis_component::generate_assignments( + assignment, + {params.group_gen, params.domain_size, params.eval_point, t.int_data}, + row) + .output; + row += unnormalized_lagrange_basis_component::rows_amount; + stack.push_back(res); + break; + } + case token_type::store: { + var x = stack.back(); + cache.emplace_back(x); + break; + } + case token_type::load: { + std::size_t idx = + (std::size_t) typename BlueprintFieldType::integral_type(t.value.first.data); + stack.push_back(cache[idx]); + break; } } + } - std::vector tokens = rpn_from_string(params.expression); + assert(row == start_row_index + rows_amount); + + result_type res; + res.output = stack[stack.size() - 1]; + return res; + } + + private: + static void generate_assignments_constants(assignment &assignment, + const params_type ¶ms, + const std::size_t start_row_index) { + std::size_t row = start_row_index; + typename KimchiParamsType::curve_type::base_field_type::integral_type endo_integral_base = + typename KimchiParamsType::curve_type::base_field_type::integral_type( + endo_scalar_component::endo_q.data); + typename BlueprintFieldType::integral_type endo_integral = endo_integral_base; + assignment.constant(0)[row] = typename BlueprintFieldType::value_type(endo_integral); + row++; + + std::array, mds_size> mds = + poseidon_component::mds_constants(); + for (std::size_t i = 0; i < mds_size; i++) { + for (std::size_t j = 0; j < mds_size; j++) { + assignment.constant(0)[row] = mds[i][j]; + row++; + } + } - for (token_value_type t : tokens) { - switch (t.type) { - case token_type::literal: { - assignment.constant(0)[row] = t.value.first; - row++; - break; - } - case token_type::pow: { - assignment.constant(0)[row] = t.value.first; - row++; - row += exponentiation_component::rows_amount; - break; - } - case token_type::add: { - row += add_component::rows_amount; - break; - } - case token_type::mul: { - row += mul_component::rows_amount; - break; - } - case token_type::sub: { - row += sub_component::rows_amount; - break; - } - case token_type::vanishes_on_last_4_rows: { - row += vanishes_on_last_4_rows_component::rows_amount; - break; - } - case token_type::unnormalized_lagrange_basis: { - row += unnormalized_lagrange_basis_component::rows_amount; - break; - } + std::vector tokens = rpn_from_string(params.expression); + + for (token_value_type t : tokens) { + switch (t.type) { + case token_type::literal: { + assignment.constant(0)[row] = t.value.first; + row++; + break; + } + case token_type::pow: { + assignment.constant(0)[row] = t.value.first; + row++; + row += exponentiation_component::rows_amount; + break; + } + case token_type::add: { + row += add_component::rows_amount; + break; + } + case token_type::mul: { + row += mul_component::rows_amount; + break; + } + case token_type::sub: { + row += sub_component::rows_amount; + break; + } + case token_type::vanishes_on_last_4_rows: { + row += vanishes_on_last_4_rows_component::rows_amount; + break; + } + case token_type::unnormalized_lagrange_basis: { + row += unnormalized_lagrange_basis_component::rows_amount; + break; } } } - }; - } // namespace components - } // namespace blueprint - } // namespace crypto3 + } + }; + } // namespace components + } // namespace blueprint } // namespace nil #endif // CRYPTO3_BLUEPRINT_COMPONENTS_PLONK_KIMCHI_DETAIL_RPN_EXPRESSION_HPP diff --git a/include/nil/blueprint/components/systems/snark/plonk/kimchi/detail/constraints/rpn_string_literal.hpp b/include/nil/blueprint/components/systems/snark/plonk/kimchi/detail/constraints/rpn_string_literal.hpp index 7b2368c71..327c527ad 100644 --- a/include/nil/blueprint/components/systems/snark/plonk/kimchi/detail/constraints/rpn_string_literal.hpp +++ b/include/nil/blueprint/components/systems/snark/plonk/kimchi/detail/constraints/rpn_string_literal.hpp @@ -37,6 +37,11 @@ #include #include + +#include +#include +#include + #include #include #include @@ -47,116 +52,116 @@ #include namespace nil { - namespace crypto3 { - namespace blueprint { - namespace components { - - constexpr const std::size_t count_delimiters(const char *expression) { - size_t i = 0; - size_t cnt = 0; - for (; expression[i] != '\0'; i++) { - if (expression[i] == ';') { - cnt++; - } + namespace blueprint { + namespace components { + + constexpr const std::size_t count_delimiters(const char *expression) { + size_t i = 0; + size_t cnt = 0; + for (; expression[i] != '\0'; i++) { + if (expression[i] == ';') { + cnt++; } - return cnt; } + return cnt; + } - constexpr const std::size_t str_len(const char *expression) { - size_t size = 0; - for (; expression[size] != '\0'; size++) { - } - return size; + constexpr const std::size_t str_len(const char *expression) { + size_t size = 0; + for (; expression[size] != '\0'; size++) { } - - constexpr std::size_t find_str(const char *expression, const char *str, std::size_t n, std::size_t start_pos, - std::size_t end_pos) { - size_t j = 0; - size_t i = start_pos; - for (; i < end_pos; i++) { - for (j = 0; j < n && expression[i + j] == str[j]; j++) - ; - if (j == n) { - return i; - } + return size; + } + + constexpr std::size_t find_str(const char *expression, const char *str, std::size_t n, + std::size_t start_pos, std::size_t end_pos) { + size_t j = 0; + size_t i = start_pos; + for (; i < end_pos; i++) { + for (j = 0; j < n && expression[i + j] == str[j]; j++) + ; + if (j == n) { + return i; } - return std::string::npos; } - - template - constexpr size_t rpn_component_rows(const char *expression) { - using mul_component = zk::components::multiplication; - using add_component = zk::components::addition; - using sub_component = zk::components::subtraction; - - using exponentiation_component = zk::components::exponentiation; - - using vanishes_on_last_4_rows_component = zk::components::vanishes_on_last_4_rows< - ArithmetizationType, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, - 11, 12, 13, 14>; - - using unnormalized_lagrange_basis_component = zk::components::unnormalized_lagrange_basis; - - const std::size_t literal_string_size = str_len(expression); - - const size_t mds_size = 3; - std::array str_start = {}; - - std::array str_end = {}; - str_start[0] = 0; - str_end[tokens_array_size - 1] = literal_string_size; - size_t i = 0; - const char *alpha_c = "Alpha"; - const char *beta_c = "Beta"; - const char *gamma_c = "Gamma"; - const char *joint_combiner_c = "JointCombiner"; - const char *endo_coefficient_c = "EndoCoefficient"; - const char *mds_c = "Mds"; - const char *literal_c = "Literal"; - const char *cell_c = "Cell"; - const char *dup_c = "Dup"; - const char *pow_c = "Pow"; - const char *add_c = "Add"; - const char *mul_c = "Mul"; - const char *sub_c = "Sub"; - const char *vanishes_on_last_4_rows_c = "VanishesOnLast4Rows"; - const char *unnormalized_lagrange_basis_c = "UnnormalizedLagrangeBasis"; - const char *store_c = "Store"; - const char *load_c = "Load"; - const char *del = ";"; - for (i = 0; i < tokens_array_size - 1; i++) { - size_t pos = find_str(expression, del, 1, str_start[i], literal_string_size); - str_end[i] = pos; - str_start[i + 1] = pos + 1; - } - size_t rows = 1 + mds_size * mds_size; - for (i = 0; i < tokens_array_size; i++) { - if (find_str(expression, literal_c, 7, str_start[i], str_end[i]) != std::string::npos) { - rows++; - } else if (find_str(expression, pow_c, 3, str_start[i], str_end[i]) != std::string::npos) { - rows++; - rows += exponentiation_component::rows_amount; - } else if (find_str(expression, add_c, 3, str_start[i], str_end[i]) != std::string::npos) { - rows += add_component::rows_amount; - } else if (find_str(expression, mul_c, 3, str_start[i], str_end[i]) != std::string::npos) { - rows += mul_component::rows_amount; - } else if (find_str(expression, sub_c, 3, str_start[i], str_end[i]) != std::string::npos) { - rows += sub_component::rows_amount; - } else if (find_str(expression, vanishes_on_last_4_rows_c, 3, str_start[i], str_end[i]) != std::string::npos) { - rows += vanishes_on_last_4_rows_component::rows_amount; - } - else if (find_str(expression, unnormalized_lagrange_basis_c, 3, str_start[i], str_end[i]) != std::string::npos) { - rows += unnormalized_lagrange_basis_component::rows_amount; - } + return std::string::npos; + } + + template + constexpr size_t rpn_component_rows(const char *expression) { + using mul_component = multiplication>; + using add_component = + addition>; + using sub_component = + subtraction>; + + using exponentiation_component = exponentiation; + + using vanishes_on_last_4_rows_component = + vanishes_on_last_4_rows; + + using unnormalized_lagrange_basis_component = + unnormalized_lagrange_basis; + + const std::size_t literal_string_size = str_len(expression); + + const size_t mds_size = 3; + std::array str_start = {}; + + std::array str_end = {}; + str_start[0] = 0; + str_end[tokens_array_size - 1] = literal_string_size; + size_t i = 0; + const char *alpha_c = "Alpha"; + const char *beta_c = "Beta"; + const char *gamma_c = "Gamma"; + const char *joint_combiner_c = "JointCombiner"; + const char *endo_coefficient_c = "EndoCoefficient"; + const char *mds_c = "Mds"; + const char *literal_c = "Literal"; + const char *cell_c = "Cell"; + const char *dup_c = "Dup"; + const char *pow_c = "Pow"; + const char *add_c = "Add"; + const char *mul_c = "Mul"; + const char *sub_c = "Sub"; + const char *vanishes_on_last_4_rows_c = "VanishesOnLast4Rows"; + const char *unnormalized_lagrange_basis_c = "UnnormalizedLagrangeBasis"; + const char *store_c = "Store"; + const char *load_c = "Load"; + const char *del = ";"; + for (i = 0; i < tokens_array_size - 1; i++) { + size_t pos = find_str(expression, del, 1, str_start[i], literal_string_size); + str_end[i] = pos; + str_start[i + 1] = pos + 1; + } + size_t rows = 1 + mds_size * mds_size; + for (i = 0; i < tokens_array_size; i++) { + if (find_str(expression, literal_c, 7, str_start[i], str_end[i]) != std::string::npos) { + rows++; + } else if (find_str(expression, pow_c, 3, str_start[i], str_end[i]) != std::string::npos) { + rows++; + rows += exponentiation_component::rows_amount; + } else if (find_str(expression, add_c, 3, str_start[i], str_end[i]) != std::string::npos) { + rows += add_component::rows_amount; + } else if (find_str(expression, mul_c, 3, str_start[i], str_end[i]) != std::string::npos) { + rows += mul_component::rows_amount; + } else if (find_str(expression, sub_c, 3, str_start[i], str_end[i]) != std::string::npos) { + rows += sub_component::rows_amount; + } else if (find_str(expression, vanishes_on_last_4_rows_c, 3, str_start[i], str_end[i]) != + std::string::npos) { + rows += vanishes_on_last_4_rows_component::rows_amount; + } else if (find_str(expression, unnormalized_lagrange_basis_c, 3, str_start[i], str_end[i]) != + std::string::npos) { + rows += unnormalized_lagrange_basis_component::rows_amount; } - - return rows; } - } // namespace components - } // namespace blueprint - } // namespace crypto3 -} // namespace nil + + return rows; + } + } // namespace components + } // namespace blueprint +} // namespace nil #endif // CRYPTO3_BLUEPRINT_COMPONENTS_PLONK_KIMCHI_DETAIL_CONSTRAINTS_RPN_STRING_LITERAL_HPP \ No newline at end of file diff --git a/include/nil/blueprint/components/systems/snark/plonk/kimchi/detail/constraints/unnormalized_lagrange_basis.hpp b/include/nil/blueprint/components/systems/snark/plonk/kimchi/detail/constraints/unnormalized_lagrange_basis.hpp index 93ac36e81..87733d330 100644 --- a/include/nil/blueprint/components/systems/snark/plonk/kimchi/detail/constraints/unnormalized_lagrange_basis.hpp +++ b/include/nil/blueprint/components/systems/snark/plonk/kimchi/detail/constraints/unnormalized_lagrange_basis.hpp @@ -32,164 +32,182 @@ #include #include -#include +#include +#include #include -#include +#include namespace nil { - namespace crypto3 { - namespace blueprint { - namespace components { - - // Compute the ith unnormalized lagrange basis - // https://github.com/o1-labs/proof-systems/blob/1f8532ec1b8d43748a372632bd854be36b371afe/kimchi/src/circuits/expr.rs#L150 - // Input: group generator (w), - // i, - // domain_size, - // evaluation point (x) - // Output: (x^domain_size - 1) / (x - w^i) - template - class unnormalized_lagrange_basis; - - template - class unnormalized_lagrange_basis< - snark::plonk_constraint_system, W0, W1, W2, W3, W4, W5, - W6, W7, W8, W9, W10, W11, W12, W13, W14> { - - typedef snark::plonk_constraint_system - ArithmetizationType; - - using var = snark::plonk_variable; - - using sub_component = zk::components::subtraction; - using exp_component = zk::components::exponentiation; - using div_component = zk::components::division; - - constexpr static const std::size_t selector_seed = 0x0f25; - - constexpr static const std::size_t zk_rows = 3; - - public: - constexpr static const std::size_t rows_amount = 3 + 2 * exp_component::rows_amount + - 2 * sub_component::rows_amount + - div_component::rows_amount; - constexpr static const std::size_t gates_amount = 0; - - struct params_type { - var group_gen; - std::size_t domain_size; - var x; - int i; - }; - - struct result_type { - var output; - - result_type(std::size_t start_row_index) { - std::size_t row = start_row_index + rows_amount - div_component::rows_amount; - output = typename div_component::result_type(row).output; - } - }; - - static result_type - generate_circuit(blueprint &bp, - blueprint_public_assignment_table &assignment, - const params_type ¶ms, - const std::size_t start_row_index) { - - generate_assignments_constants(bp, assignment, params, start_row_index); - - var domain_size(0, start_row_index, false, var::column_type::constant); - var basis_element(0, start_row_index + 1, false, var::column_type::constant); - var one(0, start_row_index + 2, false, var::column_type::constant); - - std::size_t row = start_row_index; - row += 3; // skip row for constants in exp_component - - var denominator = - exp_component::generate_circuit(bp, assignment, {params.group_gen, basis_element}, row) - .output; - row += exp_component::rows_amount; - - denominator = zk::components::generate_circuit(bp, assignment, - {params.x, denominator}, row) - .output; - row += sub_component::rows_amount; - - var numerator = - exp_component::generate_circuit(bp, assignment, {params.x, domain_size}, row).output; - row += exp_component::rows_amount; - numerator = - zk::components::generate_circuit(bp, assignment, {numerator, one}, row) - .output; - row += sub_component::rows_amount; - - var res = zk::components::generate_circuit(bp, assignment, - {numerator, denominator}, row) - .output; - row += div_component::rows_amount; + namespace blueprint { + namespace components { + + // Compute the ith unnormalized lagrange basis + // https://github.com/o1-labs/proof-systems/blob/1f8532ec1b8d43748a372632bd854be36b371afe/kimchi/src/circuits/expr.rs#L150 + // Input: group generator (w), + // i, + // domain_size, + // evaluation point (x) + // Output: (x^domain_size - 1) / (x - w^i) + template + class unnormalized_lagrange_basis; + + template + class unnormalized_lagrange_basis, + W0, + W1, + W2, + W3, + W4, + W5, + W6, + W7, + W8, + W9, + W10, + W11, + W12, + W13, + W14> { + + typedef crypto3::zk::snark::plonk_constraint_system ArithmetizationType; + + using var = crypto3::zk::snark::plonk_variable; + + using sub_component = + subtraction>; + using exp_component = exponentiation; + using div_component = + division>; + + constexpr static const std::size_t selector_seed = 0x0f25; + + constexpr static const std::size_t zk_rows = 3; + + public: + constexpr static const std::size_t rows_amount = + 3 + 2 * exp_component::rows_amount + 2 * sub_component::rows_amount + div_component::rows_amount; + constexpr static const std::size_t gates_amount = 0; + + struct params_type { + var group_gen; + std::size_t domain_size; + var x; + int i; + }; - assert(row == start_row_index + rows_amount); + struct result_type { + var output; - return result_type(start_row_index); + result_type(std::size_t start_row_index) { + std::size_t row = start_row_index + rows_amount - div_component::rows_amount; + output = typename div_component::result_type(row).output; } + }; - static result_type generate_assignments(blueprint_assignment_table &assignment, - const params_type ¶ms, - const std::size_t start_row_index) { - - var domain_size(0, start_row_index, false, var::column_type::constant); - var basis_element(0, start_row_index + 1, false, var::column_type::constant); - var one(0, start_row_index + 2, false, var::column_type::constant); - - std::size_t row = start_row_index; - row += 3; // skip row for constants in exp_component - - var denominator = - exp_component::generate_assignments(assignment, {params.group_gen, basis_element}, row) - .output; - row += exp_component::rows_amount; - - denominator = - sub_component::generate_assignments(assignment, {params.x, denominator}, row).output; - row += sub_component::rows_amount; + static result_type generate_circuit(blueprint &bp, + assignment &assignment, + const params_type ¶ms, + const std::size_t start_row_index) { - var numerator = - exp_component::generate_assignments(assignment, {params.x, domain_size}, row).output; - row += exp_component::rows_amount; - numerator = sub_component::generate_assignments(assignment, {numerator, one}, row).output; - row += sub_component::rows_amount; + generate_assignments_constants(bp, assignment, params, start_row_index); - var res = div_component::generate_assignments(assignment, {numerator, denominator}, row).output; - row += div_component::rows_amount; + var domain_size(0, start_row_index, false, var::column_type::constant); + var basis_element(0, start_row_index + 1, false, var::column_type::constant); + var one(0, start_row_index + 2, false, var::column_type::constant); - assert(row == start_row_index + rows_amount); + std::size_t row = start_row_index; + row += 3; // skip row for constants in exp_component - return result_type(start_row_index); - } + var denominator = + exp_component::generate_circuit(bp, assignment, {params.group_gen, basis_element}, row).output; + row += exp_component::rows_amount; - private: - static void generate_assignments_constants( - blueprint &bp, - blueprint_public_assignment_table &assignment, - const params_type ¶ms, - const std::size_t start_row_index) { - std::size_t row = start_row_index; - assignment.constant(0)[row] = params.domain_size; - row++; - assignment.constant(0)[row] = - params.i >= 0 ? params.i : params.domain_size - std::size_t(-params.i); - row++; - assignment.constant(0)[row] = 1; - } - }; - } // namespace components - } // namespace blueprint - } // namespace crypto3 + denominator = ::nil::blueprint::components::generate_circuit( + bp, assignment, {params.x, denominator}, row) + .output; + row += sub_component::rows_amount; + + var numerator = + exp_component::generate_circuit(bp, assignment, {params.x, domain_size}, row).output; + row += exp_component::rows_amount; + numerator = ::nil::blueprint::components::generate_circuit( + bp, assignment, {numerator, one}, row) + .output; + row += sub_component::rows_amount; + + var res = ::nil::blueprint::components::generate_circuit( + bp, assignment, {numerator, denominator}, row) + .output; + row += div_component::rows_amount; + + assert(row == start_row_index + rows_amount); + + return result_type(start_row_index); + } + + static result_type generate_assignments(assignment &assignment, + const params_type ¶ms, + const std::size_t start_row_index) { + + var domain_size(0, start_row_index, false, var::column_type::constant); + var basis_element(0, start_row_index + 1, false, var::column_type::constant); + var one(0, start_row_index + 2, false, var::column_type::constant); + + std::size_t row = start_row_index; + row += 3; // skip row for constants in exp_component + + var denominator = + exp_component::generate_assignments(assignment, {params.group_gen, basis_element}, row).output; + row += exp_component::rows_amount; + + denominator = sub_component::generate_assignments(assignment, {params.x, denominator}, row).output; + row += sub_component::rows_amount; + + var numerator = + exp_component::generate_assignments(assignment, {params.x, domain_size}, row).output; + row += exp_component::rows_amount; + numerator = sub_component::generate_assignments(assignment, {numerator, one}, row).output; + row += sub_component::rows_amount; + + var res = div_component::generate_assignments(assignment, {numerator, denominator}, row).output; + row += div_component::rows_amount; + + assert(row == start_row_index + rows_amount); + + return result_type(start_row_index); + } + + private: + static void generate_assignments_constants(blueprint &bp, + assignment &assignment, + const params_type ¶ms, + const std::size_t start_row_index) { + std::size_t row = start_row_index; + assignment.constant(0)[row] = params.domain_size; + row++; + assignment.constant(0)[row] = + params.i >= 0 ? params.i : params.domain_size - std::size_t(-params.i); + row++; + assignment.constant(0)[row] = 1; + } + }; + } // namespace components + } // namespace blueprint } // namespace nil #endif // CRYPTO3_BLUEPRINT_COMPONENTS_PLONK_KIMCHI_DETAIL_CONSTRAINTS_UNNORMALIZED_LAGRANGE_BASIS_HPP diff --git a/include/nil/blueprint/components/systems/snark/plonk/kimchi/detail/constraints/vanishes_on_last_4_rows.hpp b/include/nil/blueprint/components/systems/snark/plonk/kimchi/detail/constraints/vanishes_on_last_4_rows.hpp index a110dd8a0..f5f9cada1 100644 --- a/include/nil/blueprint/components/systems/snark/plonk/kimchi/detail/constraints/vanishes_on_last_4_rows.hpp +++ b/include/nil/blueprint/components/systems/snark/plonk/kimchi/detail/constraints/vanishes_on_last_4_rows.hpp @@ -33,182 +33,209 @@ #include #include -#include +#include +#include #include -#include +#include namespace nil { - namespace crypto3 { - namespace blueprint { - namespace components { - - // (x - w^{n - 4}) (x - w^{n - 3}) * (x - w^{n - 2}) * (x - w^{n - 1}) - // https://github.com/o1-labs/proof-systems/blob/1f8532ec1b8d43748a372632bd854be36b371afe/kimchi/src/circuits/polynomials/permutation.rs#L64 - // Input: group generator (w), - // domain size (n), - // evaluation point (x) - // Output: (x - w^{n - 4}) (x - w^{n - 3}) * (x - w^{n - 2}) * (x - w^{n - 1}) - template - class vanishes_on_last_4_rows; - - template - class vanishes_on_last_4_rows, - W0, W1, W2, W3, W4, W5, W6, W7, W8, W9, W10, W11, W12, W13, W14> { - - typedef snark::plonk_constraint_system - ArithmetizationType; - - using var = snark::plonk_variable; - - using mul_component = zk::components::multiplication; - using exp_component = zk::components::exponentiation; - using sub_component = zk::components::subtraction; - - constexpr static const std::size_t selector_seed = 0x0f25; - - constexpr static const std::size_t zk_rows = 3; - - public: - constexpr static const std::size_t rows_amount = 1 + exp_component::rows_amount + - 6 * mul_component::rows_amount + - 4 * sub_component::rows_amount; - constexpr static const std::size_t gates_amount = 0; - - struct params_type { - var group_gen; - std::size_t domain_size; - var x; - }; - - struct result_type { - var output; - - result_type(std::size_t start_row_index) { - std::size_t row = start_row_index; - } - }; - - static result_type - generate_circuit(blueprint &bp, - blueprint_public_assignment_table &assignment, - const params_type ¶ms, - const std::size_t start_row_index) { - - generate_assignments_constants(bp, assignment, params, start_row_index); - - var domain_size = var(0, start_row_index, false, var::column_type::constant); - - std::size_t row = start_row_index; - row++; // skip row for constants in exp_component - - result_type result(row); - - var w1 = exp_component::generate_circuit(bp, assignment, {params.group_gen, domain_size}, row) - .output; - row += exp_component::rows_amount; - var w2 = - zk::components::generate_circuit(bp, assignment, {w1, params.group_gen}, row) - .output; - row += mul_component::rows_amount; - var w3 = - zk::components::generate_circuit(bp, assignment, {w2, params.group_gen}, row) - .output; - row += mul_component::rows_amount; - var w4 = - zk::components::generate_circuit(bp, assignment, {w3, params.group_gen}, row) - .output; - row += mul_component::rows_amount; - - var a1 = - zk::components::generate_circuit(bp, assignment, {params.x, w1}, row).output; - row += sub_component::rows_amount; - var a2 = - zk::components::generate_circuit(bp, assignment, {params.x, w2}, row).output; - row += sub_component::rows_amount; - var a3 = - zk::components::generate_circuit(bp, assignment, {params.x, w3}, row).output; - row += sub_component::rows_amount; - var a4 = - zk::components::generate_circuit(bp, assignment, {params.x, w4}, row).output; - row += sub_component::rows_amount; - - var ans1 = - zk::components::generate_circuit(bp, assignment, {a1, a2}, row).output; - row += mul_component::rows_amount; - var ans2 = - zk::components::generate_circuit(bp, assignment, {ans1, a3}, row).output; - row += mul_component::rows_amount; - result.output = - zk::components::generate_circuit(bp, assignment, {ans2, a4}, row).output; - row += mul_component::rows_amount; - - assert(row == start_row_index + rows_amount); - - return result; - } - - static result_type generate_assignments(blueprint_assignment_table &assignment, - const params_type ¶ms, - const std::size_t start_row_index) { - - var domain_size = var(0, start_row_index, false, var::column_type::constant); + namespace blueprint { + namespace components { + + // (x - w^{n - 4}) (x - w^{n - 3}) * (x - w^{n - 2}) * (x - w^{n - 1}) + // https://github.com/o1-labs/proof-systems/blob/1f8532ec1b8d43748a372632bd854be36b371afe/kimchi/src/circuits/polynomials/permutation.rs#L64 + // Input: group generator (w), + // domain size (n), + // evaluation point (x) + // Output: (x - w^{n - 4}) (x - w^{n - 3}) * (x - w^{n - 2}) * (x - w^{n - 1}) + template + class vanishes_on_last_4_rows; + + template + class vanishes_on_last_4_rows, + W0, + W1, + W2, + W3, + W4, + W5, + W6, + W7, + W8, + W9, + W10, + W11, + W12, + W13, + W14> { + + typedef crypto3::zk::snark::plonk_constraint_system ArithmetizationType; + + using var = crypto3::zk::snark::plonk_variable; + + using mul_component = multiplication>; + using exp_component = exponentiation; + using sub_component = + subtraction>; + + constexpr static const std::size_t selector_seed = 0x0f25; + + constexpr static const std::size_t zk_rows = 3; + + public: + constexpr static const std::size_t rows_amount = + 1 + exp_component::rows_amount + 6 * mul_component::rows_amount + 4 * sub_component::rows_amount; + constexpr static const std::size_t gates_amount = 0; + + struct params_type { + var group_gen; + std::size_t domain_size; + var x; + }; - std::size_t row = start_row_index; - row++; // skip row for constants in exp_component - - result_type result(row); - - var w1 = exp_component::generate_assignments(assignment, {params.group_gen, domain_size}, row) - .output; - row += exp_component::rows_amount; - var w2 = mul_component::generate_assignments(assignment, {w1, params.group_gen}, row).output; - row += mul_component::rows_amount; - var w3 = mul_component::generate_assignments(assignment, {w2, params.group_gen}, row).output; - row += mul_component::rows_amount; - var w4 = mul_component::generate_assignments(assignment, {w3, params.group_gen}, row).output; - row += mul_component::rows_amount; - - var a1 = sub_component::generate_assignments(assignment, {params.x, w1}, row).output; - row += sub_component::rows_amount; - var a2 = sub_component::generate_assignments(assignment, {params.x, w2}, row).output; - row += sub_component::rows_amount; - var a3 = sub_component::generate_assignments(assignment, {params.x, w3}, row).output; - row += sub_component::rows_amount; - var a4 = sub_component::generate_assignments(assignment, {params.x, w4}, row).output; - row += sub_component::rows_amount; - - var ans1 = mul_component::generate_assignments(assignment, {a1, a2}, row).output; - row += mul_component::rows_amount; - var ans2 = mul_component::generate_assignments(assignment, {ans1, a3}, row).output; - row += mul_component::rows_amount; - result.output = mul_component::generate_assignments(assignment, {ans2, a4}, row).output; - row += mul_component::rows_amount; - - assert(row == start_row_index + rows_amount); - - return result; - } + struct result_type { + var output; - private: - static void generate_assignments_constants( - blueprint &bp, - blueprint_public_assignment_table &assignment, - const params_type ¶ms, - const std::size_t start_row_index) { + result_type(std::size_t start_row_index) { std::size_t row = start_row_index; - assignment.constant(0)[row] = params.domain_size - zk_rows - 1; } }; - } // namespace components - } // namespace blueprint - } // namespace crypto3 + + static result_type generate_circuit(blueprint &bp, + assignment &assignment, + const params_type ¶ms, + const std::size_t start_row_index) { + + generate_assignments_constants(bp, assignment, params, start_row_index); + + var domain_size = var(0, start_row_index, false, var::column_type::constant); + + std::size_t row = start_row_index; + row++; // skip row for constants in exp_component + + result_type result(row); + + var w1 = + exp_component::generate_circuit(bp, assignment, {params.group_gen, domain_size}, row).output; + row += exp_component::rows_amount; + var w2 = ::nil::blueprint::components::generate_circuit( + bp, assignment, {w1, params.group_gen}, row) + .output; + row += mul_component::rows_amount; + var w3 = ::nil::blueprint::components::generate_circuit( + bp, assignment, {w2, params.group_gen}, row) + .output; + row += mul_component::rows_amount; + var w4 = ::nil::blueprint::components::generate_circuit( + bp, assignment, {w3, params.group_gen}, row) + .output; + row += mul_component::rows_amount; + + var a1 = ::nil::blueprint::components::generate_circuit( + bp, assignment, {params.x, w1}, row) + .output; + row += sub_component::rows_amount; + var a2 = ::nil::blueprint::components::generate_circuit( + bp, assignment, {params.x, w2}, row) + .output; + row += sub_component::rows_amount; + var a3 = ::nil::blueprint::components::generate_circuit( + bp, assignment, {params.x, w3}, row) + .output; + row += sub_component::rows_amount; + var a4 = ::nil::blueprint::components::generate_circuit( + bp, assignment, {params.x, w4}, row) + .output; + row += sub_component::rows_amount; + + var ans1 = + ::nil::blueprint::components::generate_circuit(bp, assignment, {a1, a2}, row) + .output; + row += mul_component::rows_amount; + var ans2 = + ::nil::blueprint::components::generate_circuit(bp, assignment, {ans1, a3}, row) + .output; + row += mul_component::rows_amount; + result.output = + ::nil::blueprint::components::generate_circuit(bp, assignment, {ans2, a4}, row) + .output; + row += mul_component::rows_amount; + + assert(row == start_row_index + rows_amount); + + return result; + } + + static result_type generate_assignments(assignment &assignment, + const params_type ¶ms, + const std::size_t start_row_index) { + + var domain_size = var(0, start_row_index, false, var::column_type::constant); + + std::size_t row = start_row_index; + row++; // skip row for constants in exp_component + + result_type result(row); + + var w1 = + exp_component::generate_assignments(assignment, {params.group_gen, domain_size}, row).output; + row += exp_component::rows_amount; + var w2 = mul_component::generate_assignments(assignment, {w1, params.group_gen}, row).output; + row += mul_component::rows_amount; + var w3 = mul_component::generate_assignments(assignment, {w2, params.group_gen}, row).output; + row += mul_component::rows_amount; + var w4 = mul_component::generate_assignments(assignment, {w3, params.group_gen}, row).output; + row += mul_component::rows_amount; + + var a1 = sub_component::generate_assignments(assignment, {params.x, w1}, row).output; + row += sub_component::rows_amount; + var a2 = sub_component::generate_assignments(assignment, {params.x, w2}, row).output; + row += sub_component::rows_amount; + var a3 = sub_component::generate_assignments(assignment, {params.x, w3}, row).output; + row += sub_component::rows_amount; + var a4 = sub_component::generate_assignments(assignment, {params.x, w4}, row).output; + row += sub_component::rows_amount; + + var ans1 = mul_component::generate_assignments(assignment, {a1, a2}, row).output; + row += mul_component::rows_amount; + var ans2 = mul_component::generate_assignments(assignment, {ans1, a3}, row).output; + row += mul_component::rows_amount; + result.output = mul_component::generate_assignments(assignment, {ans2, a4}, row).output; + row += mul_component::rows_amount; + + assert(row == start_row_index + rows_amount); + + return result; + } + + private: + static void generate_assignments_constants(blueprint &bp, + assignment &assignment, + const params_type ¶ms, + const std::size_t start_row_index) { + std::size_t row = start_row_index; + assignment.constant(0)[row] = params.domain_size - zk_rows - 1; + } + }; + } // namespace components + } // namespace blueprint } // namespace nil #endif // CRYPTO3_BLUEPRINT_COMPONENTS_PLONK_KIMCHI_DETAIL_CONSTRAINTS_VANISHES_ON_LAST_4_ROWS_HPP diff --git a/include/nil/blueprint/components/systems/snark/plonk/kimchi/detail/inner_constants.hpp b/include/nil/blueprint/components/systems/snark/plonk/kimchi/detail/inner_constants.hpp index c3689c8f5..9330a192d 100644 --- a/include/nil/blueprint/components/systems/snark/plonk/kimchi/detail/inner_constants.hpp +++ b/include/nil/blueprint/components/systems/snark/plonk/kimchi/detail/inner_constants.hpp @@ -35,54 +35,52 @@ #include namespace nil { - namespace crypto3 { - namespace blueprint { - namespace components { - template - struct kimchi_inner_constants { + namespace blueprint { + namespace components { + template + struct kimchi_inner_constants { - public: - using commitment_params_type = typename KimchiParamsType::commitment_params_type; + public: + using commitment_params_type = typename KimchiParamsType::commitment_params_type; - constexpr static std::size_t ft_generic_size = 2 * 5; - constexpr static std::size_t permutation_constraints = 3; + constexpr static std::size_t ft_generic_size = 2 * 5; + constexpr static std::size_t permutation_constraints = 3; - constexpr static std::size_t evaluations_in_batch_size = - KimchiParamsType::prev_challenges_size // recursion - + 1 // p_comm - + 1 // ft_comm - + 1 // z_comm - + 1 // generic_comm - + 1 // psm_comm - + KimchiParamsType::witness_columns // w_comm - + KimchiParamsType::permut_size - 1 + KimchiParamsType::lookup_comm_size; + constexpr static std::size_t evaluations_in_batch_size = + KimchiParamsType::prev_challenges_size // recursion + + 1 // p_comm + + 1 // ft_comm + + 1 // z_comm + + 1 // generic_comm + + 1 // psm_comm + + KimchiParamsType::witness_columns // w_comm + + KimchiParamsType::permut_size - 1 + KimchiParamsType::lookup_comm_size; - constexpr static std::size_t srs_padding_size() { - std::size_t srs_two_power = 1 << (boost::static_log2::value); - std::size_t padding_size = srs_two_power == commitment_params_type::srs_len ? - 0 : - srs_two_power * 2 - commitment_params_type::srs_len; - return padding_size; - } + constexpr static std::size_t srs_padding_size() { + std::size_t srs_two_power = 1 << (boost::static_log2::value); + std::size_t padding_size = srs_two_power == commitment_params_type::srs_len ? + 0 : + srs_two_power * 2 - commitment_params_type::srs_len; + return padding_size; + } - constexpr static std::size_t final_msm_size(const std::size_t batch_size) { - return 1 // H - + commitment_params_type::srs_len // G - + srs_padding_size() + - (1 // opening.G - + 1 // U - + 2 * commitment_params_type::eval_rounds + - evaluations_in_batch_size * commitment_params_type::shifted_commitment_split + 1 // U - + 1) // opening.delta - * batch_size; - } + constexpr static std::size_t final_msm_size(const std::size_t batch_size) { + return 1 // H + + commitment_params_type::srs_len // G + + srs_padding_size() + + (1 // opening.G + + 1 // U + + 2 * commitment_params_type::eval_rounds + + evaluations_in_batch_size * commitment_params_type::shifted_commitment_split + 1 // U + + 1) // opening.delta + * batch_size; + } - constexpr static std::size_t f_comm_msm_size = - 1 + ft_generic_size + KimchiParamsType::circuit_params::index_terms_list::size; - }; - } // namespace components - } // namespace blueprint - } // namespace crypto3 + constexpr static std::size_t f_comm_msm_size = + 1 + ft_generic_size + KimchiParamsType::circuit_params::index_terms_list::size; + }; + } // namespace components + } // namespace blueprint } // namespace nil #endif // CRYPTO3_BLUEPRINT_COMPONENTS_PLONK_KIMCHI_INNER_CONSTANTS_HPP \ No newline at end of file diff --git a/include/nil/blueprint/components/systems/snark/plonk/kimchi/detail/limbs.hpp b/include/nil/blueprint/components/systems/snark/plonk/kimchi/detail/limbs.hpp index d5869971d..364cfd356 100644 --- a/include/nil/blueprint/components/systems/snark/plonk/kimchi/detail/limbs.hpp +++ b/include/nil/blueprint/components/systems/snark/plonk/kimchi/detail/limbs.hpp @@ -58,8 +58,8 @@ namespace nil { class from_limbs; template - class from_limbs>: - public plonk_component { + class from_limbs> + : public plonk_component { public: using component_type = plonk_component; @@ -73,22 +73,19 @@ namespace nil { } }; - static gate_manifest get_gate_manifest(std::size_t witness_amount, - std::size_t lookup_column_amount) { + static gate_manifest get_gate_manifest(std::size_t witness_amount, std::size_t lookup_column_amount) { static gate_manifest manifest = gate_manifest(gate_manifest_type()); return manifest; } static manifest_type get_manifest() { - static manifest_type manifest = manifest_type( - std::shared_ptr(new manifest_single_value_param(3)), - false - ); + static manifest_type manifest = + manifest_type(std::shared_ptr(new manifest_single_value_param(3)), false); return manifest; } constexpr static std::size_t get_rows_amount(std::size_t witness_amount, - std::size_t lookup_column_amount) { + std::size_t lookup_column_amount) { return 1; } @@ -112,7 +109,8 @@ namespace nil { var result = var(0, 0); result_type(const from_limbs &component, std::size_t start_row_index) { - result = var(component.W(2), static_cast(start_row_index), false, var::column_type::witness); + result = + var(component.W(2), static_cast(start_row_index), false, var::column_type::witness); } std::vector> all_vars() { @@ -120,28 +118,27 @@ namespace nil { } }; - template - from_limbs(ContainerType witness): - component_type(witness, {}, {}, get_manifest()){}; - - template - from_limbs(WitnessContainerType witness, ConstantContainerType constant, PublicInputContainerType public_input): - component_type(witness, constant, public_input, get_manifest()){}; + template + from_limbs(ContainerType witness) : component_type(witness, {}, {}, get_manifest()) {}; - from_limbs( - std::initializer_list witnesses, - std::initializer_list constants, - std::initializer_list public_inputs): - component_type(witnesses, constants, public_inputs, get_manifest()){}; + template + from_limbs(WitnessContainerType witness, ConstantContainerType constant, + PublicInputContainerType public_input) : + component_type(witness, constant, public_input, get_manifest()) {}; + from_limbs(std::initializer_list witnesses, + std::initializer_list + constants, + std::initializer_list + public_inputs) : component_type(witnesses, constants, public_inputs, get_manifest()) {}; }; template using plonk_from_limbs = from_limbs>; template - typename plonk_from_limbs::result_type - generate_circuit( + typename plonk_from_limbs::result_type generate_circuit( const plonk_from_limbs &component, circuit> &bp, assignment> &assignment, @@ -158,15 +155,14 @@ namespace nil { } template - typename plonk_from_limbs::result_type - generate_assignments( + typename plonk_from_limbs::result_type generate_assignments( const plonk_from_limbs &component, assignment> &assignment, const typename plonk_from_limbs::input_type &instance_input, const std::uint32_t start_row_index) { std::size_t row = start_row_index; - typename BlueprintFieldType::value_type first_limb = var_value(assignment, instance_input.first_limb); + typename BlueprintFieldType::value_type first_limb = var_value(assignment, instance_input.first_limb); typename BlueprintFieldType::value_type second_limb = var_value(assignment, instance_input.second_limb); assignment.witness(component.W(0), row) = first_limb; assignment.witness(component.W(1), row) = second_limb; @@ -178,14 +174,11 @@ namespace nil { } template - std::size_t generate_gates( - const plonk_from_limbs &component, - circuit> - &bp, - assignment> - &assignment, - const typename plonk_from_limbs::input_type - &instance_input) { + std::size_t + generate_gates(const plonk_from_limbs &component, + circuit> &bp, + assignment> &assignment, + const typename plonk_from_limbs::input_type &instance_input) { using var = typename plonk_from_limbs::var; @@ -197,19 +190,19 @@ namespace nil { } template - void generate_copy_constraints( + void generate_copy_constraints( const plonk_from_limbs &component, circuit> &bp, assignment> &assignment, const typename plonk_from_limbs::input_type &instance_input, const std::uint32_t start_row_index) { - bp.add_copy_constraint( - {{component.W(0), static_cast(start_row_index), false}, - {instance_input.first_limb.index, instance_input.first_limb.rotation, false, instance_input.first_limb.type}}); - bp.add_copy_constraint( - {{component.W(1), static_cast(start_row_index), false}, - {instance_input.second_limb.index, instance_input.second_limb.rotation, false, instance_input.second_limb.type}}); + bp.add_copy_constraint({{component.W(0), static_cast(start_row_index), false}, + {instance_input.first_limb.index, instance_input.first_limb.rotation, false, + instance_input.first_limb.type}}); + bp.add_copy_constraint({{component.W(1), static_cast(start_row_index), false}, + {instance_input.second_limb.index, instance_input.second_limb.rotation, false, + instance_input.second_limb.type}}); } /////////////// To Limbs //////////////////////////////// @@ -223,9 +216,8 @@ namespace nil { class to_limbs; template - class to_limbs>: - public plonk_component { - + class to_limbs> + : public plonk_component { constexpr static const std::size_t chunk_size = 64; using range_check_component = nil::blueprint::components::range_check< @@ -243,29 +235,25 @@ namespace nil { } }; - static gate_manifest get_gate_manifest(std::size_t witness_amount, - std::size_t lookup_column_amount) { - static gate_manifest manifest = - gate_manifest(gate_manifest_type()) - .merge_with(range_check_component::get_gate_manifest(witness_amount, - lookup_column_amount, - chunk_size)); + static gate_manifest get_gate_manifest(std::size_t witness_amount, std::size_t lookup_column_amount) { + static gate_manifest manifest = gate_manifest(gate_manifest_type()) + .merge_with(range_check_component::get_gate_manifest( + witness_amount, lookup_column_amount, chunk_size)); return manifest; } static manifest_type get_manifest() { - static manifest_type manifest = manifest_type( - std::shared_ptr(new manifest_single_value_param(15)), - false - ).merge_with(range_check_component::get_manifest()); + static manifest_type manifest = + manifest_type(std::shared_ptr(new manifest_single_value_param(15)), false) + .merge_with(range_check_component::get_manifest()); return manifest; } constexpr static std::size_t get_rows_amount(std::size_t witness_amount, std::size_t lookup_column_amount) { - return 1 + 2 * chunk_amount * - range_check_component::get_rows_amount(witness_amount, lookup_column_amount, - chunk_size); + return 1 + + 2 * chunk_amount * + range_check_component::get_rows_amount(witness_amount, lookup_column_amount, chunk_size); } constexpr static const std::size_t chunk_size_public = chunk_size; @@ -289,10 +277,11 @@ namespace nil { std::array result; result_type(const to_limbs &component, std::size_t start_row_index) { - result = {var(component.W(1), static_cast(start_row_index), false, var::column_type::witness), - var(component.W(2), static_cast(start_row_index), false, var::column_type::witness), - var(component.W(3), static_cast(start_row_index), false, var::column_type::witness), - var(component.W(4), static_cast(start_row_index), false, var::column_type::witness)}; + result = { + var(component.W(1), static_cast(start_row_index), false, var::column_type::witness), + var(component.W(2), static_cast(start_row_index), false, var::column_type::witness), + var(component.W(3), static_cast(start_row_index), false, var::column_type::witness), + var(component.W(4), static_cast(start_row_index), false, var::column_type::witness)}; } std::vector> all_vars() { @@ -300,27 +289,27 @@ namespace nil { } }; - template - to_limbs(ContainerType witness): - component_type(witness, {}, {}, get_manifest()){}; + template + to_limbs(ContainerType witness) : component_type(witness, {}, {}, get_manifest()) {}; - template - to_limbs(WitnessContainerType witness, ConstantContainerType constant, PublicInputContainerType public_input): - component_type(witness, constant, public_input, get_manifest()){}; + template + to_limbs(WitnessContainerType witness, ConstantContainerType constant, + PublicInputContainerType public_input) : + component_type(witness, constant, public_input, get_manifest()) {}; - to_limbs( - std::initializer_list witnesses, - std::initializer_list constants, - std::initializer_list public_inputs): - component_type(witnesses, constants, public_inputs, get_manifest()){}; + to_limbs(std::initializer_list witnesses, + std::initializer_list + constants, + std::initializer_list + public_inputs) : component_type(witnesses, constants, public_inputs, get_manifest()) {}; }; template using plonk_to_limbs = to_limbs>; template - typename plonk_to_limbs::result_type - generate_circuit( + typename plonk_to_limbs::result_type generate_circuit( const plonk_to_limbs &component, circuit> &bp, assignment> &assignment, @@ -332,9 +321,10 @@ namespace nil { using ArithmetizationType = crypto3::zk::snark::plonk_constraint_system; using component_type = plonk_to_limbs; range_check range_check_instance( - {component.W(0), component.W(1), component.W(2), component.W(3), component.W(4), - component.W(5), component.W(6), component.W(7), component.W(8), component.W(9), - component.W(10), component.W(11), component.W(12), component.W(13), component.W(14)},{component.C(0)},{},component_type::chunk_size_public); + {component.W(0), component.W(1), component.W(2), component.W(3), component.W(4), component.W(5), + component.W(6), component.W(7), component.W(8), component.W(9), component.W(10), component.W(11), + component.W(12), component.W(13), component.W(14)}, + {component.C(0)}, {}, component_type::chunk_size_public); std::size_t selector_index = generate_gates(component, bp, assignment, instance_input); @@ -342,17 +332,11 @@ namespace nil { std::size_t row = start_row_index; std::array chunks = { - var(component.W(1), row, false), - var(component.W(2), row, false), - var(component.W(3), row, false), - var(component.W(4), row, false) - }; + var(component.W(1), row, false), var(component.W(2), row, false), var(component.W(3), row, false), + var(component.W(4), row, false)}; std::array b_chunks_vars = { - var(component.W(5), row, false), - var(component.W(6), row, false), - var(component.W(7), row, false), - var(component.W(8), row, false) - }; + var(component.W(5), row, false), var(component.W(6), row, false), var(component.W(7), row, false), + var(component.W(8), row, false)}; row++; @@ -366,12 +350,10 @@ namespace nil { generate_copy_constraints(component, bp, assignment, instance_input, start_row_index); return typename plonk_to_limbs::result_type(component, start_row_index); - } template - typename plonk_to_limbs::result_type - generate_assignments( + typename plonk_to_limbs::result_type generate_assignments( const plonk_to_limbs &component, assignment> &assignment, const typename plonk_to_limbs::input_type instance_input, @@ -382,9 +364,10 @@ namespace nil { using ArithmetizationType = crypto3::zk::snark::plonk_constraint_system; using component_type = plonk_to_limbs; range_check range_check_instance( - {component.W(0), component.W(1), component.W(2), component.W(3), component.W(4), - component.W(5), component.W(6), component.W(7), component.W(8), component.W(9), - component.W(10), component.W(11), component.W(12), component.W(13), component.W(14)},{component.C(0)},{},component_type::chunk_size_public); + {component.W(0), component.W(1), component.W(2), component.W(3), component.W(4), component.W(5), + component.W(6), component.W(7), component.W(8), component.W(9), component.W(10), component.W(11), + component.W(12), component.W(13), component.W(14)}, + {component.C(0)}, {}, component_type::chunk_size_public); std::size_t row = start_row_index; typename BlueprintFieldType::value_type value = var_value(assignment, instance_input.param); @@ -419,28 +402,26 @@ namespace nil { assignment.witness(component.W(8), row) = b_chunks[3]; assignment.witness(component.W(9), row) = (typename BlueprintFieldType::extended_integral_type(assignment.witness(component.W(1), row).data) + - c_chunks[0] - b_chunks[0]) >> + c_chunks[0] - b_chunks[0]) >> 64; assignment.witness(component.W(10), row) = (typename BlueprintFieldType::extended_integral_type(assignment.witness(component.W(2), row).data) + - c_chunks[1] - b_chunks[1] + - typename BlueprintFieldType::extended_integral_type(assignment.witness(component.W(9), row).data)) >> + c_chunks[1] - b_chunks[1] + + typename BlueprintFieldType::extended_integral_type( + assignment.witness(component.W(9), row).data)) >> 64; assignment.witness(component.W(11), row) = (typename BlueprintFieldType::extended_integral_type(assignment.witness(component.W(3), row).data) + - c_chunks[2] - b_chunks[2] + - typename BlueprintFieldType::extended_integral_type(assignment.witness(component.W(10), row).data)) >> + c_chunks[2] - b_chunks[2] + + typename BlueprintFieldType::extended_integral_type( + assignment.witness(component.W(10), row).data)) >> 64; std::array chunks = { - var(component.W(1), row, false), - var(component.W(2), row, false), - var(component.W(3), row, false), + var(component.W(1), row, false), var(component.W(2), row, false), var(component.W(3), row, false), var(component.W(4), row, false)}; std::array b_chunks_vars = { - var(component.W(5), row, false), - var(component.W(6), row, false), - var(component.W(7), row, false), + var(component.W(5), row, false), var(component.W(6), row, false), var(component.W(7), row, false), var(component.W(8), row, false)}; row++; @@ -456,13 +437,11 @@ namespace nil { } template - std::size_t generate_gates( - const plonk_to_limbs &component, - circuit> &bp, - assignment> - &assignment, - const typename plonk_to_limbs::input_type - &instance_input) { + std::size_t + generate_gates(const plonk_to_limbs &component, + circuit> &bp, + assignment> &assignment, + const typename plonk_to_limbs::input_type &instance_input) { using var = typename plonk_to_limbs::var; @@ -474,22 +453,19 @@ namespace nil { typename BlueprintFieldType::extended_integral_type mask = (one << 64) - 1; std::array c_chunks = { c & mask, (c >> 64) & mask, (c >> 128) & mask, (c >> 192) & mask}; - auto constraint_1 = - var(component.W(1), 0) + var(component.W(2), 0) * scalar.pow(64) + - var(component.W(3), 0) * scalar.pow(128) + var(component.W(4), 0) * scalar.pow(192) - - var(component.W(0), 0); - auto constraint_2 = - -var(component.W(1), 0) - typename BlueprintFieldType::value_type(c_chunks[0]) + - var(component.W(5), 0) + var(component.W(9), 0) * (one << 64); - auto constraint_3 = - -var(component.W(2), 0) - typename BlueprintFieldType::value_type(c_chunks[1]) - - var(component.W(9), 0) + var(component.W(6), 0) + var(component.W(10), 0) * (one << 64); - auto constraint_4 = - -var(component.W(3), 0) - typename BlueprintFieldType::value_type(c_chunks[2]) - - var(component.W(10), 0) + var(component.W(7), 0) + var(component.W(11), 0) * (one << 64); - auto constraint_5 = - -var(component.W(4), 0) - typename BlueprintFieldType::value_type(c_chunks[3]) - - var(component.W(11), 0) + var(component.W(8), 0); + auto constraint_1 = var(component.W(1), 0) + var(component.W(2), 0) * scalar.pow(64) + + var(component.W(3), 0) * scalar.pow(128) + + var(component.W(4), 0) * scalar.pow(192) - var(component.W(0), 0); + auto constraint_2 = -var(component.W(1), 0) - typename BlueprintFieldType::value_type(c_chunks[0]) + + var(component.W(5), 0) + var(component.W(9), 0) * (one << 64); + auto constraint_3 = -var(component.W(2), 0) - typename BlueprintFieldType::value_type(c_chunks[1]) - + var(component.W(9), 0) + var(component.W(6), 0) + + var(component.W(10), 0) * (one << 64); + auto constraint_4 = -var(component.W(3), 0) - typename BlueprintFieldType::value_type(c_chunks[2]) - + var(component.W(10), 0) + var(component.W(7), 0) + + var(component.W(11), 0) * (one << 64); + auto constraint_5 = -var(component.W(4), 0) - typename BlueprintFieldType::value_type(c_chunks[3]) - + var(component.W(11), 0) + var(component.W(8), 0); auto constraint_6 = var(component.W(9), 0) * (var(component.W(9), 0) - 1); auto constraint_7 = var(component.W(10), 0) * (var(component.W(10), 0) - 1); @@ -507,8 +483,9 @@ namespace nil { const typename plonk_to_limbs::input_type &instance_input, const std::uint32_t start_row_index) { - bp.add_copy_constraint({{component.W(0), static_cast(start_row_index), false}, - {instance_input.param.index, instance_input.param.rotation, false, instance_input.param.type}}); + bp.add_copy_constraint( + {{component.W(0), static_cast(start_row_index), false}, + {instance_input.param.index, instance_input.param.rotation, false, instance_input.param.type}}); } template @@ -523,21 +500,21 @@ namespace nil { using component_type = plonk_to_limbs; using input_type = typename component_type::input_type; using var = typename nil::crypto3::zk::snark::plonk_variable; + public: - static input_type convert( - const input_type &input, - nil::blueprint::assignment> - &assignment, - nil::blueprint::assignment> - &tmp_assignment) { + static input_type + convert(const input_type &input, + nil::blueprint::assignment> + &assignment, + nil::blueprint::assignment> + &tmp_assignment) { input_type new_input(var(0, 0, false, var::column_type::public_input)); tmp_assignment.public_input(0, 0) = var_value(assignment, input.param); return new_input; } - static var deconvert_var(const input_type &input, - var variable) { + static var deconvert_var(const input_type &input, var variable) { BOOST_ASSERT(variable.type == var::column_type::public_input); return input.param; } @@ -550,17 +527,17 @@ namespace nil { using input_type = typename component_type::input_type; using result_type = typename component_type::result_type; using stretcher_type = component_stretcher; + public: static result_type convert(const stretcher_type &component, const result_type old_result, const input_type &instance_input, std::size_t start_row_index) { result_type new_result(component.component, start_row_index); for (std::size_t i = 0; i < 4; i++) { - new_result.result[i] = component.move_var( - old_result.result[i], - start_row_index + component.line_mapping[old_result.result[i].rotation], - instance_input - ); + new_result.result[i] = + component.move_var(old_result.result[i], + start_row_index + component.line_mapping[old_result.result[i].rotation], + instance_input); } return new_result; diff --git a/include/nil/blueprint/components/systems/snark/plonk/kimchi/detail/map_fq.hpp b/include/nil/blueprint/components/systems/snark/plonk/kimchi/detail/map_fq.hpp index d9dcf17be..c53277198 100644 --- a/include/nil/blueprint/components/systems/snark/plonk/kimchi/detail/map_fq.hpp +++ b/include/nil/blueprint/components/systems/snark/plonk/kimchi/detail/map_fq.hpp @@ -37,109 +37,133 @@ #include #include -#include +#include #include #include namespace nil { - namespace crypto3 { - namespace blueprint { - namespace components { - - // map_fq set copy constraints between input fq_data (which is input for scalar field components) and - // recalculated fq_data (base field components output) - // Input: common data (generated by the base part of the veridier) for scalar and base verifiers - // Output: - - template - class map_fq; - - template - class map_fq, - CurveType, KimchiParamsType, KimchiCommitmentParamsType, BatchSize, - W0, W1, W2, W3, W4, W5, W6, W7, W8, W9, W10, W11, W12, W13, W14> { - - using BlueprintFieldType = typename CurveType::base_field_type; - - typedef snark::plonk_constraint_system - ArithmetizationType; - - using var = snark::plonk_variable; - - using proof_binding = - typename zk::components::binding; - - using fq_data = typename proof_binding::template fq_data; - - constexpr static const std::size_t selector_seed = 0x0f2D; - - public: - constexpr static const std::size_t rows_amount = 0; - constexpr static const std::size_t gates_amount = 0; - - struct params_type { - fq_data data_public; - fq_data data_recalculated; - }; - - struct result_type { }; - - static result_type - generate_circuit(blueprint &bp, - blueprint_public_assignment_table &assignment, - const params_type ¶ms, - const std::size_t start_row_index) { - std::size_t row = start_row_index; - - generate_assignments_constant(bp, assignment, params, start_row_index); - - return result_type(); - } - - static result_type generate_assignments(blueprint_assignment_table &assignment, - const params_type ¶ms, - std::size_t start_row_index) { - - std::size_t row = start_row_index; - - return result_type(); - } - - private: - static void generate_gates(blueprint &bp, - blueprint_public_assignment_table &assignment, - const params_type ¶ms, - std::size_t component_start_row = 0) { - } - - static void - generate_copy_constraints(blueprint &bp, - blueprint_public_assignment_table &assignment, - const params_type ¶ms, - std::size_t component_start_row = 0) { - } - - static void generate_assignments_constant( - blueprint &bp, - blueprint_public_assignment_table &assignment, - const params_type ¶ms, - std::size_t component_start_row) { - std::size_t row = component_start_row; - } + namespace blueprint { + namespace components { + + // map_fq set copy constraints between input fq_data (which is input for scalar field components) and + // recalculated fq_data (base field components output) + // Input: common data (generated by the base part of the veridier) for scalar and base verifiers + // Output: - + template + class map_fq; + + template + class map_fq, + CurveType, + KimchiParamsType, + KimchiCommitmentParamsType, + BatchSize, + W0, + W1, + W2, + W3, + W4, + W5, + W6, + W7, + W8, + W9, + W10, + W11, + W12, + W13, + W14> { + + using BlueprintFieldType = typename CurveType::base_field_type; + + typedef crypto3::zk::snark::plonk_constraint_system ArithmetizationType; + + using var = crypto3::zk::snark::plonk_variable; + + using proof_binding = typename binding; + + using fq_data = typename proof_binding::template fq_data; + + constexpr static const std::size_t selector_seed = 0x0f2D; + + public: + constexpr static const std::size_t rows_amount = 0; + constexpr static const std::size_t gates_amount = 0; + + struct params_type { + fq_data data_public; + fq_data data_recalculated; }; - } // namespace components - } // namespace blueprint - } // namespace crypto3 + + struct result_type { }; + + static result_type generate_circuit(blueprint &bp, + assignment &assignment, + const params_type ¶ms, + const std::size_t start_row_index) { + std::size_t row = start_row_index; + + generate_assignments_constant(bp, assignment, params, start_row_index); + + return result_type(); + } + + static result_type generate_assignments(assignment &assignment, + const params_type ¶ms, + std::size_t start_row_index) { + + std::size_t row = start_row_index; + + return result_type(); + } + + private: + static void generate_gates(blueprint &bp, + assignment &assignment, + const params_type ¶ms, + std::size_t component_start_row = 0) { + } + + static void generate_copy_constraints(blueprint &bp, + assignment &assignment, + const params_type ¶ms, + std::size_t component_start_row = 0) { + } + + static void generate_assignments_constant(blueprint &bp, + assignment &assignment, + const params_type ¶ms, + std::size_t component_start_row) { + std::size_t row = component_start_row; + } + }; + } // namespace components + } // namespace blueprint } // namespace nil #endif // CRYPTO3_BLUEPRINT_COMPONENTS_PLONK_KIMCHI_DETAIL_MAP_FQ_HPP \ No newline at end of file diff --git a/include/nil/blueprint/components/systems/snark/plonk/kimchi/detail/map_fr.hpp b/include/nil/blueprint/components/systems/snark/plonk/kimchi/detail/map_fr.hpp index 133ced02e..a0d36d016 100644 --- a/include/nil/blueprint/components/systems/snark/plonk/kimchi/detail/map_fr.hpp +++ b/include/nil/blueprint/components/systems/snark/plonk/kimchi/detail/map_fr.hpp @@ -37,7 +37,7 @@ #include #include -#include +#include #include diff --git a/include/nil/blueprint/components/systems/snark/plonk/kimchi/detail/oracles_scalar/b_poly.hpp b/include/nil/blueprint/components/systems/snark/plonk/kimchi/detail/oracles_scalar/b_poly.hpp index cac1cc843..5ed14adff 100644 --- a/include/nil/blueprint/components/systems/snark/plonk/kimchi/detail/oracles_scalar/b_poly.hpp +++ b/include/nil/blueprint/components/systems/snark/plonk/kimchi/detail/oracles_scalar/b_poly.hpp @@ -34,162 +34,187 @@ #include -#include -#include +#include +#include +#include namespace nil { - namespace crypto3 { - namespace blueprint { - namespace components { - - // Univariate polynomial at point - // https://github.com/o1-labs/proof-systems/blob/1f8532ec1b8d43748a372632bd854be36b371afe/poly-commitment/src/commitment.rs#L239 - // Input: challenges, x - // Output: (1 + challenges[-1] x)(1 + challenges[-2] x^2)(1 + challenges[-3] x^4)... - template - class b_poly; - - template - class b_poly, EvalRounds, W0, - W1, W2, W3, W4, W5, W6, W7, W8, W9, W10, W11, W12, W13, W14> { - - typedef snark::plonk_constraint_system - ArithmetizationType; - - using var = snark::plonk_variable; - - using mul_component = zk::components::multiplication; - using add_component = zk::components::addition; - - constexpr static const std::size_t selector_seed = 0xf20; - - public: - constexpr static const std::size_t rows_amount = (EvalRounds - 1) * mul_component::rows_amount - + EvalRounds * ( - mul_component::rows_amount + add_component::rows_amount + mul_component::rows_amount - ); - constexpr static const std::size_t gates_amount = 0; - - struct params_type { - std::array &challenges; - var eval_point; - var one; - }; - - struct result_type { - var output; - - result_type(std::size_t start_row_index) { - std::size_t row = start_row_index; - - for (std::size_t i = 1; i < EvalRounds; i++) { - row += mul_component::rows_amount; - } - var res; - for (std::size_t i = 0; i < EvalRounds; i++) { - row += mul_component::rows_amount; - - row += add_component::rows_amount; - - res = typename mul_component::result_type(row).output; - row += mul_component::rows_amount; - } - - output = res; - } - }; + namespace blueprint { + namespace components { + + // Univariate polynomial at point + // https://github.com/o1-labs/proof-systems/blob/1f8532ec1b8d43748a372632bd854be36b371afe/poly-commitment/src/commitment.rs#L239 + // Input: challenges, x + // Output: (1 + challenges[-1] x)(1 + challenges[-2] x^2)(1 + challenges[-3] x^4)... + template + class b_poly; + + template + class b_poly, + EvalRounds, + W0, + W1, + W2, + W3, + W4, + W5, + W6, + W7, + W8, + W9, + W10, + W11, + W12, + W13, + W14> { + + typedef crypto3::zk::snark::plonk_constraint_system ArithmetizationType; + + using var = crypto3::zk::snark::plonk_variable; + + using mul_component = multiplication>; + using add_component = + addition>; + + constexpr static const std::size_t selector_seed = 0xf20; + + public: + constexpr static const std::size_t rows_amount = + (EvalRounds - 1) * mul_component::rows_amount + + EvalRounds * (mul_component::rows_amount + add_component::rows_amount + mul_component::rows_amount); + constexpr static const std::size_t gates_amount = 0; + + struct params_type { + std::array &challenges; + var eval_point; + var one; + }; - static result_type - generate_circuit(blueprint &bp, - blueprint_public_assignment_table &assignment, - const params_type ¶ms, - const std::size_t start_row_index) { + struct result_type { + var output; + result_type(std::size_t start_row_index) { std::size_t row = start_row_index; - std::array pow_twos; - pow_twos[0] = params.eval_point; for (std::size_t i = 1; i < EvalRounds; i++) { - pow_twos[i] = zk::components::generate_circuit( - bp, assignment, {pow_twos[i - 1], pow_twos[i - 1]}, row) - .output; row += mul_component::rows_amount; } - var res = params.one; + var res; for (std::size_t i = 0; i < EvalRounds; i++) { - var mul_result = - zk::components::generate_circuit( - bp, assignment, {params.challenges[i], pow_twos[EvalRounds - 1 - i]}, row) - .output; row += mul_component::rows_amount; - var sum_result = zk::components::generate_circuit( - bp, assignment, {params.one, mul_result}, row) - .output; row += add_component::rows_amount; - res = - zk::components::generate_circuit(bp, assignment, {res, sum_result}, row) - .output; + res = typename mul_component::result_type(row).output; row += mul_component::rows_amount; } - generate_copy_constraints(bp, assignment, params, start_row_index); - return result_type(start_row_index); + output = res; } + }; - static result_type generate_assignments(blueprint_assignment_table &assignment, - const params_type ¶ms, - const std::size_t start_row_index) { + static result_type generate_circuit(blueprint &bp, + assignment &assignment, + const params_type ¶ms, + const std::size_t start_row_index) { - std::size_t row = start_row_index; + std::size_t row = start_row_index; - std::array pow_twos; - pow_twos[0] = params.eval_point; - for (std::size_t i = 1; i < EvalRounds; i++) { - pow_twos[i] = - mul_component::generate_assignments(assignment, {pow_twos[i - 1], pow_twos[i - 1]}, row) - .output; - row += mul_component::rows_amount; - } - var res = params.one; - for (std::size_t i = 0; i < EvalRounds; i++) { - var mul_result = mul_component::generate_assignments( - assignment, {params.challenges[i], pow_twos[EvalRounds - 1 - i]}, row) - .output; - row += mul_component::rows_amount; + std::array pow_twos; + pow_twos[0] = params.eval_point; + for (std::size_t i = 1; i < EvalRounds; i++) { + pow_twos[i] = ::nil::blueprint::components::generate_circuit( + bp, assignment, {pow_twos[i - 1], pow_twos[i - 1]}, row) + .output; + row += mul_component::rows_amount; + } + var res = params.one; + for (std::size_t i = 0; i < EvalRounds; i++) { + var mul_result = ::nil::blueprint::components::generate_circuit( + bp, assignment, {params.challenges[i], pow_twos[EvalRounds - 1 - i]}, row) + .output; + row += mul_component::rows_amount; + + var sum_result = ::nil::blueprint::components::generate_circuit( + bp, assignment, {params.one, mul_result}, row) + .output; + row += add_component::rows_amount; + + res = ::nil::blueprint::components::generate_circuit( + bp, assignment, {res, sum_result}, row) + .output; + row += mul_component::rows_amount; + } - var sum_result = - add_component::generate_assignments(assignment, {params.one, mul_result}, row).output; - row += add_component::rows_amount; + generate_copy_constraints(bp, assignment, params, start_row_index); + return result_type(start_row_index); + } - res = mul_component::generate_assignments(assignment, {res, sum_result}, row).output; - row += mul_component::rows_amount; - } + static result_type generate_assignments(assignment &assignment, + const params_type ¶ms, + const std::size_t start_row_index) { - return result_type(start_row_index); - } + std::size_t row = start_row_index; - private: - static void generate_gates(blueprint &bp, - blueprint_public_assignment_table &assignment, - const params_type ¶ms, - const std::size_t first_selector_index) { + std::array pow_twos; + pow_twos[0] = params.eval_point; + for (std::size_t i = 1; i < EvalRounds; i++) { + pow_twos[i] = + mul_component::generate_assignments(assignment, {pow_twos[i - 1], pow_twos[i - 1]}, row) + .output; + row += mul_component::rows_amount; } - - static void - generate_copy_constraints(blueprint &bp, - blueprint_public_assignment_table &assignment, - const params_type ¶ms, - const std::size_t start_row_index) { + var res = params.one; + for (std::size_t i = 0; i < EvalRounds; i++) { + var mul_result = mul_component::generate_assignments( + assignment, {params.challenges[i], pow_twos[EvalRounds - 1 - i]}, row) + .output; + row += mul_component::rows_amount; + + var sum_result = + add_component::generate_assignments(assignment, {params.one, mul_result}, row).output; + row += add_component::rows_amount; + + res = mul_component::generate_assignments(assignment, {res, sum_result}, row).output; + row += mul_component::rows_amount; } - }; - } // namespace components - } // namespace blueprint - } // namespace crypto3 + + return result_type(start_row_index); + } + + private: + static void generate_gates(blueprint &bp, + assignment &assignment, + const params_type ¶ms, + const std::size_t first_selector_index) { + } + + static void generate_copy_constraints(blueprint &bp, + assignment &assignment, + const params_type ¶ms, + const std::size_t start_row_index) { + } + }; + } // namespace components + } // namespace blueprint } // namespace nil #endif // CRYPTO3_BLUEPRINT_COMPONENTS_PLONK_KIMCHI_DETAIL_B_POLY_HPP \ No newline at end of file diff --git a/include/nil/blueprint/components/systems/snark/plonk/kimchi/detail/oracles_scalar/b_poly_coefficients.hpp b/include/nil/blueprint/components/systems/snark/plonk/kimchi/detail/oracles_scalar/b_poly_coefficients.hpp index 2dd05990f..eb4f6cc01 100644 --- a/include/nil/blueprint/components/systems/snark/plonk/kimchi/detail/oracles_scalar/b_poly_coefficients.hpp +++ b/include/nil/blueprint/components/systems/snark/plonk/kimchi/detail/oracles_scalar/b_poly_coefficients.hpp @@ -34,113 +34,109 @@ #include -#include -#include +#include +#include namespace nil { - namespace crypto3 { - namespace blueprint { - namespace components { - - // Coefficients of univariate polynomial - // https://github.com/o1-labs/proof-systems/blob/1f8532ec1b8d43748a372632bd854be36b371afe/poly-commitment/src/commitment.rs#L251 - // Input: challenges - // Output: f = [c0, c1, ...], where f = (1 + challenges[-1] * X)(1 + challenges[-2] * X^2)(1 + - // challenges[-3] * X^4)... - template - class b_poly_coefficients; - - template - class b_poly_coefficients, - EvalRounds, W0, W1, W2, W3, W4, W5, W6, W7, W8, W9, W10, W11, W12, W13, W14> { - - typedef snark::plonk_constraint_system - ArithmetizationType; - - using var = snark::plonk_variable; - - using mul_component = zk::components::multiplication; - - constexpr static const std::size_t selector_seed = 0x0f21; - - public: - constexpr static const std::size_t polynomial_len = 1 << EvalRounds; - - constexpr static const std::size_t rows_amount = mul_component::rows_amount * polynomial_len; - constexpr static const std::size_t gates_amount = 0; - - struct params_type { - std::array &challenges; - var one; - }; - - struct result_type { - std::array output; - }; - - static result_type - generate_circuit(blueprint &bp, - blueprint_public_assignment_table &assignment, - const params_type ¶ms, - const std::size_t start_row_index) { - - std::size_t row = start_row_index; - - std::array output; - output[0] = params.one; - std::size_t k = 0; - std::size_t pow = 1; - - for (std::size_t i = 1; i < polynomial_len; i++) { - std::size_t shift = i == pow ? 1 : 0; - k += shift; - pow <<= shift; - output[i] = zk::components::generate_circuit( - bp, assignment, - {output[i - (pow >> 1)], params.challenges[EvalRounds - 1 - (k - 1)]}, row) - .output; - row += mul_component::rows_amount; - } - - result_type res; - res.output = output; - return res; + namespace blueprint { + namespace components { + + // Coefficients of univariate polynomial + // https://github.com/o1-labs/proof-systems/blob/1f8532ec1b8d43748a372632bd854be36b371afe/poly-commitment/src/commitment.rs#L251 + // Input: challenges + // Output: f = [c0, c1, ...], where f = (1 + challenges[-1] * X)(1 + challenges[-2] * X^2)(1 + + // challenges[-3] * X^4)... + template + class b_poly_coefficients; + + template + class b_poly_coefficients, EvalRounds, W0, + W1, W2, W3, W4, W5, W6, W7, W8, W9, W10, W11, W12, W13, W14> { + + typedef crypto3::zk::snark::plonk_constraint_system ArithmetizationType; + + using var = crypto3::zk::snark::plonk_variable; + + using mul_component = multiplication>; + + constexpr static const std::size_t selector_seed = 0x0f21; + + public: + constexpr static const std::size_t polynomial_len = 1 << EvalRounds; + + constexpr static const std::size_t rows_amount = mul_component::rows_amount * polynomial_len; + constexpr static const std::size_t gates_amount = 0; + + struct params_type { + std::array &challenges; + var one; + }; + + struct result_type { + std::array output; + }; + + static result_type generate_circuit(blueprint &bp, + assignment &assignment, + const params_type ¶ms, + const std::size_t start_row_index) { + + std::size_t row = start_row_index; + + std::array output; + output[0] = params.one; + std::size_t k = 0; + std::size_t pow = 1; + + for (std::size_t i = 1; i < polynomial_len; i++) { + std::size_t shift = i == pow ? 1 : 0; + k += shift; + pow <<= shift; + output[i] = ::nil::blueprint::components::generate_circuit( + bp, assignment, + {output[i - (pow >> 1)], params.challenges[EvalRounds - 1 - (k - 1)]}, row) + .output; + row += mul_component::rows_amount; } - static result_type generate_assignments(blueprint_assignment_table &assignment, - const params_type ¶ms, - const std::size_t start_row_index) { - - std::size_t row = start_row_index; - - std::array output; - output[0] = params.one; - std::size_t k = 0; - std::size_t pow = 1; - - for (std::size_t i = 1; i < polynomial_len; i++) { - std::size_t shift = i == pow ? 1 : 0; - k += shift; - pow <<= shift; - output[i] = mul_component::generate_assignments( - assignment, - {output[i - (pow >> 1)], params.challenges[EvalRounds - 1 - (k - 1)]}, - row) - .output; - row += mul_component::rows_amount; - } - - result_type res; - res.output = output; - return res; + result_type res; + res.output = output; + return res; + } + + static result_type generate_assignments(assignment &assignment, + const params_type ¶ms, + const std::size_t start_row_index) { + + std::size_t row = start_row_index; + + std::array output; + output[0] = params.one; + std::size_t k = 0; + std::size_t pow = 1; + + for (std::size_t i = 1; i < polynomial_len; i++) { + std::size_t shift = i == pow ? 1 : 0; + k += shift; + pow <<= shift; + output[i] = + mul_component::generate_assignments( + assignment, {output[i - (pow >> 1)], params.challenges[EvalRounds - 1 - (k - 1)]}, row) + .output; + row += mul_component::rows_amount; } - }; - } // namespace components - } // namespace blueprint - } // namespace crypto3 + + result_type res; + res.output = output; + return res; + } + }; + } // namespace components + } // namespace blueprint } // namespace nil #endif // CRYPTO3_BLUEPRINT_COMPONENTS_PLONK_KIMCHI_DETAIL_B_POLY_COEFFICIENTS_HPP \ No newline at end of file diff --git a/include/nil/blueprint/components/systems/snark/plonk/kimchi/detail/oracles_scalar/combine_proof_evals.hpp b/include/nil/blueprint/components/systems/snark/plonk/kimchi/detail/oracles_scalar/combine_proof_evals.hpp index e92cf835d..46ed0f1f2 100644 --- a/include/nil/blueprint/components/systems/snark/plonk/kimchi/detail/oracles_scalar/combine_proof_evals.hpp +++ b/include/nil/blueprint/components/systems/snark/plonk/kimchi/detail/oracles_scalar/combine_proof_evals.hpp @@ -32,234 +32,227 @@ #include #include -#include +#include #include #include -#include -#include +#include namespace nil { - namespace crypto3 { - namespace blueprint { - namespace components { + namespace blueprint { + namespace components { - // Proof evals are element of the finite field, so combine works just as scalar multiplication - // https://github.com/o1-labs/proof-systems/blob/1f8532ec1b8d43748a372632bd854be36b371afe/kimchi/src/proof.rs#L105 - // Input: x, proof_evaluations (see kimchi_proof_evaluations): {w_0, ... w_14, z, ..., - // poseidon_selector} Output: proof_evaluations: {x * w_0, ... x * w_14, x * z, ..., x * - // poseidon_selector} - template - class combine_proof_evals; + // Proof evals are element of the finite field, so combine works just as scalar multiplication + // https://github.com/o1-labs/proof-systems/blob/1f8532ec1b8d43748a372632bd854be36b371afe/kimchi/src/proof.rs#L105 + // Input: x, proof_evaluations (see kimchi_proof_evaluations): {w_0, ... w_14, z, ..., + // poseidon_selector} Output: proof_evaluations: {x * w_0, ... x * w_14, x * z, ..., x * + // poseidon_selector} + template + class combine_proof_evals; - template - class combine_proof_evals, - KimchiParamsType, W0, W1, W2, W3, W4, W5, W6, W7, W8, W9, W10, W11, W12, W13, - W14> { + template + class combine_proof_evals, KimchiParamsType, + W0, W1, W2, W3, W4, W5, W6, W7, W8, W9, W10, W11, W12, W13, W14> { - typedef snark::plonk_constraint_system - ArithmetizationType; + typedef crypto3::zk::snark::plonk_constraint_system ArithmetizationType; - using var = snark::plonk_variable; + using var = crypto3::zk::snark::plonk_variable; - using mul_component = zk::components::multiplication; + using mul_component = multiplication>; - constexpr static const std::size_t selector_seed = 0x0f23; + constexpr static const std::size_t selector_seed = 0x0f23; - constexpr static const std::size_t lookup_rows() { - std::size_t rows = 0; - if (KimchiParamsType::circuit_params::lookup_columns > 0) { - rows += KimchiParamsType::circuit_params::lookup_columns * mul_component::rows_amount; + constexpr static const std::size_t lookup_rows() { + std::size_t rows = 0; + if (KimchiParamsType::circuit_params::lookup_columns > 0) { + rows += KimchiParamsType::circuit_params::lookup_columns * mul_component::rows_amount; - rows += 2 * mul_component::rows_amount; + rows += 2 * mul_component::rows_amount; - if (KimchiParamsType::circuit_params::lookup_runtime) { - rows += mul_component::rows_amount; - } + if (KimchiParamsType::circuit_params::lookup_runtime) { + rows += mul_component::rows_amount; } - - return rows; } - public: - constexpr static const std::size_t rows_amount = - KimchiParamsType::witness_columns * mul_component::rows_amount // w - + mul_component::rows_amount // z - + (KimchiParamsType::permut_size - 1) * mul_component::rows_amount // s - + lookup_rows() + mul_component::rows_amount // generic - + mul_component::rows_amount; // poseidon - constexpr static const std::size_t gates_amount = 0; - - struct params_type { - kimchi_proof_evaluations evals; - var x; - }; - - struct result_type { - kimchi_proof_evaluations output; - - result_type(std::size_t component_start_row) { - std::size_t row = component_start_row; - - // w - for (std::size_t i = 0; i < KimchiParamsType::witness_columns; i++) { - output.w[i] = typename mul_component::result_type(row).output; - row += mul_component::rows_amount; - } - // z - output.z = typename mul_component::result_type(row).output; - row += mul_component::rows_amount; - // s - for (std::size_t i = 0; i < KimchiParamsType::permut_size - 1; i++) { - output.s[i] = typename mul_component::result_type(row).output; - row += mul_component::rows_amount; - } - // lookup - if (KimchiParamsType::circuit_params::lookup_columns > 0) { - for (std::size_t i = 0; i < KimchiParamsType::circuit_params::lookup_columns; i++) { - output.lookup.sorted[i] = typename mul_component::result_type(row).output; - row += mul_component::rows_amount; - } - - output.lookup.aggreg = typename mul_component::result_type(row).output; - row += mul_component::rows_amount; - - output.lookup.table = typename mul_component::result_type(row).output; - row += mul_component::rows_amount; - - if (KimchiParamsType::circuit_params::lookup_runtime) { - output.lookup.runtime = typename mul_component::result_type(row).output; - row += mul_component::rows_amount; - } - } - // generic_selector - output.generic_selector = typename mul_component::result_type(row).output; - row += mul_component::rows_amount; - // poseidon_selector - output.poseidon_selector = typename mul_component::result_type(row).output; - row += mul_component::rows_amount; - } - }; + return rows; + } + + public: + constexpr static const std::size_t rows_amount = + KimchiParamsType::witness_columns * mul_component::rows_amount // w + + mul_component::rows_amount // z + + (KimchiParamsType::permut_size - 1) * mul_component::rows_amount // s + + lookup_rows() + mul_component::rows_amount // generic + + mul_component::rows_amount; // poseidon + constexpr static const std::size_t gates_amount = 0; + + struct params_type { + kimchi_proof_evaluations evals; + var x; + }; - static result_type - generate_circuit(blueprint &bp, - blueprint_public_assignment_table &assignment, - const params_type ¶ms, - const std::size_t start_row_index) { + struct result_type { + kimchi_proof_evaluations output; - std::size_t row = start_row_index; + result_type(std::size_t component_start_row) { + std::size_t row = component_start_row; // w for (std::size_t i = 0; i < KimchiParamsType::witness_columns; i++) { - zk::components::generate_circuit(bp, assignment, - {params.evals.w[i], params.x}, row); + output.w[i] = typename mul_component::result_type(row).output; row += mul_component::rows_amount; } // z - zk::components::generate_circuit(bp, assignment, {params.evals.z, params.x}, - row); + output.z = typename mul_component::result_type(row).output; row += mul_component::rows_amount; // s for (std::size_t i = 0; i < KimchiParamsType::permut_size - 1; i++) { - zk::components::generate_circuit(bp, assignment, - {params.evals.s[i], params.x}, row); + output.s[i] = typename mul_component::result_type(row).output; row += mul_component::rows_amount; } // lookup if (KimchiParamsType::circuit_params::lookup_columns > 0) { for (std::size_t i = 0; i < KimchiParamsType::circuit_params::lookup_columns; i++) { - zk::components::generate_circuit( - bp, assignment, {params.evals.lookup.sorted[i], params.x}, row); + output.lookup.sorted[i] = typename mul_component::result_type(row).output; row += mul_component::rows_amount; } - zk::components::generate_circuit( - bp, assignment, {params.evals.lookup.aggreg, params.x}, row); + output.lookup.aggreg = typename mul_component::result_type(row).output; row += mul_component::rows_amount; - zk::components::generate_circuit(bp, assignment, - {params.evals.lookup.table, params.x}, row); + output.lookup.table = typename mul_component::result_type(row).output; row += mul_component::rows_amount; if (KimchiParamsType::circuit_params::lookup_runtime) { - zk::components::generate_circuit( - bp, assignment, {params.evals.lookup.runtime, params.x}, row); + output.lookup.runtime = typename mul_component::result_type(row).output; row += mul_component::rows_amount; } } // generic_selector - zk::components::generate_circuit(bp, assignment, - {params.evals.generic_selector, params.x}, row); + output.generic_selector = typename mul_component::result_type(row).output; row += mul_component::rows_amount; // poseidon_selector - zk::components::generate_circuit( - bp, assignment, {params.evals.poseidon_selector, params.x}, row); + output.poseidon_selector = typename mul_component::result_type(row).output; row += mul_component::rows_amount; - - assert(row == start_row_index + rows_amount); - - return result_type(start_row_index); } + }; - static result_type generate_assignments(blueprint_assignment_table &assignment, - const params_type ¶ms, - const std::size_t start_row_index) { + static result_type generate_circuit(blueprint &bp, + assignment &assignment, + const params_type ¶ms, + const std::size_t start_row_index) { - std::size_t row = start_row_index; + std::size_t row = start_row_index; - // w - for (std::size_t i = 0; i < KimchiParamsType::witness_columns; i++) { - mul_component::generate_assignments(assignment, {params.evals.w[i], params.x}, row); + // w + for (std::size_t i = 0; i < KimchiParamsType::witness_columns; i++) { + ::nil::blueprint::components::generate_circuit( + bp, assignment, {params.evals.w[i], params.x}, row); + row += mul_component::rows_amount; + } + // z + ::nil::blueprint::components::generate_circuit(bp, assignment, + {params.evals.z, params.x}, row); + row += mul_component::rows_amount; + // s + for (std::size_t i = 0; i < KimchiParamsType::permut_size - 1; i++) { + ::nil::blueprint::components::generate_circuit( + bp, assignment, {params.evals.s[i], params.x}, row); + row += mul_component::rows_amount; + } + // lookup + if (KimchiParamsType::circuit_params::lookup_columns > 0) { + for (std::size_t i = 0; i < KimchiParamsType::circuit_params::lookup_columns; i++) { + ::nil::blueprint::components::generate_circuit( + bp, assignment, {params.evals.lookup.sorted[i], params.x}, row); row += mul_component::rows_amount; } - // z - mul_component::generate_assignments(assignment, {params.evals.z, params.x}, row); + + ::nil::blueprint::components::generate_circuit( + bp, assignment, {params.evals.lookup.aggreg, params.x}, row); row += mul_component::rows_amount; - // s - for (std::size_t i = 0; i < KimchiParamsType::permut_size - 1; i++) { - mul_component::generate_assignments(assignment, {params.evals.s[i], params.x}, row); + + ::nil::blueprint::components::generate_circuit( + bp, assignment, {params.evals.lookup.table, params.x}, row); + row += mul_component::rows_amount; + + if (KimchiParamsType::circuit_params::lookup_runtime) { + ::nil::blueprint::components::generate_circuit( + bp, assignment, {params.evals.lookup.runtime, params.x}, row); row += mul_component::rows_amount; } - // lookup - if (KimchiParamsType::circuit_params::lookup_columns > 0) { - for (std::size_t i = 0; i < KimchiParamsType::circuit_params::lookup_columns; i++) { - mul_component::generate_assignments(assignment, - {params.evals.lookup.sorted[i], params.x}, row); - row += mul_component::rows_amount; - } + } + // generic_selector + ::nil::blueprint::components::generate_circuit( + bp, assignment, {params.evals.generic_selector, params.x}, row); + row += mul_component::rows_amount; + // poseidon_selector + ::nil::blueprint::components::generate_circuit( + bp, assignment, {params.evals.poseidon_selector, params.x}, row); + row += mul_component::rows_amount; - mul_component::generate_assignments(assignment, {params.evals.lookup.aggreg, params.x}, - row); - row += mul_component::rows_amount; + assert(row == start_row_index + rows_amount); - mul_component::generate_assignments(assignment, {params.evals.lookup.table, params.x}, row); - row += mul_component::rows_amount; + return result_type(start_row_index); + } - if (KimchiParamsType::circuit_params::lookup_runtime) { - mul_component::generate_assignments(assignment, {params.evals.lookup.runtime, params.x}, - row); - row += mul_component::rows_amount; - } - } - // generic_selector - mul_component::generate_assignments(assignment, {params.evals.generic_selector, params.x}, row); + static result_type generate_assignments(assignment &assignment, + const params_type ¶ms, + const std::size_t start_row_index) { + + std::size_t row = start_row_index; + + // w + for (std::size_t i = 0; i < KimchiParamsType::witness_columns; i++) { + mul_component::generate_assignments(assignment, {params.evals.w[i], params.x}, row); row += mul_component::rows_amount; - // poseidon_selector - mul_component::generate_assignments(assignment, {params.evals.poseidon_selector, params.x}, - row); + } + // z + mul_component::generate_assignments(assignment, {params.evals.z, params.x}, row); + row += mul_component::rows_amount; + // s + for (std::size_t i = 0; i < KimchiParamsType::permut_size - 1; i++) { + mul_component::generate_assignments(assignment, {params.evals.s[i], params.x}, row); row += mul_component::rows_amount; + } + // lookup + if (KimchiParamsType::circuit_params::lookup_columns > 0) { + for (std::size_t i = 0; i < KimchiParamsType::circuit_params::lookup_columns; i++) { + mul_component::generate_assignments(assignment, {params.evals.lookup.sorted[i], params.x}, + row); + row += mul_component::rows_amount; + } - assert(row == start_row_index + rows_amount); + mul_component::generate_assignments(assignment, {params.evals.lookup.aggreg, params.x}, row); + row += mul_component::rows_amount; + + mul_component::generate_assignments(assignment, {params.evals.lookup.table, params.x}, row); + row += mul_component::rows_amount; - return result_type(start_row_index); + if (KimchiParamsType::circuit_params::lookup_runtime) { + mul_component::generate_assignments(assignment, {params.evals.lookup.runtime, params.x}, + row); + row += mul_component::rows_amount; + } } - }; - } // namespace components - } // namespace blueprint - } // namespace crypto3 + // generic_selector + mul_component::generate_assignments(assignment, {params.evals.generic_selector, params.x}, row); + row += mul_component::rows_amount; + // poseidon_selector + mul_component::generate_assignments(assignment, {params.evals.poseidon_selector, params.x}, row); + row += mul_component::rows_amount; + + assert(row == start_row_index + rows_amount); + + return result_type(start_row_index); + } + }; + } // namespace components + } // namespace blueprint } // namespace nil #endif // CRYPTO3_BLUEPRINT_COMPONENTS_PLONK_KIMCHI_DETAIL_COMBINE_PROOF_EVALS_HPP \ No newline at end of file diff --git a/include/nil/blueprint/components/systems/snark/plonk/kimchi/detail/oracles_scalar/element_powers.hpp b/include/nil/blueprint/components/systems/snark/plonk/kimchi/detail/oracles_scalar/element_powers.hpp index 9f0384389..eac407018 100644 --- a/include/nil/blueprint/components/systems/snark/plonk/kimchi/detail/oracles_scalar/element_powers.hpp +++ b/include/nil/blueprint/components/systems/snark/plonk/kimchi/detail/oracles_scalar/element_powers.hpp @@ -34,122 +34,145 @@ #include -#include -#include +#include +#include namespace nil { - namespace crypto3 { - namespace blueprint { - namespace components { - - // for (base, n) calculates [base^0, base^1, ..., base^n] - // n >= 0 - // Input: base, n - // Output: [base^0, base^1, ..., base^n] - template - class element_powers; - - template - class element_powers, n, W0, - W1, W2, W3, W4, W5, W6, W7, W8, W9, W10, W11, W12, W13, W14> { - - typedef snark::plonk_constraint_system - ArithmetizationType; - - using var = snark::plonk_variable; - - using mul_component = zk::components::multiplication; - - constexpr static const std::size_t selector_seed = 0x0f0c; - - public: - constexpr static const std::size_t rows_amount = - n <= 1 ? 1 : (n - 2) * mul_component::rows_amount + 1; - constexpr static const std::size_t gates_amount = 0; - - struct params_type { - var base; - var one; - }; - - struct result_type { - std::array output; - - result_type(std::size_t component_start_row) { - output[0] = var(W0, component_start_row, false); - if (n > 0) { - output[1] = var(W1, component_start_row, false); - } - for (std::size_t i = 2; i < n; i++) { - output[i] = typename mul_component::result_type(component_start_row + i - 1).output; - } - } - }; + namespace blueprint { + namespace components { + + // for (base, n) calculates [base^0, base^1, ..., base^n] + // n >= 0 + // Input: base, n + // Output: [base^0, base^1, ..., base^n] + template + class element_powers; + + template + class element_powers, + n, + W0, + W1, + W2, + W3, + W4, + W5, + W6, + W7, + W8, + W9, + W10, + W11, + W12, + W13, + W14> { + + typedef crypto3::zk::snark::plonk_constraint_system ArithmetizationType; + + using var = crypto3::zk::snark::plonk_variable; + + using mul_component = multiplication>; + + constexpr static const std::size_t selector_seed = 0x0f0c; + + public: + constexpr static const std::size_t rows_amount = n <= 1 ? 1 : (n - 2) * mul_component::rows_amount + 1; + constexpr static const std::size_t gates_amount = 0; + + struct params_type { + var base; + var one; + }; - static result_type - generate_circuit(blueprint &bp, - blueprint_public_assignment_table &assignment, - const params_type ¶ms, - const std::size_t start_row_index) { + struct result_type { + std::array output; - var base(W1, start_row_index, false); - var last_result(W1, start_row_index, false); - std::size_t row = start_row_index + 1; + result_type(std::size_t component_start_row) { + output[0] = var(W0, component_start_row, false); + if (n > 0) { + output[1] = var(W1, component_start_row, false); + } for (std::size_t i = 2; i < n; i++) { - last_result = zk::components::generate_circuit(bp, assignment, - {base, last_result}, row) - .output; - row += mul_component::rows_amount; + output[i] = typename mul_component::result_type(component_start_row + i - 1).output; } - - generate_copy_constraints(bp, assignment, params, start_row_index); - return result_type(start_row_index); } + }; - static result_type generate_assignments(blueprint_assignment_table &assignment, - const params_type ¶ms, - const std::size_t start_row_index) { + static result_type generate_circuit(blueprint &bp, + assignment &assignment, + const params_type ¶ms, + const std::size_t start_row_index) { + + var base(W1, start_row_index, false); + var last_result(W1, start_row_index, false); + std::size_t row = start_row_index + 1; + for (std::size_t i = 2; i < n; i++) { + last_result = ::nil::blueprint::components::generate_circuit( + bp, assignment, {base, last_result}, row) + .output; + row += mul_component::rows_amount; + } - std::size_t row = start_row_index; + generate_copy_constraints(bp, assignment, params, start_row_index); + return result_type(start_row_index); + } - assignment.witness(W0)[start_row_index] = 1; - assignment.witness(W1)[start_row_index] = assignment.var_value(params.base); - var base(W1, start_row_index, false); - var last_result(W1, start_row_index, false); - row++; + static result_type generate_assignments(assignment &assignment, + const params_type ¶ms, + const std::size_t start_row_index) { - for (std::size_t i = 2; i < n; i++) { - last_result = - mul_component::generate_assignments(assignment, {base, last_result}, row).output; - row += mul_component::rows_amount; - } + std::size_t row = start_row_index; - return result_type(start_row_index); - } + assignment.witness(W0)[start_row_index] = 1; + assignment.witness(W1)[start_row_index] = assignment.var_value(params.base); + var base(W1, start_row_index, false); + var last_result(W1, start_row_index, false); + row++; - private: - static void generate_gates(blueprint &bp, - blueprint_public_assignment_table &assignment, - const params_type ¶ms, - const std::size_t first_selector_index) { + for (std::size_t i = 2; i < n; i++) { + last_result = mul_component::generate_assignments(assignment, {base, last_result}, row).output; + row += mul_component::rows_amount; } - static void - generate_copy_constraints(blueprint &bp, - blueprint_public_assignment_table &assignment, - const params_type ¶ms, - const std::size_t start_row_index) { - - bp.add_copy_constraint({{W0, static_cast(start_row_index), false}, params.one}); - bp.add_copy_constraint({{W1, static_cast(start_row_index), false}, params.base}); - } - }; - } // namespace components - } // namespace blueprint - } // namespace crypto3 + return result_type(start_row_index); + } + + private: + static void generate_gates(blueprint &bp, + assignment &assignment, + const params_type ¶ms, + const std::size_t first_selector_index) { + } + + static void generate_copy_constraints(blueprint &bp, + assignment &assignment, + const params_type ¶ms, + const std::size_t start_row_index) { + + bp.add_copy_constraint({{W0, static_cast(start_row_index), false}, params.one}); + bp.add_copy_constraint({{W1, static_cast(start_row_index), false}, params.base}); + } + }; + } // namespace components + } // namespace blueprint } // namespace nil #endif // CRYPTO3_BLUEPRINT_COMPONENTS_PLONK_KIMCHI_DETAIL_ELEMENT_POWERS_HPP \ No newline at end of file diff --git a/include/nil/blueprint/components/systems/snark/plonk/kimchi/detail/oracles_scalar/ft_eval.hpp b/include/nil/blueprint/components/systems/snark/plonk/kimchi/detail/oracles_scalar/ft_eval.hpp index d04b81495..904e9056e 100644 --- a/include/nil/blueprint/components/systems/snark/plonk/kimchi/detail/oracles_scalar/ft_eval.hpp +++ b/include/nil/blueprint/components/systems/snark/plonk/kimchi/detail/oracles_scalar/ft_eval.hpp @@ -32,593 +32,590 @@ #include #include -#include +#include +#include +#include +#include + #include #include #include #include #include +#include -#include +#include namespace nil { - namespace crypto3 { - namespace blueprint { - namespace components { - - // ft polynomial at zeta - // https://github.com/o1-labs/proof-systems/blob/1f8532ec1b8d43748a372632bd854be36b371afe/kimchi/src/verifier.rs#L320-L384 - // Input: - // Output: ft(zeta) - template - class ft_eval; - - template - class ft_eval, CurveType, - KimchiParamsType, W0, W1, W2, W3, W4, W5, W6, W7, W8, W9, W10, W11, W12, W13, W14> { - - typedef snark::plonk_constraint_system - ArithmetizationType; - - using var = snark::plonk_variable; - - using mul_component = zk::components::multiplication; - using add_component = zk::components::addition; - using sub_component = zk::components::subtraction; - using div_component = zk::components::division; - - using zkpm_eval_component = - zk::components::zkpm_evaluate; - - using zk_w3_component = zk::components::zk_w3; - - using verifier_index_type = kimchi_verifier_index_scalar; - - using index_terms_list = typename KimchiParamsType::circuit_params::index_terms_list; - using constant_term_component = - zk::components::rpn_expression; - - constexpr static const std::size_t selector_seed = 0x0f22; - constexpr static const std::size_t eval_points_amount = 2; - - constexpr static std::size_t rows() { - std::size_t row = 0; - row += 2; // skip rows for constant in zkpm - row += zkpm_eval_component::rows_amount; - row += sub_component::rows_amount; - - row += add_component::rows_amount; - row += 3 * mul_component::rows_amount; - - for (std::size_t i = 0; i < KimchiParamsType::permut_size - 1; i++) { - row += 2 * mul_component::rows_amount; - row += 2 * add_component::rows_amount; - } - - if (KimchiParamsType::public_input_size > - 0) { // if public input isn't present, then public_eval is empty - row += sub_component::rows_amount; - } - + namespace blueprint { + namespace components { + + // ft polynomial at zeta + // https://github.com/o1-labs/proof-systems/blob/1f8532ec1b8d43748a372632bd854be36b371afe/kimchi/src/verifier.rs#L320-L384 + // Input: + // Output: ft(zeta) + template + class ft_eval; + + template + class ft_eval, CurveType, KimchiParamsType, + W0, W1, W2, W3, W4, W5, W6, W7, W8, W9, W10, W11, W12, W13, W14> { + + typedef crypto3::zk::snark::plonk_constraint_system ArithmetizationType; + + using var = crypto3::zk::snark::plonk_variable; + + using mul_component = multiplication>; + using add_component = + addition>; + using sub_component = + subtraction>; + using div_component = + division>; + + using zkpm_eval_component = + zkpm_evaluate; + + using zk_w3_component = + zk_w3; + + using verifier_index_type = kimchi_verifier_index_scalar; + + using index_terms_list = typename KimchiParamsType::circuit_params::index_terms_list; + using constant_term_component = + rpn_expression; + + constexpr static const std::size_t selector_seed = 0x0f22; + constexpr static const std::size_t eval_points_amount = 2; + + constexpr static std::size_t rows() { + std::size_t row = 0; + row += 2; // skip rows for constant in zkpm + row += zkpm_eval_component::rows_amount; + row += sub_component::rows_amount; + + row += add_component::rows_amount; + row += 3 * mul_component::rows_amount; + + for (std::size_t i = 0; i < KimchiParamsType::permut_size - 1; i++) { row += 2 * mul_component::rows_amount; + row += 2 * add_component::rows_amount; + } - for (std::size_t i = 0; i < KimchiParamsType::permut_size; i++) { - row += 3 * mul_component::rows_amount; - row += 2 * add_component::rows_amount; - } + if (KimchiParamsType::public_input_size > + 0) { // if public input isn't present, then public_eval is empty row += sub_component::rows_amount; + } - // numerator calculation - row += zk_w3_component::rows_amount; - row += 3 * sub_component::rows_amount; - row += 5 * mul_component::rows_amount; - row += add_component::rows_amount; - - // denominator - row += mul_component::rows_amount; - row += div_component::rows_amount; - - row += mul_component::rows_amount; - row += add_component::rows_amount; - - row += constant_term_component::rows_amount; - row += sub_component::rows_amount; + row += 2 * mul_component::rows_amount; - return row; + for (std::size_t i = 0; i < KimchiParamsType::permut_size; i++) { + row += 3 * mul_component::rows_amount; + row += 2 * add_component::rows_amount; } + row += sub_component::rows_amount; + + // numerator calculation + row += zk_w3_component::rows_amount; + row += 3 * sub_component::rows_amount; + row += 5 * mul_component::rows_amount; + row += add_component::rows_amount; + + // denominator + row += mul_component::rows_amount; + row += div_component::rows_amount; + + row += mul_component::rows_amount; + row += add_component::rows_amount; + + row += constant_term_component::rows_amount; + row += sub_component::rows_amount; + + return row; + } + + public: + constexpr static const std::size_t rows_amount = rows(); + constexpr static const std::size_t gates_amount = 0; + + struct params_type { + verifier_index_type &verifier_index; + std::array alpha_powers; + std::array, eval_points_amount> + combined_evals; + var gamma; + var beta; + var zeta; + var zeta_pow_n; + var joint_combiner; + std::array public_eval; + }; - public: - constexpr static const std::size_t rows_amount = rows(); - constexpr static const std::size_t gates_amount = 0; - - struct params_type { - verifier_index_type &verifier_index; - std::array alpha_powers; - std::array, eval_points_amount> - combined_evals; - var gamma; - var beta; - var zeta; - var zeta_pow_n; - var joint_combiner; - std::array public_eval; - }; - - struct result_type { - var output; - - result_type(std::size_t component_start_row) { - std::size_t row = component_start_row + rows_amount - sub_component::rows_amount; - output = typename sub_component::result_type(row).output; - } - }; - - static result_type - generate_circuit(blueprint &bp, - blueprint_public_assignment_table &assignment, - const params_type ¶ms, - const std::size_t start_row_index) { - - std::size_t row = start_row_index; - - var zero(0, start_row_index, false, var::column_type::constant); - var one(0, start_row_index + 1, false, var::column_type::constant); - - row += 2; // skip rows for constant in zkpm - - // zkp = index.zkpm().evaluate(&zeta); - var zkp = - zkpm_eval_component::generate_circuit( - bp, assignment, - {params.verifier_index.omega, params.verifier_index.domain_size, params.zeta}, row) - .output; - row += zkpm_eval_component::rows_amount; - - // zeta1m1 = zeta_pow_n - ScalarField::::one(); - var zeta1m1 = zk::components::generate_circuit(bp, - assignment, {params.zeta_pow_n, one}, row).output; - row += sub_component::rows_amount; + struct result_type { + var output; - // get alpha0, alpha1, alpha2 - std::pair alpha_idxs = - index_terms_list::alpha_map(argument_type::Permutation); - assert(alpha_idxs.second >= 3); - var alpha0 = params.alpha_powers[alpha_idxs.first]; - var alpha1 = params.alpha_powers[alpha_idxs.first + 1]; - var alpha2 = params.alpha_powers[alpha_idxs.first + 2]; - - // let init = (evals[0].w[PERMUTS - 1] + gamma) * evals[1].z * alpha0 * zkp; - var init = - zk::components::generate_circuit( - bp, assignment, - {params.combined_evals[0].w[KimchiParamsType::permut_size - 1], params.gamma}, row) - .output; - row += add_component::rows_amount; - init = zk::components::generate_circuit(bp, - assignment, {init, params.combined_evals[1].z}, row).output; - row += mul_component::rows_amount; - init = - zk::components::generate_circuit(bp, assignment, {init, alpha0}, row).output; - row += mul_component::rows_amount; - init = zk::components::generate_circuit(bp, assignment, {init, zkp}, row).output; - row += mul_component::rows_amount; + result_type(std::size_t component_start_row) { + std::size_t row = component_start_row + rows_amount - sub_component::rows_amount; + output = typename sub_component::result_type(row).output; + } + }; - // let mut ft_eval0 = evals[0] - // .w - // .iter() - // .zip(evals[0].s.iter()) - // .map(|(w, s)| (beta * s) + w + gamma) - // .fold(init, |x, y| x * y); - var ft_eval0 = init; - for (std::size_t i = 0; i < KimchiParamsType::permut_size - 1; i++) { - var w = params.combined_evals[0].w[i]; - var s = params.combined_evals[0].s[i]; - var beta_s = - zk::components::generate_circuit(bp, assignment, {params.beta, s}, row) - .output; - row += mul_component::rows_amount; - var w_beta_s = - zk::components::generate_circuit(bp, assignment, {w, beta_s}, row) - .output; - row += add_component::rows_amount; - var w_beta_s_gamma = zk::components::generate_circuit( - bp, assignment, {w_beta_s, params.gamma}, row) - .output; - row += add_component::rows_amount; - ft_eval0 = zk::components::generate_circuit(bp, assignment, - {ft_eval0, w_beta_s_gamma}, row) - .output; - row += mul_component::rows_amount; - } - - // ft_eval0 - p_eval[0] - if (KimchiParamsType::public_input_size > 0) { - var ft_eval0 = zk::components::generate_circuit(bp, - assignment, {ft_eval0, params.public_eval[0]}, row).output; - row += sub_component::rows_amount; - } - - // ft_eval0 -= evals[0] - // .w - // .iter() - // .zip(index.shift.iter()) - // .map(|(w, s)| gamma + (beta * zeta * s) + w) - // .fold(alpha0 * zkp * evals[0].z, |x, y| x * y); - var ft_eval0_sub = - zk::components::generate_circuit(bp, assignment, {alpha0, zkp}, row).output; + static result_type generate_circuit(blueprint &bp, + assignment &assignment, + const params_type ¶ms, + const std::size_t start_row_index) { + + std::size_t row = start_row_index; + + var zero(0, start_row_index, false, var::column_type::constant); + var one(0, start_row_index + 1, false, var::column_type::constant); + + row += 2; // skip rows for constant in zkpm + + // zkp = index.zkpm().evaluate(&zeta); + var zkp = zkpm_eval_component::generate_circuit( + bp, assignment, + {params.verifier_index.omega, params.verifier_index.domain_size, params.zeta}, row) + .output; + row += zkpm_eval_component::rows_amount; + + // zeta1m1 = zeta_pow_n - ScalarField::::one(); + var zeta1m1 = ::nil::blueprint::components::generate_circuit( + bp, assignment, {params.zeta_pow_n, one}, row) + .output; + row += sub_component::rows_amount; + + // get alpha0, alpha1, alpha2 + std::pair alpha_idxs = + index_terms_list::alpha_map(argument_type::Permutation); + assert(alpha_idxs.second >= 3); + var alpha0 = params.alpha_powers[alpha_idxs.first]; + var alpha1 = params.alpha_powers[alpha_idxs.first + 1]; + var alpha2 = params.alpha_powers[alpha_idxs.first + 2]; + + // let init = (evals[0].w[PERMUTS - 1] + gamma) * evals[1].z * alpha0 * zkp; + var init = ::nil::blueprint::components::generate_circuit( + bp, assignment, + {params.combined_evals[0].w[KimchiParamsType::permut_size - 1], params.gamma}, row) + .output; + row += add_component::rows_amount; + init = ::nil::blueprint::components::generate_circuit( + bp, assignment, {init, params.combined_evals[1].z}, row) + .output; + row += mul_component::rows_amount; + init = ::nil::blueprint::components::generate_circuit(bp, assignment, {init, alpha0}, + row) + .output; + row += mul_component::rows_amount; + init = + ::nil::blueprint::components::generate_circuit(bp, assignment, {init, zkp}, row) + .output; + row += mul_component::rows_amount; + + // let mut ft_eval0 = evals[0] + // .w + // .iter() + // .zip(evals[0].s.iter()) + // .map(|(w, s)| (beta * s) + w + gamma) + // .fold(init, |x, y| x * y); + var ft_eval0 = init; + for (std::size_t i = 0; i < KimchiParamsType::permut_size - 1; i++) { + var w = params.combined_evals[0].w[i]; + var s = params.combined_evals[0].s[i]; + var beta_s = ::nil::blueprint::components::generate_circuit( + bp, assignment, {params.beta, s}, row) + .output; row += mul_component::rows_amount; - ft_eval0_sub = zk::components::generate_circuit( - bp, assignment, {ft_eval0_sub, params.combined_evals[0].z}, row) + var w_beta_s = ::nil::blueprint::components::generate_circuit(bp, assignment, + {w, beta_s}, row) .output; - row += mul_component::rows_amount; - - for (std::size_t i = 0; i < KimchiParamsType::permut_size; i++) { - var w = params.combined_evals[0].w[i]; - var s = params.verifier_index.shift[i]; - var beta_s = - zk::components::generate_circuit(bp, assignment, {params.beta, s}, row) - .output; - row += mul_component::rows_amount; - var beta_zeta_s = zk::components::generate_circuit( - bp, assignment, {params.zeta, beta_s}, row) - .output; - row += mul_component::rows_amount; - var gamma_beta_zeta_s = zk::components::generate_circuit( - bp, assignment, {params.gamma, beta_zeta_s}, row) - .output; - row += add_component::rows_amount; - var w_gamma_beta_zeta_s = zk::components::generate_circuit( - bp, assignment, {w, gamma_beta_zeta_s}, row) - .output; - row += add_component::rows_amount; - - ft_eval0_sub = zk::components::generate_circuit( - bp, assignment, {ft_eval0_sub, w_gamma_beta_zeta_s}, row) - .output; - row += mul_component::rows_amount; - } - ft_eval0 = zk::components::generate_circuit(bp, assignment, - {ft_eval0, ft_eval0_sub}, row) + row += add_component::rows_amount; + var w_beta_s_gamma = ::nil::blueprint::components::generate_circuit( + bp, assignment, {w_beta_s, params.gamma}, row) + .output; + row += add_component::rows_amount; + ft_eval0 = ::nil::blueprint::components::generate_circuit( + bp, assignment, {ft_eval0, w_beta_s_gamma}, row) .output; - row += sub_component::rows_amount; - - // numerator calculation - - var domain_offset_for_zk = - zk_w3_component::generate_circuit(bp, // index.w() - assignment, {params.verifier_index}, row) - .output; - row += zk_w3_component::rows_amount; - - // zeta - index.w() - var zeta_minus_w = zk::components::generate_circuit( - bp, assignment, {params.zeta, domain_offset_for_zk}, row) - .output; - row += sub_component::rows_amount; + row += mul_component::rows_amount; + } - // (zeta - ScalarField::::one()) - var zeta_minus_one = - zk::components::generate_circuit(bp, assignment, {params.zeta, one}, row) - .output; + // ft_eval0 - p_eval[0] + if (KimchiParamsType::public_input_size > 0) { + var ft_eval0 = ::nil::blueprint::components::generate_circuit( + bp, assignment, {ft_eval0, params.public_eval[0]}, row) + .output; row += sub_component::rows_amount; + } - // (ScalarField::::one() - evals[0].z) - var one_minus_z = zk::components::generate_circuit( - bp, assignment, {one, params.combined_evals[0].z}, row) + // ft_eval0 -= evals[0] + // .w + // .iter() + // .zip(index.shift.iter()) + // .map(|(w, s)| gamma + (beta * zeta * s) + w) + // .fold(alpha0 * zkp * evals[0].z, |x, y| x * y); + var ft_eval0_sub = ::nil::blueprint::components::generate_circuit(bp, assignment, + {alpha0, zkp}, row) + .output; + row += mul_component::rows_amount; + ft_eval0_sub = ::nil::blueprint::components::generate_circuit( + bp, assignment, {ft_eval0_sub, params.combined_evals[0].z}, row) + .output; + row += mul_component::rows_amount; + + for (std::size_t i = 0; i < KimchiParamsType::permut_size; i++) { + var w = params.combined_evals[0].w[i]; + var s = params.verifier_index.shift[i]; + var beta_s = ::nil::blueprint::components::generate_circuit( + bp, assignment, {params.beta, s}, row) + .output; + row += mul_component::rows_amount; + var beta_zeta_s = ::nil::blueprint::components::generate_circuit( + bp, assignment, {params.zeta, beta_s}, row) .output; - row += sub_component::rows_amount; - - // let numerator = ((zeta1m1 * alpha1 * (zeta - index.w())) - // + (zeta1m1 * alpha2 * (zeta - ScalarField::::one()))) - // * (ScalarField::::one() - evals[0].z); - var numerator = - zk::components::generate_circuit(bp, assignment, {zeta1m1, alpha1}, row) - .output; row += mul_component::rows_amount; + var gamma_beta_zeta_s = ::nil::blueprint::components::generate_circuit( + bp, assignment, {params.gamma, beta_zeta_s}, row) + .output; + row += add_component::rows_amount; + var w_gamma_beta_zeta_s = ::nil::blueprint::components::generate_circuit( + bp, assignment, {w, gamma_beta_zeta_s}, row) + .output; + row += add_component::rows_amount; - numerator = zk::components::generate_circuit(bp, assignment, - {numerator, zeta_minus_w}, row) - .output; + ft_eval0_sub = ::nil::blueprint::components::generate_circuit( + bp, assignment, {ft_eval0_sub, w_gamma_beta_zeta_s}, row) + .output; row += mul_component::rows_amount; + } + ft_eval0 = ::nil::blueprint::components::generate_circuit( + bp, assignment, {ft_eval0, ft_eval0_sub}, row) + .output; + row += sub_component::rows_amount; + + // numerator calculation + + var domain_offset_for_zk = + zk_w3_component::generate_circuit(bp, // index.w() + assignment, {params.verifier_index}, row) + .output; + row += zk_w3_component::rows_amount; + + // zeta - index.w() + var zeta_minus_w = ::nil::blueprint::components::generate_circuit( + bp, assignment, {params.zeta, domain_offset_for_zk}, row) + .output; + row += sub_component::rows_amount; - var numerator_term = - zk::components::generate_circuit(bp, assignment, {zeta1m1, alpha2}, row) - .output; - row += mul_component::rows_amount; - numerator_term = zk::components::generate_circuit( - bp, assignment, {numerator_term, zeta_minus_one}, row) + // (zeta - ScalarField::::one()) + var zeta_minus_one = ::nil::blueprint::components::generate_circuit( + bp, assignment, {params.zeta, one}, row) .output; - row += mul_component::rows_amount; - - numerator = zk::components::generate_circuit(bp, assignment, - {numerator, numerator_term}, row) - .output; - row += add_component::rows_amount; - - numerator = zk::components::generate_circuit(bp, assignment, - {numerator, one_minus_z}, row) + row += sub_component::rows_amount; + + // (ScalarField::::one() - evals[0].z) + var one_minus_z = ::nil::blueprint::components::generate_circuit( + bp, assignment, {one, params.combined_evals[0].z}, row) + .output; + row += sub_component::rows_amount; + + // let numerator = ((zeta1m1 * alpha1 * (zeta - index.w())) + // + (zeta1m1 * alpha2 * (zeta - ScalarField::::one()))) + // * (ScalarField::::one() - evals[0].z); + var numerator = ::nil::blueprint::components::generate_circuit( + bp, assignment, {zeta1m1, alpha1}, row) .output; - row += mul_component::rows_amount; + row += mul_component::rows_amount; - // let denominator = (zeta - index.w()) * (zeta - ScalarField::::one()); - // let denominator = denominator.inverse().expect("negligible probability"); - var denominator = zk::components::generate_circuit( - bp, assignment, {zeta_minus_w, zeta_minus_one}, row) - .output; - row += mul_component::rows_amount; + numerator = ::nil::blueprint::components::generate_circuit( + bp, assignment, {numerator, zeta_minus_w}, row) + .output; + row += mul_component::rows_amount; - denominator = - zk::components::generate_circuit(bp, assignment, {one, denominator}, row) - .output; - row += div_component::rows_amount; + var numerator_term = ::nil::blueprint::components::generate_circuit( + bp, assignment, {zeta1m1, alpha2}, row) + .output; + row += mul_component::rows_amount; + numerator_term = ::nil::blueprint::components::generate_circuit( + bp, assignment, {numerator_term, zeta_minus_one}, row) + .output; + row += mul_component::rows_amount; + + numerator = ::nil::blueprint::components::generate_circuit( + bp, assignment, {numerator, numerator_term}, row) + .output; + row += add_component::rows_amount; - // ft_eval0 += numerator * denominator; - var numerator_denominator = zk::components::generate_circuit( - bp, assignment, {numerator, denominator}, row) - .output; + numerator = ::nil::blueprint::components::generate_circuit( + bp, assignment, {numerator, one_minus_z}, row) + .output; + row += mul_component::rows_amount; + + // let denominator = (zeta - index.w()) * (zeta - ScalarField::::one()); + // let denominator = denominator.inverse().expect("negligible probability"); + var denominator = ::nil::blueprint::components::generate_circuit( + bp, assignment, {zeta_minus_w, zeta_minus_one}, row) + .output; + row += mul_component::rows_amount; + + denominator = ::nil::blueprint::components::generate_circuit(bp, assignment, + {one, denominator}, row) + .output; + row += div_component::rows_amount; + + // ft_eval0 += numerator * denominator; + var numerator_denominator = ::nil::blueprint::components::generate_circuit( + bp, assignment, {numerator, denominator}, row) + .output; + row += mul_component::rows_amount; + ft_eval0 = ::nil::blueprint::components::generate_circuit( + bp, assignment, {ft_eval0, numerator_denominator}, row) + .output; + row += add_component::rows_amount; + + // evaluate constant term expression + var pt = constant_term_component::generate_circuit( + bp, assignment, + {index_terms_list::constant_term_str, params.zeta, params.alpha_powers[1], params.beta, + params.gamma, params.joint_combiner, params.combined_evals, + params.verifier_index.omega, params.verifier_index.domain_size}, + row) + .output; + row += constant_term_component::rows_amount; + + ft_eval0 = ::nil::blueprint::components::generate_circuit(bp, assignment, + {ft_eval0, pt}, row) + .output; + row += sub_component::rows_amount; + + assert(row == start_row_index + rows_amount); + + generate_copy_constraints(bp, assignment, params, start_row_index); + generate_assignments_constants(assignment, params, start_row_index); + return result_type(start_row_index); + } + + static result_type generate_assignments(assignment &assignment, + const params_type ¶ms, + const std::size_t start_row_index) { + + std::size_t row = start_row_index; + + var zero(0, start_row_index, false, var::column_type::constant); + var one(0, start_row_index + 1, false, var::column_type::constant); + + row += 2; // skip rows for constant in zkpm + + // zkp = index.zkpm().evaluate(&zeta); + var zkp = zkpm_eval_component::generate_assignments( + assignment, + {params.verifier_index.omega, params.verifier_index.domain_size, params.zeta}, row) + .output; + row += zkpm_eval_component::rows_amount; + + // zeta1m1 = zeta_pow_n - ScalarField::::one(); + var zeta1m1 = sub_component::generate_assignments(assignment, {params.zeta_pow_n, one}, row).output; + row += sub_component::rows_amount; + + // get alpha0, alpha1, alpha2 + std::pair alpha_idxs = + index_terms_list::alpha_map(argument_type::Permutation); + assert(alpha_idxs.second >= 3); + var alpha0 = params.alpha_powers[alpha_idxs.first]; + var alpha1 = params.alpha_powers[alpha_idxs.first + 1]; + var alpha2 = params.alpha_powers[alpha_idxs.first + 2]; + + // let init = (evals[0].w[PERMUTS - 1] + gamma) * evals[1].z * alpha0 * zkp; + var init = add_component::generate_assignments( + assignment, + {params.combined_evals[0].w[KimchiParamsType::permut_size - 1], params.gamma}, row) + .output; + row += add_component::rows_amount; + init = + mul_component::generate_assignments(assignment, {init, params.combined_evals[1].z}, row).output; + row += mul_component::rows_amount; + init = mul_component::generate_assignments(assignment, {init, alpha0}, row).output; + row += mul_component::rows_amount; + init = mul_component::generate_assignments(assignment, {init, zkp}, row).output; + row += mul_component::rows_amount; + + // let mut ft_eval0 = evals[0] + // .w + // .iter() + // .zip(evals[0].s.iter()) + // .map(|(w, s)| (beta * s) + w + gamma) + // .fold(init, |x, y| x * y); + var ft_eval0 = init; + for (std::size_t i = 0; i < KimchiParamsType::permut_size - 1; i++) { + var w = params.combined_evals[0].w[i]; + var s = params.combined_evals[0].s[i]; + var beta_s = mul_component::generate_assignments(assignment, {params.beta, s}, row).output; row += mul_component::rows_amount; - ft_eval0 = zk::components::generate_circuit( - bp, assignment, {ft_eval0, numerator_denominator}, row) - .output; + var w_beta_s = add_component::generate_assignments(assignment, {w, beta_s}, row).output; row += add_component::rows_amount; - - // evaluate constant term expression - var pt = constant_term_component::generate_circuit( - bp, assignment, - {index_terms_list::constant_term_str, params.zeta, params.alpha_powers[1], - params.beta, params.gamma, params.joint_combiner, params.combined_evals, - params.verifier_index.omega, params.verifier_index.domain_size}, - row) - .output; - row += constant_term_component::rows_amount; - - ft_eval0 = - zk::components::generate_circuit(bp, assignment, {ft_eval0, pt}, row).output; - row += sub_component::rows_amount; - - assert(row == start_row_index + rows_amount); - - generate_copy_constraints(bp, assignment, params, start_row_index); - generate_assignments_constants(assignment, params, start_row_index); - return result_type(start_row_index); - } - - static result_type generate_assignments(blueprint_assignment_table &assignment, - const params_type ¶ms, - const std::size_t start_row_index) { - - std::size_t row = start_row_index; - - var zero(0, start_row_index, false, var::column_type::constant); - var one(0, start_row_index + 1, false, var::column_type::constant); - - row += 2; // skip rows for constant in zkpm - - // zkp = index.zkpm().evaluate(&zeta); - var zkp = - zkpm_eval_component::generate_assignments( - assignment, - {params.verifier_index.omega, params.verifier_index.domain_size, params.zeta}, row) - .output; - row += zkpm_eval_component::rows_amount; - - // zeta1m1 = zeta_pow_n - ScalarField::::one(); - var zeta1m1 = sub_component::generate_assignments( - assignment, {params.zeta_pow_n, one}, row).output; - row += sub_component::rows_amount; - - // get alpha0, alpha1, alpha2 - std::pair alpha_idxs = - index_terms_list::alpha_map(argument_type::Permutation); - assert(alpha_idxs.second >= 3); - var alpha0 = params.alpha_powers[alpha_idxs.first]; - var alpha1 = params.alpha_powers[alpha_idxs.first + 1]; - var alpha2 = params.alpha_powers[alpha_idxs.first + 2]; - - // let init = (evals[0].w[PERMUTS - 1] + gamma) * evals[1].z * alpha0 * zkp; - var init = - add_component::generate_assignments( - assignment, - {params.combined_evals[0].w[KimchiParamsType::permut_size - 1], params.gamma}, row) - .output; + var w_beta_s_gamma = + add_component::generate_assignments(assignment, {w_beta_s, params.gamma}, row).output; row += add_component::rows_amount; - init = mul_component::generate_assignments( - assignment, {init, params.combined_evals[1].z}, row).output; - row += mul_component::rows_amount; - init = mul_component::generate_assignments(assignment, {init, alpha0}, row).output; - row += mul_component::rows_amount; - init = mul_component::generate_assignments(assignment, {init, zkp}, row).output; - row += mul_component::rows_amount; - - // let mut ft_eval0 = evals[0] - // .w - // .iter() - // .zip(evals[0].s.iter()) - // .map(|(w, s)| (beta * s) + w + gamma) - // .fold(init, |x, y| x * y); - var ft_eval0 = init; - for (std::size_t i = 0; i < KimchiParamsType::permut_size - 1; i++) { - var w = params.combined_evals[0].w[i]; - var s = params.combined_evals[0].s[i]; - var beta_s = mul_component::generate_assignments(assignment, {params.beta, s}, row).output; - row += mul_component::rows_amount; - var w_beta_s = add_component::generate_assignments(assignment, {w, beta_s}, row).output; - row += add_component::rows_amount; - var w_beta_s_gamma = - add_component::generate_assignments(assignment, {w_beta_s, params.gamma}, row).output; - row += add_component::rows_amount; - ft_eval0 = - mul_component::generate_assignments(assignment, {ft_eval0, w_beta_s_gamma}, row).output; - row += mul_component::rows_amount; - } - - // ft_eval0 - p_eval[0] - if (KimchiParamsType::public_input_size > 0) { - var ft_eval0 = sub_component::generate_assignments( - assignment, {ft_eval0, params.public_eval[0]}, row).output; - row += sub_component::rows_amount; - } - - // ft_eval0 -= evals[0] - // .w - // .iter() - // .zip(index.shift.iter()) - // .map(|(w, s)| gamma + (beta * zeta * s) + w) - // .fold(alpha0 * zkp * evals[0].z, |x, y| x * y); - var ft_eval0_sub = mul_component::generate_assignments(assignment, {alpha0, zkp}, row).output; - row += mul_component::rows_amount; - ft_eval0_sub = mul_component::generate_assignments( - assignment, {ft_eval0_sub, params.combined_evals[0].z}, row) - .output; - row += mul_component::rows_amount; - - for (std::size_t i = 0; i < KimchiParamsType::permut_size; i++) { - var w = params.combined_evals[0].w[i]; - var s = params.verifier_index.shift[i]; - var beta_s = mul_component::generate_assignments(assignment, {params.beta, s}, row).output; - row += mul_component::rows_amount; - var beta_zeta_s = - mul_component::generate_assignments(assignment, {params.zeta, beta_s}, row).output; - row += mul_component::rows_amount; - var gamma_beta_zeta_s = - add_component::generate_assignments(assignment, {params.gamma, beta_zeta_s}, row) - .output; - row += add_component::rows_amount; - var w_gamma_beta_zeta_s = - add_component::generate_assignments(assignment, {w, gamma_beta_zeta_s}, row).output; - row += add_component::rows_amount; - - ft_eval0_sub = mul_component::generate_assignments(assignment, - {ft_eval0_sub, w_gamma_beta_zeta_s}, row) - .output; - row += mul_component::rows_amount; - } ft_eval0 = - sub_component::generate_assignments(assignment, {ft_eval0, ft_eval0_sub}, row).output; - row += sub_component::rows_amount; - - // numerator calculation - - var domain_offset_for_zk = zk_w3_component::generate_assignments( // index.w() - assignment, {params.verifier_index}, row) - .output; - row += zk_w3_component::rows_amount; - - // zeta - index.w() - var zeta_minus_w = - sub_component::generate_assignments(assignment, {params.zeta, domain_offset_for_zk}, row) - .output; - row += sub_component::rows_amount; - - // (zeta - ScalarField::::one()) - var zeta_minus_one = - sub_component::generate_assignments(assignment, {params.zeta, one}, row).output; - row += sub_component::rows_amount; + mul_component::generate_assignments(assignment, {ft_eval0, w_beta_s_gamma}, row).output; + row += mul_component::rows_amount; + } - // (ScalarField::::one() - evals[0].z) - var one_minus_z = - sub_component::generate_assignments(assignment, {one, params.combined_evals[0].z}, row) + // ft_eval0 - p_eval[0] + if (KimchiParamsType::public_input_size > 0) { + var ft_eval0 = + sub_component::generate_assignments(assignment, {ft_eval0, params.public_eval[0]}, row) .output; row += sub_component::rows_amount; + } - // let numerator = ((zeta1m1 * alpha1 * (zeta - index.w())) - // + (zeta1m1 * alpha2 * (zeta - ScalarField::::one()))) - // * (ScalarField::::one() - evals[0].z); - var numerator = mul_component::generate_assignments(assignment, {zeta1m1, alpha1}, row).output; - row += mul_component::rows_amount; - - numerator = - mul_component::generate_assignments(assignment, {numerator, zeta_minus_w}, row).output; + // ft_eval0 -= evals[0] + // .w + // .iter() + // .zip(index.shift.iter()) + // .map(|(w, s)| gamma + (beta * zeta * s) + w) + // .fold(alpha0 * zkp * evals[0].z, |x, y| x * y); + var ft_eval0_sub = mul_component::generate_assignments(assignment, {alpha0, zkp}, row).output; + row += mul_component::rows_amount; + ft_eval0_sub = + mul_component::generate_assignments(assignment, {ft_eval0_sub, params.combined_evals[0].z}, row) + .output; + row += mul_component::rows_amount; + + for (std::size_t i = 0; i < KimchiParamsType::permut_size; i++) { + var w = params.combined_evals[0].w[i]; + var s = params.verifier_index.shift[i]; + var beta_s = mul_component::generate_assignments(assignment, {params.beta, s}, row).output; row += mul_component::rows_amount; - - var numerator_term = - mul_component::generate_assignments(assignment, {zeta1m1, alpha2}, row).output; + var beta_zeta_s = + mul_component::generate_assignments(assignment, {params.zeta, beta_s}, row).output; row += mul_component::rows_amount; - numerator_term = - mul_component::generate_assignments(assignment, {numerator_term, zeta_minus_one}, row) - .output; - row += mul_component::rows_amount; - - numerator = - add_component::generate_assignments(assignment, {numerator, numerator_term}, row).output; + var gamma_beta_zeta_s = + add_component::generate_assignments(assignment, {params.gamma, beta_zeta_s}, row).output; row += add_component::rows_amount; - - numerator = - mul_component::generate_assignments(assignment, {numerator, one_minus_z}, row).output; - row += mul_component::rows_amount; - - // let denominator = (zeta - index.w()) * (zeta - ScalarField::::one()); - // let denominator = denominator.inverse().expect("negligible probability"); - var denominator = - mul_component::generate_assignments(assignment, {zeta_minus_w, zeta_minus_one}, row).output; - row += mul_component::rows_amount; - - denominator = div_component::generate_assignments(assignment, {one, denominator}, row).output; - row += div_component::rows_amount; - - // ft_eval0 += numerator * denominator; - var numerator_denominator = - mul_component::generate_assignments(assignment, {numerator, denominator}, row).output; - row += mul_component::rows_amount; - ft_eval0 = - add_component::generate_assignments(assignment, {ft_eval0, numerator_denominator}, row) - .output; + var w_gamma_beta_zeta_s = + add_component::generate_assignments(assignment, {w, gamma_beta_zeta_s}, row).output; row += add_component::rows_amount; - // evaluate constant term expression - var pt = constant_term_component::generate_assignments( - assignment, - {index_terms_list::constant_term_str, params.zeta, params.alpha_powers[1], - params.beta, params.gamma, params.joint_combiner, params.combined_evals, - params.verifier_index.omega, params.verifier_index.domain_size}, - row) - .output; - row += constant_term_component::rows_amount; - - ft_eval0 = sub_component::generate_assignments(assignment, {ft_eval0, pt}, row).output; - row += sub_component::rows_amount; - - assert(row == start_row_index + rows_amount); - - return result_type(start_row_index); - } - - private: - static void generate_gates(blueprint &bp, - blueprint_public_assignment_table &assignment, - const params_type ¶ms, - const std::size_t first_selector_index) { - } - - static void - generate_copy_constraints(blueprint &bp, - blueprint_public_assignment_table &assignment, - const params_type ¶ms, - const std::size_t start_row_index) { - } - - static void generate_assignments_constants( - blueprint_public_assignment_table &assignment, - const params_type ¶ms, - const std::size_t start_row_index) { - std::size_t row = start_row_index; - assignment.constant(0)[row] = 0; - row++; - assignment.constant(0)[row] = 1; - row++; + ft_eval0_sub = + mul_component::generate_assignments(assignment, {ft_eval0_sub, w_gamma_beta_zeta_s}, row) + .output; + row += mul_component::rows_amount; } - }; - } // namespace components - } // namespace blueprint - } // namespace crypto3 + ft_eval0 = sub_component::generate_assignments(assignment, {ft_eval0, ft_eval0_sub}, row).output; + row += sub_component::rows_amount; + + // numerator calculation + + var domain_offset_for_zk = zk_w3_component::generate_assignments( // index.w() + assignment, {params.verifier_index}, row) + .output; + row += zk_w3_component::rows_amount; + + // zeta - index.w() + var zeta_minus_w = + sub_component::generate_assignments(assignment, {params.zeta, domain_offset_for_zk}, row) + .output; + row += sub_component::rows_amount; + + // (zeta - ScalarField::::one()) + var zeta_minus_one = + sub_component::generate_assignments(assignment, {params.zeta, one}, row).output; + row += sub_component::rows_amount; + + // (ScalarField::::one() - evals[0].z) + var one_minus_z = + sub_component::generate_assignments(assignment, {one, params.combined_evals[0].z}, row).output; + row += sub_component::rows_amount; + + // let numerator = ((zeta1m1 * alpha1 * (zeta - index.w())) + // + (zeta1m1 * alpha2 * (zeta - ScalarField::::one()))) + // * (ScalarField::::one() - evals[0].z); + var numerator = mul_component::generate_assignments(assignment, {zeta1m1, alpha1}, row).output; + row += mul_component::rows_amount; + + numerator = mul_component::generate_assignments(assignment, {numerator, zeta_minus_w}, row).output; + row += mul_component::rows_amount; + + var numerator_term = mul_component::generate_assignments(assignment, {zeta1m1, alpha2}, row).output; + row += mul_component::rows_amount; + numerator_term = + mul_component::generate_assignments(assignment, {numerator_term, zeta_minus_one}, row).output; + row += mul_component::rows_amount; + + numerator = + add_component::generate_assignments(assignment, {numerator, numerator_term}, row).output; + row += add_component::rows_amount; + + numerator = mul_component::generate_assignments(assignment, {numerator, one_minus_z}, row).output; + row += mul_component::rows_amount; + + // let denominator = (zeta - index.w()) * (zeta - ScalarField::::one()); + // let denominator = denominator.inverse().expect("negligible probability"); + var denominator = + mul_component::generate_assignments(assignment, {zeta_minus_w, zeta_minus_one}, row).output; + row += mul_component::rows_amount; + + denominator = div_component::generate_assignments(assignment, {one, denominator}, row).output; + row += div_component::rows_amount; + + // ft_eval0 += numerator * denominator; + var numerator_denominator = + mul_component::generate_assignments(assignment, {numerator, denominator}, row).output; + row += mul_component::rows_amount; + ft_eval0 = + add_component::generate_assignments(assignment, {ft_eval0, numerator_denominator}, row).output; + row += add_component::rows_amount; + + // evaluate constant term expression + var pt = constant_term_component::generate_assignments( + assignment, + {index_terms_list::constant_term_str, params.zeta, params.alpha_powers[1], params.beta, + params.gamma, params.joint_combiner, params.combined_evals, + params.verifier_index.omega, params.verifier_index.domain_size}, + row) + .output; + row += constant_term_component::rows_amount; + + ft_eval0 = sub_component::generate_assignments(assignment, {ft_eval0, pt}, row).output; + row += sub_component::rows_amount; + + assert(row == start_row_index + rows_amount); + + return result_type(start_row_index); + } + + private: + static void generate_gates(blueprint &bp, + assignment &assignment, + const params_type ¶ms, + const std::size_t first_selector_index) { + } + + static void generate_copy_constraints(blueprint &bp, + assignment &assignment, + const params_type ¶ms, + const std::size_t start_row_index) { + } + + static void generate_assignments_constants(assignment &assignment, + const params_type ¶ms, + const std::size_t start_row_index) { + std::size_t row = start_row_index; + assignment.constant(0)[row] = 0; + row++; + assignment.constant(0)[row] = 1; + row++; + } + }; + } // namespace components + } // namespace blueprint } // namespace nil #endif // CRYPTO3_BLUEPRINT_COMPONENTS_PLONK_KIMCHI_DETAIL_FT_EVAL_HPP \ No newline at end of file diff --git a/include/nil/blueprint/components/systems/snark/plonk/kimchi/detail/oracles_scalar/lagrange_denominators.hpp b/include/nil/blueprint/components/systems/snark/plonk/kimchi/detail/oracles_scalar/lagrange_denominators.hpp index 092624e62..e1cad8a96 100644 --- a/include/nil/blueprint/components/systems/snark/plonk/kimchi/detail/oracles_scalar/lagrange_denominators.hpp +++ b/include/nil/blueprint/components/systems/snark/plonk/kimchi/detail/oracles_scalar/lagrange_denominators.hpp @@ -34,154 +34,179 @@ #include -#include -#include +#include +#include +#include namespace nil { - namespace crypto3 { - namespace blueprint { - namespace components { - - // result = [(zeta - omega^(i))^(-1)] concat. [(zeta_omega - omega^(i))^(-1)] for i in - // (0..public_input_size) - // https://github.com/o1-labs/proof-systems/blob/1f8532ec1b8d43748a372632bd854be36b371afe/kimchi/src/verifier.rs#L231-L240 - // Input: eval_point_0, eval_point_1, [omega^0, omega^1, ..., omega^public_input_size] - // Output: [(eval_point_0 - omega^(i))^(-1), (eval_point_1 - omega^(i))^(-1) for i in - // (0..public_input_size)] - template - class lagrange_denominators; - - template - class lagrange_denominators, - PublicInputSize, W0, W1, W2, W3, W4, W5, W6, W7, W8, W9, W10, W11, W12, W13, - W14> { - - typedef snark::plonk_constraint_system - ArithmetizationType; - - using var = snark::plonk_variable; - - using sub_component = zk::components::subtraction; - using div_component = zk::components::division; - - constexpr static const std::size_t selector_seed = 0x0f0d; - - public: - constexpr static const std::size_t rows_amount = - (sub_component::rows_amount + div_component::rows_amount) * PublicInputSize * 2; - constexpr static const std::size_t gates_amount = 0; - - struct params_type { - var zeta; - var zeta_omega; - std::array omega_powers; - var one; - }; - - struct result_type { - std::array output; - - result_type(std::size_t component_start_row) { - std::size_t row = component_start_row; - for (std::size_t i = 0; i < PublicInputSize; i++) { - row += sub_component::rows_amount; - var div_res = typename div_component::result_type(row).output; - row += div_component::rows_amount; - output[i] = div_res; - } - - for (std::size_t i = 0; i < PublicInputSize; i++) { - row += sub_component::rows_amount; - var div_res = typename div_component::result_type(row).output; - row += div_component::rows_amount; - output[PublicInputSize + i] = div_res; - } - } - }; - - static result_type - generate_circuit(blueprint &bp, - blueprint_public_assignment_table &assignment, - const params_type ¶ms, - const std::size_t start_row_index) { + namespace blueprint { + namespace components { + + // result = [(zeta - omega^(i))^(-1)] concat. [(zeta_omega - omega^(i))^(-1)] for i in + // (0..public_input_size) + // https://github.com/o1-labs/proof-systems/blob/1f8532ec1b8d43748a372632bd854be36b371afe/kimchi/src/verifier.rs#L231-L240 + // Input: eval_point_0, eval_point_1, [omega^0, omega^1, ..., omega^public_input_size] + // Output: [(eval_point_0 - omega^(i))^(-1), (eval_point_1 - omega^(i))^(-1) for i in + // (0..public_input_size)] + template + class lagrange_denominators; + + template + class lagrange_denominators, + PublicInputSize, + W0, + W1, + W2, + W3, + W4, + W5, + W6, + W7, + W8, + W9, + W10, + W11, + W12, + W13, + W14> { + + typedef crypto3::zk::snark::plonk_constraint_system ArithmetizationType; + + using var = crypto3::zk::snark::plonk_variable; + + using sub_component = + subtraction>; + using div_component = + division>; + + constexpr static const std::size_t selector_seed = 0x0f0d; + + public: + constexpr static const std::size_t rows_amount = + (sub_component::rows_amount + div_component::rows_amount) * PublicInputSize * 2; + constexpr static const std::size_t gates_amount = 0; + + struct params_type { + var zeta; + var zeta_omega; + std::array omega_powers; + var one; + }; - std::size_t row = start_row_index; + struct result_type { + std::array output; + result_type(std::size_t component_start_row) { + std::size_t row = component_start_row; for (std::size_t i = 0; i < PublicInputSize; i++) { - var sub_res = zk::components::generate_circuit( - bp, assignment, {params.zeta, params.omega_powers[i]}, row) - .output; row += sub_component::rows_amount; - var div_res = zk::components::generate_circuit(bp, assignment, - {params.one, sub_res}, row) - .output; + var div_res = typename div_component::result_type(row).output; row += div_component::rows_amount; + output[i] = div_res; } for (std::size_t i = 0; i < PublicInputSize; i++) { - var sub_res = zk::components::generate_circuit( - bp, assignment, {params.zeta_omega, params.omega_powers[i]}, row) - .output; row += sub_component::rows_amount; - var div_res = zk::components::generate_circuit(bp, assignment, - {params.one, sub_res}, row) - .output; + var div_res = typename div_component::result_type(row).output; row += div_component::rows_amount; + output[PublicInputSize + i] = div_res; } + } + }; - generate_copy_constraints(bp, assignment, params, start_row_index); - return result_type(start_row_index); + static result_type generate_circuit(blueprint &bp, + assignment &assignment, + const params_type ¶ms, + const std::size_t start_row_index) { + + std::size_t row = start_row_index; + + for (std::size_t i = 0; i < PublicInputSize; i++) { + var sub_res = ::nil::blueprint::components::generate_circuit( + bp, assignment, {params.zeta, params.omega_powers[i]}, row) + .output; + row += sub_component::rows_amount; + var div_res = ::nil::blueprint::components::generate_circuit( + bp, assignment, {params.one, sub_res}, row) + .output; + row += div_component::rows_amount; } - static result_type generate_assignments(blueprint_assignment_table &assignment, - const params_type ¶ms, - const std::size_t start_row_index) { + for (std::size_t i = 0; i < PublicInputSize; i++) { + var sub_res = ::nil::blueprint::components::generate_circuit( + bp, assignment, {params.zeta_omega, params.omega_powers[i]}, row) + .output; + row += sub_component::rows_amount; + var div_res = ::nil::blueprint::components::generate_circuit( + bp, assignment, {params.one, sub_res}, row) + .output; + row += div_component::rows_amount; + } - std::size_t row = start_row_index; + generate_copy_constraints(bp, assignment, params, start_row_index); + return result_type(start_row_index); + } - for (std::size_t i = 0; i < PublicInputSize; i++) { - var sub_res = sub_component::generate_assignments( - assignment, {params.zeta, params.omega_powers[i]}, row) - .output; - row += sub_component::rows_amount; - var div_res = - div_component::generate_assignments(assignment, {params.one, sub_res}, row).output; - row += div_component::rows_amount; - } + static result_type generate_assignments(assignment &assignment, + const params_type ¶ms, + const std::size_t start_row_index) { - for (std::size_t i = 0; i < PublicInputSize; i++) { - var sub_res = sub_component::generate_assignments( - assignment, {params.zeta_omega, params.omega_powers[i]}, row) - .output; - row += sub_component::rows_amount; - var div_res = - div_component::generate_assignments(assignment, {params.one, sub_res}, row).output; - row += div_component::rows_amount; - } + std::size_t row = start_row_index; - return result_type(start_row_index); + for (std::size_t i = 0; i < PublicInputSize; i++) { + var sub_res = + sub_component::generate_assignments(assignment, {params.zeta, params.omega_powers[i]}, row) + .output; + row += sub_component::rows_amount; + var div_res = + div_component::generate_assignments(assignment, {params.one, sub_res}, row).output; + row += div_component::rows_amount; } - private: - static void generate_gates(blueprint &bp, - blueprint_public_assignment_table &assignment, - const params_type ¶ms, - const std::size_t first_selector_index) { + for (std::size_t i = 0; i < PublicInputSize; i++) { + var sub_res = sub_component::generate_assignments( + assignment, {params.zeta_omega, params.omega_powers[i]}, row) + .output; + row += sub_component::rows_amount; + var div_res = + div_component::generate_assignments(assignment, {params.one, sub_res}, row).output; + row += div_component::rows_amount; } - static void - generate_copy_constraints(blueprint &bp, - blueprint_public_assignment_table &assignment, - const params_type ¶ms, - const std::size_t start_row_index) { - } - }; - } // namespace components - } // namespace blueprint - } // namespace crypto3 + return result_type(start_row_index); + } + + private: + static void generate_gates(blueprint &bp, + assignment &assignment, + const params_type ¶ms, + const std::size_t first_selector_index) { + } + + static void generate_copy_constraints(blueprint &bp, + assignment &assignment, + const params_type ¶ms, + const std::size_t start_row_index) { + } + }; + } // namespace components + } // namespace blueprint } // namespace nil #endif // CRYPTO3_BLUEPRINT_COMPONENTS_PLONK_KIMCHI_DETAIL_LAGRANGE_DENOMINATORS_HPP \ No newline at end of file diff --git a/include/nil/blueprint/components/systems/snark/plonk/kimchi/detail/oracles_scalar/oracles_cip.hpp b/include/nil/blueprint/components/systems/snark/plonk/kimchi/detail/oracles_scalar/oracles_cip.hpp index 25ee6f605..5ffd18710 100644 --- a/include/nil/blueprint/components/systems/snark/plonk/kimchi/detail/oracles_scalar/oracles_cip.hpp +++ b/include/nil/blueprint/components/systems/snark/plonk/kimchi/detail/oracles_scalar/oracles_cip.hpp @@ -38,225 +38,215 @@ #include -#include +#include namespace nil { - namespace crypto3 { - namespace blueprint { - namespace components { - - // combined inner product from oracles data - // https://github.com/o1-labs/proof-systems/blob/1f8532ec1b8d43748a372632bd854be36b371afe/kimchi/src/verifier.rs#L386-L441 - // Input: - // Output: - template - class oracles_cip; - - template - class oracles_cip, - KimchiParamsType, W0, W1, W2, W3, W4, W5, W6, W7, W8, W9, W10, W11, W12, W13, - W14> { - - typedef snark::plonk_constraint_system - ArithmetizationType; - - using var = snark::plonk_variable; - - constexpr static std::size_t poseidon_selector_size() { - if (KimchiParamsType::circuit_params::poseidon_gate == true) { - return 1; - } - return 0; + namespace blueprint { + namespace components { + + // combined inner product from oracles data + // https://github.com/o1-labs/proof-systems/blob/1f8532ec1b8d43748a372632bd854be36b371afe/kimchi/src/verifier.rs#L386-L441 + // Input: + // Output: + template + class oracles_cip; + + template + class oracles_cip, KimchiParamsType, W0, W1, + W2, W3, W4, W5, W6, W7, W8, W9, W10, W11, W12, W13, W14> { + + typedef crypto3::zk::snark::plonk_constraint_system ArithmetizationType; + + using var = crypto3::zk::snark::plonk_variable; + + constexpr static std::size_t poseidon_selector_size() { + if (KimchiParamsType::circuit_params::poseidon_gate == true) { + return 1; } - constexpr static std::size_t generic_selector_size() { - if (KimchiParamsType::circuit_params::ec_arithmetic_gates == true) { - return 1; - } - return 0; + return 0; + } + constexpr static std::size_t generic_selector_size() { + if (KimchiParamsType::circuit_params::ec_arithmetic_gates == true) { + return 1; } - constexpr static std::size_t p_eval_size() { - if (KimchiParamsType::public_input_size > 0) { - return 1; - } - return 0; + return 0; + } + constexpr static std::size_t p_eval_size() { + if (KimchiParamsType::public_input_size > 0) { + return 1; } - constexpr static const std::size_t cip_size = - KimchiParamsType::prev_challenges_size + p_eval_size() // p_eval - + 1 // ft_eval - + 1 // z - + generic_selector_size() // generic_selector - + poseidon_selector_size() // poseidon_selector - + KimchiParamsType::witness_columns + KimchiParamsType::permut_size - 1; - - constexpr static const std::size_t eval_points_amount = 2; - - using cip_component = - zk::components::combined_inner_product; - - constexpr static const std::size_t selector_seed = 0xf2e; - - public: - constexpr static const std::size_t rows_amount = cip_component::rows_amount; - constexpr static const std::size_t gates_amount = 0; - - struct params_type { - var v; - var u; - - var ft_eval0; - var ft_eval1; - std::array< - std::array, - eval_points_amount>, - KimchiParamsType::prev_challenges_size> - polys; - std::array p_eval; - std::array, eval_points_amount> - evals; - }; - - struct result_type { - var output; - result_type() { - } - result_type(std::size_t start_row_index) { - } + return 0; + } + constexpr static const std::size_t cip_size = + KimchiParamsType::prev_challenges_size + p_eval_size() // p_eval + + 1 // ft_eval + + 1 // z + + generic_selector_size() // generic_selector + + poseidon_selector_size() // poseidon_selector + + KimchiParamsType::witness_columns + KimchiParamsType::permut_size - 1; + + constexpr static const std::size_t eval_points_amount = 2; + + using cip_component = combined_inner_product; + + constexpr static const std::size_t selector_seed = 0xf2e; + + public: + constexpr static const std::size_t rows_amount = cip_component::rows_amount; + constexpr static const std::size_t gates_amount = 0; + + struct params_type { + var v; + var u; + + var ft_eval0; + var ft_eval1; + std::array< + std::array, + eval_points_amount>, + KimchiParamsType::prev_challenges_size> + polys; + std::array p_eval; + std::array, eval_points_amount> + evals; + }; - result_type(const params_type ¶ms, std::size_t start_row_index) { - output = params.ft_eval0; - } - }; - - private: - static std::array, eval_points_amount> - prepare_cip_input(const params_type ¶ms) { - std::array, eval_points_amount> es; - // std::cout< 0) { - for (std::size_t i = 0; i < KimchiParamsType::prev_challenges_size; ++i) { - for (std::size_t j = 0; - j < KimchiParamsType::commitment_params_type::split_poly_eval_size; - ++j) { - for (std::size_t k = 0; k < eval_points_amount; ++k) { - es[k][i] = params.polys[i][k][j]; - } + struct result_type { + var output; + result_type() { + } + result_type(std::size_t start_row_index) { + } + + result_type(const params_type ¶ms, std::size_t start_row_index) { + output = params.ft_eval0; + } + }; + + private: + static std::array, eval_points_amount> + prepare_cip_input(const params_type ¶ms) { + std::array, eval_points_amount> es; + // std::cout< 0) { + for (std::size_t i = 0; i < KimchiParamsType::prev_challenges_size; ++i) { + for (std::size_t j = 0; j < KimchiParamsType::commitment_params_type::split_poly_eval_size; + ++j) { + for (std::size_t k = 0; k < eval_points_amount; ++k) { + es[k][i] = params.polys[i][k][j]; } } - es_idx += KimchiParamsType::prev_challenges_size; } - if (KimchiParamsType::public_input_size > 0) { - for (std::size_t i = 0; i < eval_points_amount; ++i) { - es[i][es_idx] = params.p_eval[i]; - } - es_idx++; + es_idx += KimchiParamsType::prev_challenges_size; + } + if (KimchiParamsType::public_input_size > 0) { + for (std::size_t i = 0; i < eval_points_amount; ++i) { + es[i][es_idx] = params.p_eval[i]; } - - es[0][es_idx] = params.ft_eval0; - es[1][es_idx] = params.ft_eval1; es_idx++; + } + es[0][es_idx] = params.ft_eval0; + es[1][es_idx] = params.ft_eval1; + es_idx++; + + for (std::size_t i = 0; i < eval_points_amount; ++i) { + es[i][es_idx] = params.evals[i].z; + } + es_idx++; + if (KimchiParamsType::circuit_params::ec_arithmetic_gates == true) { for (std::size_t i = 0; i < eval_points_amount; ++i) { - es[i][es_idx] = params.evals[i].z; + es[i][es_idx] = params.evals[i].generic_selector; } es_idx++; - if (KimchiParamsType::circuit_params::ec_arithmetic_gates == true) { - for (std::size_t i = 0; i < eval_points_amount; ++i) { - es[i][es_idx] = params.evals[i].generic_selector; - } - es_idx++; - } - - if (KimchiParamsType::circuit_params::poseidon_gate == true) { - for (std::size_t i = 0; i < eval_points_amount; ++i) { - es[i][es_idx] = params.evals[i].poseidon_selector; - } + } - es_idx++; - } + if (KimchiParamsType::circuit_params::poseidon_gate == true) { for (std::size_t i = 0; i < eval_points_amount; ++i) { - // std::size_t es_idx_tmp = es_idx; - for (std::size_t j = 0, es_idx_tmp = es_idx; j < KimchiParamsType::witness_columns; - ++j, ++es_idx_tmp) { - es[i][es_idx_tmp] = params.evals[i].w[j]; - } + es[i][es_idx] = params.evals[i].poseidon_selector; } - es_idx += KimchiParamsType::witness_columns; - for (std::size_t i = 0; i < eval_points_amount; ++i) { - for (std::size_t j = 0, es_idx_tmp = es_idx; j < KimchiParamsType::permut_size - 1; - ++j, ++es_idx_tmp) { - es[i][es_idx_tmp] = params.evals[i].s[j]; - } - // es_idx++; + + es_idx++; + } + for (std::size_t i = 0; i < eval_points_amount; ++i) { + // std::size_t es_idx_tmp = es_idx; + for (std::size_t j = 0, es_idx_tmp = es_idx; j < KimchiParamsType::witness_columns; + ++j, ++es_idx_tmp) { + es[i][es_idx_tmp] = params.evals[i].w[j]; } - es_idx += KimchiParamsType::permut_size - 1; + } + es_idx += KimchiParamsType::witness_columns; + for (std::size_t i = 0; i < eval_points_amount; ++i) { + for (std::size_t j = 0, es_idx_tmp = es_idx; j < KimchiParamsType::permut_size - 1; + ++j, ++es_idx_tmp) { + es[i][es_idx_tmp] = params.evals[i].s[j]; + } + // es_idx++; + } + es_idx += KimchiParamsType::permut_size - 1; - assert(es_idx <= cip_size); + assert(es_idx <= cip_size); - return es; - } + return es; + } - public: - static result_type - generate_circuit(blueprint &bp, - blueprint_public_assignment_table &assignment, - const params_type ¶ms, - const std::size_t start_row_index) { + public: + static result_type generate_circuit(blueprint &bp, + assignment &assignment, + const params_type ¶ms, + const std::size_t start_row_index) { - std::size_t row = start_row_index; + std::size_t row = start_row_index; - auto es = prepare_cip_input(params); + auto es = prepare_cip_input(params); - var res = - cip_component::generate_circuit(bp, assignment, {es[0], es[1], params.v, params.u}, row) - .output; - row += cip_component::rows_amount; + var res = + cip_component::generate_circuit(bp, assignment, {es[0], es[1], params.v, params.u}, row).output; + row += cip_component::rows_amount; - assert(row == start_row_index + rows_amount); + assert(row == start_row_index + rows_amount); - generate_copy_constraints(bp, assignment, params, start_row_index); - result_type result; - result.output = res; - return result; - } + generate_copy_constraints(bp, assignment, params, start_row_index); + result_type result; + result.output = res; + return result; + } - static result_type generate_assignments(blueprint_assignment_table &assignment, - const params_type ¶ms, - const std::size_t start_row_index) { + static result_type generate_assignments(assignment &assignment, + const params_type ¶ms, + const std::size_t start_row_index) { - std::size_t row = start_row_index; - auto es = prepare_cip_input(params); + std::size_t row = start_row_index; + auto es = prepare_cip_input(params); - var res = - cip_component::generate_assignments(assignment, {es[0], es[1], params.v, params.u}, row) - .output; - row += cip_component::rows_amount; + var res = + cip_component::generate_assignments(assignment, {es[0], es[1], params.v, params.u}, row).output; + row += cip_component::rows_amount; - assert(row == start_row_index + rows_amount); - result_type result; - result.output = res; - return result; - } + assert(row == start_row_index + rows_amount); + result_type result; + result.output = res; + return result; + } - private: - static void - generate_copy_constraints(blueprint &bp, - blueprint_public_assignment_table &assignment, - const params_type ¶ms, - const std::size_t start_row_index) { - } - }; - } // namespace components - } // namespace blueprint - } // namespace crypto3 + private: + static void generate_copy_constraints(blueprint &bp, + assignment &assignment, + const params_type ¶ms, + const std::size_t start_row_index) { + } + }; + } // namespace components + } // namespace blueprint } // namespace nil #endif // CRYPTO3_BLUEPRINT_COMPONENTS_PLONK_KIMCHI_DETAIL_ORACLES_CIP_HPP \ No newline at end of file diff --git a/include/nil/blueprint/components/systems/snark/plonk/kimchi/detail/oracles_scalar/prev_chal_evals.hpp b/include/nil/blueprint/components/systems/snark/plonk/kimchi/detail/oracles_scalar/prev_chal_evals.hpp index 482791cf4..96f14f316 100644 --- a/include/nil/blueprint/components/systems/snark/plonk/kimchi/detail/oracles_scalar/prev_chal_evals.hpp +++ b/include/nil/blueprint/components/systems/snark/plonk/kimchi/detail/oracles_scalar/prev_chal_evals.hpp @@ -32,244 +32,244 @@ #include #include -#include +#include +#include +#include + #include #include -#include - -namespace nil { - namespace crypto3 { - namespace blueprint { - namespace components { - - // evaluate univariate polynomial at points - // https://github.com/o1-labs/proof-systems/blob/1f8532ec1b8d43748a372632bd854be36b371afe/kimchi/src/verifier.rs#L67 - // Input: prev_challenges, zeta, zeta * omega, zeta^n, (zeta * omega)^n, - // Output: (1 + prev_challenges[-1] x)(1 + prev_challenges[-2] x^2)(1 + prev_challenges[-3] x^4)... - template - class prev_chal_evals; - - template - class prev_chal_evals, - KimchiCommitmentParamsType, W0, W1, W2, W3, W4, W5, W6, W7, W8, W9, W10, W11, W12, - W13, W14> { - - typedef snark::plonk_constraint_system - ArithmetizationType; - - using var = snark::plonk_variable; - - using mul_component = zk::components::multiplication; - using add_component = zk::components::addition; - using sub_component = zk::components::subtraction; - - using b_poly_component = - zk::components::b_poly; - using b_poly_coeff_component = - zk::components::b_poly_coefficients; - - constexpr static const std::size_t selector_seed = 0x0f0f; - constexpr static const std::size_t eval_points_amount = 2; - constexpr static const std::size_t eval_rounds = KimchiCommitmentParamsType::eval_rounds; - constexpr static const std::size_t split_poly_eval_size = - KimchiCommitmentParamsType::split_poly_eval_size; - constexpr static const std::size_t max_poly_size = KimchiCommitmentParamsType::max_poly_size; - constexpr static const std::size_t b_len = 1 << eval_rounds; - - public: - constexpr static const std::size_t rows_amount = - split_poly_eval_size == 1 ? - eval_points_amount * b_poly_component::rows_amount : - b_poly_coeff_component::rows_amount + - eval_points_amount * (b_poly_component::rows_amount + - (b_len - max_poly_size) * - (mul_component::rows_amount + mul_component::rows_amount + - add_component::rows_amount) + - mul_component::rows_amount + sub_component::rows_amount); - constexpr static const std::size_t gates_amount = 0; - - struct params_type { - std::array &prev_challenges; - std::array eval_points; - std::array powers_of_eval_points_for_chunks; - var one; - var zero; - }; - - struct result_type { - std::array, eval_points_amount> output; - - result_type(std::size_t component_start_row) { - std::size_t row = component_start_row; - for (std::size_t i = 0; i < eval_points_amount; i++) { - var full = typename b_poly_component::result_type(row).output; - row += b_poly_component::rows_amount; - if (split_poly_eval_size == 1) { - output[i][0] = full; - continue; - } - var diff; - for (std::size_t j = max_poly_size; j < b_len; j++) { - if (i == 0 && j == max_poly_size) { - row += b_poly_coeff_component::rows_amount; - } - row += mul_component::rows_amount; - row += mul_component::rows_amount; +#include - diff = typename add_component::result_type(row).output; - row += add_component::rows_amount; - } - - row += mul_component::rows_amount; - var res_0 = typename sub_component::result_type(row).output; - row += sub_component::rows_amount; - output[i][0] = res_0; - output[i][1] = diff; - } - } - }; - - static result_type - generate_circuit(blueprint &bp, - blueprint_public_assignment_table &assignment, - const params_type ¶ms, - const std::size_t start_row_index) { +namespace nil { + namespace blueprint { + namespace components { + + // evaluate univariate polynomial at points + // https://github.com/o1-labs/proof-systems/blob/1f8532ec1b8d43748a372632bd854be36b371afe/kimchi/src/verifier.rs#L67 + // Input: prev_challenges, zeta, zeta * omega, zeta^n, (zeta * omega)^n, + // Output: (1 + prev_challenges[-1] x)(1 + prev_challenges[-2] x^2)(1 + prev_challenges[-3] x^4)... + template + class prev_chal_evals; + + template + class prev_chal_evals, + KimchiCommitmentParamsType, W0, W1, W2, W3, W4, W5, W6, W7, W8, W9, W10, W11, W12, + W13, W14> { + + typedef crypto3::zk::snark::plonk_constraint_system ArithmetizationType; + + using var = crypto3::zk::snark::plonk_variable; + + using mul_component = multiplication>; + using add_component = + addition>; + using sub_component = + subtraction>; + + using b_poly_component = b_poly; + using b_poly_coeff_component = + b_poly_coefficients; + + constexpr static const std::size_t selector_seed = 0x0f0f; + constexpr static const std::size_t eval_points_amount = 2; + constexpr static const std::size_t eval_rounds = KimchiCommitmentParamsType::eval_rounds; + constexpr static const std::size_t split_poly_eval_size = + KimchiCommitmentParamsType::split_poly_eval_size; + constexpr static const std::size_t max_poly_size = KimchiCommitmentParamsType::max_poly_size; + constexpr static const std::size_t b_len = 1 << eval_rounds; + + public: + constexpr static const std::size_t rows_amount = + split_poly_eval_size == 1 ? + eval_points_amount * b_poly_component::rows_amount : + b_poly_coeff_component::rows_amount + + eval_points_amount * + (b_poly_component::rows_amount + + (b_len - max_poly_size) * (mul_component::rows_amount + mul_component::rows_amount + + add_component::rows_amount) + + mul_component::rows_amount + sub_component::rows_amount); + constexpr static const std::size_t gates_amount = 0; + + struct params_type { + std::array &prev_challenges; + std::array eval_points; + std::array powers_of_eval_points_for_chunks; + var one; + var zero; + }; - std::size_t row = start_row_index; + struct result_type { + std::array, eval_points_amount> output; - std::array b; - std::array, eval_points_amount> res; + result_type(std::size_t component_start_row) { + std::size_t row = component_start_row; for (std::size_t i = 0; i < eval_points_amount; i++) { - var full = - b_poly_component::generate_circuit( - bp, assignment, {params.prev_challenges, params.eval_points[i], params.one}, row) - .output; + var full = typename b_poly_component::result_type(row).output; row += b_poly_component::rows_amount; if (split_poly_eval_size == 1) { - res[i][0] = full; + output[i][0] = full; continue; } - var betaacc = params.one; - var diff = params.zero; + var diff; for (std::size_t j = max_poly_size; j < b_len; j++) { if (i == 0 && j == max_poly_size) { - b = b_poly_coeff_component::generate_circuit( - bp, assignment, {params.prev_challenges, params.one}, row) - .output; row += b_poly_coeff_component::rows_amount; } - var b_j = b[j]; - var ret = - zk::components::generate_circuit(bp, assignment, {betaacc, b_j}, row) - .output; row += mul_component::rows_amount; - - betaacc = zk::components::generate_circuit( - bp, assignment, {betaacc, params.eval_points[i]}, row) - .output; row += mul_component::rows_amount; - diff = zk::components::generate_circuit(bp, assignment, {diff, ret}, row) - .output; + diff = typename add_component::result_type(row).output; row += add_component::rows_amount; } - // [full - (diff * powers_of_eval_points_for_chunks[i]), diff] - var res_0 = zk::components::generate_circuit( - bp, assignment, {diff, params.powers_of_eval_points_for_chunks[i]}, row) - .output; row += mul_component::rows_amount; - res_0 = zk::components::generate_circuit(bp, assignment, {full, res_0}, row) - .output; + var res_0 = typename sub_component::result_type(row).output; row += sub_component::rows_amount; - res[i][0] = res_0; - res[i][1] = diff; + output[i][0] = res_0; + output[i][1] = diff; } - - generate_copy_constraints(bp, assignment, params, start_row_index); - return result_type(start_row_index); } + }; - static result_type generate_assignments(blueprint_assignment_table &assignment, - const params_type ¶ms, - const std::size_t start_row_index) { - - std::size_t row = start_row_index; + static result_type generate_circuit(blueprint &bp, + assignment &assignment, + const params_type ¶ms, + const std::size_t start_row_index) { + + std::size_t row = start_row_index; + + std::array b; + std::array, eval_points_amount> res; + for (std::size_t i = 0; i < eval_points_amount; i++) { + var full = b_poly_component::generate_circuit( + bp, assignment, {params.prev_challenges, params.eval_points[i], params.one}, row) + .output; + row += b_poly_component::rows_amount; + if (split_poly_eval_size == 1) { + res[i][0] = full; + continue; + } - std::array b; - std::array, eval_points_amount> res; - for (std::size_t i = 0; i < eval_points_amount; i++) { - var full = b_poly_component::generate_assignments( - assignment, {params.prev_challenges, params.eval_points[i], params.one}, row) - .output; - row += b_poly_component::rows_amount; - if (split_poly_eval_size == 1) { - res[i][0] = full; - continue; + var betaacc = params.one; + var diff = params.zero; + for (std::size_t j = max_poly_size; j < b_len; j++) { + if (i == 0 && j == max_poly_size) { + b = b_poly_coeff_component::generate_circuit(bp, assignment, + {params.prev_challenges, params.one}, row) + .output; + row += b_poly_coeff_component::rows_amount; } + var b_j = b[j]; + var ret = ::nil::blueprint::components::generate_circuit(bp, assignment, + {betaacc, b_j}, row) + .output; + row += mul_component::rows_amount; - var betaacc = params.one; - var diff = params.zero; - for (std::size_t j = max_poly_size; j < b_len; j++) { - if (i == 0 && j == max_poly_size) { - b = b_poly_coeff_component::generate_assignments( - assignment, {params.prev_challenges, params.one}, row) - .output; - row += b_poly_coeff_component::rows_amount; - } - var b_j = b[j]; - var ret = mul_component::generate_assignments(assignment, {betaacc, b_j}, row).output; - row += mul_component::rows_amount; + betaacc = ::nil::blueprint::components::generate_circuit( + bp, assignment, {betaacc, params.eval_points[i]}, row) + .output; + row += mul_component::rows_amount; - betaacc = mul_component::generate_assignments(assignment, - {betaacc, params.eval_points[i]}, row) - .output; - row += mul_component::rows_amount; + diff = ::nil::blueprint::components::generate_circuit(bp, assignment, + {diff, ret}, row) + .output; + row += add_component::rows_amount; + } - diff = add_component::generate_assignments(assignment, {diff, ret}, row).output; - row += add_component::rows_amount; + // [full - (diff * powers_of_eval_points_for_chunks[i]), diff] + var res_0 = ::nil::blueprint::components::generate_circuit( + bp, assignment, {diff, params.powers_of_eval_points_for_chunks[i]}, row) + .output; + row += mul_component::rows_amount; + res_0 = ::nil::blueprint::components::generate_circuit(bp, assignment, + {full, res_0}, row) + .output; + row += sub_component::rows_amount; + res[i][0] = res_0; + res[i][1] = diff; + } + + generate_copy_constraints(bp, assignment, params, start_row_index); + return result_type(start_row_index); + } + + static result_type generate_assignments(assignment &assignment, + const params_type ¶ms, + const std::size_t start_row_index) { + + std::size_t row = start_row_index; + + std::array b; + std::array, eval_points_amount> res; + for (std::size_t i = 0; i < eval_points_amount; i++) { + var full = b_poly_component::generate_assignments( + assignment, {params.prev_challenges, params.eval_points[i], params.one}, row) + .output; + row += b_poly_component::rows_amount; + if (split_poly_eval_size == 1) { + res[i][0] = full; + continue; + } + + var betaacc = params.one; + var diff = params.zero; + for (std::size_t j = max_poly_size; j < b_len; j++) { + if (i == 0 && j == max_poly_size) { + b = b_poly_coeff_component::generate_assignments( + assignment, {params.prev_challenges, params.one}, row) + .output; + row += b_poly_coeff_component::rows_amount; } + var b_j = b[j]; + var ret = mul_component::generate_assignments(assignment, {betaacc, b_j}, row).output; + row += mul_component::rows_amount; - // [full - (diff * powers_of_eval_points_for_chunks[i]), diff] - var res_0 = mul_component::generate_assignments( - assignment, {diff, params.powers_of_eval_points_for_chunks[i]}, row) - .output; + betaacc = + mul_component::generate_assignments(assignment, {betaacc, params.eval_points[i]}, row) + .output; row += mul_component::rows_amount; - res_0 = sub_component::generate_assignments(assignment, {full, res_0}, row).output; - row += sub_component::rows_amount; - res[i][0] = res_0; - res[i][1] = diff; - } - return result_type(start_row_index); - } + diff = add_component::generate_assignments(assignment, {diff, ret}, row).output; + row += add_component::rows_amount; + } - private: - static void generate_gates(blueprint &bp, - blueprint_public_assignment_table &assignment, - const params_type ¶ms, - const std::size_t first_selector_index) { + // [full - (diff * powers_of_eval_points_for_chunks[i]), diff] + var res_0 = mul_component::generate_assignments( + assignment, {diff, params.powers_of_eval_points_for_chunks[i]}, row) + .output; + row += mul_component::rows_amount; + res_0 = sub_component::generate_assignments(assignment, {full, res_0}, row).output; + row += sub_component::rows_amount; + res[i][0] = res_0; + res[i][1] = diff; } - static void - generate_copy_constraints(blueprint &bp, - blueprint_public_assignment_table &assignment, - const params_type ¶ms, - const std::size_t start_row_index) { - } - }; - } // namespace components - } // namespace blueprint - } // namespace crypto3 + return result_type(start_row_index); + } + + private: + static void generate_gates(blueprint &bp, + assignment &assignment, + const params_type ¶ms, + const std::size_t first_selector_index) { + } + + static void generate_copy_constraints(blueprint &bp, + assignment &assignment, + const params_type ¶ms, + const std::size_t start_row_index) { + } + }; + } // namespace components + } // namespace blueprint } // namespace nil #endif // CRYPTO3_BLUEPRINT_COMPONENTS_PLONK_KIMCHI_DETAIL_PREV_CHAL_EVALS_HPP \ No newline at end of file diff --git a/include/nil/blueprint/components/systems/snark/plonk/kimchi/detail/oracles_scalar/public_evaluations.hpp b/include/nil/blueprint/components/systems/snark/plonk/kimchi/detail/oracles_scalar/public_evaluations.hpp index 37c7e627d..b26e17d38 100644 --- a/include/nil/blueprint/components/systems/snark/plonk/kimchi/detail/oracles_scalar/public_evaluations.hpp +++ b/include/nil/blueprint/components/systems/snark/plonk/kimchi/detail/oracles_scalar/public_evaluations.hpp @@ -34,209 +34,209 @@ #include -#include -#include +#include +#include +#include +#include +#include -namespace nil { - namespace crypto3 { - namespace blueprint { - namespace components { - - // evaluate negated public polynomials at evaluation points - // https://github.com/o1-labs/proof-systems/blob/1f8532ec1b8d43748a372632bd854be36b371afe/kimchi/src/verifier.rs#L245-L269 - // Input: zeta^n, (zeta * omega)^n, lagrange_denominators, public_input, omega_powers - // Output: r = {r_0, r_1} - // r_0 = (zeta_pow_n - 1) * domain.size_inv * SUM(-l * p * w) - // where l from lagrange_denominators, p from public_input, w from omega_powers for l from - // 0 to PulicInputSize - // r_1 = (zeta_omega.pow(n) - 1) * index.domain.size_inv * SUM(-l * p * w) - // where l from lagrange_denominators, p from public_input, w from omega_powers for l from - // PulicInputSize to 2 * PulicInputSize - template - class public_evaluations; - - template - class public_evaluations, - PublicInputSize, W0, W1, W2, W3, W4, W5, W6, W7, W8, W9, W10, W11, W12, W13, - W14> { - - typedef snark::plonk_constraint_system - ArithmetizationType; - - using var = snark::plonk_variable; - - using sub_component = zk::components::subtraction; - using div_component = zk::components::division; - using add_component = zk::components::addition; - using mul_component = zk::components::multiplication; - using mul_by_const_component = zk::components::mul_by_constant; - - constexpr static const std::size_t selector_seed = 0x0f0e; - - public: - constexpr static const std::size_t rows_amount = - 1 + ((mul_by_const_component::rows_amount + mul_component::rows_amount + - mul_component::rows_amount + add_component::rows_amount) * - PublicInputSize + - sub_component::rows_amount + div_component::rows_amount + mul_component::rows_amount) * - 2; - constexpr static const std::size_t gates_amount = 0; - - struct params_type { - var zeta_pow_n; - var zeta_omega_pow_n; - std::array &public_input; - std::array &lagrange_base; - std::array &omega_powers; - var domain_size; - var one; - var zero; - }; - - struct result_type { - std::array output; - - result_type(std::size_t component_start_row) { - std::size_t row = component_start_row; - row++; - for (std::size_t j = 0; j < 2; j++) { - for (std::size_t i = 0; i < PublicInputSize; i++) { - row += mul_by_const_component::rows_amount; - row += mul_component::rows_amount; - row += mul_component::rows_amount; - row += add_component::rows_amount; - } - - row += sub_component::rows_amount; - row += div_component::rows_amount; - output[j] = typename mul_component::result_type(row).output; - row += mul_component::rows_amount; - } - } - }; +#include - static result_type - generate_circuit(blueprint &bp, - blueprint_public_assignment_table &assignment, - const params_type ¶ms, - const std::size_t start_row_index) { +namespace nil { + namespace blueprint { + namespace components { + + // evaluate negated public polynomials at evaluation points + // https://github.com/o1-labs/proof-systems/blob/1f8532ec1b8d43748a372632bd854be36b371afe/kimchi/src/verifier.rs#L245-L269 + // Input: zeta^n, (zeta * omega)^n, lagrange_denominators, public_input, omega_powers + // Output: r = {r_0, r_1} + // r_0 = (zeta_pow_n - 1) * domain.size_inv * SUM(-l * p * w) + // where l from lagrange_denominators, p from public_input, w from omega_powers for l from + // 0 to PulicInputSize + // r_1 = (zeta_omega.pow(n) - 1) * index.domain.size_inv * SUM(-l * p * w) + // where l from lagrange_denominators, p from public_input, w from omega_powers for l from + // PulicInputSize to 2 * PulicInputSize + template + class public_evaluations; + + template + class public_evaluations, PublicInputSize, + W0, W1, W2, W3, W4, W5, W6, W7, W8, W9, W10, W11, W12, W13, W14> { + + typedef crypto3::zk::snark::plonk_constraint_system ArithmetizationType; + + using var = crypto3::zk::snark::plonk_variable; + + using sub_component = + subtraction>; + using div_component = + division>; + using add_component = + addition>; + using mul_component = multiplication>; + using mul_by_const_component = mul_by_constant; + + constexpr static const std::size_t selector_seed = 0x0f0e; + + public: + constexpr static const std::size_t rows_amount = + 1 + ((mul_by_const_component::rows_amount + mul_component::rows_amount + + mul_component::rows_amount + add_component::rows_amount) * + PublicInputSize + + sub_component::rows_amount + div_component::rows_amount + mul_component::rows_amount) * + 2; + constexpr static const std::size_t gates_amount = 0; + + struct params_type { + var zeta_pow_n; + var zeta_omega_pow_n; + std::array &public_input; + std::array &lagrange_base; + std::array &omega_powers; + var domain_size; + var one; + var zero; + }; - std::size_t row = start_row_index; + struct result_type { + std::array output; - std::array res = {var(W0, row, false), var(W1, row, false)}; + result_type(std::size_t component_start_row) { + std::size_t row = component_start_row; row++; - for (std::size_t j = 0; j < 2; j++) { for (std::size_t i = 0; i < PublicInputSize; i++) { - var term = zk::components::generate_circuit( - bp, assignment, {params.lagrange_base[j * PublicInputSize + i], -1}, row) - .output; row += mul_by_const_component::rows_amount; - term = zk::components::generate_circuit( - bp, assignment, {term, params.public_input[i]}, row) - .output; row += mul_component::rows_amount; - term = zk::components::generate_circuit( - bp, assignment, {term, params.omega_powers[i]}, row) - .output; row += mul_component::rows_amount; - res[j] = - zk::components::generate_circuit(bp, assignment, {res[j], term}, row) - .output; row += add_component::rows_amount; } - var tmp = j == 0 ? params.zeta_pow_n : params.zeta_omega_pow_n; - var res_multiplier = - zk::components::generate_circuit(bp, assignment, {tmp, params.one}, row) - .output; row += sub_component::rows_amount; - res_multiplier = zk::components::generate_circuit( - bp, assignment, {res_multiplier, params.domain_size}, row) - .output; row += div_component::rows_amount; - res[j] = zk::components::generate_circuit(bp, assignment, - {res[j], res_multiplier}, row) - .output; + output[j] = typename mul_component::result_type(row).output; row += mul_component::rows_amount; } - - generate_copy_constraints(bp, assignment, params, start_row_index); - return result_type(start_row_index); } + }; - static result_type generate_assignments(blueprint_assignment_table &assignment, - const params_type ¶ms, - const std::size_t start_row_index) { + static result_type generate_circuit(blueprint &bp, + assignment &assignment, + const params_type ¶ms, + const std::size_t start_row_index) { - std::size_t row = start_row_index; + std::size_t row = start_row_index; - // r[0] = (zeta_pow_n - 1) * domain.size_inv * SUM(-l * p * w) - // where l from lagrange, p from public, w from omega_powers for l from 0 to PulicInputSize - // r[2] = (zeta_omega.pow(n) - 1) * index.domain.size_inv * SUM(-l * p * w) - // where l from lagrange, p from public, w from omega_powers for l from PulicInputSize to 2 * - // PulicInputSize - assignment.witness(W0)[row] = 0; - assignment.witness(W1)[row] = 0; - std::array res = {var(W0, row, false), var(W1, row, false)}; - row++; - - for (std::size_t j = 0; j < 2; j++) { - for (std::size_t i = 0; i < PublicInputSize; i++) { - var term = mul_by_const_component::generate_assignments( - assignment, {params.lagrange_base[j * PublicInputSize + i], -1}, row) - .output; - row += mul_by_const_component::rows_amount; - term = - mul_component::generate_assignments(assignment, {term, params.public_input[i]}, row) - .output; - row += mul_component::rows_amount; - term = - mul_component::generate_assignments(assignment, {term, params.omega_powers[i]}, row) - .output; - row += mul_component::rows_amount; - res[j] = add_component::generate_assignments(assignment, {res[j], term}, row).output; - row += add_component::rows_amount; - } + std::array res = {var(W0, row, false), var(W1, row, false)}; + row++; - var tmp = j == 0 ? params.zeta_pow_n : params.zeta_omega_pow_n; - var res_multiplier = - sub_component::generate_assignments(assignment, {tmp, params.one}, row).output; - row += sub_component::rows_amount; - res_multiplier = div_component::generate_assignments( - assignment, {res_multiplier, params.domain_size}, row) - .output; - row += div_component::rows_amount; - res[j] = - mul_component::generate_assignments(assignment, {res[j], res_multiplier}, row).output; + for (std::size_t j = 0; j < 2; j++) { + for (std::size_t i = 0; i < PublicInputSize; i++) { + var term = ::nil::blueprint::components::generate_circuit( + bp, assignment, {params.lagrange_base[j * PublicInputSize + i], -1}, row) + .output; + row += mul_by_const_component::rows_amount; + term = ::nil::blueprint::components::generate_circuit( + bp, assignment, {term, params.public_input[i]}, row) + .output; + row += mul_component::rows_amount; + term = ::nil::blueprint::components::generate_circuit( + bp, assignment, {term, params.omega_powers[i]}, row) + .output; row += mul_component::rows_amount; + res[j] = ::nil::blueprint::components::generate_circuit(bp, assignment, + {res[j], term}, row) + .output; + row += add_component::rows_amount; } - return result_type(start_row_index); + var tmp = j == 0 ? params.zeta_pow_n : params.zeta_omega_pow_n; + var res_multiplier = ::nil::blueprint::components::generate_circuit( + bp, assignment, {tmp, params.one}, row) + .output; + row += sub_component::rows_amount; + res_multiplier = ::nil::blueprint::components::generate_circuit( + bp, assignment, {res_multiplier, params.domain_size}, row) + .output; + row += div_component::rows_amount; + res[j] = ::nil::blueprint::components::generate_circuit( + bp, assignment, {res[j], res_multiplier}, row) + .output; + row += mul_component::rows_amount; } - private: - static void generate_gates(blueprint &bp, - blueprint_public_assignment_table &assignment, - const params_type ¶ms, - const std::size_t first_selector_index) { - } + generate_copy_constraints(bp, assignment, params, start_row_index); + return result_type(start_row_index); + } + + static result_type generate_assignments(assignment &assignment, + const params_type ¶ms, + const std::size_t start_row_index) { + + std::size_t row = start_row_index; + + // r[0] = (zeta_pow_n - 1) * domain.size_inv * SUM(-l * p * w) + // where l from lagrange, p from public, w from omega_powers for l from 0 to PulicInputSize + // r[2] = (zeta_omega.pow(n) - 1) * index.domain.size_inv * SUM(-l * p * w) + // where l from lagrange, p from public, w from omega_powers for l from PulicInputSize to 2 * + // PulicInputSize + assignment.witness(W0)[row] = 0; + assignment.witness(W1)[row] = 0; + std::array res = {var(W0, row, false), var(W1, row, false)}; + row++; + + for (std::size_t j = 0; j < 2; j++) { + for (std::size_t i = 0; i < PublicInputSize; i++) { + var term = mul_by_const_component::generate_assignments( + assignment, {params.lagrange_base[j * PublicInputSize + i], -1}, row) + .output; + row += mul_by_const_component::rows_amount; + term = mul_component::generate_assignments(assignment, {term, params.public_input[i]}, row) + .output; + row += mul_component::rows_amount; + term = mul_component::generate_assignments(assignment, {term, params.omega_powers[i]}, row) + .output; + row += mul_component::rows_amount; + res[j] = add_component::generate_assignments(assignment, {res[j], term}, row).output; + row += add_component::rows_amount; + } - static void - generate_copy_constraints(blueprint &bp, - blueprint_public_assignment_table &assignment, - const params_type ¶ms, - const std::size_t start_row_index) { - bp.add_copy_constraint({var(W0, start_row_index, false), params.zero}); - bp.add_copy_constraint({var(W1, start_row_index, false), params.zero}); + var tmp = j == 0 ? params.zeta_pow_n : params.zeta_omega_pow_n; + var res_multiplier = + sub_component::generate_assignments(assignment, {tmp, params.one}, row).output; + row += sub_component::rows_amount; + res_multiplier = + div_component::generate_assignments(assignment, {res_multiplier, params.domain_size}, row) + .output; + row += div_component::rows_amount; + res[j] = mul_component::generate_assignments(assignment, {res[j], res_multiplier}, row).output; + row += mul_component::rows_amount; } - }; - } // namespace components - } // namespace blueprint - } // namespace crypto3 + + return result_type(start_row_index); + } + + private: + static void generate_gates(blueprint &bp, + assignment &assignment, + const params_type ¶ms, + const std::size_t first_selector_index) { + } + + static void generate_copy_constraints(blueprint &bp, + assignment &assignment, + const params_type ¶ms, + const std::size_t start_row_index) { + bp.add_copy_constraint({var(W0, start_row_index, false), params.zero}); + bp.add_copy_constraint({var(W1, start_row_index, false), params.zero}); + } + }; + } // namespace components + } // namespace blueprint } // namespace nil #endif // CRYPTO3_BLUEPRINT_COMPONENTS_PLONK_KIMCHI_DETAIL_PUBLIC_EVALUATIONS_HPP \ No newline at end of file diff --git a/include/nil/blueprint/components/systems/snark/plonk/kimchi/detail/sponge.hpp b/include/nil/blueprint/components/systems/snark/plonk/kimchi/detail/sponge.hpp index f9e5efebd..9812739ef 100644 --- a/include/nil/blueprint/components/systems/snark/plonk/kimchi/detail/sponge.hpp +++ b/include/nil/blueprint/components/systems/snark/plonk/kimchi/detail/sponge.hpp @@ -32,226 +32,223 @@ #include +#include + #include #include -#include -#include -#include + +#include +#include #include -#include +#include +#include "nil/blueprint/components/algebra/fields/plonk/addition.hpp" namespace nil { - namespace crypto3 { - namespace blueprint { - namespace components { - - // Poseidon sponge construction - // https://github.com/o1-labs/proof-systems/blob/1f8532ec1b8d43748a372632bd854be36b371afe/oracle/src/poseidon.rs#L64 - template - class kimchi_sponge; - - template - class kimchi_sponge, - CurveType, W0, W1, W2, W3, W4, W5, W6, W7, W8, W9, W10, W11, W12, W13, W14> { - - typedef snark::plonk_constraint_system - ArithmetizationType; - - using var = snark::plonk_variable; - using poseidon_component = - typename zk::components::poseidon; - using add_component = typename zk::components::addition; - std::size_t state_count = 0; - bool state_absorbed = true; - - std::array state = {var(W0, 0), var(W1, 0), var(W2, 0)}; - - void permute_assignment(blueprint_assignment_table &assignment, - const std::size_t &component_start_row) { - - typename poseidon_component::result_type poseidon_res = - poseidon_component::generate_assignments(assignment, {state}, component_start_row); - - for (std::size_t i = 0; i < poseidon_component::state_size; i++) { - state[i] = poseidon_res.output_state[i]; - } - } + namespace blueprint { + namespace components { - void add_input_assignment(blueprint_assignment_table &assignment, - var &input, - std::size_t state_index, - const std::size_t component_start_row) { + // Poseidon sponge construction + // https://github.com/o1-labs/proof-systems/blob/1f8532ec1b8d43748a372632bd854be36b371afe/oracle/src/poseidon.rs#L64 + template + class kimchi_sponge; - auto addition_result = add_component::generate_assignments( - assignment, {input, state[state_index]}, component_start_row); - state[state_index] = addition_result.output; - } + template + class kimchi_sponge, CurveType, W0, W1, W2, + W3, W4, W5, W6, W7, W8, W9, W10, W11, W12, W13, W14> { - void permute_circuit(blueprint &bp, - blueprint_public_assignment_table &assignment, - const std::size_t component_start_row) { + typedef crypto3::zk::snark::plonk_constraint_system ArithmetizationType; - typename poseidon_component::result_type poseidon_res = - poseidon_component::generate_circuit(bp, assignment, {state}, component_start_row); + using var = crypto3::zk::snark::plonk_variable; + using poseidon_component = poseidon; + using add_component = + addition>; + std::size_t state_count = 0; + bool state_absorbed = true; - for (std::size_t i = 0; i < poseidon_component::state_size; i++) { - state[i] = poseidon_res.output_state[i]; - } - } + std::array state = {var(W0, 0), var(W1, 0), var(W2, 0)}; - void add_input_circuit(blueprint &bp, - blueprint_public_assignment_table &assignment, - const var &input, - std::size_t state_index, - const std::size_t component_start_row) { + void permute_assignment(assignment &assignment, + const std::size_t &component_start_row) { - auto addition_result = zk::components::generate_circuit( - bp, assignment, {input, state[state_index]}, component_start_row); - state[state_index] = addition_result.output; + typename poseidon_component::result_type poseidon_res = + poseidon_component::generate_assignments(assignment, {state}, component_start_row); + + for (std::size_t i = 0; i < poseidon_component::state_size; i++) { + state[i] = poseidon_res.output_state[i]; } + } + + void add_input_assignment(assignment &assignment, + var &input, + std::size_t state_index, + const std::size_t component_start_row) { - constexpr static const std::size_t permute_rows = poseidon_component::rows_amount; - constexpr static const std::size_t add_input_rows = add_component::rows_amount; + auto addition_result = add_component::generate_assignments(assignment, {input, state[state_index]}, + component_start_row); + state[state_index] = addition_result.output; + } - public: - constexpr static const std::size_t init_rows = 0; - constexpr static const std::size_t absorb_rows = permute_rows + add_input_rows; - constexpr static const std::size_t squeeze_rows = permute_rows; - constexpr static const std::size_t gates_amount = 0; + void permute_circuit(blueprint &bp, + assignment &assignment, + const std::size_t component_start_row) { - constexpr static const std::size_t state_size = poseidon_component::state_size; + typename poseidon_component::result_type poseidon_res = + poseidon_component::generate_circuit(bp, assignment, {state}, component_start_row); - std::array _inner_state() { - return state; + for (std::size_t i = 0; i < poseidon_component::state_size; i++) { + state[i] = poseidon_res.output_state[i]; } + } - void init_assignment(blueprint_assignment_table &assignment, - var zero, - const std::size_t component_start_row) { + void add_input_circuit(blueprint &bp, + assignment &assignment, + const var &input, + std::size_t state_index, + const std::size_t component_start_row) { - for (std::size_t i = 0; i < poseidon_component::state_size; i++) { - state[i] = zero; - } - } + auto addition_result = generate_circuit(bp, assignment, {input, state[state_index]}, + component_start_row); + state[state_index] = addition_result.output; + } - void init_circuit(blueprint &bp, - blueprint_public_assignment_table &assignment, - const var zero, - const std::size_t component_start_row) { + constexpr static const std::size_t permute_rows = poseidon_component::rows_amount; + constexpr static const std::size_t add_input_rows = add_component::rows_amount; - for (std::size_t i = 0; i < poseidon_component::state_size; i++) { - state[i] = zero; - } + public: + constexpr static const std::size_t init_rows = 0; + constexpr static const std::size_t absorb_rows = permute_rows + add_input_rows; + constexpr static const std::size_t squeeze_rows = permute_rows; + constexpr static const std::size_t gates_amount = 0; + + constexpr static const std::size_t state_size = poseidon_component::state_size; + + std::array _inner_state() { + return state; + } + + void init_assignment(assignment &assignment, + var zero, + const std::size_t component_start_row) { + + for (std::size_t i = 0; i < poseidon_component::state_size; i++) { + state[i] = zero; } + } - void absorb_assignment(blueprint_assignment_table &assignment, - var absorbing_value, - const std::size_t component_start_row) { + void init_circuit(blueprint &bp, + assignment &assignment, + const var zero, + const std::size_t component_start_row) { - std::size_t row = component_start_row; + for (std::size_t i = 0; i < poseidon_component::state_size; i++) { + state[i] = zero; + } + } - if (this->state_absorbed) { - if (this->state_count == poseidon_component::rate) { - permute_assignment(assignment, component_start_row); - row += permute_rows; + void absorb_assignment(assignment &assignment, + var absorbing_value, + const std::size_t component_start_row) { - add_input_assignment(assignment, absorbing_value, 0, row); + std::size_t row = component_start_row; - this->state_count = 1; - } else { - add_input_assignment(assignment, absorbing_value, this->state_count, - component_start_row); + if (this->state_absorbed) { + if (this->state_count == poseidon_component::rate) { + permute_assignment(assignment, component_start_row); + row += permute_rows; - this->state_count++; - } - } else { - add_input_assignment(assignment, absorbing_value, 0, component_start_row); + add_input_assignment(assignment, absorbing_value, 0, row); - this->state_absorbed = true; this->state_count = 1; + } else { + add_input_assignment(assignment, absorbing_value, this->state_count, component_start_row); + + this->state_count++; } - } + } else { + add_input_assignment(assignment, absorbing_value, 0, component_start_row); - void absorb_circuit(blueprint &bp, - blueprint_public_assignment_table &assignment, - const var &absorbing_value, - const std::size_t component_start_row) { + this->state_absorbed = true; + this->state_count = 1; + } + } - std::size_t row = component_start_row; + void absorb_circuit(blueprint &bp, + assignment &assignment, + const var &absorbing_value, + const std::size_t component_start_row) { - if (this->state_absorbed) { - if (this->state_count == poseidon_component::rate) { - permute_circuit(bp, assignment, component_start_row); + std::size_t row = component_start_row; - row += permute_rows; + if (this->state_absorbed) { + if (this->state_count == poseidon_component::rate) { + permute_circuit(bp, assignment, component_start_row); - add_input_circuit(bp, assignment, absorbing_value, 0, row); + row += permute_rows; - this->state_count = 1; - } else { - add_input_circuit(bp, assignment, absorbing_value, this->state_count, - component_start_row); + add_input_circuit(bp, assignment, absorbing_value, 0, row); - this->state_count++; - } + this->state_count = 1; } else { - add_input_circuit(bp, assignment, absorbing_value, 0, component_start_row); + add_input_circuit(bp, assignment, absorbing_value, this->state_count, component_start_row); - this->state_absorbed = true; - this->state_count = 1; + this->state_count++; } + } else { + add_input_circuit(bp, assignment, absorbing_value, 0, component_start_row); + + this->state_absorbed = true; + this->state_count = 1; } + } - var squeeze_assignment(blueprint_assignment_table &assignment, - const std::size_t component_start_row) { - if (!this->state_absorbed) { // state = squeezed - if (this->state_count == poseidon_component::rate) { - permute_assignment(assignment, component_start_row); - this->state_count = 1; - return this->state[0]; - } else { - return this->state[this->state_count++]; - } - } else { + var squeeze_assignment(assignment &assignment, + const std::size_t component_start_row) { + if (!this->state_absorbed) { // state = squeezed + if (this->state_count == poseidon_component::rate) { permute_assignment(assignment, component_start_row); - - this->state_absorbed = false; this->state_count = 1; - return this->state[0]; + } else { + return this->state[this->state_count++]; } + } else { + permute_assignment(assignment, component_start_row); + + this->state_absorbed = false; + this->state_count = 1; + + return this->state[0]; } + } - var squeeze_circuit(blueprint &bp, - blueprint_public_assignment_table &assignment, - const std::size_t component_start_row) { - - if (!this->state_absorbed) { // state = squeezed - if (this->state_count == poseidon_component::rate) { - permute_circuit(bp, assignment, component_start_row); - this->state_count = 1; - return this->state[0]; - } else { - return this->state[this->state_count++]; - } - } else { - permute_circuit(bp, assignment, component_start_row); + var squeeze_circuit(blueprint &bp, + assignment &assignment, + const std::size_t component_start_row) { - this->state_absorbed = false; + if (!this->state_absorbed) { // state = squeezed + if (this->state_count == poseidon_component::rate) { + permute_circuit(bp, assignment, component_start_row); this->state_count = 1; - return this->state[0]; + } else { + return this->state[this->state_count++]; } + } else { + permute_circuit(bp, assignment, component_start_row); + + this->state_absorbed = false; + this->state_count = 1; + + return this->state[0]; } - }; - } // namespace components - } // namespace blueprint - } // namespace crypto3 + } + }; + } // namespace components + } // namespace blueprint } // namespace nil #endif // CRYPTO3_BLUEPRINT_COMPONENTS_PLONK_KIMCHI_SPONGE_HPP diff --git a/include/nil/blueprint/components/systems/snark/plonk/kimchi/detail/table_commitment.hpp b/include/nil/blueprint/components/systems/snark/plonk/kimchi/detail/table_commitment.hpp index fe635c6d2..7de2517cc 100644 --- a/include/nil/blueprint/components/systems/snark/plonk/kimchi/detail/table_commitment.hpp +++ b/include/nil/blueprint/components/systems/snark/plonk/kimchi/detail/table_commitment.hpp @@ -29,191 +29,201 @@ #include -#include -#include +#include +#include -#include -#include -#include +#include +#include +#include -#include +#include namespace nil { - namespace crypto3 { - namespace zk { - namespace components { - - // Compute Lookup Table commitment - // https://github.com/o1-labs/proof-systems/blob/1f8532ec1b8d43748a372632bd854be36b371afe/kimchi/src/verifier.rs#L830 - // Input: - // Output: - template - class table_commitment; - - template - class table_commitment< - snark::plonk_constraint_system, - KimchiParamsType, - CurveType, - W0, - W1, - W2, - W3, - W4, - W5, - W6, - W7, - W8, - W9, - W10, - W11, - W12, - W13, - W14> { - - typedef snark::plonk_constraint_system - ArithmetizationType; - - using var = snark::plonk_variable; - using var_ec_point = typename zk::components::var_ec_point; - - constexpr static const std::size_t lookup_columns = KimchiParamsType::circuit_params::lookup_columns; - - constexpr static const std::size_t use_lookup_runtime = KimchiParamsType::circuit_params::lookup_runtime ? 1 : 0; - - constexpr static const std::size_t msm_size = (lookup_columns + use_lookup_runtime) - * KimchiParamsType::commitment_params_type::shifted_commitment_split; - - using commitment_type = typename - zk::components::kimchi_commitment_type; - using msm_component = zk::components::element_g1_multi_scalar_mul; - - public: - constexpr static const std::size_t rows_amount = msm_component::rows_amount; - constexpr static const std::size_t gates_amount = 0; - - struct params_type { - std::vector table; - std::array joint_combiner; - commitment_type runtime; - }; - - struct result_type { - commitment_type output; - - result_type(std::size_t start_row_index) { - std::size_t row = start_row_index; - } - }; - - static result_type - generate_circuit(blueprint &bp, - blueprint_public_assignment_table &assignment, - const params_type ¶ms, - const std::size_t start_row_index) { + namespace blueprint { + namespace components { + + // Compute Lookup Table commitment + // https://github.com/o1-labs/proof-systems/blob/1f8532ec1b8d43748a372632bd854be36b371afe/kimchi/src/verifier.rs#L830 + // Input: + // Output: + template + class table_commitment; + + template + class table_commitment, + KimchiParamsType, + CurveType, + W0, + W1, + W2, + W3, + W4, + W5, + W6, + W7, + W8, + W9, + W10, + W11, + W12, + W13, + W14> { + + typedef crypto3::zk::snark::plonk_constraint_system ArithmetizationType; + + using var = crypto3::zk::snark::plonk_variable; + using var_ec_point = var_ec_point; + + constexpr static const std::size_t lookup_columns = KimchiParamsType::circuit_params::lookup_columns; + + constexpr static const std::size_t use_lookup_runtime = + KimchiParamsType::circuit_params::lookup_runtime ? 1 : 0; + + constexpr static const std::size_t msm_size = + (lookup_columns + use_lookup_runtime) * + KimchiParamsType::commitment_params_type::shifted_commitment_split; + + using commitment_type = + kimchi_commitment_type; + using msm_component = element_g1_multi_scalar_mul; + + public: + constexpr static const std::size_t rows_amount = msm_component::rows_amount; + constexpr static const std::size_t gates_amount = 0; + + struct params_type { + std::vector table; + std::array joint_combiner; + commitment_type runtime; + }; - generate_assignments_constants(bp, assignment, params, start_row_index); + struct result_type { + commitment_type output; + result_type(std::size_t start_row_index) { std::size_t row = start_row_index; - std::array commitments; - std::array scalars; - std::size_t j = 0; - std::size_t comm_size = params.table[0].parts.size(); - for(std::size_t i = j; i < commitments.size(); i++) { - for (std::size_t k = 0; k < comm_size; k++) { - commitments[i*comm_size + k] = params.table[i].parts[k]; - scalars[i*comm_size + k] = params.joint_combiner[i]; - j++; - } - } - if (KimchiParamsType::circuit_params::lookup_runtime) { - for (std::size_t k = 0; k < comm_size; k++) { - commitments[j] = params.runtime.parts[k]; - scalars[j] = params.joint_combiner[1]; - j++; - } - } - msm_component::generate_circuit(bp, assignment, {scalars, commitments}, row); - return result_type(row); - - return result_type(row); } + }; - static result_type generate_assignments(blueprint_assignment_table &assignment, - const params_type ¶ms, - const std::size_t start_row_index) { - - std::size_t row = start_row_index; - std::array commitments; - std::array scalars; - std::size_t j = 0; - std::size_t comm_size = params.table[0].parts.size(); - for(std::size_t i = j; i < commitments.size(); i++) { - for (std::size_t k = 0; k < comm_size; k++) { - commitments[i*comm_size + k] = params.table[i].parts[k]; - scalars[i*comm_size + k] = params.joint_combiner[i]; - j++; - } + static result_type generate_circuit(blueprint &bp, + assignment &assignment, + const params_type ¶ms, + const std::size_t start_row_index) { + + generate_assignments_constants(bp, assignment, params, start_row_index); + + std::size_t row = start_row_index; + std::array commitments; + std::array scalars; + std::size_t j = 0; + std::size_t comm_size = params.table[0].parts.size(); + for (std::size_t i = j; i < commitments.size(); i++) { + for (std::size_t k = 0; k < comm_size; k++) { + commitments[i * comm_size + k] = params.table[i].parts[k]; + scalars[i * comm_size + k] = params.joint_combiner[i]; + j++; } - if (KimchiParamsType::circuit_params::lookup_runtime) { - for (std::size_t k = 0; k < comm_size; k++) { - commitments[j] = params.runtime.parts[k]; - scalars[j] = params.joint_combiner[1]; - j++; - } - } - msm_component::generate_assignments(assignment, {scalars, commitments}, row); - return result_type(row); } - - private: - static void generate_gates(blueprint &bp, - blueprint_public_assignment_table &assignment, - const params_type ¶ms, - const std::size_t first_selector_index) { + if (KimchiParamsType::circuit_params::lookup_runtime) { + for (std::size_t k = 0; k < comm_size; k++) { + commitments[j] = params.runtime.parts[k]; + scalars[j] = params.joint_combiner[1]; + j++; + } } - - static void - generate_copy_constraints(blueprint &bp, - blueprint_public_assignment_table &assignment, - const params_type ¶ms, - const std::size_t start_row_index) { + msm_component::generate_circuit(bp, assignment, {scalars, commitments}, row); + return result_type(row); + + return result_type(row); + } + + static result_type generate_assignments(assignment &assignment, + const params_type ¶ms, + const std::size_t start_row_index) { + + std::size_t row = start_row_index; + std::array commitments; + std::array scalars; + std::size_t j = 0; + std::size_t comm_size = params.table[0].parts.size(); + for (std::size_t i = j; i < commitments.size(); i++) { + for (std::size_t k = 0; k < comm_size; k++) { + commitments[i * comm_size + k] = params.table[i].parts[k]; + scalars[i * comm_size + k] = params.joint_combiner[i]; + j++; + } } - - static void generate_assignments_constants( - blueprint &bp, - blueprint_public_assignment_table &assignment, - const params_type ¶ms, - const std::size_t start_row_index) { - std::size_t row = start_row_index; + if (KimchiParamsType::circuit_params::lookup_runtime) { + for (std::size_t k = 0; k < comm_size; k++) { + commitments[j] = params.runtime.parts[k]; + scalars[j] = params.joint_combiner[1]; + j++; + } } - }; - } // namespace components - } // namespace zk - } // namespace crypto3 + msm_component::generate_assignments(assignment, {scalars, commitments}, row); + return result_type(row); + } + + private: + static void generate_gates(blueprint &bp, + assignment &assignment, + const params_type ¶ms, + const std::size_t first_selector_index) { + } + + static void generate_copy_constraints(blueprint &bp, + assignment &assignment, + const params_type ¶ms, + const std::size_t start_row_index) { + } + + static void generate_assignments_constants(blueprint &bp, + assignment &assignment, + const params_type ¶ms, + const std::size_t start_row_index) { + std::size_t row = start_row_index; + } + }; + } // namespace components + } // namespace blueprint } // namespace nil #endif // CRYPTO3_ZK_BLUEPRINT_PLONK_KIMCHI_DETAIL_TABLE_COMMITMENT_HPP \ No newline at end of file diff --git a/include/nil/blueprint/components/systems/snark/plonk/kimchi/detail/to_group.hpp b/include/nil/blueprint/components/systems/snark/plonk/kimchi/detail/to_group.hpp index 82a9f3490..a5cc20d43 100644 --- a/include/nil/blueprint/components/systems/snark/plonk/kimchi/detail/to_group.hpp +++ b/include/nil/blueprint/components/systems/snark/plonk/kimchi/detail/to_group.hpp @@ -32,608 +32,619 @@ #include #include -#include +#include +#include +#include +#include #include -#include +#include #include #include namespace nil { - namespace crypto3 { - namespace blueprint { - namespace components { - - // generate elliptic curve point from a field element - // https://github.com/o1-labs/proof-systems/blob/1f8532ec1b8d43748a372632bd854be36b371afe/poly-commitment/src/commitment.rs#L370 - // Input: x \in F_q - // Output: U \in E(F_q) - template - class to_group; - - template - class to_group, W0, W1, W2, - W3, W4, W5, W6, W7, W8, W9, W10, W11, W12, W13, W14> { - - typedef snark::plonk_constraint_system - ArithmetizationType; - - using var = snark::plonk_variable; - using var_ec_point = typename zk::components::var_ec_point; - - using mul_component = zk::components::multiplication; - using add_component = zk::components::addition; - using div_component = zk::components::division_or_zero; - using sub_component = zk::components::subtraction; - - constexpr static const std::size_t selector_seed = 0x0f30; - - struct curve_params { - var u; - var fu; - var inv_three_u_squared; - var sqrt_neg_three_u_squared; - var sqrt_neg_three_u_squared_minus_u_over_2; - - var b; - - curve_params(std::size_t start_row_index) { - u = var(0, start_row_index + 3, false, var::column_type::constant); - fu = var(0, start_row_index + 4, false, var::column_type::constant); - inv_three_u_squared = var(0, start_row_index + 5, false, var::column_type::constant); - sqrt_neg_three_u_squared = var(0, start_row_index + 6, false, var::column_type::constant); - sqrt_neg_three_u_squared_minus_u_over_2 = - var(0, start_row_index + 7, false, var::column_type::constant); - b = var(0, start_row_index + 8, false, var::column_type::constant); - } - }; - - constexpr static std::size_t potential_xs_rows = - mul_component::rows_amount * 9 + add_component::rows_amount * 2 + div_component::rows_amount + - sub_component::rows_amount * 4; + namespace blueprint { + namespace components { + + // generate elliptic curve point from a field element + // https://github.com/o1-labs/proof-systems/blob/1f8532ec1b8d43748a372632bd854be36b371afe/poly-commitment/src/commitment.rs#L370 + // Input: x \in F_q + // Output: U \in E(F_q) + template + class to_group; + + template + class to_group, W0, W1, W2, W3, W4, W5, W6, + W7, W8, W9, W10, W11, W12, W13, W14> { + + typedef crypto3::zk::snark::plonk_constraint_system ArithmetizationType; + + using var = crypto3::zk::snark::plonk_variable; + using var_ec_point = var_ec_point; + + using mul_component = multiplication>; + using add_component = + addition>; + using div_component = division_or_zero; + using sub_component = + subtraction>; + + constexpr static const std::size_t selector_seed = 0x0f30; + + struct curve_params { + var u; + var fu; + var inv_three_u_squared; + var sqrt_neg_three_u_squared; + var sqrt_neg_three_u_squared_minus_u_over_2; + + var b; + + curve_params(std::size_t start_row_index) { + u = var(0, start_row_index + 3, false, var::column_type::constant); + fu = var(0, start_row_index + 4, false, var::column_type::constant); + inv_three_u_squared = var(0, start_row_index + 5, false, var::column_type::constant); + sqrt_neg_three_u_squared = var(0, start_row_index + 6, false, var::column_type::constant); + sqrt_neg_three_u_squared_minus_u_over_2 = + var(0, start_row_index + 7, false, var::column_type::constant); + b = var(0, start_row_index + 8, false, var::column_type::constant); + } + }; - static std::array - potential_xs_assignment(blueprint_assignment_table &assignment, var t, - curve_params params, var one, var zero, std::size_t row) { - var t2 = mul_component::generate_assignments(assignment, {t, t}, row).output; - row += mul_component::rows_amount; + constexpr static std::size_t potential_xs_rows = + mul_component::rows_amount * 9 + add_component::rows_amount * 2 + div_component::rows_amount + + sub_component::rows_amount * 4; + + static std::array potential_xs_assignment(assignment &assignment, var t, + curve_params params, var one, var zero, + std::size_t row) { + var t2 = mul_component::generate_assignments(assignment, {t, t}, row).output; + row += mul_component::rows_amount; + + var alpha = add_component::generate_assignments(assignment, {t2, params.fu}, row).output; + row += add_component::rows_amount; + alpha = mul_component::generate_assignments(assignment, {alpha, t2}, row).output; + row += mul_component::rows_amount; + alpha = div_component::generate_assignments(assignment, {one, alpha}, row).output; + row += div_component::rows_amount; + + var x1 = t2; + x1 = mul_component::generate_assignments(assignment, {x1, x1}, row).output; // t2^2 + row += mul_component::rows_amount; + x1 = mul_component::generate_assignments(assignment, {x1, alpha}, row).output; // t2^2 * alpha + row += mul_component::rows_amount; + x1 = mul_component::generate_assignments(assignment, {x1, params.sqrt_neg_three_u_squared}, row) + .output; // t2^2 * alpha * sqrt(-3u^2) + row += mul_component::rows_amount; + x1 = sub_component::generate_assignments(assignment, + {params.sqrt_neg_three_u_squared_minus_u_over_2, x1}, row) + .output; // sqrt(-3u^2-u/2) - t2^2 * alpha * sqrt(-3u^2) + row += sub_component::rows_amount; + + var minus_u = sub_component::generate_assignments(assignment, {zero, params.u}, row).output; + row += sub_component::rows_amount; + + var x2 = sub_component::generate_assignments(assignment, {minus_u, x1}, row).output; + row += sub_component::rows_amount; + + var t2_plus_fu = add_component::generate_assignments(assignment, {t2, params.fu}, row).output; + row += add_component::rows_amount; + var t2_inv = mul_component::generate_assignments(assignment, {t2_plus_fu, alpha}, row).output; + row += mul_component::rows_amount; + + var x3 = mul_component::generate_assignments(assignment, {t2_plus_fu, t2_plus_fu}, row).output; + row += mul_component::rows_amount; + x3 = mul_component::generate_assignments(assignment, {x3, t2_inv}, row).output; + row += mul_component::rows_amount; + x3 = mul_component::generate_assignments(assignment, {x3, params.inv_three_u_squared}, row).output; + row += mul_component::rows_amount; + x3 = sub_component::generate_assignments(assignment, {params.u, x3}, row).output; + row += sub_component::rows_amount; + + return {x1, x2, x3}; + } + + static std::array potential_xs_circuit(blueprint &bp, + assignment &assignment, var t, + curve_params params, var one, var zero, + std::size_t row) { + var t2 = ::nil::blueprint::components::generate_circuit(bp, assignment, {t, t}, row) + .output; + row += mul_component::rows_amount; - var alpha = add_component::generate_assignments(assignment, {t2, params.fu}, row).output; - row += add_component::rows_amount; - alpha = mul_component::generate_assignments(assignment, {alpha, t2}, row).output; - row += mul_component::rows_amount; - alpha = div_component::generate_assignments(assignment, {one, alpha}, row).output; - row += div_component::rows_amount; + var alpha = ::nil::blueprint::components::generate_circuit(bp, assignment, + {t2, params.fu}, row) + .output; + row += add_component::rows_amount; + alpha = + ::nil::blueprint::components::generate_circuit(bp, assignment, {alpha, t2}, row) + .output; + row += mul_component::rows_amount; + alpha = + ::nil::blueprint::components::generate_circuit(bp, assignment, {one, alpha}, row) + .output; + row += div_component::rows_amount; + + var x1 = t2; + x1 = ::nil::blueprint::components::generate_circuit(bp, assignment, {x1, x1}, row) + .output; // t2^2 + row += mul_component::rows_amount; + x1 = ::nil::blueprint::components::generate_circuit(bp, assignment, {x1, alpha}, row) + .output; // t2^2 * alpha + row += mul_component::rows_amount; + x1 = ::nil::blueprint::components::generate_circuit( + bp, assignment, {x1, params.sqrt_neg_three_u_squared}, row) + .output; // t2^2 * alpha * sqrt(-3u^2) + row += mul_component::rows_amount; + x1 = ::nil::blueprint::components::generate_circuit( + bp, assignment, {params.sqrt_neg_three_u_squared_minus_u_over_2, x1}, row) + .output; // sqrt(-3u^2-u/2) - t2^2 * alpha * sqrt(-3u^2) + row += sub_component::rows_amount; + + var minus_u = ::nil::blueprint::components::generate_circuit(bp, assignment, + {zero, params.u}, row) + .output; + row += sub_component::rows_amount; + + var x2 = ::nil::blueprint::components::generate_circuit(bp, assignment, + {minus_u, x1}, row) + .output; + row += sub_component::rows_amount; - var x1 = t2; - x1 = mul_component::generate_assignments(assignment, {x1, x1}, row).output; // t2^2 - row += mul_component::rows_amount; - x1 = - mul_component::generate_assignments(assignment, {x1, alpha}, row).output; // t2^2 * alpha - row += mul_component::rows_amount; - x1 = mul_component::generate_assignments(assignment, {x1, params.sqrt_neg_three_u_squared}, row) - .output; // t2^2 * alpha * sqrt(-3u^2) - row += mul_component::rows_amount; - x1 = sub_component::generate_assignments( - assignment, {params.sqrt_neg_three_u_squared_minus_u_over_2, x1}, row) - .output; // sqrt(-3u^2-u/2) - t2^2 * alpha * sqrt(-3u^2) - row += sub_component::rows_amount; + var t2_plus_fu = ::nil::blueprint::components::generate_circuit(bp, assignment, + {t2, params.fu}, row) + .output; + row += add_component::rows_amount; + var t2_inv = ::nil::blueprint::components::generate_circuit(bp, assignment, + {t2_plus_fu, alpha}, row) + .output; + row += mul_component::rows_amount; - var minus_u = sub_component::generate_assignments(assignment, {zero, params.u}, row).output; - row += sub_component::rows_amount; + var x3 = ::nil::blueprint::components::generate_circuit( + bp, assignment, {t2_plus_fu, t2_plus_fu}, row) + .output; + row += mul_component::rows_amount; + x3 = + ::nil::blueprint::components::generate_circuit(bp, assignment, {x3, t2_inv}, row) + .output; + row += mul_component::rows_amount; + x3 = ::nil::blueprint::components::generate_circuit( + bp, assignment, {x3, params.inv_three_u_squared}, row) + .output; + row += mul_component::rows_amount; + x3 = ::nil::blueprint::components::generate_circuit(bp, assignment, {params.u, x3}, + row) + .output; + row += sub_component::rows_amount; + + return {x1, x2, x3}; + } + + constexpr static std::size_t get_y_rows = mul_component::rows_amount * 3 + add_component::rows_amount; + + static var get_y_assignments(assignment &assignment, var x, curve_params params, + std::size_t row) { + // curve_eq + var y_squared = mul_component::generate_assignments(assignment, {x, x}, row) + .output; // x^2 + A (A = 0 for pasta curves) + row += mul_component::rows_amount; + + y_squared = + mul_component::generate_assignments(assignment, {y_squared, x}, row).output; // x^3 + A x + row += mul_component::rows_amount; + + y_squared = add_component::generate_assignments(assignment, {y_squared, params.b}, row) + .output; // x^3 + A x + B + row += add_component::rows_amount; + + // sqrt + typename BlueprintFieldType::value_type y_val = assignment.var_value(y_squared).sqrt(); + assignment.witness(0)[row] = y_val; + var y(0, row); + var y_squared_recalculated = mul_component::generate_assignments(assignment, {y, y}, row).output; + row += mul_component::rows_amount; + + // copy constraint + + return y; + } + + static var get_y_circuit(blueprint &bp, + assignment &assignment, var x, curve_params params, + std::size_t row) { + // curve_eq + var y_squared = + ::nil::blueprint::components::generate_circuit(bp, assignment, {x, x}, row) + .output; // x^2 + A (A = 0 for pasta curves) + row += mul_component::rows_amount; + + y_squared = ::nil::blueprint::components::generate_circuit(bp, assignment, + {y_squared, x}, row) + .output; // x^3 + A x + row += mul_component::rows_amount; + + y_squared = ::nil::blueprint::components::generate_circuit( + bp, assignment, {y_squared, params.b}, row) + .output; // x^3 + A x + B + row += add_component::rows_amount; + + // sqrt + var y(0, row); + var y_squared_recalculated = + ::nil::blueprint::components::generate_circuit(bp, assignment, {y, y}, row) + .output; + row += mul_component::rows_amount; + + // copy constraint + + return y; + } + + constexpr static std::size_t rows() { + std::size_t row = 0; + row += potential_xs_rows; + + const std::size_t points_size = 3; + for (std::size_t i = 0; i < points_size; ++i) { + row += get_y_rows; + } - var x2 = sub_component::generate_assignments(assignment, {minus_u, x1}, row).output; + for (std::size_t i = 0; i < points_size; ++i) { row += sub_component::rows_amount; + row += div_component::rows_amount; - var t2_plus_fu = add_component::generate_assignments(assignment, {t2, params.fu}, row).output; - row += add_component::rows_amount; - var t2_inv = mul_component::generate_assignments(assignment, {t2_plus_fu, alpha}, row).output; - row += mul_component::rows_amount; - - var x3 = mul_component::generate_assignments(assignment, {t2_plus_fu, t2_plus_fu}, row).output; - row += mul_component::rows_amount; - x3 = mul_component::generate_assignments(assignment, {x3, t2_inv}, row).output; row += mul_component::rows_amount; - x3 = mul_component::generate_assignments(assignment, {x3, params.inv_three_u_squared}, row) - .output; - row += mul_component::rows_amount; - x3 = sub_component::generate_assignments(assignment, {params.u, x3}, row).output; row += sub_component::rows_amount; - return {x1, x2, x3}; - } + row += add_component::rows_amount; - static std::array - potential_xs_circuit(blueprint &bp, - blueprint_public_assignment_table &assignment, var t, - curve_params params, var one, var zero, std::size_t row) { - var t2 = zk::components::generate_circuit(bp, assignment, {t, t}, row).output; - row += mul_component::rows_amount; + if (i == 0) { + continue; + } - var alpha = - zk::components::generate_circuit(bp, assignment, {t2, params.fu}, row) - .output; - row += add_component::rows_amount; - alpha = - zk::components::generate_circuit(bp, assignment, {alpha, t2}, row).output; - row += mul_component::rows_amount; - alpha = - zk::components::generate_circuit(bp, assignment, {one, alpha}, row).output; row += div_component::rows_amount; - var x1 = t2; - x1 = zk::components::generate_circuit(bp, assignment, {x1, x1}, row) - .output; // t2^2 - row += mul_component::rows_amount; - x1 = zk::components::generate_circuit(bp, assignment, {x1, alpha}, row) - .output; // t2^2 * alpha - row += mul_component::rows_amount; - x1 = zk::components::generate_circuit(bp, assignment, - {x1, params.sqrt_neg_three_u_squared}, row) - .output; // t2^2 * alpha * sqrt(-3u^2) row += mul_component::rows_amount; - x1 = zk::components::generate_circuit( - bp, assignment, {params.sqrt_neg_three_u_squared_minus_u_over_2, x1}, row) - .output; // sqrt(-3u^2-u/2) - t2^2 * alpha * sqrt(-3u^2) - row += sub_component::rows_amount; - - var minus_u = - zk::components::generate_circuit(bp, assignment, {zero, params.u}, row) - .output; - row += sub_component::rows_amount; - var x2 = - zk::components::generate_circuit(bp, assignment, {minus_u, x1}, row).output; row += sub_component::rows_amount; - var t2_plus_fu = - zk::components::generate_circuit(bp, assignment, {t2, params.fu}, row) - .output; - row += add_component::rows_amount; - var t2_inv = - zk::components::generate_circuit(bp, assignment, {t2_plus_fu, alpha}, row) - .output; row += mul_component::rows_amount; - var x3 = zk::components::generate_circuit(bp, assignment, - {t2_plus_fu, t2_plus_fu}, row) - .output; - row += mul_component::rows_amount; - x3 = zk::components::generate_circuit(bp, assignment, {x3, t2_inv}, row).output; - row += mul_component::rows_amount; - x3 = zk::components::generate_circuit(bp, assignment, - {x3, params.inv_three_u_squared}, row) - .output; row += mul_component::rows_amount; - x3 = - zk::components::generate_circuit(bp, assignment, {params.u, x3}, row).output; - row += sub_component::rows_amount; - - return {x1, x2, x3}; } - constexpr static std::size_t get_y_rows = - mul_component::rows_amount * 3 + add_component::rows_amount; - - static var get_y_assignments(blueprint_assignment_table &assignment, var x, - curve_params params, std::size_t row) { - // curve_eq - var y_squared = mul_component::generate_assignments(assignment, {x, x}, row) - .output; // x^2 + A (A = 0 for pasta curves) - row += mul_component::rows_amount; - - y_squared = - mul_component::generate_assignments(assignment, {y_squared, x}, row).output; // x^3 + A x + for (std::size_t i = 0; i < points_size; ++i) { row += mul_component::rows_amount; - - y_squared = add_component::generate_assignments(assignment, {y_squared, params.b}, row) - .output; // x^3 + A x + B row += add_component::rows_amount; - // sqrt - typename BlueprintFieldType::value_type y_val = assignment.var_value(y_squared).sqrt(); - assignment.witness(0)[row] = y_val; - var y(0, row); - var y_squared_recalculated = - mul_component::generate_assignments(assignment, {y, y}, row).output; row += mul_component::rows_amount; - - // copy constraint - - return y; - } - - static var get_y_circuit(blueprint &bp, - blueprint_public_assignment_table &assignment, var x, - curve_params params, std::size_t row) { - // curve_eq - var y_squared = zk::components::generate_circuit(bp, assignment, {x, x}, row) - .output; // x^2 + A (A = 0 for pasta curves) - row += mul_component::rows_amount; - - y_squared = zk::components::generate_circuit(bp, assignment, {y_squared, x}, row) - .output; // x^3 + A x - row += mul_component::rows_amount; - - y_squared = - zk::components::generate_circuit(bp, assignment, {y_squared, params.b}, row) - .output; // x^3 + A x + B row += add_component::rows_amount; - - // sqrt - var y(0, row); - var y_squared_recalculated = - zk::components::generate_circuit(bp, assignment, {y, y}, row).output; - row += mul_component::rows_amount; - - // copy constraint - - return y; } - constexpr static std::size_t rows() { - std::size_t row = 0; - row += potential_xs_rows; - - const std::size_t points_size = 3; - for (std::size_t i = 0; i < points_size; ++i) { - row += get_y_rows; - } - - for (std::size_t i = 0; i < points_size; ++i) { - row += sub_component::rows_amount; - row += div_component::rows_amount; - - row += mul_component::rows_amount; - row += sub_component::rows_amount; - - row += add_component::rows_amount; + return row; + } - if (i == 0) { - continue; - } + public: + constexpr static const std::size_t rows_amount = rows(); + constexpr static const std::size_t gates_amount = 0; - row += div_component::rows_amount; + struct params_type { + var t; + }; - row += mul_component::rows_amount; + struct result_type { + var_ec_point output; - row += sub_component::rows_amount; + result_type(std::size_t start_row_index) { + const std::size_t points_size = 3; - row += mul_component::rows_amount; + std::size_t row = rows_amount - points_size * (2 * mul_component::rows_amount + + 2 * add_component::rows_amount); - row += mul_component::rows_amount; - } + var x; + var y; for (std::size_t i = 0; i < points_size; ++i) { row += mul_component::rows_amount; + x = typename add_component::result_type(row).output; row += add_component::rows_amount; row += mul_component::rows_amount; + y = typename add_component::result_type(row).output; row += add_component::rows_amount; } - return row; + output = {x, y}; } + }; - public: - constexpr static const std::size_t rows_amount = rows(); - constexpr static const std::size_t gates_amount = 0; - - struct params_type { - var t; - }; - - struct result_type { - var_ec_point output; - - result_type(std::size_t start_row_index) { - const std::size_t points_size = 3; - - std::size_t row = rows_amount - points_size * (2 * mul_component::rows_amount + - 2 * add_component::rows_amount); - - var x; - var y; + static result_type generate_circuit(blueprint &bp, + assignment &assignment, + const params_type ¶ms, + const std::size_t start_row_index) { - for (std::size_t i = 0; i < points_size; ++i) { - row += mul_component::rows_amount; - x = typename add_component::result_type(row).output; - row += add_component::rows_amount; + generate_assignments_constants(assignment, params, start_row_index); + std::size_t row = start_row_index; - row += mul_component::rows_amount; - y = typename add_component::result_type(row).output; - row += add_component::rows_amount; - } + var zero(0, start_row_index, false, var::column_type::constant); + var one(0, start_row_index + 1, false, var::column_type::constant); + var minus_one(0, start_row_index + 2, false, var::column_type::constant); - output = {x, y}; - } - }; + curve_params params_curve(start_row_index); - static result_type - generate_circuit(blueprint &bp, - blueprint_public_assignment_table &assignment, - const params_type ¶ms, - const std::size_t start_row_index) { + std::array xs = + potential_xs_circuit(bp, assignment, params.t, params_curve, one, zero, row); + row += potential_xs_rows; - generate_assignments_constants(assignment, params, start_row_index); - std::size_t row = start_row_index; + std::array ys; + for (std::size_t i = 0; i < xs.size(); ++i) { + ys[i] = get_y_circuit(bp, assignment, xs[i], params_curve, row); + row += get_y_rows; + } - var zero(0, start_row_index, false, var::column_type::constant); - var one(0, start_row_index + 1, false, var::column_type::constant); - var minus_one(0, start_row_index + 2, false, var::column_type::constant); + std::array nulifiers; + // nulifiers[i] = 1 if ys[i] != -1 AND nulifiers[i - 1] == 0, 0 otherwise + // E1: (ys[i] - (-1)) * (ys[i] - (-1))**(-1) -1 = 0 if ys[i] != -1, -1 otherwise + // E2: E1 + 1 = 1 if ys[i] != -1, 0 otherwise + // E3: nulifiers[i - 1] * nulifiers[i - 1]**(-1) -1 = 0 if nulifiers[i - 1] != 0, -1 otherwise + // E4: E3 * (-1) = 0 if nulifiers[i - 1] != 0, 1 otherwise + // E5: E2 * E4 = 1 if ys[i] != -1 AND nulifiers[i - 1] = 0, 0 otherwise + + for (std::size_t i = 0; i < ys.size(); ++i) { + var y1 = ::nil::blueprint::components::generate_circuit(bp, assignment, + {ys[i], minus_one}, row) + .output; + row += sub_component::rows_amount; + var y1_inversed = ::nil::blueprint::components::generate_circuit(bp, assignment, + {one, y1}, row) + .output; + row += div_component::rows_amount; - curve_params params_curve(start_row_index); + var e1 = ::nil::blueprint::components::generate_circuit(bp, assignment, + {y1, y1_inversed}, row) + .output; + row += mul_component::rows_amount; + e1 = ::nil::blueprint::components::generate_circuit(bp, assignment, {e1, one}, + row) + .output; + row += sub_component::rows_amount; - std::array xs = - potential_xs_circuit(bp, assignment, params.t, params_curve, one, zero, row); - row += potential_xs_rows; + var e2 = ::nil::blueprint::components::generate_circuit(bp, assignment, + {e1, one}, row) + .output; + row += add_component::rows_amount; - std::array ys; - for (std::size_t i = 0; i < xs.size(); ++i) { - ys[i] = get_y_circuit(bp, assignment, xs[i], params_curve, row); - row += get_y_rows; + if (i == 0) { + nulifiers[i] = e2; + continue; } - std::array nulifiers; - // nulifiers[i] = 1 if ys[i] != -1 AND nulifiers[i - 1] == 0, 0 otherwise - // E1: (ys[i] - (-1)) * (ys[i] - (-1))**(-1) -1 = 0 if ys[i] != -1, -1 otherwise - // E2: E1 + 1 = 1 if ys[i] != -1, 0 otherwise - // E3: nulifiers[i - 1] * nulifiers[i - 1]**(-1) -1 = 0 if nulifiers[i - 1] != 0, -1 otherwise - // E4: E3 * (-1) = 0 if nulifiers[i - 1] != 0, 1 otherwise - // E5: E2 * E4 = 1 if ys[i] != -1 AND nulifiers[i - 1] = 0, 0 otherwise - - for (std::size_t i = 0; i < ys.size(); ++i) { - var y1 = - zk::components::generate_circuit(bp, assignment, {ys[i], minus_one}, row) - .output; - row += sub_component::rows_amount; - var y1_inversed = - zk::components::generate_circuit(bp, assignment, {one, y1}, row).output; - row += div_component::rows_amount; - - var e1 = - zk::components::generate_circuit(bp, assignment, {y1, y1_inversed}, row) - .output; - row += mul_component::rows_amount; - e1 = zk::components::generate_circuit(bp, assignment, {e1, one}, row).output; - row += sub_component::rows_amount; - - var e2 = - zk::components::generate_circuit(bp, assignment, {e1, one}, row).output; - row += add_component::rows_amount; - - if (i == 0) { - nulifiers[i] = e2; - continue; - } - - var n_inversed = zk::components::generate_circuit( - bp, assignment, {one, nulifiers[i - 1]}, row) - .output; - row += div_component::rows_amount; - - var e3 = zk::components::generate_circuit( - bp, assignment, {nulifiers[i - 1], n_inversed}, row) - .output; - row += mul_component::rows_amount; - - e3 = zk::components::generate_circuit(bp, assignment, {e3, one}, row).output; - row += sub_component::rows_amount; + var n_inversed = ::nil::blueprint::components::generate_circuit( + bp, assignment, {one, nulifiers[i - 1]}, row) + .output; + row += div_component::rows_amount; - var e4 = - zk::components::generate_circuit(bp, assignment, {e3, minus_one}, row) - .output; - row += mul_component::rows_amount; + var e3 = ::nil::blueprint::components::generate_circuit( + bp, assignment, {nulifiers[i - 1], n_inversed}, row) + .output; + row += mul_component::rows_amount; - var e5 = - zk::components::generate_circuit(bp, assignment, {e2, e4}, row).output; - row += mul_component::rows_amount; + e3 = ::nil::blueprint::components::generate_circuit(bp, assignment, {e3, one}, + row) + .output; + row += sub_component::rows_amount; - nulifiers[i] = e5; - } + var e4 = ::nil::blueprint::components::generate_circuit(bp, assignment, + {e3, minus_one}, row) + .output; + row += mul_component::rows_amount; - var x = zero; - var y = zero; + var e5 = + ::nil::blueprint::components::generate_circuit(bp, assignment, {e2, e4}, row) + .output; + row += mul_component::rows_amount; - // res = (xs[0] * nulifiers[0] + xs[1] * nulifiers[1] + xs[2] * nulifiers[2], - // ys[0] * nulifiers[0] + ys[1] * nulifiers[1] + ys[2] * nulifiers[2]) - for (std::size_t i = 0; i < xs.size(); ++i) { - var tmp = zk::components::generate_circuit(bp, assignment, - {xs[i], nulifiers[i]}, row) - .output; - row += mul_component::rows_amount; - x = zk::components::generate_circuit(bp, assignment, {x, tmp}, row).output; - row += add_component::rows_amount; + nulifiers[i] = e5; + } - var tmp_y = zk::components::generate_circuit(bp, assignment, - {ys[i], nulifiers[i]}, row) - .output; - row += mul_component::rows_amount; - y = zk::components::generate_circuit(bp, assignment, {y, tmp_y}, row).output; - row += add_component::rows_amount; - } + var x = zero; + var y = zero; - assert(row == start_row_index + rows_amount); + // res = (xs[0] * nulifiers[0] + xs[1] * nulifiers[1] + xs[2] * nulifiers[2], + // ys[0] * nulifiers[0] + ys[1] * nulifiers[1] + ys[2] * nulifiers[2]) + for (std::size_t i = 0; i < xs.size(); ++i) { + var tmp = ::nil::blueprint::components::generate_circuit( + bp, assignment, {xs[i], nulifiers[i]}, row) + .output; + row += mul_component::rows_amount; + x = ::nil::blueprint::components::generate_circuit(bp, assignment, {x, tmp}, row) + .output; + row += add_component::rows_amount; - generate_copy_constraints(bp, assignment, params, start_row_index); - return result_type(start_row_index); + var tmp_y = ::nil::blueprint::components::generate_circuit( + bp, assignment, {ys[i], nulifiers[i]}, row) + .output; + row += mul_component::rows_amount; + y = ::nil::blueprint::components::generate_circuit(bp, assignment, {y, tmp_y}, + row) + .output; + row += add_component::rows_amount; } - static result_type generate_assignments(blueprint_assignment_table &assignment, - const params_type ¶ms, - const std::size_t start_row_index) { - std::size_t row = start_row_index; + assert(row == start_row_index + rows_amount); - var zero(0, start_row_index, false, var::column_type::constant); - var one(0, start_row_index + 1, false, var::column_type::constant); - var minus_one(0, start_row_index + 2, false, var::column_type::constant); + generate_copy_constraints(bp, assignment, params, start_row_index); + return result_type(start_row_index); + } - curve_params params_curve(start_row_index); + static result_type generate_assignments(assignment &assignment, + const params_type ¶ms, + const std::size_t start_row_index) { + std::size_t row = start_row_index; - std::array xs = - potential_xs_assignment(assignment, params.t, params_curve, one, zero, row); - row += potential_xs_rows; + var zero(0, start_row_index, false, var::column_type::constant); + var one(0, start_row_index + 1, false, var::column_type::constant); + var minus_one(0, start_row_index + 2, false, var::column_type::constant); - std::array ys; - for (std::size_t i = 0; i < xs.size(); ++i) { - ys[i] = get_y_assignments(assignment, xs[i], params_curve, row); - row += get_y_rows; - } + curve_params params_curve(start_row_index); - std::array nulifiers; - // nulifiers[i] = 1 if ys[i] != -1 AND nulifiers[i - 1] == 0, 0 otherwise - // E1: (ys[i] - (-1)) * (ys[i] - (-1))**(-1) -1 = 0 if ys[i] != -1, -1 otherwise - // E2: E1 + 1 = 1 if ys[i] != -1, 0 otherwise - // E3: nulifiers[i - 1] * nulifiers[i - 1]**(-1) -1 = 0 if nulifiers[i - 1] != 0, -1 otherwise - // E4: E3 * (-1) = 0 if nulifiers[i - 1] != 0, 1 otherwise - // E5: E2 * E4 = 1 if ys[i] != -1 AND nulifiers[i - 1] = 0, 0 otherwise - - for (std::size_t i = 0; i < ys.size(); ++i) { - var y1 = sub_component::generate_assignments(assignment, {ys[i], minus_one}, row).output; - row += sub_component::rows_amount; - var y1_inversed = div_component::generate_assignments(assignment, {one, y1}, row).output; - row += div_component::rows_amount; - - var e1 = mul_component::generate_assignments(assignment, {y1, y1_inversed}, row).output; - row += mul_component::rows_amount; - e1 = sub_component::generate_assignments(assignment, {e1, one}, row).output; - row += sub_component::rows_amount; + std::array xs = potential_xs_assignment(assignment, params.t, params_curve, one, zero, row); + row += potential_xs_rows; - var e2 = add_component::generate_assignments(assignment, {e1, one}, row).output; - row += add_component::rows_amount; - - if (i == 0) { - nulifiers[i] = e2; - continue; - } - - var n_inversed = - div_component::generate_assignments(assignment, {one, nulifiers[i - 1]}, row).output; - row += div_component::rows_amount; + std::array ys; + for (std::size_t i = 0; i < xs.size(); ++i) { + ys[i] = get_y_assignments(assignment, xs[i], params_curve, row); + row += get_y_rows; + } - var e3 = - mul_component::generate_assignments(assignment, {nulifiers[i - 1], n_inversed}, row) - .output; - row += mul_component::rows_amount; + std::array nulifiers; + // nulifiers[i] = 1 if ys[i] != -1 AND nulifiers[i - 1] == 0, 0 otherwise + // E1: (ys[i] - (-1)) * (ys[i] - (-1))**(-1) -1 = 0 if ys[i] != -1, -1 otherwise + // E2: E1 + 1 = 1 if ys[i] != -1, 0 otherwise + // E3: nulifiers[i - 1] * nulifiers[i - 1]**(-1) -1 = 0 if nulifiers[i - 1] != 0, -1 otherwise + // E4: E3 * (-1) = 0 if nulifiers[i - 1] != 0, 1 otherwise + // E5: E2 * E4 = 1 if ys[i] != -1 AND nulifiers[i - 1] = 0, 0 otherwise - e3 = sub_component::generate_assignments(assignment, {e3, one}, row).output; - row += sub_component::rows_amount; + for (std::size_t i = 0; i < ys.size(); ++i) { + var y1 = sub_component::generate_assignments(assignment, {ys[i], minus_one}, row).output; + row += sub_component::rows_amount; + var y1_inversed = div_component::generate_assignments(assignment, {one, y1}, row).output; + row += div_component::rows_amount; - var e4 = mul_component::generate_assignments(assignment, {e3, minus_one}, row).output; - row += mul_component::rows_amount; + var e1 = mul_component::generate_assignments(assignment, {y1, y1_inversed}, row).output; + row += mul_component::rows_amount; + e1 = sub_component::generate_assignments(assignment, {e1, one}, row).output; + row += sub_component::rows_amount; - var e5 = mul_component::generate_assignments(assignment, {e2, e4}, row).output; - row += mul_component::rows_amount; + var e2 = add_component::generate_assignments(assignment, {e1, one}, row).output; + row += add_component::rows_amount; - nulifiers[i] = e5; + if (i == 0) { + nulifiers[i] = e2; + continue; } - var x = zero; - var y = zero; + var n_inversed = + div_component::generate_assignments(assignment, {one, nulifiers[i - 1]}, row).output; + row += div_component::rows_amount; - // res = (xs[0] * nulifiers[0] + xs[1] * nulifiers[1] + xs[2] * nulifiers[2], - // ys[0] * nulifiers[0] + ys[1] * nulifiers[1] + ys[2] * nulifiers[2]) - for (std::size_t i = 0; i < xs.size(); ++i) { - var tmp = - mul_component::generate_assignments(assignment, {xs[i], nulifiers[i]}, row).output; - row += mul_component::rows_amount; - x = add_component::generate_assignments(assignment, {x, tmp}, row).output; - row += add_component::rows_amount; + var e3 = + mul_component::generate_assignments(assignment, {nulifiers[i - 1], n_inversed}, row).output; + row += mul_component::rows_amount; - var tmp_y = - mul_component::generate_assignments(assignment, {ys[i], nulifiers[i]}, row).output; - row += mul_component::rows_amount; - y = add_component::generate_assignments(assignment, {y, tmp_y}, row).output; - row += add_component::rows_amount; - } + e3 = sub_component::generate_assignments(assignment, {e3, one}, row).output; + row += sub_component::rows_amount; - assert(row == start_row_index + rows_amount); + var e4 = mul_component::generate_assignments(assignment, {e3, minus_one}, row).output; + row += mul_component::rows_amount; - return result_type(start_row_index); - } + var e5 = mul_component::generate_assignments(assignment, {e2, e4}, row).output; + row += mul_component::rows_amount; - private: - static void generate_gates(blueprint &bp, - blueprint_public_assignment_table &assignment, - const params_type ¶ms, - const std::size_t first_selector_index) { + nulifiers[i] = e5; } - static void - generate_copy_constraints(blueprint &bp, - blueprint_public_assignment_table &assignment, - const params_type ¶ms, - const std::size_t start_row_index) { + var x = zero; + var y = zero; + + // res = (xs[0] * nulifiers[0] + xs[1] * nulifiers[1] + xs[2] * nulifiers[2], + // ys[0] * nulifiers[0] + ys[1] * nulifiers[1] + ys[2] * nulifiers[2]) + for (std::size_t i = 0; i < xs.size(); ++i) { + var tmp = mul_component::generate_assignments(assignment, {xs[i], nulifiers[i]}, row).output; + row += mul_component::rows_amount; + x = add_component::generate_assignments(assignment, {x, tmp}, row).output; + row += add_component::rows_amount; + + var tmp_y = mul_component::generate_assignments(assignment, {ys[i], nulifiers[i]}, row).output; + row += mul_component::rows_amount; + y = add_component::generate_assignments(assignment, {y, tmp_y}, row).output; + row += add_component::rows_amount; } - static void generate_assignments_constants( - blueprint_public_assignment_table &assignment, - const params_type ¶ms, - const std::size_t start_row_index) { - std::size_t row = start_row_index; - assignment.constant(0)[row] = 0; - row++; - assignment.constant(0)[row] = 1; - row++; - assignment.constant(0)[row] = -1; - row++; - - // curve_params: - typename BlueprintFieldType::value_type u_val; - typename BlueprintFieldType::value_type fu_val; - typename BlueprintFieldType::value_type inv_three_u_squared_val; - typename BlueprintFieldType::value_type sqrt_neg_three_u_squared_val; - typename BlueprintFieldType::value_type sqrt_neg_three_u_squared_minus_u_over_2_val; - typename BlueprintFieldType::value_type b_val; - - if (std::is_same::value) { - u_val = 0x0000000000000000000000000000000000000000000000000000000000000001_cppui255; - fu_val = 0x0000000000000000000000000000000000000000000000000000000000000006_cppui255; - inv_three_u_squared_val = - 0x2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC18465FD5B88A612661E209E00000001_cppui255; - sqrt_neg_three_u_squared_val = - 0x25999506959B74E25955ABB8AF5563603A3F17A46F5A62923B5ABD7BFBFC9573_cppui255; - sqrt_neg_three_u_squared_minus_u_over_2_val = - 0x12CCCA834ACDBA712CAAD5DC57AAB1B01D1F8BD237AD31491DAD5EBDFDFE4AB9_cppui255; - b_val = 0x0000000000000000000000000000000000000000000000000000000000000005_cppui255; - } else { // vesta - u_val = 0x0000000000000000000000000000000000000000000000000000000000000001_cppui255; - fu_val = 0x0000000000000000000000000000000000000000000000000000000000000006_cppui255; - inv_three_u_squared_val = - 0x2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC18465FD5BB87093B2D9F21600000001_cppui255; - sqrt_neg_three_u_squared_val = - 0x0D0334B0507CA51CA23B69B039EE1EB41FDA8CFA8F80675E5553A5C0A1541C9F_cppui255; - sqrt_neg_three_u_squared_minus_u_over_2_val = - 0x06819A58283E528E511DB4D81CF70F5A0FED467D47C033AF2AA9D2E050AA0E4F_cppui255; - b_val = 0x0000000000000000000000000000000000000000000000000000000000000005_cppui255; - } - // var u; - assignment.constant(0)[row] = u_val; - row++; - // var fu; - assignment.constant(0)[row] = fu_val; - row++; - // var inv_three_u_squared; - assignment.constant(0)[row] = inv_three_u_squared_val; - row++; - // var sqrt_neg_three_u_squared; - assignment.constant(0)[row] = sqrt_neg_three_u_squared_val; - row++; - // var sqrt_neg_three_u_squared_minus_u_over_2; - assignment.constant(0)[row] = sqrt_neg_three_u_squared_minus_u_over_2_val; - row++; - // var b; - assignment.constant(0)[row] = b_val; - row++; + assert(row == start_row_index + rows_amount); + + return result_type(start_row_index); + } + + private: + static void generate_gates(blueprint &bp, + assignment &assignment, + const params_type ¶ms, + const std::size_t first_selector_index) { + } + + static void generate_copy_constraints(blueprint &bp, + assignment &assignment, + const params_type ¶ms, + const std::size_t start_row_index) { + } + + static void generate_assignments_constants(assignment &assignment, + const params_type ¶ms, + const std::size_t start_row_index) { + std::size_t row = start_row_index; + assignment.constant(0)[row] = 0; + row++; + assignment.constant(0)[row] = 1; + row++; + assignment.constant(0)[row] = -1; + row++; + + // curve_params: + typename BlueprintFieldType::value_type u_val; + typename BlueprintFieldType::value_type fu_val; + typename BlueprintFieldType::value_type inv_three_u_squared_val; + typename BlueprintFieldType::value_type sqrt_neg_three_u_squared_val; + typename BlueprintFieldType::value_type sqrt_neg_three_u_squared_minus_u_over_2_val; + typename BlueprintFieldType::value_type b_val; + + if (std::is_same::value) { + u_val = 0x0000000000000000000000000000000000000000000000000000000000000001_cppui255; + fu_val = 0x0000000000000000000000000000000000000000000000000000000000000006_cppui255; + inv_three_u_squared_val = + 0x2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC18465FD5B88A612661E209E00000001_cppui255; + sqrt_neg_three_u_squared_val = + 0x25999506959B74E25955ABB8AF5563603A3F17A46F5A62923B5ABD7BFBFC9573_cppui255; + sqrt_neg_three_u_squared_minus_u_over_2_val = + 0x12CCCA834ACDBA712CAAD5DC57AAB1B01D1F8BD237AD31491DAD5EBDFDFE4AB9_cppui255; + b_val = 0x0000000000000000000000000000000000000000000000000000000000000005_cppui255; + } else { // vesta + u_val = 0x0000000000000000000000000000000000000000000000000000000000000001_cppui255; + fu_val = 0x0000000000000000000000000000000000000000000000000000000000000006_cppui255; + inv_three_u_squared_val = + 0x2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC18465FD5BB87093B2D9F21600000001_cppui255; + sqrt_neg_three_u_squared_val = + 0x0D0334B0507CA51CA23B69B039EE1EB41FDA8CFA8F80675E5553A5C0A1541C9F_cppui255; + sqrt_neg_three_u_squared_minus_u_over_2_val = + 0x06819A58283E528E511DB4D81CF70F5A0FED467D47C033AF2AA9D2E050AA0E4F_cppui255; + b_val = 0x0000000000000000000000000000000000000000000000000000000000000005_cppui255; } - }; - } // namespace components - } // namespace blueprint - } // namespace crypto3 + // var u; + assignment.constant(0)[row] = u_val; + row++; + // var fu; + assignment.constant(0)[row] = fu_val; + row++; + // var inv_three_u_squared; + assignment.constant(0)[row] = inv_three_u_squared_val; + row++; + // var sqrt_neg_three_u_squared; + assignment.constant(0)[row] = sqrt_neg_three_u_squared_val; + row++; + // var sqrt_neg_three_u_squared_minus_u_over_2; + assignment.constant(0)[row] = sqrt_neg_three_u_squared_minus_u_over_2_val; + row++; + // var b; + assignment.constant(0)[row] = b_val; + row++; + } + }; + } // namespace components + } // namespace blueprint } // namespace nil #endif // CRYPTO3_BLUEPRINT_COMPONENTS_PLONK_KIMCHI_DETAIL_TO_GROUP_HPP \ No newline at end of file diff --git a/include/nil/blueprint/components/systems/snark/plonk/kimchi/detail/transcript_fq.hpp b/include/nil/blueprint/components/systems/snark/plonk/kimchi/detail/transcript_fq.hpp index 6928adf71..b6a8241e9 100644 --- a/include/nil/blueprint/components/systems/snark/plonk/kimchi/detail/transcript_fq.hpp +++ b/include/nil/blueprint/components/systems/snark/plonk/kimchi/detail/transcript_fq.hpp @@ -43,249 +43,285 @@ #include #include -#include +#include +#include #include -#include +#include namespace nil { - namespace crypto3 { - namespace blueprint { - namespace components { - - // Fiat-Shamir transfotmation (base field part) - // https://github.com/o1-labs/proof-systems/blob/1f8532ec1b8d43748a372632bd854be36b371afe/oracle/src/sponge.rs#L98 - // https://github.com/o1-labs/proof-systems/blob/1f8532ec1b8d43748a372632bd854be36b371afe/oracle/src/sponge.rs#L128 - template - class kimchi_transcript_fq; - - template - class kimchi_transcript_fq, - CurveType, W0, W1, W2, W3, W4, W5, W6, W7, W8, W9, W10, W11, W12, W13, W14> { - - typedef snark::plonk_constraint_system - ArithmetizationType; - - using var = snark::plonk_variable; - - using group_value = typename zk::components::var_ec_point; - - constexpr static bool scalar_larger() { - using ScalarField = typename CurveType::scalar_field_type; - using BaseField = typename CurveType::base_field_type; - - auto n1 = ScalarField::modulus; - auto n2 = BaseField::modulus; - return (n1 > n2); - } - - static const std::size_t fr_value_size = scalar_larger() ? 2 : 1; - - struct fr_value { - std::array value; - }; - - static const std::size_t CHALLENGE_LENGTH_IN_LIMBS = 2; - static const std::size_t HIGH_ENTROPY_LIMBS = 2; - - using sponge_component = kimchi_sponge; - sponge_component sponge; - - using sub_component = zk::components::subtraction; - using mul_component = zk::components::multiplication; - - using pack = from_limbs; - using unpack = - to_limbs; - using compare = compare_with_const; - - std::vector last_squeezed; - - std::array - squeeze_limbs_assignment(blueprint_assignment_table &assignment, - std::size_t component_start_row) { - std::size_t row = component_start_row; - if (last_squeezed.size() >= CHALLENGE_LENGTH_IN_LIMBS) { - std::array limbs = {last_squeezed[0], last_squeezed[1]}; - std::vector remaining = {last_squeezed.begin() + CHALLENGE_LENGTH_IN_LIMBS, - last_squeezed.end()}; - last_squeezed = remaining; - return limbs; - } - var sq = sponge.squeeze_assignment(assignment, row); - row += sponge_component::squeeze_rows; - auto x = unpack::generate_assignments(assignment, {sq}, row).result; - row += unpack::rows_amount; - for (int i = 0; i < HIGH_ENTROPY_LIMBS; ++i) { - last_squeezed.push_back(x[i]); - } - return squeeze_limbs_assignment(assignment, row); - } + namespace blueprint { + namespace components { + + // Fiat-Shamir transfotmation (base field part) + // https://github.com/o1-labs/proof-systems/blob/1f8532ec1b8d43748a372632bd854be36b371afe/oracle/src/sponge.rs#L98 + // https://github.com/o1-labs/proof-systems/blob/1f8532ec1b8d43748a372632bd854be36b371afe/oracle/src/sponge.rs#L128 + template + class kimchi_transcript_fq; + + template + class kimchi_transcript_fq, + CurveType, + W0, + W1, + W2, + W3, + W4, + W5, + W6, + W7, + W8, + W9, + W10, + W11, + W12, + W13, + W14> { + + typedef crypto3::zk::snark::plonk_constraint_system ArithmetizationType; + + using var = crypto3::zk::snark::plonk_variable; + + using group_value = var_ec_point; + + constexpr static bool scalar_larger() { + using ScalarField = typename CurveType::scalar_field_type; + using BaseField = typename CurveType::base_field_type; + + auto n1 = ScalarField::modulus; + auto n2 = BaseField::modulus; + return (n1 > n2); + } + + static const std::size_t fr_value_size = scalar_larger() ? 2 : 1; + + struct fr_value { + std::array value; + }; - std::array - squeeze_limbs_circuit(blueprint &bp, - blueprint_public_assignment_table &assignment, - std::size_t component_start_row) { - std::size_t row = component_start_row; - if (last_squeezed.size() >= CHALLENGE_LENGTH_IN_LIMBS) { - std::array limbs = {last_squeezed[0], last_squeezed[1]}; - std::vector remaining = {last_squeezed.begin() + CHALLENGE_LENGTH_IN_LIMBS, - last_squeezed.end()}; - last_squeezed = remaining; - return limbs; - } - var sq = sponge.squeeze_circuit(bp, assignment, row); - row += sponge_component::squeeze_rows; - auto x = unpack::generate_circuit(bp, assignment, {sq}, row).result; - row += unpack::rows_amount; - for (int i = 0; i < HIGH_ENTROPY_LIMBS; ++i) { - last_squeezed.push_back(x[i]); - } - return squeeze_limbs_circuit(bp, assignment, row); + static const std::size_t CHALLENGE_LENGTH_IN_LIMBS = 2; + static const std::size_t HIGH_ENTROPY_LIMBS = 2; + + using sponge_component = kimchi_sponge; + sponge_component sponge; + + using sub_component = + subtraction>; + using mul_component = multiplication>; + + using pack = from_limbs; + using unpack = to_limbs; + using compare = compare_with_const; + + std::vector last_squeezed; + + std::array squeeze_limbs_assignment(assignment &assignment, + std::size_t component_start_row) { + std::size_t row = component_start_row; + if (last_squeezed.size() >= CHALLENGE_LENGTH_IN_LIMBS) { + std::array limbs = {last_squeezed[0], last_squeezed[1]}; + std::vector remaining = {last_squeezed.begin() + CHALLENGE_LENGTH_IN_LIMBS, + last_squeezed.end()}; + last_squeezed = remaining; + return limbs; } - - public: - constexpr static const std::size_t rows_amount = 0; - constexpr static const std::size_t init_rows = sponge_component::init_rows; - constexpr static const std::size_t absorb_group_rows = 2 * sponge_component::absorb_rows; - constexpr static const std::size_t absorb_fr_rows = fr_value_size * sponge_component::absorb_rows; - constexpr static const std::size_t challenge_rows = - sponge_component::squeeze_rows + unpack::rows_amount + pack::rows_amount; - constexpr static const std::size_t challenge_fq_rows = sponge_component::squeeze_rows; - constexpr static const std::size_t digest_rows = - sponge_component::squeeze_rows + compare::rows_amount + mul_component::rows_amount; - - void init_assignment(blueprint_assignment_table &assignment, - var zero, - const std::size_t component_start_row) { - sponge.init_assignment(assignment, zero, component_start_row); - last_squeezed = {}; + var sq = sponge.squeeze_assignment(assignment, row); + row += sponge_component::squeeze_rows; + auto x = unpack::generate_assignments(assignment, {sq}, row).result; + row += unpack::rows_amount; + for (int i = 0; i < HIGH_ENTROPY_LIMBS; ++i) { + last_squeezed.push_back(x[i]); } - - void init_circuit(blueprint &bp, - blueprint_public_assignment_table &assignment, - const var &zero, - const std::size_t component_start_row) { - sponge.init_circuit(bp, assignment, zero, component_start_row); - last_squeezed = {}; + return squeeze_limbs_assignment(assignment, row); + } + + std::array squeeze_limbs_circuit(blueprint &bp, + assignment &assignment, + std::size_t component_start_row) { + std::size_t row = component_start_row; + if (last_squeezed.size() >= CHALLENGE_LENGTH_IN_LIMBS) { + std::array limbs = {last_squeezed[0], last_squeezed[1]}; + std::vector remaining = {last_squeezed.begin() + CHALLENGE_LENGTH_IN_LIMBS, + last_squeezed.end()}; + last_squeezed = remaining; + return limbs; } - - void absorb_g_assignment(blueprint_assignment_table &assignment, - group_value g, - std::size_t component_start_row) { - // accepts {g.X, g.Y} - std::size_t row = component_start_row; - last_squeezed = {}; - sponge.absorb_assignment(assignment, g.X, row); - row += sponge_component::absorb_rows; - sponge.absorb_assignment(assignment, g.Y, row); + var sq = sponge.squeeze_circuit(bp, assignment, row); + row += sponge_component::squeeze_rows; + auto x = unpack::generate_circuit(bp, assignment, {sq}, row).result; + row += unpack::rows_amount; + for (int i = 0; i < HIGH_ENTROPY_LIMBS; ++i) { + last_squeezed.push_back(x[i]); } - - void absorb_g_circuit(blueprint &bp, - blueprint_public_assignment_table &assignment, - group_value g, + return squeeze_limbs_circuit(bp, assignment, row); + } + + public: + constexpr static const std::size_t rows_amount = 0; + constexpr static const std::size_t init_rows = sponge_component::init_rows; + constexpr static const std::size_t absorb_group_rows = 2 * sponge_component::absorb_rows; + constexpr static const std::size_t absorb_fr_rows = fr_value_size * sponge_component::absorb_rows; + constexpr static const std::size_t challenge_rows = + sponge_component::squeeze_rows + unpack::rows_amount + pack::rows_amount; + constexpr static const std::size_t challenge_fq_rows = sponge_component::squeeze_rows; + constexpr static const std::size_t digest_rows = + sponge_component::squeeze_rows + compare::rows_amount + mul_component::rows_amount; + + void init_assignment(assignment &assignment, + var zero, + const std::size_t component_start_row) { + sponge.init_assignment(assignment, zero, component_start_row); + last_squeezed = {}; + } + + void init_circuit(blueprint &bp, + assignment &assignment, + const var &zero, + const std::size_t component_start_row) { + sponge.init_circuit(bp, assignment, zero, component_start_row); + last_squeezed = {}; + } + + void absorb_g_assignment(assignment &assignment, + group_value g, + std::size_t component_start_row) { + // accepts {g.X, g.Y} + std::size_t row = component_start_row; + last_squeezed = {}; + sponge.absorb_assignment(assignment, g.X, row); + row += sponge_component::absorb_rows; + sponge.absorb_assignment(assignment, g.Y, row); + } + + void absorb_g_circuit(blueprint &bp, + assignment &assignment, + group_value g, + std::size_t component_start_row) { + // accepts {g.X, g.Y} + std::size_t row = component_start_row; + last_squeezed = {}; + sponge.absorb_circuit(bp, assignment, g.X, row); + row += sponge_component::absorb_rows; + sponge.absorb_circuit(bp, assignment, g.Y, row); + } + + void absorb_fr_assignment(assignment &assignment, + fr_value absorbing_value, std::size_t component_start_row) { - // accepts {g.X, g.Y} - std::size_t row = component_start_row; - last_squeezed = {}; - sponge.absorb_circuit(bp, assignment, g.X, row); + std::size_t row = component_start_row; + last_squeezed = {}; + for (std::size_t i = 0; i < fr_value_size; i++) { + sponge.absorb_assignment(assignment, absorbing_value.value[i], row); row += sponge_component::absorb_rows; - sponge.absorb_circuit(bp, assignment, g.Y, row); } - - void absorb_fr_assignment(blueprint_assignment_table &assignment, - fr_value absorbing_value, - std::size_t component_start_row) { - std::size_t row = component_start_row; - last_squeezed = {}; - for (std::size_t i = 0; i < fr_value_size; i++) { - sponge.absorb_assignment(assignment, absorbing_value.value[i], row); - row += sponge_component::absorb_rows; - } - } - - void absorb_fr_circuit(blueprint &bp, - blueprint_public_assignment_table &assignment, - fr_value absorbing_value, - std::size_t &component_start_row) { - std::size_t row = component_start_row; - last_squeezed = {}; - for (std::size_t i = 0; i < fr_value_size; i++) { - sponge.absorb_circuit(bp, assignment, absorbing_value.value[i], row); - row += sponge_component::absorb_rows; - } - } - - var challenge_assignment(blueprint_assignment_table &assignment, - std::size_t component_start_row) { - std::size_t row = component_start_row; - auto limbs = squeeze_limbs_assignment(assignment, row); - row += sponge_component::squeeze_rows; - row += unpack::rows_amount; - return pack::generate_assignments(assignment, limbs, row).result; - } - - var challenge_circuit(blueprint &bp, - blueprint_public_assignment_table &assignment, - std::size_t component_start_row) { - std::size_t row = component_start_row; - auto limbs = squeeze_limbs_circuit(bp, assignment, row); - row += sponge_component::squeeze_rows; - row += unpack::rows_amount; - return pack::generate_circuit(bp, assignment, limbs, row).result; - } - - var challenge_fq_assignment(blueprint_assignment_table &assignment, - std::size_t component_start_row) { - last_squeezed = {}; - return sponge.squeeze_assignment(assignment, component_start_row); - } - - var challenge_fq_circuit(blueprint &bp, - blueprint_public_assignment_table &assignment, - std::size_t component_start_row) { - last_squeezed = {}; - return sponge.squeeze_circuit(bp, assignment, component_start_row); + } + + void absorb_fr_circuit(blueprint &bp, + assignment &assignment, + fr_value absorbing_value, + std::size_t &component_start_row) { + std::size_t row = component_start_row; + last_squeezed = {}; + for (std::size_t i = 0; i < fr_value_size; i++) { + sponge.absorb_circuit(bp, assignment, absorbing_value.value[i], row); + row += sponge_component::absorb_rows; } - - var digest_assignment(blueprint_assignment_table &assignment, - std::size_t component_start_row) { - std::size_t row = component_start_row; - last_squeezed = {}; - var sq = sponge.squeeze_assignment(assignment, row); - row += sponge_component::squeeze_rows; - if (scalar_larger()) { - return sq; - } - var compare_result = compare::generate_assignments(assignment, sq, row).output; - row += compare::rows_amount; - return mul_component::generate_assignments(assignment, {compare_result, sq}, row).output; + } + + var challenge_assignment(assignment &assignment, std::size_t component_start_row) { + std::size_t row = component_start_row; + auto limbs = squeeze_limbs_assignment(assignment, row); + row += sponge_component::squeeze_rows; + row += unpack::rows_amount; + return pack::generate_assignments(assignment, limbs, row).result; + } + + var challenge_circuit(blueprint &bp, + assignment &assignment, + std::size_t component_start_row) { + std::size_t row = component_start_row; + auto limbs = squeeze_limbs_circuit(bp, assignment, row); + row += sponge_component::squeeze_rows; + row += unpack::rows_amount; + return pack::generate_circuit(bp, assignment, limbs, row).result; + } + + var challenge_fq_assignment(assignment &assignment, + std::size_t component_start_row) { + last_squeezed = {}; + return sponge.squeeze_assignment(assignment, component_start_row); + } + + var challenge_fq_circuit(blueprint &bp, + assignment &assignment, + std::size_t component_start_row) { + last_squeezed = {}; + return sponge.squeeze_circuit(bp, assignment, component_start_row); + } + + var digest_assignment(assignment &assignment, std::size_t component_start_row) { + std::size_t row = component_start_row; + last_squeezed = {}; + var sq = sponge.squeeze_assignment(assignment, row); + row += sponge_component::squeeze_rows; + if (scalar_larger()) { + return sq; } - - var digest_circuit(blueprint &bp, - blueprint_public_assignment_table &assignment, - std::size_t component_start_row) { - std::size_t row = component_start_row; - last_squeezed = {}; - var sq = sponge.squeeze_circuit(bp, assignment, row); - row += sponge_component::squeeze_rows; - if (scalar_larger()) { - return sq; - } - var compare_result = compare::generate_circuit(bp, assignment, sq, row).output; - row += compare::rows_amount; - return zk::components::generate_circuit( - bp, assignment, {compare_result, sq}, row) - .output; + var compare_result = compare::generate_assignments(assignment, sq, row).output; + row += compare::rows_amount; + return mul_component::generate_assignments(assignment, {compare_result, sq}, row).output; + } + + var digest_circuit(blueprint &bp, + assignment &assignment, + std::size_t component_start_row) { + std::size_t row = component_start_row; + last_squeezed = {}; + var sq = sponge.squeeze_circuit(bp, assignment, row); + row += sponge_component::squeeze_rows; + if (scalar_larger()) { + return sq; } - }; - } // namespace components - } // namespace blueprint - } // namespace crypto3 + var compare_result = compare::generate_circuit(bp, assignment, sq, row).output; + row += compare::rows_amount; + return generate_circuit(bp, assignment, {compare_result, sq}, row).output; + } + }; + } // namespace components + } // namespace blueprint } // namespace nil #endif // CRYPTO3_BLUEPRINT_COMPONENTS_PLONK_KIMCHI_TRANSCRIPT_FQ_HPP diff --git a/include/nil/blueprint/components/systems/snark/plonk/kimchi/detail/transcript_fr.hpp b/include/nil/blueprint/components/systems/snark/plonk/kimchi/detail/transcript_fr.hpp index 4f3361d8e..1da32ac70 100644 --- a/include/nil/blueprint/components/systems/snark/plonk/kimchi/detail/transcript_fr.hpp +++ b/include/nil/blueprint/components/systems/snark/plonk/kimchi/detail/transcript_fr.hpp @@ -44,243 +44,281 @@ #include namespace nil { - namespace crypto3 { - namespace blueprint { - namespace components { + namespace blueprint { + namespace components { - // Fiat-Shamir transfotmation (scalar field part) - // https://github.com/o1-labs/proof-systems/blob/1f8532ec1b8d43748a372632bd854be36b371afe/oracle/src/sponge.rs#L81 - template - class kimchi_transcript_fr; + // Fiat-Shamir transfotmation (scalar field part) + // https://github.com/o1-labs/proof-systems/blob/1f8532ec1b8d43748a372632bd854be36b371afe/oracle/src/sponge.rs#L81 + template + class kimchi_transcript_fr; - template - class kimchi_transcript_fr, - CurveType, - KimchiParamsType, - W0, W1, W2, W3, W4, W5, W6, W7, W8, W9, W10, W11, W12, W13, W14> { + template + class kimchi_transcript_fr, + CurveType, + KimchiParamsType, + W0, + W1, + W2, + W3, + W4, + W5, + W6, + W7, + W8, + W9, + W10, + W11, + W12, + W13, + W14> { - typedef snark::plonk_constraint_system - ArithmetizationType; + typedef crypto3::zk::snark::plonk_constraint_system ArithmetizationType; - using var = snark::plonk_variable; + using var = crypto3::zk::snark::plonk_variable; - static const std::size_t CHALLENGE_LENGTH_IN_LIMBS = 2; - static const std::size_t HIGH_ENTROPY_LIMBS = 2; + static const std::size_t CHALLENGE_LENGTH_IN_LIMBS = 2; + static const std::size_t HIGH_ENTROPY_LIMBS = 2; - using sponge_component = kimchi_sponge; + using sponge_component = kimchi_sponge; - sponge_component sponge; - using pack = from_limbs; - using unpack = - to_limbs; + sponge_component sponge; + using pack = from_limbs; + using unpack = to_limbs; - std::vector last_squeezed; + std::vector last_squeezed; - var pack_assignment(blueprint_assignment_table &assignment, - const std::size_t component_start_row, - std::array - limbs) { - auto pack_res = pack::generate_assignments(assignment, limbs, component_start_row); - return pack_res.result; - } + var pack_assignment(assignment &assignment, + const std::size_t component_start_row, + std::array + limbs) { + auto pack_res = pack::generate_assignments(assignment, limbs, component_start_row); + return pack_res.result; + } - var pack_circuit(blueprint &bp, - blueprint_public_assignment_table &assignment, - const std::size_t component_start_row, - std::array - limbs) { - auto pack_res = pack::generate_circuit(bp, assignment, limbs, component_start_row); - return pack_res.result; - } + var pack_circuit(blueprint &bp, + assignment &assignment, + const std::size_t component_start_row, + std::array + limbs) { + auto pack_res = pack::generate_circuit(bp, assignment, limbs, component_start_row); + return pack_res.result; + } - std::array unpack_assignment(blueprint_assignment_table &assignment, - const std::size_t component_start_row, - var elem) { - auto unpack_res = unpack::generate_assignments(assignment, {elem}, component_start_row); - return unpack_res.result; - } + std::array unpack_assignment(assignment &assignment, + const std::size_t component_start_row, + var elem) { + auto unpack_res = unpack::generate_assignments(assignment, {elem}, component_start_row); + return unpack_res.result; + } - std::array - unpack_circuit(blueprint &bp, - blueprint_public_assignment_table &assignment, - const std::size_t component_start_row, - var elem) { - auto unpack_res = unpack::generate_circuit(bp, assignment, {elem}, component_start_row); - return unpack_res.result; - } + std::array unpack_circuit(blueprint &bp, + assignment &assignment, + const std::size_t component_start_row, + var elem) { + auto unpack_res = unpack::generate_circuit(bp, assignment, {elem}, component_start_row); + return unpack_res.result; + } - public: - constexpr static const std::size_t rows_amount = 0; - constexpr static const std::size_t init_rows = sponge_component::init_rows; - constexpr static const std::size_t absorb_rows = sponge_component::absorb_rows; - constexpr static const std::size_t challenge_rows = - sponge_component::squeeze_rows + unpack::rows_amount + pack::rows_amount; - constexpr static const std::size_t absorb_evaluations_rows = 25 * absorb_rows; + public: + constexpr static const std::size_t rows_amount = 0; + constexpr static const std::size_t init_rows = sponge_component::init_rows; + constexpr static const std::size_t absorb_rows = sponge_component::absorb_rows; + constexpr static const std::size_t challenge_rows = + sponge_component::squeeze_rows + unpack::rows_amount + pack::rows_amount; + constexpr static const std::size_t absorb_evaluations_rows = 25 * absorb_rows; - constexpr static const std::size_t state_size = sponge_component::state_size; + constexpr static const std::size_t state_size = sponge_component::state_size; - std::array state() { - return sponge._inner_state(); - } + std::array state() { + return sponge._inner_state(); + } - void init_assignment(blueprint_assignment_table &assignment, - var zero, - const std::size_t component_start_row) { - sponge.init_assignment(assignment, zero, component_start_row); - last_squeezed = {}; - } + void init_assignment(assignment &assignment, + var zero, + const std::size_t component_start_row) { + sponge.init_assignment(assignment, zero, component_start_row); + last_squeezed = {}; + } - void init_circuit(blueprint &bp, - blueprint_public_assignment_table &assignment, - const var &zero, - const std::size_t component_start_row) { - sponge.init_circuit(bp, assignment, zero, component_start_row); - last_squeezed = {}; - } + void init_circuit(blueprint &bp, + assignment &assignment, + const var &zero, + const std::size_t component_start_row) { + sponge.init_circuit(bp, assignment, zero, component_start_row); + last_squeezed = {}; + } - void absorb_assignment(blueprint_assignment_table &assignment, - var absorbing_value, - const std::size_t component_start_row) { - last_squeezed = {}; - sponge.absorb_assignment(assignment, absorbing_value, component_start_row); - } + void absorb_assignment(assignment &assignment, + var absorbing_value, + const std::size_t component_start_row) { + last_squeezed = {}; + sponge.absorb_assignment(assignment, absorbing_value, component_start_row); + } - void absorb_circuit(blueprint &bp, - blueprint_public_assignment_table &assignment, - const var &input, - const std::size_t component_start_row) { - last_squeezed = {}; - sponge.absorb_circuit(bp, assignment, input, component_start_row); - } + void absorb_circuit(blueprint &bp, + assignment &assignment, + const var &input, + const std::size_t component_start_row) { + last_squeezed = {}; + sponge.absorb_circuit(bp, assignment, input, component_start_row); + } - void absorb_evaluations_assignment(blueprint_assignment_table &assignment, - var public_eval, - kimchi_proof_evaluations - private_eval, - const std::size_t component_start_row) { - last_squeezed = {}; - std::size_t row = component_start_row; - std::vector points = {public_eval, private_eval.z, private_eval.generic_selector, - private_eval.poseidon_selector, - private_eval.w[0], - private_eval.w[1], - private_eval.w[2], - private_eval.w[3], - private_eval.w[4], - private_eval.w[5], - private_eval.w[6], - private_eval.w[7], - private_eval.w[8], - private_eval.w[9], - private_eval.w[10], - private_eval.w[11], - private_eval.w[12], - private_eval.w[13], - private_eval.w[14], - private_eval.s[0], - private_eval.s[1], - private_eval.s[2], - private_eval.s[3], - private_eval.s[4], - private_eval.s[5]}; - for (auto p : points) { - sponge.absorb_assignment(assignment, p, row); - row += sponge_component::absorb_rows; - } + void absorb_evaluations_assignment(assignment &assignment, + var public_eval, + kimchi_proof_evaluations + private_eval, + const std::size_t component_start_row) { + last_squeezed = {}; + std::size_t row = component_start_row; + std::vector points = {public_eval, + private_eval.z, + private_eval.generic_selector, + private_eval.poseidon_selector, + private_eval.w[0], + private_eval.w[1], + private_eval.w[2], + private_eval.w[3], + private_eval.w[4], + private_eval.w[5], + private_eval.w[6], + private_eval.w[7], + private_eval.w[8], + private_eval.w[9], + private_eval.w[10], + private_eval.w[11], + private_eval.w[12], + private_eval.w[13], + private_eval.w[14], + private_eval.s[0], + private_eval.s[1], + private_eval.s[2], + private_eval.s[3], + private_eval.s[4], + private_eval.s[5]}; + for (auto p : points) { + sponge.absorb_assignment(assignment, p, row); + row += sponge_component::absorb_rows; } + } - void absorb_evaluations_circuit(blueprint &bp, - blueprint_public_assignment_table &assignment, - var public_eval, - kimchi_proof_evaluations - private_eval, - const std::size_t component_start_row) { - last_squeezed = {}; - std::size_t row = component_start_row; - std::vector points = {public_eval, - private_eval.z, - private_eval.generic_selector, - private_eval.poseidon_selector, - private_eval.w[0], - private_eval.w[1], - private_eval.w[2], - private_eval.w[3], - private_eval.w[4], - private_eval.w[5], - private_eval.w[6], - private_eval.w[7], - private_eval.w[8], - private_eval.w[9], - private_eval.w[10], - private_eval.w[11], - private_eval.w[12], - private_eval.w[13], - private_eval.w[14], - private_eval.s[0], - private_eval.s[1], - private_eval.s[2], - private_eval.s[3], - private_eval.s[4], - private_eval.s[5]}; - for (auto p : points) { - sponge.absorb_circuit(bp, assignment, p, row); - row += sponge_component::absorb_rows; - } + void absorb_evaluations_circuit(blueprint &bp, + assignment &assignment, + var public_eval, + kimchi_proof_evaluations + private_eval, + const std::size_t component_start_row) { + last_squeezed = {}; + std::size_t row = component_start_row; + std::vector points = {public_eval, + private_eval.z, + private_eval.generic_selector, + private_eval.poseidon_selector, + private_eval.w[0], + private_eval.w[1], + private_eval.w[2], + private_eval.w[3], + private_eval.w[4], + private_eval.w[5], + private_eval.w[6], + private_eval.w[7], + private_eval.w[8], + private_eval.w[9], + private_eval.w[10], + private_eval.w[11], + private_eval.w[12], + private_eval.w[13], + private_eval.w[14], + private_eval.s[0], + private_eval.s[1], + private_eval.s[2], + private_eval.s[3], + private_eval.s[4], + private_eval.s[5]}; + for (auto p : points) { + sponge.absorb_circuit(bp, assignment, p, row); + row += sponge_component::absorb_rows; } + } - var challenge_assignment(blueprint_assignment_table &assignment, - const std::size_t component_start_row) { - std::size_t row = component_start_row; - if (last_squeezed.size() >= CHALLENGE_LENGTH_IN_LIMBS) { - std::array limbs = {last_squeezed[0], last_squeezed[1]}; - std::vector remaining = {last_squeezed.begin() + CHALLENGE_LENGTH_IN_LIMBS, - last_squeezed.end()}; - last_squeezed = remaining; - return pack_assignment(assignment, row, limbs); - } - var sq = sponge.squeeze_assignment(assignment, row); - row += sponge_component::squeeze_rows; - auto x = unpack_assignment(assignment, row, sq); - row += unpack::rows_amount; - for (int i = 0; i < HIGH_ENTROPY_LIMBS; ++i) { - last_squeezed.push_back(x[i]); - } - return challenge_assignment(assignment, row); + var challenge_assignment(assignment &assignment, + const std::size_t component_start_row) { + std::size_t row = component_start_row; + if (last_squeezed.size() >= CHALLENGE_LENGTH_IN_LIMBS) { + std::array limbs = {last_squeezed[0], last_squeezed[1]}; + std::vector remaining = {last_squeezed.begin() + CHALLENGE_LENGTH_IN_LIMBS, + last_squeezed.end()}; + last_squeezed = remaining; + return pack_assignment(assignment, row, limbs); } + var sq = sponge.squeeze_assignment(assignment, row); + row += sponge_component::squeeze_rows; + auto x = unpack_assignment(assignment, row, sq); + row += unpack::rows_amount; + for (int i = 0; i < HIGH_ENTROPY_LIMBS; ++i) { + last_squeezed.push_back(x[i]); + } + return challenge_assignment(assignment, row); + } - var challenge_circuit(blueprint &bp, - blueprint_public_assignment_table &assignment, - const std::size_t component_start_row) { - std::size_t row = component_start_row; - if (last_squeezed.size() >= CHALLENGE_LENGTH_IN_LIMBS) { - std::array limbs = {last_squeezed[0], last_squeezed[1]}; - std::vector remaining = {last_squeezed.begin() + CHALLENGE_LENGTH_IN_LIMBS, - last_squeezed.end()}; - last_squeezed = remaining; - return pack_circuit(bp, assignment, row, limbs); - } - var sq = sponge.squeeze_circuit(bp, assignment, row); - row += sponge_component::squeeze_rows; - auto x = unpack_circuit(bp, assignment, row, sq); - row += unpack::rows_amount; - for (int i = 0; i < HIGH_ENTROPY_LIMBS; ++i) { - last_squeezed.push_back(x[i]); - } - return challenge_circuit(bp, assignment, row); + var challenge_circuit(blueprint &bp, + assignment &assignment, + const std::size_t component_start_row) { + std::size_t row = component_start_row; + if (last_squeezed.size() >= CHALLENGE_LENGTH_IN_LIMBS) { + std::array limbs = {last_squeezed[0], last_squeezed[1]}; + std::vector remaining = {last_squeezed.begin() + CHALLENGE_LENGTH_IN_LIMBS, + last_squeezed.end()}; + last_squeezed = remaining; + return pack_circuit(bp, assignment, row, limbs); + } + var sq = sponge.squeeze_circuit(bp, assignment, row); + row += sponge_component::squeeze_rows; + auto x = unpack_circuit(bp, assignment, row, sq); + row += unpack::rows_amount; + for (int i = 0; i < HIGH_ENTROPY_LIMBS; ++i) { + last_squeezed.push_back(x[i]); } - }; - } // namespace components - } // namespace blueprint - } // namespace crypto3 + return challenge_circuit(bp, assignment, row); + } + }; + } // namespace components + } // namespace blueprint } // namespace nil #endif // CRYPTO3_BLUEPRINT_COMPONENTS_PLONK_KIMCHI_TRANSCRIPT_HPP diff --git a/include/nil/blueprint/components/systems/snark/plonk/kimchi/detail/zk_w3.hpp b/include/nil/blueprint/components/systems/snark/plonk/kimchi/detail/zk_w3.hpp index 4acf58387..d04e44536 100644 --- a/include/nil/blueprint/components/systems/snark/plonk/kimchi/detail/zk_w3.hpp +++ b/include/nil/blueprint/components/systems/snark/plonk/kimchi/detail/zk_w3.hpp @@ -35,115 +35,134 @@ #include #include -#include +#include namespace nil { - namespace crypto3 { - namespace blueprint { - namespace components { - - // Returns the end of the circuit, which is used for introducing zero-knowledge in the permutation - // polynomial - // https://github.com/o1-labs/proof-systems/blob/1f8532ec1b8d43748a372632bd854be36b371afe/kimchi/src/circuits/polynomials/permutation.rs#L85 - // Input: verifier_index - // Output: g**(domain_size - zk_rows) - template - class zk_w3; - - template - class zk_w3, W0, W1, W2, W3, - W4, W5, W6, W7, W8, W9, W10, W11, W12, W13, W14> { - - typedef snark::plonk_constraint_system - ArithmetizationType; - - using var = snark::plonk_variable; - - constexpr static std::size_t exp_size = 64; - using exp_component = - zk::components::exponentiation; - - using verifier_index_type = kimchi_verifier_index_scalar; - - constexpr static const std::size_t zk_rows = 3; - - constexpr static const std::size_t selector_seed = 0xf21; - - public: - constexpr static const std::size_t rows_amount = exp_component::rows_amount + 1; - constexpr static const std::size_t gates_amount = 0; - - struct params_type { - verifier_index_type verifier_index; - }; - - struct result_type { - var output; - - result_type(std::size_t start_row_index) { - std::size_t row = start_row_index; - output = typename exp_component::result_type(start_row_index + 1).output; - } - }; - - static result_type - generate_circuit(blueprint &bp, - blueprint_public_assignment_table &assignment, - const params_type ¶ms, - const std::size_t start_row_index) { - - std::size_t row = start_row_index; - - // domain.group_gen.pow(&[domain.size - (ZK_ROWS)]) - var exponent(0, start_row_index, false, var::column_type::constant); - row++; // exponent component also uses constant column - var res = exp_component::generate_circuit(bp, assignment, - {params.verifier_index.omega, exponent}, row) - .output; - row += exp_component::rows_amount; - - assert(row == start_row_index + rows_amount); - - generate_assignments_constants(assignment, params, start_row_index); - return result_type(start_row_index); - } - - static result_type generate_assignments(blueprint_assignment_table &assignment, - const params_type ¶ms, - const std::size_t start_row_index) { - - std::size_t row = start_row_index; - - // domain.group_gen.pow(&[domain.size - (ZK_ROWS)]) - var exponent(0, start_row_index, false, var::column_type::constant); - row++; // exponent component also uses constant column - var res = exp_component::generate_assignments(assignment, - {params.verifier_index.omega, exponent}, row) - .output; - row += exp_component::rows_amount; - - assert(row == start_row_index + rows_amount); + namespace blueprint { + namespace components { + + // Returns the end of the circuit, which is used for introducing zero-knowledge in the permutation + // polynomial + // https://github.com/o1-labs/proof-systems/blob/1f8532ec1b8d43748a372632bd854be36b371afe/kimchi/src/circuits/polynomials/permutation.rs#L85 + // Input: verifier_index + // Output: g**(domain_size - zk_rows) + template + class zk_w3; + + template + class zk_w3, + W0, + W1, + W2, + W3, + W4, + W5, + W6, + W7, + W8, + W9, + W10, + W11, + W12, + W13, + W14> { + + typedef crypto3::zk::snark::plonk_constraint_system ArithmetizationType; + + using var = crypto3::zk::snark::plonk_variable; + + constexpr static std::size_t exp_size = 64; + using exp_component = exponentiation; + + using verifier_index_type = kimchi_verifier_index_scalar; + + constexpr static const std::size_t zk_rows = 3; + + constexpr static const std::size_t selector_seed = 0xf21; + + public: + constexpr static const std::size_t rows_amount = exp_component::rows_amount + 1; + constexpr static const std::size_t gates_amount = 0; + + struct params_type { + verifier_index_type verifier_index; + }; - return result_type(start_row_index); - } + struct result_type { + var output; - private: - static void generate_assignments_constants( - blueprint_public_assignment_table &assignment, - const params_type ¶ms, - const std::size_t start_row_index) { + result_type(std::size_t start_row_index) { std::size_t row = start_row_index; - assignment.constant(0)[row] = params.verifier_index.domain_size - zk_rows; - row++; + output = typename exp_component::result_type(start_row_index + 1).output; } }; - } // namespace components - } // namespace blueprint - } // namespace crypto3 + + static result_type generate_circuit(blueprint &bp, + assignment &assignment, + const params_type ¶ms, + const std::size_t start_row_index) { + + std::size_t row = start_row_index; + + // domain.group_gen.pow(&[domain.size - (ZK_ROWS)]) + var exponent(0, start_row_index, false, var::column_type::constant); + row++; // exponent component also uses constant column + var res = + exp_component::generate_circuit(bp, assignment, {params.verifier_index.omega, exponent}, row) + .output; + row += exp_component::rows_amount; + + assert(row == start_row_index + rows_amount); + + generate_assignments_constants(assignment, params, start_row_index); + return result_type(start_row_index); + } + + static result_type generate_assignments(assignment &assignment, + const params_type ¶ms, + const std::size_t start_row_index) { + + std::size_t row = start_row_index; + + // domain.group_gen.pow(&[domain.size - (ZK_ROWS)]) + var exponent(0, start_row_index, false, var::column_type::constant); + row++; // exponent component also uses constant column + var res = + exp_component::generate_assignments(assignment, {params.verifier_index.omega, exponent}, row) + .output; + row += exp_component::rows_amount; + + assert(row == start_row_index + rows_amount); + + return result_type(start_row_index); + } + + private: + static void generate_assignments_constants(assignment &assignment, + const params_type ¶ms, + const std::size_t start_row_index) { + std::size_t row = start_row_index; + assignment.constant(0)[row] = params.verifier_index.domain_size - zk_rows; + row++; + } + }; + } // namespace components + } // namespace blueprint } // namespace nil #endif // CRYPTO3_BLUEPRINT_COMPONENTS_PLONK_KIMCHI_DETAIL_ZK_W3_HPP \ No newline at end of file diff --git a/include/nil/blueprint/components/systems/snark/plonk/kimchi/detail/zkpm_evaluate.hpp b/include/nil/blueprint/components/systems/snark/plonk/kimchi/detail/zkpm_evaluate.hpp index 21f774084..9cb78473c 100644 --- a/include/nil/blueprint/components/systems/snark/plonk/kimchi/detail/zkpm_evaluate.hpp +++ b/include/nil/blueprint/components/systems/snark/plonk/kimchi/detail/zkpm_evaluate.hpp @@ -33,176 +33,201 @@ #include #include -#include +#include #include -#include +#include +#include namespace nil { - namespace crypto3 { - namespace blueprint { - namespace components { - - // (x - w^{n - 3}) * (x - w^{n - 2}) * (x - w^{n - 1}) - // zk-polynomial evaluation - // https://github.com/o1-labs/proof-systems/blob/1f8532ec1b8d43748a372632bd854be36b371afe/kimchi/src/circuits/polynomials/permutation.rs#L91 - // Input: group generator (w), - // domain size (n), - // evaluation point (x) - // Output: (x - w^{n - 3}) * (x - w^{n - 2}) * (x - w^{n - 1}) - template - class zkpm_evaluate; - - template - class zkpm_evaluate, - W0, W1, W2, W3, W4, W5, W6, W7, W8, W9, W10, W11, W12, W13, W14> { - - typedef snark::plonk_constraint_system - ArithmetizationType; - - using var = snark::plonk_variable; - - using mul_component = zk::components::multiplication; - using exp_component = zk::components::exponentiation; - using sub_component = zk::components::subtraction; - - constexpr static const std::size_t selector_seed = 0x0f25; - - constexpr static const std::size_t zk_rows = 3; - - public: - constexpr static const std::size_t rows_amount = 1 + exp_component::rows_amount + - 4 * mul_component::rows_amount + - 3 * sub_component::rows_amount; - constexpr static const std::size_t gates_amount = 0; - - struct params_type { - var group_gen; - std::size_t domain_size; - var x; - }; - - struct result_type { - var output; - - result_type(std::size_t start_row_index) { - std::size_t row = start_row_index; - } - }; - - static result_type - generate_circuit(blueprint &bp, - blueprint_public_assignment_table &assignment, - const params_type ¶ms, - const std::size_t start_row_index) { - - generate_assignments_constants(bp, assignment, params, start_row_index); - - var domain_size = var(0, start_row_index, false, var::column_type::constant); - - std::size_t row = start_row_index; - row++; // skip row for constants in exp_component - - result_type result(row); - - var w1 = exp_component::generate_circuit(bp, assignment, {params.group_gen, domain_size}, row) - .output; - row += exp_component::rows_amount; - var w2 = - zk::components::generate_circuit(bp, assignment, {w1, params.group_gen}, row) - .output; - row += mul_component::rows_amount; - var w3 = - zk::components::generate_circuit(bp, assignment, {w2, params.group_gen}, row) - .output; - row += mul_component::rows_amount; - - var a1 = - zk::components::generate_circuit(bp, assignment, {params.x, w1}, row).output; - row += sub_component::rows_amount; - var a2 = - zk::components::generate_circuit(bp, assignment, {params.x, w2}, row).output; - row += sub_component::rows_amount; - var a3 = - zk::components::generate_circuit(bp, assignment, {params.x, w3}, row).output; - row += sub_component::rows_amount; - - var ans1 = - zk::components::generate_circuit(bp, assignment, {a1, a2}, row).output; - row += mul_component::rows_amount; - result.output = - zk::components::generate_circuit(bp, assignment, {ans1, a3}, row).output; - row += mul_component::rows_amount; - - return result; - } - - static result_type generate_assignments(blueprint_assignment_table &assignment, - const params_type ¶ms, - const std::size_t start_row_index) { - - var domain_size = var(0, start_row_index, false, var::column_type::constant); - - std::size_t row = start_row_index; - row++; // skip row for constants in exp_component - - result_type result(row); - - var w1 = exp_component::generate_assignments(assignment, {params.group_gen, domain_size}, row) - .output; - row += exp_component::rows_amount; - var w2 = mul_component::generate_assignments(assignment, {w1, params.group_gen}, row).output; - row += mul_component::rows_amount; - var w3 = mul_component::generate_assignments(assignment, {w2, params.group_gen}, row).output; - row += mul_component::rows_amount; - - var a1 = sub_component::generate_assignments(assignment, {params.x, w1}, row).output; - row += sub_component::rows_amount; - var a2 = sub_component::generate_assignments(assignment, {params.x, w2}, row).output; - row += sub_component::rows_amount; - var a3 = sub_component::generate_assignments(assignment, {params.x, w3}, row).output; - row += sub_component::rows_amount; - - var ans1 = mul_component::generate_assignments(assignment, {a1, a2}, row).output; - row += mul_component::rows_amount; - result.output = mul_component::generate_assignments(assignment, {ans1, a3}, row).output; - row += mul_component::rows_amount; - - return result; - } - - private: - static void generate_gates(blueprint &bp, - blueprint_public_assignment_table &assignment, - const params_type ¶ms, - const std::size_t first_selector_index) { - } + namespace blueprint { + namespace components { + + // (x - w^{n - 3}) * (x - w^{n - 2}) * (x - w^{n - 1}) + // zk-polynomial evaluation + // https://github.com/o1-labs/proof-systems/blob/1f8532ec1b8d43748a372632bd854be36b371afe/kimchi/src/circuits/polynomials/permutation.rs#L91 + // Input: group generator (w), + // domain size (n), + // evaluation point (x) + // Output: (x - w^{n - 3}) * (x - w^{n - 2}) * (x - w^{n - 1}) + template + class zkpm_evaluate; + + template + class zkpm_evaluate, + W0, + W1, + W2, + W3, + W4, + W5, + W6, + W7, + W8, + W9, + W10, + W11, + W12, + W13, + W14> { + + typedef crypto3::zk::snark::plonk_constraint_system ArithmetizationType; + + using var = crypto3::zk::snark::plonk_variable; + + using mul_component = multiplication>; + using exp_component = exponentiation; + using sub_component = + subtraction>; + + constexpr static const std::size_t selector_seed = 0x0f25; + + constexpr static const std::size_t zk_rows = 3; + + public: + constexpr static const std::size_t rows_amount = + 1 + exp_component::rows_amount + 4 * mul_component::rows_amount + 3 * sub_component::rows_amount; + constexpr static const std::size_t gates_amount = 0; + + struct params_type { + var group_gen; + std::size_t domain_size; + var x; + }; - static void - generate_copy_constraints(blueprint &bp, - blueprint_public_assignment_table &assignment, - const params_type ¶ms, - const std::size_t start_row_index) { - } + struct result_type { + var output; - static void generate_assignments_constants( - blueprint &bp, - blueprint_public_assignment_table &assignment, - const params_type ¶ms, - const std::size_t start_row_index) { + result_type(std::size_t start_row_index) { std::size_t row = start_row_index; - assignment.constant(0)[row] = params.domain_size - zk_rows; } }; - } // namespace components - } // namespace blueprint - } // namespace crypto3 + + static result_type generate_circuit(blueprint &bp, + assignment &assignment, + const params_type ¶ms, + const std::size_t start_row_index) { + + generate_assignments_constants(bp, assignment, params, start_row_index); + + var domain_size = var(0, start_row_index, false, var::column_type::constant); + + std::size_t row = start_row_index; + row++; // skip row for constants in exp_component + + result_type result(row); + + var w1 = + exp_component::generate_circuit(bp, assignment, {params.group_gen, domain_size}, row).output; + row += exp_component::rows_amount; + var w2 = ::nil::blueprint::components::generate_circuit( + bp, assignment, {w1, params.group_gen}, row) + .output; + row += mul_component::rows_amount; + var w3 = ::nil::blueprint::components::generate_circuit( + bp, assignment, {w2, params.group_gen}, row) + .output; + row += mul_component::rows_amount; + + var a1 = ::nil::blueprint::components::generate_circuit( + bp, assignment, {params.x, w1}, row) + .output; + row += sub_component::rows_amount; + var a2 = ::nil::blueprint::components::generate_circuit( + bp, assignment, {params.x, w2}, row) + .output; + row += sub_component::rows_amount; + var a3 = ::nil::blueprint::components::generate_circuit( + bp, assignment, {params.x, w3}, row) + .output; + row += sub_component::rows_amount; + + var ans1 = + ::nil::blueprint::components::generate_circuit(bp, assignment, {a1, a2}, row) + .output; + row += mul_component::rows_amount; + result.output = + ::nil::blueprint::components::generate_circuit(bp, assignment, {ans1, a3}, row) + .output; + row += mul_component::rows_amount; + + return result; + } + + static result_type generate_assignments(assignment &assignment, + const params_type ¶ms, + const std::size_t start_row_index) { + + var domain_size = var(0, start_row_index, false, var::column_type::constant); + + std::size_t row = start_row_index; + row++; // skip row for constants in exp_component + + result_type result(row); + + var w1 = + exp_component::generate_assignments(assignment, {params.group_gen, domain_size}, row).output; + row += exp_component::rows_amount; + var w2 = mul_component::generate_assignments(assignment, {w1, params.group_gen}, row).output; + row += mul_component::rows_amount; + var w3 = mul_component::generate_assignments(assignment, {w2, params.group_gen}, row).output; + row += mul_component::rows_amount; + + var a1 = sub_component::generate_assignments(assignment, {params.x, w1}, row).output; + row += sub_component::rows_amount; + var a2 = sub_component::generate_assignments(assignment, {params.x, w2}, row).output; + row += sub_component::rows_amount; + var a3 = sub_component::generate_assignments(assignment, {params.x, w3}, row).output; + row += sub_component::rows_amount; + + var ans1 = mul_component::generate_assignments(assignment, {a1, a2}, row).output; + row += mul_component::rows_amount; + result.output = mul_component::generate_assignments(assignment, {ans1, a3}, row).output; + row += mul_component::rows_amount; + + return result; + } + + private: + static void generate_gates(blueprint &bp, + assignment &assignment, + const params_type ¶ms, + const std::size_t first_selector_index) { + } + + static void generate_copy_constraints(blueprint &bp, + assignment &assignment, + const params_type ¶ms, + const std::size_t start_row_index) { + } + + static void generate_assignments_constants(blueprint &bp, + assignment &assignment, + const params_type ¶ms, + const std::size_t start_row_index) { + std::size_t row = start_row_index; + assignment.constant(0)[row] = params.domain_size - zk_rows; + } + }; + } // namespace components + } // namespace blueprint } // namespace nil #endif // CRYPTO3_BLUEPRINT_COMPONENTS_PLONK_KIMCHI_DETAIL_ZKPM_EVALUATE_HPP diff --git a/include/nil/blueprint/components/systems/snark/plonk/kimchi/oracles_scalar.hpp b/include/nil/blueprint/components/systems/snark/plonk/kimchi/oracles_scalar.hpp index afeb90359..afbef5c82 100644 --- a/include/nil/blueprint/components/systems/snark/plonk/kimchi/oracles_scalar.hpp +++ b/include/nil/blueprint/components/systems/snark/plonk/kimchi/oracles_scalar.hpp @@ -47,7 +47,6 @@ #include #include #include -#include #include @@ -63,85 +62,67 @@ namespace nil { // Output: oracles result, scalar field part // (https://github.com/o1-labs/proof-systems/blob/1f8532ec1b8d43748a372632bd854be36b371afe/kimchi/src/verifier.rs#L457-L468) template + typename KimchiCommitmentParamsType, std::size_t... WireIndexes> class oracles_scalar; - template - class oracles_scalar< - snark::plonk_constraint_system, - CurveType, KimchiParamsType, KimchiCommitmentParamsType, - W0, W1, W2, W3, W4, W5, W6, W7, W8, W9, W10, W11, W12, W13, W14> { + class oracles_scalar, + CurveType, KimchiParamsType, KimchiCommitmentParamsType, W0, W1, W2, W3, W4, W5, W6, + W7, W8, W9, W10, W11, W12, W13, W14> { using BlueprintFieldType = typename CurveType::scalar_field_type; - typedef snark::plonk_constraint_system - ArithmetizationType; + typedef crypto3::zk::snark::plonk_constraint_system ArithmetizationType; - using var = snark::plonk_variable; + using var = crypto3::zk::snark::plonk_variable; constexpr static const std::size_t selector_seed = 0x0f08; - using endo_scalar_component = - zk::components::endo_scalar; + using endo_scalar_component = endo_scalar; - using exponentiation_component = - zk::components::exponentiation; - using mul_component = zk::components::multiplication; + using exponentiation_component = exponentiation; + using mul_component = multiplication>; - using alpha_powers_component = zk::components::element_powers; + using alpha_powers_component = element_powers; - using pi_powers_component = zk::components::element_powers; + using pi_powers_component = element_powers; using lagrange_denominators_component = - zk::components::lagrange_denominators; + lagrange_denominators; using public_eval_component = - zk::components::public_evaluations; + public_evaluations; using prev_chal_evals_component = - zk::components::prev_chal_evals; + prev_chal_evals; using combined_proof_evals_component = - zk::components::combine_proof_evals; + combine_proof_evals; - using ft_eval_component = - zk::components::ft_eval; + using ft_eval_component = ft_eval; - using cip_component = zk::components::oracles_cip; + using cip_component = oracles_cip; - using transcript_type = kimchi_transcript; + using transcript_type = kimchi_transcript_fr; - - - using proof_binding = typename zk::components::binding; + using proof_binding = binding; constexpr static const std::size_t eval_points_amount = 2; using prev_chal_output = - std::array, eval_points_amount>; + std::array, eval_points_amount>; constexpr static std::size_t rows() { std::size_t row = 0; @@ -156,7 +137,7 @@ namespace nil { // zeta row += endo_scalar_component::rows_amount; - //transcript.init_assignment(assignment, row); + // transcript.init_assignment(assignment, row); row += transcript_type::init_rows; row += transcript_type::absorb_rows; @@ -211,7 +192,7 @@ namespace nil { // ft_eval0 row += ft_eval_component::rows_amount; - //cip + // cip row += cip_component::rows_amount; return row; @@ -223,19 +204,17 @@ namespace nil { struct params_type { - kimchi_verifier_index_scalar &verifier_index; - kimchi_proof_scalar &proof; + kimchi_proof_scalar + &proof; typename proof_binding::fq_sponge_output &fq_output; params_type(kimchi_verifier_index_scalar &_verifier_index, - kimchi_proof_scalar &_proof, - typename proof_binding::fq_sponge_output &_fq_output) : - verifier_index(_verifier_index), - proof(_proof), - fq_output(_fq_output) {} + kimchi_proof_scalar &_proof, + typename proof_binding::fq_sponge_output &_fq_output) : + verifier_index(_verifier_index), proof(_proof), fq_output(_fq_output) { + } }; struct result_type { @@ -253,21 +232,19 @@ namespace nil { std::array alpha_powers; std::array p_eval; std::array powers_of_eval_points_for_chunks; - std::array - prev_challenges_evals; + std::array prev_challenges_evals; var zeta_pow_n; var ft_eval0; - std::array, - eval_points_amount> combined_evals; + std::array, eval_points_amount> + combined_evals; var cip; std::array eval_points; }; - static result_type - generate_circuit(blueprint &bp, - blueprint_public_assignment_table &assignment, - const params_type ¶ms, - const std::size_t start_row_index) { + static result_type generate_circuit(blueprint &bp, + assignment &assignment, + const params_type ¶ms, + const std::size_t start_row_index) { auto selector_iterator = assignment.find_selector(selector_seed); std::size_t first_selector_index; @@ -290,22 +267,22 @@ namespace nil { var beta = params.fq_output.beta; var gamma = params.fq_output.gamma; - var joint_combiner; if (KimchiParamsType::circuit_params::use_lookup && KimchiParamsType::circuit_params::joint_lookup) { joint_combiner = endo_scalar_component::generate_circuit(bp, assignment, - {params.fq_output.joint_combiner}, row).output; + {params.fq_output.joint_combiner}, row) + .output; row += endo_scalar_component::rows_amount; } // alpha = phi(alpha_challenge) - var alpha = endo_scalar_component::generate_circuit( - bp, assignment, {params.fq_output.alpha}, row).output; + var alpha = + endo_scalar_component::generate_circuit(bp, assignment, {params.fq_output.alpha}, row).output; row += endo_scalar_component::rows_amount; // zeta = phi(zeta_challenge) - var zeta = endo_scalar_component::generate_circuit( - bp, assignment, {params.fq_output.zeta}, row).output; + var zeta = + endo_scalar_component::generate_circuit(bp, assignment, {params.fq_output.zeta}, row).output; row += endo_scalar_component::rows_amount; // fr_transcript.absorb(fq_digest) @@ -316,51 +293,51 @@ namespace nil { row += transcript_type::absorb_rows; // zeta_pow_n = zeta**n - var zeta_pow_n = exponentiation_component::generate_circuit( - bp, assignment, - {zeta, domain_size}, row) - .output; + var zeta_pow_n = + exponentiation_component::generate_circuit(bp, assignment, {zeta, domain_size}, row).output; row += exponentiation_component::rows_amount; - var zeta_omega = zk::components::generate_circuit(bp, assignment, - {zeta, params.verifier_index.omega}, row).output; + var zeta_omega = ::nil::blueprint::components::generate_circuit( + bp, assignment, {zeta, params.verifier_index.omega}, row) + .output; row += mul_component::rows_amount; var zeta_omega_pow_n = - exponentiation_component::generate_circuit(bp, assignment, - {zeta_omega, domain_size}, row).output; + exponentiation_component::generate_circuit(bp, assignment, {zeta_omega, domain_size}, row) + .output; row += exponentiation_component::rows_amount; std::array alpha_powers = - alpha_powers_component::generate_circuit(bp, assignment, - {alpha, one}, row).output; + alpha_powers_component::generate_circuit(bp, assignment, {alpha, one}, row).output; row += alpha_powers_component::rows_amount; std::array omega_powers = - pi_powers_component::generate_circuit(bp, assignment, - {params.verifier_index.omega, one}, row).output; + pi_powers_component::generate_circuit(bp, assignment, {params.verifier_index.omega, one}, row) + .output; row += pi_powers_component::rows_amount; std::array lagrange_denominators = - lagrange_denominators_component::generate_circuit(bp, assignment, - {zeta, zeta_omega, omega_powers, one}, row).output; + lagrange_denominators_component::generate_circuit(bp, assignment, + {zeta, zeta_omega, omega_powers, one}, row) + .output; row += lagrange_denominators_component::rows_amount; // TODO: check on empty public_input std::array pi = params.proof.public_input; - std::array public_eval = public_eval_component::generate_circuit(bp, - assignment, {zeta_pow_n, zeta_omega_pow_n, - pi, - lagrange_denominators, - omega_powers, - domain_size, one, zero}, row).output; + std::array public_eval = + public_eval_component::generate_circuit(bp, assignment, + {zeta_pow_n, zeta_omega_pow_n, pi, + lagrange_denominators, omega_powers, domain_size, one, + zero}, + row) + .output; row += public_eval_component::rows_amount; - transcript.absorb_evaluations_circuit( - bp, assignment, public_eval[0], params.proof.proof_evals[0], row); + transcript.absorb_evaluations_circuit(bp, assignment, public_eval[0], params.proof.proof_evals[0], + row); row += transcript_type::absorb_evaluations_rows; - transcript.absorb_evaluations_circuit( - bp, assignment, public_eval[1], params.proof.proof_evals[1], row); + transcript.absorb_evaluations_circuit(bp, assignment, public_eval[1], params.proof.proof_evals[1], + row); row += transcript_type::absorb_evaluations_rows; transcript.absorb_circuit(bp, assignment, params.proof.ft_eval, row); @@ -369,111 +346,86 @@ namespace nil { var v_challenge = transcript.challenge_circuit(bp, assignment, row); row += transcript_type::challenge_rows; - var v = endo_scalar_component::generate_circuit( - bp, assignment, {v_challenge}, row).output; + var v = endo_scalar_component::generate_circuit(bp, assignment, {v_challenge}, row).output; row += endo_scalar_component::rows_amount; var u_challenge = transcript.challenge_circuit(bp, assignment, row); row += transcript_type::challenge_rows; - var u = endo_scalar_component::generate_circuit( - bp, assignment, {u_challenge}, row).output; + var u = endo_scalar_component::generate_circuit(bp, assignment, {u_challenge}, row).output; row += endo_scalar_component::rows_amount; - std::array powers_of_eval_points_for_chunks; - powers_of_eval_points_for_chunks[0] = exponentiation_component::generate_circuit( - bp, assignment, - {zeta, max_poly_size}, row) - .output; + powers_of_eval_points_for_chunks[0] = + exponentiation_component::generate_circuit(bp, assignment, {zeta, max_poly_size}, row).output; row += exponentiation_component::rows_amount; - powers_of_eval_points_for_chunks[1] = exponentiation_component::generate_circuit( - bp, assignment, - {zeta_omega, max_poly_size}, row) - .output; + powers_of_eval_points_for_chunks[1] = + exponentiation_component::generate_circuit(bp, assignment, {zeta_omega, max_poly_size}, row) + .output; row += exponentiation_component::rows_amount; - std::array prev_challenges_evals; for (std::size_t i = 0; i < KimchiParamsType::prev_challenges_size; i++) { std::array prev_challenges = params.proof.prev_challenges[i]; prev_challenges_evals[i] = - prev_chal_evals_component::generate_circuit(bp, assignment, - {prev_challenges, - {{zeta, zeta_omega}}, - powers_of_eval_points_for_chunks, - one, zero}, row).output; + prev_chal_evals_component::generate_circuit( + bp, assignment, + {prev_challenges, {{zeta, zeta_omega}}, powers_of_eval_points_for_chunks, one, zero}, + row) + .output; row += prev_chal_evals_component::rows_amount; } - std::array, - eval_points_amount> combined_evals; + std::array, eval_points_amount> + combined_evals; for (std::size_t i = 0; i < eval_points_amount; i++) { - combined_evals[i] = combined_proof_evals_component::generate_circuit( - bp, assignment, {params.proof.proof_evals[i], - powers_of_eval_points_for_chunks[i]}, row).output; + combined_evals[i] = + combined_proof_evals_component::generate_circuit( + bp, assignment, {params.proof.proof_evals[i], powers_of_eval_points_for_chunks[i]}, row) + .output; row += combined_proof_evals_component::rows_amount; } - std::array, - eval_points_amount> evals = params.proof.proof_evals; - var ft_eval0 = ft_eval_component::generate_circuit( - bp, - assignment, - {params.verifier_index, - zeta_pow_n, - alpha_powers, - combined_evals, - gamma, - beta, - public_eval, - zeta, - joint_combiner}, - row - ).output; + std::array, eval_points_amount> + evals = params.proof.proof_evals; + var ft_eval0 = ft_eval_component::generate_circuit(bp, + assignment, + {params.verifier_index, zeta_pow_n, alpha_powers, + combined_evals, gamma, beta, public_eval, zeta, + joint_combiner}, + row) + .output; row += ft_eval_component::rows_amount; - //cip - var cip = cip_component::generate_circuit(bp, - assignment, - {v, - u, - ft_eval0, - params.proof.ft_eval, - prev_challenges_evals, - public_eval, - params.proof.proof_evals}, - row).output; + // cip + var cip = + cip_component::generate_circuit(bp, + assignment, + {v, u, ft_eval0, params.proof.ft_eval, prev_challenges_evals, + public_eval, params.proof.proof_evals}, + row) + .output; row += cip_component::rows_amount; generate_copy_constraints(bp, assignment, params, start_row_index); - typename result_type::random_oracles random_oracles = { - alpha, - zeta, - v, - u, - v_challenge, - u_challenge - }; - - return { - transcript, - random_oracles, - alpha_powers, - public_eval, - powers_of_eval_points_for_chunks, - prev_challenges_evals, - zeta_pow_n, - ft_eval0, - combined_evals, - cip, - {zeta, zeta_omega} - }; + typename result_type::random_oracles random_oracles = {alpha, zeta, v, u, v_challenge, u_challenge}; + + return {transcript, + random_oracles, + alpha_powers, + public_eval, + powers_of_eval_points_for_chunks, + prev_challenges_evals, + zeta_pow_n, + ft_eval0, + combined_evals, + cip, + {zeta, zeta_omega}}; } - static result_type generate_assignments(blueprint_assignment_table &assignment, + static result_type generate_assignments(assignment &assignment, const params_type ¶ms, std::size_t start_row_index) { @@ -490,17 +442,18 @@ namespace nil { var joint_combiner; if (KimchiParamsType::circuit_params::use_lookup && KimchiParamsType::circuit_params::joint_lookup) { - joint_combiner = endo_scalar_component::generate_assignments(assignment, - {params.fq_output.joint_combiner}, row).output; + joint_combiner = endo_scalar_component::generate_assignments( + assignment, {params.fq_output.joint_combiner}, row) + .output; row += endo_scalar_component::rows_amount; } - var alpha = endo_scalar_component::generate_assignments(assignment, - {params.fq_output.alpha}, row).output; + var alpha = + endo_scalar_component::generate_assignments(assignment, {params.fq_output.alpha}, row).output; row += endo_scalar_component::rows_amount; - var zeta = endo_scalar_component::generate_assignments(assignment, - {params.fq_output.zeta}, row).output; + var zeta = + endo_scalar_component::generate_assignments(assignment, {params.fq_output.zeta}, row).output; row += endo_scalar_component::rows_amount; var zero = var(0, start_row_index + 4, false, var::column_type::constant); @@ -515,46 +468,46 @@ namespace nil { row += transcript_type::absorb_rows; var n = domain_size; - var zeta_pow_n = exponentiation_component::generate_assignments( - assignment, {zeta, n}, row).output; + var zeta_pow_n = exponentiation_component::generate_assignments(assignment, {zeta, n}, row).output; row += exponentiation_component::rows_amount; - var zeta_omega = mul_component::generate_assignments(assignment, {zeta, - params.verifier_index.omega}, row).output; + var zeta_omega = + mul_component::generate_assignments(assignment, {zeta, params.verifier_index.omega}, row) + .output; row += mul_component::rows_amount; - var zeta_omega_pow_n = exponentiation_component::generate_assignments( - assignment, {zeta_omega, n}, row).output; + var zeta_omega_pow_n = + exponentiation_component::generate_assignments(assignment, {zeta_omega, n}, row).output; row += exponentiation_component::rows_amount; - std::array alpha_powers = alpha_powers_component::generate_assignments( - assignment, {alpha, one}, row).output; + std::array alpha_powers = + alpha_powers_component::generate_assignments(assignment, {alpha, one}, row).output; row += alpha_powers_component::rows_amount; std::array omega_powers = - pi_powers_component::generate_assignments(assignment, - {params.verifier_index.omega, one}, row).output; + pi_powers_component::generate_assignments(assignment, {params.verifier_index.omega, one}, row) + .output; row += pi_powers_component::rows_amount; std::array lagrange_denominators = - lagrange_denominators_component::generate_assignments(assignment, - {zeta, zeta_omega, omega_powers, one}, row).output; + lagrange_denominators_component::generate_assignments( + assignment, {zeta, zeta_omega, omega_powers, one}, row) + .output; row += lagrange_denominators_component::rows_amount; std::array pi = params.proof.public_input; - std::array public_eval = public_eval_component::generate_assignments( - assignment, {zeta_pow_n, zeta_omega_pow_n, - pi, - lagrange_denominators, - omega_powers, - n, one, zero}, row).output; + std::array public_eval = + public_eval_component::generate_assignments( + assignment, + {zeta_pow_n, zeta_omega_pow_n, pi, lagrange_denominators, omega_powers, n, one, zero}, row) + .output; row += public_eval_component::rows_amount; - transcript.absorb_evaluations_assignment( - assignment, public_eval[0], params.proof.proof_evals[0], row); + transcript.absorb_evaluations_assignment(assignment, public_eval[0], params.proof.proof_evals[0], + row); row += transcript_type::absorb_evaluations_rows; - transcript.absorb_evaluations_assignment( - assignment, public_eval[1], params.proof.proof_evals[1], row); + transcript.absorb_evaluations_assignment(assignment, public_eval[1], params.proof.proof_evals[1], + row); row += transcript_type::absorb_evaluations_rows; transcript.absorb_assignment(assignment, params.proof.ft_eval, row); @@ -562,23 +515,19 @@ namespace nil { var v_challenge = transcript.challenge_assignment(assignment, row); row += transcript_type::challenge_rows; - var v = endo_scalar_component::generate_assignments(assignment, - {v_challenge}, row).output; + var v = endo_scalar_component::generate_assignments(assignment, {v_challenge}, row).output; row += endo_scalar_component::rows_amount; var u_challenge = transcript.challenge_assignment(assignment, row); row += transcript_type::challenge_rows; - var u = endo_scalar_component::generate_assignments(assignment, - {u_challenge}, row).output; + var u = endo_scalar_component::generate_assignments(assignment, {u_challenge}, row).output; row += endo_scalar_component::rows_amount; std::array powers_of_eval_points_for_chunks = { - exponentiation_component::generate_assignments( - assignment, {zeta, max_poly_size}, row).output, - exponentiation_component::generate_assignments( - assignment, {zeta_omega, max_poly_size}, - row + exponentiation_component::rows_amount).output - }; + exponentiation_component::generate_assignments(assignment, {zeta, max_poly_size}, row).output, + exponentiation_component::generate_assignments(assignment, {zeta_omega, max_poly_size}, + row + exponentiation_component::rows_amount) + .output}; row += 2 * exponentiation_component::rows_amount; std::array prev_challenges_evals; @@ -587,110 +536,88 @@ namespace nil { std::array prev_challenges = params.proof.prev_challenges[i]; prev_challenges_evals[i] = - prev_chal_evals_component::generate_assignments(assignment, - {prev_challenges, - {{zeta, zeta_omega}}, - powers_of_eval_points_for_chunks, - one, zero}, row).output; + prev_chal_evals_component::generate_assignments( + assignment, + {prev_challenges, {{zeta, zeta_omega}}, powers_of_eval_points_for_chunks, one, zero}, + row) + .output; row += prev_chal_evals_component::rows_amount; } - std::array, - eval_points_amount> combined_evals; + std::array, eval_points_amount> + combined_evals; for (std::size_t i = 0; i < eval_points_amount; i++) { - combined_evals[i] = combined_proof_evals_component::generate_assignments( - assignment, {params.proof.proof_evals[i], - powers_of_eval_points_for_chunks[i]}, row).output; + combined_evals[i] = + combined_proof_evals_component::generate_assignments( + assignment, {params.proof.proof_evals[i], powers_of_eval_points_for_chunks[i]}, row) + .output; row += combined_proof_evals_component::rows_amount; } - std::array, - eval_points_amount> evals = params.proof.proof_evals; - var ft_eval0 = ft_eval_component::generate_assignments( - assignment, - {params.verifier_index, - zeta_pow_n, - alpha_powers, - combined_evals, - gamma, - beta, - public_eval, - zeta, - joint_combiner}, - row - ).output; + std::array, eval_points_amount> + evals = params.proof.proof_evals; + var ft_eval0 = ft_eval_component::generate_assignments(assignment, + {params.verifier_index, zeta_pow_n, + alpha_powers, combined_evals, gamma, beta, + public_eval, zeta, joint_combiner}, + row) + .output; row += ft_eval_component::rows_amount; - //cip - var cip = cip_component::generate_assignments( - assignment, - {v, - u, - ft_eval0, - params.proof.ft_eval, - prev_challenges_evals, - public_eval, - params.proof.proof_evals}, - row).output; + // cip + var cip = cip_component::generate_assignments(assignment, + {v, u, ft_eval0, params.proof.ft_eval, + prev_challenges_evals, public_eval, + params.proof.proof_evals}, + row) + .output; row += cip_component::rows_amount; - typename result_type::random_oracles random_oracles = { - alpha, - zeta, - v, - u, - v_challenge, - u_challenge - }; - - return { - transcript, - random_oracles, - alpha_powers, - public_eval, - powers_of_eval_points_for_chunks, - prev_challenges_evals, - zeta_pow_n, - ft_eval0, - combined_evals, - cip, - {zeta, zeta_omega} - }; + typename result_type::random_oracles random_oracles = {alpha, zeta, v, u, v_challenge, u_challenge}; + + return {transcript, + random_oracles, + alpha_powers, + public_eval, + powers_of_eval_points_for_chunks, + prev_challenges_evals, + zeta_pow_n, + ft_eval0, + combined_evals, + cip, + {zeta, zeta_omega}}; } private: static void generate_gates(blueprint &bp, - blueprint_public_assignment_table &assignment, + assignment &assignment, const params_type ¶ms, std::size_t component_start_row = 0) { } - static void - generate_copy_constraints(blueprint &bp, - blueprint_public_assignment_table &assignment, - const params_type ¶ms, - std::size_t component_start_row = 0) { - + static void generate_copy_constraints(blueprint &bp, + assignment &assignment, + const params_type ¶ms, + std::size_t component_start_row = 0) { } - static void - generate_assignments_constant(blueprint &bp, - blueprint_public_assignment_table &assignment, - const params_type ¶ms, - std::size_t component_start_row) { - std::size_t row = component_start_row + 4; - assignment.constant(0)[row] = 0; - row++; - assignment.constant(0)[row] = 1; - row++; - - assignment.constant(0)[row] = params.verifier_index.domain_size; - row++; - assignment.constant(0)[row] = KimchiCommitmentParamsType::max_poly_size; + static void generate_assignments_constant(blueprint &bp, + assignment &assignment, + const params_type ¶ms, + std::size_t component_start_row) { + std::size_t row = component_start_row + 4; + assignment.constant(0)[row] = 0; + row++; + assignment.constant(0)[row] = 1; + row++; + + assignment.constant(0)[row] = params.verifier_index.domain_size; + row++; + assignment.constant(0)[row] = KimchiCommitmentParamsType::max_poly_size; } }; } // namespace components - } // namespace blueprint + } // namespace blueprint } // namespace nil #endif // CRYPTO3_BLUEPRINT_COMPONENTS_PLONK_KIMCHI_ORACLES_SCALAR_COMPONENT_HPP diff --git a/include/nil/blueprint/components/systems/snark/plonk/kimchi/prepare_batch_scalar.hpp b/include/nil/blueprint/components/systems/snark/plonk/kimchi/prepare_batch_scalar.hpp index 2b1565e34..094b46928 100644 --- a/include/nil/blueprint/components/systems/snark/plonk/kimchi/prepare_batch_scalar.hpp +++ b/include/nil/blueprint/components/systems/snark/plonk/kimchi/prepare_batch_scalar.hpp @@ -38,7 +38,7 @@ #include #include -#include +#include #include #include @@ -49,7 +49,7 @@ #include #include -#include +#include namespace nil { namespace blueprint { @@ -63,57 +63,52 @@ namespace nil { // Output: batch evaluation proof, scalar field part // (https://github.com/o1-labs/proof-systems/blob/1f8532ec1b8d43748a372632bd854be36b371afe/kimchi/src/verifier.rs#L881-L888) template + typename KimchiCommitmentParamsType, std::size_t... WireIndexes> class prepare_batch_scalar; - template class prepare_batch_scalar< - snark::plonk_constraint_system, - CurveType, KimchiParamsType, KimchiCommitmentParamsType, - W0, W1, W2, W3, W4, W5, W6, W7, W8, W9, W10, W11, W12, W13, W14> { + crypto3::zk::snark::plonk_constraint_system, CurveType, + KimchiParamsType, KimchiCommitmentParamsType, W0, W1, W2, W3, W4, W5, W6, W7, W8, W9, W10, W11, W12, + W13, W14> { using BlueprintFieldType = typename CurveType::scalar_field_type; - typedef snark::plonk_constraint_system - ArithmetizationType; + typedef crypto3::zk::snark::plonk_constraint_system ArithmetizationType; - using var = snark::plonk_variable; + using var = crypto3::zk::snark::plonk_variable; - using sub_component = zk::components::subtraction; + using sub_component = + subtraction>; - using oracles_component = oracles_scalar; + using oracles_component = + oracles_scalar; - using zkpm_evaluate_component = zkpm_evaluate; + using zkpm_evaluate_component = + zkpm_evaluate; - using perm_scalars_component = perm_scalars; + using perm_scalars_component = perm_scalars; - using generic_scalars_component = generic_scalars; + using generic_scalars_component = generic_scalars; - using index_terms_scalars_component = index_terms_scalars; + using index_terms_scalars_component = + index_terms_scalars; - using proof_binding = typename zk::components::binding; + using proof_binding = binding; - using batch_proof = batch_evaluation_proof_scalar; + using batch_proof = batch_evaluation_proof_scalar; using index_terms_list = typename KimchiParamsType::circuit_params::index_terms_list; - using kimchi_constants = zk::components::kimchi_inner_constants; + using kimchi_constants = kimchi_inner_constants; using verifier_index_type = kimchi_verifier_index_scalar; @@ -141,13 +136,12 @@ namespace nil { constexpr static const std::size_t rows_amount = rows(); constexpr static const std::size_t gates_amount = 0; - constexpr static const std::size_t f_comm_msm_size = - kimchi_constants::f_comm_msm_size; + constexpr static const std::size_t f_comm_msm_size = kimchi_constants::f_comm_msm_size; struct params_type { verifier_index_type &verifier_index; - kimchi_proof_scalar &proof; + kimchi_proof_scalar + &proof; typename proof_binding::fq_sponge_output &fq_output; }; @@ -157,11 +151,10 @@ namespace nil { std::array f_comm_scalars; }; - static result_type - generate_circuit(blueprint &bp, - blueprint_public_assignment_table &assignment, - const params_type ¶ms, - const std::size_t start_row_index) { + static result_type generate_circuit(blueprint &bp, + assignment &assignment, + const params_type ¶ms, + const std::size_t start_row_index) { std::size_t row = start_row_index; generate_assignments_constant(bp, assignment, params, start_row_index); @@ -171,61 +164,62 @@ namespace nil { var domain_size = var(0, start_row_index + 2, false, var::column_type::constant); var max_poly_size = var(0, start_row_index + 3, false, var::column_type::constant); - typename oracles_component::params_type oracles_params( - params.verifier_index, params.proof, params.fq_output - ); - auto oracles_output = oracles_component::generate_circuit(bp, assignment, - oracles_params, row); + typename oracles_component::params_type oracles_params(params.verifier_index, params.proof, + params.fq_output); + auto oracles_output = oracles_component::generate_circuit(bp, assignment, oracles_params, row); row += oracles_component::rows_amount; std::array f_comm_scalars; std::size_t f_comm_idx = 0; var zkp = zkpm_evaluate_component::generate_circuit(bp, assignment, - {params.verifier_index.omega, params.verifier_index.domain_size, - oracles_output.oracles.zeta}, row).output; + {params.verifier_index.omega, + params.verifier_index.domain_size, + oracles_output.oracles.zeta}, + row) + .output; row += zkpm_evaluate_component::rows_amount; std::pair alpha_idxs = index_terms_list::alpha_map(argument_type::Permutation); - f_comm_scalars[f_comm_idx] = perm_scalars_component::generate_circuit(bp, - assignment, {oracles_output.combined_evals, oracles_output.alpha_powers, - alpha_idxs.first, - params.fq_output.beta, params.fq_output.gamma, - zkp}, row).output; + f_comm_scalars[f_comm_idx] = + perm_scalars_component::generate_circuit(bp, assignment, + {oracles_output.combined_evals, + oracles_output.alpha_powers, alpha_idxs.first, + params.fq_output.beta, params.fq_output.gamma, zkp}, + row) + .output; f_comm_idx += 1; row += perm_scalars_component::rows_amount; - alpha_idxs = - index_terms_list::alpha_map(argument_type::Generic); + alpha_idxs = index_terms_list::alpha_map(argument_type::Generic); std::array generic_scalars = - generic_scalars_component::generate_circuit(bp, - assignment, {oracles_output.combined_evals, oracles_output.alpha_powers, - alpha_idxs.first}, row).output; + generic_scalars_component::generate_circuit( + bp, assignment, + {oracles_output.combined_evals, oracles_output.alpha_powers, alpha_idxs.first}, row) + .output; std::copy(std::begin(generic_scalars), std::end(generic_scalars), - std::begin(f_comm_scalars) + f_comm_idx); + std::begin(f_comm_scalars) + f_comm_idx); f_comm_idx += generic_scalars_component::output_size; row += generic_scalars_component::rows_amount; // xi^n - 1 - var vanishing_eval = zk::components::generate_circuit(bp, - assignment, {oracles_output.zeta_pow_n, one}, row - ).output; + var vanishing_eval = ::nil::blueprint::components::generate_circuit( + bp, assignment, {oracles_output.zeta_pow_n, one}, row) + .output; row += sub_component::rows_amount; - auto index_scalars = index_terms_scalars_component::generate_circuit( - bp, assignment, { - oracles_output.oracles.zeta, - oracles_output.oracles.alpha, - params.fq_output.beta, params.fq_output.gamma, - params.fq_output.joint_combiner, - oracles_output.combined_evals, - params.verifier_index.omega, - params.verifier_index.domain_size}, row - ).output; + auto index_scalars = + index_terms_scalars_component::generate_circuit( + bp, assignment, + {oracles_output.oracles.zeta, oracles_output.oracles.alpha, params.fq_output.beta, + params.fq_output.gamma, params.fq_output.joint_combiner, oracles_output.combined_evals, + params.verifier_index.omega, params.verifier_index.domain_size}, + row) + .output; row += index_terms_scalars_component::rows_amount; - for(std::size_t i = 0; i < index_scalars.size(); i++) { + for (std::size_t i = 0; i < index_scalars.size(); i++) { f_comm_scalars[f_comm_idx++] = index_scalars[i]; } @@ -233,22 +227,16 @@ namespace nil { assert(row == start_row_index + rows_amount); - result_type res = { - {oracles_output.cip, - params.fq_output, - oracles_output.eval_points, - oracles_output.oracles.u, - oracles_output.oracles.v, - params.proof.opening, - oracles_output.transcript}, - zeta_to_srs_len, - f_comm_scalars - }; + result_type res = {{oracles_output.cip, params.fq_output, oracles_output.eval_points, + oracles_output.oracles.u, oracles_output.oracles.v, params.proof.opening, + oracles_output.transcript}, + zeta_to_srs_len, + f_comm_scalars}; return res; } - static result_type generate_assignments(blueprint_assignment_table &assignment, + static result_type generate_assignments(assignment &assignment, const params_type ¶ms, std::size_t start_row_index) { @@ -259,59 +247,59 @@ namespace nil { var domain_size = var(0, start_row_index + 2, false, var::column_type::constant); var max_poly_size = var(0, start_row_index + 3, false, var::column_type::constant); - typename oracles_component::params_type oracles_params( - params.verifier_index, params.proof, params.fq_output - ); - auto oracles_output = oracles_component::generate_assignments(assignment, - oracles_params, row); + typename oracles_component::params_type oracles_params(params.verifier_index, params.proof, + params.fq_output); + auto oracles_output = oracles_component::generate_assignments(assignment, oracles_params, row); row += oracles_component::rows_amount; std::array f_comm_scalars; std::size_t f_comm_idx = 0; var zkp = zkpm_evaluate_component::generate_assignments(assignment, - {params.verifier_index.omega, params.verifier_index.domain_size, - oracles_output.oracles.zeta}, row).output; + {params.verifier_index.omega, + params.verifier_index.domain_size, + oracles_output.oracles.zeta}, + row) + .output; row += zkpm_evaluate_component::rows_amount; std::pair alpha_idxs = index_terms_list::alpha_map(argument_type::Permutation); - f_comm_scalars[f_comm_idx] = perm_scalars_component::generate_assignments( - assignment, {oracles_output.combined_evals, oracles_output.alpha_powers, - alpha_idxs.first, - params.fq_output.beta, params.fq_output.gamma, - zkp}, row).output; + f_comm_scalars[f_comm_idx] = + perm_scalars_component::generate_assignments( + assignment, + {oracles_output.combined_evals, oracles_output.alpha_powers, alpha_idxs.first, + params.fq_output.beta, params.fq_output.gamma, zkp}, + row) + .output; f_comm_idx += 1; row += perm_scalars_component::rows_amount; - alpha_idxs = - index_terms_list::alpha_map(argument_type::Generic); + alpha_idxs = index_terms_list::alpha_map(argument_type::Generic); std::array generic_scalars = generic_scalars_component::generate_assignments( - assignment, {oracles_output.combined_evals, oracles_output.alpha_powers, - alpha_idxs.first}, row).output; + assignment, {oracles_output.combined_evals, oracles_output.alpha_powers, alpha_idxs.first}, + row) + .output; std::copy(std::begin(generic_scalars), std::end(generic_scalars), - std::begin(f_comm_scalars) + f_comm_idx); + std::begin(f_comm_scalars) + f_comm_idx); f_comm_idx += generic_scalars_component::output_size; row += generic_scalars_component::rows_amount; // xi^n - 1 - var vanishing_eval = sub_component::generate_assignments( - assignment, {oracles_output.zeta_pow_n, one}, row - ).output; + var vanishing_eval = + sub_component::generate_assignments(assignment, {oracles_output.zeta_pow_n, one}, row).output; row += sub_component::rows_amount; - auto index_scalars = index_terms_scalars_component::generate_assignments( - assignment, { - oracles_output.oracles.zeta, - oracles_output.oracles.alpha, - params.fq_output.beta, params.fq_output.gamma, - params.fq_output.joint_combiner, - oracles_output.combined_evals, - params.verifier_index.omega, - params.verifier_index.domain_size}, row - ).output; - row += index_terms_scalars_component::rows_amount; - for(std::size_t i = 0; i < index_scalars.size(); i++) { + auto index_scalars = + index_terms_scalars_component::generate_assignments( + assignment, + {oracles_output.oracles.zeta, oracles_output.oracles.alpha, params.fq_output.beta, + params.fq_output.gamma, params.fq_output.joint_combiner, oracles_output.combined_evals, + params.verifier_index.omega, params.verifier_index.domain_size}, + row) + .output; + row += index_terms_scalars_component::rows_amount; + for (std::size_t i = 0; i < index_scalars.size(); i++) { f_comm_scalars[f_comm_idx] = index_scalars[i]; } @@ -319,54 +307,45 @@ namespace nil { assert(row == start_row_index + rows_amount); - result_type res = { - {oracles_output.cip, - params.fq_output, - oracles_output.eval_points, - oracles_output.oracles.u, - oracles_output.oracles.v, - params.proof.opening, - oracles_output.transcript}, - zeta_to_srs_len, - f_comm_scalars - }; + result_type res = {{oracles_output.cip, params.fq_output, oracles_output.eval_points, + oracles_output.oracles.u, oracles_output.oracles.v, params.proof.opening, + oracles_output.transcript}, + zeta_to_srs_len, + f_comm_scalars}; return res; } private: static void generate_gates(blueprint &bp, - blueprint_public_assignment_table &assignment, + assignment &assignment, const params_type ¶ms, std::size_t component_start_row = 0) { } - static void - generate_copy_constraints(blueprint &bp, - blueprint_public_assignment_table &assignment, - const params_type ¶ms, - std::size_t component_start_row = 0) { - + static void generate_copy_constraints(blueprint &bp, + assignment &assignment, + const params_type ¶ms, + std::size_t component_start_row = 0) { } - static void - generate_assignments_constant(blueprint &bp, - blueprint_public_assignment_table &assignment, - const params_type ¶ms, - std::size_t component_start_row) { - std::size_t row = component_start_row; - assignment.constant(0)[row] = 0; - row++; - assignment.constant(0)[row] = 1; - row++; - - assignment.constant(0)[row] = params.verifier_index.domain_size; - row++; - assignment.constant(0)[row] = KimchiCommitmentParamsType::max_poly_size; + static void generate_assignments_constant(blueprint &bp, + assignment &assignment, + const params_type ¶ms, + std::size_t component_start_row) { + std::size_t row = component_start_row; + assignment.constant(0)[row] = 0; + row++; + assignment.constant(0)[row] = 1; + row++; + + assignment.constant(0)[row] = params.verifier_index.domain_size; + row++; + assignment.constant(0)[row] = KimchiCommitmentParamsType::max_poly_size; } }; } // namespace components - } // namespace blueprint + } // namespace blueprint } // namespace nil #endif // CRYPTO3_BLUEPRINT_COMPONENTS_PLONK_KIMCHI_PREPARE_BATCH_SCALAR_HPP diff --git a/include/nil/blueprint/components/systems/snark/plonk/kimchi/scalar_details/batch_dlog_accumulator_check_scalar.hpp b/include/nil/blueprint/components/systems/snark/plonk/kimchi/scalar_details/batch_dlog_accumulator_check_scalar.hpp index 3a3981625..225cbf7a7 100644 --- a/include/nil/blueprint/components/systems/snark/plonk/kimchi/scalar_details/batch_dlog_accumulator_check_scalar.hpp +++ b/include/nil/blueprint/components/systems/snark/plonk/kimchi/scalar_details/batch_dlog_accumulator_check_scalar.hpp @@ -27,23 +27,23 @@ #ifndef CRYPTO3_ZK_BLUEPRINT_BATCH_VERIFY_SCALAR_FIELD_HPP #define CRYPTO3_ZK_BLUEPRINT_BATCH_VERIFY_SCALAR_FIELD_HPP -#include +#include #include -#include +#include -#include -#include -#include -#include +#include +#include +#include +#include -#include -#include +#include +#include -#include -#include +#include +#include -#include +#include namespace nil { namespace crypto3 { @@ -191,14 +191,14 @@ namespace nil { scalars[scalar_idx++] = rand_base_i; rand_base_i = - zk::components::generate_circuit(bp, assignment, {rand_base_i, rand_base}, row).output; + ::nil::blueprint::components::generate_circuit(bp, assignment, {rand_base_i, rand_base}, row).output; row += mul_component::rows_amount; } std::vector challenges_inv(params.challenges.size()); for (std::size_t i = 0; i < params.challenges.size(); i++) { - challenges_inv[i] = zk::components::generate_circuit(bp, assignment, + challenges_inv[i] = ::nil::blueprint::components::generate_circuit(bp, assignment, {one, params.challenges[i]}, row) .output; row += div_component::rows_amount; @@ -213,7 +213,7 @@ namespace nil { row += b_poly_coeff_component::rows_amount; for (std::size_t k = 0; k < s.size(); k++) { - s[k] = zk::components::generate_circuit(bp, assignment, {s[k], rs[j]}, row) + s[k] = ::nil::blueprint::components::generate_circuit(bp, assignment, {s[k], rs[j]}, row) .output; row += mul_component::rows_amount; @@ -227,7 +227,7 @@ namespace nil { j < KimchiCommitmentParamsType::srs_len + kimchi_constants::srs_padding_size(); j++) { - scalars[j] = zk::components::generate_circuit(bp, assignment, {scalars[i], termss[i][j]}, row).output; + scalars[j] = ::nil::blueprint::components::generate_circuit(bp, assignment, {scalars[i], termss[i][j]}, row).output; row += sub_component::rows_amount; } } diff --git a/include/nil/blueprint/components/systems/snark/plonk/kimchi/scalar_details/derive_plonk.hpp b/include/nil/blueprint/components/systems/snark/plonk/kimchi/scalar_details/derive_plonk.hpp index 2a1fcad04..8b6ed6e5e 100644 --- a/include/nil/blueprint/components/systems/snark/plonk/kimchi/scalar_details/derive_plonk.hpp +++ b/include/nil/blueprint/components/systems/snark/plonk/kimchi/scalar_details/derive_plonk.hpp @@ -29,20 +29,20 @@ #include -#include -#include +#include +#include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include -#include +#include -#include +#include namespace nil { namespace crypto3 { diff --git a/include/nil/blueprint/components/systems/snark/plonk/kimchi/scalar_details/evals_of_split_evals.hpp b/include/nil/blueprint/components/systems/snark/plonk/kimchi/scalar_details/evals_of_split_evals.hpp index 920150566..1d317fc4c 100644 --- a/include/nil/blueprint/components/systems/snark/plonk/kimchi/scalar_details/evals_of_split_evals.hpp +++ b/include/nil/blueprint/components/systems/snark/plonk/kimchi/scalar_details/evals_of_split_evals.hpp @@ -29,15 +29,15 @@ #include -#include -#include +#include +#include -#include -#include -#include -#include +#include +#include +#include +#include -#include +#include namespace nil { namespace crypto3 { @@ -151,40 +151,40 @@ namespace nil { row += combined_proof_evals_component::rows_amount; for (std::size_t k = 0; k < evals_acc.w.size(); k++) { - evals_acc.w[k] = zk::components::generate_circuit(bp, assignment, {evals_acc.w[k], params.split_evals[j].w[k]}, row).output; + evals_acc.w[k] = ::nil::blueprint::components::generate_circuit(bp, assignment, {evals_acc.w[k], params.split_evals[j].w[k]}, row).output; row += add_component::rows_amount; } - evals_acc.z = zk::components::generate_circuit(bp, assignment, {evals_acc.z, params.split_evals[j].z}, row).output; + evals_acc.z = ::nil::blueprint::components::generate_circuit(bp, assignment, {evals_acc.z, params.split_evals[j].z}, row).output; row += add_component::rows_amount; for (std::size_t k = 0; k < evals_acc.s.size(); k++) { - evals_acc.s[k] = zk::components::generate_circuit(bp, assignment, {evals_acc.s[k], params.split_evals[j].s[k]}, row).output; + evals_acc.s[k] = ::nil::blueprint::components::generate_circuit(bp, assignment, {evals_acc.s[k], params.split_evals[j].s[k]}, row).output; row += add_component::rows_amount; } if (KimchiParamsType::circuit_params::lookup_columns > 0) { for (std::size_t k = 0; k < evals_acc.lookup.sorted.size(); k++) { - evals_acc.lookup.sorted[k] = zk::components::generate_circuit(bp, assignment, {evals_acc.lookup.sorted[k], params.split_evals[j].lookup.sorted[k]}, row).output; + evals_acc.lookup.sorted[k] = ::nil::blueprint::components::generate_circuit(bp, assignment, {evals_acc.lookup.sorted[k], params.split_evals[j].lookup.sorted[k]}, row).output; row += add_component::rows_amount; } - evals_acc.lookup.aggreg = zk::components::generate_circuit(bp, assignment, {evals_acc.lookup.aggreg, params.split_evals[j].lookup.aggreg}, row).output; + evals_acc.lookup.aggreg = ::nil::blueprint::components::generate_circuit(bp, assignment, {evals_acc.lookup.aggreg, params.split_evals[j].lookup.aggreg}, row).output; row += add_component::rows_amount; - evals_acc.lookup.table = zk::components::generate_circuit(bp, assignment, {evals_acc.lookup.table, params.split_evals[j].lookup.table}, row).output; + evals_acc.lookup.table = ::nil::blueprint::components::generate_circuit(bp, assignment, {evals_acc.lookup.table, params.split_evals[j].lookup.table}, row).output; row += add_component::rows_amount; if (KimchiParamsType::circuit_params::lookup_runtime) { - evals_acc.lookup.runtime = zk::components::generate_circuit(bp, assignment, {evals_acc.lookup.runtime, params.split_evals[j].lookup.runtime}, row).output; + evals_acc.lookup.runtime = ::nil::blueprint::components::generate_circuit(bp, assignment, {evals_acc.lookup.runtime, params.split_evals[j].lookup.runtime}, row).output; row += add_component::rows_amount; } } - evals_acc.generic_selector = zk::components::generate_circuit(bp, assignment, {evals_acc.generic_selector, params.split_evals[j].generic_selector}, row).output; + evals_acc.generic_selector = ::nil::blueprint::components::generate_circuit(bp, assignment, {evals_acc.generic_selector, params.split_evals[j].generic_selector}, row).output; row += add_component::rows_amount; - evals_acc.poseidon_selector = zk::components::generate_circuit(bp, assignment, {evals_acc.poseidon_selector, params.split_evals[j].poseidon_selector}, row).output; + evals_acc.poseidon_selector = ::nil::blueprint::components::generate_circuit(bp, assignment, {evals_acc.poseidon_selector, params.split_evals[j].poseidon_selector}, row).output; row += add_component::rows_amount; } } diff --git a/include/nil/blueprint/components/systems/snark/plonk/kimchi/scalar_details/plonk_map_fields.hpp b/include/nil/blueprint/components/systems/snark/plonk/kimchi/scalar_details/plonk_map_fields.hpp index 320d1d18e..403d1f224 100644 --- a/include/nil/blueprint/components/systems/snark/plonk/kimchi/scalar_details/plonk_map_fields.hpp +++ b/include/nil/blueprint/components/systems/snark/plonk/kimchi/scalar_details/plonk_map_fields.hpp @@ -29,10 +29,10 @@ #include -#include -#include +#include +#include -#include +#include namespace nil { namespace crypto3 { diff --git a/include/nil/blueprint/components/systems/snark/plonk/kimchi/scalar_details/prepare_scalars_inversion.hpp b/include/nil/blueprint/components/systems/snark/plonk/kimchi/scalar_details/prepare_scalars_inversion.hpp index b0c90b593..cc5f65975 100644 --- a/include/nil/blueprint/components/systems/snark/plonk/kimchi/scalar_details/prepare_scalars_inversion.hpp +++ b/include/nil/blueprint/components/systems/snark/plonk/kimchi/scalar_details/prepare_scalars_inversion.hpp @@ -27,11 +27,11 @@ #include -#include -#include +#include +#include -#include -#include +#include +#include namespace nil { namespace crypto3 { @@ -101,12 +101,12 @@ namespace nil { result_type result; for (std::size_t i = 0; i < InputSize; ++i) { - shifted[i] = zk::components::generate_circuit( + shifted[i] = ::nil::blueprint::components::generate_circuit( bp, assignment, {params.scalars[i], shift}, row) .output; row += add_component::rows_amount; result.output[i] = - zk::components::generate_circuit(bp, assignment, {shifted[i], coef}, row) + ::nil::blueprint::components::generate_circuit(bp, assignment, {shifted[i], coef}, row) .output; row += mul_component::rows_amount; } diff --git a/include/nil/blueprint/components/systems/snark/plonk/kimchi/types/alpha_argument_type.hpp b/include/nil/blueprint/components/systems/snark/plonk/kimchi/types/alpha_argument_type.hpp index 2932a5863..233162397 100644 --- a/include/nil/blueprint/components/systems/snark/plonk/kimchi/types/alpha_argument_type.hpp +++ b/include/nil/blueprint/components/systems/snark/plonk/kimchi/types/alpha_argument_type.hpp @@ -29,18 +29,16 @@ #include namespace nil { - namespace crypto3 { - namespace blueprint { - namespace components { - enum argument_type { - Permutation, - Generic, - Zero, - Lookup, - }; - } // namespace components - } // namespace blueprint - } // namespace crypto3 + namespace blueprint { + namespace components { + enum argument_type { + Permutation, + Generic, + Zero, + Lookup, + }; + } // namespace components + } // namespace blueprint } // namespace nil #endif // CRYPTO3_BLUEPRINT_COMPONENTS_PLONK_KIMCHI_TYPES_ALPHA_ARGUMENT_TYPE_HPP \ No newline at end of file diff --git a/include/nil/blueprint/components/systems/snark/plonk/kimchi/types/commitment.hpp b/include/nil/blueprint/components/systems/snark/plonk/kimchi/types/commitment.hpp index 7aa9ab249..5ff2b77bc 100644 --- a/include/nil/blueprint/components/systems/snark/plonk/kimchi/types/commitment.hpp +++ b/include/nil/blueprint/components/systems/snark/plonk/kimchi/types/commitment.hpp @@ -36,18 +36,16 @@ #include namespace nil { - namespace crypto3 { - namespace blueprint { - namespace components { - - template - struct kimchi_commitment_type { - using var_ec_point = typename zk::components::var_ec_point; - std::array parts; - }; - } // namespace components - } // namespace blueprint - } // namespace crypto3 + namespace blueprint { + namespace components { + + template + struct kimchi_commitment_type { + using var_ec_point = typename components::var_ec_point; + std::array parts; + }; + } // namespace components + } // namespace blueprint } // namespace nil #endif // CRYPTO3_BLUEPRINT_COMPONENTS_PLONK_KIMCHI_DETAIL_COMMITMENT_HPP \ No newline at end of file diff --git a/include/nil/blueprint/components/systems/snark/plonk/kimchi/types/evaluation_proof.hpp b/include/nil/blueprint/components/systems/snark/plonk/kimchi/types/evaluation_proof.hpp index 2c8e7c76a..fe696baf0 100644 --- a/include/nil/blueprint/components/systems/snark/plonk/kimchi/types/evaluation_proof.hpp +++ b/include/nil/blueprint/components/systems/snark/plonk/kimchi/types/evaluation_proof.hpp @@ -33,48 +33,44 @@ #include namespace nil { - namespace crypto3 { - namespace blueprint { - namespace components { + namespace blueprint { + namespace components { - template - struct kimchi_lookup_evaluations { - using var = snark::plonk_variable; + template + struct kimchi_lookup_evaluations { + kimchi_lookup_evaluations() = default; - std::array sorted; + using var = crypto3::zk::snark::plonk_variable; - var aggreg; - var table; + std::array sorted; - var runtime; + var aggreg; + var table; - kimchi_lookup_evaluations() { - } - }; + var runtime; + }; - template - struct kimchi_proof_evaluations { - using var = snark::plonk_variable; - // witness polynomials - std::array w; - // permutation polynomial - var z; - // permutation polynomials - // (PERMUTS-1 evaluations because the last permutation is only used in commitment form) - std::array s; - // /// lookup-related evaluations - kimchi_lookup_evaluations lookup; - // /// evaluation of the generic selector polynomial - var generic_selector; - // /// evaluation of the poseidon selector polynomial - var poseidon_selector; + template + struct kimchi_proof_evaluations { + kimchi_proof_evaluations() = default; - kimchi_proof_evaluations() { - } - }; - } // namespace components - } // namespace blueprint - } // namespace crypto3 + using var = crypto3::zk::snark::plonk_variable; + // witness polynomials + std::array w; + // permutation polynomial + var z; + // permutation polynomials + // (PERMUTS-1 evaluations because the last permutation is only used in commitment form) + std::array s; + // /// lookup-related evaluations + kimchi_lookup_evaluations lookup; + // /// evaluation of the generic selector polynomial + var generic_selector; + // /// evaluation of the poseidon selector polynomial + var poseidon_selector; + }; + } // namespace components + } // namespace blueprint } // namespace nil #endif // CRYPTO3_BLUEPRINT_COMPONENTS_PLONK_KIMCHI_TYPES_EVALUATION_PROOF_HPP \ No newline at end of file diff --git a/include/nil/blueprint/components/systems/snark/plonk/kimchi/types/index_term_type.hpp b/include/nil/blueprint/components/systems/snark/plonk/kimchi/types/index_term_type.hpp index 6749b8530..776c10c2f 100644 --- a/include/nil/blueprint/components/systems/snark/plonk/kimchi/types/index_term_type.hpp +++ b/include/nil/blueprint/components/systems/snark/plonk/kimchi/types/index_term_type.hpp @@ -31,18 +31,16 @@ #include namespace nil { - namespace crypto3 { - namespace blueprint { - namespace components { - struct index_term_type { - const column_type type; - const std::size_t index; - const char *str_repr; - const std::size_t rows_amount; - }; - } // namespace components - } // namespace blueprint - } // namespace crypto3 + namespace blueprint { + namespace components { + struct index_term_type { + const column_type type; + const std::size_t index; + const char *str_repr; + const std::size_t rows_amount; + }; + } // namespace components + } // namespace blueprint } // namespace nil #endif // CRYPTO3_BLUEPRINT_COMPONENTS_PLONK_KIMCHI_DETAIL_CONSTRAINTS_INDEX_TERM_TYPE_HPP \ No newline at end of file diff --git a/include/nil/blueprint/components/systems/snark/plonk/kimchi/types/proof.hpp b/include/nil/blueprint/components/systems/snark/plonk/kimchi/types/proof.hpp index 1f7c7c184..e79cdfe53 100644 --- a/include/nil/blueprint/components/systems/snark/plonk/kimchi/types/proof.hpp +++ b/include/nil/blueprint/components/systems/snark/plonk/kimchi/types/proof.hpp @@ -44,126 +44,118 @@ #include namespace nil { - namespace crypto3 { - namespace blueprint { - namespace components { - - template - struct kimchi_opening_proof_scalar { - using var = snark::plonk_variable; - - var z1; - var z2; + namespace blueprint { + namespace components { + + template + struct kimchi_opening_proof_scalar { + using var = crypto3::zk::snark::plonk_variable; + + var z1; + var z2; + }; + + template + struct kimchi_proof_scalar { + using var = crypto3::zk::snark::plonk_variable; + + std::array, 2> proof_evals; + var ft_eval; + std::array public_input; + std::array, KimchiParamsType::prev_challenges_size> prev_challenges; + + kimchi_opening_proof_scalar opening; + }; + + template + struct batch_evaluation_proof_scalar { + using proof_binding = binding; + using var = crypto3::zk::snark::plonk_variable; + + var cip; + typename proof_binding::fq_sponge_output fq_output; + std::array eval_points; + // scaling factor for polynomials + var r; + // scaling factor for evaluation point powers + var xi; + + kimchi_opening_proof_scalar opening; + + using transcript_type = + kimchi_transcript_fr; + transcript_type transcript; + }; + + template + struct kimchi_opening_proof_base { + using var = crypto3::zk::snark::plonk_variable; + using var_ec_point = var_ec_point; + + std::array L; + std::array R; + var_ec_point delta; + var_ec_point G; + }; + + template + struct kimchi_proof_base { + using var = crypto3::zk::snark::plonk_variable; + using commitment_params_type = typename KimchiParamsType::commitment_params_type; + + using commitment_type = + kimchi_commitment_type; + + using opening_proof_type = + kimchi_opening_proof_base; + + using kimchi_constants = kimchi_inner_constants; + + struct commitments_type { + std::array witness; + commitment_type lookup_runtime; + commitment_type table; + std::vector lookup_sorted; + commitment_type lookup_agg; + commitment_type z; + commitment_type t; + std::array + prev_challenges; // to-do: get in the component from oracles }; - template - struct kimchi_proof_scalar { - using var = snark::plonk_variable; + commitments_type comm; + opening_proof_type o; + std::array scalars; + }; - std::array, 2> proof_evals; - var ft_eval; - std::array public_input; - std::array, KimchiParamsType::prev_challenges_size> prev_challenges; + template + struct batch_evaluation_proof_base { + using proof_binding = binding; + using var = crypto3::zk::snark::plonk_variable; - kimchi_opening_proof_scalar opening; - }; + using commitment_type = + kimchi_commitment_type; - template - struct batch_evaluation_proof_scalar { - using proof_binding = - typename zk::components::binding; - using var = snark::plonk_variable; - - var cip; - typename proof_binding::fq_sponge_output fq_output; - std::array eval_points; - // scaling factor for polynomials - var r; - // scaling factor for evaluation point powers - var xi; - - kimchi_opening_proof_scalar opening; - - using transcript_type = - kimchi_transcript_fr; - transcript_type transcript; - }; + using opening_proof_type = + kimchi_opening_proof_base; - template - struct kimchi_opening_proof_base { - using var = snark::plonk_variable; - using var_ec_point = typename zk::components::var_ec_point; + using kimchi_constants = kimchi_inner_constants; - std::array L; - std::array R; - var_ec_point delta; - var_ec_point G; - }; - - template - struct kimchi_proof_base { - using var = snark::plonk_variable; - using commitment_params_type = typename KimchiParamsType::commitment_params_type; - - using commitment_type = typename zk::components::kimchi_commitment_type< - BlueprintFieldType, commitment_params_type::shifted_commitment_split>; - - using opening_proof_type = - typename zk::components::kimchi_opening_proof_base; - - using kimchi_constants = zk::components::kimchi_inner_constants; - - struct commitments_type { - std::array witness; - commitment_type lookup_runtime; - commitment_type table; - std::vector lookup_sorted; - commitment_type lookup_agg; - commitment_type z; - commitment_type t; - std::array - prev_challenges; // to-do: get in the component from oracles - }; - - commitments_type comm; - opening_proof_type o; - std::array scalars; - }; + using transcript_type = kimchi_transcript_fq; - template - struct batch_evaluation_proof_base { - using proof_binding = - typename zk::components::binding; - using var = snark::plonk_variable; + // typename proof_binding::fq_sponge_output fq_output; + std::array comm; + opening_proof_type opening_proof; - using commitment_type = typename zk::components::kimchi_commitment_type< - BlueprintFieldType, KimchiCommitmentParamsType::shifted_commitment_split>; - - using opening_proof_type = - typename zk::components::kimchi_opening_proof_base; - - using kimchi_constants = zk::components::kimchi_inner_constants; - - using transcript_type = - typename zk::components::kimchi_transcript_fq; - - // typename proof_binding::fq_sponge_output fq_output; - std::array comm; - opening_proof_type opening_proof; - - transcript_type transcript; - }; - } // namespace components - } // namespace blueprint - } // namespace crypto3 + transcript_type transcript; + }; + } // namespace components + } // namespace blueprint } // namespace nil #endif // CRYPTO3_BLUEPRINT_COMPONENTS_PLONK_KIMCHI_PROOF_HPP \ No newline at end of file diff --git a/include/nil/blueprint/components/systems/snark/plonk/kimchi/types/verifier_index.hpp b/include/nil/blueprint/components/systems/snark/plonk/kimchi/types/verifier_index.hpp index 04801d632..0aa74f40d 100644 --- a/include/nil/blueprint/components/systems/snark/plonk/kimchi/types/verifier_index.hpp +++ b/include/nil/blueprint/components/systems/snark/plonk/kimchi/types/verifier_index.hpp @@ -39,62 +39,60 @@ #include namespace nil { - namespace crypto3 { - namespace blueprint { - namespace components { - typedef std::array kimchi_scalar_limbs; - - template - struct kimchi_verifier_index_scalar { - using var = snark::plonk_variable; - - // nil::crypto3::math::evaluation_domain domain; - std::size_t max_quot_size; - std::size_t domain_size; - std::array shift; - - var omega; + namespace blueprint { + namespace components { + typedef std::array kimchi_scalar_limbs; + + template + struct kimchi_verifier_index_scalar { + using var = crypto3::zk::snark::plonk_variable; + + // nil::crypto3::math::evaluation_domain domain; + std::size_t max_quot_size; + std::size_t domain_size; + std::array shift; + + var omega; + }; + + template + struct kimchi_verifier_index_base { + using FieldType = typename CurveType::base_field_type; + using commitment_params_type = typename KimchiParamsType::commitment_params_type; + + using commitment_type = + kimchi_commitment_type; + + using var = crypto3::zk::snark::plonk_variable; + using var_ec_point = var_ec_point; + + static constexpr const std::size_t chacha_size = 4; + static constexpr const std::size_t range_check_size = 2; + + struct commitments_type { + std::array sigma; + std::array coefficient; + commitment_type generic; + commitment_type psm; + std::vector selectors; + std::vector lookup_selectors; + commitment_type runtime_tables_selector; + std::vector lookup_table; + commitment_type complete_add; + commitment_type var_base_mul; + commitment_type endo_mul; + commitment_type endo_mul_scalar; + std::array chacha; + std::array range_check; }; - template - struct kimchi_verifier_index_base { - using FieldType = typename CurveType::base_field_type; - using commitment_params_type = typename KimchiParamsType::commitment_params_type; - - using commitment_type = typename zk::components::kimchi_commitment_type< - FieldType, commitment_params_type::shifted_commitment_split>; - - using var = snark::plonk_variable; - using var_ec_point = typename zk::components::var_ec_point; - - static constexpr const std::size_t chacha_size = 4; - static constexpr const std::size_t range_check_size = 2; - - struct commitments_type { - std::array sigma; - std::array coefficient; - commitment_type generic; - commitment_type psm; - std::vector selectors; - std::vector lookup_selectors; - commitment_type runtime_tables_selector; - std::vector lookup_table; - commitment_type complete_add; - commitment_type var_base_mul; - commitment_type endo_mul; - commitment_type endo_mul_scalar; - std::array chacha; - std::array range_check; - }; - - var_ec_point H; - std::array G; - std::array lagrange_bases; - commitments_type comm; - }; - } // namespace components - } // namespace blueprint - } // namespace crypto3 + var_ec_point H; + std::array G; + std::array lagrange_bases; + commitments_type comm; + }; + } // namespace components + } // namespace blueprint } // namespace nil #endif // CRYPTO3_BLUEPRINT_COMPONENTS_PLONK_KIMCHI_VERIFIER_INDEX_HPP \ No newline at end of file diff --git a/include/nil/blueprint/components/systems/snark/plonk/kimchi/verifier_base_field.hpp b/include/nil/blueprint/components/systems/snark/plonk/kimchi/verifier_base_field.hpp index bb3120ef8..bb523ad92 100644 --- a/include/nil/blueprint/components/systems/snark/plonk/kimchi/verifier_base_field.hpp +++ b/include/nil/blueprint/components/systems/snark/plonk/kimchi/verifier_base_field.hpp @@ -30,7 +30,8 @@ #include #include #include -#include +#include +#include #include #include #include @@ -39,833 +40,810 @@ #include #include #include +#include #include #include namespace nil { - namespace crypto3 { - namespace blueprint { - namespace components { - - // base field part of batch_verify - // https://github.com/o1-labs/proof-systems/blob/1f8532ec1b8d43748a372632bd854be36b371afe/kimchi/src/verifier.rs#L911 - // Input: list of mina-proofs (base field part), - // precalculated fq_data and fr_data (the data that used both by scalar and base verifiers) - // verifier index (public data) - // Output: - - template - class base_field; - - template - class base_field, CurveType, - KimchiParamsType, KimchiCommitmentParamsType, BatchSize, W0, W1, W2, W3, W4, W5, W6, - W7, W8, W9, W10, W11, W12, W13, W14> { - - typedef crypto3::zk::snark::plonk_constraint_system - ArithmetizationType; - - using var = crypto3::zk::snark::plonk_variable; - using var_ec_point = typename zk::components::var_ec_point; - using sub_component = zk::components::subtraction; - using mul_component = zk::components::multiplication; - using const_mul_component = zk::components::mul_by_constant; - using table_comm_component = - zk::components::table_commitment; - - using proof_type = kimchi_proof_base; - using kimchi_constants = zk::components::kimchi_inner_constants; - - constexpr static const std::size_t f_comm_base_size = kimchi_constants::f_comm_msm_size; - - using msm_component = - zk::components::element_g1_multi_scalar_mul; - using lagrange_msm_component = - zk::components::element_g1_multi_scalar_mul; - - using scalar_mul_component = - zk::components::curve_element_variable_base_scalar_mul; - using add_component = - zk::components::curve_element_unified_addition; - - using proof_binding = - typename zk::components::binding; - - using map_fq_component = zk::components::map_fq; - - using batch_proof_type = typename zk::components::batch_evaluation_proof_base< - BlueprintFieldType, ArithmetizationType, KimchiParamsType, KimchiCommitmentParamsType>; - - using verifier_index_type = kimchi_verifier_index_base; - - using index_terms_list = typename KimchiParamsType::circuit_params::index_terms_list; - - using commitment_type = typename zk::components::kimchi_commitment_type< - BlueprintFieldType, KimchiCommitmentParamsType::shifted_commitment_split>; - - using batch_verify_component = - zk::components::batch_verify_base_field; - - using transcript_type = kimchi_transcript_fq; - - constexpr static const std::size_t selector_seed = 0xff91; - - constexpr static const std::size_t rows() { - std::size_t row = 0; - - row++; - - for (std::size_t i = 0; i < BatchSize; i++) { - row = row + lagrange_msm_component::rows_amount; - - // Oracles - row += transcript_type::init_rows; + namespace blueprint { + namespace components { - row += transcript_type::absorb_group_rows; + // base field part of batch_verify + // https://github.com/o1-labs/proof-systems/blob/1f8532ec1b8d43748a372632bd854be36b371afe/kimchi/src/verifier.rs#L911 + // Input: list of mina-proofs (base field part), + // precalculated fq_data and fr_data (the data that used both by scalar and base verifiers) + // verifier index (public data) + // Output: - + template + class base_field; - row += KimchiParamsType::circuit_params::witness_columns * - KimchiParamsType::witness_commitment_size * transcript_type::absorb_group_rows; + template + class base_field, CurveType, + KimchiParamsType, KimchiCommitmentParamsType, BatchSize, W0, W1, W2, W3, W4, W5, W6, W7, + W8, W9, W10, W11, W12, W13, W14> { - if (KimchiParamsType::circuit_params::use_lookup) { - if (KimchiParamsType::circuit_params::lookup_runtime) { - row += KimchiParamsType::lookup_runtime_commitment_size * - transcript_type::absorb_group_rows; - } + typedef crypto3::zk::snark::plonk_constraint_system ArithmetizationType; - if (KimchiParamsType::circuit_params::joint_lookup) { - row += transcript_type::challenge_rows; - } + using var = crypto3::zk::snark::plonk_variable; + using var_ec_point = var_ec_point; + using sub_component = + subtraction>; + using mul_component = multiplication>; + using const_mul_component = mul_by_constant; + using table_comm_component = table_commitment; - row += KimchiParamsType::circuit_params::lookup_columns * - KimchiParamsType::lookup_sorted_commitment_size * - transcript_type::absorb_group_rows; - } + using proof_type = kimchi_proof_base; + using kimchi_constants = kimchi_inner_constants; - row += transcript_type::challenge_rows; - row += transcript_type::challenge_rows; + constexpr static const std::size_t f_comm_base_size = kimchi_constants::f_comm_msm_size; - if (KimchiParamsType::circuit_params::use_lookup) { - row += KimchiParamsType::lookup_aggregated_commitment_size * - transcript_type::absorb_group_rows; - } + using msm_component = + element_g1_multi_scalar_mul; + using lagrange_msm_component = + element_g1_multi_scalar_mul; - row += KimchiParamsType::z_commitment_size * transcript_type::absorb_group_rows; + using scalar_mul_component = curve_element_variable_base_scalar_mul; + using add_component = unified_addition; - row += transcript_type::challenge_rows; + using proof_binding = binding; - row += KimchiParamsType::t_commitment_size * transcript_type::absorb_group_rows; + using map_fq_component = + map_fq; - row += transcript_type::challenge_rows; + using batch_proof_type = batch_evaluation_proof_base; - row += transcript_type::digest_rows; + using verifier_index_type = kimchi_verifier_index_base; - // Oracles end + using index_terms_list = typename KimchiParamsType::circuit_params::index_terms_list; - for (std::size_t j = 0; j < KimchiCommitmentParamsType::max_comm_size; j++) { - row += msm_component::rows_amount; - } + using commitment_type = + kimchi_commitment_type; + + using batch_verify_component = + batch_verify_base_field; + + using transcript_type = kimchi_transcript_fq; + + constexpr static const std::size_t selector_seed = 0xff91; + + constexpr static const std::size_t rows() { + std::size_t row = 0; - for (std::size_t j = 0; j < KimchiCommitmentParamsType::max_comm_size; j++) { - row += scalar_mul_component::rows_amount; - row += add_component::rows_amount; + row++; + + for (std::size_t i = 0; i < BatchSize; i++) { + row = row + lagrange_msm_component::rows_amount; + + // Oracles + row += transcript_type::init_rows; + + row += transcript_type::absorb_group_rows; + + row += KimchiParamsType::circuit_params::witness_columns * + KimchiParamsType::witness_commitment_size * transcript_type::absorb_group_rows; + + if (KimchiParamsType::circuit_params::use_lookup) { + if (KimchiParamsType::circuit_params::lookup_runtime) { + row += KimchiParamsType::lookup_runtime_commitment_size * + transcript_type::absorb_group_rows; } - for (std::size_t j = 0; j < KimchiParamsType::t_commitment_size; j++) { - row += scalar_mul_component::rows_amount; - row += add_component::rows_amount; + if (KimchiParamsType::circuit_params::joint_lookup) { + row += transcript_type::challenge_rows; } - row += scalar_mul_component::rows_amount; - row += const_mul_component::rows_amount; - row += add_component::rows_amount; + row += KimchiParamsType::circuit_params::lookup_columns * + KimchiParamsType::lookup_sorted_commitment_size * transcript_type::absorb_group_rows; + } - if (KimchiParamsType::circuit_params::use_lookup) { - row += table_comm_component::rows_amount; - } + row += transcript_type::challenge_rows; + row += transcript_type::challenge_rows; + + if (KimchiParamsType::circuit_params::use_lookup) { + row += KimchiParamsType::lookup_aggregated_commitment_size * + transcript_type::absorb_group_rows; } - row += batch_verify_component::rows_amount; + row += KimchiParamsType::z_commitment_size * transcript_type::absorb_group_rows; - row += map_fq_component::rows_amount; + row += transcript_type::challenge_rows; - return row; - } + row += KimchiParamsType::t_commitment_size * transcript_type::absorb_group_rows; - public: - constexpr static const std::size_t rows_amount = rows(); + row += transcript_type::challenge_rows; - constexpr static const std::size_t gates_amount = 0; + row += transcript_type::digest_rows; - struct params_type { - std::array proofs; - verifier_index_type verifier_index; + // Oracles end - typename proof_binding::template fr_data fr_data; - typename proof_binding::template fq_data fq_data; - }; + for (std::size_t j = 0; j < KimchiCommitmentParamsType::max_comm_size; j++) { + row += msm_component::rows_amount; + } - struct result_type { + for (std::size_t j = 0; j < KimchiCommitmentParamsType::max_comm_size; j++) { + row += scalar_mul_component::rows_amount; + row += add_component::rows_amount; + } - result_type(std::size_t start_row_index) { + for (std::size_t j = 0; j < KimchiParamsType::t_commitment_size; j++) { + row += scalar_mul_component::rows_amount; + row += add_component::rows_amount; } - }; + row += scalar_mul_component::rows_amount; + row += const_mul_component::rows_amount; - private: - template - static void parse_commitments( - std::array, f_comm_base_size> &unshifted_commitments, - CommitmentType comm, - std::size_t &comm_idx) { + row += add_component::rows_amount; - for (std::size_t k = 0; k < comm.parts.size(); k++) { - unshifted_commitments[comm_idx].push_back(comm.parts[k]); + if (KimchiParamsType::circuit_params::use_lookup) { + row += table_comm_component::rows_amount; } - comm_idx++; } - static std::array, f_comm_base_size> - prepare_f_comm(const params_type ¶ms, std::size_t batch_idx) { - - std::array, f_comm_base_size> unshifted_commitments; - std::size_t comm_idx = 0; - - typename proof_type::commitments_type comm = params.proofs[batch_idx].comm; - typename verifier_index_type::commitments_type index_comm = params.verifier_index.comm; - - parse_commitments(unshifted_commitments, - params.verifier_index.comm.sigma[KimchiParamsType::permut_size - 1], - comm_idx); - - // take generic_size coeff_comm - std::array generic_comm; - for (std::size_t i = 0; i < generic_comm.size(); i++) { - generic_comm[i] = params.verifier_index.comm.coefficient[i]; - } - - for (std::size_t i = 0; i < kimchi_constants::ft_generic_size; i++) { - parse_commitments(unshifted_commitments, generic_comm[i], comm_idx); - } - - for (std::size_t i = 0; i < index_terms_list::size; i++) { - index_term_type term = index_terms_list::terms[i]; - switch (term.type) { - case column_type::Witness: - parse_commitments(unshifted_commitments, comm.witness[term.index], comm_idx); - break; - case column_type::Coefficient: - parse_commitments(unshifted_commitments, index_comm.coefficient[term.index], - comm_idx); - break; - case column_type::Z: - parse_commitments(unshifted_commitments, comm.z, comm_idx); - break; - case column_type::LookupSorted: - parse_commitments(unshifted_commitments, comm.lookup_sorted[term.index], comm_idx); - break; - case column_type::LookupAggreg: { - parse_commitments(unshifted_commitments, comm.lookup_agg, comm_idx); - break; - } - case column_type::LookupKindIndex: { - parse_commitments(unshifted_commitments, index_comm.lookup_selectors[term.index], - comm_idx); - break; - } - case column_type::LookupRuntimeSelector: { - parse_commitments(unshifted_commitments, index_comm.runtime_tables_selector, - comm_idx); - break; - } - case column_type::CompleteAdd: { - parse_commitments(unshifted_commitments, index_comm.complete_add, comm_idx); - break; - } - case column_type::VarBaseMul: { - parse_commitments(unshifted_commitments, index_comm.var_base_mul, comm_idx); - break; - } - case column_type::EndoMul: { - parse_commitments(unshifted_commitments, index_comm.endo_mul, comm_idx); - break; - } - case column_type::EndoMulScalar: { - parse_commitments(unshifted_commitments, index_comm.endo_mul_scalar, comm_idx); - break; - } - case column_type::Poseidon: { - parse_commitments(unshifted_commitments, index_comm.psm, comm_idx); - break; - } - case column_type::ChaCha0: { - parse_commitments(unshifted_commitments, index_comm.chacha[0], comm_idx); - break; - } - case column_type::ChaCha1: { - parse_commitments(unshifted_commitments, index_comm.chacha[1], comm_idx); - break; - } - case column_type::ChaCha2: { - parse_commitments(unshifted_commitments, index_comm.chacha[2], comm_idx); - break; - } - case column_type::ChaChaFinal: { - parse_commitments(unshifted_commitments, index_comm.chacha[3], comm_idx); - break; - } - case column_type::RangeCheck0: { - parse_commitments(unshifted_commitments, index_comm.range_check[0], comm_idx); - break; - } - case column_type::RangeCheck1: { - parse_commitments(unshifted_commitments, index_comm.range_check[1], comm_idx); - break; - } - case column_type::LookupTable: - break; - case column_type::LookupRuntimeTable: - break; - } - } + row += batch_verify_component::rows_amount; + + row += map_fq_component::rows_amount; - assert(comm_idx == f_comm_base_size); + return row; + } - return unshifted_commitments; + public: + constexpr static const std::size_t rows_amount = rows(); + + constexpr static const std::size_t gates_amount = 0; + + struct params_type { + std::array proofs; + verifier_index_type verifier_index; + + typename proof_binding::template fr_data fr_data; + typename proof_binding::template fq_data fq_data; + }; + + struct result_type { + + result_type(std::size_t start_row_index) { } + }; - public: - static result_type generate_assignments(blueprint_assignment_table &assignment, - const params_type ¶ms, - std::size_t start_row_index) { - std::size_t row = start_row_index; - std::array batch_proofs; - var zero(0, row, false, var::column_type::constant); - row++; - - for (std::size_t i = 0; i < BatchSize; i++) { - - // p_comm is always the commitment of size 1 - auto p_comm_unshifted = - lagrange_msm_component::generate_assignments( - assignment, {params.fr_data.neg_pub, params.verifier_index.lagrange_bases}, row) - .output; - row = row + lagrange_msm_component::rows_amount; + private: + template + static void + parse_commitments(std::array, f_comm_base_size> &unshifted_commitments, + CommitmentType comm, + std::size_t &comm_idx) { - // Oracles - transcript_type transcript; - transcript.init_assignment(assignment, zero, row); - row += transcript_type::init_rows; + for (std::size_t k = 0; k < comm.parts.size(); k++) { + unshifted_commitments[comm_idx].push_back(comm.parts[k]); + } + comm_idx++; + } - transcript.absorb_g_assignment(assignment, p_comm_unshifted, row); - row += transcript_type::absorb_group_rows; + static std::array, f_comm_base_size> prepare_f_comm(const params_type ¶ms, + std::size_t batch_idx) { - for (std::size_t j = 0; j < params.proofs[i].comm.witness.size(); j++) { - for (std::size_t k = 0; k < params.proofs[i].comm.witness[j].parts.size(); k++) { - transcript.absorb_g_assignment(assignment, - params.proofs[i].comm.witness[j].parts[k], row); - row += transcript_type::absorb_group_rows; - } - } + std::array, f_comm_base_size> unshifted_commitments; + std::size_t comm_idx = 0; - var joint_combiner; + typename proof_type::commitments_type comm = params.proofs[batch_idx].comm; + typename verifier_index_type::commitments_type index_comm = params.verifier_index.comm; - if (KimchiParamsType::circuit_params::use_lookup) { - if (KimchiParamsType::circuit_params::lookup_runtime) { - for (std::size_t k = 0; k < params.proofs[i].comm.lookup_runtime.parts.size(); - k++) { - transcript.absorb_g_assignment( - assignment, params.proofs[i].comm.lookup_runtime.parts[k], row); - row += transcript_type::absorb_group_rows; - } - } + parse_commitments(unshifted_commitments, + params.verifier_index.comm.sigma[KimchiParamsType::permut_size - 1], + comm_idx); - if (KimchiParamsType::circuit_params::joint_lookup) { - joint_combiner = transcript.challenge_assignment(assignment, row); - row += transcript_type::challenge_rows; - } else { - joint_combiner = zero; - } + // take generic_size coeff_comm + std::array generic_comm; + for (std::size_t i = 0; i < generic_comm.size(); i++) { + generic_comm[i] = params.verifier_index.comm.coefficient[i]; + } - for (std::size_t j = 0; j < params.proofs[i].comm.lookup_sorted.size(); j++) { - for (std::size_t k = 0; k < params.proofs[i].comm.lookup_sorted[j].parts.size(); - k++) { - transcript.absorb_g_assignment( - assignment, params.proofs[i].comm.lookup_sorted[j].parts[k], row); - row += transcript_type::absorb_group_rows; - } - } - } + for (std::size_t i = 0; i < kimchi_constants::ft_generic_size; i++) { + parse_commitments(unshifted_commitments, generic_comm[i], comm_idx); + } - var beta = transcript.challenge_assignment(assignment, row); - row += transcript_type::challenge_rows; + for (std::size_t i = 0; i < index_terms_list::size; i++) { + index_term_type term = index_terms_list::terms[i]; + switch (term.type) { + case column_type::Witness: + parse_commitments(unshifted_commitments, comm.witness[term.index], comm_idx); + break; + case column_type::Coefficient: + parse_commitments(unshifted_commitments, index_comm.coefficient[term.index], comm_idx); + break; + case column_type::Z: + parse_commitments(unshifted_commitments, comm.z, comm_idx); + break; + case column_type::LookupSorted: + parse_commitments(unshifted_commitments, comm.lookup_sorted[term.index], comm_idx); + break; + case column_type::LookupAggreg: { + parse_commitments(unshifted_commitments, comm.lookup_agg, comm_idx); + break; + } + case column_type::LookupKindIndex: { + parse_commitments(unshifted_commitments, index_comm.lookup_selectors[term.index], + comm_idx); + break; + } + case column_type::LookupRuntimeSelector: { + parse_commitments(unshifted_commitments, index_comm.runtime_tables_selector, comm_idx); + break; + } + case column_type::CompleteAdd: { + parse_commitments(unshifted_commitments, index_comm.complete_add, comm_idx); + break; + } + case column_type::VarBaseMul: { + parse_commitments(unshifted_commitments, index_comm.var_base_mul, comm_idx); + break; + } + case column_type::EndoMul: { + parse_commitments(unshifted_commitments, index_comm.endo_mul, comm_idx); + break; + } + case column_type::EndoMulScalar: { + parse_commitments(unshifted_commitments, index_comm.endo_mul_scalar, comm_idx); + break; + } + case column_type::Poseidon: { + parse_commitments(unshifted_commitments, index_comm.psm, comm_idx); + break; + } + case column_type::ChaCha0: { + parse_commitments(unshifted_commitments, index_comm.chacha[0], comm_idx); + break; + } + case column_type::ChaCha1: { + parse_commitments(unshifted_commitments, index_comm.chacha[1], comm_idx); + break; + } + case column_type::ChaCha2: { + parse_commitments(unshifted_commitments, index_comm.chacha[2], comm_idx); + break; + } + case column_type::ChaChaFinal: { + parse_commitments(unshifted_commitments, index_comm.chacha[3], comm_idx); + break; + } + case column_type::RangeCheck0: { + parse_commitments(unshifted_commitments, index_comm.range_check[0], comm_idx); + break; + } + case column_type::RangeCheck1: { + parse_commitments(unshifted_commitments, index_comm.range_check[1], comm_idx); + break; + } + case column_type::LookupTable: + break; + case column_type::LookupRuntimeTable: + break; + } + } - var gamma = transcript.challenge_assignment(assignment, row); - row += transcript_type::challenge_rows; + assert(comm_idx == f_comm_base_size); + + return unshifted_commitments; + } + + public: + static result_type generate_assignments(assignment &assignment, + const params_type ¶ms, + std::size_t start_row_index) { + std::size_t row = start_row_index; + std::array batch_proofs; + var zero(0, row, false, var::column_type::constant); + row++; + + for (std::size_t i = 0; i < BatchSize; i++) { + + // p_comm is always the commitment of size 1 + auto p_comm_unshifted = + lagrange_msm_component::generate_assignments( + assignment, {params.fr_data.neg_pub, params.verifier_index.lagrange_bases}, row) + .output; + row = row + lagrange_msm_component::rows_amount; + + // Oracles + transcript_type transcript; + transcript.init_assignment(assignment, zero, row); + row += transcript_type::init_rows; + + transcript.absorb_g_assignment(assignment, p_comm_unshifted, row); + row += transcript_type::absorb_group_rows; + + for (std::size_t j = 0; j < params.proofs[i].comm.witness.size(); j++) { + for (std::size_t k = 0; k < params.proofs[i].comm.witness[j].parts.size(); k++) { + transcript.absorb_g_assignment(assignment, params.proofs[i].comm.witness[j].parts[k], + row); + row += transcript_type::absorb_group_rows; + } + } + + var joint_combiner; - if (KimchiParamsType::circuit_params::use_lookup) { - for (std::size_t k = 0; k < params.proofs[i].comm.lookup_agg.parts.size(); k++) { + if (KimchiParamsType::circuit_params::use_lookup) { + if (KimchiParamsType::circuit_params::lookup_runtime) { + for (std::size_t k = 0; k < params.proofs[i].comm.lookup_runtime.parts.size(); k++) { transcript.absorb_g_assignment(assignment, - params.proofs[i].comm.lookup_agg.parts[k], row); + params.proofs[i].comm.lookup_runtime.parts[k], row); row += transcript_type::absorb_group_rows; } } - for (std::size_t k = 0; k < params.proofs[i].comm.z.parts.size(); k++) { - transcript.absorb_g_assignment(assignment, params.proofs[i].comm.z.parts[k], row); - row += transcript_type::absorb_group_rows; + if (KimchiParamsType::circuit_params::joint_lookup) { + joint_combiner = transcript.challenge_assignment(assignment, row); + row += transcript_type::challenge_rows; + } else { + joint_combiner = zero; } - var alpha = transcript.challenge_assignment(assignment, row); - row += transcript_type::challenge_rows; - - for (std::size_t k = 0; k < params.proofs[i].comm.t.parts.size(); k++) { - transcript.absorb_g_assignment(assignment, params.proofs[i].comm.t.parts[k], row); - row += transcript_type::absorb_group_rows; + for (std::size_t j = 0; j < params.proofs[i].comm.lookup_sorted.size(); j++) { + for (std::size_t k = 0; k < params.proofs[i].comm.lookup_sorted[j].parts.size(); k++) { + transcript.absorb_g_assignment( + assignment, params.proofs[i].comm.lookup_sorted[j].parts[k], row); + row += transcript_type::absorb_group_rows; + } } + } - var zeta = transcript.challenge_assignment(assignment, row); - row += transcript_type::challenge_rows; + var beta = transcript.challenge_assignment(assignment, row); + row += transcript_type::challenge_rows; - var digest = transcript.digest_assignment(assignment, row); - row += transcript_type::digest_rows; + var gamma = transcript.challenge_assignment(assignment, row); + row += transcript_type::challenge_rows; - // Oracles end + if (KimchiParamsType::circuit_params::use_lookup) { + for (std::size_t k = 0; k < params.proofs[i].comm.lookup_agg.parts.size(); k++) { + transcript.absorb_g_assignment(assignment, params.proofs[i].comm.lookup_agg.parts[k], + row); + row += transcript_type::absorb_group_rows; + } + } - // f_comm - std::array, f_comm_base_size> f_comm_bases = - prepare_f_comm(params, i); + for (std::size_t k = 0; k < params.proofs[i].comm.z.parts.size(); k++) { + transcript.absorb_g_assignment(assignment, params.proofs[i].comm.z.parts[k], row); + row += transcript_type::absorb_group_rows; + } - std::array f_comm; - for (std::size_t j = 0; j < KimchiCommitmentParamsType::max_comm_size; j++) { - std::array bases; - std::array scalars; - for (std::size_t k = 0; k < f_comm_base_size; k++) { - if (j < f_comm_bases[k].size()) { - bases[k] = f_comm_bases[k][j]; - scalars[k] = params.proofs[i].scalars[k]; - } else { - bases[k] = {zero, zero}; - scalars[k] = zero; - } - } - auto res = msm_component::generate_assignments(assignment, {scalars, bases}, row); - f_comm[j] = {res.output.X, res.output.Y}; - row += msm_component::rows_amount; - } - - // chuncked_f_comm - var_ec_point chuncked_f_comm = {zero, zero}; - - for (std::size_t j = 0; j < f_comm.size(); j++) { - auto res0 = scalar_mul_component::generate_assignments( - assignment, - {{chuncked_f_comm.X, chuncked_f_comm.Y}, params.fr_data.zeta_to_srs_len[i]}, row); - row += scalar_mul_component::rows_amount; - auto res1 = add_component::generate_assignments( - assignment, {{res0.X, res0.Y}, {f_comm[j].X, f_comm[j].Y}}, row); - row += add_component::rows_amount; - chuncked_f_comm = {res1.X, res1.Y}; - } - - // chunked_t_comm - var_ec_point chunked_t_comm = {zero, zero}; - ; - for (std::size_t j = 0; j < params.proofs[i].comm.t.parts.size(); j++) { - auto res0 = scalar_mul_component::generate_assignments( - assignment, - {{chunked_t_comm.X, chunked_t_comm.Y}, params.fr_data.zeta_to_srs_len[i]}, row); - row += scalar_mul_component::rows_amount; - - auto res1 = add_component::generate_assignments( - assignment, - {{res0.X, res0.Y}, - {params.proofs[i].comm.t.parts[j].X, params.proofs[i].comm.t.parts[j].Y}}, - row); - row += add_component::rows_amount; - chunked_t_comm = {res1.X, res1.Y}; - } - - // ft_comm - - auto scaled_t_comm = scalar_mul_component::generate_assignments( - assignment, - {{chunked_t_comm.X, chunked_t_comm.Y}, params.fr_data.zeta_to_domain_size_minus_1}, - row); - row += scalar_mul_component::rows_amount; + var alpha = transcript.challenge_assignment(assignment, row); + row += transcript_type::challenge_rows; - typename BlueprintFieldType::value_type minus_1 = -1; - var const_res_unshifted = - const_mul_component::generate_assignments(assignment, {scaled_t_comm.Y, minus_1}, row) - .output; - row += const_mul_component::rows_amount; + for (std::size_t k = 0; k < params.proofs[i].comm.t.parts.size(); k++) { + transcript.absorb_g_assignment(assignment, params.proofs[i].comm.t.parts[k], row); + row += transcript_type::absorb_group_rows; + } - var_ec_point neg_scaled_t_comm = {scaled_t_comm.X, const_res_unshifted}; + var zeta = transcript.challenge_assignment(assignment, row); + row += transcript_type::challenge_rows; - auto ft_comm_part = add_component::generate_assignments( - assignment, - {{neg_scaled_t_comm.X, neg_scaled_t_comm.Y}, {chuncked_f_comm.X, chuncked_f_comm.Y}}, - row); - row += add_component::rows_amount; - commitment_type ft_comm = {{{ft_comm_part.X, ft_comm_part.Y}}}; - for (std::size_t j = 1; - j < KimchiParamsType::commitment_params_type::shifted_commitment_split; - j++) { - ft_comm.parts[j] = {zero, zero}; - } - - // evaluations + var digest = transcript.digest_assignment(assignment, row); + row += transcript_type::digest_rows; - std::array evaluations; - std::size_t eval_idx = 0; + // Oracles end - for (auto chal : params.proofs[i].comm.prev_challenges) { - evaluations[eval_idx++] = chal; - } + // f_comm + std::array, f_comm_base_size> f_comm_bases = + prepare_f_comm(params, i); - commitment_type p_comm = {{{p_comm_unshifted.X, p_comm_unshifted.Y}}}; - for (std::size_t j = 1; - j < KimchiParamsType::commitment_params_type::shifted_commitment_split; - j++) { - ft_comm.parts[j] = {zero, zero}; + std::array f_comm; + for (std::size_t j = 0; j < KimchiCommitmentParamsType::max_comm_size; j++) { + std::array bases; + std::array scalars; + for (std::size_t k = 0; k < f_comm_base_size; k++) { + if (j < f_comm_bases[k].size()) { + bases[k] = f_comm_bases[k][j]; + scalars[k] = params.proofs[i].scalars[k]; + } else { + bases[k] = {zero, zero}; + scalars[k] = zero; + } } - evaluations[eval_idx++] = p_comm; - evaluations[eval_idx++] = ft_comm; - evaluations[eval_idx++] = params.proofs[i].comm.z; - evaluations[eval_idx++] = params.verifier_index.comm.generic; - evaluations[eval_idx++] = params.verifier_index.comm.psm; + auto res = msm_component::generate_assignments(assignment, {scalars, bases}, row); + f_comm[j] = {res.output.X, res.output.Y}; + row += msm_component::rows_amount; + } - for (std::size_t j = 0; j < params.proofs[i].comm.witness.size(); j++) { - evaluations[eval_idx++] = params.proofs[i].comm.witness[j]; - } - for (std::size_t j = 0; j < params.verifier_index.comm.sigma.size() - 1; j++) { - evaluations[eval_idx++] = params.verifier_index.comm.sigma[j]; - } + // chuncked_f_comm + var_ec_point chuncked_f_comm = {zero, zero}; - if (KimchiParamsType::circuit_params::use_lookup) { - for (std::size_t j = 0; j < params.proofs[i].comm.lookup_sorted.size(); j++) { - evaluations[eval_idx++] = params.proofs[i].comm.lookup_sorted[j]; - } + for (std::size_t j = 0; j < f_comm.size(); j++) { + auto res0 = scalar_mul_component::generate_assignments( + assignment, {{chuncked_f_comm.X, chuncked_f_comm.Y}, params.fr_data.zeta_to_srs_len[i]}, + row); + row += scalar_mul_component::rows_amount; + auto res1 = add_component::generate_assignments( + assignment, {{res0.X, res0.Y}, {f_comm[j].X, f_comm[j].Y}}, row); + row += add_component::rows_amount; + chuncked_f_comm = {res1.X, res1.Y}; + } - evaluations[eval_idx++] = params.proofs[i].comm.lookup_agg; + // chunked_t_comm + var_ec_point chunked_t_comm = {zero, zero}; + ; + for (std::size_t j = 0; j < params.proofs[i].comm.t.parts.size(); j++) { + auto res0 = scalar_mul_component::generate_assignments( + assignment, {{chunked_t_comm.X, chunked_t_comm.Y}, params.fr_data.zeta_to_srs_len[i]}, + row); + row += scalar_mul_component::rows_amount; - evaluations[eval_idx++] = table_comm_component::generate_assignments( - assignment, - {params.verifier_index.comm.lookup_table, params.fr_data.joint_combiner_powers_prepared, - params.proofs[i].comm.lookup_runtime}, - row) - .output; - row += table_comm_component::rows_amount; + auto res1 = add_component::generate_assignments( + assignment, + {{res0.X, res0.Y}, + {params.proofs[i].comm.t.parts[j].X, params.proofs[i].comm.t.parts[j].Y}}, + row); + row += add_component::rows_amount; + chunked_t_comm = {res1.X, res1.Y}; + } - if (KimchiParamsType::circuit_params::lookup_runtime) { - evaluations[eval_idx++] = params.proofs[i].comm.lookup_runtime; - } - } + // ft_comm + + auto scaled_t_comm = scalar_mul_component::generate_assignments( + assignment, + {{chunked_t_comm.X, chunked_t_comm.Y}, params.fr_data.zeta_to_domain_size_minus_1}, + row); + row += scalar_mul_component::rows_amount; + + typename BlueprintFieldType::value_type minus_1 = -1; + var const_res_unshifted = + const_mul_component::generate_assignments(assignment, {scaled_t_comm.Y, minus_1}, row) + .output; + row += const_mul_component::rows_amount; + + var_ec_point neg_scaled_t_comm = {scaled_t_comm.X, const_res_unshifted}; + + auto ft_comm_part = add_component::generate_assignments( + assignment, + {{neg_scaled_t_comm.X, neg_scaled_t_comm.Y}, {chuncked_f_comm.X, chuncked_f_comm.Y}}, + row); + row += add_component::rows_amount; + commitment_type ft_comm = {{{ft_comm_part.X, ft_comm_part.Y}}}; + for (std::size_t j = 1; j < KimchiParamsType::commitment_params_type::shifted_commitment_split; + j++) { + ft_comm.parts[j] = {zero, zero}; + } - assert(eval_idx == kimchi_constants::evaluations_in_batch_size); + // evaluations - batch_proof_type p = {{evaluations}, params.proofs[i].o, transcript}; + std::array evaluations; + std::size_t eval_idx = 0; - batch_proofs[i] = p; + for (auto chal : params.proofs[i].comm.prev_challenges) { + evaluations[eval_idx++] = chal; } - typename batch_verify_component::params_type batch_params = { - batch_proofs, params.verifier_index, params.fr_data}; - batch_verify_component::generate_assignments(assignment, batch_params, row); - row += batch_verify_component::rows_amount; - typename proof_binding::template fq_data fq_data_recalculated; - map_fq_component::generate_assignments(assignment, {params.fq_data, fq_data_recalculated}, row); - row += map_fq_component::rows_amount; + commitment_type p_comm = {{{p_comm_unshifted.X, p_comm_unshifted.Y}}}; + for (std::size_t j = 1; j < KimchiParamsType::commitment_params_type::shifted_commitment_split; + j++) { + ft_comm.parts[j] = {zero, zero}; + } + evaluations[eval_idx++] = p_comm; + evaluations[eval_idx++] = ft_comm; + evaluations[eval_idx++] = params.proofs[i].comm.z; + evaluations[eval_idx++] = params.verifier_index.comm.generic; + evaluations[eval_idx++] = params.verifier_index.comm.psm; + + for (std::size_t j = 0; j < params.proofs[i].comm.witness.size(); j++) { + evaluations[eval_idx++] = params.proofs[i].comm.witness[j]; + } + for (std::size_t j = 0; j < params.verifier_index.comm.sigma.size() - 1; j++) { + evaluations[eval_idx++] = params.verifier_index.comm.sigma[j]; + } - assert(row == start_row_index + rows_amount); - return result_type(start_row_index); - } + if (KimchiParamsType::circuit_params::use_lookup) { + for (std::size_t j = 0; j < params.proofs[i].comm.lookup_sorted.size(); j++) { + evaluations[eval_idx++] = params.proofs[i].comm.lookup_sorted[j]; + } - static result_type - generate_circuit(blueprint &bp, - blueprint_public_assignment_table &assignment, - const params_type ¶ms, - const std::size_t start_row_index) { + evaluations[eval_idx++] = params.proofs[i].comm.lookup_agg; - generate_assignments_constant(assignment, params, start_row_index); + evaluations[eval_idx++] = table_comm_component::generate_assignments( + assignment, + {params.verifier_index.comm.lookup_table, + params.fr_data.joint_combiner_powers_prepared, + params.proofs[i].comm.lookup_runtime}, + row) + .output; + row += table_comm_component::rows_amount; - std::size_t row = start_row_index; - var zero(0, row, false, var::column_type::constant); - row++; + if (KimchiParamsType::circuit_params::lookup_runtime) { + evaluations[eval_idx++] = params.proofs[i].comm.lookup_runtime; + } + } - std::array batch_proofs; - for (std::size_t i = 0; i < BatchSize; i++) { - auto p_comm_unshifted = - lagrange_msm_component::generate_circuit( - bp, assignment, {params.fr_data.neg_pub, params.verifier_index.lagrange_bases}, row) - .output; - row = row + lagrange_msm_component::rows_amount; + assert(eval_idx == kimchi_constants::evaluations_in_batch_size); - std::size_t row_tmp = row; + batch_proof_type p = {{evaluations}, params.proofs[i].o, transcript}; - // Oracles - transcript_type transcript; - transcript.init_circuit(bp, assignment, zero, row); - row += transcript_type::init_rows; + batch_proofs[i] = p; + } + typename batch_verify_component::params_type batch_params = {batch_proofs, params.verifier_index, + params.fr_data}; + batch_verify_component::generate_assignments(assignment, batch_params, row); + row += batch_verify_component::rows_amount; + + typename proof_binding::template fq_data fq_data_recalculated; + map_fq_component::generate_assignments(assignment, {params.fq_data, fq_data_recalculated}, row); + row += map_fq_component::rows_amount; + + assert(row == start_row_index + rows_amount); + return result_type(start_row_index); + } + + static result_type generate_circuit(blueprint &bp, + assignment &assignment, + const params_type ¶ms, + const std::size_t start_row_index) { + + generate_assignments_constant(assignment, params, start_row_index); + + std::size_t row = start_row_index; + var zero(0, row, false, var::column_type::constant); + row++; + + std::array batch_proofs; + for (std::size_t i = 0; i < BatchSize; i++) { + auto p_comm_unshifted = + lagrange_msm_component::generate_circuit( + bp, assignment, {params.fr_data.neg_pub, params.verifier_index.lagrange_bases}, row) + .output; + row = row + lagrange_msm_component::rows_amount; + + std::size_t row_tmp = row; + + // Oracles + transcript_type transcript; + transcript.init_circuit(bp, assignment, zero, row); + row += transcript_type::init_rows; + + transcript.absorb_g_circuit(bp, assignment, p_comm_unshifted, row); + row += transcript_type::absorb_group_rows; + + for (std::size_t j = 0; j < params.proofs[i].comm.witness.size(); j++) { + for (std::size_t k = 0; k < params.proofs[i].comm.witness[j].parts.size(); k++) { + transcript.absorb_g_circuit(bp, assignment, params.proofs[i].comm.witness[j].parts[k], + row); + row += transcript_type::absorb_group_rows; + } + } - transcript.absorb_g_circuit(bp, assignment, p_comm_unshifted, row); - row += transcript_type::absorb_group_rows; + var joint_combiner; - for (std::size_t j = 0; j < params.proofs[i].comm.witness.size(); j++) { - for (std::size_t k = 0; k < params.proofs[i].comm.witness[j].parts.size(); k++) { + if (KimchiParamsType::circuit_params::use_lookup) { + if (KimchiParamsType::circuit_params::lookup_runtime) { + for (std::size_t k = 0; k < params.proofs[i].comm.lookup_runtime.parts.size(); k++) { transcript.absorb_g_circuit(bp, assignment, - params.proofs[i].comm.witness[j].parts[k], row); + params.proofs[i].comm.lookup_runtime.parts[k], row); row += transcript_type::absorb_group_rows; } } - var joint_combiner; - - if (KimchiParamsType::circuit_params::use_lookup) { - if (KimchiParamsType::circuit_params::lookup_runtime) { - for (std::size_t k = 0; k < params.proofs[i].comm.lookup_runtime.parts.size(); - k++) { - transcript.absorb_g_circuit(bp, assignment, - params.proofs[i].comm.lookup_runtime.parts[k], row); - row += transcript_type::absorb_group_rows; - } - } - - if (KimchiParamsType::circuit_params::joint_lookup) { - joint_combiner = transcript.challenge_circuit(bp, assignment, row); - row += transcript_type::challenge_rows; - } else { - joint_combiner = zero; - } - - for (std::size_t j = 0; j < params.proofs[i].comm.lookup_sorted.size(); j++) { - for (std::size_t k = 0; k < params.proofs[i].comm.lookup_sorted[j].parts.size(); - k++) { - transcript.absorb_g_circuit( - bp, assignment, params.proofs[i].comm.lookup_sorted[j].parts[k], row); - row += transcript_type::absorb_group_rows; - } - } + if (KimchiParamsType::circuit_params::joint_lookup) { + joint_combiner = transcript.challenge_circuit(bp, assignment, row); + row += transcript_type::challenge_rows; + } else { + joint_combiner = zero; } - var beta = transcript.challenge_circuit(bp, assignment, row); - row += transcript_type::challenge_rows; - - var gamma = transcript.challenge_circuit(bp, assignment, row); - row += transcript_type::challenge_rows; - - if (KimchiParamsType::circuit_params::use_lookup) { - for (std::size_t k = 0; k < params.proofs[i].comm.lookup_agg.parts.size(); k++) { + for (std::size_t j = 0; j < params.proofs[i].comm.lookup_sorted.size(); j++) { + for (std::size_t k = 0; k < params.proofs[i].comm.lookup_sorted[j].parts.size(); k++) { transcript.absorb_g_circuit(bp, assignment, - params.proofs[i].comm.lookup_agg.parts[k], row); + params.proofs[i].comm.lookup_sorted[j].parts[k], row); row += transcript_type::absorb_group_rows; } } + } - for (std::size_t k = 0; k < params.proofs[i].comm.z.parts.size(); k++) { - transcript.absorb_g_circuit(bp, assignment, params.proofs[i].comm.z.parts[k], row); - row += transcript_type::absorb_group_rows; - } + var beta = transcript.challenge_circuit(bp, assignment, row); + row += transcript_type::challenge_rows; - var alpha = transcript.challenge_circuit(bp, assignment, row); - row += transcript_type::challenge_rows; + var gamma = transcript.challenge_circuit(bp, assignment, row); + row += transcript_type::challenge_rows; - for (std::size_t k = 0; k < params.proofs[i].comm.t.parts.size(); k++) { - transcript.absorb_g_circuit(bp, assignment, params.proofs[i].comm.t.parts[k], row); + if (KimchiParamsType::circuit_params::use_lookup) { + for (std::size_t k = 0; k < params.proofs[i].comm.lookup_agg.parts.size(); k++) { + transcript.absorb_g_circuit(bp, assignment, params.proofs[i].comm.lookup_agg.parts[k], + row); row += transcript_type::absorb_group_rows; } + } + + for (std::size_t k = 0; k < params.proofs[i].comm.z.parts.size(); k++) { + transcript.absorb_g_circuit(bp, assignment, params.proofs[i].comm.z.parts[k], row); + row += transcript_type::absorb_group_rows; + } - var zeta = transcript.challenge_circuit(bp, assignment, row); - row += transcript_type::challenge_rows; + var alpha = transcript.challenge_circuit(bp, assignment, row); + row += transcript_type::challenge_rows; - var digest = transcript.digest_circuit(bp, assignment, row); - row += transcript_type::digest_rows; + for (std::size_t k = 0; k < params.proofs[i].comm.t.parts.size(); k++) { + transcript.absorb_g_circuit(bp, assignment, params.proofs[i].comm.t.parts[k], row); + row += transcript_type::absorb_group_rows; + } + + var zeta = transcript.challenge_circuit(bp, assignment, row); + row += transcript_type::challenge_rows; - // Oracles end + var digest = transcript.digest_circuit(bp, assignment, row); + row += transcript_type::digest_rows; - std::array, f_comm_base_size> f_comm_bases = - prepare_f_comm(params, i); + // Oracles end - std::array f_comm; - for (std::size_t j = 0; j < KimchiCommitmentParamsType::max_comm_size; j++) { - std::array bases; - std::array scalars; - for (std::size_t k = 0; k < f_comm_base_size; k++) { - if (j < f_comm_bases[k].size()) { - bases[k] = f_comm_bases[k][j]; - scalars[k] = params.proofs[i].scalars[k]; - } else { - bases[k] = {zero, zero}; - scalars[k] = zero; - } + std::array, f_comm_base_size> f_comm_bases = + prepare_f_comm(params, i); + + std::array f_comm; + for (std::size_t j = 0; j < KimchiCommitmentParamsType::max_comm_size; j++) { + std::array bases; + std::array scalars; + for (std::size_t k = 0; k < f_comm_base_size; k++) { + if (j < f_comm_bases[k].size()) { + bases[k] = f_comm_bases[k][j]; + scalars[k] = params.proofs[i].scalars[k]; + } else { + bases[k] = {zero, zero}; + scalars[k] = zero; } - auto res = msm_component::generate_circuit(bp, assignment, {scalars, bases}, row); - f_comm[j] = {res.output.X, res.output.Y}; - row += msm_component::rows_amount; - } - - // chuncked_f_comm - var_ec_point chuncked_f_comm = {zero, zero}; - - for (std::size_t j = 0; j < f_comm.size(); j++) { - auto res0 = scalar_mul_component::generate_circuit( - bp, assignment, - {{chuncked_f_comm.X, chuncked_f_comm.Y}, params.fr_data.zeta_to_srs_len[i]}, row); - row += scalar_mul_component::rows_amount; - auto res1 = zk::components::generate_circuit( - bp, assignment, {{res0.X, res0.Y}, {f_comm[j].X, f_comm[j].Y}}, row); - row += add_component::rows_amount; - chuncked_f_comm = {res1.X, res1.Y}; - } - - // chunked_t_comm - var_ec_point chunked_t_comm = {zero, zero}; - ; - for (std::size_t j = 0; j < params.proofs[i].comm.t.parts.size(); j++) { - auto res0 = scalar_mul_component::generate_circuit( - bp, assignment, - {{chunked_t_comm.X, chunked_t_comm.Y}, params.fr_data.zeta_to_srs_len[i]}, row); - row += scalar_mul_component::rows_amount; - - auto res1 = zk::components::generate_circuit( - bp, assignment, - {{res0.X, res0.Y}, - {params.proofs[i].comm.t.parts[j].X, params.proofs[i].comm.t.parts[j].Y}}, - row); - row += add_component::rows_amount; - chunked_t_comm = {res1.X, res1.Y}; - } - - // ft_comm - - auto scaled_t_comm = scalar_mul_component::generate_circuit( + } + auto res = msm_component::generate_circuit(bp, assignment, {scalars, bases}, row); + f_comm[j] = {res.output.X, res.output.Y}; + row += msm_component::rows_amount; + } + + // chuncked_f_comm + var_ec_point chuncked_f_comm = {zero, zero}; + + for (std::size_t j = 0; j < f_comm.size(); j++) { + auto res0 = scalar_mul_component::generate_circuit( bp, assignment, - {{chunked_t_comm.X, chunked_t_comm.Y}, params.fr_data.zeta_to_domain_size_minus_1}, - row); + {{chuncked_f_comm.X, chuncked_f_comm.Y}, params.fr_data.zeta_to_srs_len[i]}, row); row += scalar_mul_component::rows_amount; + auto res1 = ::nil::blueprint::components::generate_circuit( + bp, assignment, {{res0.X, res0.Y}, {f_comm[j].X, f_comm[j].Y}}, row); + row += add_component::rows_amount; + chuncked_f_comm = {res1.X, res1.Y}; + } - typename BlueprintFieldType::value_type minus_1 = -1; - var const_res_unshifted = zk::components::generate_circuit( - bp, assignment, {scaled_t_comm.Y, minus_1}, row) - .output; - row += const_mul_component::rows_amount; - - var_ec_point neg_scaled_t_comm = {scaled_t_comm.X, const_res_unshifted}; + // chunked_t_comm + var_ec_point chunked_t_comm = {zero, zero}; + ; + for (std::size_t j = 0; j < params.proofs[i].comm.t.parts.size(); j++) { + auto res0 = scalar_mul_component::generate_circuit( + bp, assignment, + {{chunked_t_comm.X, chunked_t_comm.Y}, params.fr_data.zeta_to_srs_len[i]}, row); + row += scalar_mul_component::rows_amount; - auto ft_comm_part = zk::components::generate_circuit( + auto res1 = ::nil::blueprint::components::generate_circuit( bp, assignment, - {{neg_scaled_t_comm.X, neg_scaled_t_comm.Y}, {chuncked_f_comm.X, chuncked_f_comm.Y}}, + {{res0.X, res0.Y}, + {params.proofs[i].comm.t.parts[j].X, params.proofs[i].comm.t.parts[j].Y}}, row); row += add_component::rows_amount; - commitment_type ft_comm = {{{ft_comm_part.X, ft_comm_part.Y}}}; - for (std::size_t j = 1; - j < KimchiParamsType::commitment_params_type::shifted_commitment_split; - j++) { - ft_comm.parts[j] = {zero, zero}; - } - - // evaluations - std::array evaluations; - std::size_t eval_idx = 0; - for (auto chal : params.proofs[i].comm.prev_challenges) { - evaluations[eval_idx++] = chal; - } - - commitment_type p_comm = {{{p_comm_unshifted.X, p_comm_unshifted.Y}}}; - for (std::size_t j = 1; - j < KimchiParamsType::commitment_params_type::shifted_commitment_split; - j++) { - ft_comm.parts[j] = {zero, zero}; - } - evaluations[eval_idx++] = p_comm; - evaluations[eval_idx++] = ft_comm; - evaluations[eval_idx++] = params.proofs[i].comm.z; - evaluations[eval_idx++] = params.verifier_index.comm.generic; - evaluations[eval_idx++] = params.verifier_index.comm.psm; - - for (std::size_t j = 0; j < params.proofs[i].comm.witness.size(); j++) { - evaluations[eval_idx++] = params.proofs[i].comm.witness[j]; - } - for (std::size_t j = 0; j < params.verifier_index.comm.sigma.size() - 1; j++) { - evaluations[eval_idx++] = params.verifier_index.comm.sigma[j]; - } + chunked_t_comm = {res1.X, res1.Y}; + } - if (KimchiParamsType::circuit_params::use_lookup) { - for (std::size_t j = 0; j < params.proofs[i].comm.lookup_sorted.size(); j++) { - evaluations[eval_idx++] = params.proofs[i].comm.lookup_sorted[j]; - } + // ft_comm + + auto scaled_t_comm = scalar_mul_component::generate_circuit( + bp, assignment, + {{chunked_t_comm.X, chunked_t_comm.Y}, params.fr_data.zeta_to_domain_size_minus_1}, row); + row += scalar_mul_component::rows_amount; + + typename BlueprintFieldType::value_type minus_1 = -1; + var const_res_unshifted = ::nil::blueprint::components::generate_circuit( + bp, assignment, {scaled_t_comm.Y, minus_1}, row) + .output; + row += const_mul_component::rows_amount; + + var_ec_point neg_scaled_t_comm = {scaled_t_comm.X, const_res_unshifted}; + + auto ft_comm_part = ::nil::blueprint::components::generate_circuit( + bp, assignment, + {{neg_scaled_t_comm.X, neg_scaled_t_comm.Y}, {chuncked_f_comm.X, chuncked_f_comm.Y}}, row); + row += add_component::rows_amount; + commitment_type ft_comm = {{{ft_comm_part.X, ft_comm_part.Y}}}; + for (std::size_t j = 1; j < KimchiParamsType::commitment_params_type::shifted_commitment_split; + j++) { + ft_comm.parts[j] = {zero, zero}; + } - evaluations[eval_idx++] = params.proofs[i].comm.lookup_agg; + // evaluations + std::array evaluations; + std::size_t eval_idx = 0; + for (auto chal : params.proofs[i].comm.prev_challenges) { + evaluations[eval_idx++] = chal; + } - evaluations[eval_idx++] = table_comm_component::generate_circuit( - bp, assignment, - {params.verifier_index.comm.lookup_table, params.fr_data.joint_combiner_powers_prepared, - params.proofs[i].comm.lookup_runtime}, - row) - .output; - row += table_comm_component::rows_amount; + commitment_type p_comm = {{{p_comm_unshifted.X, p_comm_unshifted.Y}}}; + for (std::size_t j = 1; j < KimchiParamsType::commitment_params_type::shifted_commitment_split; + j++) { + ft_comm.parts[j] = {zero, zero}; + } + evaluations[eval_idx++] = p_comm; + evaluations[eval_idx++] = ft_comm; + evaluations[eval_idx++] = params.proofs[i].comm.z; + evaluations[eval_idx++] = params.verifier_index.comm.generic; + evaluations[eval_idx++] = params.verifier_index.comm.psm; + + for (std::size_t j = 0; j < params.proofs[i].comm.witness.size(); j++) { + evaluations[eval_idx++] = params.proofs[i].comm.witness[j]; + } + for (std::size_t j = 0; j < params.verifier_index.comm.sigma.size() - 1; j++) { + evaluations[eval_idx++] = params.verifier_index.comm.sigma[j]; + } - if (KimchiParamsType::circuit_params::lookup_runtime) { - evaluations[eval_idx++] = params.proofs[i].comm.lookup_runtime; - } + if (KimchiParamsType::circuit_params::use_lookup) { + for (std::size_t j = 0; j < params.proofs[i].comm.lookup_sorted.size(); j++) { + evaluations[eval_idx++] = params.proofs[i].comm.lookup_sorted[j]; } - assert(eval_idx == kimchi_constants::evaluations_in_batch_size); + evaluations[eval_idx++] = params.proofs[i].comm.lookup_agg; - batch_proof_type p = {{evaluations}, params.proofs[i].o, transcript}; + evaluations[eval_idx++] = + table_comm_component::generate_circuit(bp, assignment, + {params.verifier_index.comm.lookup_table, + params.fr_data.joint_combiner_powers_prepared, + params.proofs[i].comm.lookup_runtime}, + row) + .output; + row += table_comm_component::rows_amount; - batch_proofs[i] = p; + if (KimchiParamsType::circuit_params::lookup_runtime) { + evaluations[eval_idx++] = params.proofs[i].comm.lookup_runtime; + } } - typename batch_verify_component::params_type batch_params = { - batch_proofs, params.verifier_index, params.fr_data}; - batch_verify_component::generate_circuit(bp, assignment, batch_params, row); - row += batch_verify_component::rows_amount; - typename proof_binding::template fq_data fq_data_recalculated; - map_fq_component::generate_circuit(bp, assignment, {params.fq_data, fq_data_recalculated}, row); - row += map_fq_component::rows_amount; + assert(eval_idx == kimchi_constants::evaluations_in_batch_size); - assert(row == start_row_index + rows_amount); + batch_proof_type p = {{evaluations}, params.proofs[i].o, transcript}; - return result_type(start_row_index); + batch_proofs[i] = p; } - - private: - static void - generate_copy_constraints(blueprint &bp, - blueprint_public_assignment_table &assignment, - const params_type ¶ms, - const std::size_t start_row_index) { - std::size_t row = start_row_index; - } - - static void generate_assignments_constant( - blueprint_public_assignment_table &assignment, - const params_type ¶ms, - std::size_t start_row_index) { - std::size_t row = start_row_index; - assignment.constant(0)[row] = 0; - } - }; - - } // namespace components - } // namespace blueprint - } // namespace crypto3 + typename batch_verify_component::params_type batch_params = {batch_proofs, params.verifier_index, + params.fr_data}; + batch_verify_component::generate_circuit(bp, assignment, batch_params, row); + row += batch_verify_component::rows_amount; + + typename proof_binding::template fq_data fq_data_recalculated; + map_fq_component::generate_circuit(bp, assignment, {params.fq_data, fq_data_recalculated}, row); + row += map_fq_component::rows_amount; + + assert(row == start_row_index + rows_amount); + + return result_type(start_row_index); + } + + private: + static void generate_copy_constraints(blueprint &bp, + assignment &assignment, + const params_type ¶ms, + const std::size_t start_row_index) { + std::size_t row = start_row_index; + } + + static void generate_assignments_constant(assignment &assignment, + const params_type ¶ms, + std::size_t start_row_index) { + std::size_t row = start_row_index; + assignment.constant(0)[row] = 0; + } + }; + + } // namespace components + } // namespace blueprint } // namespace nil #endif // CRYPTO3_BLUEPRINT_COMPONENTS_BASE_FIELD_HPP diff --git a/include/nil/blueprint/components/systems/snark/plonk/kimchi/verify_heterogenous_base.hpp b/include/nil/blueprint/components/systems/snark/plonk/kimchi/verify_heterogenous_base.hpp index d8e7b699c..35c9846b0 100644 --- a/include/nil/blueprint/components/systems/snark/plonk/kimchi/verify_heterogenous_base.hpp +++ b/include/nil/blueprint/components/systems/snark/plonk/kimchi/verify_heterogenous_base.hpp @@ -31,15 +31,15 @@ #include -#include +#include #include -#include +#include -#include +#include -#include +#include -#include +#include namespace nil { namespace crypto3 { diff --git a/include/nil/blueprint/components/systems/snark/plonk/kimchi/verify_heterogenous_scalar.hpp b/include/nil/blueprint/components/systems/snark/plonk/kimchi/verify_heterogenous_scalar.hpp index 7c7018ece..2f1e3814b 100644 --- a/include/nil/blueprint/components/systems/snark/plonk/kimchi/verify_heterogenous_scalar.hpp +++ b/include/nil/blueprint/components/systems/snark/plonk/kimchi/verify_heterogenous_scalar.hpp @@ -31,25 +31,25 @@ #include -#include +#include #include -#include -#include -#include +#include +#include +#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include -#include -#include -#include -#include +#include +#include +#include +#include -#include +#include namespace nil { namespace crypto3 { @@ -226,7 +226,7 @@ namespace nil { row += endo_scalar_component::rows_amount; auto alpha = endo_scalar_component::generate_circuit(bp, assignment, {params.def_values[i].plonk.alpha}, row).output; row += endo_scalar_component::rows_amount; - auto zetaw = zk::components::generate_circuit(bp, assignment, {zets, params.domain_generator}, row).output; + auto zetaw = ::nil::blueprint::components::generate_circuit(bp, assignment, {zets, params.domain_generator}, row).output; row += mul_component::rows_amount; var min_poly_joint_combiner; if (KimchiParamsType::circuit_params::lookup_used) { @@ -306,10 +306,10 @@ s .output; row += b_poly_component::rows_amount; - auto t = zk::components::generate_circuit(bp, assignment, {chal_zetaw, r_actual}, row).output; + auto t = ::nil::blueprint::components::generate_circuit(bp, assignment, {chal_zetaw, r_actual}, row).output; row += mul_component::rows_amount; - auto b_actual = zk::components::generate_circuit(bp, assignment, {chal_zeta, t}, row).output; + auto b_actual = ::nil::blueprint::components::generate_circuit(bp, assignment, {chal_zeta, t}, row).output; row += add_component::rows_amount; shifted_combined_inner_product = prepare_scalars_inversion_component::generate_circuit(bp, assignment, { diff --git a/include/nil/blueprint/components/systems/snark/plonk/kimchi/verify_scalar.hpp b/include/nil/blueprint/components/systems/snark/plonk/kimchi/verify_scalar.hpp index 860e64a95..e73570fa8 100644 --- a/include/nil/blueprint/components/systems/snark/plonk/kimchi/verify_scalar.hpp +++ b/include/nil/blueprint/components/systems/snark/plonk/kimchi/verify_scalar.hpp @@ -37,7 +37,7 @@ #include #include -#include +#include #include diff --git a/include/nil/blueprint/components/systems/snark/r1cs_pp_zksnark/verifier.hpp b/include/nil/blueprint/components/systems/snark/r1cs_pp_zksnark/verifier.hpp index 4d66023d6..5a9cac1ef 100644 --- a/include/nil/blueprint/components/systems/snark/r1cs_pp_zksnark/verifier.hpp +++ b/include/nil/blueprint/components/systems/snark/r1cs_pp_zksnark/verifier.hpp @@ -38,7 +38,7 @@ #include -#include +#include #include #include #include diff --git a/include/nil/blueprint/components/voting/r1cs/encrypted_input_voting.hpp b/include/nil/blueprint/components/voting/r1cs/encrypted_input_voting.hpp index 08b700569..d87b5ec2d 100644 --- a/include/nil/blueprint/components/voting/r1cs/encrypted_input_voting.hpp +++ b/include/nil/blueprint/components/voting/r1cs/encrypted_input_voting.hpp @@ -27,122 +27,119 @@ #ifndef CRYPTO3_BLUEPRINT_COMPONENTS_VOTING_ENCRYPTED_INPUT_VOTING_COMPONENT_HPP #define CRYPTO3_BLUEPRINT_COMPONENTS_VOTING_ENCRYPTED_INPUT_VOTING_COMPONENT_HPP -#include +#include #include namespace nil { - namespace crypto3 { - namespace blueprint { - namespace components { - template, - typename MerkleTreeHashComponent = HashComponent, - typename Field = typename HashComponent::field_type> - struct encrypted_input_voting : public component { - using field_type = Field; - using hash_component = HashComponent; - using merkle_proof_validating_component = - merkle_proof_validate; - using merkle_proof_component = typename merkle_proof_validating_component::merkle_proof_component; + namespace blueprint { + namespace components { + template, + typename MerkleTreeHashComponent = HashComponent, + typename Field = typename HashComponent::field_type> + struct encrypted_input_voting : public component { + using field_type = Field; + using hash_component = HashComponent; + using merkle_proof_validating_component = merkle_proof_validate; + using merkle_proof_component = typename merkle_proof_validating_component::merkle_proof_component; - digest_variable sn_computed; - digest_variable pk; - digest_variable pk_leaf; - hash_component pk_hasher; - MerkleTreeHashComponent pk_leaf_hasher; - merkle_proof_validating_component root_validator; - hash_component sn_hasher; - bit_vector_copy_component check_sn; + digest_variable sn_computed; + digest_variable pk; + digest_variable pk_leaf; + hash_component pk_hasher; + MerkleTreeHashComponent pk_leaf_hasher; + merkle_proof_validating_component root_validator; + hash_component sn_hasher; + bit_vector_copy_component check_sn; - block_variable m; - block_variable eid; - digest_variable sn; - block_variable sk; + block_variable m; + block_variable eid; + digest_variable sn; + block_variable sk; - /** - * @warning If you just want to compute intermediate fields (\p rt and \p sn) it is sufficient to - * instantiate encrypted_input_voting component and call \p generate_assignments, but if you want - * to check satisfiability of the CS you have to call \p generate_assignments for \p rt and \p sn - * with expected values before call \p is_satisfied for \p bp. This is due to using of the - * bit_vector_copy_component which is responsible for both logics: copying of the computed fields - * (\p rt and \p sn) and comparison of the computed and passed values. So, if you don't call \p - * generate_assignments for \p rt and \p sn satisfiability check will always be positive, i.e. - * false positive error happens. Another solution - instead of manual calling to the \p - * generate_assignments for \p rt and \p sn just use encrypted_input_voting's \p - * generate_assignments accepting additional parameters \p root and \p sn. - */ - encrypted_input_voting(blueprint &bp, - const block_variable &m, - const block_variable &eid, - const digest_variable &sn, - const digest_variable &rt, - const detail::blueprint_linear_combination_vector &address_bits, - const merkle_proof_component &path, - const block_variable &sk, - const detail::blueprint_linear_combination &read_successful) : - component(bp), - // private fields - sn_computed(bp, hash_component::digest_bits), pk(bp, hash_component::digest_bits), - pk_leaf(bp, MerkleTreeHashComponent::digest_bits), pk_hasher(bp, sk, pk), - pk_leaf_hasher(bp, pk, pk_leaf), - root_validator(bp, path.tree_depth, address_bits, pk_leaf, rt, path, read_successful), - sn_hasher(bp, - std::vector { - eid, - sk, - }, - sn_computed), - check_sn(bp, sn_computed.bits, sn.bits, read_successful, field_type::number_bits), - // public fields - m(m), eid(eid), sn(sn), sk(sk) { - } + /** + * @warning If you just want to compute intermediate fields (\p rt and \p sn) it is sufficient to + * instantiate encrypted_input_voting component and call \p generate_assignments, but if you want + * to check satisfiability of the CS you have to call \p generate_assignments for \p rt and \p sn + * with expected values before call \p is_satisfied for \p bp. This is due to using of the + * bit_vector_copy_component which is responsible for both logics: copying of the computed fields + * (\p rt and \p sn) and comparison of the computed and passed values. So, if you don't call \p + * generate_assignments for \p rt and \p sn satisfiability check will always be positive, i.e. + * false positive error happens. Another solution - instead of manual calling to the \p + * generate_assignments for \p rt and \p sn just use encrypted_input_voting's \p + * generate_assignments accepting additional parameters \p root and \p sn. + */ + encrypted_input_voting(blueprint &bp, + const block_variable &m, + const block_variable &eid, + const digest_variable &sn, + const digest_variable &rt, + const detail::blueprint_linear_combination_vector &address_bits, + const merkle_proof_component &path, + const block_variable &sk, + const detail::blueprint_linear_combination &read_successful) : + component(bp), + // private fields + sn_computed(bp, hash_component::digest_bits), pk(bp, hash_component::digest_bits), + pk_leaf(bp, MerkleTreeHashComponent::digest_bits), pk_hasher(bp, sk, pk), + pk_leaf_hasher(bp, pk, pk_leaf), + root_validator(bp, path.tree_depth, address_bits, pk_leaf, rt, path, read_successful), + sn_hasher(bp, + std::vector { + eid, + sk, + }, + sn_computed), + check_sn(bp, sn_computed.bits, sn.bits, read_successful, field_type::number_bits), + // public fields + m(m), eid(eid), sn(sn), sk(sk) { + } - // TODO: review all necessary constrains, for example, eid - void generate_gates() { - pk_hasher.generate_gates(); - pk_leaf_hasher.generate_gates(); - root_validator.generate_gates(); - sn_hasher.generate_gates(); - check_sn.generate_gates(false, false); + // TODO: review all necessary constrains, for example, eid + void generate_gates() { + pk_hasher.generate_gates(); + pk_leaf_hasher.generate_gates(); + root_validator.generate_gates(); + sn_hasher.generate_gates(); + check_sn.generate_gates(false, false); - math::linear_combination sum_m_i; - for (const auto &m_i : m.bits) { - // m_i == 0 or m_i == 1 - generate_boolean_r1cs_constraint( - this->bp, static_cast>(m_i)); - sum_m_i = sum_m_i + m_i; - } - // sum_m_i == 1 - this->bp.add_r1cs_constraint( - snark::r1cs_constraint(Field::value_type::one(), sum_m_i, Field::value_type::one())); + crypto3::math::linear_combination sum_m_i; + for (const auto &m_i : m.bits) { + // m_i == 0 or m_i == 1 + generate_boolean_r1cs_constraint( + this->bp, static_cast>(m_i)); + sum_m_i = sum_m_i + m_i; } + // sum_m_i == 1 + this->bp.add_r1cs_constraint(crypto3::zk::snark::r1cs_constraint( + Field::value_type::one(), sum_m_i, Field::value_type::one())); + } - private: - void generate_assignments() { - pk_hasher.generate_assignments(); - pk_leaf_hasher.generate_assignments(); - root_validator.generate_assignments(); - sn_hasher.generate_assignments(); - check_sn.generate_assignments(); - } + private: + void generate_assignments() { + pk_hasher.generate_assignments(); + pk_leaf_hasher.generate_assignments(); + root_validator.generate_assignments(); + sn_hasher.generate_assignments(); + check_sn.generate_assignments(); + } - public: - /** - * @brief Witness generation should be called every time we update - */ - void generate_assignments(const std::vector &root, const std::vector &sn) { - generate_assignments(); - root_validator.root.generate_assignments(root); - this->sn.generate_assignments(sn); - } + public: + /** + * @brief Witness generation should be called every time we update + */ + void generate_assignments(const std::vector &root, const std::vector &sn) { + generate_assignments(); + root_validator.root.generate_assignments(root); + this->sn.generate_assignments(sn); + } - inline std::size_t get_input_size() const { - return m.block_size + eid.block_size + sn.digest_size + root_validator.root.digest_size; - } - }; - } // namespace components - } // namespace blueprint - } // namespace crypto3 + inline std::size_t get_input_size() const { + return m.block_size + eid.block_size + sn.digest_size + root_validator.root.digest_size; + } + }; + } // namespace components + } // namespace blueprint } // namespace nil #endif // CRYPTO3_BLUEPRINT_COMPONENTS_VOTING_ENCRYPTED_INPUT_VOTING_COMPONENT_HPP diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index e24e14030..a5dbbcb39 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -172,7 +172,8 @@ set(HASHES_TESTS_FILES "hashes/r1cs/knapsack_verification" "hashes/r1cs/sha256" "hashes/r1cs/sha256_verification" - "hashes/r1cs/pedersen") +# "hashes/r1cs/pedersen" +) set(PAIRING_TESTS_FILES "algebra/pairing/weierstrass/r1cs/miller_loop" @@ -191,11 +192,13 @@ set(MERKLE_TREE_TESTS_FILES "merkle_tree_components") set(VOTING_TESTS_FILES - "voting/r1cs/encrypted_input_voting") +# "voting/r1cs/encrypted_input_voting" +) set(BASIC_COMPONENTS_TESTS_FILES - "basic_components" - "basic_components_r1cs_gg_ppzksnark") +# "basic_components" +# "basic_components_r1cs_gg_ppzksnark" +) SET(ALGEBRA_TESTS_FILES ${FIELDS_TESTS_FILES} diff --git a/test/algebra/curves/plonk/variable_base_endo_scalar_mul.cpp b/test/algebra/curves/plonk/variable_base_endo_scalar_mul.cpp index 36cab97b9..641c00e23 100644 --- a/test/algebra/curves/plonk/variable_base_endo_scalar_mul.cpp +++ b/test/algebra/curves/plonk/variable_base_endo_scalar_mul.cpp @@ -43,8 +43,7 @@ #include #include "test_plonk_component.hpp" -#include "../../../profiling.hpp" - +using namespace nil; using namespace nil::crypto3; BOOST_AUTO_TEST_SUITE(blueprint_plonk_test_suite) @@ -59,35 +58,37 @@ BOOST_AUTO_TEST_CASE(blueprint_plonk_base_endo_scalar_mul) { constexpr std::size_t PublicInputColumns = 1; constexpr std::size_t ConstantColumns = 1; constexpr std::size_t SelectorColumns = 3; - using ArithmetizationParams = zk::snark::plonk_arithmetization_params; - using ArithmetizationType = zk::snark::plonk_constraint_system; + using ArithmetizationType = zk::snark::plonk_constraint_system; using AssignmentType = blueprint::assignment; - using hash_type = nil::crypto3::hashes::keccak_1600<256>; + using hash_type = hashes::keccak_1600<256>; using var = zk::snark::plonk_variable; constexpr std::size_t Lambda = 40; - using component_type = zk::components::curve_element_variable_base_endo_scalar_mul; + using component_type = + blueprint::components::curve_element_variable_base_endo_scalar_mul; - //curve_type::scalar_field_type::value_type b = algebra::random_element(); + // curve_type::scalar_field_type::value_type b = algebra::random_element(); curve_type::scalar_field_type::value_type b = 2; - typename curve_type::scalar_field_type::integral_type integral_b = typename curve_type::scalar_field_type::integral_type(b.data); - BlueprintFieldType::value_type b_scalar = integral_b; - curve_type::template g1_type::value_type T = algebra::random_element>(); + typename curve_type::scalar_field_type::integral_type integral_b = + typename curve_type::scalar_field_type::integral_type(b.data); + BlueprintFieldType::value_type b_scalar = integral_b; + curve_type::template g1_type::value_type T = + algebra::random_element>(); var T_X_var = {0, 1, false, var::column_type::public_input}; var T_Y_var = {0, 2, false, var::column_type::public_input}; var scalar_var = {0, 3, false, var::column_type::public_input}; - typename component_type::params_type assignment_params = {{T_X_var, T_Y_var},scalar_var}; - std::cout<<"random point: " << T.X.data << " " << T.Y.data < public_input = {T.X, T.Y, b_scalar}; - constexpr static const typename BlueprintFieldType::value_type endo = component_type::endo; - typename BlueprintFieldType::value_type endo_scalar = 0x244630A7EE5033DA383B3677B4C5CA94A3EBE4156FC4FA4E08B35974929CA2C5_cppui255; + constexpr static const typename BlueprintFieldType::value_type endo = component_type::endo; + typename BlueprintFieldType::value_type endo_scalar = + 0x244630A7EE5033DA383B3677B4C5CA94A3EBE4156FC4FA4E08B35974929CA2C5_cppui255; - typename curve_type::template g1_type::value_type testResult = endo_scalar * T; - std::cout<<"Expected result for endo_scalar * T: "<::value_type testResult = + endo_scalar * T; + std::cout << "Expected result for endo_scalar * T: " << testResult.X.data << " " << testResult.Y.data << std::endl; std::array bits = {false}; for (std::size_t i = 0; i < 128; i++) { bits[128 - i - 1] = multiprecision::bit_test(integral_b, i); @@ -95,12 +96,13 @@ BOOST_AUTO_TEST_CASE(blueprint_plonk_base_endo_scalar_mul) { typename curve_type::template g1_type::value_type testQ; testQ.X = endo * T.X; testQ.Y = T.Y; - typename curve_type::template g1_type::value_type acc = T + (T + testQ) + testQ; + typename curve_type::template g1_type::value_type acc = + T + (T + testQ) + testQ; for (std::size_t i = 0; i < 128; i = i + 2) { typename BlueprintFieldType::value_type b1 = bits[i]; typename BlueprintFieldType::value_type b2 = bits[i + 1]; - if (b1 == 0){ - testQ.X = T.X; + if (b1 == 0) { + testQ.X = T.X; } else { testQ.X = endo * T.X; } @@ -111,13 +113,13 @@ BOOST_AUTO_TEST_CASE(blueprint_plonk_base_endo_scalar_mul) { } acc = acc + testQ + acc; } - std::cout<<"Expected result: "< (assignment_params, public_input, result_check); - auto duration = std::chrono::duration_cast(std::chrono::high_resolution_clock::now() - start); + auto result_check = [](AssignmentType &assignment, component_type::result_type &real_res) {}; + test_component(assignment_params, public_input, + result_check); + auto duration = + std::chrono::duration_cast(std::chrono::high_resolution_clock::now() - start); std::cout << "base_endo_scalar_mul: " << duration.count() << "ms" << std::endl; } diff --git a/test/algebra/curves/r1cs/test_utils.hpp b/test/algebra/curves/r1cs/test_utils.hpp index 578b632f8..dc61d7f0b 100644 --- a/test/algebra/curves/r1cs/test_utils.hpp +++ b/test/algebra/curves/r1cs/test_utils.hpp @@ -31,7 +31,7 @@ #include #include -#include +#include using namespace nil::crypto3::zk; using namespace nil::crypto3::algebra; diff --git a/test/algebra/fields/plonk/combined_inner_product.cpp b/test/algebra/fields/plonk/combined_inner_product.cpp index 185eae483..ae03fa10a 100644 --- a/test/algebra/fields/plonk/combined_inner_product.cpp +++ b/test/algebra/fields/plonk/combined_inner_product.cpp @@ -65,13 +65,13 @@ BOOST_AUTO_TEST_CASE(blueprint_plonk_combined_inner_product) { using var = zk::snark::plonk_variable; - using component_type = zk::components::combined_inner_product; + using component_type = zk::components:: + combined_inner_product; std::array input_var_zeta1; std::array input_var_zeta2; std::vector public_input; - for (std::size_t i = 0 ; i < k; i++) { + for (std::size_t i = 0; i < k; i++) { input_var_zeta1[i] = var(0, 2 * i, false, var::column_type::public_input); input_var_zeta2[i] = var(0, 2 * i + 1, false, var::column_type::public_input); public_input.push_back(algebra::random_element()); @@ -85,14 +85,12 @@ BOOST_AUTO_TEST_CASE(blueprint_plonk_combined_inner_product) { typename component_type::params_type params = {input_var_zeta1, input_var_zeta2, xi, r}; - - auto result_check = [](AssignmentType &assignment, - component_type::result_type &real_res) { - }; + auto result_check = [](AssignmentType &assignment, component_type::result_type &real_res) {}; test_component(params, public_input, result_check); - auto duration = std::chrono::duration_cast(std::chrono::high_resolution_clock::now() - start); + auto duration = + std::chrono::duration_cast(std::chrono::high_resolution_clock::now() - start); std::cout << "combined_inner_product_component: " << duration.count() << "ms" << std::endl; } diff --git a/test/algebra/fields/plonk/element_powers.cpp b/test/algebra/fields/plonk/element_powers.cpp index 8b1e8a713..592b22214 100644 --- a/test/algebra/fields/plonk/element_powers.cpp +++ b/test/algebra/fields/plonk/element_powers.cpp @@ -64,8 +64,8 @@ BOOST_AUTO_TEST_CASE(blueprint_plonk_element_powers) { using var = zk::snark::plonk_variable; - using component_type = zk::components::element_powers; + using component_type = + zk::components::element_powers; var one(0, 0, false, var::column_type::public_input); var base(0, 1, false, var::column_type::public_input); @@ -82,22 +82,21 @@ BOOST_AUTO_TEST_CASE(blueprint_plonk_element_powers) { if (expected_result.size() > 1) { expected_result[1] = base_value; } - for (std::size_t i =2; i < n; i++) { + for (std::size_t i = 2; i < n; i++) { last_value = last_value * base_value; expected_result[i] = last_value; } - - auto result_check = [&expected_result](AssignmentType &assignment, - component_type::result_type &real_res) { - for (std::size_t i = 0; i < n; i++) { - assert(expected_result[i] == assignment.var_value(real_res.output[i])); - } + auto result_check = [&expected_result](AssignmentType &assignment, component_type::result_type &real_res) { + for (std::size_t i = 0; i < n; i++) { + assert(expected_result[i] == assignment.var_value(real_res.output[i])); + } }; test_component(params, public_input, result_check); - auto duration = std::chrono::duration_cast(std::chrono::high_resolution_clock::now() - start); + auto duration = + std::chrono::duration_cast(std::chrono::high_resolution_clock::now() - start); std::cout << "element_powers_component: " << duration.count() << "ms" << std::endl; } diff --git a/test/algebra/fields/plonk/exponentiation.cpp b/test/algebra/fields/plonk/exponentiation.cpp index 83738f57b..276a5f878 100644 --- a/test/algebra/fields/plonk/exponentiation.cpp +++ b/test/algebra/fields/plonk/exponentiation.cpp @@ -46,23 +46,25 @@ #include #include "../../../test_plonk_component.hpp" -template -void test_exponentiation(std::vector public_input){ +template +void test_exponentiation(std::vector public_input) { constexpr std::size_t WitnessColumns = 15; constexpr std::size_t PublicInputColumns = 1; constexpr std::size_t ConstantColumns = 1; constexpr std::size_t SelectorColumns = 1; constexpr std::size_t exp_size = ExpSize; - using BlueprintFieldType = FieldType; + using BlueprintFieldType = FieldType; using ArithmetizationType = nil::crypto3::zk::snark::plonk_constraint_system; - using AssignmentType = nil::blueprint::assignment>; - zk::snark::plonk_table_description desc( + using AssignmentType = + nil::blueprint::assignment>; + zk::snark::plonk_table_description desc( WitnessColumns, PublicInputColumns, ConstantColumns, SelectorColumns); using hash_type = nil::crypto3::hashes::keccak_1600<256>; constexpr std::size_t Lambda = 1; - using component_type = nil::blueprint::components::exponentiation; + using component_type = + nil::blueprint::components::exponentiation; - using var = nil::crypto3::zk::snark::plonk_variable; + using var = nil::crypto3::zk::snark::plonk_variable; var base(0, 0, false, var::column_type::public_input); var exponent(0, 1, false, var::column_type::public_input); @@ -70,31 +72,32 @@ void test_exponentiation(std::vector public_inpu typename component_type::input_type instance_input = {base, exponent}; typename BlueprintFieldType::value_type base_value = public_input[0]; - typename BlueprintFieldType::integral_type exponent_value_integral = typename BlueprintFieldType::integral_type(public_input[1].data); + typename BlueprintFieldType::integral_type exponent_value_integral = + typename BlueprintFieldType::integral_type(public_input[1].data); typename BlueprintFieldType::value_type expected_res = power(base_value, exponent_value_integral); auto result_check = [&expected_res, public_input](AssignmentType &assignment, - typename component_type::result_type &real_res) { - #ifdef BLUEPRINT_PLONK_PROFILING_ENABLED - std::cout << "exponentiation test: " << "\n"; - std::cout << "input : " << public_input[0].data << " " << public_input[1].data << "\n"; - std::cout << "expected: " << expected_res.data << "\n"; - std::cout << "real : " << var_value(assignment, real_res.output).data << "\n\n"; - #endif - assert(expected_res == var_value(assignment, real_res.output)); + typename component_type::result_type &real_res) { +#ifdef BLUEPRINT_PLONK_PROFILING_ENABLED + std::cout << "exponentiation test: " + << "\n"; + std::cout << "input : " << public_input[0].data << " " << public_input[1].data << "\n"; + std::cout << "expected: " << expected_res.data << "\n"; + std::cout << "real : " << var_value(assignment, real_res.output).data << "\n\n"; +#endif + assert(expected_res == var_value(assignment, real_res.output)); }; - component_type component_instance({0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14},{0},{}); + component_type component_instance({0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}, {0}, {}); - - nil::crypto3::test_component ( + nil::crypto3::test_component( component_instance, desc, public_input, result_check, instance_input); } -template -void exponentiation_tests(){ - for (int i = -2; i < 3; i++){ - for (int j = -2; j < 3; j++){ +template +void exponentiation_tests() { + for (int i = -2; i < 3; i++) { + for (int j = -2; j < 3; j++) { test_exponentiation({i, j}); } } diff --git a/test/algebra/fields/plonk/field_operations.cpp b/test/algebra/fields/plonk/field_operations.cpp index eea3329f6..494869963 100644 --- a/test/algebra/fields/plonk/field_operations.cpp +++ b/test/algebra/fields/plonk/field_operations.cpp @@ -49,8 +49,8 @@ using namespace nil; -template -void test_add(std::vector public_input){ +template +void test_add(std::vector public_input) { using BlueprintFieldType = FieldType; constexpr std::size_t WitnessColumns = 3; constexpr std::size_t PublicInputColumns = 1; @@ -65,34 +65,36 @@ void test_add(std::vector public_input){ using var = crypto3::zk::snark::plonk_variable; - using component_type = blueprint::components::addition>; + using component_type = blueprint::components:: + addition>; - typename component_type::input_type instance_input = { - var(0, 0, false, var::column_type::public_input), var(0, 1, false, var::column_type::public_input)}; + typename component_type::input_type instance_input = {var(0, 0, false, var::column_type::public_input), + var(0, 1, false, var::column_type::public_input)}; typename BlueprintFieldType::value_type expected_res = public_input[0] + public_input[1]; auto result_check = [&expected_res, public_input](AssignmentType &assignment, - typename component_type::result_type &real_res) { - #ifdef BLUEPRINT_PLONK_PROFILING_ENABLED - std::cout << "add test: " << "\n"; - std::cout << "input : " << public_input[0].data << " " << public_input[1].data << "\n"; - std::cout << "expected: " << expected_res.data << "\n"; - std::cout << "real : " << var_value(assignment, real_res.output).data << "\n\n"; - #endif - assert(expected_res == var_value(assignment, real_res.output)); + typename component_type::result_type &real_res) { +#ifdef BLUEPRINT_PLONK_PROFILING_ENABLED + std::cout << "add test: " + << "\n"; + std::cout << "input : " << public_input[0].data << " " << public_input[1].data << "\n"; + std::cout << "expected: " << expected_res.data << "\n"; + std::cout << "real : " << var_value(assignment, real_res.output).data << "\n\n"; +#endif + assert(expected_res == var_value(assignment, real_res.output)); }; - component_type component_instance({0, 1, 2},{},{}); + component_type component_instance({0, 1, 2}, {}, {}); - nil::crypto3::test_component ( + nil::crypto3::test_component( component_instance, desc, public_input, result_check, instance_input); - nil::crypto3::test_empty_component ( + nil::crypto3::test_empty_component( component_instance, desc, public_input, result_check, instance_input); } -template -void test_sub(std::vector public_input){ +template +void test_sub(std::vector public_input) { using BlueprintFieldType = FieldType; constexpr std::size_t WitnessColumns = 3; constexpr std::size_t PublicInputColumns = 1; @@ -107,34 +109,38 @@ void test_sub(std::vector public_input){ using var = crypto3::zk::snark::plonk_variable; - using component_type = blueprint::components::subtraction>; + using component_type = + blueprint::components::subtraction>; - typename component_type::input_type instance_input = { - var(0, 0, false, var::column_type::public_input), var(0, 1, false, var::column_type::public_input)}; + typename component_type::input_type instance_input = {var(0, 0, false, var::column_type::public_input), + var(0, 1, false, var::column_type::public_input)}; typename BlueprintFieldType::value_type expected_res = public_input[0] - public_input[1]; auto result_check = [&expected_res, public_input](AssignmentType &assignment, - typename component_type::result_type &real_res) { - #ifdef BLUEPRINT_PLONK_PROFILING_ENABLED - std::cout << "sub test: " << "\n"; - std::cout << "input : " << public_input[0].data << " " << public_input[1].data << "\n"; - std::cout << "expected: " << expected_res.data << "\n"; - std::cout << "real : " << var_value(assignment, real_res.output).data << "\n\n"; - #endif - assert(expected_res == var_value(assignment, real_res.output)); + typename component_type::result_type &real_res) { +#ifdef BLUEPRINT_PLONK_PROFILING_ENABLED + std::cout << "sub test: " + << "\n"; + std::cout << "input : " << public_input[0].data << " " << public_input[1].data << "\n"; + std::cout << "expected: " << expected_res.data << "\n"; + std::cout << "real : " << var_value(assignment, real_res.output).data << "\n\n"; +#endif + assert(expected_res == var_value(assignment, real_res.output)); }; - component_type component_instance({0, 1, 2},{},{}); + component_type component_instance({0, 1, 2}, {}, {}); - nil::crypto3::test_component ( + nil::crypto3::test_component( component_instance, desc, public_input, result_check, instance_input); - nil::crypto3::test_empty_component ( + nil::crypto3::test_empty_component( component_instance, desc, public_input, result_check, instance_input); } -template -void test_mul(std::vector public_input){ +template +void test_mul(std::vector public_input) { using BlueprintFieldType = FieldType; constexpr std::size_t WitnessColumns = 3; constexpr std::size_t PublicInputColumns = 1; @@ -149,35 +155,38 @@ void test_mul(std::vector public_input){ using var = crypto3::zk::snark::plonk_variable; - using component_type = blueprint::components::multiplication>; + using component_type = + blueprint::components::multiplication>; - typename component_type::input_type instance_input = { - var(0, 0, false, var::column_type::public_input), var(0, 1, false, var::column_type::public_input)}; + typename component_type::input_type instance_input = {var(0, 0, false, var::column_type::public_input), + var(0, 1, false, var::column_type::public_input)}; typename BlueprintFieldType::value_type expected_res = public_input[0] * public_input[1]; auto result_check = [&expected_res, public_input](AssignmentType &assignment, - typename component_type::result_type &real_res) { - #ifdef BLUEPRINT_PLONK_PROFILING_ENABLED - std::cout << "mul test: " << "\n"; - std::cout << "input : " << public_input[0].data << " " << public_input[1].data << "\n"; - std::cout << "expected: " << expected_res.data << "\n"; - std::cout << "real : " << var_value(assignment, real_res.output).data << "\n\n"; - #endif - assert(expected_res == var_value(assignment, real_res.output)); + typename component_type::result_type &real_res) { +#ifdef BLUEPRINT_PLONK_PROFILING_ENABLED + std::cout << "mul test: " + << "\n"; + std::cout << "input : " << public_input[0].data << " " << public_input[1].data << "\n"; + std::cout << "expected: " << expected_res.data << "\n"; + std::cout << "real : " << var_value(assignment, real_res.output).data << "\n\n"; +#endif + assert(expected_res == var_value(assignment, real_res.output)); }; - component_type component_instance({0, 1, 2},{},{}); + component_type component_instance({0, 1, 2}, {}, {}); - nil::crypto3::test_component ( + nil::crypto3::test_component( component_instance, desc, public_input, result_check, instance_input); - nil::crypto3::test_empty_component ( + nil::crypto3::test_empty_component( component_instance, desc, public_input, result_check, instance_input); } -template -void test_mul_by_const(std::vector public_input, - typename FieldType::value_type y){ +template +void test_mul_by_const(std::vector public_input, typename FieldType::value_type y) { using BlueprintFieldType = FieldType; constexpr std::size_t WitnessColumns = 2; constexpr std::size_t PublicInputColumns = 1; @@ -194,33 +203,32 @@ void test_mul_by_const(std::vector public_input, using component_type = blueprint::components::mul_by_constant; - typename component_type::input_type instance_input = { - var(0, 0, false, var::column_type::public_input)}; + typename component_type::input_type instance_input = {var(0, 0, false, var::column_type::public_input)}; typename BlueprintFieldType::value_type expected_res = public_input[0] * y; auto result_check = [&expected_res, public_input, y](AssignmentType &assignment, - typename component_type::result_type &real_res) { - #ifdef BLUEPRINT_PLONK_PROFILING_ENABLED - std::cout << "mul_by_const test: " << "\n"; - std::cout << "input : " << public_input[0].data << " " << y.data << "\n"; - std::cout << "expected: " << expected_res.data << "\n"; - std::cout << "real : " << var_value(assignment, real_res.output).data << "\n\n"; - #endif - assert(expected_res == var_value(assignment, real_res.output)); + typename component_type::result_type &real_res) { +#ifdef BLUEPRINT_PLONK_PROFILING_ENABLED + std::cout << "mul_by_const test: " + << "\n"; + std::cout << "input : " << public_input[0].data << " " << y.data << "\n"; + std::cout << "expected: " << expected_res.data << "\n"; + std::cout << "real : " << var_value(assignment, real_res.output).data << "\n\n"; +#endif + assert(expected_res == var_value(assignment, real_res.output)); }; - component_type component_instance({0, 1},{0},{},y); + component_type component_instance({0, 1}, {0}, {}, y); - nil::crypto3::test_component ( + nil::crypto3::test_component( component_instance, desc, public_input, result_check, instance_input); - nil::crypto3::test_empty_component ( + nil::crypto3::test_empty_component( component_instance, desc, public_input, result_check, instance_input); } -template -void test_div(std::vector public_input, - typename FieldType::value_type expected_res){ +template +void test_div(std::vector public_input, typename FieldType::value_type expected_res) { using BlueprintFieldType = FieldType; constexpr std::size_t WitnessColumns = 4; constexpr std::size_t PublicInputColumns = 1; @@ -234,26 +242,26 @@ void test_div(std::vector public_input, WitnessColumns, PublicInputColumns, ConstantColumns, SelectorColumns); using var = crypto3::zk::snark::plonk_variable; - using component_type = blueprint::components::division>; + using component_type = blueprint::components:: + division>; - typename component_type::input_type instance_input = { - var(0, 0, false, var::column_type::public_input), var(0, 1, false, var::column_type::public_input)}; + typename component_type::input_type instance_input = {var(0, 0, false, var::column_type::public_input), + var(0, 1, false, var::column_type::public_input)}; - auto result_check = [&expected_res](AssignmentType &assignment, - typename component_type::result_type &real_res) { - assert(expected_res == var_value(assignment, real_res.output)); + auto result_check = [&expected_res](AssignmentType &assignment, typename component_type::result_type &real_res) { + assert(expected_res == var_value(assignment, real_res.output)); }; - component_type component_instance({0, 1, 2, 3},{},{}); + component_type component_instance({0, 1, 2, 3}, {}, {}); - nil::crypto3::test_component ( + nil::crypto3::test_component( component_instance, desc, public_input, result_check, instance_input); - nil::crypto3::test_empty_component ( + nil::crypto3::test_empty_component( component_instance, desc, public_input, result_check, instance_input); } -template -void test_div_or_zero(std::vector public_input){ +template +void test_div_or_zero(std::vector public_input) { using BlueprintFieldType = FieldType; constexpr std::size_t WitnessColumns = 5; constexpr std::size_t PublicInputColumns = 1; @@ -270,8 +278,8 @@ void test_div_or_zero(std::vector public_input){ using component_type = blueprint::components::division_or_zero; - typename component_type::input_type instance_input = { - var(0, 0, false, var::column_type::public_input), var(0, 1, false, var::column_type::public_input)}; + typename component_type::input_type instance_input = {var(0, 0, false, var::column_type::public_input), + var(0, 1, false, var::column_type::public_input)}; typename FieldType::value_type expected_res; if (public_input[1] != 0) { @@ -281,25 +289,26 @@ void test_div_or_zero(std::vector public_input){ } auto result_check = [&expected_res, public_input](AssignmentType &assignment, - typename component_type::result_type &real_res) { - #ifdef BLUEPRINT_PLONK_PROFILING_ENABLED - std::cout << "div_or_zero test: " << "\n"; - std::cout << "input : " << public_input[0].data << " " << public_input[1].data << "\n"; - std::cout << "expected: " << expected_res.data << "\n"; - std::cout << "real : " << var_value(assignment, real_res.output).data << "\n\n"; - #endif - assert(expected_res == var_value(assignment, real_res.output)); + typename component_type::result_type &real_res) { +#ifdef BLUEPRINT_PLONK_PROFILING_ENABLED + std::cout << "div_or_zero test: " + << "\n"; + std::cout << "input : " << public_input[0].data << " " << public_input[1].data << "\n"; + std::cout << "expected: " << expected_res.data << "\n"; + std::cout << "real : " << var_value(assignment, real_res.output).data << "\n\n"; +#endif + assert(expected_res == var_value(assignment, real_res.output)); }; - component_type component_instance({0, 1, 2, 3, 4},{},{}); + component_type component_instance({0, 1, 2, 3, 4}, {}, {}); - nil::crypto3::test_component ( + nil::crypto3::test_component( component_instance, desc, public_input, result_check, instance_input); - nil::crypto3::test_empty_component ( + nil::crypto3::test_empty_component( component_instance, desc, public_input, result_check, instance_input); } -template +template void test_5_components(int i, int j) { test_add({i, j}); test_sub({i, j}); @@ -308,7 +317,7 @@ void test_5_components(int i, int j) { test_div_or_zero({i, j}); } -template +template void test_5_components_on_random_data() { nil::crypto3::random::algebraic_engine generate_random; boost::random::mt19937 seed_seq; @@ -324,15 +333,15 @@ void test_5_components_on_random_data() { test_div_or_zero({i, j}); } -template +template void field_operations_test() { - for (int i = -2; i < 3; i++){ - for (int j = -2; j < 3; j++){ + for (int i = -2; i < 3; i++) { + for (int j = -2; j < 3; j++) { test_5_components(i, j); } } - for (std::size_t i = 0; i < RandomTestsAmount; i++){ + for (std::size_t i = 0; i < RandomTestsAmount; i++) { test_5_components_on_random_data(); } } diff --git a/test/algebra/fields/plonk/logic_and_flag.cpp b/test/algebra/fields/plonk/logic_and_flag.cpp index 5cfc91b7e..4fe965ab6 100644 --- a/test/algebra/fields/plonk/logic_and_flag.cpp +++ b/test/algebra/fields/plonk/logic_and_flag.cpp @@ -46,11 +46,11 @@ auto test_logic_and_flag(std::vector pu constexpr std::size_t ConstantColumns = 0; constexpr std::size_t SelectorColumns = 1; - zk::snark::plonk_table_description desc = { - WitnessColumns, PublicInputColumns, ConstantColumns, SelectorColumns}; - using ArithmetizationType = - nil::crypto3::zk::snark::plonk_constraint_system; - using AssignmentType = nil::blueprint::assignment>; + zk::snark::plonk_table_description desc = {WitnessColumns, PublicInputColumns, ConstantColumns, + SelectorColumns}; + using ArithmetizationType = nil::crypto3::zk::snark::plonk_constraint_system; + using AssignmentType = + nil::blueprint::assignment>; using hash_type = nil::crypto3::hashes::keccak_1600<256>; constexpr std::size_t Lambda = 1; @@ -71,8 +71,7 @@ auto test_logic_and_flag(std::vector pu typename BlueprintFieldType::value_type p = public_input[0] * public_input[1]; typename BlueprintFieldType::value_type expected_result = (p.is_zero() ? p : BlueprintFieldType::value_type::one()); - auto result_check = [&expected_result](AssignmentType &assignment, - typename component_type::result_type &real_res) { + auto result_check = [&expected_result](AssignmentType &assignment, typename component_type::result_type &real_res) { #ifdef BLUEPRINT_PLONK_PROFILING_ENABLED std::cout << "logic and test: \n"; std::cout << "input : " << public_input[0].data << " " << public_input[1].data << "\n"; diff --git a/test/algebra/fields/plonk/logic_or_flag.cpp b/test/algebra/fields/plonk/logic_or_flag.cpp index e926c68ae..f27baaa28 100644 --- a/test/algebra/fields/plonk/logic_or_flag.cpp +++ b/test/algebra/fields/plonk/logic_or_flag.cpp @@ -51,9 +51,9 @@ auto test_logic_or_flag(std::vector pub zk::snark::plonk_table_description desc( WitnessColumns, PublicInputColumns, ConstantColumns, SelectorColumns); - using ArithmetizationType = - nil::crypto3::zk::snark::plonk_constraint_system; - using AssignmentType = nil::blueprint::assignment>; + using ArithmetizationType = nil::crypto3::zk::snark::plonk_constraint_system; + using AssignmentType = + nil::blueprint::assignment>; using hash_type = nil::crypto3::hashes::keccak_1600<256>; constexpr std::size_t Lambda = 1; @@ -77,8 +77,7 @@ auto test_logic_or_flag(std::vector pub (public_input[1].is_zero() ? public_input[1] : BlueprintFieldType::value_type::one()); typename BlueprintFieldType::value_type expected_result = fx + fy - fx * fy; - auto result_check = [&expected_result](AssignmentType &assignment, - typename component_type::result_type &real_res) { + auto result_check = [&expected_result](AssignmentType &assignment, typename component_type::result_type &real_res) { #ifdef BLUEPRINT_PLONK_PROFILING_ENABLED std::cout << "logic or test: \n"; std::cout << "input : " << public_input[0].data << " " << public_input[1].data << "\n"; diff --git a/test/algebra/fields/plonk/range_check.cpp b/test/algebra/fields/plonk/range_check.cpp index b3c781bd9..3b1073e9d 100644 --- a/test/algebra/fields/plonk/range_check.cpp +++ b/test/algebra/fields/plonk/range_check.cpp @@ -57,26 +57,26 @@ std::size_t clz(typename BlueprintFieldType::value_type value) { return count; } -template -auto test_range_check(typename BlueprintFieldType::value_type input, - const std::map, typename BlueprintFieldType::value_type> - &patches = {}) { +template +auto test_range_check( + typename BlueprintFieldType::value_type input, + const std::map, typename BlueprintFieldType::value_type> &patches = {}) { constexpr std::size_t PublicInputColumns = 1; constexpr std::size_t ConstantColumns = 1; // We use either one or two depending on whether R divides chunk_size or not. // Since we need to know SelectorColumns amount before the component is actually intialized, // we use two. constexpr std::size_t SelectorColumns = 2; - zk::snark::plonk_table_description desc( - WitnessesAmount, PublicInputColumns, ConstantColumns, SelectorColumns); + zk::snark::plonk_table_description desc(WitnessesAmount, PublicInputColumns, ConstantColumns, + SelectorColumns); using ArithmetizationType = nil::crypto3::zk::snark::plonk_constraint_system; - using AssignmentType = nil::blueprint::assignment>; - using hash_type = nil::crypto3::hashes::keccak_1600<256>; + using AssignmentType = + nil::blueprint::assignment>; + using hash_type = nil::crypto3::hashes::keccak_1600<256>; constexpr std::size_t Lambda = 1; using component_type = nil::blueprint::components::range_check; - using var = nil::crypto3::zk::snark::plonk_variable; + using var = nil::crypto3::zk::snark::plonk_variable; using value_type = typename BlueprintFieldType::value_type; var x(0, 0, false, var::column_type::public_input); @@ -85,9 +85,9 @@ auto test_range_check(typename BlueprintFieldType::value_type input, typename component_type::input_type instance_input = {x}; - #ifdef BLUEPRINT_PLONK_PROFILING_ENABLED +#ifdef BLUEPRINT_PLONK_PROFILING_ENABLED std::cout << "range_check_test_input: " << std::hex << public_input[0].data << "\n"; - #endif +#endif auto result_check = [](AssignmentType &assignment, typename component_type::result_type &real_res) {}; const bool expected_to_pass = input < value_type(2).pow(R); @@ -97,8 +97,8 @@ auto test_range_check(typename BlueprintFieldType::value_type input, witnesses[i] = i; } - component_type component_instance = component_type(witnesses, std::array({0}), - std::array({0}), R); + component_type component_instance = + component_type(witnesses, std::array({0}), std::array({0}), R); if (!CustomAssignments) { if (expected_to_pass) { @@ -106,27 +106,23 @@ auto test_range_check(typename BlueprintFieldType::value_type input, component_instance, desc, public_input, result_check, instance_input, nil::blueprint::connectedness_check_type::type::STRONG, R); } else { - nil::crypto3::test_component_to_fail( - component_instance, desc, public_input, result_check, instance_input, - nil::blueprint::connectedness_check_type::type::STRONG, R); + nil::crypto3::test_component_to_fail( + component_instance, desc, public_input, result_check, instance_input, + nil::blueprint::connectedness_check_type::type::STRONG, R); } } else { - auto custom_assignment = nil::crypto3::generate_patched_assignments< - BlueprintFieldType, component_type>(patches); + auto custom_assignment = + nil::crypto3::generate_patched_assignments(patches); if (expected_to_pass) { - nil::crypto3::test_component_custom_assignments( - component_instance, desc, public_input, - result_check, custom_assignment, instance_input, - nil::blueprint::connectedness_check_type::type::STRONG, R); + nil::crypto3::test_component_custom_assignments( + component_instance, desc, public_input, result_check, custom_assignment, instance_input, + nil::blueprint::connectedness_check_type::type::STRONG, R); } else { - nil::crypto3::test_component_to_fail_custom_assignments( - component_instance, desc, public_input, result_check, - custom_assignment, instance_input, - nil::blueprint::connectedness_check_type::type::STRONG, R); + nil::crypto3::test_component_to_fail_custom_assignments( + component_instance, desc, public_input, result_check, custom_assignment, instance_input, + nil::blueprint::connectedness_check_type::type::STRONG, R); } } } @@ -143,8 +139,7 @@ void test_range_check_specific_inputs() { test_range_check(-1); test_range_check(value_type(2).pow(R)); test_range_check( - 0x4000000000000000000000000000000000000000000000000000000000000000_cppui256 - ); + 0x4000000000000000000000000000000000000000000000000000000000000000_cppui256); } template @@ -158,19 +153,19 @@ void test_range_check_random_inputs() { value_type max_value = value_type(2).pow(R); - for (std::size_t i = 0; i < RandomTestsAmount; i++){ + for (std::size_t i = 0; i < RandomTestsAmount; i++) { value_type input = generate_random(); - integral_type input_integral = integral_type(input.data); + integral_type input_integral = integral_type(input.data); input_integral = input_integral & integral_type((max_value - 1).data); - value_type input_scalar = input_integral; + value_type input_scalar = input_integral; // Sanity check assert(input_scalar < max_value); test_range_check(input_scalar); - } + } } template -void test_range_check_fail_random_inputs(){ +void test_range_check_fail_random_inputs() { using value_type = typename BlueprintFieldType::value_type; using integral_type = typename BlueprintFieldType::integral_type; @@ -181,13 +176,13 @@ void test_range_check_fail_random_inputs(){ value_type max_value = value_type(2).pow(R); integral_type restriction_modulus = BlueprintFieldType::modulus - integral_type(max_value.data); - for (std::size_t i = 0; i < RandomTestsAmount; i++){ + for (std::size_t i = 0; i < RandomTestsAmount; i++) { value_type input = generate_random(); input = max_value + (value_type(integral_type(input.data) % restriction_modulus)); // Sanity check assert(input >= max_value); test_range_check(input); - } + } } constexpr static const std::size_t random_tests_amount = 10; @@ -328,9 +323,8 @@ BOOST_AUTO_TEST_CASE(blueprint_plonk_fields_range_check_oops_first_chunk_overflo test_range_check(test_val, patches); using field_type_2 = nil::crypto3::algebra::curves::vesta::scalar_field_type; - test_range_check(2, - {std::make_pair(std::make_pair(1, 14), 2), - std::make_pair(std::make_pair(1, 0 ), 2)}); + test_range_check( + 2, {std::make_pair(std::make_pair(1, 14), 2), std::make_pair(std::make_pair(1, 0), 2)}); } BOOST_AUTO_TEST_CASE(blueprint_plonk_fields_range_check_oops_wrong_chunks) { diff --git a/test/algebra/fields/plonk/sqrt.cpp b/test/algebra/fields/plonk/sqrt.cpp index 9de034d08..d8c0495dc 100644 --- a/test/algebra/fields/plonk/sqrt.cpp +++ b/test/algebra/fields/plonk/sqrt.cpp @@ -48,14 +48,14 @@ using namespace nil::crypto3; using namespace nil::blueprint; -template +template void test_sqrt(typename BlueprintFieldType::value_type input) { constexpr std::size_t WitnessColumns = 15; constexpr std::size_t PublicInputColumns = 1; constexpr std::size_t ConstantColumns = 1; constexpr std::size_t SelectorColumns = 4; - zk::snark::plonk_table_description desc( - WitnessColumns, PublicInputColumns, ConstantColumns, SelectorColumns); + zk::snark::plonk_table_description desc(WitnessColumns, PublicInputColumns, ConstantColumns, + SelectorColumns); using ArithmetizationType = zk::snark::plonk_constraint_system; using AssignmentType = assignment; using hash_type = nil::crypto3::hashes::keccak_1600<256>; @@ -67,8 +67,7 @@ void test_sqrt(typename BlueprintFieldType::value_type input) { typename BlueprintFieldType::value_type expected_res = input.sqrt(); - typename component_type::input_type instance_input = { - var(0, 0, false, var::column_type::public_input)}; + typename component_type::input_type instance_input = {var(0, 0, false, var::column_type::public_input)}; std::vector public_input = {input}; @@ -78,8 +77,8 @@ void test_sqrt(typename BlueprintFieldType::value_type input) { assert(expected_res == var_value(assignment, real_res.output)); }; - test_component - (component_instance, desc, public_input, result_check, instance_input); + test_component(component_instance, desc, public_input, + result_check, instance_input); } static const std::size_t random_tests_amount = 10; diff --git a/test/basic_components_r1cs_gg_ppzksnark.cpp b/test/basic_components_r1cs_gg_ppzksnark.cpp index 6b055151a..dbd0a7fdb 100644 --- a/test/basic_components_r1cs_gg_ppzksnark.cpp +++ b/test/basic_components_r1cs_gg_ppzksnark.cpp @@ -61,6 +61,7 @@ #include +using namespace nil; using namespace nil::crypto3; using namespace nil::crypto3::zk; using namespace nil::crypto3::algebra; @@ -73,8 +74,8 @@ void test_disjunction_component(std::size_t w) { std::size_t n = std::log2(w) + ((w > (1ul << std::size_t(std::log2(w)))) ? 1 : 0); - blueprint::blueprint bp; - nil::crypto3::blueprint::detail::blueprint_variable output; + blueprint bp; + blueprint::detail::blueprint_variable output; output.allocate(bp); bp.set_input_sizes(1); diff --git a/test/hashes/r1cs/pedersen.cpp b/test/hashes/r1cs/pedersen.cpp index 111c1d172..ea2dfa802 100644 --- a/test/hashes/r1cs/pedersen.cpp +++ b/test/hashes/r1cs/pedersen.cpp @@ -36,8 +36,8 @@ #include #include #include -#include +using namespace nil; using namespace nil::crypto3; using namespace nil::crypto3::zk; using namespace nil::crypto3::algebra; @@ -54,8 +54,8 @@ void test_blueprint_variable_vector_component_constructor(const std::vector bp, bp_manual; - nil::crypto3::zk::detail::blueprint_variable_vector scalar, scalar_manual; + blueprint::blueprint bp, bp_manual; + blueprint::detail::blueprint_variable_vector scalar, scalar_manual; scalar.allocate(bp, in_bits.size()); scalar.fill_with_bits(bp, in_bits); scalar_manual.allocate(bp_manual, in_bits.size()); @@ -88,8 +88,9 @@ void test_block_variable_component_constructor(const std::vector &in_bits, using field_type = typename HashComponent::field_type; // input as block_variable - blueprint bp, bp_manual; - components::block_variable in_block(bp, in_bits.size()), in_block_manual(bp_manual, in_bits.size()); + blueprint::blueprint bp, bp_manual; + blueprint::components::block_variable in_block(bp, in_bits.size()), + in_block_manual(bp_manual, in_bits.size()); in_block.generate_assignments(in_bits); in_block_manual.generate_assignments(in_bits); @@ -117,16 +118,16 @@ void test_block_variables_component_constructor(const std::vector &in_bits using field_type = typename HashComponent::field_type; // input as container of block_variable - blueprint bp, bp_manual; + blueprint::blueprint bp, bp_manual; std::size_t half_size = in_bits.size() / 2; - components::block_variable in_block_left(bp, half_size), in_block_right(bp, in_bits.size() - half_size), - in_block_manual_left(bp_manual, half_size), in_block_manual_right(bp_manual, in_bits.size() - half_size); + blueprint::components::block_variable in_block_left(bp, half_size), + in_block_right(bp, in_bits.size() - half_size), in_block_manual_left(bp_manual, half_size), + in_block_manual_right(bp_manual, in_bits.size() - half_size); in_block_left.generate_assignments(std::vector(std::cbegin(in_bits), std::cbegin(in_bits) + half_size)); in_block_right.generate_assignments(std::vector(std::cbegin(in_bits) + half_size, std::cend(in_bits))); in_block_manual_left.generate_assignments( std::vector(std::cbegin(in_bits), std::cbegin(in_bits) + half_size)); - in_block_manual_right.generate_assignments( - std::vector(std::cbegin(in_bits) + half_size, std::cend(in_bits))); + in_block_manual_right.generate_assignments(std::vector(std::cbegin(in_bits) + half_size, std::cend(in_bits))); // Auto allocation of the result HashComponent hash_comp(bp, @@ -162,8 +163,8 @@ void test_blueprint_variable_vector_component_constructor(const std::vector bp_bits, bp_bits_manual; - nil::crypto3::zk::detail::blueprint_variable_vector scalar_bits, scalar_bits_manual; + blueprint::blueprint bp_bits, bp_bits_manual; + blueprint::detail::blueprint_variable_vector scalar_bits, scalar_bits_manual; scalar_bits.allocate(bp_bits, in_bits.size()); scalar_bits.fill_with_bits(bp_bits, in_bits); scalar_bits_manual.allocate(bp_bits_manual, in_bits.size()); @@ -195,8 +196,8 @@ void test_digest_variable_component_constructor(const std::vector &in_bits using field_type = typename HashComponent::field_type; // input as digest_variable - blueprint bp_bits, bp_bits_manual; - components::digest_variable in_block(bp_bits, in_bits.size()), + blueprint::blueprint bp_bits, bp_bits_manual; + blueprint::components::digest_variable in_block(bp_bits, in_bits.size()), in_block_manual(bp_bits_manual, in_bits.size()); in_block.generate_assignments(in_bits); in_block_manual.generate_assignments(in_bits); @@ -224,17 +225,16 @@ void test_digest_variables_component_constructor(const std::vector &in_bit using field_type = typename HashComponent::field_type; // input as container of block_variable - blueprint bp_bits, bp_bits_manual; + blueprint::blueprint bp_bits, bp_bits_manual; std::size_t half_size = in_bits.size() / 2; - components::digest_variable in_block_left(bp_bits, half_size), + blueprint::components::digest_variable in_block_left(bp_bits, half_size), in_block_right(bp_bits, in_bits.size() - half_size), in_block_manual_left(bp_bits_manual, half_size), in_block_manual_right(bp_bits_manual, in_bits.size() - half_size); in_block_left.generate_assignments(std::vector(std::cbegin(in_bits), std::cbegin(in_bits) + half_size)); in_block_right.generate_assignments(std::vector(std::cbegin(in_bits) + half_size, std::cend(in_bits))); in_block_manual_left.generate_assignments( std::vector(std::cbegin(in_bits), std::cbegin(in_bits) + half_size)); - in_block_manual_right.generate_assignments( - std::vector(std::cbegin(in_bits) + half_size, std::cend(in_bits))); + in_block_manual_right.generate_assignments(std::vector(std::cbegin(in_bits) + half_size, std::cend(in_bits))); // Auto allocation of the result HashComponent hash_comp_bits(bp_bits, @@ -263,8 +263,8 @@ void test_digest_variables_component_constructor(const std::vector &in_bit // TODO: extend tests (check verification of wrong values) template, - typename HashComponent = components::pedersen> + typename HashToPointComponent = blueprint::components::pedersen_to_point, + typename HashComponent = blueprint::components::pedersen> void test_pedersen_default_params_component( const std::vector &in_bits, const typename HashToPointComponent::element_component::group_value_type &expected, diff --git a/test/merkle_tree_components.cpp b/test/merkle_tree_components.cpp index fd3d1c5d5..f201e35b3 100644 --- a/test/merkle_tree_components.cpp +++ b/test/merkle_tree_components.cpp @@ -30,180 +30,180 @@ #include -// TODO: fix sha256 component -// #include +#include #include -// TODO: fix update component -// #include -#include +#include +#include +#include +using namespace nil; using namespace nil::crypto3; using namespace nil::crypto3::zk; using namespace nil::crypto3::algebra; -// template -// void test_merkle_tree_check_update_component() { -// /* prepare test */ -// const std::size_t digest_len = Hash::get_digest_len(); -// -// const std::size_t tree_depth = 16; -// std::vector prev_path(tree_depth); -// -// std::vector prev_load_hash(digest_len); -// std::generate(prev_load_hash.begin(), prev_load_hash.end(), [&]() { return std::rand() % 2; }); -// std::vector prev_store_hash(digest_len); -// std::generate(prev_store_hash.begin(), prev_store_hash.end(), [&]() { return std::rand() % 2; }); -// -// std::vector loaded_leaf = prev_load_hash; -// std::vector stored_leaf = prev_store_hash; -// -// std::vector address_bits; -// -// std::size_t address = 0; -// for (long level = tree_depth - 1; level >= 0; --level) { -// const bool computed_is_right = (std::rand() % 2); -// address |= (computed_is_right ? 1ul << (tree_depth - 1 - level) : 0); -// address_bits.push_back(computed_is_right); -// std::vector other(digest_len); -// std::generate(other.begin(), other.end(), [&]() { return std::rand() % 2; }); -// -// std::vector load_block = prev_load_hash; -// load_block.insert(computed_is_right ? load_block.begin() : load_block.end(), other.begin(), other.end()); -// std::vector store_block = prev_store_hash; -// store_block.insert(computed_is_right ? store_block.begin() : store_block.end(), other.begin(), other.end()); -// -// std::vector load_h = Hash::get_hash(load_block); -// std::vector store_h = Hash::get_hash(store_block); -// -// prev_path[level] = other; -// -// prev_load_hash = load_h; -// prev_store_hash = store_h; -// } -// -// std::vector load_root = prev_load_hash; -// std::vector store_root = prev_store_hash; -// -// /* execute the test */ -// components::blueprint bp; -// components::blueprint_variable_vector address_bits_va; -// address_bits_va.allocate(bp, tree_depth); -// components::digest_variable prev_leaf_digest(bp, digest_len); -// components::digest_variable prev_root_digest(bp, digest_len); -// components::merkle_authentication_path_variable prev_path_var(bp, tree_depth); -// components::digest_variable next_leaf_digest(bp, digest_len); -// components::digest_variable next_root_digest(bp, digest_len); -// components::merkle_authentication_path_variable next_path_var(bp, tree_depth); -// components::merkle_tree_check_update_components mls( -// bp, tree_depth, address_bits_va, prev_leaf_digest, prev_root_digest, prev_path_var, next_leaf_digest, -// next_root_digest, next_path_var, components::blueprint_variable(0)); -// -// prev_path_var.generate_gates(); -// mls.generate_gates(); -// -// address_bits_va.fill_with_bits(bp, address_bits); -// BOOST_REQUIRE(address_bits_va.get_field_element_from_bits(bp) == address); -// prev_leaf_digest.generate_assignments(loaded_leaf); -// prev_path_var.generate_assignments(address, prev_path); -// next_leaf_digest.generate_assignments(stored_leaf); -// address_bits_va.fill_with_bits(bp, address_bits); -// mls.generate_assignments(); -// -// /* make sure that update check will check for the right things */ -// prev_leaf_digest.generate_assignments(loaded_leaf); -// next_leaf_digest.generate_assignments(stored_leaf); -// prev_root_digest.generate_assignments(load_root); -// next_root_digest.generate_assignments(store_root); -// address_bits_va.fill_with_bits(bp, address_bits); -// BOOST_REQUIRE(bp.is_satisfied()); -// -// const std::size_t num_constraints = bp.num_constraints(); -// const std::size_t expected_constraints = -// components::merkle_tree_check_update_components::expected_constraints(tree_depth); -// BOOST_REQUIRE(num_constraints == expected_constraints); -// } +template +void test_merkle_tree_check_update_component() { + /* prepare test */ + const std::size_t digest_len = Hash::get_digest_len(); -// template -// void test_merkle_tree_check_read_component() { -// /* prepare test */ -// const std::size_t digest_len = Hash::get_digest_len(); -// const std::size_t tree_depth = 16; -// std::vector path(tree_depth); -// -// std::vector prev_hash(digest_len); -// std::generate(prev_hash.begin(), prev_hash.end(), [&]() { return std::rand() % 2; }); -// std::vector leaf = prev_hash; -// -// std::vector address_bits; -// -// std::size_t address = 0; -// for (long level = tree_depth - 1; level >= 0; --level) { -// const bool computed_is_right = (std::rand() % 2); -// address |= (computed_is_right ? 1ul << (tree_depth - 1 - level) : 0); -// address_bits.push_back(computed_is_right); -// std::vector other(digest_len); -// std::generate(other.begin(), other.end(), [&]() { return std::rand() % 2; }); -// -// std::vector block = prev_hash; -// block.insert(computed_is_right ? block.begin() : block.end(), other.begin(), other.end()); -// std::vector h = Hash::get_hash(block); -// -// path[level] = other; -// -// prev_hash = h; -// } -// std::vector root = prev_hash; -// -// /* execute test */ -// components::blueprint bp; -// components::blueprint_variable_vector address_bits_va; -// address_bits_va.allocate(bp, tree_depth); -// components::digest_variable leaf_digest(bp, digest_len); -// components::digest_variable root_digest(bp, digest_len); -// components::merkle_authentication_path_variable path_var(bp, tree_depth); -// components::merkle_tree_check_read_component ml(bp, tree_depth, address_bits_va, leaf_digest, -// root_digest, path_var, -// components::blueprint_variable(0)); -// -// path_var.generate_gates(); -// ml.generate_gates(); -// -// address_bits_va.fill_with_bits(bp, address_bits); -// BOOST_REQUIRE(address_bits_va.get_field_element_from_bits(bp) == address); -// leaf_digest.generate_assignments(leaf); -// path_var.generate_assignments(address, path); -// ml.generate_assignments(); -// -// /* make sure that read checker didn't accidentally overwrite anything */ -// address_bits_va.fill_with_bits(bp, address_bits); -// leaf_digest.generate_assignments(leaf); -// root_digest.generate_assignments(root); -// BOOST_REQUIRE(bp.is_satisfied()); -// -// const std::size_t num_constraints = bp.num_constraints(); -// const std::size_t expected_constraints = -// components::merkle_tree_check_read_component::expected_constraints(tree_depth); -// BOOST_REQUIRE(num_constraints == expected_constraints); -// } + const std::size_t tree_depth = 16; + std::vector, 2>> prev_path(tree_depth); -// template -// void test_all_merkle_tree_components() { -// typedef typename CurveType::scalar_field_type scalar_field_type; -// -// // for now all CRH components are knapsack CRH's; can be easily extended -// // later to more expressive selector types. -// using crh_with_field_out_component = components::knapsack_crh_with_field_out_component; -// using crh_with_bit_out_component = components::knapsack_crh_with_bit_out_component; -// -// test_merkle_tree_check_read_component(); -// test_merkle_tree_check_read_component>(); -// -// test_merkle_tree_check_update_component(); -// test_merkle_tree_check_update_component>(); -// } + std::vector prev_load_hash(digest_len); + std::generate(prev_load_hash.begin(), prev_load_hash.end(), [&]() { return std::rand() % 2; }); + std::vector prev_store_hash(digest_len); + std::generate(prev_store_hash.begin(), prev_store_hash.end(), [&]() { return std::rand() % 2; }); + + std::vector loaded_leaf = prev_load_hash; + std::vector stored_leaf = prev_store_hash; + + std::vector address_bits; + + std::size_t address = 0; + for (long level = tree_depth - 1; level >= 0; --level) { + const bool computed_is_right = (std::rand() % 2); + address |= (computed_is_right ? 1ul << (tree_depth - 1 - level) : 0); + address_bits.push_back(computed_is_right); + std::vector other(digest_len); + std::generate(other.begin(), other.end(), [&]() { return std::rand() % 2; }); + + std::vector load_block = prev_load_hash; + load_block.insert(computed_is_right ? load_block.begin() : load_block.end(), other.begin(), other.end()); + std::vector store_block = prev_store_hash; + store_block.insert(computed_is_right ? store_block.begin() : store_block.end(), other.begin(), other.end()); + + std::vector load_h = Hash::get_hash(load_block); + std::vector store_h = Hash::get_hash(store_block); + + prev_path[level] = other; + + prev_load_hash = load_h; + prev_store_hash = store_h; + } + + std::vector load_root = prev_load_hash; + std::vector store_root = prev_store_hash; + + /* execute the test */ + blueprint::blueprint bp; + blueprint::detail::blueprint_variable_vector address_bits_va; + address_bits_va.allocate(bp, tree_depth); + blueprint::components::digest_variable prev_leaf_digest(bp, digest_len); + blueprint::components::digest_variable prev_root_digest(bp, digest_len); + blueprint::components::merkle_authentication_path_variable prev_path_var(bp, tree_depth); + blueprint::components::digest_variable next_leaf_digest(bp, digest_len); + blueprint::components::digest_variable next_root_digest(bp, digest_len); + blueprint::components::merkle_authentication_path_variable next_path_var(bp, tree_depth); + blueprint::components::merkle_proof_update mls( + bp, tree_depth, address_bits_va, prev_leaf_digest, prev_root_digest, prev_path_var, next_leaf_digest, + next_root_digest, next_path_var, blueprint::detail::blueprint_variable(0)); + + prev_path_var.generate_gates(); + mls.generate_gates(); + + address_bits_va.fill_with_bits(bp, address_bits); + BOOST_REQUIRE(address_bits_va.get_field_element_from_bits(bp) == address); + prev_leaf_digest.generate_assignments(loaded_leaf); + prev_path_var.generate_assignments(address, prev_path); + next_leaf_digest.generate_assignments(stored_leaf); + address_bits_va.fill_with_bits(bp, address_bits); + mls.generate_assignments(); + + /* make sure that update check will check for the right things */ + prev_leaf_digest.generate_assignments(loaded_leaf); + next_leaf_digest.generate_assignments(stored_leaf); + prev_root_digest.generate_assignments(load_root); + next_root_digest.generate_assignments(store_root); + address_bits_va.fill_with_bits(bp, address_bits); + BOOST_REQUIRE(bp.is_satisfied()); + + const std::size_t num_constraints = bp.num_constraints(); + const std::size_t expected_constraints = + components::merkle_tree_check_update_components::expected_constraints(tree_depth); + BOOST_REQUIRE(num_constraints == expected_constraints); +} + +template +void test_merkle_tree_check_read_component() { + /* prepare test */ + const std::size_t digest_len = Hash::get_digest_len(); + const std::size_t tree_depth = 16; + std::vector path(tree_depth); + + std::vector prev_hash(digest_len); + std::generate(prev_hash.begin(), prev_hash.end(), [&]() { return std::rand() % 2; }); + std::vector leaf = prev_hash; + + std::vector address_bits; + + std::size_t address = 0; + for (long level = tree_depth - 1; level >= 0; --level) { + const bool computed_is_right = (std::rand() % 2); + address |= (computed_is_right ? 1ul << (tree_depth - 1 - level) : 0); + address_bits.push_back(computed_is_right); + std::vector other(digest_len); + std::generate(other.begin(), other.end(), [&]() { return std::rand() % 2; }); + + std::vector block = prev_hash; + block.insert(computed_is_right ? block.begin() : block.end(), other.begin(), other.end()); + std::vector h = Hash::get_hash(block); + + path[level] = other; + + prev_hash = h; + } + std::vector root = prev_hash; + + /* execute test */ + components::blueprint bp; + components::blueprint_variable_vector address_bits_va; + address_bits_va.allocate(bp, tree_depth); + components::digest_variable leaf_digest(bp, digest_len); + components::digest_variable root_digest(bp, digest_len); + components::merkle_authentication_path_variable path_var(bp, tree_depth); + components::merkle_tree_check_read_component ml(bp, tree_depth, address_bits_va, leaf_digest, + root_digest, path_var, + components::blueprint_variable(0)); + + path_var.generate_gates(); + ml.generate_gates(); + + address_bits_va.fill_with_bits(bp, address_bits); + BOOST_REQUIRE(address_bits_va.get_field_element_from_bits(bp) == address); + leaf_digest.generate_assignments(leaf); + path_var.generate_assignments(address, path); + ml.generate_assignments(); + + /* make sure that read checker didn't accidentally overwrite anything */ + address_bits_va.fill_with_bits(bp, address_bits); + leaf_digest.generate_assignments(leaf); + root_digest.generate_assignments(root); + BOOST_REQUIRE(bp.is_satisfied()); + + const std::size_t num_constraints = bp.num_constraints(); + const std::size_t expected_constraints = + components::merkle_tree_check_read_component::expected_constraints(tree_depth); + BOOST_REQUIRE(num_constraints == expected_constraints); +} + +template +void test_all_merkle_tree_components() { + typedef typename CurveType::scalar_field_type scalar_field_type; + + // for now all CRH components are knapsack CRH's; can be easily extended + // later to more expressive selector types. + using crh_with_field_out_component = components::knapsack_crh_with_field_out_component; + using crh_with_bit_out_component = components::knapsack_crh_with_bit_out_component; + + test_merkle_tree_check_read_component(); + test_merkle_tree_check_read_component>(); + + test_merkle_tree_check_update_component(); + test_merkle_tree_check_update_component>(); +} template std::vector calculate_pedersen_via_component(const std::vector &in_bits) { diff --git a/test/test_plonk_component.hpp b/test/test_plonk_component.hpp index 3711108c8..02dd667cc 100644 --- a/test/test_plonk_component.hpp +++ b/test/test_plonk_component.hpp @@ -50,7 +50,7 @@ #include #include #include -//#include +// #include #include #include #include @@ -71,13 +71,12 @@ namespace nil { namespace blueprint { namespace components { template - std::tuple< - nil::crypto3::zk::snark::plonk_table_description, - circuit>, - assignment>> - generate_empty_assignments(); + std::tuple, + circuit>, + assignment>> + generate_empty_assignments(); } - } + } // namespace blueprint namespace crypto3 { inline std::vector generate_random_step_list(const std::size_t r, const std::size_t max_step) { @@ -103,7 +102,8 @@ namespace nil { } template - typename fri_type::params_type create_fri_params(std::size_t degree_log, const std::size_t expand_factor = 4, const std::size_t max_step = 1) { + typename fri_type::params_type create_fri_params(std::size_t degree_log, const std::size_t expand_factor = 4, + const std::size_t max_step = 1) { math::polynomial q = {0, 0, 1}; const std::size_t r = degree_log - 1; @@ -111,12 +111,8 @@ namespace nil { std::vector>> domain_set = math::calculate_domain_set(degree_log + expand_factor, r); - typename fri_type::params_type params( - (1 << degree_log) - 1, - domain_set, - generate_random_step_list(r, max_step), - expand_factor - ); + typename fri_type::params_type params((1 << degree_log) - 1, domain_set, + generate_random_step_list(r, max_step), expand_factor); return params; } @@ -125,15 +121,14 @@ namespace nil { class plonk_test_assigner { public: virtual typename ComponentType::result_type operator()( - const ComponentType&, - nil::blueprint::assignment>&, - const typename ComponentType::input_type&, + const ComponentType &, + nil::blueprint::assignment> &, + const typename ComponentType::input_type &, const std::uint32_t) const = 0; }; template - class plonk_test_default_assigner : - public plonk_test_assigner { + class plonk_test_default_assigner : public plonk_test_assigner { public: typename ComponentType::result_type operator()( const ComponentType &component, @@ -141,22 +136,21 @@ namespace nil { const typename ComponentType::input_type &instance_input, const std::uint32_t start_row_index) const override { - return blueprint::components::generate_assignments( - component, assignment, instance_input, start_row_index); + return blueprint::components::generate_assignments(component, assignment, + instance_input, start_row_index); } }; template - class plonk_test_custom_assigner : - public plonk_test_assigner { - - using assigner_type = - std::function>&, - const typename ComponentType::input_type&, - const std::uint32_t)>; + class plonk_test_custom_assigner : public plonk_test_assigner { + + using assigner_type = std::function> &, + const typename ComponentType::input_type &, + const std::uint32_t)>; assigner_type assigner; + public: plonk_test_custom_assigner(assigner_type assigner) : assigner(assigner) {}; @@ -170,12 +164,12 @@ namespace nil { } }; - template< - typename ComponentType, typename BlueprintFieldType, typename Hash, - std::size_t Lambda, typename PublicInputContainerType, typename FunctorResultCheck, bool PrivateInput, - typename... ComponentStaticInfoArgs> + template auto prepare_component(ComponentType component_instance, - zk::snark::plonk_table_description desc, + zk::snark::plonk_table_description + desc, const PublicInputContainerType &public_input, const FunctorResultCheck &result_check, const plonk_test_assigner &assigner, @@ -188,9 +182,9 @@ namespace nil { blueprint::circuit> bp; blueprint::assignment> assignment(desc); - if constexpr( nil::blueprint::use_lookups() ){ + if constexpr (nil::blueprint::use_lookups()) { auto lookup_tables = component_instance.component_lookup_tables(); - for(auto &[k,v]:lookup_tables){ + for (auto &[k, v] : lookup_tables) { bp.reserve_table(k); } }; @@ -209,20 +203,17 @@ namespace nil { } } - blueprint::components::generate_circuit( - component_instance, bp, assignment, instance_input, start_row); + blueprint::components::generate_circuit(component_instance, bp, assignment, + instance_input, start_row); auto component_result = boost::get( assigner(component_instance, assignment, instance_input, start_row)); result_check(assignment, component_result); if constexpr (!PrivateInput) { - bool is_connected = check_connectedness( - assignment, - bp, - instance_input.all_vars(), - component_result.all_vars(), start_row, component_instance.rows_amount, - connectedness_check); + bool is_connected = + check_connectedness(assignment, bp, instance_input.all_vars(), component_result.all_vars(), + start_row, component_instance.rows_amount, connectedness_check); if (connectedness_check.t == blueprint::connectedness_check_type::type::NONE) { std::cout << "WARNING: Connectedness check is disabled." << std::endl; } @@ -234,33 +225,35 @@ namespace nil { // auto zones = blueprint::detail::generate_connectedness_zones( // assignment, bp, instance_input.all_vars(), start_row, component_instance.rows_amount); // blueprint::detail::export_connectedness_zones( - // zones, assignment, instance_input.all_vars(), start_row, component_instance.rows_amount, std::cout); + // zones, assignment, instance_input.all_vars(), start_row, component_instance.rows_amount, + // std::cout); // BOOST_ASSERT_MSG(is_connected, - // "Component disconnected! See comment above this assert for a way to output a visual representation of the connectedness graph."); + // "Component disconnected! See comment above this assert for a way to output a visual representation + // of the connectedness graph."); } desc.usable_rows_amount = assignment.rows_amount(); if (start_row + component_instance.rows_amount >= public_input.size()) { BOOST_ASSERT_MSG(assignment.rows_amount() - start_row == component_instance.rows_amount, - "Component rows amount does not match actual rows amount."); + "Component rows amount does not match actual rows amount."); // Stretched components do not have a manifest, as they are dynamically generated. - if constexpr (!blueprint::components::is_component_stretcher< - BlueprintFieldType, ComponentType>::value) { + if constexpr (!blueprint::components::is_component_stretcher::value) { BOOST_ASSERT_MSG(assignment.rows_amount() - start_row == - component_type::get_rows_amount(component_instance.witness_amount(), 0, - component_static_info_args...), - "Static component rows amount does not match actual rows amount."); + component_type::get_rows_amount(component_instance.witness_amount(), 0, + component_static_info_args...), + "Static component rows amount does not match actual rows amount."); } } // Stretched components do not have a manifest, as they are dynamically generated. - if constexpr (!blueprint::components::is_component_stretcher< - BlueprintFieldType, ComponentType>::value) { - BOOST_ASSERT_MSG(bp.num_gates() + bp.num_lookup_gates()== - component_type::get_gate_manifest(component_instance.witness_amount(), 0, - component_static_info_args...).get_gates_amount(), - "Component total gates amount does not match actual gates amount."); + if constexpr (!blueprint::components::is_component_stretcher::value) { + BOOST_ASSERT_MSG(bp.num_gates() + bp.num_lookup_gates() == + component_type::get_gate_manifest(component_instance.witness_amount(), 0, + component_static_info_args...) + .get_gates_amount(), + "Component total gates amount does not match actual gates amount."); } if constexpr (nil::blueprint::use_lookups()) { @@ -270,23 +263,20 @@ namespace nil { // Rather universal for testing // We may start from zero if component doesn't use ordinary constants. std::vector lookup_columns_indices; - for( std::size_t i = 1; i < assignment.constants_amount(); i++ ) lookup_columns_indices.push_back(i); + for (std::size_t i = 1; i < assignment.constants_amount(); i++) + lookup_columns_indices.push_back(i); std::size_t cur_selector_id = 0; - for(const auto &gate: bp.gates()){ + for (const auto &gate : bp.gates()) { cur_selector_id = std::max(cur_selector_id, gate.selector_index); } - for(const auto &lookup_gate: bp.lookup_gates()){ + for (const auto &lookup_gate : bp.lookup_gates()) { cur_selector_id = std::max(cur_selector_id, lookup_gate.tag_index); } cur_selector_id++; desc.usable_rows_amount = zk::snark::pack_lookup_tables_horizontal( - bp.get_reserved_indices(), - bp.get_reserved_tables(), - bp, assignment, lookup_columns_indices, cur_selector_id, - desc.usable_rows_amount, - 500000 - ); + bp.get_reserved_indices(), bp.get_reserved_tables(), bp, assignment, lookup_columns_indices, + cur_selector_id, desc.usable_rows_amount, 500000); } desc.rows_amount = zk::snark::basic_padding(assignment); @@ -296,25 +286,24 @@ namespace nil { profiling(assignment); #endif - //assignment.export_table(std::cout); - //bp.export_circuit(std::cout); + // assignment.export_table(std::cout); + // bp.export_circuit(std::cout); assert(blueprint::is_satisfied(bp, assignment) == expected_to_pass); return std::make_tuple(desc, bp, assignment); } - template< - typename ComponentType, typename BlueprintFieldType, typename Hash, - std::size_t Lambda, typename PublicInputContainerType, typename FunctorResultCheck, bool PrivateInput, - typename... ComponentStaticInfoArgs> + template auto prepare_empty_component(ComponentType component_instance, - const zk::snark::plonk_table_description &desc, - const PublicInputContainerType &public_input, - const FunctorResultCheck &result_check, - typename ComponentType::input_type instance_input, - blueprint::connectedness_check_type connectedness_check, - ComponentStaticInfoArgs... component_static_info_args) { + const zk::snark::plonk_table_description &desc, + const PublicInputContainerType &public_input, + const FunctorResultCheck &result_check, + typename ComponentType::input_type instance_input, + blueprint::connectedness_check_type connectedness_check, + ComponentStaticInfoArgs... component_static_info_args) { using component_type = ComponentType; blueprint::circuit> bp; @@ -335,15 +324,15 @@ namespace nil { } auto component_result = boost::get( - blueprint::components::generate_empty_assignments( - component_instance, assignment, instance_input, start_row)); + blueprint::components::generate_empty_assignments(component_instance, assignment, + instance_input, start_row)); // assignment.export_table(std::cout); // bp.export_circuit(std::cout); result_check(assignment, component_result); if (start_row + component_instance.empty_rows_amount >= public_input.size()) { BOOST_ASSERT_MSG(assignment.rows_amount() - start_row == component_instance.empty_rows_amount, - "Component rows amount does not match actual rows amount."); + "Component rows amount does not match actual rows amount."); } BOOST_ASSERT(bp.num_gates() == 0); BOOST_ASSERT(bp.num_lookup_gates() == 0); @@ -351,62 +340,62 @@ namespace nil { return std::make_tuple(desc, bp, assignment); } - template - typename std::enable_if< - std::is_same::value_type>::value>::type + template + typename std::enable_if::value_type>::value>::type test_empty_component(ComponentType component_instance, - zk::snark::plonk_table_description input_desc, - const PublicInputContainerType &public_input, - FunctorResultCheck result_check, - typename ComponentType::input_type instance_input, - blueprint::connectedness_check_type connectedness_check = - blueprint::connectedness_check_type::type::STRONG, - ComponentStaticInfoArgs... component_static_info_args) { + zk::snark::plonk_table_description + input_desc, + const PublicInputContainerType &public_input, + FunctorResultCheck result_check, + typename ComponentType::input_type instance_input, + blueprint::connectedness_check_type connectedness_check = + blueprint::connectedness_check_type::type::STRONG, + ComponentStaticInfoArgs... component_static_info_args) { auto [desc, bp, assignments] = - prepare_empty_component - (component_instance, input_desc, public_input, result_check, instance_input, - connectedness_check, component_static_info_args...); + prepare_empty_component( + component_instance, input_desc, public_input, result_check, instance_input, connectedness_check, + component_static_info_args...); } - template - typename std::enable_if< - std::is_same::value_type>::value>::type + typename std::enable_if::value_type>::value>::type test_component_inner(ComponentType component_instance, - zk::snark::plonk_table_description input_desc, - const PublicInputContainerType &public_input, - const FunctorResultCheck &result_check, - const plonk_test_assigner - &assigner, - const typename ComponentType::input_type &instance_input, - bool expected_to_pass, - blueprint::connectedness_check_type connectedness_check, - ComponentStaticInfoArgs... component_static_info_args) { + zk::snark::plonk_table_description + input_desc, + const PublicInputContainerType &public_input, + const FunctorResultCheck &result_check, + const plonk_test_assigner &assigner, + const typename ComponentType::input_type &instance_input, + bool expected_to_pass, + blueprint::connectedness_check_type connectedness_check, + ComponentStaticInfoArgs... component_static_info_args) { auto [desc, bp, assignments] = - prepare_component - (component_instance, input_desc, public_input, result_check, assigner, instance_input, - expected_to_pass, connectedness_check, component_static_info_args...); + prepare_component( + component_instance, input_desc, public_input, result_check, assigner, instance_input, + expected_to_pass, connectedness_check, component_static_info_args...); // How to define it from crypto3 cmake? -//#define BLUEPRINT_PLACEHOLDER_PROOF_GEN_ENABLED +// #define BLUEPRINT_PLACEHOLDER_PROOF_GEN_ENABLED #ifdef BLUEPRINT_PLACEHOLDER_PROOF_GEN_ENABLED using circuit_params = typename nil::crypto3::zk::snark::placeholder_circuit_params; - using lpc_params_type = typename nil::crypto3::zk::commitments::list_polynomial_commitment_params< - Hash, Hash, Lambda, 2 - >; + using lpc_params_type = + typename nil::crypto3::zk::commitments::list_polynomial_commitment_params; - using commitment_type = typename nil::crypto3::zk::commitments::list_polynomial_commitment; - using commitment_scheme_type = typename nil::crypto3::zk::commitments::lpc_commitment_scheme; - using placeholder_params_type = typename nil::crypto3::zk::snark::placeholder_params; + using commitment_type = + typename nil::crypto3::zk::commitments::list_polynomial_commitment; + using commitment_scheme_type = + typename nil::crypto3::zk::commitments::lpc_commitment_scheme; + using placeholder_params_type = + typename nil::crypto3::zk::snark::placeholder_params; using fri_type = typename commitment_type::fri_type; @@ -417,158 +406,156 @@ namespace nil { std::size_t permutation_size = desc.witness_columns + desc.public_input_columns + desc.constant_columns; - typename nil::crypto3::zk::snark::placeholder_public_preprocessor::preprocessed_data_type - preprocessed_public_data = nil::crypto3::zk::snark::placeholder_public_preprocessor::process( - bp, assignments.public_table(), desc, lpc_scheme, permutation_size - ); + typename nil::crypto3::zk::snark::placeholder_public_preprocessor< + BlueprintFieldType, placeholder_params_type>::preprocessed_data_type preprocessed_public_data = + nil::crypto3::zk::snark::placeholder_public_preprocessor< + BlueprintFieldType, placeholder_params_type>::process(bp, assignments.public_table(), desc, + lpc_scheme, permutation_size); - typename nil::crypto3::zk::snark::placeholder_private_preprocessor::preprocessed_data_type - preprocessed_private_data = nil::crypto3::zk::snark::placeholder_private_preprocessor::process( - bp, assignments.private_table(), desc - ); + typename nil::crypto3::zk::snark::placeholder_private_preprocessor< + BlueprintFieldType, placeholder_params_type>::preprocessed_data_type preprocessed_private_data = + nil::crypto3::zk::snark::placeholder_private_preprocessor< + BlueprintFieldType, placeholder_params_type>::process(bp, assignments.private_table(), desc); - auto proof = nil::crypto3::zk::snark::placeholder_prover::process( - preprocessed_public_data, preprocessed_private_data, desc, bp, lpc_scheme - ); + auto proof = + nil::crypto3::zk::snark::placeholder_prover::process( + preprocessed_public_data, preprocessed_private_data, desc, bp, lpc_scheme); - bool verifier_res = nil::crypto3::zk::snark::placeholder_verifier::process( - preprocessed_public_data, proof, desc, bp, lpc_scheme - ); + bool verifier_res = + nil::crypto3::zk::snark::placeholder_verifier::process( + preprocessed_public_data, proof, desc, bp, lpc_scheme); if (expected_to_pass) { BOOST_CHECK(verifier_res); - } - else { + } else { BOOST_CHECK(!verifier_res); } #endif } - template - typename std::enable_if< - std::is_same::value_type>::value>::type + template + typename std::enable_if::value_type>::value>::type test_component(ComponentType component_instance, - zk::snark::plonk_table_description desc, + zk::snark::plonk_table_description + desc, const PublicInputContainerType &public_input, FunctorResultCheck result_check, typename ComponentType::input_type instance_input, blueprint::connectedness_check_type connectedness_check = - blueprint::connectedness_check_type::type::STRONG, + blueprint::connectedness_check_type::type::STRONG, ComponentStaticInfoArgs... component_static_info_args) { - return test_component_inner( - component_instance, desc, public_input, result_check, - plonk_test_default_assigner(), - instance_input, true, connectedness_check, component_static_info_args...); + return test_component_inner( + component_instance, desc, public_input, result_check, + plonk_test_default_assigner(), instance_input, true, + connectedness_check, component_static_info_args...); } - template - typename std::enable_if< - std::is_same::value_type>::value>::type + template + typename std::enable_if::value_type>::value>::type test_component_to_fail(ComponentType component_instance, - zk::snark::plonk_table_description desc, - const PublicInputContainerType &public_input, - FunctorResultCheck result_check, - typename ComponentType::input_type instance_input, - blueprint::connectedness_check_type connectedness_check = - blueprint::connectedness_check_type::type::STRONG, - ComponentStaticInfoArgs... component_static_info_args) { - return test_component_inner( - component_instance, desc, public_input, result_check, - plonk_test_default_assigner(), - instance_input, false, connectedness_check, component_static_info_args...); + zk::snark::plonk_table_description + desc, + const PublicInputContainerType &public_input, + FunctorResultCheck result_check, + typename ComponentType::input_type instance_input, + blueprint::connectedness_check_type connectedness_check = + blueprint::connectedness_check_type::type::STRONG, + ComponentStaticInfoArgs... component_static_info_args) { + return test_component_inner( + component_instance, desc, public_input, result_check, + plonk_test_default_assigner(), instance_input, false, + connectedness_check, component_static_info_args...); } - template - typename std::enable_if< - std::is_same::value_type>::value>::type - test_component_custom_assignments(ComponentType component_instance, - zk::snark::plonk_table_description desc, - const PublicInputContainerType &public_input, FunctorResultCheck result_check, - const plonk_test_custom_assigner &custom_assigner, - typename ComponentType::input_type instance_input, - blueprint::connectedness_check_type connectedness_check = - blueprint::connectedness_check_type::type::STRONG, - ComponentStaticInfoArgs... component_static_info_args) { - - return test_component_inner - (component_instance, desc, public_input, result_check, custom_assigner, - instance_input, true, connectedness_check, component_static_info_args...); - } + template + typename std::enable_if::value_type>::value>::type + test_component_custom_assignments( + ComponentType component_instance, zk::snark::plonk_table_description desc, + const PublicInputContainerType &public_input, FunctorResultCheck result_check, + const plonk_test_custom_assigner &custom_assigner, + typename ComponentType::input_type instance_input, + blueprint::connectedness_check_type connectedness_check = + blueprint::connectedness_check_type::type::STRONG, + ComponentStaticInfoArgs... component_static_info_args) { + + return test_component_inner( + component_instance, desc, public_input, result_check, custom_assigner, instance_input, true, + connectedness_check, component_static_info_args...); + } - template - typename std::enable_if< - std::is_same::value_type>::value>::type - test_component_to_fail_custom_assignments(ComponentType component_instance, - zk::snark::plonk_table_description desc, - const PublicInputContainerType &public_input, FunctorResultCheck result_check, - const plonk_test_custom_assigner &custom_assigner, - typename ComponentType::input_type instance_input, - blueprint::connectedness_check_type connectedness_check = - blueprint::connectedness_check_type::type::STRONG, - ComponentStaticInfoArgs... component_static_info_args) { - - return test_component_inner - (component_instance, desc, public_input, result_check, custom_assigner, - instance_input, false, connectedness_check,component_static_info_args...); - } + template + typename std::enable_if::value_type>::value>::type + test_component_to_fail_custom_assignments( + ComponentType component_instance, zk::snark::plonk_table_description desc, + const PublicInputContainerType &public_input, FunctorResultCheck result_check, + const plonk_test_custom_assigner &custom_assigner, + typename ComponentType::input_type instance_input, + blueprint::connectedness_check_type connectedness_check = + blueprint::connectedness_check_type::type::STRONG, + ComponentStaticInfoArgs... component_static_info_args) { + + return test_component_inner( + component_instance, desc, public_input, result_check, custom_assigner, instance_input, false, + connectedness_check, component_static_info_args...); + } - template - typename std::enable_if< - std::is_same::value_type>::value>::type + template + typename std::enable_if::value_type>::value>::type test_component_private_input(ComponentType component_instance, - zk::snark::plonk_table_description desc, - const PublicInputContainerType &public_input, FunctorResultCheck result_check, - typename ComponentType::input_type instance_input, - blueprint::connectedness_check_type connectedness_check = - blueprint::connectedness_check_type::type::STRONG, - ComponentStaticInfoArgs... component_static_info_args) { - - return test_component_inner - (component_instance, desc, public_input, result_check, - plonk_test_default_assigner(), - instance_input, true, connectedness_check, component_static_info_args...); - } + zk::snark::plonk_table_description desc, + const PublicInputContainerType &public_input, FunctorResultCheck result_check, + typename ComponentType::input_type instance_input, + blueprint::connectedness_check_type connectedness_check = + blueprint::connectedness_check_type::type::STRONG, + ComponentStaticInfoArgs... component_static_info_args) { + + return test_component_inner( + component_instance, desc, public_input, result_check, + plonk_test_default_assigner(), instance_input, true, + connectedness_check, component_static_info_args...); + } - template - typename std::enable_if< - std::is_same::value_type>::value>::type + template + typename std::enable_if::value_type>::value>::type test_component_to_fail_private_input(ComponentType component_instance, - zk::snark::plonk_table_description desc, - const PublicInputContainerType &public_input, FunctorResultCheck result_check, - typename ComponentType::input_type instance_input, - blueprint::connectedness_check_type connectedness_check = - blueprint::connectedness_check_type::type::STRONG, - ComponentStaticInfoArgs... component_static_info_args) { - - return test_component_inner - (component_instance, desc, public_input, result_check, - plonk_test_default_assigner(), - instance_input, false, connectedness_check, component_static_info_args...); - } + zk::snark::plonk_table_description + desc, + const PublicInputContainerType &public_input, + FunctorResultCheck result_check, + typename ComponentType::input_type instance_input, + blueprint::connectedness_check_type connectedness_check = + blueprint::connectedness_check_type::type::STRONG, + ComponentStaticInfoArgs... component_static_info_args) { + + return test_component_inner( + component_instance, desc, public_input, result_check, + plonk_test_default_assigner(), instance_input, false, + connectedness_check, component_static_info_args...); + } /* Most of the time while testing we do not want to generate an entire set of assignments from scratch. @@ -577,30 +564,30 @@ namespace nil { */ template std::function>&, - const typename ComponentType::input_type&, - const std::uint32_t)> + const ComponentType &, + nil::blueprint::assignment> &, + const typename ComponentType::input_type &, + const std::uint32_t)> generate_patched_assignments( - const std::map, typename BlueprintFieldType::value_type> - &patches) { - - return [&patches] - (const ComponentType &component, - nil::blueprint::assignment> &assignment, - const typename ComponentType::input_type &instance_input, - const std::uint32_t start_row_index) { - typename ComponentType::result_type result = - blueprint::components::generate_assignments( - component, assignment, instance_input, start_row_index); - - for (const auto &patch : patches) { - assignment.witness(component.W(patch.first.second), patch.first.first + start_row_index) = - patch.second; - } + const std::map, typename BlueprintFieldType::value_type> &patches) { + + return + [&patches](const ComponentType &component, + nil::blueprint::assignment> + &assignment, + const typename ComponentType::input_type &instance_input, + const std::uint32_t start_row_index) { + typename ComponentType::result_type result = + blueprint::components::generate_assignments( + component, assignment, instance_input, start_row_index); - return result; - }; + for (const auto &patch : patches) { + assignment.witness(component.W(patch.first.second), patch.first.first + start_row_index) = + patch.second; + } + + return result; + }; } } // namespace crypto3 } // namespace nil diff --git a/test/verifiers/kimchi/demo_verifier.cpp b/test/verifiers/kimchi/demo_verifier.cpp index e42b8d4e6..13c16fd22 100644 --- a/test/verifiers/kimchi/demo_verifier.cpp +++ b/test/verifiers/kimchi/demo_verifier.cpp @@ -50,8 +50,8 @@ #include #include -#include -#include +#include +#include #include @@ -162,7 +162,7 @@ BOOST_AUTO_TEST_CASE(blueprint_plonk_kimchi_demo_verifier_test) { std::size_t row = start_row + i * component_type::rows_amount; result[i] = component_type::result_type(component_params, row); - zk::components::generate_circuit(bp, public_assignment, component_params, row); + ::nil::blueprint::components::generate_circuit(bp, public_assignment, component_params, row); component_type::generate_assignments(assignment_bp, component_params, row); } diff --git a/test/verifiers/kimchi/detail/to_group.cpp b/test/verifiers/kimchi/detail/to_group.cpp index 31843870a..a4f201784 100644 --- a/test/verifiers/kimchi/detail/to_group.cpp +++ b/test/verifiers/kimchi/detail/to_group.cpp @@ -41,6 +41,7 @@ #include #include "../../../test_plonk_component.hpp" +using namespace nil; using namespace nil::crypto3; BOOST_AUTO_TEST_SUITE(blueprint_plonk_test_suite) @@ -68,8 +69,7 @@ BOOST_AUTO_TEST_CASE(blueprint_plonk_kimchi_to_group) { typename BlueprintFieldType::value_type t_value = 0x28B65D3D28EEAB51CE0B9D26B1A801AFF855B82210E18901C47EA3E46F4F3AED_cppui255; - curve_type::template g1_type::value_type - expected_result; + curve_type::template g1_type::value_type expected_result; expected_result.X = 0x0DAFF73C33C0C65C641C6780E151E272069F84CFBAB3BA922A2AE640ACB9234A_cppui255; expected_result.Y = 0x171ADF13662AD137A9D177BEA98605DD9523A570B05C3161AF32C7B2D7ECCC58_cppui255; @@ -77,14 +77,12 @@ BOOST_AUTO_TEST_CASE(blueprint_plonk_kimchi_to_group) { typename component_type::params_type params = {var(0, 0, false, var::column_type::public_input)}; - auto result_check = [&expected_result](AssignmentType &assignment, component_type::result_type &real_res) { assert(expected_result.X == assignment.var_value(real_res.output.X)); assert(expected_result.Y == assignment.var_value(real_res.output.Y)); }; - test_component(params, public_input, - result_check); + test_component(params, public_input, result_check); auto duration = std::chrono::duration_cast(std::chrono::high_resolution_clock::now() - start); diff --git a/test/verifiers/kimchi/index_terms_instances/chacha_test.hpp b/test/verifiers/kimchi/index_terms_instances/chacha_test.hpp index 2d98bd2e2..dfdbd96ba 100644 --- a/test/verifiers/kimchi/index_terms_instances/chacha_test.hpp +++ b/test/verifiers/kimchi/index_terms_instances/chacha_test.hpp @@ -25,10 +25,10 @@ #ifndef CRYPTO3_ZK_BLUEPRINT_PLONK_KIMCHI_DETAIL_CONSTRAINTS_INDEX_TERMS_INSTANCES_CHACHA_TEST_HPP #define CRYPTO3_ZK_BLUEPRINT_PLONK_KIMCHI_DETAIL_CONSTRAINTS_INDEX_TERMS_INSTANCES_CHACHA_TEST_HPP -#include -#include -#include -#include +#include +#include +#include +#include namespace nil { namespace crypto3 { diff --git a/test/verifiers/kimchi/index_terms_instances/recursion_test.hpp b/test/verifiers/kimchi/index_terms_instances/recursion_test.hpp index 82515c08e..8256e3fb9 100644 --- a/test/verifiers/kimchi/index_terms_instances/recursion_test.hpp +++ b/test/verifiers/kimchi/index_terms_instances/recursion_test.hpp @@ -25,10 +25,10 @@ #ifndef CRYPTO3_ZK_BLUEPRINT_PLONK_KIMCHI_DETAIL_CONSTRAINTS_INDEX_TERMS_INSTANCES_RECURSION_TEST_HPP #define CRYPTO3_ZK_BLUEPRINT_PLONK_KIMCHI_DETAIL_CONSTRAINTS_INDEX_TERMS_INSTANCES_RECURSION_TEST_HPP -#include -#include -#include -#include +#include +#include +#include +#include namespace nil { namespace crypto3 { diff --git a/test/verifiers/kimchi/sponge/aux_sponge.hpp b/test/verifiers/kimchi/sponge/aux_sponge.hpp index 1c27c30e1..6d9d5ff25 100644 --- a/test/verifiers/kimchi/sponge/aux_sponge.hpp +++ b/test/verifiers/kimchi/sponge/aux_sponge.hpp @@ -35,7 +35,7 @@ #include #include -#include +#include #include namespace nil { diff --git a/test/verifiers/kimchi/sponge/aux_transcript_fq.hpp b/test/verifiers/kimchi/sponge/aux_transcript_fq.hpp index fb1fe8d5d..0c46ab7e9 100644 --- a/test/verifiers/kimchi/sponge/aux_transcript_fq.hpp +++ b/test/verifiers/kimchi/sponge/aux_transcript_fq.hpp @@ -35,7 +35,7 @@ #include #include -#include +#include #include namespace nil { diff --git a/test/verifiers/kimchi/sponge/aux_transcript_fr.hpp b/test/verifiers/kimchi/sponge/aux_transcript_fr.hpp index 2251a5873..2257ccc28 100644 --- a/test/verifiers/kimchi/sponge/aux_transcript_fr.hpp +++ b/test/verifiers/kimchi/sponge/aux_transcript_fr.hpp @@ -35,7 +35,7 @@ #include #include -#include +#include #include #include #include diff --git a/test/verifiers/kimchi/table_commitment.cpp b/test/verifiers/kimchi/table_commitment.cpp index 0e38e1921..bdd760ebc 100644 --- a/test/verifiers/kimchi/table_commitment.cpp +++ b/test/verifiers/kimchi/table_commitment.cpp @@ -35,18 +35,18 @@ #include #include -//#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +//#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include "verifiers/kimchi/index_terms_instances/lookup_test.hpp" #include "test_plonk_component.hpp" diff --git a/test/verifiers/pickles/scalar_details/evals_of_split_evals.cpp b/test/verifiers/pickles/scalar_details/evals_of_split_evals.cpp index 5e8dbfabc..5023ff947 100644 --- a/test/verifiers/pickles/scalar_details/evals_of_split_evals.cpp +++ b/test/verifiers/pickles/scalar_details/evals_of_split_evals.cpp @@ -36,13 +36,13 @@ #include -#include +#include #include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include #include "verifiers/kimchi/index_terms_instances/ec_index_terms.hpp" #include "test_plonk_component.hpp" diff --git a/test/verifiers/pickles/verify_heterogenous_base.cpp b/test/verifiers/pickles/verify_heterogenous_base.cpp index 5a57d151d..eafa35178 100644 --- a/test/verifiers/pickles/verify_heterogenous_base.cpp +++ b/test/verifiers/pickles/verify_heterogenous_base.cpp @@ -36,12 +36,12 @@ #include -#include +#include #include -#include -#include -#include -#include +#include +#include +#include +#include #include "verifiers/kimchi/index_terms_instances/ec_index_terms.hpp" #include "test_plonk_component.hpp" diff --git a/test/verifiers/pickles/verify_heterogenous_scalar.cpp b/test/verifiers/pickles/verify_heterogenous_scalar.cpp index 5b5a6e575..b825fc48a 100644 --- a/test/verifiers/pickles/verify_heterogenous_scalar.cpp +++ b/test/verifiers/pickles/verify_heterogenous_scalar.cpp @@ -36,12 +36,12 @@ #include -#include +#include #include -#include -#include -#include -#include +#include +#include +#include +#include #include "verifiers/kimchi/index_terms_instances/ec_index_terms.hpp" #include "test_plonk_component.hpp" diff --git a/test/verify_r1cs_scheme.hpp b/test/verify_r1cs_scheme.hpp index b821fd137..c306c2f2e 100644 --- a/test/verify_r1cs_scheme.hpp +++ b/test/verify_r1cs_scheme.hpp @@ -36,6 +36,7 @@ #include +using namespace nil; using namespace nil::crypto3; using namespace nil::crypto3::zk; using namespace nil::crypto3::algebra; diff --git a/test/voting/r1cs/encrypted_input_voting.cpp b/test/voting/r1cs/encrypted_input_voting.cpp index d284224ba..dbec86ba5 100644 --- a/test/voting/r1cs/encrypted_input_voting.cpp +++ b/test/voting/r1cs/encrypted_input_voting.cpp @@ -29,14 +29,11 @@ #include -#include - -#include +#include #include -#include - +using namespace nil; using namespace nil::crypto3; using namespace nil::crypto3::zk; using namespace nil::crypto3::algebra; @@ -45,8 +42,8 @@ template std::vector calculate_hash_via_component(const std::vector &in_bits) { using field_type = typename HashComponent::field_type; - blueprint bp_bits; - components::block_variable in_block(bp_bits, in_bits.size()); + blueprint::blueprint bp_bits; + blueprint::components::block_variable in_block(bp_bits, in_bits.size()); in_block.generate_assignments(in_bits); HashComponent hash_comp_bits(bp_bits, in_block); @@ -59,14 +56,14 @@ void test_jubjub_pedersen_encrypted_input_voting_component() { using curve_type = curves::jubjub; using bp_generator_hash_type = hashes::sha2<256>; using hash_params = hashes::find_group_hash_default_params; - using hash_component = components::pedersen; + using hash_component = blueprint::components::pedersen; using hash_type = typename hash_component::hash_type; using merkle_hash_component = hash_component; using merkle_hash_type = typename merkle_hash_component::hash_type; using field_type = typename hash_component::field_type; constexpr std::size_t arity = 2; using voting_component = - components::encrypted_input_voting; + blueprint::components::encrypted_input_voting; using merkle_proof_component = typename voting_component::merkle_proof_component; using merkle_validate_component = typename voting_component::merkle_proof_validating_component; @@ -130,14 +127,14 @@ void test_jubjub_pedersen_encrypted_input_voting_component() { sn_wrong[0] = !sn_wrong[0]; /* execute test */ - blueprint bp; + blueprint::blueprint bp; nil::crypto3::zk::detail::blueprint_variable_vector address_bits_va; address_bits_va.allocate(bp, tree_depth); - components::block_variable m_block(bp, m.size()); - components::block_variable eid_block(bp, eid.size()); - components::block_variable sk_block(bp, sk.size()); - components::digest_variable sn_digest(bp, hash_component::digest_bits); - components::digest_variable root_digest(bp, merkle_hash_component::digest_bits); + blueprint::components::block_variable m_block(bp, m.size()); + blueprint::components::block_variable eid_block(bp, eid.size()); + blueprint::components::block_variable sk_block(bp, sk.size()); + blueprint::components::digest_variable sn_digest(bp, hash_component::digest_bits); + blueprint::components::digest_variable root_digest(bp, merkle_hash_component::digest_bits); merkle_hash_component path_var(bp, tree_depth); voting_component vote_var(bp, m_block, eid_block, sn_digest, root_digest, address_bits_va, path_var, sk_block, nil::crypto3::zk::detail::blueprint_variable(0)); @@ -223,7 +220,7 @@ void test_jubjub_merkle_container_pedersen_encrypted_input_voting_component() { using curve_type = curves::jubjub; using bp_generator_hash_type = hashes::sha2<256>; using hash_params = hashes::find_group_hash_default_params; - using hash_component = components::pedersen; + using hash_component = blueprint::components::pedersen; using hash_type = typename hash_component::hash_type; using merkle_hash_component = hash_component; using merkle_hash_type = typename merkle_hash_component::hash_type; @@ -281,14 +278,14 @@ void test_jubjub_merkle_container_pedersen_encrypted_input_voting_component() { sn_wrong[0] = !sn_wrong[0]; /* execute test */ - blueprint bp; + blueprint::blueprint bp; nil::crypto3::zk::detail::blueprint_variable_vector address_bits_va; address_bits_va.allocate(bp, tree_depth); - components::block_variable m_block(bp, m.size()); - components::block_variable eid_block(bp, eid.size()); - components::block_variable sk_block(bp, secret_keys[proof_idx].size()); - components::digest_variable sn_digest(bp, hash_component::digest_bits); - components::digest_variable root_digest(bp, merkle_hash_component::digest_bits); + blueprint::components::block_variable m_block(bp, m.size()); + blueprint::components::block_variable eid_block(bp, eid.size()); + blueprint::components::block_variable sk_block(bp, secret_keys[proof_idx].size()); + blueprint::components::digest_variable sn_digest(bp, hash_component::digest_bits); + blueprint::components::digest_variable root_digest(bp, merkle_hash_component::digest_bits); merkle_proof_component path_var(bp, tree_depth); voting_component vote_var(bp, m_block, eid_block, sn_digest, root_digest, address_bits_va, path_var, sk_block, nil::crypto3::zk::detail::blueprint_variable(0));