diff --git a/parallel-crypto3/libs/parallel-zk/include/nil/crypto3/zk/snark/systems/plonk/kate/params.hpp b/parallel-crypto3/libs/parallel-zk/include/nil/crypto3/zk/snark/systems/plonk/kate/params.hpp deleted file mode 100644 index f98c314add..0000000000 --- a/parallel-crypto3/libs/parallel-zk/include/nil/crypto3/zk/snark/systems/plonk/kate/params.hpp +++ /dev/null @@ -1,102 +0,0 @@ -//---------------------------------------------------------------------------// -// Copyright (c) 2018-2021 Mikhail Komarov -// Copyright (c) 2020-2021 Nikita Kaskov -// -// MIT License -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -//---------------------------------------------------------------------------// - -#ifndef PARALLEL_CRYPTO3_ZK_PLONK_BATCHED_KATE_PARAMS_HPP -#define PARALLEL_CRYPTO3_ZK_PLONK_BATCHED_KATE_PARAMS_HPP - -#ifdef CRYPTO3_ZK_PLONK_BATCHED_KATE_PARAMS_HPP -#error "You're mixing parallel and non-parallel crypto3 versions" -#endif - -#include - -#include - -namespace nil { - namespace crypto3 { - namespace zk { - namespace snark { - template> - struct standard_settings { - constexpr static const std::size_t num_challenge_bytes = 32; - constexpr static const transcript::HashType hash_type = transcript::HashType::Keccak256; - constexpr static const std::size_t program_width = 3; - constexpr static const std::size_t num_shifted_wire_evaluations = 1; - constexpr static const std::uint64_t wire_shift_settings = 0b0100; - constexpr static const bool uses_quotient_mid = false; - constexpr static const std::uint32_t permutation_shift = 30; - constexpr static const std::uint32_t permutation_mask = 0xC0000000; - constexpr static const bool use_linearisation = true; - constexpr static const std::size_t num_roots_cut_out_of_vanishing_polynomial = 4; - }; - - template - struct unrolled_standard_settings { - constexpr static const size_t num_challenge_bytes = 16; - constexpr static const transcript::HashType hash_type = transcript::HashType::PedersenBlake2s; - constexpr static const size_t program_width = 3; - constexpr static const size_t num_shifted_wire_evaluations = 1; - constexpr static const uint64_t wire_shift_settings = 0b0100; - constexpr static const bool uses_quotient_mid = false; - constexpr static const uint32_t permutation_shift = 30; - constexpr static const uint32_t permutation_mask = 0xC0000000; - constexpr static const bool use_linearisation = false; - constexpr static const size_t num_roots_cut_out_of_vanishing_polynomial = 4; - }; - - template> - struct turbo_settings { - constexpr static const size_t num_challenge_bytes = 32; - constexpr static const transcript::HashType hash_type = transcript::HashType::Keccak256; - constexpr static const size_t program_width = 4; - constexpr static const size_t num_shifted_wire_evaluations = 4; - constexpr static const uint64_t wire_shift_settings = 0b1111; - constexpr static const bool uses_quotient_mid = false; - constexpr static const uint32_t permutation_shift = 30; - constexpr static const uint32_t permutation_mask = 0xC0000000; - constexpr static const bool use_linearisation = true; - constexpr static const size_t num_roots_cut_out_of_vanishing_polynomial = 4; - }; - - template - class unrolled_turbo_settings { - public: - constexpr static const size_t num_challenge_bytes = 16; - constexpr static const transcript::HashType hash_type = transcript::HashType::PedersenBlake2s; - constexpr static const size_t program_width = 4; - constexpr static const size_t num_shifted_wire_evaluations = 4; - constexpr static const uint64_t wire_shift_settings = 0b1111; - constexpr static const bool uses_quotient_mid = false; - constexpr static const uint32_t permutation_shift = 30; - constexpr static const uint32_t permutation_mask = 0xC0000000; - constexpr static const bool use_linearisation = false; - constexpr static const size_t num_roots_cut_out_of_vanishing_polynomial = 4; - }; - } // namespace snark - } // namespace zk - } // namespace crypto3 -} // namespace nil - -#endif // CRYPTO3_ZK_PLONK_BATCHED_KATE_PARAMS_HPP diff --git a/parallel-crypto3/libs/parallel-zk/include/nil/crypto3/zk/snark/systems/plonk/kate/proof.hpp b/parallel-crypto3/libs/parallel-zk/include/nil/crypto3/zk/snark/systems/plonk/kate/proof.hpp deleted file mode 100644 index eda8721569..0000000000 --- a/parallel-crypto3/libs/parallel-zk/include/nil/crypto3/zk/snark/systems/plonk/kate/proof.hpp +++ /dev/null @@ -1,52 +0,0 @@ -//---------------------------------------------------------------------------// -// Copyright (c) 2021 Mikhail Komarov -// Copyright (c) 2021 Nikita Kaskov -// -// MIT License -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -//---------------------------------------------------------------------------// - -#ifndef PARALLEL_CRYPTO3_ZK_PLONK_BATCHED_KATE_PROOF_HPP -#define PARALLEL_CRYPTO3_ZK_PLONK_BATCHED_KATE_PROOF_HPP - -#ifdef CRYPTO3_ZK_PLONK_BATCHED_KATE_PROOF_HPP -#error "You're mixing parallel and non-parallel crypto3 versions" -#endif - -#include - -namespace nil { - namespace crypto3 { - namespace zk { - namespace snark { - - template - class plonk_proof; - - template - struct plonk_proof> { - std::vector data; - }; - } // namespace snark - } // namespace zk - } // namespace crypto3 -} // namespace nil - -#endif // CRYPTO3_ZK_PLONK_BATCHED_KATE_PROOF_HPP diff --git a/parallel-crypto3/libs/parallel-zk/include/nil/crypto3/zk/snark/systems/plonk/kate/prover.hpp b/parallel-crypto3/libs/parallel-zk/include/nil/crypto3/zk/snark/systems/plonk/kate/prover.hpp deleted file mode 100644 index 4c1fc17f70..0000000000 --- a/parallel-crypto3/libs/parallel-zk/include/nil/crypto3/zk/snark/systems/plonk/kate/prover.hpp +++ /dev/null @@ -1,398 +0,0 @@ -//---------------------------------------------------------------------------// -// Copyright (c) 2021 Mikhail Komarov -// Copyright (c) 2021 Nikita Kaskov -// -// MIT License -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -//---------------------------------------------------------------------------// - -#ifndef PARALLEL_CRYPTO3_ZK_PLONK_BATCHED_KATE_PROVER_HPP -#define PARALLEL_CRYPTO3_ZK_PLONK_BATCHED_KATE_PROVER_HPP - -#ifdef CRYPTO3_ZK_PLONK_BATCHED_KATE_PROVER_HPP -#error "You're mixing parallel and non-parallel crypto3 versions" -#endif - -#include - -namespace nil { - namespace crypto3 { - namespace zk { - namespace snark { - - template - class plonk_prover; - - template - class plonk_prover> { - using commitment_scheme_type = batched_kate_commitment_scheme<...>; - using constraint_system_type = plonk_constraint_system; - - size_t n; - - std::vector sigma_1_mapping; - std::vector sigma_2_mapping; - std::vector sigma_3_mapping; - - std::vector> random_widgets; - std::vector>> - transition_widgets; - transcript::StandardTranscript transcript; - - std::shared_ptr> key; - std::shared_ptr witness; - std::unique_ptr commitment; - - work_queue queue; - bool uses_quotient_mid; - - plonk_proof proof; - - public: - plonk_prover(std::shared_ptr> input_key, - std::shared_ptr - input_witness, - const transcript::Manifest &input_manifest) : - n(input_key == nullptr ? 0 : input_key->n), - transcript(input_manifest, hash_type, num_challenge_bytes), key(input_key), - witness(input_witness), queue(key.get(), witness.get(), &transcript) { - if (input_witness && witness->wires.count("z") == 0) { - witness->wires.insert({"z", math::polynomial(n, n)}); - } - } - - plonk_prover &operator=(plonk_prover &&other) { - n = other.n; - - random_widgets.resize(0); - transition_widgets.resize(0); - for (size_t i = 0; i < other.random_widgets.size(); ++i) { - random_widgets.emplace_back(std::move(other.random_widgets[i])); - } - for (size_t i = 0; i < other.transition_widgets.size(); ++i) { - transition_widgets.emplace_back(std::move(other.transition_widgets[i])); - } - transcript = other.transcript; - key = std::move(other.key); - witness = std::move(other.witness); - commitment = std::move(other.commitment); - - queue = work_queue(key.get(), witness.get(), &transcript); - return *this; - } - - plonk_prover(plonk_prover &&other) : - n(other.n), transcript(other.transcript), key(std::move(other.key)), - witness(std::move(other.witness)), commitment(std::move(other.commitment)), - queue(key.get(), witness.get(), &transcript) { - for (size_t i = 0; i < other.random_widgets.size(); ++i) { - random_widgets.emplace_back(std::move(other.random_widgets[i])); - } - for (size_t i = 0; i < other.transition_widgets.size(); ++i) { - transition_widgets.emplace_back(std::move(other.transition_widgets[i])); - } - } - - void compute_wire_pre_commitments() { - for (size_t i = 0; i < settings::program_width; ++i) { - std::string wire_tag = "w_" + std::to_string(i + 1); - std::string commit_tag = "W_" + std::to_string(i + 1); - typename TCurve::scalar_field_type::value_type *coefficients = - witness->wires.at(wire_tag).get_coefficients(); - commitment->commit(coefficients, commit_tag, - typename TCurve::scalar_field_type::value_type::zero(), queue); - } - - // add public inputs - const math::polynomial &public_wires_source = key->wire_ffts.at("w_2_fft"); - std::vector public_wires; - for (size_t i = 0; i < key->num_public_inputs; ++i) { - public_wires.push_back(public_wires_source[i]); - } - transcript.add_element("public_inputs", ::to_buffer(public_wires)); - } - - void compute_quotient_pre_commitment() { - // In this method, we compute the commitments to polynomials t_{low}(X), t_{mid}(X) and - // t_{high}(X). Recall, the quotient polynomial t(X) = t_{low}(X) + t_{mid}(X).X^n + - // t_{high}(X).X^{2n} - // - // The reason we split t(X) into three degree-n polynomials is because: - // (i) We want the opening proof polynomials bounded by degree n as the opening algorithm of - // the - // polynomial commitment scheme results in O(n) prover computation. - // (ii) The size of the srs restricts us to compute commitments to polynomials of degree n - // (and disallows for degree 2n and 3n for large n). - // - // The degree of t(X) is determined by the term: - // ((a(X) + βX + γ) (b(X) + βk_1X + γ) (c(X) + βk_2X + γ)z(X)) / Z*_H(X). - // - // Let k = num_roots_cut_out_of_vanishing_polynomial, we have - // deg(t) = (n - 1) * (program_width + 1) - (n - k) - // = n * program_width - program_width - 1 + k - // - // Since we must cut atleast 4 roots from the vanishing polynomial - // (refer to - // ./src/aztec/plonk/proof_system/widgets/random_widgets/permutation_widget_impl.hpp/L247), k = - // 4 => deg(t) = n * program_width - program_width + 3 - // - // For standard plonk, program_width = 3 and thus, deg(t) = 3n. This implies that there would be - // (3n + 1) coefficients of t(X). Now, splitting them into t_{low}(X), t_{mid}(X) and - // t_{high}(X), t_{high} will have (n+1) coefficients while t_{low} and t_{mid} will have n - // coefficients. This means that to commit t_{high}, we need a multi-scalar multiplication of - // size (n+1). Thus, we first compute the commitments to t_{low}(X), t_{mid}(X) using n - // multi-scalar multiplications each and separately compute commitment to t_{high} which is of - // size (n + 1). Note that this must be done only when program_width = 3. - // - // - // NOTE: If in future there is a need to cut off more zeros off the vanishing polynomial, the - // degree of the quotient polynomial t(X) will increase, so the degrees of t_{high}, t_{mid}, - // t_{low} could also increase according to the type of the composer type we are using. - // Currently, for TurboPLONK and Ultra- PLONK, the degree of t(X) is (4n - 1) and hence each - // t_{low}, t_{mid}, t_{high}, t_{higher} each is of degree (n - 1) (and thus contains n - // coefficients). Therefore, we are on the brink! If we need to cut out more zeros off the - // vanishing polynomial, sizes of coefficients of individual t_{i} would change and so we will - // have to ensure the correct size of multi-scalar multiplication in computing the commitments - // to these polynomials. - // - for (size_t i = 0; i < program_width - 1; ++i) { - const size_t offset = n * i; - typename TCurve::scalar_field_type::value_type *coefficients = - &key->quotient_large.get_coefficients()[offset]; - std::string quotient_tag = "T_" + std::to_string(i + 1); - commitment->commit(coefficients, quotient_tag, - typename TCurve::scalar_field_type::value_type::zero(), queue); - } - - typename TCurve::scalar_field_type::value_type *coefficients = - &key->quotient_large.get_coefficients()[(program_width - 1) * n]; - std::string quotient_tag = "T_" + std::to_string(program_width); - typename TCurve::scalar_field_type::value_type program_flag = - program_width == 3 ? typename TCurve::scalar_field_type::value_type::one() : - typename TCurve::scalar_field_type::value_type::zero(); - commitment->commit(coefficients, quotient_tag, program_flag, queue); - } - - void execute_preamble_round() { - queue.flush_queue(); - transcript.add_element("circuit_size", - {static_cast(n >> 24), static_cast(n >> 16), - static_cast(n >> 8), static_cast(n)}); - transcript.add_element("public_input_size", - {static_cast(key->num_public_inputs >> 24), - static_cast(key->num_public_inputs >> 16), - static_cast(key->num_public_inputs >> 8), - static_cast(key->num_public_inputs)}); - transcript.apply_fiat_shamir("init"); - - for (size_t i = 0; i < settings::program_width; ++i) { - // fetch witness wire w_i - std::string wire_tag = "w_" + std::to_string(i + 1); - math::polynomial &wire = witness->wires.at(wire_tag); - - /* - Adding zero knowledge to the witness polynomials. - */ - // To ensure that PLONK is honest-verifier zero-knowledge, we need to ensure that the - // witness polynomials and the permutation polynomial look uniformly random to an adversary. - // To make the witness polynomials a(X), b(X) and c(X) uniformly random, we need to add 2 - // random blinding factors into each of them. i.e. a'(X) = a(X) + (r_1X + r_2) where r_1 and - // r_2 are uniformly random scalar field elements. A natural question is: Why do we need 2 - // random scalars in witness polynomials? The reason is: our witness polynomials are - // evaluated at only 1 point (\scripted{z}), so adding a random degree-1 polynomial - // suffices. - // - // NOTE: In TurboPlonk and UltraPlonk, the witness polynomials are evaluated at 2 points and - // thus we need to add 3 random scalars in them. - // - // We start adding random scalars in `wire` polynomials from index (n - k) upto (n - k + 2). - // For simplicity, we add 3 random scalars even for standard plonk (recall, just 2 of them - // are required) since an additional random scalar would not affect things. - // - // NOTE: If in future there is a need to cut off more zeros off the vanishing polynomial, - // this method will not change. This must be changed only if the number of evaluations of - // witness polynomials change. - // - const size_t w_randomness = 3; - ASSERT(w_randomness < settings::num_roots_cut_out_of_vanishing_polynomial); - for (size_t k = 0; k < w_randomness; ++k) { - wire.at(n - settings::num_roots_cut_out_of_vanishing_polynomial + k) = - algebra::random_element(typename TCurve::scalar_field_type); - } - - math::polynomial &wire_fft = key->wire_ffts.at(wire_tag + "_fft"); - math::polynomial_arithmetic::copy_polynomial(&wire[0], &wire_fft[0], n, n); - queue.add_to_queue({ - work_queue::WorkType::IFFT, - nullptr, - wire_tag, - typename TCurve::scalar_field_type::value_type::zero(), - 0, - }); - } - } - - void execute_first_round() { - queue.flush_queue(); - compute_wire_pre_commitments(); - for (auto &widget : random_widgets) { - widget->compute_round_commitments(transcript, 1, queue); - } - } - - void execute_second_round() { - queue.flush_queue(); - transcript.apply_fiat_shamir("eta"); - for (auto &widget : random_widgets) { - widget->compute_round_commitments(transcript, 2, queue); - } - } - - void execute_third_round() { - queue.flush_queue(); - transcript.apply_fiat_shamir("beta"); - for (auto &widget : random_widgets) { - widget->compute_round_commitments(transcript, 3, queue); - } - - for (size_t i = 0; i < settings::program_width; ++i) { - std::string wire_tag = "w_" + std::to_string(i + 1); - queue.add_to_queue({ - work_queue::WorkType::FFT, - nullptr, - wire_tag, - typename TCurve::scalar_field_type::value_type::zero(), - 0, - }); - } - } - - void execute_fourth_round() { - queue.flush_queue(); - transcript.apply_fiat_shamir("alpha"); - - typename TCurve::scalar_field_type::value_type alpha_base = - typename TCurve::scalar_field_type::value_type::serialize_from_buffer( - transcript.get_challenge("alpha").begin()); - - for (auto &widget : random_widgets) { - alpha_base = widget->compute_quotient_contribution(alpha_base, transcript); - } - for (auto &widget : transition_widgets) { - alpha_base = widget->compute_quotient_contribution(alpha_base, transcript); - } - typename TCurve::scalar_field_type::value_type *q_mid = &key->quotient_mid[0]; - typename TCurve::scalar_field_type::value_type *q_large = &key->quotient_large[0]; - - if constexpr (settings::uses_quotient_mid) { - math::polynomial_arithmetic::divide_by_pseudo_vanishing_polynomial( - key->quotient_mid.get_coefficients(), key->small_domain, key->mid_domain); - } - math::polynomial_arithmetic::divide_by_pseudo_vanishing_polynomial( - key->quotient_large.get_coefficients(), key->small_domain, key->large_domain); - if (settings::uses_quotient_mid) { - key->quotient_mid.coset_ifft(key->mid_domain); - } - key->quotient_large.coset_ifft(key->large_domain); - if (settings::uses_quotient_mid) { - ITERATE_OVER_DOMAIN_START(key->mid_domain); - q_large[i] += q_mid[i]; - ITERATE_OVER_DOMAIN_END; - } - compute_quotient_pre_commitment(); - } - - void execute_fifth_round() { - queue.flush_queue(); - transcript.apply_fiat_shamir("z"); // end of 4th round - compute_linearisation_coefficients(); - } - - void execute_sixth_round() { - queue.flush_queue(); - transcript.apply_fiat_shamir("nu"); - - commitment->batch_open(transcript, queue, key, witness); - } - - typename TCurve::scalar_field_type::value_type compute_linearisation_coefficients() { - - typename TCurve::scalar_field_type::value_type zeta = crypto3::marshalling::algebra < - typename TCurve::scalar_field_type >> - (transcript.get_challenge("z").begin()); - - math::polynomial &r = key->linear_poly; - - commitment->add_opening_evaluations_to_transcript(transcript, key, witness, false); - typename TCurve::scalar_field_type::value_type t_eval = - key->quotient_large.evaluate(zeta, 4 * n); - - if constexpr (use_linearisation) { - typename TCurve::scalar_field_type::value_type alpha_base = - typename TCurve::scalar_field_type::value_type::serialize_from_buffer( - transcript.get_challenge("alpha").begin()); - - for (auto &widget : random_widgets) { - alpha_base = widget->compute_linear_contribution(alpha_base, transcript, r); - } - for (auto &widget : transition_widgets) { - alpha_base = widget->compute_linear_contribution(alpha_base, transcript, &r[0]); - } - typename TCurve::scalar_field_type::value_type linear_eval = r.evaluate(zeta, n); - transcript.add_element("r", linear_eval.to_buffer()); - } - transcript.add_element("t", t_eval.to_buffer()); - return t_eval; - } - - plonk_proof &export_proof() { - proof.proof_data = transcript.export_transcript(); - return proof; - } - - plonk_proof &construct_proof() { - execute_preamble_round(); - queue.process_queue(); - execute_first_round(); - queue.process_queue(); - execute_second_round(); - queue.process_queue(); - execute_third_round(); - queue.process_queue(); - execute_fourth_round(); - queue.process_queue(); - execute_fifth_round(); - execute_sixth_round(); - queue.process_queue(); - return export_proof(); - } - - void reset() { - transcript::Manifest manifest = transcript.get_manifest(); - transcript = transcript::StandardTranscript(manifest, settings::hash_type, - settings::num_challenge_bytes); - } - }; - } // namespace snark - } // namespace zk - } // namespace crypto3 -} // namespace nil - -#endif // CRYPTO3_ZK_PLONK_BATCHED_KATE_PROVER_HPP diff --git a/parallel-crypto3/libs/parallel-zk/include/nil/crypto3/zk/snark/systems/plonk/kate/proving_key.hpp b/parallel-crypto3/libs/parallel-zk/include/nil/crypto3/zk/snark/systems/plonk/kate/proving_key.hpp deleted file mode 100644 index 872c5a3416..0000000000 --- a/parallel-crypto3/libs/parallel-zk/include/nil/crypto3/zk/snark/systems/plonk/kate/proving_key.hpp +++ /dev/null @@ -1,302 +0,0 @@ -//---------------------------------------------------------------------------// -// Copyright (c) 2021 Mikhail Komarov -// Copyright (c) 2021 Nikita Kaskov -// -// MIT License -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -//---------------------------------------------------------------------------// - -#ifndef PARALLEL_CRYPTO3_PLONK_BATCHED_KATE_PROVING_KEY_HPP -#define PARALLEL_CRYPTO3_PLONK_BATCHED_KATE_PROVING_KEY_HPP - -#ifdef CRYPTO3_PLONK_BATCHED_KATE_PROVING_KEY_HPP -#error "You're mixing parallel and non-parallel crypto3 versions" -#endif - -#include - -namespace nil { - namespace crypto3 { - namespace zk { - namespace snark { - - template - struct plonk_proving_key_data; - - template - struct plonk_proving_key_data> { - std::uint32_t n; - std::uint32_t num_public_inputs; - bool contains_recursive_proof; - std::vector recursive_proof_public_input_indices; - std::map constraint_selectors; - std::map constraint_selector_ffts; - std::map permutation_selectors; - std::map permutation_selectors_lagrange_base; - std::map permutation_selector_ffts; - }; - - inline bool operator==(plonk_proving_key_data const &lhs, plonk_proving_key_data const &rhs) { - return lhs.n == rhs.n && lhs.num_public_inputs == rhs.num_public_inputs && - lhs.constraint_selectors == rhs.constraint_selectors && - lhs.constraint_selector_ffts == rhs.constraint_selector_ffts && - lhs.permutation_selectors == rhs.permutation_selectors && - lhs.permutation_selectors_lagrange_base == rhs.permutation_selectors_lagrange_base && - lhs.permutation_selector_ffts == rhs.permutation_selector_ffts && - lhs.contains_recursive_proof == rhs.contains_recursive_proof && - lhs.recursive_proof_public_input_indices == rhs.recursive_proof_public_input_indices; - } - - template - class plonk_proving_key; - - template - class plonk_proving_key> { - constexpr static const std::size_t scalar_bytes = TCurve::scalar_field_type::value_bits / BYTE_BITS; - - std::size_t n; - std::size_t num_public_inputs; - - std::map constraint_selectors; - std::map constraint_selectors_lagrange_base; - std::map constraint_selector_ffts; - - std::map permutation_selectors; - std::map permutation_selectors_lagrange_base; - std::map permutation_selector_ffts; - - std::map wire_ffts; - - math::evaluation_domain small_domain; - math::evaluation_domain mid_domain; - math::evaluation_domain large_domain; - - std::shared_ptr reference_string; - - math::polynomial lagrange_1; - math::polynomial opening_poly; - math::polynomial shifted_opening_poly; - math::polynomial linear_poly; - - math::polynomial quotient_mid; - math::polynomial quotient_large; - - algebra::scalar_multiplication::pippenger_runtime_state pippenger_runtime_state; - - std::vector polynomial_manifest; - - bool contains_recursive_proof = false; - std::vector recursive_proof_public_input_indices; - static constexpr std::size_t min_thread_block = 4UL; - - public: - enum LookupType { - NONE, - ABSOLUTE_LOOKUP, - RELATIVE_LOOKUP, - }; - - plonk_proving_key(const std::size_t num_gates, - const std::size_t num_inputs, - std::shared_ptr const &crs) : - n(num_gates), - num_public_inputs(num_inputs), small_domain(n, n), - mid_domain(2 * n, n > min_thread_block ? n : 2 * n), - large_domain(4 * n, n > min_thread_block ? n : 4 * n), reference_string(crs), - pippenger_runtime_state(n + 1) { - init(); - } - - plonk_proving_key(plonk_proving_key_data &&data, - std::shared_ptr const &crs) : - n(data.n), - num_public_inputs(data.num_public_inputs), - constraint_selectors(std::move(data.constraint_selectors)), - constraint_selector_ffts(std::move(data.constraint_selector_ffts)), - permutation_selectors(std::move(data.permutation_selectors)), - permutation_selectors_lagrange_base(std::move(data.permutation_selectors_lagrange_base)), - permutation_selector_ffts(std::move(data.permutation_selector_ffts)), small_domain(n, n), - mid_domain(2 * n, n > min_thread_block ? n : 2 * n), - large_domain(4 * n, n > min_thread_block ? n : 4 * n), reference_string(crs), - pippenger_runtime_state(n + 1), contains_recursive_proof(data.contains_recursive_proof), - recursive_proof_public_input_indices(std::move(data.recursive_proof_public_input_indices)) { - init(); - // TODO: Currently only supporting TurboComposer in serialization! - std::copy(turbo_polynomial_manifest, - turbo_polynomial_manifest + 20, - std::back_inserter(polynomial_manifest)); - } - - void init() { - if (n != 0) { - small_domain.compute_lookup_table(); - mid_domain.compute_lookup_table(); - large_domain.compute_lookup_table(); - } - - reset(); - - lagrange_1 = math::polynomial(4 * n, 4 * n + 8); - math::polynomial_arithmetic::compute_lagrange_polynomial_fft( - lagrange_1.get_coefficients(), small_domain, large_domain); - lagrange_1.add_lagrange_base_coefficient(lagrange_1[0]); - lagrange_1.add_lagrange_base_coefficient(lagrange_1[1]); - lagrange_1.add_lagrange_base_coefficient(lagrange_1[2]); - lagrange_1.add_lagrange_base_coefficient(lagrange_1[3]); - lagrange_1.add_lagrange_base_coefficient(lagrange_1[4]); - lagrange_1.add_lagrange_base_coefficient(lagrange_1[5]); - lagrange_1.add_lagrange_base_coefficient(lagrange_1[6]); - lagrange_1.add_lagrange_base_coefficient(lagrange_1[7]); - - // The opening polynomial W_{\script{z}}(X) in round 5 of prover's algorithm has degree n. - // However, as explained in - // (./src/aztec/plonk/proof_system/prover/prover.cpp/ProverBase::compute_quotient_pre_commitment), - // for standard plonk (program_width = 3) and number of roots cut out of the vanishing - // polynomial is 4, the degree of the quotient polynomial t(X) is 3n. Thus, the number of - // coefficients in t_{high} is (n + 1). But our prover algorithm assumes that each of t_{low}, - // t_{mid}, t_{high} is of degree (n - 1) (i.e. n coefficients in each). Note that: - // deg(W_{\script{z}}) = max{ deg(t_{low}), deg(t_{mid}), deg(t_{high}), deg(a), deg(b), ... } - // => deg(W_{\script{z}}) = n + 1 when program_width is 3! - // Therefore, when program_width is 3, we need to allow the degree of the opening polynomial to - // be (n + 1) and NOT n. - // - opening_poly = math::polynomial(n, n); - shifted_opening_poly = math::polynomial(n, n); - linear_poly = math::polynomial(n, n); - - quotient_mid = math::polynomial(2 * n, 2 * n); - quotient_large = math::polynomial(4 * n, 4 * n); - - memset((void *)&opening_poly[0], 0x00, scalar_bytes * n); - memset((void *)&shifted_opening_poly[0], 0x00, scalar_bytes * n); - memset((void *)&linear_poly[0], 0x00, scalar_bytes * n); - memset((void *)"ient_mid[0], 0x00, scalar_bytes * 2 * n); - memset((void *)"ient_large[0], 0x00, scalar_bytes * 4 * n); - } - - void reset() { - wire_ffts.clear(); - - opening_poly = math::polynomial(n, n); - - math::polynomial w_1_fft = math::polynomial(4 * n + 4, 4 * n + 4); - math::polynomial w_2_fft = math::polynomial(4 * n + 4, 4 * n + 4); - math::polynomial w_3_fft = math::polynomial(4 * n + 4, 4 * n + 4); - math::polynomial w_4_fft = math::polynomial(4 * n + 4, 4 * n + 4); - math::polynomial z_fft = math::polynomial(4 * n + 4, 4 * n + 4); - - memset((void *)&w_1_fft[0], 0x00, sizeof(scalar_bytes) * (4 * n + 4)); - memset((void *)&w_2_fft[0], 0x00, sizeof(scalar_bytes) * (4 * n + 4)); - memset((void *)&w_3_fft[0], 0x00, sizeof(scalar_bytes) * (4 * n + 4)); - memset((void *)&w_4_fft[0], 0x00, sizeof(scalar_bytes) * (4 * n + 4)); - memset((void *)&z_fft[0], 0x00, sizeof(scalar_bytes) * (4 * n + 4)); - - wire_ffts.insert({"w_1_fft", std::move(w_1_fft)}); - wire_ffts.insert({"w_2_fft", std::move(w_2_fft)}); - wire_ffts.insert({"w_3_fft", std::move(w_3_fft)}); - wire_ffts.insert({"w_4_fft", std::move(w_4_fft)}); - wire_ffts.insert({"z_fft", std::move(z_fft)}); - } - - plonk_proving_key &operator=(const plonk_proving_key &other) { - n = other.n; - num_public_inputs = other.num_public_inputs; - constraint_selectors = std::move(other.constraint_selectors); - constraint_selectors_lagrange_base = std::move(other.constraint_selectors_lagrange_base); - constraint_selector_ffts = std::move(other.constraint_selector_ffts); - permutation_selectors = std::move(other.permutation_selectors); - permutation_selectors_lagrange_base = std::move(other.permutation_selectors_lagrange_base); - permutation_selector_ffts = std::move(other.permutation_selector_ffts); - wire_ffts = std::move(other.wire_ffts); - small_domain = std::move(other.small_domain); - mid_domain = std::move(other.mid_domain); - large_domain = std::move(other.large_domain); - reference_string = std::move(other.reference_string); - lagrange_1 = std::move(other.lagrange_1); - opening_poly = std::move(other.opening_poly); - shifted_opening_poly = std::move(other.shifted_opening_poly); - linear_poly = std::move(other.linear_poly); - pippenger_runtime_state = std::move(other.pippenger_runtime_state); - polynomial_manifest = std::move(other.polynomial_manifest); - contains_recursive_proof = other.contains_recursive_proof; - recursive_proof_public_input_indices = std::move(other.recursive_proof_public_input_indices); - - return *this; - } - - plonk_proving_key(const plonk_proving_key &other) : - n(other.n), num_public_inputs(other.num_public_inputs), - constraint_selectors(other.constraint_selectors), - constraint_selectors_lagrange_base(other.constraint_selectors_lagrange_base), - constraint_selector_ffts(other.constraint_selector_ffts), - permutation_selectors(other.permutation_selectors), - permutation_selectors_lagrange_base(other.permutation_selectors_lagrange_base), - permutation_selector_ffts(other.permutation_selector_ffts), wire_ffts(other.wire_ffts), - small_domain(other.small_domain), mid_domain(other.mid_domain), - large_domain(other.large_domain), reference_string(other.reference_string), - lagrange_1(other.lagrange_1), opening_poly(other.opening_poly), - shifted_opening_poly(other.shifted_opening_poly), linear_poly(other.linear_poly), - quotient_mid(other.quotient_mid), quotient_large(other.quotient_large), - pippenger_runtime_state(n + 1), polynomial_manifest(other.polynomial_manifest), - contains_recursive_proof(other.contains_recursive_proof), - recursive_proof_public_input_indices(other.recursive_proof_public_input_indices) { - } - - plonk_proving_key(plonk_proving_key &&other) : - n(other.n), num_public_inputs(other.num_public_inputs), - constraint_selectors(other.constraint_selectors), - constraint_selectors_lagrange_base(other.constraint_selectors_lagrange_base), - constraint_selector_ffts(other.constraint_selector_ffts), - permutation_selectors(other.permutation_selectors), - permutation_selectors_lagrange_base(other.permutation_selectors_lagrange_base), - permutation_selector_ffts(other.permutation_selector_ffts), wire_ffts(other.wire_ffts), - small_domain(std::move(other.small_domain)), mid_domain(std::move(other.mid_domain)), - large_domain(std::move(other.large_domain)), - reference_string(std::move(other.reference_string)), lagrange_1(std::move(other.lagrange_1)), - opening_poly(std::move(other.opening_poly)), - shifted_opening_poly(std::move(other.shifted_opening_poly)), - linear_poly(std::move(other.linear_poly)), - pippenger_runtime_state(std::move(other.pippenger_runtime_state)), - polynomial_manifest(std::move(other.polynomial_manifest)), - contains_recursive_proof(other.contains_recursive_proof), - recursive_proof_public_input_indices(std::move(other.recursive_proof_public_input_indices)) { - } - - std::size_t size_in_bits() const { - ? ? ? ; - } - - bool operator==(const plonk_proving_key &other) const { - return this->n == other.n && this->num_public_inputs == other.num_public_inputs && - this->constraint_selectors == other.constraint_selectors && - this->constraint_selector_ffts == other.constraint_selector_ffts && - this->permutation_selectors == other.permutation_selectors && - this->permutation_selectors_lagrange_base == other.permutation_selectors_lagrange_base && - this->permutation_selector_ffts == other.permutation_selector_ffts && - this->contains_recursive_proof == other.contains_recursive_proof && - this->recursive_proof_public_input_indices == other.recursive_proof_public_input_indices; - } - }; - } // namespace snark - } // namespace zk - } // namespace crypto3 -} // namespace nil - -#endif // CRYPTO3_PLONK_BATCHED_KATE_PROVING_KEY_HPP diff --git a/parallel-crypto3/libs/parallel-zk/include/nil/crypto3/zk/snark/systems/plonk/kate/verification_key.hpp b/parallel-crypto3/libs/parallel-zk/include/nil/crypto3/zk/snark/systems/plonk/kate/verification_key.hpp deleted file mode 100644 index bada02f6ea..0000000000 --- a/parallel-crypto3/libs/parallel-zk/include/nil/crypto3/zk/snark/systems/plonk/kate/verification_key.hpp +++ /dev/null @@ -1,157 +0,0 @@ -//---------------------------------------------------------------------------// -// Copyright (c) 2021 Mikhail Komarov -// Copyright (c) 2021 Nikita Kaskov -// -// MIT License -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -//---------------------------------------------------------------------------// - -#ifndef PARALLEL_CRYPTO3_PLONK_BATCHED_KATE_VERIFICATION_KEY_HPP -#define PARALLEL_CRYPTO3_PLONK_BATCHED_KATE_VERIFICATION_KEY_HPP - -#ifdef CRYPTO3_PLONK_BATCHED_KATE_VERIFICATION_KEY_HPP -#error "You're mixing parallel and non-parallel crypto3 versions" -#endif - -#include - -namespace nil { - namespace crypto3 { - namespace zk { - namespace snark { - - template - struct plonk_verification_key_data; - - template - struct plonk_verification_key_data> { - std::uint32_t n; - std::uint32_t num_public_inputs; - std::map::value_type> constraint_selectors; - std::map::value_type> permutation_selectors; - bool contains_recursive_proof = false; - std::vector recursive_proof_public_input_indices; - }; - - inline bool operator==(plonk_verification_key_data const &lhs, plonk_verification_key_data const &rhs) { - return lhs.n == rhs.n && lhs.num_public_inputs == rhs.num_public_inputs && - lhs.constraint_selectors == rhs.constraint_selectors && - lhs.permutation_selectors == rhs.permutation_selectors; - } - - template - class plonk_verification_key; - - template - class plonk_verification_key> { - using commitment_scheme_type = batched_kate_commitment_scheme<...>; - - constexpr static const std::size_t scalar_bytes = TCurve::scalar_field_type::value_bits / BYTE_BITS; - - std::size_t n; - std::size_t num_public_inputs; - - math::evaluation_domain domain; - - std::shared_ptr reference_string; - - std::map::value_type> constraint_selectors; - - std::map::value_type> permutation_selectors; - - std::vector polynomial_manifest; - - // this is a member variable because stdlib::field has no `pow` method, we - // have to compute this differently for the normal and recursive settings respectively - typename TCurve::scalar_field_type::value_type z_pow_n; - - bool contains_recursive_proof = false; - std::vector recursive_proof_public_input_indices; - std::size_t program_width = 3; - - public: - plonk_verification_key(const std::size_t num_gates, - const std::size_t num_inputs, - std::shared_ptr const &crs) : - n(num_gates), - num_public_inputs(num_inputs), domain(n), reference_string(crs) { - } - - plonk_verification_key(plonk_verification_key_data &&data, - std::shared_ptr const &crs) : - n(data.n), - num_public_inputs(data.num_public_inputs), domain(n), reference_string(crs), - constraint_selectors(std::move(data.constraint_selectors)), - permutation_selectors(std::move(data.permutation_selectors)), - contains_recursive_proof(data.contains_recursive_proof), - recursive_proof_public_input_indices(std::move(data.recursive_proof_public_input_indices)) { - // TODO: Currently only supporting TurboComposer in serialization! - std::copy(turbo_polynomial_manifest, - turbo_polynomial_manifest + 20, - std::back_inserter(polynomial_manifest)); - } - - plonk_verification_key &operator=(plonk_verification_key &&other) { - n = other.n; - num_public_inputs = other.num_public_inputs; - reference_string = std::move(other.reference_string); - constraint_selectors = std::move(other.constraint_selectors); - permutation_selectors = std::move(other.permutation_selectors); - polynomial_manifest = std::move(other.polynomial_manifest); - domain = std::move(other.domain); - contains_recursive_proof = (other.contains_recursive_proof); - recursive_proof_public_input_indices = std::move(other.recursive_proof_public_input_indices); - return *this; - } - - plonk_verification_key(const plonk_verification_key &other) : - n(other.n), num_public_inputs(other.num_public_inputs), domain(other.domain), - reference_string(other.reference_string), constraint_selectors(other.constraint_selectors), - permutation_selectors(other.permutation_selectors), - polynomial_manifest(other.polynomial_manifest), - contains_recursive_proof(other.contains_recursive_proof), - recursive_proof_public_input_indices(other.recursive_proof_public_input_indices) { - } - - plonk_verification_key(plonk_verification_key &&other) : - n(other.n), num_public_inputs(other.num_public_inputs), domain(other.domain), - reference_string(other.reference_string), constraint_selectors(other.constraint_selectors), - permutation_selectors(other.permutation_selectors), - polynomial_manifest(other.polynomial_manifest), - contains_recursive_proof(other.contains_recursive_proof), - recursive_proof_public_input_indices(other.recursive_proof_public_input_indices) { - } - - std::size_t size_in_bits() const { - ? ? ? ; - } - - bool operator==(const plonk_verification_key &other) const { - return this->n == rhs.n && this->num_public_inputs == rhs.num_public_inputs && - this->constraint_selectors == rhs.constraint_selectors && - this->permutation_selectors == rhs.permutation_selectors; - } - }; - } // namespace snark - } // namespace zk - } // namespace crypto3 -} // namespace nil - -#endif // CRYPTO3_PLONK_BATCHED_KATE_VERIFICATION_KEY_HPP diff --git a/parallel-crypto3/libs/parallel-zk/include/nil/crypto3/zk/snark/systems/plonk/kate/verifier.hpp b/parallel-crypto3/libs/parallel-zk/include/nil/crypto3/zk/snark/systems/plonk/kate/verifier.hpp deleted file mode 100644 index 626ed523e4..0000000000 --- a/parallel-crypto3/libs/parallel-zk/include/nil/crypto3/zk/snark/systems/plonk/kate/verifier.hpp +++ /dev/null @@ -1,296 +0,0 @@ -//---------------------------------------------------------------------------// -// Copyright (c) 2021 Mikhail Komarov -// Copyright (c) 2021 Nikita Kaskov -// -// MIT License -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -//---------------------------------------------------------------------------// - -#ifndef PARALLEL_CRYPTO3_ZK_PLONK_BATCHED_KATE_VERIFIER_HPP -#define PARALLEL_CRYPTO3_ZK_PLONK_BATCHED_KATE_VERIFIER_HPP - -#ifdef CRYPTO3_ZK_PLONK_BATCHED_KATE_VERIFIER_HPP -#error "You're mixing parallel and non-parallel crypto3 versions" -#endif - -#include - -namespace nil { - namespace crypto3 { - namespace zk { - namespace snark { - - template - class plonk_verifier; - - template - class plonk_verifier> { - using commitment_scheme_type = batched_kate_commitment_scheme<...>; - using constraint_system_type = plonk_constraint_system; - - transcript::Manifest manifest; - - std::shared_ptr> key; - std::map::value_type> kate_g1_elements; - std::map kate_fr_elements; - std::unique_ptr commitment; - - public: - plonk_verifier(std::shared_ptr> verifier_key, - const transcript::Manifest &input_manifest) : - manifest(input_manifest), - key(verifier_key) { - } - - plonk_verifier &operator=(plonk_verifier &&other) { - key = other.key; - manifest = other.manifest; - commitment = (std::move(other.commitment)); - kate_g1_elements.clear(); - kate_fr_elements.clear(); - return *this; - } - - plonk_verifier(plonk_verifier &&other) : - manifest(other.manifest), key(other.key), commitment(std::move(other.commitment)) { - } - - bool validate_commitments() { - // TODO - return true; - } - - bool validate_scalars() { - // TODO - return true; - } - - bool process(const plonk_proof &proof) { - // This function verifies a PLONK proof for given program settings. - // A PLONK proof for standard PLONK with linearisation as on page 31 in the paper is of the - // form: - // - // π_SNARK = { [a]_1,[b]_1,[c]_1,[z]_1,[t_{low}]_1,[t_{mid}]_1,[t_{high}]_1,[W_z]_1,[W_zω]_1 - // \in G, - // a_eval, b_eval, c_eval, sigma1_eval, sigma2_eval, r_eval, z_eval_omega \in F } - // - // Proof π_SNARK must be first added in the transcrip with other program settings. - // - key->program_width = program_settings::program_width; - transcript::StandardTranscript transcript = - transcript::StandardTranscript(proof.proof_data, - manifest, - program_settings::hash_type, - program_settings::num_challenge_bytes); - - // Compute challenges using Fiat-Shamir heuristic from transcript - transcript.add_element( - "circuit_size", - {static_cast(key->n >> 24), static_cast(key->n >> 16), - static_cast(key->n >> 8), static_cast(key->n)}); - transcript.add_element("public_input_size", - {static_cast(key->num_public_inputs >> 24), - static_cast(key->num_public_inputs >> 16), - static_cast(key->num_public_inputs >> 8), - static_cast(key->num_public_inputs)}); - transcript.apply_fiat_shamir("init"); - transcript.apply_fiat_shamir("eta"); - transcript.apply_fiat_shamir("beta"); - transcript.apply_fiat_shamir("alpha"); - transcript.apply_fiat_shamir("z"); - - const typename TCurve::scalar_field_type::value_type alpha = - crypto3::marshalling::algebra( - transcript.get_challenge("alpha").begin()); - const typename TCurve::scalar_field_type::value_type zeta = - crypto3::marshalling::algebra( - transcript.get_challenge("z").begin()); - - // Compute the evaluations of the lagrange polynomials L_1(X) and L_{n - k}(X) at X = zeta. - // Here k = num_roots_cut_out_of_the_vanishing_polynomial and n is the size of the evaluation - // domain. - const auto lagrange_evals = - math::polynomial_arithmetic::get_lagrange_evaluations(zeta, key->domain); - - // Step 8: Compute quotient polynomial evaluation at zeta - // r_eval − ((a_eval + β.sigma1_eval + γ)(b_eval + β.sigma2_eval + γ)(c_eval + γ) - // z_eval_omega)α − L_1(zeta).α^{3} + (z_eval_omega - ∆_{PI}).L_{n-k}(zeta)α^{2} - // t_eval = - // -------------------------------------------------------------------------------------------------------------------------------------------------------------- - // Z_H*(zeta) - // where Z_H*(X) is the modified vanishing polynomial. - // The `compute_quotient_evaluation_contribution` function computes the numerator of t_eval - // according to the program settings for standard/turbo/ultra PLONK. - // - key->z_pow_n = zeta; - for (size_t i = 0; i < key->domain.log2_size; ++i) { - key->z_pow_n *= key->z_pow_n; - } - typename TCurve::scalar_field_type::value_type t_eval = - typename TCurve::scalar_field_type::value_type::zero(); - program_settings::compute_quotient_evaluation_contribution( - key.get(), alpha, transcript, t_eval); - t_eval *= lagrange_evals.vanishing_poly.invert(); - transcript.add_element("t", t_eval.to_buffer()); - - transcript.apply_fiat_shamir("nu"); - transcript.apply_fiat_shamir("separator"); - const typename TCurve::scalar_field_type::value_type separator_challenge = - crypto3::marshalling::algebra( - transcript.get_challenge("separator").begin()); - - // In the following function, we do the following computation. - // Step 10: Compute batch opening commitment [F]_1 - // [F] := [t_{low}]_1 + \zeta^{n}.[tmid]1 + \zeta^{2n}.[t_{high}]_1 - // + [D]_1 + \nu_{a}.[a]_1 + \nu_{b}.[b]_1 + \nu_{c}.[c]_1 - // + \nu_{\sigma1}.[s_{\sigma_1}]1 + \nu_{\sigma2}.[s_{\sigma_2}]1 - // - // We do not compute [D]_1 term in this method as the information required to compute [D]_1 - // in inadequate as far as this KateCommitmentScheme class is concerned. - // - // Step 11: Compute batch evaluation commitment [E]_1 - // [E]_1 := (t_eval + \nu_{r}.r_eval + \nu_{a}.a_eval + \nu_{b}.b_eval - // \nu_{c}.c_eval + \nu_{\sigma1}.sigma1_eval + \nu_{\sigma2}.sigma2_eval + - // nu_z_omega.separator.z_eval_omega) . [1]_1 - // - // Note that we do not actually compute the scalar multiplications but just accumulate the - // scalars and the group elements in different vectors. - // - commitment->batch_verify(transcript, kate_g1_elements, kate_fr_elements, key); - - // Step 9: Compute partial opening batch commitment [D]_1: - // [D]_1 = (a_eval.b_eval.[qM]_1 + a_eval.[qL]_1 + b_eval.[qR]_1 + c_eval.[qO]_1 + - // [qC]_1) * nu_{linear} * α - // >> selector polynomials - // + [(a_eval + β.z + γ)(b_eval + β.k_1.z + γ)(c_eval + β.k_2.z + γ).α + - // L_1(z).α^{3}].nu_{linear}.[z]_1 >> grand product perm polynomial - // - (a_eval + β.sigma1_eval + γ)(b_eval + β.sigma2_eval + - // γ)α.β.nu_{linear}.z_omega_eval.[sigma3]_1 >> last perm polynomial - // - // Again, we dont actually compute the MSMs and just accumulate scalars and group elements and - // postpone MSM to last step. - // - append_scalar_multiplication_inputs(key.get(), alpha, transcript, kate_fr_elements); - - // Fetch the group elements [W_z]_1,[W_zω]_1 from the transcript - typename TCurve::g1_type::value_type PI_Z = - crypto3::marshalling::algebra::value_type>( - &transcript.get_element("PI_Z")[0]); - typename TCurve::g1_type::value_type PI_Z_OMEGA = - crypto3::marshalling::algebra::value_type>( - &transcript.get_element("PI_Z_OMEGA")[0]); - - // Accumulate pairs of scalars and group elements which would be used in the final pairing - // check. - kate_g1_elements.insert({"PI_Z_OMEGA", PI_Z_OMEGA}); - kate_fr_elements.insert({"PI_Z_OMEGA", zeta * key->domain.root * separator_challenge}); - - kate_g1_elements.insert({"PI_Z", PI_Z}); - kate_fr_elements.insert({"PI_Z", zeta}); - - validate_commitments(); - validate_scalars(); - - std::vector scalars; - std::vector::value_type> elements; - - for (const auto &[key, value] : kate_g1_elements) { - if (value.on_curve()) { - scalars.emplace_back(kate_fr_elements.at(key)); - elements.emplace_back(value); - } - } - - size_t num_elements = elements.size(); - elements.resize(num_elements * 2); - algebra::scalar_multiplication::generate_pippenger_point_table( - &elements[0], &elements[0], num_elements); - scalar_multiplication::pippenger_runtime_state state(num_elements); - - typename TCurve::g1_type<>::value_type P[2]; - - P[0] = - alegbra::scalar_multiplication::pippenger(&scalars[0], &elements[0], num_elements, state); - P[1] = -(typename TCurve::g1_type<>::value_type(PI_Z_OMEGA) * separator_challenge + PI_Z); - - if (key->contains_recursive_proof) { - assert(key->recursive_proof_public_input_indices.size() == 16); - const auto &inputs = transcript.get_field_element_vector("public_inputs"); - const auto recover_fq_from_public_inputs = - [&inputs](const size_t idx0, const size_t idx1, const size_t idx2, const size_t idx3) { - const uint256_t l0 = inputs[idx0]; - const uint256_t l1 = inputs[idx1]; - const uint256_t l2 = inputs[idx2]; - const uint256_t l3 = inputs[idx3]; - - const uint256_t limb = l0 + (l1 << NUM_LIMB_BITS_IN_FIELD_SIMULATION) + - (l2 << (NUM_LIMB_BITS_IN_FIELD_SIMULATION * 2)) + - (l3 << (NUM_LIMB_BITS_IN_FIELD_SIMULATION * 3)); - return typename TCurve::base_field_type::value_type(limb); - }; - - const auto recursion_separator_challenge = - transcript.get_challenge_field_element("separator").sqr(); - - const typename TCurve::base_field_type::value_type x0 = - recover_fq_from_public_inputs(key->recursive_proof_public_input_indices[0], - key->recursive_proof_public_input_indices[1], - key->recursive_proof_public_input_indices[2], - key->recursive_proof_public_input_indices[3]); - const typename TCurve::base_field_type::value_type y0 = - recover_fq_from_public_inputs(key->recursive_proof_public_input_indices[4], - key->recursive_proof_public_input_indices[5], - key->recursive_proof_public_input_indices[6], - key->recursive_proof_public_input_indices[7]); - const typename TCurve::base_field_type::value_type x1 = - recover_fq_from_public_inputs(key->recursive_proof_public_input_indices[8], - key->recursive_proof_public_input_indices[9], - key->recursive_proof_public_input_indices[10], - key->recursive_proof_public_input_indices[11]); - const typename TCurve::base_field_type::value_type y1 = - recover_fq_from_public_inputs(key->recursive_proof_public_input_indices[12], - key->recursive_proof_public_input_indices[13], - key->recursive_proof_public_input_indices[14], - key->recursive_proof_public_input_indices[15]); - P[0] += typename TCurve::g1_type<>::value_type(x0, y0, 1) * recursion_separator_challenge; - P[1] += typename TCurve::g1_type<>::value_type(x1, y1, 1) * recursion_separator_challenge; - } - - typename TCurve::g1_type<>::value_type::batch_normalize(P, 2); - - typename TCurve::g1_type::value_type P_affine[2] { - {P[0].x, P[0].y}, - {P[1].x, P[1].y}, - }; - - // The final pairing check of step 12. - typename TCurve::gt_type::value_type result = - algebra::pairing::reduced_ate_pairing_batch_precomputed( - P_affine, key->reference_string->get_precomputed_g2_lines(), 2); - - return (result == typename TCurve::gt_type::value_type::one()); - } - }; - } // namespace snark - } // namespace zk - } // namespace crypto3 -} // namespace nil - -#endif // CRYPTO3_ZK_PLONK_BATCHED_KATE_VERIFIER_HPP