From 9a3d2652d2614439017a6f47152efb9a177b7127 Mon Sep 17 00:00:00 2001 From: maramihali Date: Mon, 25 Sep 2023 14:58:45 +0100 Subject: [PATCH] feat: update to protogalaxy interfaces (#2498) This PR resolves [#725](https://github.com/AztecProtocol/barretenberg/issues/725) and introduces `ProverInstances` and `VerifierInstances` classes responsible of managing the Instances objects and determining the number of instances to be folded. --- .../honk/composer/ultra_composer.cpp | 28 ----------- .../honk/composer/ultra_composer.hpp | 25 ++++++++-- .../barretenberg/honk/instance/instances.hpp | 48 +++++++++++++++++++ .../honk/instance/prover_instance.hpp | 4 -- .../honk/instance/verifier_instance.hpp | 1 - .../honk/proof_system/protogalaxy_prover.cpp | 36 +++++++------- .../honk/proof_system/protogalaxy_prover.hpp | 17 +++---- .../proof_system/protogalaxy_verifier.cpp | 44 +++++++---------- .../proof_system/protogalaxy_verifier.hpp | 19 ++++---- .../honk/transcript/transcript.test.cpp | 3 +- 10 files changed, 127 insertions(+), 98 deletions(-) create mode 100644 barretenberg/cpp/src/barretenberg/honk/instance/instances.hpp diff --git a/barretenberg/cpp/src/barretenberg/honk/composer/ultra_composer.cpp b/barretenberg/cpp/src/barretenberg/honk/composer/ultra_composer.cpp index 93aba6f71bf..f01b4d3588d 100644 --- a/barretenberg/cpp/src/barretenberg/honk/composer/ultra_composer.cpp +++ b/barretenberg/cpp/src/barretenberg/honk/composer/ultra_composer.cpp @@ -35,35 +35,7 @@ UltraVerifier_ UltraComposer_::create_verifier(std::shared_ptr -ProtoGalaxyProver_ UltraComposer_::create_folding_prover( - std::vector> instances) -{ - uint32_t idx = 0; - for (const auto& inst : instances) { - inst->index = idx; - idx++; - } - ProtoGalaxyProver_ output_state(instances); - - return output_state; -} - -template -ProtoGalaxyVerifier_ UltraComposer_::create_folding_verifier( - std::vector> instances) -{ - std::vector> vks; - for (const auto& inst : instances) { - vks.emplace_back(inst->compute_verification_key()); - } - ProtoGalaxyVerifier_ output_state(vks); - - return output_state; -} - template class UltraComposer_; template class UltraComposer_; template class UltraComposer_; - } // namespace proof_system::honk diff --git a/barretenberg/cpp/src/barretenberg/honk/composer/ultra_composer.hpp b/barretenberg/cpp/src/barretenberg/honk/composer/ultra_composer.hpp index 0a33f748ba3..8cf4c27c8aa 100644 --- a/barretenberg/cpp/src/barretenberg/honk/composer/ultra_composer.hpp +++ b/barretenberg/cpp/src/barretenberg/honk/composer/ultra_composer.hpp @@ -24,9 +24,12 @@ template class UltraComposer_ { using VerifierCommitmentKey = typename Flavor::VerifierCommitmentKey; using Instance = ProverInstance_; + static constexpr size_t NUM_FOLDING = 2; + using ProverInstances = ProverInstances_; + using VerifierInstances = VerifierInstances_; + // offset due to placing zero wires at the start of execution trace static constexpr size_t num_zero_rows = Flavor::has_zero_row ? 1 : 0; - static constexpr std::string_view NAME_STRING = "UltraHonk"; static constexpr size_t NUM_WIRES = CircuitBuilder::NUM_WIRES; std::shared_ptr proving_key; @@ -69,8 +72,24 @@ template class UltraComposer_ { UltraProver_ create_prover(std::shared_ptr); UltraVerifier_ create_verifier(std::shared_ptr); - ProtoGalaxyProver_ create_folding_prover(std::vector>); - ProtoGalaxyVerifier_ create_folding_verifier(std::vector>); + ProtoGalaxyProver_ create_folding_prover(std::vector> instances) + { + ProverInstances insts(instances); + ProtoGalaxyProver_ output_state(insts); + + return output_state; + }; + ProtoGalaxyVerifier_ create_folding_verifier(std::vector> instances) + { + std::vector> vks; + for (const auto& inst : instances) { + vks.emplace_back(inst->compute_verification_key()); + } + VerifierInstances insts(vks); + ProtoGalaxyVerifier_ output_state(insts); + + return output_state; + }; }; extern template class UltraComposer_; // TODO: the UltraGrumpkin flavor still works on BN254 because plookup needs to be templated to be able to construct diff --git a/barretenberg/cpp/src/barretenberg/honk/instance/instances.hpp b/barretenberg/cpp/src/barretenberg/honk/instance/instances.hpp new file mode 100644 index 00000000000..565757ebb86 --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/honk/instance/instances.hpp @@ -0,0 +1,48 @@ +#pragma once +#include "barretenberg/honk/instance/prover_instance.hpp" +#include "barretenberg/honk/instance/verifier_instance.hpp" +namespace proof_system::honk { + +template struct ProverInstances_ { + using Flavor = Flavor_; + using Instance = ProverInstance_; + using ArrayType = std::array, NUM_>; + + public: + static constexpr size_t NUM = NUM_; + ArrayType _data; + Instance const& operator[](size_t idx) const { return _data[idx]; } + typename ArrayType::iterator begin() { return _data.begin(); }; + typename ArrayType::iterator end() { return _data.end(); }; + ProverInstances_(std::vector> data) + { + ASSERT(data.size() == NUM); + for (size_t idx = 0; idx < data.size(); idx++) { + _data[idx] = std::move(data[idx]); + } + }; +}; + +template struct VerifierInstances_ { + using Flavor = Flavor_; + using VerificationKey = typename Flavor::VerificationKey; + using Instance = VerifierInstance_; + using ArrayType = std::array; + + public: + static constexpr size_t NUM = NUM_; + ArrayType _data; + Instance const& operator[](size_t idx) const { return _data[idx]; } + typename ArrayType::iterator begin() { return _data.begin(); }; + typename ArrayType::iterator end() { return _data.end(); }; + VerifierInstances_(std::vector> vks) + { + ASSERT(vks.size() == NUM); + for (size_t idx = 0; idx < vks.size(); idx++) { + Instance inst; + inst.verification_key = std::move(vks[idx]); + _data[idx] = inst; + } + }; +}; +} // namespace proof_system::honk \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/honk/instance/prover_instance.hpp b/barretenberg/cpp/src/barretenberg/honk/instance/prover_instance.hpp index 82a15ae736f..042566a3358 100644 --- a/barretenberg/cpp/src/barretenberg/honk/instance/prover_instance.hpp +++ b/barretenberg/cpp/src/barretenberg/honk/instance/prover_instance.hpp @@ -44,8 +44,6 @@ template class ProverInstance_ { proof_system::RelationParameters relation_parameters; std::vector recursive_proof_public_input_indices; FoldingParameters folding_params; - // Used by the prover for domain separation in the transcript - uint32_t index; ProverInstance_(Circuit& circuit) { @@ -101,6 +99,4 @@ extern template class ProverInstance_; extern template class ProverInstance_; extern template class ProverInstance_; -using ProverInstance = ProverInstance_; - } // namespace proof_system::honk \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/honk/instance/verifier_instance.hpp b/barretenberg/cpp/src/barretenberg/honk/instance/verifier_instance.hpp index 7adb643d441..3ba7979103a 100644 --- a/barretenberg/cpp/src/barretenberg/honk/instance/verifier_instance.hpp +++ b/barretenberg/cpp/src/barretenberg/honk/instance/verifier_instance.hpp @@ -15,6 +15,5 @@ template class VerifierInstance_ { size_t circuit_size; RelationParameters relation_parameters; FoldingParameters folding_params; - size_t index; }; } // namespace proof_system::honk \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_prover.cpp b/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_prover.cpp index 679071c8cb7..0fb90be5d06 100644 --- a/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_prover.cpp +++ b/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_prover.cpp @@ -1,10 +1,6 @@ #include "protogalaxy_prover.hpp" #include "barretenberg/proof_system/flavor/flavor.hpp" namespace proof_system::honk { -template -ProtoGalaxyProver_::ProtoGalaxyProver_(std::vector> insts) - : instances(insts) -{} /** * @brief Prior to folding we need to add all the public inputs to the transcript, labelled by their corresponding @@ -12,43 +8,45 @@ ProtoGalaxyProver_::ProtoGalaxyProver_(std::vector void ProtoGalaxyProver_::prepare_for_folding() +template void ProtoGalaxyProver_::prepare_for_folding() { - for (const auto& instance : instances) { + // this doesnt work in the current format + auto idx = 0; + for (auto it = instances.begin(); it != instances.end(); it++, idx++) { + auto instance = *it; instance->initialise_prover_polynomials(); - const auto instance_index = std::to_string(instance->index); + auto domain_separator = std::to_string(idx); const auto circuit_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(instance_index + "_circuit_size", circuit_size); - transcript.send_to_verifier(instance_index + "_public_input_size", num_public_inputs); - transcript.send_to_verifier(instance_index + "_pub_inputs_offset", + transcript.send_to_verifier(domain_separator + "_circuit_size", circuit_size); + transcript.send_to_verifier(domain_separator + "_public_input_size", num_public_inputs); + transcript.send_to_verifier(domain_separator + "_pub_inputs_offset", static_cast(instance->pub_inputs_offset)); for (size_t i = 0; i < instance->proving_key->num_public_inputs; ++i) { auto public_input_i = instance->public_inputs[i]; - transcript.send_to_verifier(instance_index + "_public_input_" + std::to_string(i), public_input_i); + transcript.send_to_verifier(domain_separator + "_public_input_" + std::to_string(i), public_input_i); } - auto [eta, beta, gamma] = - transcript.get_challenges(instance_index + "_eta", instance_index + "_beta", instance_index + "_gamma"); + auto [eta, beta, gamma] = transcript.get_challenges( + domain_separator + "_eta", domain_separator + "_beta", domain_separator + "_gamma"); instance->compute_sorted_accumulator_polynomials(eta); instance->compute_grand_product_polynomials(beta, gamma); } } // TODO(#689): implement this function -template ProverFoldingResult ProtoGalaxyProver_::fold_instances() +template +ProverFoldingResult ProtoGalaxyProver_::fold_instances() { prepare_for_folding(); ProverFoldingResult res; res.folding_data = transcript.proof_data; return res; } - -template class ProtoGalaxyProver_; -template class ProtoGalaxyProver_; -template class ProtoGalaxyProver_; - +template class ProtoGalaxyProver_>; +template class ProtoGalaxyProver_>; +template class ProtoGalaxyProver_>; } // namespace proof_system::honk \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_prover.hpp b/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_prover.hpp index a2e2969c77b..3874e77d7bd 100644 --- a/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_prover.hpp +++ b/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_prover.hpp @@ -2,21 +2,22 @@ #include "barretenberg/honk/flavor/goblin_ultra.hpp" #include "barretenberg/honk/flavor/ultra.hpp" #include "barretenberg/honk/flavor/ultra_grumpkin.hpp" -#include "barretenberg/honk/instance/prover_instance.hpp" +#include "barretenberg/honk/instance/instances.hpp" #include "barretenberg/honk/proof_system/folding_result.hpp" #include "barretenberg/proof_system/flavor/flavor.hpp" namespace proof_system::honk { -template class ProtoGalaxyProver_ { +template class ProtoGalaxyProver_ { public: + using Flavor = typename ProverInstances::Flavor; using FF = typename Flavor::FF; - using Instance = ProverInstance_; using ProverPolynomials = typename Flavor::ProverPolynomials; - std::vector> instances; + ProverInstances instances; ProverTranscript transcript; - explicit ProtoGalaxyProver_(std::vector>); + ProtoGalaxyProver_(ProverInstances insts) + : instances(insts){}; ~ProtoGalaxyProver_() = default; void prepare_for_folding(); @@ -24,7 +25,7 @@ template class ProtoGalaxyProver_ { ProverFoldingResult fold_instances(); }; -extern template class ProtoGalaxyProver_; -extern template class ProtoGalaxyProver_; -extern template class ProtoGalaxyProver_; +extern template class ProtoGalaxyProver_>; +extern template class ProtoGalaxyProver_>; +extern template class ProtoGalaxyProver_>; } // namespace proof_system::honk \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_verifier.cpp b/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_verifier.cpp index 8ad3054595f..d9b8393d120 100644 --- a/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_verifier.cpp @@ -1,36 +1,28 @@ #include "protogalaxy_verifier.hpp" #include "barretenberg/honk/utils/grand_product_delta.hpp" namespace proof_system::honk { -template -ProtoGalaxyVerifier_::ProtoGalaxyVerifier_(std::vector> vks) -{ - // TODO(https://github.com/AztecProtocol/barretenberg/issues/391): simplify code with C++23 features - uint32_t idx = 0; - for (const auto& vk : vks) { - VerifierInstance inst; - inst.verification_key = std::move(vk); - inst.index = idx; - verifier_instances.emplace_back(inst); - idx++; - } -} - -template -VerifierFoldingResult ProtoGalaxyVerifier_::fold_public_parameters(std::vector fold_data) +template +VerifierFoldingResult ProtoGalaxyVerifier_< + VerifierInstances>::fold_public_parameters(std::vector fold_data) { transcript = VerifierTranscript{ fold_data }; - for (auto& inst : verifier_instances) { - auto idx = std::to_string(inst.index); - inst.circuit_size = transcript.template receive_from_prover(idx + "_circuit_size"); - inst.public_input_size = transcript.template receive_from_prover(idx + "_public_input_size"); - inst.pub_inputs_offset = transcript.template receive_from_prover(idx + "_pub_inputs_offset"); + auto index = 0; + for (auto it = verifier_instances.begin(); it != verifier_instances.end(); it++, index++) { + auto inst = *it; + auto domain_separator = std::to_string(index); + inst.circuit_size = transcript.template receive_from_prover(domain_separator + "_circuit_size"); + inst.public_input_size = + transcript.template receive_from_prover(domain_separator + "_public_input_size"); + inst.pub_inputs_offset = + transcript.template receive_from_prover(domain_separator + "_pub_inputs_offset"); for (size_t i = 0; i < inst.public_input_size; ++i) { auto public_input_i = - transcript.template receive_from_prover(idx + "_public_input_" + std::to_string(i)); + transcript.template receive_from_prover(domain_separator + "_public_input_" + std::to_string(i)); inst.public_inputs.emplace_back(public_input_i); } - auto [eta, beta, gamma] = transcript.get_challenges(idx + "_eta", idx + "_beta", idx + "_gamma"); + auto [eta, beta, gamma] = transcript.get_challenges( + domain_separator + "_eta", domain_separator + "_beta", domain_separator + "_gamma"); const FF public_input_delta = compute_public_input_delta( inst.public_inputs, beta, gamma, inst.circuit_size, inst.pub_inputs_offset); const FF lookup_grand_product_delta = compute_lookup_grand_product_delta(beta, gamma, inst.circuit_size); @@ -43,7 +35,7 @@ VerifierFoldingResult ProtoGalaxyVerifier_::fold_public_paramete return res; } -template class ProtoGalaxyVerifier_; -template class ProtoGalaxyVerifier_; -template class ProtoGalaxyVerifier_; +template class ProtoGalaxyVerifier_>; +template class ProtoGalaxyVerifier_>; +template class ProtoGalaxyVerifier_>; } // namespace proof_system::honk \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_verifier.hpp b/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_verifier.hpp index e556480af1c..eeb64a44c0e 100644 --- a/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_verifier.hpp +++ b/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_verifier.hpp @@ -2,26 +2,29 @@ #include "barretenberg/honk/flavor/goblin_ultra.hpp" #include "barretenberg/honk/flavor/ultra.hpp" #include "barretenberg/honk/flavor/ultra_grumpkin.hpp" -#include "barretenberg/honk/instance/verifier_instance.hpp" +#include "barretenberg/honk/instance/instances.hpp" #include "barretenberg/honk/proof_system/folding_result.hpp" #include "barretenberg/honk/transcript/transcript.hpp" #include "barretenberg/proof_system/flavor/flavor.hpp" namespace proof_system::honk { -template class ProtoGalaxyVerifier_ { +template class ProtoGalaxyVerifier_ { public: + using Flavor = typename VerifierInstances::Flavor; using FF = typename Flavor::FF; + using Instance = typename VerifierInstances::Instance; using VerificationKey = typename Flavor::VerificationKey; - using VerifierInstance = VerifierInstance_; - std::vector verifier_instances; + VerifierInstances verifier_instances; VerifierTranscript transcript; - explicit ProtoGalaxyVerifier_(std::vector> vks); + // should the PG verifier be given the VerifierInstances, nah this makes sense yo me + ProtoGalaxyVerifier_(VerifierInstances insts) + : verifier_instances(insts){}; ~ProtoGalaxyVerifier_() = default; VerifierFoldingResult fold_public_parameters(std::vector fold_data); }; -extern template class ProtoGalaxyVerifier_; -extern template class ProtoGalaxyVerifier_; -extern template class ProtoGalaxyVerifier_; +extern template class ProtoGalaxyVerifier_>; +extern template class ProtoGalaxyVerifier_>; +extern template class ProtoGalaxyVerifier_>; } // namespace proof_system::honk \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/honk/transcript/transcript.test.cpp b/barretenberg/cpp/src/barretenberg/honk/transcript/transcript.test.cpp index 9e789932c88..8d9f55966da 100644 --- a/barretenberg/cpp/src/barretenberg/honk/transcript/transcript.test.cpp +++ b/barretenberg/cpp/src/barretenberg/honk/transcript/transcript.test.cpp @@ -187,6 +187,7 @@ TEST_F(UltraTranscriptTests, VerifierManifestConsistency) TEST_F(UltraTranscriptTests, FoldingManifestTest) { + using Flavor = flavor::Ultra; auto builder_one = proof_system::UltraCircuitBuilder(); auto a = 2; auto b = 3; @@ -206,7 +207,7 @@ TEST_F(UltraTranscriptTests, FoldingManifestTest) auto instance_one = composer.create_instance(builder_one); auto instance_two = composer.create_instance(builder_two); - std::vector> insts; + std::vector>> insts; insts.emplace_back(instance_one); insts.emplace_back(instance_two); auto prover = composer.create_folding_prover(insts);