diff --git a/barretenberg/cpp/src/barretenberg/client_ivc/mock_kernel_pinning.test.cpp b/barretenberg/cpp/src/barretenberg/client_ivc/mock_kernel_pinning.test.cpp index eebaa2e8185..5d48c880294 100644 --- a/barretenberg/cpp/src/barretenberg/client_ivc/mock_kernel_pinning.test.cpp +++ b/barretenberg/cpp/src/barretenberg/client_ivc/mock_kernel_pinning.test.cpp @@ -37,7 +37,7 @@ TEST_F(MockKernelTest, PinFoldingKernelSizes) kernel_circuit, { func_fold_proof, ivc.vks.func_vk }, {}, kernel_acc); auto kernel_fold_proof = ivc.accumulate(kernel_circuit); - EXPECT_EQ(ivc.prover_instance->log_instance_size, 17); + EXPECT_EQ(ivc.prover_instance->proving_key->log_circuit_size, 17); GoblinUltraCircuitBuilder circuit_3{ ivc.goblin.op_queue }; GoblinMockCircuits::construct_mock_function_circuit(circuit_3); diff --git a/barretenberg/cpp/src/barretenberg/flavor/flavor.hpp b/barretenberg/cpp/src/barretenberg/flavor/flavor.hpp index 00f890bc875..fd80d637de5 100644 --- a/barretenberg/cpp/src/barretenberg/flavor/flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/flavor/flavor.hpp @@ -110,6 +110,15 @@ class ProvingKey_ : public PrecomputedPolynomials, public WitnessPolynomials { bb::EvaluationDomain evaluation_domain; std::shared_ptr commitment_key; + // offset due to placing zero wires at the start of execution trace + // non-zero for Instances constructed from circuits, this concept doesn't exist for accumulated + // instances + size_t pub_inputs_offset = 0; + + // The number of public inputs has to be the same for all instances because they are + // folded element by element. + std::vector public_inputs; + std::vector get_labels() const { return concatenate(PrecomputedPolynomials::get_labels(), WitnessPolynomials::get_labels()); @@ -147,6 +156,7 @@ template class VerificationKey_ : public PrecomputedCommitments { public: std::shared_ptr pcs_verification_key; + size_t pub_inputs_offset = 0; VerificationKey_() = default; VerificationKey_(const size_t circuit_size, const size_t num_public_inputs) @@ -158,10 +168,11 @@ class VerificationKey_ : public PrecomputedCommitments { template VerificationKey_(const ProvingKeyPtr& proving_key) { + this->pcs_verification_key = std::make_shared(); this->circuit_size = proving_key->circuit_size; this->log_circuit_size = numeric::get_msb(this->circuit_size); this->num_public_inputs = proving_key->num_public_inputs; - this->pcs_verification_key = std::make_shared(); + this->pub_inputs_offset = proving_key->pub_inputs_offset; for (auto [polynomial, commitment] : zip_view(proving_key->get_precomputed_polynomials(), this->get_all())) { commitment = proving_key->commitment_key->commit(polynomial); diff --git a/barretenberg/cpp/src/barretenberg/flavor/goblin_ultra.hpp b/barretenberg/cpp/src/barretenberg/flavor/goblin_ultra.hpp index 3a68c154cb5..32842ebe9b5 100644 --- a/barretenberg/cpp/src/barretenberg/flavor/goblin_ultra.hpp +++ b/barretenberg/cpp/src/barretenberg/flavor/goblin_ultra.hpp @@ -287,7 +287,20 @@ class GoblinUltraFlavor { * circuits. * @todo TODO(https://github.com/AztecProtocol/barretenberg/issues/876) */ - 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 container for storing the partially evaluated multivariates produced by sumcheck. diff --git a/barretenberg/cpp/src/barretenberg/flavor/goblin_ultra_recursive.hpp b/barretenberg/cpp/src/barretenberg/flavor/goblin_ultra_recursive.hpp index ec5062277a5..c638064c97c 100644 --- a/barretenberg/cpp/src/barretenberg/flavor/goblin_ultra_recursive.hpp +++ b/barretenberg/cpp/src/barretenberg/flavor/goblin_ultra_recursive.hpp @@ -99,6 +99,8 @@ template class GoblinUltraRecursiveFlavor_ { class VerificationKey : public VerificationKey_, VerifierCommitmentKey> { public: + std::vector public_inputs; + VerificationKey(const size_t circuit_size, const size_t num_public_inputs) { this->circuit_size = circuit_size; @@ -118,6 +120,11 @@ template class GoblinUltraRecursiveFlavor_ { this->circuit_size = native_key->circuit_size; this->log_circuit_size = numeric::get_msb(this->circuit_size); this->num_public_inputs = native_key->num_public_inputs; + this->pub_inputs_offset = native_key->pub_inputs_offset; + this->public_inputs = std::vector(native_key->num_public_inputs); + for (auto [public_input, native_public_input] : zip_view(this->public_inputs, native_key->public_inputs)) { + public_input = FF::from_witness(builder, native_public_input); + } this->q_m = Commitment::from_witness(builder, native_key->q_m); this->q_l = Commitment::from_witness(builder, native_key->q_l); this->q_r = Commitment::from_witness(builder, native_key->q_r); diff --git a/barretenberg/cpp/src/barretenberg/flavor/ultra.hpp b/barretenberg/cpp/src/barretenberg/flavor/ultra.hpp index a2323eba35f..32a3a627bea 100644 --- a/barretenberg/cpp/src/barretenberg/flavor/ultra.hpp +++ b/barretenberg/cpp/src/barretenberg/flavor/ultra.hpp @@ -290,7 +290,20 @@ class UltraFlavor { * 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 diff --git a/barretenberg/cpp/src/barretenberg/flavor/ultra_recursive.hpp b/barretenberg/cpp/src/barretenberg/flavor/ultra_recursive.hpp index 0ac2f297ce6..632661bb6c4 100644 --- a/barretenberg/cpp/src/barretenberg/flavor/ultra_recursive.hpp +++ b/barretenberg/cpp/src/barretenberg/flavor/ultra_recursive.hpp @@ -271,6 +271,8 @@ template class UltraRecursiveFlavor_ { */ class VerificationKey : public VerificationKey_, VerifierCommitmentKey> { public: + std::vector public_inputs; + VerificationKey(const size_t circuit_size, const size_t num_public_inputs) { this->circuit_size = circuit_size; @@ -285,10 +287,15 @@ template class UltraRecursiveFlavor_ { */ VerificationKey(CircuitBuilder* builder, const std::shared_ptr& native_key) { + this->pcs_verification_key = native_key->pcs_verification_key; this->circuit_size = native_key->circuit_size; this->log_circuit_size = numeric::get_msb(this->circuit_size); this->num_public_inputs = native_key->num_public_inputs; - this->pcs_verification_key = native_key->pcs_verification_key; + this->pub_inputs_offset = native_key->pub_inputs_offset; + this->public_inputs = std::vector(native_key->num_public_inputs); + for (auto [public_input, native_public_input] : zip_view(this->public_inputs, native_key->public_inputs)) { + public_input = FF::from_witness(builder, native_public_input); + } this->q_m = Commitment::from_witness(builder, native_key->q_m); this->q_l = Commitment::from_witness(builder, native_key->q_l); this->q_r = Commitment::from_witness(builder, native_key->q_r); @@ -318,8 +325,8 @@ template class UltraRecursiveFlavor_ { }; /** - * @brief A field element for each entity of the flavor. These entities represent the prover polynomials evaluated - * at one point. + * @brief A field element for each entity of the flavor. These entities represent the prover polynomials + * evaluated at one point. */ class AllValues : public AllEntities { public: @@ -330,8 +337,8 @@ template class UltraRecursiveFlavor_ { /** * @brief A container for commitment labels. - * @note It's debatable whether this should inherit from AllEntities. since most entries are not strictly needed. It - * has, however, been useful during debugging to have these labels available. + * @note It's debatable whether this should inherit from AllEntities. since most entries are not strictly + * needed. It has, however, been useful during debugging to have these labels available. * */ class CommitmentLabels : public AllEntities { diff --git a/barretenberg/cpp/src/barretenberg/protogalaxy/combiner.test.cpp b/barretenberg/cpp/src/barretenberg/protogalaxy/combiner.test.cpp index d78b066a94a..390ccd71779 100644 --- a/barretenberg/cpp/src/barretenberg/protogalaxy/combiner.test.cpp +++ b/barretenberg/cpp/src/barretenberg/protogalaxy/combiner.test.cpp @@ -45,7 +45,8 @@ TEST(Protogalaxy, CombinerOn2Instances) /*log_circuit_size=*/1, idx * 128); restrict_to_standard_arithmetic_relation(prover_polynomials); instance->prover_polynomials = std::move(prover_polynomials); - instance->instance_size = 2; + instance->proving_key = std::make_shared(); + instance->proving_key->circuit_size = 2; instance_data[idx] = instance; } @@ -77,7 +78,8 @@ TEST(Protogalaxy, CombinerOn2Instances) /*log_circuit_size=*/1); restrict_to_standard_arithmetic_relation(prover_polynomials); instance->prover_polynomials = std::move(prover_polynomials); - instance->instance_size = 2; + instance->proving_key = std::make_shared(); + instance->proving_key->circuit_size = 2; instance_data[idx] = instance; } @@ -167,7 +169,8 @@ TEST(Protogalaxy, CombinerOn4Instances) auto prover_polynomials = get_zero_prover_polynomials( /*log_circuit_size=*/1); instance->prover_polynomials = std::move(prover_polynomials); - instance->instance_size = 2; + instance->proving_key = std::make_shared(); + instance->proving_key->circuit_size = 2; instance_data[idx] = instance; } diff --git a/barretenberg/cpp/src/barretenberg/protogalaxy/decider_prover.cpp b/barretenberg/cpp/src/barretenberg/protogalaxy/decider_prover.cpp index 4f1fa1eb481..0b13eefeb37 100644 --- a/barretenberg/cpp/src/barretenberg/protogalaxy/decider_prover.cpp +++ b/barretenberg/cpp/src/barretenberg/protogalaxy/decider_prover.cpp @@ -28,7 +28,7 @@ DeciderProver_::DeciderProver_(const std::shared_ptr& inst, template void DeciderProver_::execute_relation_check_rounds() { using Sumcheck = SumcheckProver; - auto instance_size = accumulator->instance_size; + auto instance_size = accumulator->proving_key->circuit_size; auto sumcheck = Sumcheck(instance_size, transcript); sumcheck_output = sumcheck.prove(accumulator); } diff --git a/barretenberg/cpp/src/barretenberg/protogalaxy/decider_verifier.cpp b/barretenberg/cpp/src/barretenberg/protogalaxy/decider_verifier.cpp index ebb0b6c7034..637dc322980 100644 --- a/barretenberg/cpp/src/barretenberg/protogalaxy/decider_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/protogalaxy/decider_verifier.cpp @@ -35,7 +35,8 @@ template bool DeciderVerifier_::verify_proof(const Hon VerifierCommitments commitments{ accumulator->verification_key, accumulator->witness_commitments }; - auto sumcheck = SumcheckVerifier(accumulator->log_instance_size, transcript, accumulator->target_sum); + auto sumcheck = + SumcheckVerifier(accumulator->verification_key->log_circuit_size, transcript, accumulator->target_sum); auto [multivariate_challenge, claimed_evaluations, sumcheck_verified] = sumcheck.verify(accumulator->relation_parameters, accumulator->alphas, accumulator->gate_challenges); diff --git a/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover.cpp b/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover.cpp index 382dfcddf3f..65df1840efa 100644 --- a/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover.cpp +++ b/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover.cpp @@ -7,17 +7,17 @@ void ProtoGalaxyProver_::finalise_and_send_instance(std::shared { instance->initialize_prover_polynomials(); - const auto instance_size = static_cast(instance->instance_size); - const auto num_public_inputs = static_cast(instance->public_inputs.size()); + const auto instance_size = static_cast(instance->proving_key->circuit_size); + const auto num_public_inputs = static_cast(instance->proving_key->num_public_inputs); transcript->send_to_verifier(domain_separator + "_instance_size", instance_size); transcript->send_to_verifier(domain_separator + "_public_input_size", num_public_inputs); - for (size_t i = 0; i < instance->public_inputs.size(); ++i) { - auto public_input_i = instance->public_inputs[i]; + for (size_t i = 0; i < instance->proving_key->public_inputs.size(); ++i) { + auto public_input_i = instance->proving_key->public_inputs[i]; transcript->send_to_verifier(domain_separator + "_public_input_" + std::to_string(i), public_input_i); } transcript->send_to_verifier(domain_separator + "_pub_inputs_offset", - static_cast(instance->pub_inputs_offset)); + static_cast(instance->proving_key->pub_inputs_offset)); auto& witness_commitments = instance->witness_commitments; @@ -102,7 +102,7 @@ template void ProtoGalaxyProver_::prepa if (!instance->is_accumulator) { finalise_and_send_instance(instance, domain_separator); instance->target_sum = 0; - instance->gate_challenges = std::vector(instance->log_instance_size, 0); + instance->gate_challenges = std::vector(instance->proving_key->log_circuit_size, 0); } idx++; @@ -132,8 +132,6 @@ std::shared_ptr ProtoGalaxyProver_(); next_accumulator->is_accumulator = true; - next_accumulator->instance_size = instances[0]->instance_size; - next_accumulator->log_instance_size = instances[0]->log_instance_size; next_accumulator->proving_key = instances[0]->proving_key; // Compute the next target sum and send the next folding parameters to the verifier @@ -146,7 +144,7 @@ std::shared_ptr ProtoGalaxyProver_instance_size); + polynomial = typename Flavor::Polynomial(instances[0]->proving_key->circuit_size); } // Fold the prover polynomials @@ -164,14 +162,14 @@ std::shared_ptr ProtoGalaxyProver_public_inputs = std::vector(instances[0]->public_inputs.size(), 0); + next_accumulator->proving_key->public_inputs = std::vector(instances[0]->proving_key->public_inputs.size(), 0); size_t el_idx = 0; - for (auto& el : next_accumulator->public_inputs) { + for (auto& el : next_accumulator->proving_key->public_inputs) { size_t inst = 0; for (auto& instance : instances) { // TODO(https://github.com/AztecProtocol/barretenberg/issues/830) - if (instance->public_inputs.size() >= next_accumulator->public_inputs.size()) { - el += instance->public_inputs[el_idx] * lagranges[inst]; + if (instance->proving_key->num_public_inputs >= next_accumulator->proving_key->num_public_inputs) { + el += instance->proving_key->public_inputs[el_idx] * lagranges[inst]; inst++; }; } @@ -208,14 +206,14 @@ template void ProtoGalaxyProver_::pertu { state.accumulator = get_accumulator(); FF delta = transcript->template get_challenge("delta"); - state.deltas = compute_round_challenge_pows(state.accumulator->log_instance_size, delta); - state.perturbator = Polynomial(state.accumulator->log_instance_size + 1); // initialize to all zeros + state.deltas = compute_round_challenge_pows(state.accumulator->proving_key->log_circuit_size, delta); + state.perturbator = Polynomial(state.accumulator->proving_key->log_circuit_size + 1); // initialize to all zeros // compute perturbator only if this is not the first round and has an accumulator if (state.accumulator->is_accumulator) { state.perturbator = compute_perturbator(state.accumulator, state.deltas); // Prover doesn't send the constant coefficient of F because this is supposed to be equal to the target sum of // the accumulator which the folding verifier has from the previous iteration. - for (size_t idx = 1; idx <= state.accumulator->log_instance_size; idx++) { + for (size_t idx = 1; idx <= state.accumulator->proving_key->log_circuit_size; idx++) { transcript->send_to_verifier("perturbator_" + std::to_string(idx), state.perturbator[idx]); } } diff --git a/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover.hpp b/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover.hpp index f1b41ae42b2..73407b99a7c 100644 --- a/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover.hpp +++ b/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover.hpp @@ -294,7 +294,7 @@ template class ProtoGalaxyProver_ { ExtendedUnivariateWithRandomization compute_combiner(const ProverInstances& instances, PowPolynomial& pow_betas) { BB_OP_COUNT_TIME(); - size_t common_instance_size = instances[0]->instance_size; + size_t common_instance_size = instances[0]->proving_key->circuit_size; pow_betas.compute_values(); // Determine number of threads for multithreading. // Note: Multithreading is "on" for every round but we reduce the number of threads from the max available based diff --git a/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_verifier.cpp b/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_verifier.cpp index ab406ffcb7e..667460b5b20 100644 --- a/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_verifier.cpp @@ -7,18 +7,20 @@ void ProtoGalaxyVerifier_::receive_and_finalise_instance(cons const std::string& domain_separator) { // Get circuit parameters and the public inputs - inst->instance_size = transcript->template receive_from_prover(domain_separator + "_instance_size"); - inst->log_instance_size = static_cast(numeric::get_msb(inst->instance_size)); - inst->public_input_size = + inst->verification_key->circuit_size = + transcript->template receive_from_prover(domain_separator + "_instance_size"); + inst->verification_key->log_circuit_size = + static_cast(numeric::get_msb(inst->verification_key->circuit_size)); + inst->verification_key->num_public_inputs = transcript->template receive_from_prover(domain_separator + "_public_input_size"); - - for (size_t i = 0; i < inst->public_input_size; ++i) { + inst->verification_key->public_inputs.clear(); + for (size_t i = 0; i < inst->verification_key->num_public_inputs; ++i) { auto public_input_i = transcript->template receive_from_prover(domain_separator + "_public_input_" + std::to_string(i)); - inst->public_inputs.emplace_back(public_input_i); + inst->verification_key->public_inputs.emplace_back(public_input_i); } - inst->pub_inputs_offset = + inst->verification_key->pub_inputs_offset = transcript->template receive_from_prover(domain_separator + "_pub_inputs_offset"); // Get commitments to first three wire polynomials @@ -66,9 +68,13 @@ void ProtoGalaxyVerifier_::receive_and_finalise_instance(cons transcript->template receive_from_prover(domain_separator + "_" + labels.z_lookup); // Compute correction terms for grand products - const FF public_input_delta = compute_public_input_delta( - inst->public_inputs, beta, gamma, inst->instance_size, inst->pub_inputs_offset); - const FF lookup_grand_product_delta = compute_lookup_grand_product_delta(beta, gamma, inst->instance_size); + const FF public_input_delta = compute_public_input_delta(inst->verification_key->public_inputs, + beta, + gamma, + inst->verification_key->circuit_size, + inst->verification_key->pub_inputs_offset); + const FF lookup_grand_product_delta = + compute_lookup_grand_product_delta(beta, gamma, inst->verification_key->circuit_size); inst->relation_parameters = RelationParameters{ eta, beta, gamma, public_input_delta, lookup_grand_product_delta }; @@ -90,7 +96,7 @@ void ProtoGalaxyVerifier_::prepare_for_folding(const std::vec if (!inst->is_accumulator) { receive_and_finalise_instance(inst, domain_separator); inst->target_sum = 0; - inst->gate_challenges = std::vector(inst->log_instance_size, 0); + inst->gate_challenges = std::vector(inst->verification_key->log_circuit_size, 0); } index++; @@ -109,11 +115,11 @@ std::shared_ptr ProtoGalaxyVerifier_template get_challenge("delta"); auto accumulator = get_accumulator(); - auto deltas = compute_round_challenge_pows(accumulator->log_instance_size, delta); + auto deltas = compute_round_challenge_pows(accumulator->verification_key->log_circuit_size, delta); - std::vector perturbator_coeffs(accumulator->log_instance_size + 1, 0); + std::vector perturbator_coeffs(accumulator->verification_key->log_circuit_size + 1, 0); if (accumulator->is_accumulator) { - for (size_t idx = 1; idx <= accumulator->log_instance_size; idx++) { + for (size_t idx = 1; idx <= accumulator->verification_key->log_circuit_size; idx++) { perturbator_coeffs[idx] = transcript->template receive_from_prover("perturbator_" + std::to_string(idx)); } @@ -140,8 +146,36 @@ std::shared_ptr ProtoGalaxyVerifier_(accumulator->verification_key); - next_accumulator->instance_size = accumulator->instance_size; - next_accumulator->log_instance_size = accumulator->log_instance_size; + next_accumulator->verification_key = std::make_shared( + accumulator->verification_key->circuit_size, accumulator->verification_key->num_public_inputs); + next_accumulator->verification_key->pcs_verification_key = accumulator->verification_key->pcs_verification_key; + next_accumulator->verification_key->pub_inputs_offset = accumulator->verification_key->pub_inputs_offset; + size_t vk_idx = 0; + for (auto& expected_vk : next_accumulator->verification_key->get_all()) { + size_t inst = 0; + expected_vk = Commitment::infinity(); + for (auto& instance : instances) { + expected_vk = expected_vk + instance->verification_key->get_all()[vk_idx] * lagranges[inst]; + inst++; + } + vk_idx++; + } + next_accumulator->verification_key->num_public_inputs = accumulator->verification_key->num_public_inputs; + next_accumulator->verification_key->public_inputs = + std::vector(next_accumulator->verification_key->num_public_inputs, 0); + size_t public_input_idx = 0; + for (auto& public_input : next_accumulator->verification_key->public_inputs) { + size_t inst = 0; + for (auto& instance : instances) { + // TODO(https://github.com/AztecProtocol/barretenberg/issues/830) + if (instance->verification_key->num_public_inputs >= + next_accumulator->verification_key->num_public_inputs) { + public_input += instance->verification_key->public_inputs[public_input_idx] * lagranges[inst]; + inst++; + } + } + public_input_idx++; + } next_accumulator->is_accumulator = true; // Compute next folding parameters @@ -163,21 +197,6 @@ std::shared_ptr ProtoGalaxyVerifier_public_input_size = instances[0]->public_input_size; - next_accumulator->public_inputs = std::vector(next_accumulator->public_input_size, 0); - size_t public_input_idx = 0; - for (auto& public_input : next_accumulator->public_inputs) { - size_t inst = 0; - for (auto& instance : instances) { - // TODO(https://github.com/AztecProtocol/barretenberg/issues/830) - if (instance->public_inputs.size() >= next_accumulator->public_input_size) { - public_input += instance->public_inputs[public_input_idx] * lagranges[inst]; - inst++; - } - } - public_input_idx++; - } - size_t alpha_idx = 0; for (auto& alpha : next_accumulator->alphas) { alpha = FF(0); @@ -200,20 +219,6 @@ std::shared_ptr ProtoGalaxyVerifier_relation_parameters.lookup_grand_product_delta * lagranges[inst_idx]; } - next_accumulator->verification_key = - std::make_shared(instances[0]->instance_size, instances[0]->public_input_size); - next_accumulator->verification_key->pcs_verification_key = accumulator->verification_key->pcs_verification_key; - size_t vk_idx = 0; - for (auto& expected_vk : next_accumulator->verification_key->get_all()) { - size_t inst = 0; - expected_vk = Commitment::infinity(); - for (auto& instance : instances) { - expected_vk = expected_vk + instance->verification_key->get_all()[vk_idx] * lagranges[inst]; - inst++; - } - vk_idx++; - } - return next_accumulator; } diff --git a/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/decider_recursive_verifier.cpp b/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/decider_recursive_verifier.cpp index dffe20412d7..a726c6a2377 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/decider_recursive_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/decider_recursive_verifier.cpp @@ -24,7 +24,7 @@ std::array DeciderRecursiveVerifier_:: VerifierCommitments commitments{ accumulator->verification_key, accumulator->witness_commitments }; - auto sumcheck = Sumcheck(accumulator->log_instance_size, transcript, accumulator->target_sum); + auto sumcheck = Sumcheck(accumulator->verification_key->log_circuit_size, transcript, accumulator->target_sum); auto [multivariate_challenge, claimed_evaluations, sumcheck_verified] = sumcheck.verify(accumulator->relation_parameters, accumulator->alphas, accumulator->gate_challenges); diff --git a/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/protogalaxy_recursive_verifier.cpp b/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/protogalaxy_recursive_verifier.cpp index 38ed52ba00a..b460fe76b5b 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/protogalaxy_recursive_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/protogalaxy_recursive_verifier.cpp @@ -12,20 +12,21 @@ void ProtoGalaxyRecursiveVerifier_::receive_and_finalise_inst const auto instance_size = transcript->template receive_from_prover(domain_separator + "_instance_size"); const auto public_input_size = transcript->template receive_from_prover(domain_separator + "_public_input_size"); - inst->instance_size = uint32_t(instance_size.get_value()); - inst->log_instance_size = static_cast(numeric::get_msb(inst->instance_size)); - inst->public_input_size = uint32_t(public_input_size.get_value()); - - for (size_t i = 0; i < inst->public_input_size; ++i) { + inst->verification_key->circuit_size = uint32_t(instance_size.get_value()); + inst->verification_key->log_circuit_size = + static_cast(numeric::get_msb(inst->verification_key->circuit_size)); + inst->verification_key->num_public_inputs = uint32_t(public_input_size.get_value()); + inst->verification_key->public_inputs.clear(); + for (size_t i = 0; i < inst->verification_key->num_public_inputs; ++i) { auto public_input_i = transcript->template receive_from_prover(domain_separator + "_public_input_" + std::to_string(i)); - inst->public_inputs.emplace_back(public_input_i); + inst->verification_key->public_inputs.emplace_back(public_input_i); } const auto pub_inputs_offset = transcript->template receive_from_prover(domain_separator + "_pub_inputs_offset"); - inst->pub_inputs_offset = uint32_t(pub_inputs_offset.get_value()); + inst->verification_key->pub_inputs_offset = uint32_t(pub_inputs_offset.get_value()); // Get commitments to first three wire polynomials auto labels = inst->commitment_labels; @@ -71,9 +72,13 @@ void ProtoGalaxyRecursiveVerifier_::receive_and_finalise_inst transcript->template receive_from_prover(domain_separator + "_" + labels.z_lookup); // Compute correction terms for grand products - const FF public_input_delta = compute_public_input_delta( - inst->public_inputs, beta, gamma, inst->instance_size, inst->pub_inputs_offset); - const FF lookup_grand_product_delta = compute_lookup_grand_product_delta(beta, gamma, inst->instance_size); + const FF public_input_delta = compute_public_input_delta(inst->verification_key->public_inputs, + beta, + gamma, + inst->verification_key->circuit_size, + inst->verification_key->pub_inputs_offset); + const FF lookup_grand_product_delta = + compute_lookup_grand_product_delta(beta, gamma, inst->verification_key->circuit_size); inst->relation_parameters = RelationParameters{ eta, beta, gamma, public_input_delta, lookup_grand_product_delta }; @@ -94,7 +99,7 @@ template void ProtoGalaxyRecursiveVerifier_is_accumulator) { receive_and_finalise_instance(inst, domain_separator); inst->target_sum = 0; - inst->gate_challenges = std::vector(inst->log_instance_size, 0); + inst->gate_challenges = std::vector(inst->verification_key->log_circuit_size, 0); } index++; @@ -117,11 +122,11 @@ std::shared_ptr ProtoGalaxyRecursiveVerifi auto delta = transcript->template get_challenge("delta"); auto accumulator = get_accumulator(); - auto deltas = compute_round_challenge_pows(accumulator->log_instance_size, delta); + auto deltas = compute_round_challenge_pows(accumulator->verification_key->log_circuit_size, delta); - std::vector perturbator_coeffs(accumulator->log_instance_size + 1, 0); + std::vector perturbator_coeffs(accumulator->verification_key->log_circuit_size + 1, 0); if (accumulator->is_accumulator) { - for (size_t idx = 1; idx <= accumulator->log_instance_size; idx++) { + for (size_t idx = 1; idx <= accumulator->verification_key->log_circuit_size; idx++) { perturbator_coeffs[idx] = transcript->template receive_from_prover("perturbator_" + std::to_string(idx)); } @@ -147,8 +152,24 @@ std::shared_ptr ProtoGalaxyRecursiveVerifi auto lagranges = std::vector{ FF(1) - combiner_challenge, combiner_challenge }; auto next_accumulator = std::make_shared(builder); - next_accumulator->instance_size = accumulator->instance_size; - next_accumulator->log_instance_size = accumulator->log_instance_size; + next_accumulator->verification_key = std::make_shared( + accumulator->verification_key->circuit_size, accumulator->verification_key->num_public_inputs); + next_accumulator->verification_key->pcs_verification_key = accumulator->verification_key->pcs_verification_key; + next_accumulator->verification_key->pub_inputs_offset = accumulator->verification_key->pub_inputs_offset; + next_accumulator->verification_key->public_inputs = accumulator->verification_key->public_inputs; + size_t vk_idx = 0; + for (auto& expected_vk : next_accumulator->verification_key->get_all()) { + size_t inst = 0; + std::vector scalars; + std::vector commitments; + for (auto& instance : instances) { + scalars.emplace_back(lagranges[inst]); + commitments.emplace_back(instance->verification_key->get_all()[vk_idx]); + inst++; + } + expected_vk = Commitment::batch_mul(commitments, scalars); + vk_idx++; + } next_accumulator->is_accumulator = true; // Compute next folding parameters and verify against the ones received from the prover @@ -173,14 +194,16 @@ std::shared_ptr ProtoGalaxyRecursiveVerifi comm_idx++; } - next_accumulator->public_input_size = instances[0]->public_input_size; - next_accumulator->public_inputs = std::vector(next_accumulator->public_input_size, 0); + next_accumulator->verification_key->num_public_inputs = accumulator->verification_key->num_public_inputs; + next_accumulator->verification_key->public_inputs = + std::vector(next_accumulator->verification_key->num_public_inputs, 0); size_t public_input_idx = 0; - for (auto& public_input : next_accumulator->public_inputs) { + for (auto& public_input : next_accumulator->verification_key->public_inputs) { size_t inst = 0; for (auto& instance : instances) { - if (instance->public_inputs.size() >= next_accumulator->public_inputs.size()) { - public_input += instance->public_inputs[public_input_idx] * lagranges[inst]; + if (instance->verification_key->num_public_inputs >= + next_accumulator->verification_key->num_public_inputs) { + public_input += instance->verification_key->public_inputs[public_input_idx] * lagranges[inst]; inst++; }; } @@ -209,23 +232,6 @@ std::shared_ptr ProtoGalaxyRecursiveVerifi expected_parameters.lookup_grand_product_delta += instance->relation_parameters.lookup_grand_product_delta * lagranges[inst_idx]; } - - next_accumulator->verification_key = - std::make_shared(instances[0]->instance_size, instances[0]->public_input_size); - next_accumulator->verification_key->pcs_verification_key = accumulator->verification_key->pcs_verification_key; - size_t vk_idx = 0; - for (auto& expected_vk : next_accumulator->verification_key->get_all()) { - size_t inst = 0; - std::vector scalars; - std::vector commitments; - for (auto& instance : instances) { - scalars.emplace_back(lagranges[inst]); - commitments.emplace_back(instance->verification_key->get_all()[vk_idx]); - inst++; - } - expected_vk = Commitment::batch_mul(commitments, scalars); - vk_idx++; - } return next_accumulator; } diff --git a/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/recursive_verifier_instance.hpp b/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/recursive_verifier_instance.hpp index cbc2e71ae5e..236719a8c4b 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/recursive_verifier_instance.hpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/recursive_verifier_instance.hpp @@ -26,11 +26,6 @@ template class RecursiveVerifierInstance_ { Builder* builder; std::shared_ptr verification_key; - std::vector public_inputs; - size_t pub_inputs_offset = 0; - size_t public_input_size; - size_t instance_size; - size_t log_instance_size; RelationParameters relation_parameters; RelationSeparator alphas; bool is_accumulator = false; @@ -50,21 +45,19 @@ template class RecursiveVerifierInstance_ { {} RecursiveVerifierInstance_(Builder* builder, const std::shared_ptr& instance) - : pub_inputs_offset((instance->pub_inputs_offset)) - , public_input_size((instance->public_input_size)) - , instance_size((instance->instance_size)) - , log_instance_size((instance->log_instance_size)) + : verification_key(std::make_shared(instance->verification_key->circuit_size, + instance->verification_key->num_public_inputs)) , is_accumulator(bool(instance->is_accumulator)) { - size_t public_input_idx = 0; - public_inputs = std::vector(public_input_size); - for (auto& public_input : instance->public_inputs) { - public_inputs[public_input_idx] = FF::from_witness(builder, public_input); - public_input_idx++; - } - verification_key = std::make_shared(instance_size, public_input_size); + verification_key->pub_inputs_offset = instance->verification_key->pub_inputs_offset; verification_key->pcs_verification_key = instance->verification_key->pcs_verification_key; + verification_key->public_inputs = std::vector(instance->verification_key->num_public_inputs); + for (auto [public_input, native_public_input] : + zip_view(verification_key->public_inputs, instance->verification_key->public_inputs)) { + public_input = FF::from_witness(builder, native_public_input); + } + auto other_vks = instance->verification_key->get_all(); size_t vk_idx = 0; for (auto& vk : verification_key->get_all()) { @@ -107,21 +100,19 @@ template class RecursiveVerifierInstance_ { */ VerifierInstance get_value() { - auto inst_verification_key = std::make_shared(instance_size, public_input_size); + auto inst_verification_key = std::make_shared(verification_key->circuit_size, + verification_key->num_public_inputs); inst_verification_key->pcs_verification_key = verification_key->pcs_verification_key; for (auto [vk, inst_vk] : zip_view(verification_key->get_all(), inst_verification_key->get_all())) { inst_vk = vk.get_value(); } VerifierInstance inst(inst_verification_key); - inst.pub_inputs_offset = pub_inputs_offset; - inst.public_input_size = public_input_size; - inst.log_instance_size = log_instance_size; - inst.instance_size = instance_size; inst.is_accumulator = is_accumulator; - inst.public_inputs = std::vector(public_input_size); - for (auto [public_input, inst_public_input] : zip_view(public_inputs, inst.public_inputs)) { + inst.verification_key->public_inputs = std::vector(verification_key->num_public_inputs); + for (auto [public_input, inst_public_input] : + zip_view(verification_key->public_inputs, inst.verification_key->public_inputs)) { inst_public_input = public_input.get_value(); } diff --git a/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/ultra_recursive_verifier.cpp b/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/ultra_recursive_verifier.cpp index 47d4be24aca..ce8a96fa2aa 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/ultra_recursive_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/ultra_recursive_verifier.cpp @@ -43,6 +43,7 @@ std::array UltraRecursiveVerifier_::ve // For debugging purposes only ASSERT(static_cast(circuit_size.get_value()) == key->circuit_size); ASSERT(static_cast(public_input_size.get_value()) == key->num_public_inputs); + ASSERT(static_cast(pub_inputs_offset.get_value()) == key->pub_inputs_offset); std::vector public_inputs; for (size_t i = 0; i < key->num_public_inputs; ++i) { diff --git a/barretenberg/cpp/src/barretenberg/sumcheck/instance/prover_instance.cpp b/barretenberg/cpp/src/barretenberg/sumcheck/instance/prover_instance.cpp index db6030ed29b..731619b9e50 100644 --- a/barretenberg/cpp/src/barretenberg/sumcheck/instance/prover_instance.cpp +++ b/barretenberg/cpp/src/barretenberg/sumcheck/instance/prover_instance.cpp @@ -85,22 +85,6 @@ template void ProverInstance_::initialize_prover_polynomi (flavor_get_label(*proving_key, key_poly) + "_shift")); prover_poly = key_poly.shifted(); } - - std::span public_wires_source = prover_polynomials.w_r; - - // Determine public input offsets in the circuit relative to the 0th index for Ultra flavors - pub_inputs_offset = Flavor::has_zero_row ? 1 : 0; - if constexpr (IsGoblinFlavor) { - pub_inputs_offset += proving_key->num_ecc_op_gates; - } - // Construct the public inputs array - for (size_t i = 0; i < proving_key->num_public_inputs; ++i) { - size_t idx = i + pub_inputs_offset; - public_inputs.emplace_back(public_wires_source[idx]); - } - - instance_size = proving_key->circuit_size; - log_instance_size = static_cast(numeric::get_msb(instance_size)); } template void ProverInstance_::compute_sorted_accumulator_polynomials(FF eta) @@ -207,8 +191,8 @@ void ProverInstance_::compute_logderivative_inverse(FF beta, FF gamma) template void ProverInstance_::compute_grand_product_polynomials(FF beta, FF gamma) { - auto public_input_delta = - compute_public_input_delta(public_inputs, beta, gamma, proving_key->circuit_size, pub_inputs_offset); + auto public_input_delta = compute_public_input_delta( + proving_key->public_inputs, beta, gamma, proving_key->circuit_size, proving_key->pub_inputs_offset); relation_parameters.beta = beta; relation_parameters.gamma = gamma; relation_parameters.public_input_delta = public_input_delta; diff --git a/barretenberg/cpp/src/barretenberg/sumcheck/instance/prover_instance.hpp b/barretenberg/cpp/src/barretenberg/sumcheck/instance/prover_instance.hpp index 544e1d5f9f0..4c4d62cb177 100644 --- a/barretenberg/cpp/src/barretenberg/sumcheck/instance/prover_instance.hpp +++ b/barretenberg/cpp/src/barretenberg/sumcheck/instance/prover_instance.hpp @@ -39,16 +39,8 @@ template class ProverInstance_ { std::array sorted_polynomials; - // The number of public inputs has to be the same for all instances because they are - // folded element by element. - std::vector public_inputs; - // offset due to placing zero wires at the start of execution trace - // non-zero for Instances constructed from circuits, this concept doesn't exist for accumulated - // instances - size_t pub_inputs_offset = 0; RelationSeparator alphas; bb::RelationParameters relation_parameters; - std::vector recursive_proof_public_input_indices; bool is_accumulator = false; @@ -56,9 +48,6 @@ template class ProverInstance_ { std::vector gate_challenges; FF target_sum; - size_t instance_size; - size_t log_instance_size; - ProverInstance_(Circuit& circuit) { BB_OP_COUNT_TIME_NAME("ProverInstance(Circuit&)"); @@ -81,11 +70,20 @@ template class ProverInstance_ { construct_table_polynomials(circuit, dyadic_circuit_size); - proving_key->recursive_proof_public_input_indices = std::vector( - recursive_proof_public_input_indices.begin(), recursive_proof_public_input_indices.end()); - proving_key->contains_recursive_proof = contains_recursive_proof; - sorted_polynomials = construct_sorted_list_polynomials(circuit, dyadic_circuit_size); + + std::span public_wires_source = proving_key->w_r; + + // Determine public input offsets in the circuit relative to the 0th index for Ultra flavors + proving_key->pub_inputs_offset = Flavor::has_zero_row ? 1 : 0; + if constexpr (IsGoblinFlavor) { + proving_key->pub_inputs_offset += proving_key->num_ecc_op_gates; + } + // Construct the public inputs array + for (size_t i = 0; i < proving_key->num_public_inputs; ++i) { + size_t idx = i + proving_key->pub_inputs_offset; + proving_key->public_inputs.emplace_back(public_wires_source[idx]); + } } ProverInstance_() = default; @@ -108,7 +106,6 @@ template class ProverInstance_ { private: static constexpr size_t num_zero_rows = Flavor::has_zero_row ? 1 : 0; static constexpr size_t NUM_WIRES = Circuit::NUM_WIRES; - bool contains_recursive_proof = false; size_t dyadic_circuit_size = 0; // final power-of-2 circuit size size_t compute_dyadic_size(Circuit&); @@ -118,10 +115,6 @@ template class ProverInstance_ { void construct_table_polynomials(Circuit&, size_t); - void add_memory_records_to_proving_key(Circuit&); - - void add_table_column_selector_poly_to_proving_key(bb::polynomial& small, const std::string& tag); - void add_plookup_memory_records_to_wire_4(FF); }; diff --git a/barretenberg/cpp/src/barretenberg/sumcheck/instance/verifier_instance.hpp b/barretenberg/cpp/src/barretenberg/sumcheck/instance/verifier_instance.hpp index 9c6faf879aa..e739a2fa08c 100644 --- a/barretenberg/cpp/src/barretenberg/sumcheck/instance/verifier_instance.hpp +++ b/barretenberg/cpp/src/barretenberg/sumcheck/instance/verifier_instance.hpp @@ -20,11 +20,6 @@ template class VerifierInstance_ { using RelationSeparator = typename Flavor::RelationSeparator; std::shared_ptr verification_key; - std::vector public_inputs; - size_t pub_inputs_offset = 0; - size_t public_input_size; - size_t instance_size; - size_t log_instance_size; RelationParameters relation_parameters; RelationSeparator alphas; bool is_accumulator = false; diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/protogalaxy.test.cpp b/barretenberg/cpp/src/barretenberg/ultra_honk/protogalaxy.test.cpp index 4ae0c8e4a3a..db3c0ff3ff9 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/protogalaxy.test.cpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/protogalaxy.test.cpp @@ -81,7 +81,7 @@ template class ProtoGalaxyTests : public testing::Test { static void check_accumulator_target_sum_manual(std::shared_ptr& accumulator, bool expected_result) { - auto instance_size = accumulator->instance_size; + auto instance_size = accumulator->proving_key->circuit_size; auto expected_honk_evals = ProtoGalaxyProver::compute_full_honk_evaluations( accumulator->prover_polynomials, accumulator->alphas, accumulator->relation_parameters); // Construct pow(\vec{betas*}) as in the paper diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_prover.cpp b/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_prover.cpp index 7d4325054ee..f6d800558b5 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_prover.cpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_prover.cpp @@ -47,10 +47,10 @@ template void UltraProver_::execute_preamble_roun transcript->send_to_verifier("circuit_size", circuit_size); transcript->send_to_verifier("public_input_size", num_public_inputs); - transcript->send_to_verifier("pub_inputs_offset", static_cast(instance->pub_inputs_offset)); + transcript->send_to_verifier("pub_inputs_offset", static_cast(proving_key->pub_inputs_offset)); for (size_t i = 0; i < proving_key->num_public_inputs; ++i) { - auto public_input_i = instance->public_inputs[i]; + auto public_input_i = proving_key->public_inputs[i]; transcript->send_to_verifier("public_input_" + std::to_string(i), public_input_i); } } @@ -125,6 +125,8 @@ template void UltraProver_::execute_sorted_list_a */ template void UltraProver_::execute_log_derivative_inverse_round() { + auto& proving_key = instance->proving_key; + // Compute and store challenges beta and gamma auto [beta, gamma] = transcript->template get_challenges("beta", "gamma"); relation_parameters.beta = beta; @@ -132,8 +134,7 @@ template void UltraProver_::execute_log_derivativ if constexpr (IsGoblinFlavor) { instance->compute_logderivative_inverse(beta, gamma); - instance->witness_commitments.lookup_inverses = - commitment_key->commit(instance->prover_polynomials.lookup_inverses); + instance->witness_commitments.lookup_inverses = commitment_key->commit(proving_key->lookup_inverses); transcript->send_to_verifier(commitment_labels.lookup_inverses, instance->witness_commitments.lookup_inverses); } } @@ -144,12 +145,13 @@ template void UltraProver_::execute_log_derivativ */ template void UltraProver_::execute_grand_product_computation_round() { + auto& proving_key = instance->proving_key; instance->compute_grand_product_polynomials(relation_parameters.beta, relation_parameters.gamma); auto& witness_commitments = instance->witness_commitments; - witness_commitments.z_perm = commitment_key->commit(instance->prover_polynomials.z_perm); - witness_commitments.z_lookup = commitment_key->commit(instance->prover_polynomials.z_lookup); + witness_commitments.z_perm = commitment_key->commit(proving_key->z_perm); + witness_commitments.z_lookup = commitment_key->commit(proving_key->z_lookup); transcript->send_to_verifier(commitment_labels.z_perm, instance->witness_commitments.z_perm); transcript->send_to_verifier(commitment_labels.z_lookup, instance->witness_commitments.z_lookup); } diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_verifier.cpp b/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_verifier.cpp index 08ace233814..b0b7a602c18 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_verifier.cpp @@ -66,6 +66,9 @@ template bool UltraVerifier_::verify_proof(const HonkP if (public_input_size != key->num_public_inputs) { return false; } + if (pub_inputs_offset != key->pub_inputs_offset) { + return false; + } std::vector public_inputs; for (size_t i = 0; i < public_input_size; ++i) {