From c8897ca7e551d988df0e23c7b4e9587569685052 Mon Sep 17 00:00:00 2001 From: Cody Gunton Date: Tue, 19 Mar 2024 16:43:57 -0400 Subject: [PATCH] refactor: No Translator composer (#5202) Get rid of the Translator composer. The eventual goal will be a a uniform interface across all proving systems (prover, verifier, keys all constructed in the same way, also sharing more code). --- .../src/barretenberg/eccvm/eccvm_composer.cpp | 6 +- .../barretenberg/flavor/goblin_translator.hpp | 135 +++++++- .../cpp/src/barretenberg/goblin/goblin.hpp | 18 +- .../honk/proof_system/permutation_library.hpp | 83 +---- .../proof_system/composer/permutation_lib.hpp | 15 +- .../composer/permutation_lib.test.cpp | 2 +- .../sumcheck/instance/prover_instance.hpp | 6 +- .../goblin_translator_composer.cpp | 302 ------------------ .../goblin_translator_composer.fuzzer.cpp | 7 +- .../goblin_translator_composer.hpp | 74 ----- .../goblin_translator_composer.test.cpp | 8 +- .../goblin_translator_prover.cpp | 184 ++++++++++- .../goblin_translator_prover.hpp | 14 +- .../goblin_translator_verifier.cpp | 21 +- .../goblin_translator_verifier.hpp | 13 +- .../ultra_honk/relation_correctness.test.cpp | 2 +- 16 files changed, 361 insertions(+), 529 deletions(-) delete mode 100644 barretenberg/cpp/src/barretenberg/translator_vm/goblin_translator_composer.cpp delete mode 100644 barretenberg/cpp/src/barretenberg/translator_vm/goblin_translator_composer.hpp diff --git a/barretenberg/cpp/src/barretenberg/eccvm/eccvm_composer.cpp b/barretenberg/cpp/src/barretenberg/eccvm/eccvm_composer.cpp index bf5b4c7316c..c6c8bea829d 100644 --- a/barretenberg/cpp/src/barretenberg/eccvm/eccvm_composer.cpp +++ b/barretenberg/cpp/src/barretenberg/eccvm/eccvm_composer.cpp @@ -85,7 +85,11 @@ std::shared_ptr ECCVMComposer_::compute_pro // Fix once we have a stable base to work off of // enforce_nonzero_polynomial_selectors(circuit_constructor, proving_key.get()); - compute_first_and_last_lagrange_polynomials(proving_key.get()); + // First and last lagrange polynomials (in the full circuit size) + const auto [lagrange_first, lagrange_last] = + compute_first_and_last_lagrange_polynomials(proving_key->circuit_size); + proving_key->lagrange_first = lagrange_first; + proving_key->lagrange_last = lagrange_last; { const size_t n = proving_key->circuit_size; typename Flavor::Polynomial lagrange_polynomial_second(n); diff --git a/barretenberg/cpp/src/barretenberg/flavor/goblin_translator.hpp b/barretenberg/cpp/src/barretenberg/flavor/goblin_translator.hpp index 16ea236f8f6..f69a5814155 100644 --- a/barretenberg/cpp/src/barretenberg/flavor/goblin_translator.hpp +++ b/barretenberg/cpp/src/barretenberg/flavor/goblin_translator.hpp @@ -5,6 +5,7 @@ #include "barretenberg/ecc/curves/bn254/bn254.hpp" #include "barretenberg/flavor/flavor.hpp" #include "barretenberg/flavor/flavor_macros.hpp" +#include "barretenberg/honk/proof_system/permutation_library.hpp" #include "barretenberg/polynomials/univariate.hpp" #include "barretenberg/proof_system/arithmetization/arithmetization.hpp" #include "barretenberg/proof_system/circuit_builder/goblin_translator_circuit_builder.hpp" @@ -34,6 +35,8 @@ class GoblinTranslatorFlavor { using Polynomial = bb::Polynomial; using RelationSeparator = FF; + static constexpr size_t MINIMUM_MINI_CIRCUIT_SIZE = 2048; + // The size of the circuit which is filled with non-zero values for most polynomials. Most relations (everything // except for Permutation and GenPermSort) can be evaluated just on the first chunk // It is also the only parameter that can be changed without updating relations or structures in the flavor @@ -125,6 +128,72 @@ class GoblinTranslatorFlavor { auto get_selectors() { return RefArray{}; }; auto get_sigma_polynomials() { return RefArray{}; }; auto get_id_polynomials() { return RefArray{}; }; + + inline void compute_lagrange_polynomials(const CircuitBuilder& builder) + { + const size_t circuit_size = compute_dyadic_circuit_size(builder); + const size_t mini_circuit_dyadic_size = compute_mini_circuit_dyadic_size(builder); + + Polynomial lagrange_polynomial_odd_in_minicircuit(circuit_size); + Polynomial lagrange_polynomial_even_in_minicircut(circuit_size); + Polynomial lagrange_polynomial_second(circuit_size); + Polynomial lagrange_polynomial_second_to_last_in_minicircuit(circuit_size); + + for (size_t i = 1; i < mini_circuit_dyadic_size - 1; i += 2) { + lagrange_polynomial_odd_in_minicircuit[i] = 1; + lagrange_polynomial_even_in_minicircut[i + 1] = 1; + } + this->lagrange_odd_in_minicircuit = lagrange_polynomial_odd_in_minicircuit.share(); + this->lagrange_even_in_minicircuit = lagrange_polynomial_even_in_minicircut.share(); + lagrange_polynomial_second[1] = 1; + lagrange_polynomial_second_to_last_in_minicircuit[mini_circuit_dyadic_size - 2] = 1; + this->lagrange_second_to_last_in_minicircuit = lagrange_polynomial_second_to_last_in_minicircuit.share(); + this->lagrange_second = lagrange_polynomial_second.share(); + } + + /** + * @brief Compute the extra numerator for Goblin range constraint argument + * + * @details Goblin proves that several polynomials contain only values in a certain range through 2 relations: + * 1) A grand product which ignores positions of elements (GoblinTranslatorPermutationRelation) + * 2) A relation enforcing a certain ordering on the elements of the given polynomial + * (GoblinTranslatorGenPermSortRelation) + * + * We take the values from 4 polynomials, and spread them into 5 polynomials + add all the steps from MAX_VALUE + * to 0. We order these polynomials and use them in the denominator of the grand product, at the same time + * checking that they go from MAX_VALUE to 0. To counteract the added steps we also generate an extra range + * constraint numerator, which contains 5 MAX_VALUE, 5 (MAX_VALUE-STEP),... values + * + */ + inline void compute_extra_range_constraint_numerator() + { + auto& extra_range_constraint_numerator = this->ordered_extra_range_constraints_numerator; + + static constexpr uint32_t MAX_VALUE = (1 << MICRO_LIMB_BITS) - 1; + + // Calculate how many elements there are in the sequence MAX_VALUE, MAX_VALUE - 3,...,0 + size_t sorted_elements_count = (MAX_VALUE / SORT_STEP) + 1 + (MAX_VALUE % SORT_STEP == 0 ? 0 : 1); + + // Check that we can fit every element in the polynomial + ASSERT((NUM_CONCATENATED_WIRES + 1) * sorted_elements_count < extra_range_constraint_numerator.size()); + + std::vector sorted_elements(sorted_elements_count); + + // Calculate the sequence in integers + sorted_elements[0] = MAX_VALUE; + for (size_t i = 1; i < sorted_elements_count; i++) { + sorted_elements[i] = (sorted_elements_count - 1 - i) * SORT_STEP; + } + + // TODO(#756): can be parallelized further. This will use at most 5 threads + auto fill_with_shift = [&](size_t shift) { + for (size_t i = 0; i < sorted_elements_count; i++) { + extra_range_constraint_numerator[shift + i * (NUM_CONCATENATED_WIRES + 1)] = sorted_elements[i]; + } + }; + // Fill polynomials with a sequence, where each element is repeated NUM_CONCATENATED_WIRES+1 times + parallel_for(NUM_CONCATENATED_WIRES + 1, fill_with_shift); + } }; template class ConcatenatedRangeConstraints { @@ -890,6 +959,28 @@ class GoblinTranslatorFlavor { }; public: + static inline size_t compute_total_num_gates(const CircuitBuilder& builder) + { + return std::max(builder.num_gates, MINIMUM_MINI_CIRCUIT_SIZE); + } + + static inline size_t compute_dyadic_circuit_size(const CircuitBuilder& builder) + { + const size_t total_num_gates = compute_total_num_gates(builder); + + // Next power of 2 + const size_t mini_circuit_dyadic_size = builder.get_circuit_subgroup_size(total_num_gates); + + // The actual circuit size is several times bigger than the trace in the builder, because we use + // concatenation to bring the degree of relations down, while extending the length. + return mini_circuit_dyadic_size * CONCATENATION_GROUP_SIZE; + } + + static inline size_t compute_mini_circuit_dyadic_size(const CircuitBuilder& builder) + { + return builder.get_circuit_subgroup_size(compute_total_num_gates(builder)); + } + /** * @brief The proving key is responsible for storing the polynomials used by the prover. * @note TODO(Cody): Maybe multiple inheritance is the right thing here. In that case, nothing should eve @@ -899,12 +990,33 @@ class GoblinTranslatorFlavor { public: BF batching_challenge_v = { 0 }; BF evaluation_input_x = { 0 }; - ProvingKey() = default; // Expose constructors on the base class using Base = ProvingKey_, WitnessEntities, CommitmentKey>; using Base::Base; + ProvingKey() = default; + ProvingKey(const CircuitBuilder& builder) + : ProvingKey_, WitnessEntities, CommitmentKey>( + compute_dyadic_circuit_size(builder), 0) + , batching_challenge_v(builder.batching_challenge_v) + , evaluation_input_x(builder.evaluation_input_x) + { + // First and last lagrange polynomials (in the full circuit size) + const auto [lagrange_first, lagrange_last] = + compute_first_and_last_lagrange_polynomials(compute_dyadic_circuit_size(builder)); + this->lagrange_first = lagrange_first; + this->lagrange_last = lagrange_last; + + // Compute polynomials with odd and even indices set to 1 up to the minicircuit margin + lagrange + // polynomials at second and second to last indices in the minicircuit + compute_lagrange_polynomials(builder); + + // Compute the numerator for the permutation argument with several repetitions of steps bridging 0 and + // maximum range constraint + compute_extra_range_constraint_numerator(); + } + // TODO(https://github.com/AztecProtocol/barretenberg/issues/810): get around this by properly having // concatenated range be a concept outside of witnessentities std::vector get_labels() @@ -917,13 +1029,6 @@ class GoblinTranslatorFlavor { return concatenate(PrecomputedEntities::get_all(), WitnessEntities::get_unshifted_wires()); } - - ProvingKey(const size_t circuit_size) - : ProvingKey_, WitnessEntities, CommitmentKey>(circuit_size, 0) - - , batching_challenge_v(0) - , evaluation_input_x(0) - {} }; /** @@ -934,8 +1039,20 @@ class GoblinTranslatorFlavor { * resolve that, and split out separate PrecomputedPolynomials/Commitments data for clarity but also for * portability of our circuits. */ - using VerificationKey = VerificationKey_, VerifierCommitmentKey>; + class VerificationKey : public VerificationKey_, VerifierCommitmentKey> { + public: + std::vector public_inputs; + + VerificationKey(const size_t circuit_size, const size_t num_public_inputs) + : VerificationKey_(circuit_size, num_public_inputs) + {} + template + VerificationKey(const ProvingKeyPtr& proving_key) + : VerificationKey_(proving_key) + , public_inputs(proving_key->public_inputs) + {} + }; /** * @brief A field element for each entity of the flavor. These entities represent the prover polynomials * evaluated at one point. diff --git a/barretenberg/cpp/src/barretenberg/goblin/goblin.hpp b/barretenberg/cpp/src/barretenberg/goblin/goblin.hpp index 32a36b4cd71..d590482e05b 100644 --- a/barretenberg/cpp/src/barretenberg/goblin/goblin.hpp +++ b/barretenberg/cpp/src/barretenberg/goblin/goblin.hpp @@ -8,7 +8,8 @@ #include "barretenberg/proof_system/circuit_builder/goblin_ultra_circuit_builder.hpp" #include "barretenberg/proof_system/instance_inspector.hpp" #include "barretenberg/stdlib/honk_recursion/verifier/merge_recursive_verifier.hpp" -#include "barretenberg/translator_vm/goblin_translator_composer.hpp" +#include "barretenberg/translator_vm/goblin_translator_prover.hpp" +#include "barretenberg/translator_vm/goblin_translator_verifier.hpp" #include "barretenberg/ultra_honk/merge_prover.hpp" #include "barretenberg/ultra_honk/merge_verifier.hpp" #include "barretenberg/ultra_honk/ultra_prover.hpp" @@ -32,7 +33,7 @@ class Goblin { using ECCVMComposer = bb::ECCVMComposer; using ECCVMProver = bb::ECCVMProver_; using TranslatorBuilder = bb::GoblinTranslatorCircuitBuilder; - using TranslatorComposer = bb::GoblinTranslatorComposer; + using TranslatorProver = bb::GoblinTranslatorProver; using RecursiveMergeVerifier = bb::stdlib::recursion::goblin::MergeRecursiveVerifier_; using MergeProver = bb::MergeProver_; using MergeVerifier = bb::MergeVerifier_; @@ -82,9 +83,9 @@ class Goblin { // TODO(https://github.com/AztecProtocol/barretenberg/issues/798) unique_ptr use is a hack std::unique_ptr eccvm_builder; std::unique_ptr translator_builder; + std::unique_ptr translator_prover; std::unique_ptr eccvm_composer; std::unique_ptr eccvm_prover; - std::unique_ptr translator_composer; AccumulationOutput accumulator; // Used only for ACIR methods for now @@ -173,9 +174,8 @@ class Goblin { { translator_builder = std::make_unique( eccvm_prover->translation_batching_challenge_v, eccvm_prover->evaluation_challenge_x, op_queue); - translator_composer = std::make_unique(); - auto translator_prover = translator_composer->create_prover(*translator_builder, eccvm_prover->transcript); - goblin_proof.translator_proof = translator_prover.construct_proof(); + translator_prover = std::make_unique(*translator_builder, eccvm_prover->transcript); + goblin_proof.translator_proof = translator_prover->construct_proof(); }; /** @@ -208,7 +208,8 @@ class Goblin { auto eccvm_verifier = eccvm_composer->create_verifier(*eccvm_builder); bool eccvm_verified = eccvm_verifier.verify_proof(proof.eccvm_proof); - auto translator_verifier = translator_composer->create_verifier(*translator_builder, eccvm_verifier.transcript); + GoblinTranslatorVerifier translator_verifier(translator_prover->key, eccvm_verifier.transcript); + bool accumulator_construction_verified = translator_verifier.verify_proof(proof.translator_proof); // TODO(https://github.com/AztecProtocol/barretenberg/issues/799): Ensure translation_evaluations are passed // correctly @@ -294,7 +295,8 @@ class Goblin { auto eccvm_verifier = eccvm_composer->create_verifier(*eccvm_builder); bool eccvm_verified = eccvm_verifier.verify_proof(goblin_proof.eccvm_proof); - auto translator_verifier = translator_composer->create_verifier(*translator_builder, eccvm_verifier.transcript); + GoblinTranslatorVerifier translator_verifier(translator_prover->key, eccvm_verifier.transcript); + bool translation_accumulator_construction_verified = translator_verifier.verify_proof(goblin_proof.translator_proof); // TODO(https://github.com/AztecProtocol/barretenberg/issues/799): Ensure translation_evaluations are passed diff --git a/barretenberg/cpp/src/barretenberg/honk/proof_system/permutation_library.hpp b/barretenberg/cpp/src/barretenberg/honk/proof_system/permutation_library.hpp index 59744f96b20..43ec3081adf 100644 --- a/barretenberg/cpp/src/barretenberg/honk/proof_system/permutation_library.hpp +++ b/barretenberg/cpp/src/barretenberg/honk/proof_system/permutation_library.hpp @@ -1,6 +1,7 @@ #pragma once #include "barretenberg/common/ref_vector.hpp" #include "barretenberg/polynomials/polynomial.hpp" +#include "barretenberg/relations/relation_parameters.hpp" #include namespace bb { @@ -353,86 +354,4 @@ void compute_goblin_translator_range_constraint_ordered_polynomials(StorageHandl [](uint32_t in) { return FF(in); }); } -/** - * @brief Compute the extra numerator for Goblin range constraint argument - * - * @details Goblin proves that several polynomials contain only values in a certain range through 2 relations: - * 1) A grand product which ignores positions of elements (GoblinTranslatorPermutationRelation) - * 2) A relation enforcing a certain ordering on the elements of the given polynomial - * (GoblinTranslatorGenPermSortRelation) - * - * We take the values from 4 polynomials, and spread them into 5 polynomials + add all the steps from MAX_VALUE to 0. We - * order these polynomials and use them in the denominator of the grand product, at the same time checking that they go - * from MAX_VALUE to 0. To counteract the added steps we also generate an extra range constraint numerator, which - * contains 5 MAX_VALUE, 5 (MAX_VALUE-STEP),... values - * - * @param key Proving key where we will save the polynomials - * @param dyadic_circuit_size The full size of the circuit - */ -template -inline void compute_extra_range_constraint_numerator(auto proving_key, size_t dyadic_circuit_size) -{ - - // Get the full goblin circuits size (this is the length of concatenated range constraint polynomials) - auto full_circuit_size = dyadic_circuit_size; - auto sort_step = Flavor::SORT_STEP; - auto num_concatenated_wires = Flavor::NUM_CONCATENATED_WIRES; - - auto& extra_range_constraint_numerator = proving_key->ordered_extra_range_constraints_numerator; - - uint32_t MAX_VALUE = (1 << Flavor::MICRO_LIMB_BITS) - 1; - - // Calculate how many elements there are in the sequence MAX_VALUE, MAX_VALUE - 3,...,0 - size_t sorted_elements_count = (MAX_VALUE / sort_step) + 1 + (MAX_VALUE % sort_step == 0 ? 0 : 1); - - // Check that we can fit every element in the polynomial - ASSERT((num_concatenated_wires + 1) * sorted_elements_count < full_circuit_size); - - std::vector sorted_elements(sorted_elements_count); - - // Calculate the sequence in integers - sorted_elements[0] = MAX_VALUE; - for (size_t i = 1; i < sorted_elements_count; i++) { - sorted_elements[i] = (sorted_elements_count - 1 - i) * sort_step; - } - - // TODO(#756): can be parallelized further. This will use at most 5 threads - auto fill_with_shift = [&](size_t shift) { - for (size_t i = 0; i < sorted_elements_count; i++) { - extra_range_constraint_numerator[shift + i * (num_concatenated_wires + 1)] = sorted_elements[i]; - } - }; - // Fill polynomials with a sequence, where each element is repeated num_concatenated_wires+1 times - parallel_for(num_concatenated_wires + 1, fill_with_shift); -} - -/** - * @brief Compute odd and even largrange polynomials (up to mini_circuit length) and put them in the polynomial cache - * - * @param key Proving key where we will save the polynomials - * @param mini_circuit_dyadic_size The size of the part of the circuit where the computation of translated value happens - */ -template -inline void compute_lagrange_polynomials_for_goblin_translator(auto proving_key, size_t mini_circuit_dyadic_size) - -{ - const size_t n = proving_key->circuit_size; - typename Flavor::Polynomial lagrange_polynomial_odd_in_minicircuit(n); - typename Flavor::Polynomial lagrange_polynomial_even_in_minicircut(n); - typename Flavor::Polynomial lagrange_polynomial_second(n); - typename Flavor::Polynomial lagrange_polynomial_second_to_last_in_minicircuit(n); - - for (size_t i = 1; i < mini_circuit_dyadic_size - 1; i += 2) { - lagrange_polynomial_odd_in_minicircuit[i] = 1; - lagrange_polynomial_even_in_minicircut[i + 1] = 1; - } - proving_key->lagrange_odd_in_minicircuit = lagrange_polynomial_odd_in_minicircuit.share(); - - proving_key->lagrange_even_in_minicircuit = lagrange_polynomial_even_in_minicircut.share(); - lagrange_polynomial_second[1] = 1; - lagrange_polynomial_second_to_last_in_minicircuit[mini_circuit_dyadic_size - 2] = 1; - proving_key->lagrange_second_to_last_in_minicircuit = lagrange_polynomial_second_to_last_in_minicircuit.share(); - proving_key->lagrange_second = lagrange_polynomial_second.share(); -} - } // namespace bb \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/proof_system/composer/permutation_lib.hpp b/barretenberg/cpp/src/barretenberg/proof_system/composer/permutation_lib.hpp index 99740c61205..8d2d4c4520a 100644 --- a/barretenberg/cpp/src/barretenberg/proof_system/composer/permutation_lib.hpp +++ b/barretenberg/cpp/src/barretenberg/proof_system/composer/permutation_lib.hpp @@ -349,19 +349,16 @@ void compute_monomial_and_coset_fft_polynomials_from_lagrange(std::string label, /** * @brief Compute Lagrange Polynomials L_0 and L_{n-1} and put them in the polynomial cache - * - * @param key Proving key where we will save the polynomials */ -template inline void compute_first_and_last_lagrange_polynomials(const auto& proving_key) +template +inline std::tuple, Polynomial> compute_first_and_last_lagrange_polynomials(const size_t circuit_size) { - const size_t n = proving_key->circuit_size; - typename Flavor::Polynomial lagrange_polynomial_0(n); - typename Flavor::Polynomial lagrange_polynomial_n_min_1(n); + Polynomial lagrange_polynomial_0(circuit_size); + Polynomial lagrange_polynomial_n_min_1(circuit_size); lagrange_polynomial_0[0] = 1; - proving_key->lagrange_first = lagrange_polynomial_0.share(); - lagrange_polynomial_n_min_1[n - 1] = 1; - proving_key->lagrange_last = lagrange_polynomial_n_min_1.share(); + lagrange_polynomial_n_min_1[circuit_size - 1] = 1; + return std::make_tuple(lagrange_polynomial_0.share(), lagrange_polynomial_n_min_1.share()); } /** diff --git a/barretenberg/cpp/src/barretenberg/proof_system/composer/permutation_lib.test.cpp b/barretenberg/cpp/src/barretenberg/proof_system/composer/permutation_lib.test.cpp index 5754a7ed824..c0d61b918a2 100644 --- a/barretenberg/cpp/src/barretenberg/proof_system/composer/permutation_lib.test.cpp +++ b/barretenberg/cpp/src/barretenberg/proof_system/composer/permutation_lib.test.cpp @@ -82,5 +82,5 @@ TEST_F(PermutationHelperTests, ComputeHonkStyleSigmaLagrangePolynomialsFromMappi TEST_F(PermutationHelperTests, ComputeStandardAuxPolynomials) { // TODO(#425) Flesh out these tests - compute_first_and_last_lagrange_polynomials(proving_key); + compute_first_and_last_lagrange_polynomials(1024); } diff --git a/barretenberg/cpp/src/barretenberg/sumcheck/instance/prover_instance.hpp b/barretenberg/cpp/src/barretenberg/sumcheck/instance/prover_instance.hpp index 4a40250fd6f..29a2b71fc86 100644 --- a/barretenberg/cpp/src/barretenberg/sumcheck/instance/prover_instance.hpp +++ b/barretenberg/cpp/src/barretenberg/sumcheck/instance/prover_instance.hpp @@ -65,7 +65,11 @@ template class ProverInstance_ { construct_databus_polynomials(circuit); } - compute_first_and_last_lagrange_polynomials(proving_key.get()); + // First and last lagrange polynomials (in the full circuit size) + const auto [lagrange_first, lagrange_last] = + compute_first_and_last_lagrange_polynomials(dyadic_circuit_size); + proving_key->lagrange_first = lagrange_first; + proving_key->lagrange_last = lagrange_last; construct_table_polynomials(circuit, dyadic_circuit_size); diff --git a/barretenberg/cpp/src/barretenberg/translator_vm/goblin_translator_composer.cpp b/barretenberg/cpp/src/barretenberg/translator_vm/goblin_translator_composer.cpp deleted file mode 100644 index 8178fe972cc..00000000000 --- a/barretenberg/cpp/src/barretenberg/translator_vm/goblin_translator_composer.cpp +++ /dev/null @@ -1,302 +0,0 @@ -/** - * @file goblin_translator_composer.cpp - * @brief Contains the logic for transfroming a Goblin Translator Circuit Builder object into a witness and methods to - * create prover and verifier objects - * @date 2023-10-05 - */ -#include "goblin_translator_composer.hpp" -#include "barretenberg/flavor/goblin_translator.hpp" -#include "barretenberg/honk/proof_system/permutation_library.hpp" -#include "barretenberg/proof_system/circuit_builder/goblin_translator_circuit_builder.hpp" -#include "barretenberg/proof_system/composer/composer_lib.hpp" -#include "barretenberg/proof_system/composer/permutation_lib.hpp" - -namespace { -using Flavor = bb::GoblinTranslatorFlavor; -} // namespace - -namespace bb { - -/** - * @brief Helper method to compute quantities like total number of gates and dyadic circuit size - * - * @tparam Flavor - * @param circuit_builder - */ - -void GoblinTranslatorComposer::compute_circuit_size_parameters(CircuitBuilder& circuit_builder) -{ - total_num_gates = std::max(circuit_builder.num_gates, MINIMUM_MINI_CIRCUIT_SIZE); - - // Next power of 2 - mini_circuit_dyadic_size = circuit_builder.get_circuit_subgroup_size(total_num_gates); - - // The actual circuit size is several times bigger than the trace in the builder, because we use concatenation to - // bring the degree of relations down, while extending the length. - dyadic_circuit_size = mini_circuit_dyadic_size * Flavor::CONCATENATION_GROUP_SIZE; -} - -/** - * @brief Construct the witness polynomials from the witness vectors in the circuit constructor. - * - * @details In goblin translator wires come as is, since they have to reflect the structure of polynomials in the first - * 4 wires, which we've commited to - * - * @tparam Flavor provides the circuit constructor type and the number of wires. - * @param circuit_builder - * @param dyadic_circuit_size Power of 2 circuit size - * @todo TODO(https://github.com/AztecProtocol/barretenberg/issues/783) Optimize memory operations. - * @return std::vector - * */ - -std::vector construct_wire_polynomials_base_goblin_translator( - const typename Flavor::CircuitBuilder& circuit_builder, const size_t dyadic_circuit_size) -{ - const size_t num_gates = circuit_builder.num_gates; - - std::vector wire_polynomials; - // Populate the wire polynomials with values from conventional wires - for (size_t wire_idx = 0; wire_idx < Flavor::NUM_WIRES; ++wire_idx) { - // Expect all values to be set to 0 initially - typename Flavor::Polynomial w_lagrange(dyadic_circuit_size); - - // Insert conventional gate wire values into the wire polynomial - for (size_t i = 0; i < num_gates; ++i) { - auto& wire = circuit_builder.wires[wire_idx]; - w_lagrange[i] = circuit_builder.get_variable(wire[i]); - } - - wire_polynomials.push_back(std::move(w_lagrange)); - } - return wire_polynomials; -} - -/** - * @brief Compute witness polynomials - * - */ -void GoblinTranslatorComposer::compute_witness(CircuitBuilder& circuit_builder) -{ - if (computed_witness) { - return; - } - - // Construct the conventional wire polynomials - auto wire_polynomials = construct_wire_polynomials_base_goblin_translator(circuit_builder, dyadic_circuit_size); - - // TODO(AD): figure out how to get this in a loop, why does NUM_WIRES=81? @kesha - proving_key->op = wire_polynomials[0]; - proving_key->x_lo_y_hi = wire_polynomials[1]; - proving_key->x_hi_z_1 = wire_polynomials[2]; - proving_key->y_lo_z_2 = wire_polynomials[3]; - proving_key->p_x_low_limbs = wire_polynomials[4]; - proving_key->p_x_low_limbs_range_constraint_0 = wire_polynomials[5]; - proving_key->p_x_low_limbs_range_constraint_1 = wire_polynomials[6]; - proving_key->p_x_low_limbs_range_constraint_2 = wire_polynomials[7]; - proving_key->p_x_low_limbs_range_constraint_3 = wire_polynomials[8]; - proving_key->p_x_low_limbs_range_constraint_4 = wire_polynomials[9]; - proving_key->p_x_low_limbs_range_constraint_tail = wire_polynomials[10]; - proving_key->p_x_high_limbs = wire_polynomials[11]; - proving_key->p_x_high_limbs_range_constraint_0 = wire_polynomials[12]; - proving_key->p_x_high_limbs_range_constraint_1 = wire_polynomials[13]; - proving_key->p_x_high_limbs_range_constraint_2 = wire_polynomials[14]; - proving_key->p_x_high_limbs_range_constraint_3 = wire_polynomials[15]; - proving_key->p_x_high_limbs_range_constraint_4 = wire_polynomials[16]; - proving_key->p_x_high_limbs_range_constraint_tail = wire_polynomials[17]; - proving_key->p_y_low_limbs = wire_polynomials[18]; - proving_key->p_y_low_limbs_range_constraint_0 = wire_polynomials[19]; - proving_key->p_y_low_limbs_range_constraint_1 = wire_polynomials[20]; - proving_key->p_y_low_limbs_range_constraint_2 = wire_polynomials[21]; - proving_key->p_y_low_limbs_range_constraint_3 = wire_polynomials[22]; - proving_key->p_y_low_limbs_range_constraint_4 = wire_polynomials[23]; - proving_key->p_y_low_limbs_range_constraint_tail = wire_polynomials[24]; - proving_key->p_y_high_limbs = wire_polynomials[25]; - proving_key->p_y_high_limbs_range_constraint_0 = wire_polynomials[26]; - proving_key->p_y_high_limbs_range_constraint_1 = wire_polynomials[27]; - proving_key->p_y_high_limbs_range_constraint_2 = wire_polynomials[28]; - proving_key->p_y_high_limbs_range_constraint_3 = wire_polynomials[29]; - proving_key->p_y_high_limbs_range_constraint_4 = wire_polynomials[30]; - proving_key->p_y_high_limbs_range_constraint_tail = wire_polynomials[31]; - proving_key->z_low_limbs = wire_polynomials[32]; - proving_key->z_low_limbs_range_constraint_0 = wire_polynomials[33]; - proving_key->z_low_limbs_range_constraint_1 = wire_polynomials[34]; - proving_key->z_low_limbs_range_constraint_2 = wire_polynomials[35]; - proving_key->z_low_limbs_range_constraint_3 = wire_polynomials[36]; - proving_key->z_low_limbs_range_constraint_4 = wire_polynomials[37]; - proving_key->z_low_limbs_range_constraint_tail = wire_polynomials[38]; - proving_key->z_high_limbs = wire_polynomials[39]; - proving_key->z_high_limbs_range_constraint_0 = wire_polynomials[40]; - proving_key->z_high_limbs_range_constraint_1 = wire_polynomials[41]; - proving_key->z_high_limbs_range_constraint_2 = wire_polynomials[42]; - proving_key->z_high_limbs_range_constraint_3 = wire_polynomials[43]; - proving_key->z_high_limbs_range_constraint_4 = wire_polynomials[44]; - proving_key->z_high_limbs_range_constraint_tail = wire_polynomials[45]; - proving_key->accumulators_binary_limbs_0 = wire_polynomials[46]; - proving_key->accumulators_binary_limbs_1 = wire_polynomials[47]; - proving_key->accumulators_binary_limbs_2 = wire_polynomials[48]; - proving_key->accumulators_binary_limbs_3 = wire_polynomials[49]; - proving_key->accumulator_low_limbs_range_constraint_0 = wire_polynomials[50]; - proving_key->accumulator_low_limbs_range_constraint_1 = wire_polynomials[51]; - proving_key->accumulator_low_limbs_range_constraint_2 = wire_polynomials[52]; - proving_key->accumulator_low_limbs_range_constraint_3 = wire_polynomials[53]; - proving_key->accumulator_low_limbs_range_constraint_4 = wire_polynomials[54]; - proving_key->accumulator_low_limbs_range_constraint_tail = wire_polynomials[55]; - proving_key->accumulator_high_limbs_range_constraint_0 = wire_polynomials[56]; - proving_key->accumulator_high_limbs_range_constraint_1 = wire_polynomials[57]; - proving_key->accumulator_high_limbs_range_constraint_2 = wire_polynomials[58]; - proving_key->accumulator_high_limbs_range_constraint_3 = wire_polynomials[59]; - proving_key->accumulator_high_limbs_range_constraint_4 = wire_polynomials[60]; - proving_key->accumulator_high_limbs_range_constraint_tail = wire_polynomials[61]; - proving_key->quotient_low_binary_limbs = wire_polynomials[62]; - proving_key->quotient_high_binary_limbs = wire_polynomials[63]; - proving_key->quotient_low_limbs_range_constraint_0 = wire_polynomials[64]; - proving_key->quotient_low_limbs_range_constraint_1 = wire_polynomials[65]; - proving_key->quotient_low_limbs_range_constraint_2 = wire_polynomials[66]; - proving_key->quotient_low_limbs_range_constraint_3 = wire_polynomials[67]; - proving_key->quotient_low_limbs_range_constraint_4 = wire_polynomials[68]; - proving_key->quotient_low_limbs_range_constraint_tail = wire_polynomials[69]; - proving_key->quotient_high_limbs_range_constraint_0 = wire_polynomials[70]; - proving_key->quotient_high_limbs_range_constraint_1 = wire_polynomials[71]; - proving_key->quotient_high_limbs_range_constraint_2 = wire_polynomials[72]; - proving_key->quotient_high_limbs_range_constraint_3 = wire_polynomials[73]; - proving_key->quotient_high_limbs_range_constraint_4 = wire_polynomials[74]; - proving_key->quotient_high_limbs_range_constraint_tail = wire_polynomials[75]; - proving_key->relation_wide_limbs = wire_polynomials[76]; - proving_key->relation_wide_limbs_range_constraint_0 = wire_polynomials[77]; - proving_key->relation_wide_limbs_range_constraint_1 = wire_polynomials[78]; - proving_key->relation_wide_limbs_range_constraint_2 = wire_polynomials[79]; - proving_key->relation_wide_limbs_range_constraint_3 = wire_polynomials[80]; - - // We construct concatenated versions of range constraint polynomials, where several polynomials are concatenated - // into one. These polynomials are not commited to. - bb::compute_concatenated_polynomials(proving_key.get()); - - // We also contruct ordered polynomials, which have the same values as concatenated ones + enough values to bridge - // the range from 0 to maximum range defined by the range constraint. - bb::compute_goblin_translator_range_constraint_ordered_polynomials(proving_key.get(), - mini_circuit_dyadic_size); - - computed_witness = true; -} - -/** - * @brief Create a prover object (used to create the proof) - * - * @tparam Flavor - * @param circuit_builder - * @return GoblinTranslatorProver - */ - -GoblinTranslatorProver GoblinTranslatorComposer::create_prover(CircuitBuilder& circuit_builder, - const std::shared_ptr& transcript) -{ - BB_OP_COUNT_TIME_NAME("GoblinTranslatorComposer::create_prover"); - - // Compute total number of gates, dyadic circuit size, etc. - compute_circuit_size_parameters(circuit_builder); - - // Compute non-witness polynomials - compute_proving_key(circuit_builder); - - compute_witness(circuit_builder); - - compute_commitment_key(proving_key->circuit_size); - - GoblinTranslatorProver output_state(proving_key, commitment_key, transcript); - - return output_state; -} - -/** - * @brief Create verifier: compute verification key, - * initialize verifier with it and an initial manifest and initialize commitment_scheme. - * - * @tparam Flavor - * @param circuit_builder - * @return GoblinTranslatorVerifier - */ - -GoblinTranslatorVerifier GoblinTranslatorComposer::create_verifier(const CircuitBuilder& circuit_builder, - const std::shared_ptr& transcript) -{ - auto verification_key = compute_verification_key(circuit_builder); - - GoblinTranslatorVerifier output_state(verification_key); - - auto pcs_verification_key = std::make_unique(); - output_state.pcs_verification_key = std::move(pcs_verification_key); - output_state.transcript = transcript; - - return output_state; -} - -/** - * @brief Move goblin translator specific inputs from circuit builder and compute all the constant polynomials used by - * the prover - * - * @tparam Flavor - * @param circuit_builder - * @return std::shared_ptr - */ - -std::shared_ptr GoblinTranslatorComposer::compute_proving_key( - const CircuitBuilder& circuit_builder) -{ - if (proving_key) { - return proving_key; - } - - proving_key = std::make_shared(dyadic_circuit_size); - - // The input/challenge that we are evaluating all polynomials at - proving_key->evaluation_input_x = circuit_builder.evaluation_input_x; - - // The challenge for batching polynomials - proving_key->batching_challenge_v = circuit_builder.batching_challenge_v; - - // First and last lagrange polynomials (in the full circuit size) - compute_first_and_last_lagrange_polynomials(proving_key.get()); - - // Compute polynomials with odd and even indices set to 1 up to the minicircuit margin + lagrange polynomials at - // second and second to last indices in the minicircuit - bb::compute_lagrange_polynomials_for_goblin_translator(proving_key.get(), mini_circuit_dyadic_size); - - // Compute the numerator for the permutation argument with several repetitions of steps bridging 0 and maximum range - // constraint - bb::compute_extra_range_constraint_numerator(proving_key.get(), dyadic_circuit_size); - - return proving_key; -} - -/** - * Compute verification key consisting of non-changing polynomials' precommitments. - * - * @return Pointer to created circuit verification key. - * */ - -std::shared_ptr GoblinTranslatorComposer::compute_verification_key( - const CircuitBuilder& circuit_builder) -{ - if (verification_key) { - return verification_key; - } - - if (!proving_key) { - compute_proving_key(circuit_builder); - } - - verification_key = std::make_shared(proving_key->circuit_size, proving_key->num_public_inputs); - - verification_key->lagrange_first = commitment_key->commit(proving_key->lagrange_first); - verification_key->lagrange_last = commitment_key->commit(proving_key->lagrange_last); - verification_key->lagrange_odd_in_minicircuit = commitment_key->commit(proving_key->lagrange_odd_in_minicircuit); - verification_key->lagrange_even_in_minicircuit = commitment_key->commit(proving_key->lagrange_even_in_minicircuit); - verification_key->lagrange_second = commitment_key->commit(proving_key->lagrange_second); - verification_key->lagrange_second_to_last_in_minicircuit = - commitment_key->commit(proving_key->lagrange_second_to_last_in_minicircuit); - verification_key->ordered_extra_range_constraints_numerator = - commitment_key->commit(proving_key->ordered_extra_range_constraints_numerator); - - return verification_key; -} -} // namespace bb diff --git a/barretenberg/cpp/src/barretenberg/translator_vm/goblin_translator_composer.fuzzer.cpp b/barretenberg/cpp/src/barretenberg/translator_vm/goblin_translator_composer.fuzzer.cpp index 4e2ad508063..c84224a9fe6 100644 --- a/barretenberg/cpp/src/barretenberg/translator_vm/goblin_translator_composer.fuzzer.cpp +++ b/barretenberg/cpp/src/barretenberg/translator_vm/goblin_translator_composer.fuzzer.cpp @@ -1,6 +1,6 @@ -#include "barretenberg/translator_vm/goblin_translator_composer.hpp" #include "barretenberg/proof_system/circuit_builder/goblin_translator.fuzzer.hpp" #include "barretenberg/translator_vm/goblin_translator_prover.hpp" +#include "barretenberg/translator_vm/goblin_translator_verifier.hpp" extern "C" void LLVMFuzzerInitialize(int*, char***) { srs::init_crs_factory("../srs_db/ignition"); @@ -32,14 +32,13 @@ extern "C" int LLVMFuzzerTestOneInput(const unsigned char* data, size_t size) bool checked = circuit_builder.check_circuit(); // Construct proof - auto composer = bb::GoblinTranslatorComposer(); - auto prover = composer.create_prover(circuit_builder, prover_transcript); + GoblinTranslatorProver prover(circuit_builder, prover_transcript); auto proof = prover.construct_proof(); // Verify proof auto verifier_transcript = std::make_shared(prover_transcript->proof_data); verifier_transcript->template receive_from_prover("init"); - auto verifier = composer.create_verifier(circuit_builder, verifier_transcript); + GoblinTranslatorVerifier verifier(prover.key, verifier_transcript); bool verified = verifier.verify_proof(proof); (void)checked; (void)verified; diff --git a/barretenberg/cpp/src/barretenberg/translator_vm/goblin_translator_composer.hpp b/barretenberg/cpp/src/barretenberg/translator_vm/goblin_translator_composer.hpp deleted file mode 100644 index 88b1dc94189..00000000000 --- a/barretenberg/cpp/src/barretenberg/translator_vm/goblin_translator_composer.hpp +++ /dev/null @@ -1,74 +0,0 @@ -#pragma once - -#include "barretenberg/flavor/goblin_translator.hpp" -#include "barretenberg/proof_system/composer/composer_lib.hpp" -#include "barretenberg/srs/factories/file_crs_factory.hpp" -#include "barretenberg/srs/global_crs.hpp" -#include "barretenberg/translator_vm/goblin_translator_prover.hpp" -#include "barretenberg/translator_vm/goblin_translator_verifier.hpp" - -namespace bb { -class GoblinTranslatorComposer { - public: - using Flavor = GoblinTranslatorFlavor; - using Curve = typename Flavor::Curve; - using CircuitBuilder = typename Flavor::CircuitBuilder; - using ProvingKey = typename Flavor::ProvingKey; - using VerificationKey = typename Flavor::VerificationKey; - using PCS = typename Flavor::PCS; - using CommitmentKey = typename Flavor::CommitmentKey; - using VerifierCommitmentKey = typename Flavor::VerifierCommitmentKey; - using Polynomial = typename Flavor::Polynomial; - using Transcript = NativeTranscript; - - static constexpr std::string_view NAME_STRING = "GoblinTranslator"; - static constexpr size_t NUM_WIRES = CircuitBuilder::NUM_WIRES; - // The minimum size of the mini-circuit (or sorted constraints won't work) - static constexpr size_t MINIMUM_MINI_CIRCUIT_SIZE = 2048; - std::shared_ptr proving_key; - std::shared_ptr verification_key; - - // The crs_factory holds the path to the srs and exposes methods to extract the srs elements - std::shared_ptr> crs_factory_; - - // The commitment key is passed to the prover but also used herein to compute the verfication key commitments - std::shared_ptr commitment_key; - - bool computed_witness = false; - size_t total_num_gates = 0; // num_gates (already include zero row offset) (used to compute dyadic size) - size_t dyadic_circuit_size = 0; // final power-of-2 circuit size - size_t mini_circuit_dyadic_size = 0; // The size of the small circuit that contains non-range constraint relations - - // We only need the standard crs factory. GoblinTranslatorFlavor is not supposed to be used with Grumpkin - GoblinTranslatorComposer() { crs_factory_ = bb::srs::get_bn254_crs_factory(); } - - GoblinTranslatorComposer(std::shared_ptr p_key, std::shared_ptr v_key) - : proving_key(std::move(p_key)) - , verification_key(std::move(v_key)) - {} - - std::shared_ptr compute_proving_key(const CircuitBuilder& circuit_builder); - std::shared_ptr compute_verification_key(const CircuitBuilder& circuit_builder); - - void compute_circuit_size_parameters(CircuitBuilder& circuit_builder); - - void compute_witness(CircuitBuilder& circuit_builder); - - GoblinTranslatorProver create_prover( - CircuitBuilder& circuit_builder, - const std::shared_ptr& transcript = std::make_shared()); - GoblinTranslatorVerifier create_verifier( - const CircuitBuilder& circuit_builder, - const std::shared_ptr& transcript = std::make_shared()); - - std::shared_ptr compute_commitment_key(size_t circuit_size) - { - if (commitment_key) { - return commitment_key; - } - - commitment_key = std::make_shared(circuit_size); - return commitment_key; - }; -}; -} // namespace bb diff --git a/barretenberg/cpp/src/barretenberg/translator_vm/goblin_translator_composer.test.cpp b/barretenberg/cpp/src/barretenberg/translator_vm/goblin_translator_composer.test.cpp index 7e2d37aba96..346a3b9891f 100644 --- a/barretenberg/cpp/src/barretenberg/translator_vm/goblin_translator_composer.test.cpp +++ b/barretenberg/cpp/src/barretenberg/translator_vm/goblin_translator_composer.test.cpp @@ -1,10 +1,10 @@ -#include "barretenberg/translator_vm/goblin_translator_composer.hpp" #include "barretenberg/common/log.hpp" #include "barretenberg/numeric/uint256/uint256.hpp" #include "barretenberg/proof_system/circuit_builder/goblin_translator_circuit_builder.hpp" #include "barretenberg/relations/relation_parameters.hpp" #include "barretenberg/sumcheck/sumcheck_round.hpp" #include "barretenberg/translator_vm/goblin_translator_prover.hpp" +#include "barretenberg/translator_vm/goblin_translator_verifier.hpp" #include using namespace bb; @@ -67,16 +67,16 @@ TEST_F(GoblinTranslatorComposerTests, Basic) prover_transcript->export_proof(); Fq translation_batching_challenge = prover_transcript->template get_challenge("Translation:batching_challenge"); Fq translation_evaluation_challenge = Fq::random_element(); + auto circuit_builder = CircuitBuilder(translation_batching_challenge, translation_evaluation_challenge, op_queue); EXPECT_TRUE(circuit_builder.check_circuit()); - auto composer = GoblinTranslatorComposer(); - auto prover = composer.create_prover(circuit_builder, prover_transcript); + GoblinTranslatorProver prover{ circuit_builder, prover_transcript }; auto proof = prover.construct_proof(); auto verifier_transcript = std::make_shared(prover_transcript->proof_data); verifier_transcript->template receive_from_prover("init"); - auto verifier = composer.create_verifier(circuit_builder, verifier_transcript); + GoblinTranslatorVerifier verifier(prover.key, verifier_transcript); bool verified = verifier.verify_proof(proof); EXPECT_TRUE(verified); } diff --git a/barretenberg/cpp/src/barretenberg/translator_vm/goblin_translator_prover.cpp b/barretenberg/cpp/src/barretenberg/translator_vm/goblin_translator_prover.cpp index 6e10cb24ad9..2ddff25fa1e 100644 --- a/barretenberg/cpp/src/barretenberg/translator_vm/goblin_translator_prover.cpp +++ b/barretenberg/cpp/src/barretenberg/translator_vm/goblin_translator_prover.cpp @@ -2,6 +2,7 @@ #include "barretenberg/commitment_schemes/claim.hpp" #include "barretenberg/commitment_schemes/commitment_key.hpp" #include "barretenberg/commitment_schemes/zeromorph/zeromorph.hpp" +#include "barretenberg/honk/proof_system/permutation_library.hpp" #include "barretenberg/proof_system/library/grand_product_library.hpp" #include "barretenberg/sumcheck/sumcheck.hpp" @@ -15,16 +16,6 @@ namespace bb { * * @tparam settings Settings class. * */ - -/** - * Create GoblinTranslatorProver from proving key, witness and manifest. - * - * @param input_key Proving key. - * @param input_manifest Input manifest - * - * @tparam settings Settings class. - * */ - GoblinTranslatorProver::GoblinTranslatorProver(const std::shared_ptr& input_key, const std::shared_ptr& commitment_key, const std::shared_ptr& transcript) @@ -48,6 +39,179 @@ GoblinTranslatorProver::GoblinTranslatorProver(const std::shared_ptrconcatenated_range_constraints_3; } +GoblinTranslatorProver::GoblinTranslatorProver(CircuitBuilder& circuit_builder, + const std::shared_ptr& transcript) + : dyadic_circuit_size(Flavor::compute_dyadic_circuit_size(circuit_builder)) + , mini_circuit_dyadic_size(Flavor::compute_mini_circuit_dyadic_size(circuit_builder)) + +{ + BB_OP_COUNT_TIME(); + + // Compute total number of gates, dyadic circuit size, etc. + key = std::make_shared(circuit_builder); + dyadic_circuit_size = key->circuit_size; + compute_witness(circuit_builder); + compute_commitment_key(key->circuit_size); + + *this = GoblinTranslatorProver(key, commitment_key, transcript); +} + +/** + * @brief Construct the witness polynomials from the witness vectors in the circuit constructor. + * + * @details In goblin translator wires come as is, since they have to reflect the structure of polynomials in the first + * 4 wires, which we've commited to + * + * @tparam Flavor provides the circuit constructor type and the number of wires. + * @param circuit_builder + * @param dyadic_circuit_size Power of 2 circuit size + * @todo TODO(https://github.com/AztecProtocol/barretenberg/issues/783) Optimize memory operations. + * @return std::vector + * */ +std::vector construct_wire_polynomials( + const GoblinTranslatorProver::CircuitBuilder& circuit_builder, const size_t dyadic_circuit_size) +{ + const size_t num_gates = circuit_builder.num_gates; + + std::vector wire_polynomials; + // Populate the wire polynomials with values from conventional wires + for (size_t wire_idx = 0; wire_idx < GoblinTranslatorFlavor::NUM_WIRES; ++wire_idx) { + // Expect all values to be set to 0 initially + GoblinTranslatorProver::Polynomial w_lagrange(dyadic_circuit_size); + + // Insert conventional gate wire values into the wire polynomial + for (size_t i = 0; i < num_gates; ++i) { + auto& wire = circuit_builder.wires[wire_idx]; + w_lagrange[i] = circuit_builder.get_variable(wire[i]); + } + + wire_polynomials.push_back(std::move(w_lagrange)); + } + return wire_polynomials; +} + +/** + * @brief Compute witness polynomials + * + */ +void GoblinTranslatorProver::compute_witness(CircuitBuilder& circuit_builder) +{ + if (computed_witness) { + return; + } + + // Construct the conventional wire polynomials + auto wire_polynomials = construct_wire_polynomials(circuit_builder, dyadic_circuit_size); + + // TODO(https://github.com/AztecProtocol/barretenberg/issues/907) + // In order: + // wire_polynomials + // = WireEntities::get_wires - concatenated + // = WireNonShiftedEntities + WireToBeShiftedEntities - concatenated + key->op = wire_polynomials[0]; + key->x_lo_y_hi = wire_polynomials[1]; + key->x_hi_z_1 = wire_polynomials[2]; + key->y_lo_z_2 = wire_polynomials[3]; + key->p_x_low_limbs = wire_polynomials[4]; + key->p_x_low_limbs_range_constraint_0 = wire_polynomials[5]; + key->p_x_low_limbs_range_constraint_1 = wire_polynomials[6]; + key->p_x_low_limbs_range_constraint_2 = wire_polynomials[7]; + key->p_x_low_limbs_range_constraint_3 = wire_polynomials[8]; + key->p_x_low_limbs_range_constraint_4 = wire_polynomials[9]; + key->p_x_low_limbs_range_constraint_tail = wire_polynomials[10]; + key->p_x_high_limbs = wire_polynomials[11]; + key->p_x_high_limbs_range_constraint_0 = wire_polynomials[12]; + key->p_x_high_limbs_range_constraint_1 = wire_polynomials[13]; + key->p_x_high_limbs_range_constraint_2 = wire_polynomials[14]; + key->p_x_high_limbs_range_constraint_3 = wire_polynomials[15]; + key->p_x_high_limbs_range_constraint_4 = wire_polynomials[16]; + key->p_x_high_limbs_range_constraint_tail = wire_polynomials[17]; + key->p_y_low_limbs = wire_polynomials[18]; + key->p_y_low_limbs_range_constraint_0 = wire_polynomials[19]; + key->p_y_low_limbs_range_constraint_1 = wire_polynomials[20]; + key->p_y_low_limbs_range_constraint_2 = wire_polynomials[21]; + key->p_y_low_limbs_range_constraint_3 = wire_polynomials[22]; + key->p_y_low_limbs_range_constraint_4 = wire_polynomials[23]; + key->p_y_low_limbs_range_constraint_tail = wire_polynomials[24]; + key->p_y_high_limbs = wire_polynomials[25]; + key->p_y_high_limbs_range_constraint_0 = wire_polynomials[26]; + key->p_y_high_limbs_range_constraint_1 = wire_polynomials[27]; + key->p_y_high_limbs_range_constraint_2 = wire_polynomials[28]; + key->p_y_high_limbs_range_constraint_3 = wire_polynomials[29]; + key->p_y_high_limbs_range_constraint_4 = wire_polynomials[30]; + key->p_y_high_limbs_range_constraint_tail = wire_polynomials[31]; + key->z_low_limbs = wire_polynomials[32]; + key->z_low_limbs_range_constraint_0 = wire_polynomials[33]; + key->z_low_limbs_range_constraint_1 = wire_polynomials[34]; + key->z_low_limbs_range_constraint_2 = wire_polynomials[35]; + key->z_low_limbs_range_constraint_3 = wire_polynomials[36]; + key->z_low_limbs_range_constraint_4 = wire_polynomials[37]; + key->z_low_limbs_range_constraint_tail = wire_polynomials[38]; + key->z_high_limbs = wire_polynomials[39]; + key->z_high_limbs_range_constraint_0 = wire_polynomials[40]; + key->z_high_limbs_range_constraint_1 = wire_polynomials[41]; + key->z_high_limbs_range_constraint_2 = wire_polynomials[42]; + key->z_high_limbs_range_constraint_3 = wire_polynomials[43]; + key->z_high_limbs_range_constraint_4 = wire_polynomials[44]; + key->z_high_limbs_range_constraint_tail = wire_polynomials[45]; + key->accumulators_binary_limbs_0 = wire_polynomials[46]; + key->accumulators_binary_limbs_1 = wire_polynomials[47]; + key->accumulators_binary_limbs_2 = wire_polynomials[48]; + key->accumulators_binary_limbs_3 = wire_polynomials[49]; + key->accumulator_low_limbs_range_constraint_0 = wire_polynomials[50]; + key->accumulator_low_limbs_range_constraint_1 = wire_polynomials[51]; + key->accumulator_low_limbs_range_constraint_2 = wire_polynomials[52]; + key->accumulator_low_limbs_range_constraint_3 = wire_polynomials[53]; + key->accumulator_low_limbs_range_constraint_4 = wire_polynomials[54]; + key->accumulator_low_limbs_range_constraint_tail = wire_polynomials[55]; + key->accumulator_high_limbs_range_constraint_0 = wire_polynomials[56]; + key->accumulator_high_limbs_range_constraint_1 = wire_polynomials[57]; + key->accumulator_high_limbs_range_constraint_2 = wire_polynomials[58]; + key->accumulator_high_limbs_range_constraint_3 = wire_polynomials[59]; + key->accumulator_high_limbs_range_constraint_4 = wire_polynomials[60]; + key->accumulator_high_limbs_range_constraint_tail = wire_polynomials[61]; + key->quotient_low_binary_limbs = wire_polynomials[62]; + key->quotient_high_binary_limbs = wire_polynomials[63]; + key->quotient_low_limbs_range_constraint_0 = wire_polynomials[64]; + key->quotient_low_limbs_range_constraint_1 = wire_polynomials[65]; + key->quotient_low_limbs_range_constraint_2 = wire_polynomials[66]; + key->quotient_low_limbs_range_constraint_3 = wire_polynomials[67]; + key->quotient_low_limbs_range_constraint_4 = wire_polynomials[68]; + key->quotient_low_limbs_range_constraint_tail = wire_polynomials[69]; + key->quotient_high_limbs_range_constraint_0 = wire_polynomials[70]; + key->quotient_high_limbs_range_constraint_1 = wire_polynomials[71]; + key->quotient_high_limbs_range_constraint_2 = wire_polynomials[72]; + key->quotient_high_limbs_range_constraint_3 = wire_polynomials[73]; + key->quotient_high_limbs_range_constraint_4 = wire_polynomials[74]; + key->quotient_high_limbs_range_constraint_tail = wire_polynomials[75]; + key->relation_wide_limbs = wire_polynomials[76]; + key->relation_wide_limbs_range_constraint_0 = wire_polynomials[77]; + key->relation_wide_limbs_range_constraint_1 = wire_polynomials[78]; + key->relation_wide_limbs_range_constraint_2 = wire_polynomials[79]; + key->relation_wide_limbs_range_constraint_3 = wire_polynomials[80]; + + // We construct concatenated versions of range constraint polynomials, where several polynomials are concatenated + // into one. These polynomials are not commited to. + bb::compute_concatenated_polynomials(key.get()); + + // We also contruct ordered polynomials, which have the same values as concatenated ones + enough values to bridge + // the range from 0 to maximum range defined by the range constraint. + bb::compute_goblin_translator_range_constraint_ordered_polynomials(key.get(), mini_circuit_dyadic_size); + + computed_witness = true; +} + +std::shared_ptr GoblinTranslatorProver::compute_commitment_key( + size_t circuit_size) +{ + if (commitment_key) { + return commitment_key; + } + + commitment_key = std::make_shared(circuit_size); + return commitment_key; +}; + /** * @brief Add circuit size and values used in the relations to the transcript * diff --git a/barretenberg/cpp/src/barretenberg/translator_vm/goblin_translator_prover.hpp b/barretenberg/cpp/src/barretenberg/translator_vm/goblin_translator_prover.hpp index c8bb0893d13..3daf2218f48 100644 --- a/barretenberg/cpp/src/barretenberg/translator_vm/goblin_translator_prover.hpp +++ b/barretenberg/cpp/src/barretenberg/translator_vm/goblin_translator_prover.hpp @@ -9,8 +9,9 @@ namespace bb { // We won't compile this class with Standard, but we will like want to compile it (at least for testing) // with a flavor that uses the curve Grumpkin, or a flavor that does/does not have zk, etc. class GoblinTranslatorProver { - + public: using Flavor = GoblinTranslatorFlavor; + using CircuitBuilder = typename Flavor::CircuitBuilder; using FF = typename Flavor::FF; using BF = typename Flavor::BF; using Commitment = typename Flavor::Commitment; @@ -21,12 +22,21 @@ class GoblinTranslatorProver { using CommitmentLabels = typename Flavor::CommitmentLabels; using PCS = typename Flavor::PCS; using Transcript = typename Flavor::Transcript; + static constexpr size_t MINIMUM_MINI_CIRCUIT_SIZE = 2048; + bool computed_witness = false; + size_t total_num_gates = 0; // num_gates (already include zero row offset) (used to compute dyadic size) + size_t dyadic_circuit_size = 0; // final power-of-2 circuit size + size_t mini_circuit_dyadic_size = 0; // The size of the small circuit that contains non-range constraint relations - public: explicit GoblinTranslatorProver(const std::shared_ptr& input_key, const std::shared_ptr& commitment_key, const std::shared_ptr& transcript = std::make_shared()); + explicit GoblinTranslatorProver(CircuitBuilder& circuit_builder, const std::shared_ptr& transcript); + + void compute_witness(CircuitBuilder& circuit_builder); + std::shared_ptr compute_commitment_key(size_t circuit_size); + BB_PROFILE void execute_preamble_round(); BB_PROFILE void execute_wire_and_sorted_constraints_commitments_round(); BB_PROFILE void execute_grand_product_computation_round(); diff --git a/barretenberg/cpp/src/barretenberg/translator_vm/goblin_translator_verifier.cpp b/barretenberg/cpp/src/barretenberg/translator_vm/goblin_translator_verifier.cpp index 720ae146648..6cb2a9653d4 100644 --- a/barretenberg/cpp/src/barretenberg/translator_vm/goblin_translator_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/translator_vm/goblin_translator_verifier.cpp @@ -6,25 +6,16 @@ namespace bb { GoblinTranslatorVerifier::GoblinTranslatorVerifier( - const std::shared_ptr& verifier_key, + const std::shared_ptr& verifier_key, const std::shared_ptr& transcript) : key(verifier_key) , transcript(transcript) {} -GoblinTranslatorVerifier::GoblinTranslatorVerifier(GoblinTranslatorVerifier&& other) noexcept - : key(std::move(other.key)) - , pcs_verification_key(std::move(other.pcs_verification_key)) -{} - -GoblinTranslatorVerifier& GoblinTranslatorVerifier::operator=(GoblinTranslatorVerifier&& other) noexcept -{ - key = std::move(other.key); - pcs_verification_key = (std::move(other.pcs_verification_key)); - commitments.clear(); - pcs_fr_elements.clear(); - return *this; -} +GoblinTranslatorVerifier::GoblinTranslatorVerifier( + const std::shared_ptr& proving_key, + const std::shared_ptr& transcript) + : GoblinTranslatorVerifier(std::make_shared(proving_key), transcript){}; void GoblinTranslatorVerifier::put_translation_data_in_relation_parameters(const uint256_t& evaluation_input_x, const BF& batching_challenge_v, @@ -268,7 +259,7 @@ bool GoblinTranslatorVerifier::verify_proof(const HonkProof& proof) commitments.get_concatenation_groups(), claimed_evaluations.get_concatenated_constraints()); - auto verified = pcs_verification_key->pairing_check(pairing_points[0], pairing_points[1]); + auto verified = key->pcs_verification_key->pairing_check(pairing_points[0], pairing_points[1]); return verified; } diff --git a/barretenberg/cpp/src/barretenberg/translator_vm/goblin_translator_verifier.hpp b/barretenberg/cpp/src/barretenberg/translator_vm/goblin_translator_verifier.hpp index 1af71745bfb..a7ded5cc915 100644 --- a/barretenberg/cpp/src/barretenberg/translator_vm/goblin_translator_verifier.hpp +++ b/barretenberg/cpp/src/barretenberg/translator_vm/goblin_translator_verifier.hpp @@ -2,14 +2,17 @@ #include "barretenberg/flavor/goblin_translator.hpp" #include "barretenberg/goblin/translation_evaluations.hpp" #include "barretenberg/honk/proof_system/types/proof.hpp" +#include "barretenberg/translator_vm/goblin_translator_prover.hpp" namespace bb { class GoblinTranslatorVerifier { public: using Flavor = GoblinTranslatorFlavor; + using CircuitBuilder = typename Flavor::CircuitBuilder; using FF = typename Flavor::FF; using BF = typename Flavor::BF; using Commitment = typename Flavor::Commitment; + using ProvingKey = typename Flavor::ProvingKey; using VerificationKey = typename Flavor::VerificationKey; using VerifierCommitmentKey = typename Flavor::VerifierCommitmentKey; using TranslationEvaluations = bb::TranslationEvaluations; @@ -17,20 +20,18 @@ class GoblinTranslatorVerifier { BF evaluation_input_x = 0; BF batching_challenge_v = 0; + std::shared_ptr key; std::map commitments; std::map pcs_fr_elements; - std::shared_ptr pcs_verification_key; std::shared_ptr transcript; RelationParameters relation_parameters; GoblinTranslatorVerifier(const std::shared_ptr& verifier_key = nullptr, const std::shared_ptr& transcript = std::make_shared()); - GoblinTranslatorVerifier(GoblinTranslatorVerifier&& other) noexcept; - GoblinTranslatorVerifier(const GoblinTranslatorVerifier& other) = delete; - GoblinTranslatorVerifier& operator=(const GoblinTranslatorVerifier& other) = delete; - GoblinTranslatorVerifier& operator=(GoblinTranslatorVerifier&& other) noexcept; - ~GoblinTranslatorVerifier() = default; + + GoblinTranslatorVerifier(const std::shared_ptr& proving_key, + const std::shared_ptr& transcript = std::make_shared()); void put_translation_data_in_relation_parameters(const uint256_t& evaluation_input_x, const BF& batching_challenge_v, diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/relation_correctness.test.cpp b/barretenberg/cpp/src/barretenberg/ultra_honk/relation_correctness.test.cpp index 848d5144c0e..2ff86d31da2 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/relation_correctness.test.cpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/relation_correctness.test.cpp @@ -465,7 +465,7 @@ TEST_F(RelationCorrectnessTests, GoblinTranslatorPermutationRelationCorrectness) compute_goblin_translator_range_constraint_ordered_polynomials(&prover_polynomials, mini_circuit_size); // Compute the fixed numerator (part of verification key) - compute_extra_range_constraint_numerator(&prover_polynomials, full_circuit_size); + prover_polynomials.compute_extra_range_constraint_numerator(); // Compute concatenated polynomials (4 polynomials produced from other constraint polynomials by concatenation) compute_concatenated_polynomials(&prover_polynomials);