From 8259636c016c0adecb052f176e78444fb5481c38 Mon Sep 17 00:00:00 2001 From: ludamad Date: Fri, 1 Dec 2023 17:09:50 -0500 Subject: [PATCH] refactor(bb): Reuse entities from GoblinUltra in GoblinUltraRecursive (#3521) This is achieved by adding some minimal templating that is redundant in the context of GoblinUltra, but can be used to remove a lot of duplication in GoblinUltraRecursive --- .../src/barretenberg/eccvm/eccvm_verifier.cpp | 4 +- .../cpp/src/barretenberg/flavor/ecc_vm.hpp | 13 +- .../flavor/generated/AvmMini_flavor.hpp | 3 +- .../flavor/generated/Fib_flavor.hpp | 3 +- .../barretenberg/flavor/goblin_translator.hpp | 3 +- .../src/barretenberg/flavor/goblin_ultra.hpp | 326 ++++++------ .../flavor/goblin_ultra_recursive.hpp | 471 +----------------- .../cpp/src/barretenberg/flavor/ultra.hpp | 4 +- .../barretenberg/flavor/ultra_recursive.hpp | 2 +- .../verifier/ultra_recursive_verifier.cpp | 4 +- .../goblin_translator_verifier.cpp | 2 +- .../ultra_honk/ultra_verifier.cpp | 4 +- .../vm/generated/AvmMini_verifier.cpp | 4 +- .../vm/generated/Fib_verifier.cpp | 4 +- 14 files changed, 202 insertions(+), 645 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/eccvm/eccvm_verifier.cpp b/barretenberg/cpp/src/barretenberg/eccvm/eccvm_verifier.cpp index 3f61f75d571..1ef8d6d3d16 100644 --- a/barretenberg/cpp/src/barretenberg/eccvm/eccvm_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/eccvm/eccvm_verifier.cpp @@ -51,8 +51,8 @@ template bool ECCVMVerifier_::verify_proof(const plonk transcript = Transcript{ proof.proof_data }; - auto commitments = VerifierCommitments(key, transcript); - auto commitment_labels = CommitmentLabels(); + VerifierCommitments commitments{ key }; + CommitmentLabels commitment_labels; const auto circuit_size = transcript.template receive_from_prover("circuit_size"); diff --git a/barretenberg/cpp/src/barretenberg/flavor/ecc_vm.hpp b/barretenberg/cpp/src/barretenberg/flavor/ecc_vm.hpp index fb76b7e02fd..2d864059b96 100644 --- a/barretenberg/cpp/src/barretenberg/flavor/ecc_vm.hpp +++ b/barretenberg/cpp/src/barretenberg/flavor/ecc_vm.hpp @@ -519,17 +519,12 @@ template class ECCVMBa }; class VerifierCommitments : public AllEntities { - private: - using Base = AllEntities; - public: - VerifierCommitments(const std::shared_ptr& verification_key, - [[maybe_unused]] const BaseTranscript& transcript) + VerifierCommitments(const std::shared_ptr& verification_key) { - static_cast(transcript); - Base::lagrange_first = verification_key->lagrange_first; - Base::lagrange_second = verification_key->lagrange_second; - Base::lagrange_last = verification_key->lagrange_last; + this->lagrange_first = verification_key->lagrange_first; + this->lagrange_second = verification_key->lagrange_second; + this->lagrange_last = verification_key->lagrange_last; } }; diff --git a/barretenberg/cpp/src/barretenberg/flavor/generated/AvmMini_flavor.hpp b/barretenberg/cpp/src/barretenberg/flavor/generated/AvmMini_flavor.hpp index a950e184655..e1bb16eb859 100644 --- a/barretenberg/cpp/src/barretenberg/flavor/generated/AvmMini_flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/flavor/generated/AvmMini_flavor.hpp @@ -326,9 +326,8 @@ class AvmMiniFlavor { using Base = AllEntities; public: - VerifierCommitments(const std::shared_ptr& verification_key, const BaseTranscript& transcript) + VerifierCommitments(const std::shared_ptr& verification_key) { - static_cast(transcript); avmMini_clk = verification_key->avmMini_clk; avmMini_first = verification_key->avmMini_first; } diff --git a/barretenberg/cpp/src/barretenberg/flavor/generated/Fib_flavor.hpp b/barretenberg/cpp/src/barretenberg/flavor/generated/Fib_flavor.hpp index ab0b320ac4b..9572fedd3ff 100644 --- a/barretenberg/cpp/src/barretenberg/flavor/generated/Fib_flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/flavor/generated/Fib_flavor.hpp @@ -216,9 +216,8 @@ class FibFlavor { using Base = AllEntities; public: - VerifierCommitments(const std::shared_ptr& verification_key, const BaseTranscript& transcript) + VerifierCommitments(const std::shared_ptr& verification_key) { - static_cast(transcript); Fibonacci_LAST = verification_key->Fibonacci_LAST; Fibonacci_FIRST = verification_key->Fibonacci_FIRST; } diff --git a/barretenberg/cpp/src/barretenberg/flavor/goblin_translator.hpp b/barretenberg/cpp/src/barretenberg/flavor/goblin_translator.hpp index b9ff0998aea..24809478010 100644 --- a/barretenberg/cpp/src/barretenberg/flavor/goblin_translator.hpp +++ b/barretenberg/cpp/src/barretenberg/flavor/goblin_translator.hpp @@ -1204,8 +1204,7 @@ class GoblinTranslator { class VerifierCommitments : public AllEntities { public: - VerifierCommitments([[maybe_unused]] std::shared_ptr verification_key, - [[maybe_unused]] const BaseTranscript& transcript) + VerifierCommitments(const std::shared_ptr& verification_key) { this->lagrange_first = verification_key->lagrange_first; this->lagrange_last = verification_key->lagrange_last; diff --git a/barretenberg/cpp/src/barretenberg/flavor/goblin_ultra.hpp b/barretenberg/cpp/src/barretenberg/flavor/goblin_ultra.hpp index 2d9410626c4..29085b01611 100644 --- a/barretenberg/cpp/src/barretenberg/flavor/goblin_ultra.hpp +++ b/barretenberg/cpp/src/barretenberg/flavor/goblin_ultra.hpp @@ -48,14 +48,17 @@ class GoblinUltra { std::tuple, proof_system::LookupRelation>; // define the tuple of Relations that comprise the Sumcheck relation - using Relations = std::tuple, - proof_system::UltraPermutationRelation, - proof_system::LookupRelation, - proof_system::GenPermSortRelation, - proof_system::EllipticRelation, - proof_system::AuxiliaryRelation, - proof_system::EccOpQueueRelation, - proof_system::DatabusLookupRelation>; + // Note: made generic for use in GoblinUltraRecursive. + template + using Relations_ = std::tuple, + proof_system::UltraPermutationRelation, + proof_system::LookupRelation, + proof_system::GenPermSortRelation, + proof_system::EllipticRelation, + proof_system::AuxiliaryRelation, + proof_system::EccOpQueueRelation, + proof_system::DatabusLookupRelation>; + using Relations = Relations_; using LogDerivLookupRelation = proof_system::DatabusLookupRelation; @@ -79,7 +82,6 @@ class GoblinUltra { // Whether or not the first row of the execution trace is reserved for 0s to enable shifts static constexpr bool has_zero_row = true; - private: /** * @brief A base class labelling precomputed entities and (ordered) subsets of interest. * @details Used to build the proving key and verification key. @@ -128,17 +130,23 @@ class GoblinUltra { RefVector get_table_polynomials() { return { table_1, table_2, table_3, table_4 }; }; }; - /** - * @brief Container for all witness polynomials used/constructed by the prover. - * @details Shifts are not included here since they do not occupy their own memory. - */ - template class WitnessEntities { + // GoblinUltra needs to expose more public classes than most flavors due to GoblinUltraRecursive reuse, but these + // are internal: + private: + // WireEntities for basic witness entities + template class WireEntities { + public: + DEFINE_FLAVOR_MEMBERS(DataType, + w_l, // column 0 + w_r, // column 1 + w_o, // column 2 + w_4); // column 3 + }; + + // DerivedEntities for derived witness entities + template class DerivedEntities { public: DEFINE_FLAVOR_MEMBERS(DataType, - w_l, // column 0 - w_r, // column 1 - w_o, // column 2 - w_4, // column 3 sorted_accum, // column 4 z_perm, // column 5 z_lookup, // column 6 @@ -148,15 +156,49 @@ class GoblinUltra { ecc_op_wire_4, // column 10 calldata, // column 11 calldata_read_counts, // column 12 - lookup_inverses // column 13 - ) - RefVector get_wires() { return { w_l, w_r, w_o, w_4 }; }; + lookup_inverses); // column 13 + }; + + /** + * @brief Container for all witness polynomials used/constructed by the prover. + * @details Shifts are not included here since they do not occupy their own memory. + * Combines WireEntities + DerivedEntities. + */ + template + class WitnessEntities : public WireEntities, public DerivedEntities { + public: + DEFINE_COMPOUND_GET_ALL(WireEntities::get_all(), DerivedEntities::get_all()) + + RefVector get_wires() { return WireEntities::get_all(); }; RefVector get_ecc_op_wires() { - return { ecc_op_wire_1, ecc_op_wire_2, ecc_op_wire_3, ecc_op_wire_4 }; + return { this->ecc_op_wire_1, this->ecc_op_wire_2, this->ecc_op_wire_3, this->ecc_op_wire_4 }; + } + // The sorted concatenations of table and witness data needed for plookup. + RefVector get_sorted_polynomials() + { + return { this->sorted_1, this->sorted_2, this->sorted_3, this->sorted_4 }; }; }; + template class ShiftedEntities { + public: + DEFINE_FLAVOR_MEMBERS(DataType, + table_1_shift, // column 0 + table_2_shift, // column 1 + table_3_shift, // column 2 + table_4_shift, // column 3 + w_l_shift, // column 4 + w_r_shift, // column 5 + w_o_shift, // column 6 + w_4_shift, // column 7 + sorted_accum_shift, // column 8 + z_perm_shift, // column 9 + z_lookup_shift // column 10 + ) + }; + + public: /** * @brief A base class labelling all entities (for instance, all of the polynomials used by the prover during * sumcheck) in this Honk variant along with particular subsets of interest @@ -166,127 +208,74 @@ class GoblinUltra { * Symbolically we have: AllEntities = PrecomputedEntities + WitnessEntities + "ShiftedEntities". It could be * implemented as such, but we have this now. */ - template class AllEntities { + template + class AllEntities : public PrecomputedEntities, + public WitnessEntities, + public ShiftedEntities { public: - DEFINE_FLAVOR_MEMBERS(DataType, - q_c, // column 0 - q_l, // column 1 - q_r, // column 2 - q_o, // column 3 - q_4, // column 4 - q_m, // column 5 - q_arith, // column 6 - q_sort, // column 7 - q_elliptic, // column 8 - q_aux, // column 9 - q_lookup, // column 10 - q_busread, // column 11 - sigma_1, // column 12 - sigma_2, // column 13 - sigma_3, // column 14 - sigma_4, // column 15 - id_1, // column 16 - id_2, // column 17 - id_3, // column 18 - id_4, // column 19 - table_1, // column 20 - table_2, // column 21 - table_3, // column 22 - table_4, // column 23 - lagrange_first, // column 24 - lagrange_last, // column 25 - lagrange_ecc_op, // column 26 - databus_id, // column 27 - w_l, // column 28 - w_r, // column 29 - w_o, // column 30 - w_4, // column 31 - sorted_accum, // column 32 - z_perm, // column 33 - z_lookup, // column 34 - ecc_op_wire_1, // column 35 - ecc_op_wire_2, // column 36 - ecc_op_wire_3, // column 37 - ecc_op_wire_4, // column 38 - calldata, // column 39 - calldata_read_counts, // column 40 - lookup_inverses, // column 41 - table_1_shift, // column 42 - table_2_shift, // column 43 - table_3_shift, // column 44 - table_4_shift, // column 45 - w_l_shift, // column 46 - w_r_shift, // column 47 - w_o_shift, // column 48 - w_4_shift, // column 49 - sorted_accum_shift, // column 50 - z_perm_shift, // column 51 - z_lookup_shift // column 52 - ) + DEFINE_COMPOUND_GET_ALL(PrecomputedEntities::get_all(), + WitnessEntities::get_all(), + ShiftedEntities::get_all()) - RefVector get_wires() { return { w_l, w_r, w_o, w_4 }; }; + RefVector get_wires() { return { this->w_l, this->w_r, this->w_o, this->w_4 }; }; RefVector get_ecc_op_wires() { - return { ecc_op_wire_1, ecc_op_wire_2, ecc_op_wire_3, ecc_op_wire_4 }; + return { this->ecc_op_wire_1, this->ecc_op_wire_2, this->ecc_op_wire_3, this->ecc_op_wire_4 }; }; // Gemini-specific getters. RefVector get_unshifted() { - return { q_c, - q_l, - q_r, - q_o, - q_4, - q_m, - q_arith, - q_sort, - q_elliptic, - q_aux, - q_lookup, - q_busread, - sigma_1, - sigma_2, - sigma_3, - sigma_4, - id_1, - id_2, - id_3, - id_4, - table_1, - table_2, - table_3, - table_4, - lagrange_first, - lagrange_last, - lagrange_ecc_op, - databus_id, - w_l, - w_r, - w_o, - w_4, - sorted_accum, - z_perm, - z_lookup, - ecc_op_wire_1, - ecc_op_wire_2, - ecc_op_wire_3, - ecc_op_wire_4, - calldata, - calldata_read_counts, - lookup_inverses }; + return { this->q_c, + this->q_l, + this->q_r, + this->q_o, + this->q_4, + this->q_m, + this->q_arith, + this->q_sort, + this->q_elliptic, + this->q_aux, + this->q_lookup, + this->q_busread, + this->sigma_1, + this->sigma_2, + this->sigma_3, + this->sigma_4, + this->id_1, + this->id_2, + this->id_3, + this->id_4, + this->table_1, + this->table_2, + this->table_3, + this->table_4, + this->lagrange_first, + this->lagrange_last, + this->lagrange_ecc_op, + this->databus_id, + this->w_l, + this->w_r, + this->w_o, + this->w_4, + this->sorted_accum, + this->z_perm, + this->z_lookup, + this->ecc_op_wire_1, + this->ecc_op_wire_2, + this->ecc_op_wire_3, + this->ecc_op_wire_4, + this->calldata, + this->calldata_read_counts, + this->lookup_inverses }; }; RefVector get_to_be_shifted() { - return { table_1, table_2, table_3, table_4, w_l, w_r, w_o, w_4, sorted_accum, z_perm, z_lookup }; - }; - RefVector get_shifted() - { - return { table_1_shift, table_2_shift, table_3_shift, table_4_shift, w_l_shift, w_r_shift, - w_o_shift, w_4_shift, sorted_accum_shift, z_perm_shift, z_lookup_shift }; + return { this->table_1, this->table_2, this->table_3, this->table_4, this->w_l, this->w_r, + this->w_o, this->w_4, this->sorted_accum, this->z_perm, this->z_lookup }; }; + RefVector get_shifted() { return ShiftedEntities::get_all(); }; }; - public: /** * @brief The proving key is responsible for storing the polynomials used by the prover. * @note TODO(Cody): Maybe multiple inheritance is the right thing here. In that case, nothing should eve inherit @@ -431,43 +420,46 @@ class GoblinUltra { }; }; - class VerifierCommitments : public AllEntities { + /** + * Note: Made generic for use in GoblinUltraRecursive. + **/ + template + class VerifierCommitments_ : public AllEntities { public: - VerifierCommitments(std::shared_ptr verification_key, - [[maybe_unused]] const BaseTranscript& transcript) + VerifierCommitments_(const std::shared_ptr& verification_key) { - static_cast(transcript); - q_m = verification_key->q_m; - q_l = verification_key->q_l; - q_r = verification_key->q_r; - q_o = verification_key->q_o; - q_4 = verification_key->q_4; - q_c = verification_key->q_c; - q_arith = verification_key->q_arith; - q_sort = verification_key->q_sort; - q_elliptic = verification_key->q_elliptic; - q_aux = verification_key->q_aux; - q_lookup = verification_key->q_lookup; - q_busread = verification_key->q_busread; - sigma_1 = verification_key->sigma_1; - sigma_2 = verification_key->sigma_2; - sigma_3 = verification_key->sigma_3; - sigma_4 = verification_key->sigma_4; - id_1 = verification_key->id_1; - id_2 = verification_key->id_2; - id_3 = verification_key->id_3; - id_4 = verification_key->id_4; - table_1 = verification_key->table_1; - table_2 = verification_key->table_2; - table_3 = verification_key->table_3; - table_4 = verification_key->table_4; - lagrange_first = verification_key->lagrange_first; - lagrange_last = verification_key->lagrange_last; - lagrange_ecc_op = verification_key->lagrange_ecc_op; - databus_id = verification_key->databus_id; + this->q_m = verification_key->q_m; + this->q_l = verification_key->q_l; + this->q_r = verification_key->q_r; + this->q_o = verification_key->q_o; + this->q_4 = verification_key->q_4; + this->q_c = verification_key->q_c; + this->q_arith = verification_key->q_arith; + this->q_sort = verification_key->q_sort; + this->q_elliptic = verification_key->q_elliptic; + this->q_aux = verification_key->q_aux; + this->q_lookup = verification_key->q_lookup; + this->q_busread = verification_key->q_busread; + this->sigma_1 = verification_key->sigma_1; + this->sigma_2 = verification_key->sigma_2; + this->sigma_3 = verification_key->sigma_3; + this->sigma_4 = verification_key->sigma_4; + this->id_1 = verification_key->id_1; + this->id_2 = verification_key->id_2; + this->id_3 = verification_key->id_3; + this->id_4 = verification_key->id_4; + this->table_1 = verification_key->table_1; + this->table_2 = verification_key->table_2; + this->table_3 = verification_key->table_3; + this->table_4 = verification_key->table_4; + this->lagrange_first = verification_key->lagrange_first; + this->lagrange_last = verification_key->lagrange_last; + this->lagrange_ecc_op = verification_key->lagrange_ecc_op; + this->databus_id = verification_key->databus_id; } }; - + // Specialize for GoblinUltra (general case used in GoblinUltraRecursive). + using VerifierCommitments = VerifierCommitments_; class FoldingParameters { public: std::vector gate_separation_challenges; @@ -476,9 +468,9 @@ class GoblinUltra { /** * @brief Derived class that defines proof structure for GoblinUltra proofs, as well as supporting functions. - * + * Note: Made generic for use in GoblinUltraRecursive. */ - class Transcript : public BaseTranscript { + template class Transcript_ : public BaseTranscript { public: uint32_t circuit_size; uint32_t public_input_size; @@ -504,9 +496,9 @@ class GoblinUltra { Commitment zm_cq_comm; Commitment zm_pi_comm; - Transcript() = default; + Transcript_() = default; - Transcript(const std::vector& proof) + Transcript_(const std::vector& proof) : BaseTranscript(proof) {} @@ -588,6 +580,8 @@ class GoblinUltra { ASSERT(proof_data.size() == old_proof_length); } }; + // Specialize for GoblinUltra (general case used in GoblinUltraRecursive). + using Transcript = Transcript_; }; } // namespace proof_system::honk::flavor \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/flavor/goblin_ultra_recursive.hpp b/barretenberg/cpp/src/barretenberg/flavor/goblin_ultra_recursive.hpp index dd2a5e7ac5f..cbce512e6ed 100644 --- a/barretenberg/cpp/src/barretenberg/flavor/goblin_ultra_recursive.hpp +++ b/barretenberg/cpp/src/barretenberg/flavor/goblin_ultra_recursive.hpp @@ -62,22 +62,16 @@ template class GoblinUltraRecursive_ { // The number of multivariate polynomials on which a sumcheck prover sumcheck operates (including shifts). We often // need containers of this size to hold related data, so we choose a name more agnostic than `NUM_POLYNOMIALS`. // Note: this number does not include the individual sorted list polynomials. - static constexpr size_t NUM_ALL_ENTITIES = 53; + static constexpr size_t NUM_ALL_ENTITIES = flavor::GoblinUltra::NUM_ALL_ENTITIES; // The number of polynomials precomputed to describe a circuit and to aid a prover in constructing a satisfying // assignment of witnesses. We again choose a neutral name. - static constexpr size_t NUM_PRECOMPUTED_ENTITIES = 28; + static constexpr size_t NUM_PRECOMPUTED_ENTITIES = flavor::GoblinUltra::NUM_PRECOMPUTED_ENTITIES; // The total number of witness entities not including shifts. - static constexpr size_t NUM_WITNESS_ENTITIES = 14; + static constexpr size_t NUM_WITNESS_ENTITIES = flavor::GoblinUltra::NUM_WITNESS_ENTITIES; // define the tuple of Relations that comprise the Sumcheck relation - using Relations = std::tuple, - proof_system::UltraPermutationRelation, - proof_system::LookupRelation, - proof_system::GenPermSortRelation, - proof_system::EllipticRelation, - proof_system::AuxiliaryRelation, - proof_system::EccOpQueueRelation, - proof_system::DatabusLookupRelation>; + // Reuse the Relations from GoblinUltra + using Relations = GoblinUltra::Relations_; static constexpr size_t MAX_PARTIAL_RELATION_LENGTH = compute_max_partial_relation_length(); @@ -91,216 +85,17 @@ template class GoblinUltraRecursive_ { using SumcheckTupleOfTuplesOfUnivariates = decltype(create_sumcheck_tuple_of_tuples_of_univariates()); using TupleOfArraysOfValues = decltype(create_tuple_of_arrays_of_values()); - private: - template - /** - * @brief A base class labelling precomputed entities and (ordered) subsets of interest. - * @details Used to build the proving key and verification key. - */ - class PrecomputedEntities : public PrecomputedEntitiesBase { - public: - DEFINE_FLAVOR_MEMBERS(DataType, - q_m, // column 0 - q_c, // column 1 - q_l, // column 2 - q_r, // column 3 - q_o, // column 4 - q_4, // column 5 - q_arith, // column 6 - q_sort, // column 7 - q_elliptic, // column 8 - q_aux, // column 9 - q_lookup, // column 10 - q_busread, // column 11 - sigma_1, // column 12 - sigma_2, // column 13 - sigma_3, // column 14 - sigma_4, // column 15 - id_1, // column 16 - id_2, // column 17 - id_3, // column 18 - id_4, // column 19 - table_1, // column 20 - table_2, // column 21 - table_3, // column 22 - table_4, // column 23 - lagrange_first, // column 24 - lagrange_last, // column 25 - lagrange_ecc_op, // column 26 // indicator poly for ecc op gates - databus_id // column 27 // id polynomial, i.e. id_i = i - ) - - static constexpr CircuitType CIRCUIT_TYPE = CircuitBuilder::CIRCUIT_TYPE; - - RefVector get_selectors() - { - return { q_m, q_c, q_l, q_r, q_o, q_4, q_arith, q_sort, q_elliptic, q_aux, q_lookup, q_busread }; - }; - RefVector get_sigma_polynomials() { return { sigma_1, sigma_2, sigma_3, sigma_4 }; }; - RefVector get_id_polynomials() { return { id_1, id_2, id_3, id_4 }; }; - - RefVector get_table_polynomials() { return { table_1, table_2, table_3, table_4 }; }; - }; - - /** - * @brief Container for all witness polynomials used/constructed by the prover. - * @details Shifts are not included here since they do not occupy their own memory. - */ - template class WitnessEntities { - public: - DEFINE_FLAVOR_MEMBERS(DataType, - w_l, // column 0 - w_r, // column 1 - w_o, // column 2 - w_4, // column 3 - sorted_accum, // column 4 - z_perm, // column 5 - z_lookup, // column 6 - ecc_op_wire_1, // column 7 - ecc_op_wire_2, // column 8 - ecc_op_wire_3, // column 9 - ecc_op_wire_4, // column 10 - calldata, // column 11 - calldata_read_counts, // column 12 - lookup_inverses // column 13 - ) - - RefVector get_wires() { return { w_l, w_r, w_o, w_4 }; }; - RefVector get_ecc_op_wires() - { - return { ecc_op_wire_1, ecc_op_wire_2, ecc_op_wire_3, ecc_op_wire_4 }; - }; - }; - + public: /** - * @brief A base class labelling all entities (for instance, all of the polynomials used by the prover during - * sumcheck) in this Honk variant along with particular subsets of interest - * @details Used to build containers for: the prover's polynomial during sumcheck; the sumcheck's folded - * polynomials; the univariates consturcted during during sumcheck; the evaluations produced by sumcheck. - * - * Symbolically we have: AllEntities = PrecomputedEntities + WitnessEntities + "ShiftedEntities". It could be - * implemented as such, but we have this now. + * @brief A field element for each entity of the flavor. These entities represent the prover polynomials evaluated + * at one point. */ - template class AllEntities { + class AllValues : public GoblinUltra::AllEntities { public: - DEFINE_FLAVOR_MEMBERS(DataType, - q_c, // column 0 - q_l, // column 1 - q_r, // column 2 - q_o, // column 3 - q_4, // column 4 - q_m, // column 5 - q_arith, // column 6 - q_sort, // column 7 - q_elliptic, // column 8 - q_aux, // column 9 - q_lookup, // column 10 - q_busread, // column 11 - sigma_1, // column 12 - sigma_2, // column 13 - sigma_3, // column 14 - sigma_4, // column 15 - id_1, // column 16 - id_2, // column 17 - id_3, // column 18 - id_4, // column 19 - table_1, // column 20 - table_2, // column 21 - table_3, // column 22 - table_4, // column 23 - lagrange_first, // column 24 - lagrange_last, // column 25 - lagrange_ecc_op, // column 26 - databus_id, // column 27 - w_l, // column 28 - w_r, // column 29 - w_o, // column 30 - w_4, // column 31 - sorted_accum, // column 32 - z_perm, // column 33 - z_lookup, // column 34 - ecc_op_wire_1, // column 35 - ecc_op_wire_2, // column 36 - ecc_op_wire_3, // column 37 - ecc_op_wire_4, // column 38 - calldata, // column 39 - calldata_read_counts, // column 40 - lookup_inverses, // column 41 - table_1_shift, // column 42 - table_2_shift, // column 43 - table_3_shift, // column 44 - table_4_shift, // column 45 - w_l_shift, // column 46 - w_r_shift, // column 47 - w_o_shift, // column 48 - w_4_shift, // column 49 - sorted_accum_shift, // column 50 - z_perm_shift, // column 51 - z_lookup_shift); // column 52 - - RefVector get_wires() { return { w_l, w_r, w_o, w_4 }; }; - RefVector get_ecc_op_wires() - { - return { ecc_op_wire_1, ecc_op_wire_2, ecc_op_wire_3, ecc_op_wire_4 }; - }; - // Gemini-specific getters. - RefVector get_unshifted() - { - return { q_c, - q_l, - q_r, - q_o, - q_4, - q_m, - q_arith, - q_sort, - q_elliptic, - q_aux, - q_lookup, - q_busread, - sigma_1, - sigma_2, - sigma_3, - sigma_4, - id_1, - id_2, - id_3, - id_4, - table_1, - table_2, - table_3, - table_4, - lagrange_first, - lagrange_last, - lagrange_ecc_op, - databus_id, - w_l, - w_r, - w_o, - w_4, - sorted_accum, - z_perm, - z_lookup, - ecc_op_wire_1, - ecc_op_wire_2, - ecc_op_wire_3, - ecc_op_wire_4, - calldata, - calldata_read_counts, - lookup_inverses }; - }; - RefVector get_to_be_shifted() - { - return { table_1, table_2, table_3, table_4, w_l, w_r, w_o, w_4, sorted_accum, z_perm, z_lookup }; - }; - RefVector get_shifted() - { - return { table_1_shift, table_2_shift, table_3_shift, table_4_shift, w_l_shift, w_r_shift, - w_o_shift, w_4_shift, sorted_accum_shift, z_perm_shift, z_lookup_shift }; - }; + using Base = GoblinUltra::AllEntities; + using Base::Base; + AllValues(std::array _data_in) { this->_data = _data_in; } }; - - public: /** * @brief The verification key is responsible for storing the the commitments to the precomputed (non-witnessk) * polynomials used by the verifier. @@ -308,8 +103,9 @@ template class GoblinUltraRecursive_ { * @note Note the discrepancy with what sort of data is stored here vs in the proving key. We may want to resolve * that, and split out separate PrecomputedPolynomials/Commitments data for clarity but also for portability of our * circuits. + * This differs from GoblinUltra in how we construct the commitments. */ - class VerificationKey : public VerificationKey_> { + class VerificationKey : public VerificationKey_> { public: /** * @brief Construct a new Verification Key with stdlib types from a provided native verification @@ -318,8 +114,9 @@ template class GoblinUltraRecursive_ { * @param builder * @param native_key Native verification key from which to extract the precomputed commitments */ - VerificationKey(CircuitBuilder* builder, auto native_key) - : VerificationKey_>(native_key->circuit_size, native_key->num_public_inputs) + VerificationKey(CircuitBuilder* builder, const auto& native_key) + : VerificationKey_>(native_key->circuit_size, + native_key->num_public_inputs) { this->q_m = Commitment::from_witness(builder, native_key->q_m); this->q_l = Commitment::from_witness(builder, native_key->q_l); @@ -352,235 +149,11 @@ template class GoblinUltraRecursive_ { }; }; - /** - * @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: - using Base = AllEntities; - using Base::Base; - AllValues(std::array _data_in) { this->_data = _data_in; } - }; - - /** - * @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. - * - */ - class CommitmentLabels : public AllEntities { - public: - CommitmentLabels() - { - this->w_l = "W_L"; - this->w_r = "W_R"; - this->w_o = "W_O"; - this->w_4 = "W_4"; - this->z_perm = "Z_PERM"; - this->z_lookup = "Z_LOOKUP"; - this->sorted_accum = "SORTED_ACCUM"; - this->ecc_op_wire_1 = "ECC_OP_WIRE_1"; - this->ecc_op_wire_2 = "ECC_OP_WIRE_2"; - this->ecc_op_wire_3 = "ECC_OP_WIRE_3"; - this->ecc_op_wire_4 = "ECC_OP_WIRE_4"; - this->calldata = "CALLDATA"; - this->calldata_read_counts = "CALLDATA_READ_COUNTS"; - this->lookup_inverses = "LOOKUP_INVERSES"; - - // The ones beginning with "__" are only used for debugging - this->q_c = "__Q_C"; - this->q_l = "__Q_L"; - this->q_r = "__Q_R"; - this->q_o = "__Q_O"; - this->q_4 = "__Q_4"; - this->q_m = "__Q_M"; - this->q_arith = "__Q_ARITH"; - this->q_sort = "__Q_SORT"; - this->q_elliptic = "__Q_ELLIPTIC"; - this->q_aux = "__Q_AUX"; - this->q_lookup = "__Q_LOOKUP"; - this->q_busread = "__Q_BUSREAD"; - this->sigma_1 = "__SIGMA_1"; - this->sigma_2 = "__SIGMA_2"; - this->sigma_3 = "__SIGMA_3"; - this->sigma_4 = "__SIGMA_4"; - this->id_1 = "__ID_1"; - this->id_2 = "__ID_2"; - this->id_3 = "__ID_3"; - this->id_4 = "__ID_4"; - this->table_1 = "__TABLE_1"; - this->table_2 = "__TABLE_2"; - this->table_3 = "__TABLE_3"; - this->table_4 = "__TABLE_4"; - this->lagrange_first = "__LAGRANGE_FIRST"; - this->lagrange_last = "__LAGRANGE_LAST"; - this->lagrange_ecc_op = "__Q_ECC_OP_QUEUE"; - }; - }; - - class VerifierCommitments : public AllEntities { - public: - VerifierCommitments(std::shared_ptr verification_key) - { - this->q_m = verification_key->q_m; - this->q_l = verification_key->q_l; - this->q_r = verification_key->q_r; - this->q_o = verification_key->q_o; - this->q_4 = verification_key->q_4; - this->q_c = verification_key->q_c; - this->q_arith = verification_key->q_arith; - this->q_sort = verification_key->q_sort; - this->q_elliptic = verification_key->q_elliptic; - this->q_aux = verification_key->q_aux; - this->q_lookup = verification_key->q_lookup; - this->q_busread = verification_key->q_busread; - this->sigma_1 = verification_key->sigma_1; - this->sigma_2 = verification_key->sigma_2; - this->sigma_3 = verification_key->sigma_3; - this->sigma_4 = verification_key->sigma_4; - this->id_1 = verification_key->id_1; - this->id_2 = verification_key->id_2; - this->id_3 = verification_key->id_3; - this->id_4 = verification_key->id_4; - this->table_1 = verification_key->table_1; - this->table_2 = verification_key->table_2; - this->table_3 = verification_key->table_3; - this->table_4 = verification_key->table_4; - this->lagrange_first = verification_key->lagrange_first; - this->lagrange_last = verification_key->lagrange_last; - this->lagrange_ecc_op = verification_key->lagrange_ecc_op; - this->databus_id = verification_key->databus_id; - } - }; - - /** - * @brief Derived class that defines proof structure for GoblinUltraRecursive proofs, as well as supporting - * functions. - * - */ - class Transcript : public BaseTranscript { - public: - uint32_t circuit_size; - uint32_t public_input_size; - uint32_t pub_inputs_offset; - std::vector public_inputs; - Commitment w_l_comm; - Commitment w_r_comm; - Commitment w_o_comm; - Commitment ecc_op_wire_1_comm; - Commitment ecc_op_wire_2_comm; - Commitment ecc_op_wire_3_comm; - Commitment ecc_op_wire_4_comm; - Commitment calldata_comm; - Commitment calldata_read_counts_comm; - Commitment lookup_inverses_comm; - Commitment sorted_accum_comm; - Commitment w_4_comm; - Commitment z_perm_comm; - Commitment z_lookup_comm; - std::vector> sumcheck_univariates; - std::array sumcheck_evaluations; - std::vector zm_cq_comms; - Commitment zm_cq_comm; - Commitment zm_pi_comm; - - Transcript() = default; - - Transcript(const std::vector& proof) - : BaseTranscript(proof) - {} - /** - * @brief Takes a FULL GoblinUltraRecursive proof and deserializes it into the public member - * variables that compose the structure. Must be called in order to access the structure of the - * proof. - * - */ - void deserialize_full_transcript() - { - // take current proof and put them into the struct - size_t num_bytes_read = 0; - circuit_size = deserialize_from_buffer(BaseTranscript::proof_data, num_bytes_read); - size_t log_n = numeric::get_msb(circuit_size); - - public_input_size = deserialize_from_buffer(BaseTranscript::proof_data, num_bytes_read); - pub_inputs_offset = deserialize_from_buffer(BaseTranscript::proof_data, num_bytes_read); - for (size_t i = 0; i < public_input_size; ++i) { - public_inputs.push_back(deserialize_from_buffer(BaseTranscript::proof_data, num_bytes_read)); - } - w_l_comm = deserialize_from_buffer(BaseTranscript::proof_data, num_bytes_read); - w_r_comm = deserialize_from_buffer(BaseTranscript::proof_data, num_bytes_read); - w_o_comm = deserialize_from_buffer(BaseTranscript::proof_data, num_bytes_read); - ecc_op_wire_1_comm = deserialize_from_buffer(BaseTranscript::proof_data, num_bytes_read); - ecc_op_wire_2_comm = deserialize_from_buffer(BaseTranscript::proof_data, num_bytes_read); - ecc_op_wire_3_comm = deserialize_from_buffer(BaseTranscript::proof_data, num_bytes_read); - ecc_op_wire_4_comm = deserialize_from_buffer(BaseTranscript::proof_data, num_bytes_read); - calldata_comm = deserialize_from_buffer(BaseTranscript::proof_data, num_bytes_read); - calldata_read_counts_comm = deserialize_from_buffer(BaseTranscript::proof_data, num_bytes_read); - lookup_inverses_comm = deserialize_from_buffer(BaseTranscript::proof_data, num_bytes_read); - sorted_accum_comm = deserialize_from_buffer(BaseTranscript::proof_data, num_bytes_read); - w_4_comm = deserialize_from_buffer(BaseTranscript::proof_data, num_bytes_read); - z_perm_comm = deserialize_from_buffer(BaseTranscript::proof_data, num_bytes_read); - z_lookup_comm = deserialize_from_buffer(BaseTranscript::proof_data, num_bytes_read); - for (size_t i = 0; i < log_n; ++i) { - sumcheck_univariates.push_back( - deserialize_from_buffer>( - BaseTranscript::proof_data, num_bytes_read)); - } - sumcheck_evaluations = - deserialize_from_buffer>(BaseTranscript::proof_data, num_bytes_read); - for (size_t i = 0; i < log_n; ++i) { - zm_cq_comms.push_back(deserialize_from_buffer(BaseTranscript::proof_data, num_bytes_read)); - } - zm_cq_comm = deserialize_from_buffer(BaseTranscript::proof_data, num_bytes_read); - zm_pi_comm = deserialize_from_buffer(BaseTranscript::proof_data, num_bytes_read); - } - - /** - * @brief Serializes the structure variables into a FULL GoblinUltraRecursive proof. Should be - * called only if deserialize_full_transcript() was called and some transcript variable was - * modified. - * - */ - void serialize_full_transcript() - { - size_t old_proof_length = BaseTranscript::proof_data.size(); - BaseTranscript::proof_data.clear(); - size_t log_n = numeric::get_msb(circuit_size); - serialize_to_buffer(circuit_size, BaseTranscript::proof_data); - serialize_to_buffer(public_input_size, BaseTranscript::proof_data); - serialize_to_buffer(pub_inputs_offset, BaseTranscript::proof_data); - for (size_t i = 0; i < public_input_size; ++i) { - serialize_to_buffer(public_inputs[i], BaseTranscript::proof_data); - } - serialize_to_buffer(w_l_comm, BaseTranscript::proof_data); - serialize_to_buffer(w_r_comm, BaseTranscript::proof_data); - serialize_to_buffer(w_o_comm, BaseTranscript::proof_data); - serialize_to_buffer(ecc_op_wire_1_comm, BaseTranscript::proof_data); - serialize_to_buffer(ecc_op_wire_2_comm, BaseTranscript::proof_data); - serialize_to_buffer(ecc_op_wire_3_comm, BaseTranscript::proof_data); - serialize_to_buffer(ecc_op_wire_4_comm, BaseTranscript::proof_data); - serialize_to_buffer(calldata_comm, BaseTranscript::proof_data); - serialize_to_buffer(calldata_read_counts_comm, BaseTranscript::proof_data); - serialize_to_buffer(lookup_inverses_comm, BaseTranscript::proof_data); - serialize_to_buffer(sorted_accum_comm, BaseTranscript::proof_data); - serialize_to_buffer(w_4_comm, BaseTranscript::proof_data); - serialize_to_buffer(z_perm_comm, BaseTranscript::proof_data); - serialize_to_buffer(z_lookup_comm, BaseTranscript::proof_data); - for (size_t i = 0; i < log_n; ++i) { - serialize_to_buffer(sumcheck_univariates[i], BaseTranscript::proof_data); - } - serialize_to_buffer(sumcheck_evaluations, BaseTranscript::proof_data); - for (size_t i = 0; i < log_n; ++i) { - serialize_to_buffer(zm_cq_comms[i], BaseTranscript::proof_data); - } - serialize_to_buffer(zm_cq_comm, BaseTranscript::proof_data); - serialize_to_buffer(zm_pi_comm, BaseTranscript::proof_data); - - // sanity check to make sure we generate the same length of proof as before. - ASSERT(BaseTranscript::proof_data.size() == old_proof_length); - } - }; + using CommitmentLabels = GoblinUltra::CommitmentLabels; + // Reuse the VerifierCommitments from GoblinUltra + using VerifierCommitments = GoblinUltra::VerifierCommitments_; + // Reuse the transcript from GoblinUltra + using Transcript = GoblinUltra::Transcript_; }; } // namespace proof_system::honk::flavor diff --git a/barretenberg/cpp/src/barretenberg/flavor/ultra.hpp b/barretenberg/cpp/src/barretenberg/flavor/ultra.hpp index 9b34d66340b..10a69f89c9a 100644 --- a/barretenberg/cpp/src/barretenberg/flavor/ultra.hpp +++ b/barretenberg/cpp/src/barretenberg/flavor/ultra.hpp @@ -354,10 +354,8 @@ class Ultra { class VerifierCommitments : public AllEntities { public: - VerifierCommitments(std::shared_ptr verification_key, - [[maybe_unused]] const BaseTranscript& transcript) + VerifierCommitments(const std::shared_ptr& verification_key) { - static_cast(transcript); q_m = verification_key->q_m; q_l = verification_key->q_l; q_r = verification_key->q_r; diff --git a/barretenberg/cpp/src/barretenberg/flavor/ultra_recursive.hpp b/barretenberg/cpp/src/barretenberg/flavor/ultra_recursive.hpp index b9980e0d071..1d7a75e5a20 100644 --- a/barretenberg/cpp/src/barretenberg/flavor/ultra_recursive.hpp +++ b/barretenberg/cpp/src/barretenberg/flavor/ultra_recursive.hpp @@ -341,7 +341,7 @@ template class UltraRecursive_ { class VerifierCommitments : public AllEntities { public: - VerifierCommitments(std::shared_ptr verification_key) + VerifierCommitments(const std::shared_ptr& verification_key) { this->q_m = verification_key->q_m; this->q_l = verification_key->q_l; 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 6a79ecfe890..0e63c544de1 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 @@ -32,8 +32,8 @@ std::array UltraRecursiveVerifier_::ve transcript = Transcript{ builder, proof.proof_data }; - auto commitments = VerifierCommitments(key); - auto commitment_labels = CommitmentLabels(); + VerifierCommitments commitments{ key }; + CommitmentLabels commitment_labels; const auto circuit_size = transcript.template receive_from_prover("circuit_size"); const auto public_input_size = transcript.template receive_from_prover("public_input_size"); diff --git a/barretenberg/cpp/src/barretenberg/translator_vm/goblin_translator_verifier.cpp b/barretenberg/cpp/src/barretenberg/translator_vm/goblin_translator_verifier.cpp index 5c95bd8b75e..8b8c934742b 100644 --- a/barretenberg/cpp/src/barretenberg/translator_vm/goblin_translator_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/translator_vm/goblin_translator_verifier.cpp @@ -67,7 +67,7 @@ bool GoblinTranslatorVerifier::verify_proof(const plonk::proof& proof) { transcript = BaseTranscript{ proof.proof_data }; - Flavor::VerifierCommitments commitments{ key, transcript }; + Flavor::VerifierCommitments commitments{ key }; Flavor::CommitmentLabels commitment_labels; // TODO(Adrian): Change the initialization of the transcript to take the VK hash? diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_verifier.cpp b/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_verifier.cpp index 1198bf981ec..22ea2ecdafe 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_verifier.cpp @@ -44,8 +44,8 @@ template bool UltraVerifier_::verify_proof(const plonk transcript = BaseTranscript{ proof.proof_data }; - auto commitments = VerifierCommitments(key, transcript); - auto commitment_labels = CommitmentLabels(); + VerifierCommitments commitments{ key }; + CommitmentLabels commitment_labels; // TODO(Adrian): Change the initialization of the transcript to take the VK hash? const auto circuit_size = transcript.template receive_from_prover("circuit_size"); diff --git a/barretenberg/cpp/src/barretenberg/vm/generated/AvmMini_verifier.cpp b/barretenberg/cpp/src/barretenberg/vm/generated/AvmMini_verifier.cpp index 042323b480d..493ac8d2d18 100644 --- a/barretenberg/cpp/src/barretenberg/vm/generated/AvmMini_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/generated/AvmMini_verifier.cpp @@ -45,8 +45,8 @@ bool AvmMiniVerifier::verify_proof(const plonk::proof& proof) transcript = BaseTranscript{ proof.proof_data }; - auto commitments = VerifierCommitments(key, transcript); - auto commitment_labels = CommitmentLabels(); + VerifierCommitments commitments{ key }; + CommitmentLabels commitment_labels; const auto circuit_size = transcript.template receive_from_prover("circuit_size"); diff --git a/barretenberg/cpp/src/barretenberg/vm/generated/Fib_verifier.cpp b/barretenberg/cpp/src/barretenberg/vm/generated/Fib_verifier.cpp index 58cc5cfcbc1..f4da6b8f02f 100644 --- a/barretenberg/cpp/src/barretenberg/vm/generated/Fib_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/generated/Fib_verifier.cpp @@ -45,8 +45,8 @@ bool FibVerifier::verify_proof(const plonk::proof& proof) transcript = BaseTranscript{ proof.proof_data }; - auto commitments = VerifierCommitments(key, transcript); - auto commitment_labels = CommitmentLabels(); + VerifierCommitments commitments{ key }; + CommitmentLabels commitment_labels; const auto circuit_size = transcript.template receive_from_prover("circuit_size");