diff --git a/barretenberg/cpp/src/barretenberg/eccvm/eccvm_circuit_builder.hpp b/barretenberg/cpp/src/barretenberg/eccvm/eccvm_circuit_builder.hpp index 6fcea1cb32a..29966706ee4 100644 --- a/barretenberg/cpp/src/barretenberg/eccvm/eccvm_circuit_builder.hpp +++ b/barretenberg/cpp/src/barretenberg/eccvm/eccvm_circuit_builder.hpp @@ -8,7 +8,6 @@ #include "barretenberg/ecc/curves/bn254/fr.hpp" #include "barretenberg/ecc/curves/grumpkin/grumpkin.hpp" #include "barretenberg/honk/proof_system/logderivative_library.hpp" -#include "barretenberg/honk/proof_system/permutation_library.hpp" #include "barretenberg/polynomials/polynomial.hpp" #include "barretenberg/relations/relation_parameters.hpp" #include "barretenberg/stdlib_circuit_builders/op_queue/ecc_op_queue.hpp" diff --git a/barretenberg/cpp/src/barretenberg/goblin/goblin.hpp b/barretenberg/cpp/src/barretenberg/goblin/goblin.hpp index fae8b19ec45..be0fab4ad75 100644 --- a/barretenberg/cpp/src/barretenberg/goblin/goblin.hpp +++ b/barretenberg/cpp/src/barretenberg/goblin/goblin.hpp @@ -22,27 +22,22 @@ namespace bb { class GoblinProver { - using MegaCircuitBuilder = bb::MegaCircuitBuilder; using Commitment = MegaFlavor::Commitment; using FF = MegaFlavor::FF; public: - using Builder = MegaCircuitBuilder; + using MegaBuilder = MegaCircuitBuilder; using Fr = bb::fr; using Transcript = NativeTranscript; using MegaDeciderProvingKey = DeciderProvingKey_; - using OpQueue = bb::ECCOpQueue; - using ECCVMFlavor = bb::ECCVMFlavor; - using ECCVMBuilder = bb::ECCVMCircuitBuilder; - using ECCVMProver = bb::ECCVMProver; + using OpQueue = ECCOpQueue; + using ECCVMBuilder = ECCVMFlavor::CircuitBuilder; using ECCVMProvingKey = ECCVMFlavor::ProvingKey; using TranslationEvaluations = ECCVMProver::TranslationEvaluations; - using TranslatorBuilder = bb::TranslatorCircuitBuilder; - using TranslatorProver = bb::TranslatorProver; - using TranslatorProvingKey = bb::TranslatorFlavor::ProvingKey; - using RecursiveMergeVerifier = bb::stdlib::recursion::goblin::MergeRecursiveVerifier_; + using TranslatorBuilder = TranslatorCircuitBuilder; + using RecursiveMergeVerifier = stdlib::recursion::goblin::MergeRecursiveVerifier_; using PairingPoints = RecursiveMergeVerifier::PairingPoints; - using MergeProver = bb::MergeProver_; + using MergeProver = MergeProver_; using VerificationKey = MegaFlavor::VerificationKey; using MergeProof = std::vector; /** @@ -60,13 +55,17 @@ class GoblinProver { bool merge_proof_exists{ false }; std::shared_ptr get_eccvm_proving_key() const { return eccvm_key; } - std::shared_ptr get_translator_proving_key() const { return translator_prover->key; } + std::shared_ptr get_translator_proving_key() const + { + return translator_key->proving_key; + } private: // TODO(https://github.com/AztecProtocol/barretenberg/issues/798) unique_ptr use is a hack std::unique_ptr translator_prover; std::unique_ptr eccvm_prover; std::shared_ptr eccvm_key; + std::shared_ptr translator_key; GoblinAccumulationOutput accumulator; // Used only for ACIR methods for now @@ -84,7 +83,7 @@ class GoblinProver { * * @param circuit_builder */ - GoblinAccumulationOutput accumulate(MegaCircuitBuilder& circuit_builder) + GoblinAccumulationOutput accumulate(MegaBuilder& circuit_builder) { // Complete the circuit logic by recursively verifying previous merge proof if it exists if (merge_proof_exists) { @@ -117,7 +116,7 @@ class GoblinProver { * * @param circuit_builder */ - void merge(MegaCircuitBuilder& circuit_builder) + void merge(MegaBuilder& circuit_builder) { // Append a recursive merge verification of the merge proof if (merge_proof_exists) { @@ -134,7 +133,7 @@ class GoblinProver { * @param circuit_builder * @return PairingPoints */ - PairingPoints verify_merge(MegaCircuitBuilder& circuit_builder, MergeProof& proof) const + PairingPoints verify_merge(MegaBuilder& circuit_builder, MergeProof& proof) const { PROFILE_THIS_NAME("Goblin::merge"); RecursiveMergeVerifier merge_verifier{ &circuit_builder }; @@ -146,7 +145,7 @@ class GoblinProver { * * @param circuit_builder */ - MergeProof prove_merge(MegaCircuitBuilder& circuit_builder) + MergeProof prove_merge(MegaBuilder& circuit_builder) { PROFILE_THIS_NAME("Goblin::merge"); // TODO(https://github.com/AztecProtocol/barretenberg/issues/993): Some circuits (particularly on the first call @@ -211,7 +210,8 @@ class GoblinProver { auto translator_builder = std::make_unique(translation_batching_challenge_v, evaluation_challenge_x, op_queue); - translator_prover = std::make_unique(*translator_builder, transcript, commitment_key); + translator_key = std::make_shared(*translator_builder, commitment_key); + translator_prover = std::make_unique(translator_key, transcript); } { diff --git a/barretenberg/cpp/src/barretenberg/stdlib/translator_vm_verifier/translator_recursive_verifier.test.cpp b/barretenberg/cpp/src/barretenberg/stdlib/translator_vm_verifier/translator_recursive_verifier.test.cpp index 1e2ab4beac0..05bd7342ce0 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/translator_vm_verifier/translator_recursive_verifier.test.cpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/translator_vm_verifier/translator_recursive_verifier.test.cpp @@ -25,6 +25,7 @@ template class TranslatorRecursiveTests : public ::te public: using InnerFlavor = typename RecursiveFlavor::NativeFlavor; using InnerBuilder = typename InnerFlavor::CircuitBuilder; + using InnerProvingKey = TranslatorProvingKey; using InnerProver = TranslatorProver; using InnerVerifier = TranslatorVerifier; using InnerG1 = InnerFlavor::Commitment; @@ -68,8 +69,8 @@ template class TranslatorRecursiveTests : public ::te auto circuit_builder = InnerBuilder(translation_batching_challenge, translation_evaluation_challenge, op_queue); EXPECT_TRUE(circuit_builder.check_circuit()); - - InnerProver prover{ circuit_builder, prover_transcript }; + auto proving_key = std::make_shared(circuit_builder); + InnerProver prover{ proving_key, prover_transcript }; auto proof = prover.construct_proof(); OuterBuilder outer_circuit; @@ -79,7 +80,7 @@ template class TranslatorRecursiveTests : public ::te auto transcript = std::make_shared(stdlib_proof); transcript->template receive_from_prover("init"); - auto verification_key = std::make_shared(prover.key); + auto verification_key = std::make_shared(prover.key->proving_key); RecursiveVerifier verifier{ &outer_circuit, verification_key, transcript }; auto pairing_points = verifier.verify_proof(proof); info("Recursive Verifier: num gates = ", outer_circuit.num_gates); @@ -89,7 +90,7 @@ template class TranslatorRecursiveTests : public ::te auto native_verifier_transcript = std::make_shared(prover_transcript->proof_data); native_verifier_transcript->template receive_from_prover("init"); - InnerVerifier native_verifier(prover.key, native_verifier_transcript); + InnerVerifier native_verifier(verification_key, native_verifier_transcript); bool native_result = native_verifier.verify_proof(proof); auto recursive_result = native_verifier.key->pcs_verification_key->pairing_check(pairing_points[0].get_value(), pairing_points[1].get_value()); diff --git a/barretenberg/cpp/src/barretenberg/translator_vm/relation_correctness.test.cpp b/barretenberg/cpp/src/barretenberg/translator_vm/relation_correctness.test.cpp index ca13448d383..292c868f2c0 100644 --- a/barretenberg/cpp/src/barretenberg/translator_vm/relation_correctness.test.cpp +++ b/barretenberg/cpp/src/barretenberg/translator_vm/relation_correctness.test.cpp @@ -1,7 +1,7 @@ #include "barretenberg/common/thread.hpp" -#include "barretenberg/honk/proof_system/permutation_library.hpp" #include "barretenberg/plonk_honk_shared/library/grand_product_library.hpp" #include "barretenberg/translator_vm/translator_flavor.hpp" +#include "barretenberg/translator_vm/translator_proving_key.hpp" #include #include @@ -45,7 +45,6 @@ TEST_F(TranslatorRelationCorrectnessTests, Permutation) using Flavor = TranslatorFlavor; using FF = typename Flavor::FF; using ProverPolynomials = typename Flavor::ProverPolynomials; - using ProvingKey = typename Flavor::ProvingKey; using Polynomial = bb::Polynomial; auto& engine = numeric::get_debug_randomness(); const size_t mini_circuit_size = 2048; @@ -59,8 +58,8 @@ TEST_F(TranslatorRelationCorrectnessTests, Permutation) params.gamma = gamma; // Create storage for polynomials - auto proving_key = std::make_shared(); - + auto proving_key = std::make_shared(full_circuit_size); + TranslatorProvingKey key{ proving_key, mini_circuit_size }; ProverPolynomials& prover_polynomials = proving_key->polynomials; // ensure we can shift these for (Polynomial& prover_poly : prover_polynomials.get_to_be_shifted()) { @@ -149,13 +148,13 @@ TEST_F(TranslatorRelationCorrectnessTests, Permutation) fill_polynomial_with_random_14_bit_values(prover_polynomials.relation_wide_limbs_range_constraint_3); // Compute ordered range constraint polynomials that go in the denominator of the grand product polynomial - compute_translator_range_constraint_ordered_polynomials(prover_polynomials, mini_circuit_size); + key.compute_translator_range_constraint_ordered_polynomials(); // Compute the fixed numerator (part of verification key) - proving_key->compute_extra_range_constraint_numerator(); + key.compute_extra_range_constraint_numerator(); // Compute concatenated polynomials (4 polynomials produced from other constraint polynomials by concatenation) - compute_concatenated_polynomials(prover_polynomials); + key.compute_concatenated_polynomials(); // Compute the grand product polynomial compute_grand_product>(prover_polynomials, params); diff --git a/barretenberg/cpp/src/barretenberg/translator_vm/translator.test.cpp b/barretenberg/cpp/src/barretenberg/translator_vm/translator.test.cpp index 62e3eefff30..b9f2327b747 100644 --- a/barretenberg/cpp/src/barretenberg/translator_vm/translator.test.cpp +++ b/barretenberg/cpp/src/barretenberg/translator_vm/translator.test.cpp @@ -70,13 +70,14 @@ TEST_F(TranslatorTests, Basic) auto circuit_builder = CircuitBuilder(translation_batching_challenge, translation_evaluation_challenge, op_queue); EXPECT_TRUE(circuit_builder.check_circuit()); - - TranslatorProver prover{ circuit_builder, prover_transcript }; + auto proving_key = std::make_shared(circuit_builder); + TranslatorProver prover{ proving_key, prover_transcript }; auto proof = prover.construct_proof(); auto verifier_transcript = std::make_shared(prover_transcript->proof_data); verifier_transcript->template receive_from_prover("init"); - TranslatorVerifier verifier(prover.key, verifier_transcript); + auto verification_key = std::make_shared(proving_key->proving_key); + TranslatorVerifier verifier(verification_key, verifier_transcript); bool verified = verifier.verify_proof(proof); EXPECT_TRUE(verified); } diff --git a/barretenberg/cpp/src/barretenberg/translator_vm/translator_flavor.hpp b/barretenberg/cpp/src/barretenberg/translator_vm/translator_flavor.hpp index 0221f95fedf..b25dbb2dd8f 100644 --- a/barretenberg/cpp/src/barretenberg/translator_vm/translator_flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/translator_vm/translator_flavor.hpp @@ -7,7 +7,6 @@ #include "barretenberg/flavor/flavor_macros.hpp" #include "barretenberg/flavor/relation_definitions.hpp" #include "barretenberg/flavor/repeated_commitments_data.hpp" -#include "barretenberg/honk/proof_system/permutation_library.hpp" #include "barretenberg/polynomials/polynomial.hpp" #include "barretenberg/polynomials/univariate.hpp" #include "barretenberg/relations/relation_parameters.hpp" @@ -544,7 +543,7 @@ class TranslatorFlavor { public: DEFINE_COMPOUND_GET_ALL(PrecomputedEntities, WitnessEntities, ShiftedEntities) - auto get_precomputed() { return PrecomputedEntities::get_all(); }; + auto get_precomputed() const { return PrecomputedEntities::get_all(); }; /** * @brief Get entities concatenated for the permutation relation @@ -615,29 +614,6 @@ class TranslatorFlavor { } }; - 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 A field element for each entity of the flavor. These entities represent the prover polynomials * evaluated at one point. @@ -704,8 +680,6 @@ class TranslatorFlavor { */ class ProvingKey : public ProvingKey_ { public: - BF batching_challenge_v = { 0 }; - BF evaluation_input_x = { 0 }; ProverPolynomials polynomials; // storage for all polynomials evaluated by the prover // Expose constructors on the base class @@ -713,80 +687,10 @@ class TranslatorFlavor { using Base::Base; ProvingKey() = default; - ProvingKey(const CircuitBuilder& builder) - : Base(compute_dyadic_circuit_size(builder), 0) - , batching_challenge_v(builder.batching_challenge_v) - , evaluation_input_x(builder.evaluation_input_x) + ProvingKey(const size_t dyadic_circuit_size, std::shared_ptr commitment_key = nullptr) + : Base(dyadic_circuit_size, 0, std::move(commitment_key)) , polynomials(this->circuit_size) - { - // First and last lagrange polynomials (in the full circuit size) - polynomials.lagrange_first.at(0) = 1; - polynomials.lagrange_last.at(circuit_size - 1) = 1; - - // 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(); - compute_extra_range_constraint_numerator(); - } - - inline void compute_lagrange_polynomials(const CircuitBuilder& builder) - { - const size_t mini_circuit_dyadic_size = compute_mini_circuit_dyadic_size(builder); - - for (size_t i = 1; i < mini_circuit_dyadic_size - 1; i += 2) { - polynomials.lagrange_odd_in_minicircuit.at(i) = 1; - polynomials.lagrange_even_in_minicircuit.at(i + 1) = 1; - } - polynomials.lagrange_second.at(1) = 1; - polynomials.lagrange_second_to_last_in_minicircuit.at(mini_circuit_dyadic_size - 2) = 1; - } - - /** - * @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 (TranslatorPermutationRelation) 2) A - * relation enforcing a certain ordering on the elements of the given polynomial - * (TranslatorDeltaRangeConstraintRelation) - * - * 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 = polynomials.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.at(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); - } + {} }; /** diff --git a/barretenberg/cpp/src/barretenberg/translator_vm/translator_prover.cpp b/barretenberg/cpp/src/barretenberg/translator_vm/translator_prover.cpp index 77c85b444c5..3e0485b7ede 100644 --- a/barretenberg/cpp/src/barretenberg/translator_vm/translator_prover.cpp +++ b/barretenberg/cpp/src/barretenberg/translator_vm/translator_prover.cpp @@ -2,66 +2,20 @@ #include "barretenberg/commitment_schemes/claim.hpp" #include "barretenberg/commitment_schemes/commitment_key.hpp" #include "barretenberg/commitment_schemes/shplonk/shplemini.hpp" -#include "barretenberg/honk/proof_system/permutation_library.hpp" #include "barretenberg/plonk_honk_shared/library/grand_product_library.hpp" #include "barretenberg/sumcheck/sumcheck.hpp" namespace bb { -TranslatorProver::TranslatorProver(CircuitBuilder& circuit_builder, - const std::shared_ptr& transcript, - std::shared_ptr commitment_key) - : dyadic_circuit_size(Flavor::compute_dyadic_circuit_size(circuit_builder)) - , mini_circuit_dyadic_size(Flavor::compute_mini_circuit_dyadic_size(circuit_builder)) - , transcript(transcript) - , key(std::make_shared(circuit_builder)) +TranslatorProver::TranslatorProver(const std::shared_ptr& key, + const std::shared_ptr& transcript) + : transcript(transcript) + , key(key) { PROFILE_THIS(); - - key->commitment_key = commitment_key ? commitment_key : std::make_shared(key->circuit_size); - compute_witness(circuit_builder); -} - -/** - * @brief Compute witness polynomials - * - */ -void TranslatorProver::compute_witness(CircuitBuilder& circuit_builder) -{ - if (computed_witness) { - return; + if (key->proving_key->commitment_key == nullptr) { + key->proving_key->commitment_key = std::make_shared(key->proving_key->circuit_size); } - - // Populate the wire polynomials from the wire vectors in the circuit constructor. Note: 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 - for (auto [wire_poly_, wire_] : zip_view(key->polynomials.get_wires(), circuit_builder.wires)) { - auto& wire_poly = wire_poly_; - auto& wire = wire_; - parallel_for_range(circuit_builder.num_gates, [&](size_t start, size_t end) { - for (size_t i = start; i < end; i++) { - if (i >= wire_poly.start_index() && i < wire_poly.end_index()) { - wire_poly.at(i) = circuit_builder.get_variable(wire[i]); - } else { - ASSERT(wire[i] == 0); - } - } - }); - } - - // 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->polynomials); - - // 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_translator_range_constraint_ordered_polynomials(key->polynomials, mini_circuit_dyadic_size); - - computed_witness = true; -} - -void TranslatorProver::compute_commitment_key(size_t circuit_size) -{ - key->commitment_key = std::make_shared(circuit_size); } /** @@ -70,14 +24,15 @@ void TranslatorProver::compute_commitment_key(size_t circuit_size) */ void TranslatorProver::execute_preamble_round() { - const auto circuit_size = static_cast(key->circuit_size); + const auto circuit_size = static_cast(key->proving_key->circuit_size); const auto SHIFT = uint256_t(1) << Flavor::NUM_LIMB_BITS; const auto SHIFTx2 = uint256_t(1) << (Flavor::NUM_LIMB_BITS * 2); const auto SHIFTx3 = uint256_t(1) << (Flavor::NUM_LIMB_BITS * 3); - const auto accumulated_result = BF(uint256_t(key->polynomials.accumulators_binary_limbs_0[1]) + - uint256_t(key->polynomials.accumulators_binary_limbs_1[1]) * SHIFT + - uint256_t(key->polynomials.accumulators_binary_limbs_2[1]) * SHIFTx2 + - uint256_t(key->polynomials.accumulators_binary_limbs_3[1]) * SHIFTx3); + const auto accumulated_result = + BF(uint256_t(key->proving_key->polynomials.accumulators_binary_limbs_0[1]) + + uint256_t(key->proving_key->polynomials.accumulators_binary_limbs_1[1]) * SHIFT + + uint256_t(key->proving_key->polynomials.accumulators_binary_limbs_2[1]) * SHIFTx2 + + uint256_t(key->proving_key->polynomials.accumulators_binary_limbs_3[1]) * SHIFTx3); transcript->send_to_verifier("circuit_size", circuit_size); transcript->send_to_verifier("evaluation_input_x", key->evaluation_input_x); transcript->send_to_verifier("accumulated_result", accumulated_result); @@ -90,10 +45,10 @@ void TranslatorProver::execute_preamble_round() void TranslatorProver::execute_wire_and_sorted_constraints_commitments_round() { // Commit to all wire polynomials and ordered range constraint polynomials - auto wire_polys = key->polynomials.get_wires_and_ordered_range_constraints(); + auto wire_polys = key->proving_key->polynomials.get_wires_and_ordered_range_constraints(); auto labels = commitment_labels.get_wires_and_ordered_range_constraints(); for (size_t idx = 0; idx < wire_polys.size(); ++idx) { - transcript->send_to_verifier(labels[idx], key->commitment_key->commit(wire_polys[idx])); + transcript->send_to_verifier(labels[idx], key->proving_key->commitment_key->commit(wire_polys[idx])); } } @@ -117,10 +72,10 @@ void TranslatorProver::execute_grand_product_computation_round() uint_evaluation_input.slice(NUM_LIMB_BITS * 3, NUM_LIMB_BITS * 4), uint_evaluation_input }; - relation_parameters.accumulated_result = { key->polynomials.accumulators_binary_limbs_0[1], - key->polynomials.accumulators_binary_limbs_1[1], - key->polynomials.accumulators_binary_limbs_2[1], - key->polynomials.accumulators_binary_limbs_3[1] }; + relation_parameters.accumulated_result = { key->proving_key->polynomials.accumulators_binary_limbs_0[1], + key->proving_key->polynomials.accumulators_binary_limbs_1[1], + key->proving_key->polynomials.accumulators_binary_limbs_2[1], + key->proving_key->polynomials.accumulators_binary_limbs_3[1] }; std::vector uint_batching_challenge_powers; auto batching_challenge_v = key->batching_challenge_v; @@ -142,9 +97,10 @@ void TranslatorProver::execute_grand_product_computation_round() }; } // Compute constraint permutation grand product - compute_grand_products(key->polynomials, relation_parameters); + compute_grand_products(key->proving_key->polynomials, relation_parameters); - transcript->send_to_verifier(commitment_labels.z_perm, key->commitment_key->commit(key->polynomials.z_perm)); + transcript->send_to_verifier(commitment_labels.z_perm, + key->proving_key->commitment_key->commit(key->proving_key->polynomials.z_perm)); } /** @@ -155,7 +111,7 @@ void TranslatorProver::execute_relation_check_rounds() { using Sumcheck = SumcheckProver; - auto sumcheck = Sumcheck(key->circuit_size, transcript); + auto sumcheck = Sumcheck(key->proving_key->circuit_size, transcript); FF alpha = transcript->template get_challenge("Sumcheck:alpha"); std::vector gate_challenges(CONST_PROOF_SIZE_LOG_N); for (size_t idx = 0; idx < gate_challenges.size(); idx++) { @@ -163,9 +119,11 @@ void TranslatorProver::execute_relation_check_rounds() } // // create masking polynomials for sumcheck round univariates and auxiliary data - zk_sumcheck_data = ZKSumcheckData(key->log_circuit_size, transcript, key->commitment_key); + zk_sumcheck_data = + ZKSumcheckData(key->proving_key->log_circuit_size, transcript, key->proving_key->commitment_key); - sumcheck_output = sumcheck.prove(key->polynomials, relation_parameters, alpha, gate_challenges, zk_sumcheck_data); + sumcheck_output = + sumcheck.prove(key->proving_key->polynomials, relation_parameters, alpha, gate_challenges, zk_sumcheck_data); } /** @@ -181,18 +139,18 @@ void TranslatorProver::execute_pcs_rounds() using OpeningClaim = ProverOpeningClaim; const OpeningClaim prover_opening_claim = - ShpleminiProver_::prove(key->circuit_size, - key->polynomials.get_unshifted_without_concatenated(), - key->polynomials.get_to_be_shifted(), + ShpleminiProver_::prove(key->proving_key->circuit_size, + key->proving_key->polynomials.get_unshifted_without_concatenated(), + key->proving_key->polynomials.get_to_be_shifted(), sumcheck_output.challenge, - key->commitment_key, + key->proving_key->commitment_key, transcript, zk_sumcheck_data.libra_univariates_monomial, sumcheck_output.claimed_libra_evaluations, - key->polynomials.get_concatenated(), - key->polynomials.get_groups_to_be_concatenated()); + key->proving_key->polynomials.get_concatenated(), + key->proving_key->polynomials.get_groups_to_be_concatenated()); - PCS::compute_opening_proof(key->commitment_key, prover_opening_claim, transcript); + PCS::compute_opening_proof(key->proving_key->commitment_key, prover_opening_claim, transcript); } HonkProof TranslatorProver::export_proof() diff --git a/barretenberg/cpp/src/barretenberg/translator_vm/translator_prover.hpp b/barretenberg/cpp/src/barretenberg/translator_vm/translator_prover.hpp index 989596fd02b..357c7aa6a90 100644 --- a/barretenberg/cpp/src/barretenberg/translator_vm/translator_prover.hpp +++ b/barretenberg/cpp/src/barretenberg/translator_vm/translator_prover.hpp @@ -4,6 +4,7 @@ #include "barretenberg/sumcheck/sumcheck_output.hpp" #include "barretenberg/sumcheck/zk_sumcheck_data.hpp" #include "barretenberg/translator_vm/translator_flavor.hpp" +#include "barretenberg/translator_vm/translator_proving_key.hpp" namespace bb { @@ -23,17 +24,12 @@ class TranslatorProver { 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 - explicit TranslatorProver(CircuitBuilder& circuit_builder, - const std::shared_ptr& transcript, - std::shared_ptr commitment_key = nullptr); - - void compute_witness(CircuitBuilder& circuit_builder); - void compute_commitment_key(size_t circuit_size); + explicit TranslatorProver(const std::shared_ptr& key, + const std::shared_ptr& transcript); BB_PROFILE void execute_preamble_round(); BB_PROFILE void execute_wire_and_sorted_constraints_commitments_round(); @@ -47,7 +43,7 @@ class TranslatorProver { bb::RelationParameters relation_parameters; - std::shared_ptr key; + std::shared_ptr key; CommitmentLabels commitment_labels; diff --git a/barretenberg/cpp/src/barretenberg/honk/proof_system/permutation_library.hpp b/barretenberg/cpp/src/barretenberg/translator_vm/translator_proving_key.cpp similarity index 66% rename from barretenberg/cpp/src/barretenberg/honk/proof_system/permutation_library.hpp rename to barretenberg/cpp/src/barretenberg/translator_vm/translator_proving_key.cpp index bbe394315ad..68e48aff80b 100644 --- a/barretenberg/cpp/src/barretenberg/honk/proof_system/permutation_library.hpp +++ b/barretenberg/cpp/src/barretenberg/translator_vm/translator_proving_key.cpp @@ -1,10 +1,4 @@ -#pragma once -#include "barretenberg/common/ref_vector.hpp" -#include "barretenberg/common/zip_view.hpp" -#include "barretenberg/relations/relation_parameters.hpp" -#include -#include - +#include "translator_proving_key.hpp" namespace bb { /** @@ -23,16 +17,16 @@ namespace bb { * @tparam Flavor * @param proving_key Can be a proving_key or an AllEntities object */ -template void compute_concatenated_polynomials(typename Flavor::ProverPolynomials& polynomials) +void TranslatorProvingKey::compute_concatenated_polynomials() { // Concatenation groups are vectors of polynomials that are concatenated together - auto concatenation_groups = polynomials.get_groups_to_be_concatenated(); + auto concatenation_groups = proving_key->polynomials.get_groups_to_be_concatenated(); // Resulting concatenated polynomials - auto targets = polynomials.get_concatenated(); + auto targets = proving_key->polynomials.get_concatenated(); - // Targets have to be full-sized polynomials. We can compute the mini circuit size from them by dividing by - // concatenation index + // Targets have to be full-sized proving_key->polynomials. We can compute the mini circuit size from them by + // dividing by concatenation index const size_t MINI_CIRCUIT_SIZE = targets[0].size() / Flavor::CONCATENATION_GROUP_SIZE; ASSERT(MINI_CIRCUIT_SIZE * Flavor::CONCATENATION_GROUP_SIZE == targets[0].size()); // A function that produces 1 concatenated polynomial @@ -40,7 +34,7 @@ template void compute_concatenated_polynomials(typename Flavor // Translator uses concatenated polynomials in the permutation argument. These polynomials contain the same // coefficients as other shorter polynomials, but we don't have to commit to them due to reusing commitments of // shorter polynomials and updating our PCS to open using them. But the prover still needs the concatenated - // polynomials. This function constructs a chunk of the polynomial. + // proving_key->polynomials. This function constructs a chunk of the polynomial. auto ordering_function = [&](size_t index) { // Get the index of the concatenated polynomial size_t i = index / concatenation_groups[0].size(); @@ -80,14 +74,11 @@ template void compute_concatenated_polynomials(typename Flavor * @tparam Flavor * @param proving_key */ -template -void compute_translator_range_constraint_ordered_polynomials(typename Flavor::ProverPolynomials& polynomials, - size_t mini_circuit_dyadic_size) +void TranslatorProvingKey::compute_translator_range_constraint_ordered_polynomials() { // Get constants constexpr auto sort_step = Flavor::SORT_STEP; constexpr auto num_concatenated_wires = Flavor::NUM_CONCATENATED_WIRES; - const auto mini_circuit_size = mini_circuit_dyadic_size; const auto full_circuit_size = mini_circuit_dyadic_size * Flavor::CONCATENATION_GROUP_SIZE; // The value we have to end polynomials with @@ -109,14 +100,14 @@ void compute_translator_range_constraint_ordered_polynomials(typename Flavor::Pr } std::vector> ordered_vectors_uint(num_concatenated_wires); - RefArray ordered_constraint_polynomials{ polynomials.ordered_range_constraints_0, - polynomials.ordered_range_constraints_1, - polynomials.ordered_range_constraints_2, - polynomials.ordered_range_constraints_3 }; + RefArray ordered_constraint_polynomials{ proving_key->polynomials.ordered_range_constraints_0, + proving_key->polynomials.ordered_range_constraints_1, + proving_key->polynomials.ordered_range_constraints_2, + proving_key->polynomials.ordered_range_constraints_3 }; std::vector extra_denominator_uint(full_circuit_size); // Get information which polynomials need to be concatenated - auto concatenation_groups = polynomials.get_groups_to_be_concatenated(); + auto concatenation_groups = proving_key->polynomials.get_groups_to_be_concatenated(); // A function that transfers elements from each of the polynomials in the chosen concatenation group in the uint // ordered polynomials @@ -136,9 +127,9 @@ void compute_translator_range_constraint_ordered_polynomials(typename Flavor::Pr for (size_t j = 0; j < Flavor::CONCATENATION_GROUP_SIZE; j++) { // Calculate the offset in the target vector - auto current_offset = j * mini_circuit_size; + auto current_offset = j * mini_circuit_dyadic_size; // For each element in the polynomial - for (size_t k = 0; k < mini_circuit_size; k++) { + for (size_t k = 0; k < mini_circuit_dyadic_size; k++) { // Put it it the target polynomial if ((current_offset + k) < free_space_before_runway) { @@ -159,8 +150,8 @@ void compute_translator_range_constraint_ordered_polynomials(typename Flavor::Pr // Sort the polynomial in nondescending order. We sort using vector with size_t elements for 2 reasons: // 1. It is faster to sort size_t - // 2. Comparison operators for finite fields are operating on internal form, so we'd have to convert them from - // Montgomery + // 2. Comparison operators for finite fields are operating on internal form, so we'd have to convert them + // from Montgomery std::sort(current_vector.begin(), current_vector.end()); // Copy the values into the actual polynomial ordered_constraint_polynomials[i].copy_vector(current_vector); @@ -184,7 +175,61 @@ void compute_translator_range_constraint_ordered_polynomials(typename Flavor::Pr #endif // Copy the values into the actual polynomial - polynomials.ordered_range_constraints_4.copy_vector(extra_denominator_uint); + proving_key->polynomials.ordered_range_constraints_4.copy_vector(extra_denominator_uint); +} + +void TranslatorProvingKey::compute_lagrange_polynomials() +{ + + for (size_t i = 1; i < mini_circuit_dyadic_size - 1; i += 2) { + proving_key->polynomials.lagrange_odd_in_minicircuit.at(i) = 1; + proving_key->polynomials.lagrange_even_in_minicircuit.at(i + 1) = 1; + } + proving_key->polynomials.lagrange_second.at(1) = 1; + proving_key->polynomials.lagrange_second_to_last_in_minicircuit.at(mini_circuit_dyadic_size - 2) = 1; } -} // namespace bb +/** + * @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 (TranslatorPermutationRelation) 2) A + * relation enforcing a certain ordering on the elements of the given polynomial + * (TranslatorDeltaRangeConstraintRelation) + * + * 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 + * + */ +void TranslatorProvingKey::compute_extra_range_constraint_numerator() +{ + auto& extra_range_constraint_numerator = proving_key->polynomials.ordered_extra_range_constraints_numerator; + + static constexpr 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 / Flavor::SORT_STEP) + 1 + (MAX_VALUE % Flavor::SORT_STEP == 0 ? 0 : 1); + + // Check that we can fit every element in the polynomial + ASSERT((Flavor::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) * Flavor::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.at(shift + i * (Flavor::NUM_CONCATENATED_WIRES + 1)) = sorted_elements[i]; + } + }; + // Fill polynomials with a sequence, where each element is repeated NUM_CONCATENATED_WIRES+1 times + parallel_for(Flavor::NUM_CONCATENATED_WIRES + 1, fill_with_shift); +} +} // namespace bb \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/translator_vm/translator_proving_key.hpp b/barretenberg/cpp/src/barretenberg/translator_vm/translator_proving_key.hpp new file mode 100644 index 00000000000..f0ba84f368e --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/translator_vm/translator_proving_key.hpp @@ -0,0 +1,108 @@ +#pragma once +#include + +#include "barretenberg/translator_vm/translator_flavor.hpp" +namespace bb { +class TranslatorProvingKey { + public: + using Flavor = TranslatorFlavor; + using Circuit = typename Flavor::CircuitBuilder; + using FF = typename Flavor::FF; + using BF = typename Flavor::BF; + using ProvingKey = typename Flavor::ProvingKey; + using Polynomial = typename Flavor::Polynomial; + using CommitmentKey = typename Flavor::CommitmentKey; + + size_t mini_circuit_dyadic_size; + size_t dyadic_circuit_size; + std::shared_ptr proving_key; + + BF batching_challenge_v = { 0 }; + BF evaluation_input_x = { 0 }; + + TranslatorProvingKey() = default; + + TranslatorProvingKey(std::shared_ptr& proving_key, size_t mini_circuit_dyadic_size) + : mini_circuit_dyadic_size(mini_circuit_dyadic_size) + , dyadic_circuit_size(proving_key->circuit_size) + , proving_key(proving_key) + + { + ASSERT(mini_circuit_dyadic_size * Flavor::CONCATENATION_GROUP_SIZE == dyadic_circuit_size); + } + + TranslatorProvingKey(const Circuit& circuit, std::shared_ptr commitment_key = nullptr) + : batching_challenge_v(circuit.batching_challenge_v) + , evaluation_input_x(circuit.evaluation_input_x) + { + PROFILE_THIS_NAME("TranslatorProvingKey(TranslatorCircuit&)"); + + compute_mini_circuit_dyadic_size(circuit); + compute_dyadic_circuit_size(); + proving_key = std::make_shared(dyadic_circuit_size, std::move(commitment_key)); + + // Populate the wire polynomials from the wire vectors in the circuit constructor. Note: 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 + for (auto [wire_poly_, wire_] : zip_view(proving_key->polynomials.get_wires(), circuit.wires)) { + auto& wire_poly = wire_poly_; + auto& wire = wire_; + parallel_for_range(circuit.num_gates, [&](size_t start, size_t end) { + for (size_t i = start; i < end; i++) { + if (i >= wire_poly.start_index() && i < wire_poly.end_index()) { + wire_poly.at(i) = circuit.get_variable(wire[i]); + } else { + ASSERT(wire[i] == 0); + } + } + }); + } + + // First and last lagrange polynomials (in the full circuit size) + proving_key->polynomials.lagrange_first.at(0) = 1; + proving_key->polynomials.lagrange_last.at(dyadic_circuit_size - 1) = 1; + + // 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(); + + // Compute the numerator for the permutation argument with several repetitions of steps bridging 0 and + // maximum range constraint compute_extra_range_constraint_numerator(); + compute_extra_range_constraint_numerator(); + + // We construct concatenated versions of range constraint polynomials, where several polynomials are + // concatenated + // into one. These polynomials are not commited to. + compute_concatenated_polynomials(); + + // 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. + compute_translator_range_constraint_ordered_polynomials(); + }; + + inline void compute_dyadic_circuit_size() + { + + // The actual circuit size is several times bigger than the trace in the circuit, 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; + } + + inline void compute_mini_circuit_dyadic_size(const Circuit& circuit) + { + const size_t total_num_gates = std::max(circuit.num_gates, Flavor::MINIMUM_MINI_CIRCUIT_SIZE); + // Next power of 2 + mini_circuit_dyadic_size = circuit.get_circuit_subgroup_size(total_num_gates); + } + + void compute_lagrange_polynomials(); + + void compute_extra_range_constraint_numerator(); + + void compute_concatenated_polynomials(); + + void compute_translator_range_constraint_ordered_polynomials(); +}; +} // namespace bb \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/translator_vm/translator_verifier.cpp b/barretenberg/cpp/src/barretenberg/translator_vm/translator_verifier.cpp index 628d3b0aab1..8acaa89f736 100644 --- a/barretenberg/cpp/src/barretenberg/translator_vm/translator_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/translator_vm/translator_verifier.cpp @@ -5,16 +5,12 @@ namespace bb { -TranslatorVerifier::TranslatorVerifier(const std::shared_ptr& verifier_key, +TranslatorVerifier::TranslatorVerifier(const std::shared_ptr& verifier_key, const std::shared_ptr& transcript) : key(verifier_key) , transcript(transcript) {} -TranslatorVerifier::TranslatorVerifier(const std::shared_ptr& proving_key, - const std::shared_ptr& transcript) - : TranslatorVerifier(std::make_shared(proving_key), transcript){}; - void TranslatorVerifier::put_translation_data_in_relation_parameters(const uint256_t& evaluation_input_x, const BF& batching_challenge_v, const uint256_t& accumulated_result) diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/decider_proving_key.hpp b/barretenberg/cpp/src/barretenberg/ultra_honk/decider_proving_key.hpp index c6b5bf1b1c0..5da7c791708 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/decider_proving_key.hpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/decider_proving_key.hpp @@ -24,7 +24,6 @@ namespace bb { template class DeciderProvingKey_ { using Circuit = typename Flavor::CircuitBuilder; using ProvingKey = typename Flavor::ProvingKey; - using VerificationKey = typename Flavor::VerificationKey; using CommitmentKey = typename Flavor::CommitmentKey; using FF = typename Flavor::FF; using ProverPolynomials = typename Flavor::ProverPolynomials; 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 334a7d6e5f0..9169f22a183 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/relation_correctness.test.cpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/relation_correctness.test.cpp @@ -1,4 +1,3 @@ -#include "barretenberg/honk/proof_system/permutation_library.hpp" #include "barretenberg/plonk_honk_shared/library/grand_product_library.hpp" #include "barretenberg/relations/auxiliary_relation.hpp" #include "barretenberg/relations/delta_range_constraint_relation.hpp" diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/generated/prover.cpp b/barretenberg/cpp/src/barretenberg/vm/avm/generated/prover.cpp index 647e0ccdc8b..80b993d3f4e 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/generated/prover.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/generated/prover.cpp @@ -6,7 +6,6 @@ #include "barretenberg/common/constexpr_utils.hpp" #include "barretenberg/common/thread.hpp" #include "barretenberg/honk/proof_system/logderivative_library.hpp" -#include "barretenberg/honk/proof_system/permutation_library.hpp" #include "barretenberg/plonk_honk_shared/library/grand_product_library.hpp" #include "barretenberg/relations/permutation_relation.hpp" #include "barretenberg/sumcheck/sumcheck.hpp" diff --git a/bb-pilcom/bb-pil-backend/templates/prover.cpp.hbs b/bb-pilcom/bb-pil-backend/templates/prover.cpp.hbs index 0a94299e240..79d8ee68530 100644 --- a/bb-pilcom/bb-pil-backend/templates/prover.cpp.hbs +++ b/bb-pilcom/bb-pil-backend/templates/prover.cpp.hbs @@ -6,7 +6,6 @@ #include "barretenberg/common/constexpr_utils.hpp" #include "barretenberg/common/thread.hpp" #include "barretenberg/honk/proof_system/logderivative_library.hpp" -#include "barretenberg/honk/proof_system/permutation_library.hpp" #include "barretenberg/plonk_honk_shared/library/grand_product_library.hpp" #include "barretenberg/relations/permutation_relation.hpp" #include "barretenberg/sumcheck/sumcheck.hpp"