From 34acaaf8ab6030ed28c24628ace3fa06b4ff9474 Mon Sep 17 00:00:00 2001 From: Rumata888 Date: Tue, 21 Nov 2023 18:07:41 +0000 Subject: [PATCH 01/15] Generalize lookup library --- .../honk/proof_system/lookup_library.hpp | 4 ++-- .../relations/databus_lookup_relation.hpp | 11 +++++++++++ .../relations/ecc_vm/ecc_lookup_relation.hpp | 12 ++++++++++++ 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/honk/proof_system/lookup_library.hpp b/barretenberg/cpp/src/barretenberg/honk/proof_system/lookup_library.hpp index 820bc2907a50..c6e629db0782 100644 --- a/barretenberg/cpp/src/barretenberg/honk/proof_system/lookup_library.hpp +++ b/barretenberg/cpp/src/barretenberg/honk/proof_system/lookup_library.hpp @@ -29,9 +29,9 @@ void compute_logderivative_inverse(Polynomials& polynomials, auto& relation_para using Accumulator = typename Relation::ValueAccumulator0; constexpr size_t READ_TERMS = Relation::READ_TERMS; constexpr size_t WRITE_TERMS = Relation::WRITE_TERMS; - auto& inverse_polynomial = polynomials.lookup_inverses; auto lookup_relation = Relation(); + auto& inverse_polynomial = lookup_relation.template get_lookup_inverse_polynomial(polynomials); for (size_t i = 0; i < circuit_size; ++i) { auto row = polynomials.get_row(i); bool has_inverse = lookup_relation.lookup_exists_at_row(row); @@ -97,7 +97,7 @@ void accumulate_logderivative_lookup_subrelation_contributions(ContainerOverSubr using Accumulator = typename std::tuple_element_t<0, ContainerOverSubrelations>; using View = typename Accumulator::View; - auto lookup_inverses = View(in.lookup_inverses); + auto lookup_inverses = View(lookup_relation.template get_lookup_inverse_polynomial(in)); constexpr size_t NUM_TOTAL_TERMS = READ_TERMS + WRITE_TERMS; std::array lookup_terms; diff --git a/barretenberg/cpp/src/barretenberg/relations/databus_lookup_relation.hpp b/barretenberg/cpp/src/barretenberg/relations/databus_lookup_relation.hpp index da659a321e9d..eb8c426b3558 100644 --- a/barretenberg/cpp/src/barretenberg/relations/databus_lookup_relation.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/databus_lookup_relation.hpp @@ -42,6 +42,17 @@ template class DatabusLookupRelationImpl { return (row.q_busread == 1 || row.calldata_read_counts > 0); } + /** + * @brief Get the lookup inverse polynomial + * + * @tparam AllEntities + * @param in + * @return auto& + */ + template static auto& get_lookup_inverse_polynomial(AllEntities& in) + { + return in.lookup_inverses; + } /** * @brief Compute the Accumulator whose values indicate whether the inverse is computed or not * @details This is needed for efficiency since we don't need to compute the inverse unless the log derivative diff --git a/barretenberg/cpp/src/barretenberg/relations/ecc_vm/ecc_lookup_relation.hpp b/barretenberg/cpp/src/barretenberg/relations/ecc_vm/ecc_lookup_relation.hpp index 35af59f74902..d032f5647d37 100644 --- a/barretenberg/cpp/src/barretenberg/relations/ecc_vm/ecc_lookup_relation.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/ecc_vm/ecc_lookup_relation.hpp @@ -30,6 +30,18 @@ template class ECCVMLookupRelationImpl { return (row.msm_add == 1) || (row.msm_skew == 1) || (row.precompute_select == 1); } + /** + * @brief Get the inverse lookup polynomial + * + * @tparam AllEntities + * @param in + * @return auto& + */ + template static auto& get_lookup_inverse_polynomial(AllEntities& in) + { + return in.lookup_inverses; + } + template static Accumulator compute_inverse_exists(const AllEntities& in) { From d2a1d1924633d6f9ca7720d51ed5fffa3b13a9a7 Mon Sep 17 00:00:00 2001 From: Rumata888 Date: Mon, 27 Nov 2023 17:01:51 +0000 Subject: [PATCH 02/15] Basic case --- .../src/barretenberg/flavor/avm_template.hpp | 388 ++++++++++++++++++ .../honk/proof_system/lookup_library.hpp | 96 ++++- .../avm_template_circuit_builder.hpp | 132 ++++++ .../avm_template_circuit_builder.test.cpp | 40 ++ .../generic_permutation_relation.cpp | 36 ++ .../generic_permutation_relation.hpp | 118 ++++++ .../relations/databus_lookup_relation.hpp | 4 +- .../relations/ecc_vm/ecc_lookup_relation.hpp | 4 +- 8 files changed, 811 insertions(+), 7 deletions(-) create mode 100644 barretenberg/cpp/src/barretenberg/flavor/avm_template.hpp create mode 100644 barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/avm_templates/avm_template_circuit_builder.hpp create mode 100644 barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/avm_templates/avm_template_circuit_builder.test.cpp create mode 100644 barretenberg/cpp/src/barretenberg/relations/avm_templates/generic_permutation_relation.cpp create mode 100644 barretenberg/cpp/src/barretenberg/relations/avm_templates/generic_permutation_relation.hpp diff --git a/barretenberg/cpp/src/barretenberg/flavor/avm_template.hpp b/barretenberg/cpp/src/barretenberg/flavor/avm_template.hpp new file mode 100644 index 000000000000..73e4eec2372e --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/flavor/avm_template.hpp @@ -0,0 +1,388 @@ +#pragma once +#include "barretenberg/commitment_schemes/commitment_key.hpp" +#include "barretenberg/commitment_schemes/kzg/kzg.hpp" +#include "barretenberg/ecc/curves/bn254/bn254.hpp" +#include "barretenberg/flavor/flavor.hpp" +#include "barretenberg/polynomials/univariate.hpp" +#include "barretenberg/relations/avm_templates/generic_permutation_relation.hpp" +#include "barretenberg/relations/relation_parameters.hpp" +#include "barretenberg/relations/relation_types.hpp" +#include "relation_definitions_fwd.hpp" +#include +#include +#include +#include +#include +#include + +// NOLINTBEGIN(cppcoreguidelines-avoid-const-or-ref-data-members) + +namespace proof_system::honk { +namespace flavor { + +class AVMTemplate { + public: + using Curve = curve::BN254; + using FF = Curve::ScalarField; + using GroupElement = Curve::Element; + using Commitment = Curve::AffineElement; + using CommitmentHandle = Curve::AffineElement; + using PCS = pcs::kzg::KZG; + using Polynomial = barretenberg::Polynomial; + using PolynomialHandle = std::span; + using CommitmentKey = pcs::CommitmentKey; + using VerifierCommitmentKey = pcs::VerifierCommitmentKey; + + static constexpr size_t NUM_WIRES = 2; + + // 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 = 5; + // 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 = 2; + // The total number of witness entities not including shifts. + static constexpr size_t NUM_WITNESS_ENTITIES = 3; + + // define the tuple of Relations that comprise the Sumcheck relation + using Relations = std::tuple>; + + static constexpr size_t MAX_PARTIAL_RELATION_LENGTH = compute_max_partial_relation_length(); + + // BATCHED_RELATION_PARTIAL_LENGTH = algebraic degree of sumcheck relation *after* multiplying by the `pow_zeta` + // random polynomial e.g. For \sum(x) [A(x) * B(x) + C(x)] * PowZeta(X), relation length = 2 and random relation + // length = 3 + static constexpr size_t BATCHED_RELATION_PARTIAL_LENGTH = MAX_PARTIAL_RELATION_LENGTH + 1; + static constexpr size_t NUM_RELATIONS = std::tuple_size::value; + + // Instantiate the BarycentricData needed to extend each Relation Univariate + + // define the containers for storing the contributions from each relation in Sumcheck + using SumcheckTupleOfTuplesOfUnivariates = decltype(create_sumcheck_tuple_of_tuples_of_univariates()); + using TupleOfArraysOfValues = decltype(create_tuple_of_arrays_of_values()); + + private: + /** + * @brief A base class labelling precomputed entities and (ordered) subsets of interest. + * @details Used to build the proving key and verification key. + */ + template + class PrecomputedEntities : public PrecomputedEntities_ { + public: + DataType lagrange_first; // column 0 + DataType enable_set_permutation; // column 1 + + DEFINE_POINTER_VIEW(NUM_PRECOMPUTED_ENTITIES, &lagrange_first) + + std::vector get_selectors() override { return { lagrange_first }; }; + std::vector get_sigma_polynomials() override { return {}; }; + std::vector get_id_polynomials() override { return {}; }; + std::vector get_table_polynomials() { return {}; }; + }; + + /** + * @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 WitnessEntities_ { + public: + DataType column_0; // column 0 + DataType column_1; // column 1 + DataType permutation_inverses; // column 2 + + DEFINE_POINTER_VIEW(NUM_WITNESS_ENTITIES, &column_0, &column_1, &permutation_inverses) + std::vector get_wires() override { return { column_0, column_1 }; }; + // The sorted concatenations of table and witness data needed for plookup. + std::vector get_sorted_polynomials() { return {}; }; + }; + + /** + * @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. + */ + template + class AllEntities : public AllEntities_ { + public: + DataType lagrange_first; // column 0 + DataType enable_set_permutation; // column 0 + DataType permutation_set_column_1; // column 1 + DataType permutation_set_column_2; // column 2 + DataType permutation_inverses; // column 3 + + // defines a method pointer_view that returns the following, with const and non-const variants + DEFINE_POINTER_VIEW(NUM_ALL_ENTITIES, + &lagrange_first, + &enable_set_permutation, + &permutation_set_column_1, + &permutation_set_column_2, + &permutation_inverses) + std::vector get_wires() override + { + return { + permutation_set_column_1, + permutation_set_column_2, + }; + }; + // Gemini-specific getters. + std::vector get_unshifted() override + { + return { + lagrange_first, enable_set_permutation, permutation_set_column_1, + permutation_set_column_2, permutation_inverses, + }; + }; + + std::vector get_to_be_shifted() override { return {}; }; + std::vector get_shifted() override { return {}; }; + }; + + 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 + * from ProvingKey. + */ + class ProvingKey : public ProvingKey_, + WitnessEntities> { + public: + // Expose constructors on the base class + using Base = ProvingKey_, + WitnessEntities>; + using Base::Base; + + // The plookup wires that store plookup read data. + std::array get_table_column_wires() { return {}; }; + }; + + /** + * @brief The verification key is responsible for storing the the commitments to the precomputed (non-witnessk) + * polynomials used by the verifier. + * + * @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. + */ + using VerificationKey = VerificationKey_>; + + /** + * @brief A container for polynomials produced after the first round of sumcheck. + * @todo TODO(#394) Use polynomial classes for guaranteed memory alignment. + */ + using FoldedPolynomials = AllEntities, PolynomialHandle>; + + /** + * @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; + }; + + /** + * @brief An owning container of polynomials. + * @warning When this was introduced it broke some of our design principles. + * - Execution trace builders don't handle "polynomials" because the interpretation of the execution trace columns + * as polynomials is a detail of the proving system, and trace builders are (sometimes in practice, always in + * principle) reusable for different proving protocols (e.g., Plonk and Honk). + * - Polynomial storage is handled by key classes. Polynomials aren't moved, but are accessed elsewhere by + * std::spans. + * + * We will consider revising this data model: TODO(https://github.com/AztecProtocol/barretenberg/issues/743) + */ + class AllPolynomials : public AllEntities { + public: + [[nodiscard]] size_t get_polynomial_size() const { return this->lagrange_first.size(); } + AllValues get_row(const size_t row_idx) const + { + AllValues result; + for (auto [result_field, polynomial] : zip_view(result.pointer_view(), this->pointer_view())) { + *result_field = (*polynomial)[row_idx]; + } + return result; + } + }; + /** + * @brief A container for polynomials produced after the first round of sumcheck. + * @todo TODO(#394) Use polynomial classes for guaranteed memory alignment. + */ + using RowPolynomials = AllEntities; + + /** + * @brief A container for storing the partially evaluated multivariates produced by sumcheck. + */ + class PartiallyEvaluatedMultivariates : public AllEntities { + + public: + PartiallyEvaluatedMultivariates() = default; + PartiallyEvaluatedMultivariates(const size_t circuit_size) + { + // Storage is only needed after the first partial evaluation, hence polynomials of size (n / 2) + for (auto* poly : this->pointer_view()) { + *poly = Polynomial(circuit_size / 2); + } + } + }; + + /** + * @brief A container for univariates used during sumcheck. + */ + template + using ProverUnivariates = AllEntities, barretenberg::Univariate>; + + /** + * @brief A container for univariates produced during the hot loop in sumcheck. + */ + using ExtendedEdges = ProverUnivariates; + + /** + * @brief A container for the prover polynomials handles; only stores spans. + */ + class ProverPolynomials : public AllEntities { + public: + /** + * @brief Returns the evaluations of all prover polynomials at one point on the boolean hypercube, which + * represents one row in the execution trace. + */ + AllValues get_row(const size_t row_idx) + { + AllValues result; + for (auto [result_field, polynomial] : zip_view(result.pointer_view(), this->pointer_view())) { + *result_field = (*polynomial)[row_idx]; + } + return result; + } + }; + + /** + * @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 { + private: + using Base = AllEntities; + + public: + CommitmentLabels() + : AllEntities() + { + Base::permutation_set_column_1 = "PERMUTATION_SET_COLUMN_1"; + Base::permutation_set_column_2 = "PERMUTATION_SET_COLUMN_2"; + Base::permutation_inverses = "PERMUTATION_INVERSES"; + // The ones beginning with "__" are only used for debugging + Base::lagrange_first = "__LAGRANGE_FIRST"; + Base::enable_set_permutation = "__ENABLE_SET_PERMUTATION"; + }; + }; + + class VerifierCommitments : public AllEntities { + private: + using Base = AllEntities; + + public: + VerifierCommitments(const std::shared_ptr& verification_key, + [[maybe_unused]] const BaseTranscript& transcript) + { + static_cast(transcript); + Base::lagrange_first = verification_key->lagrange_first; + } + }; + + /** + * @brief Derived class that defines proof structure for ECCVM proofs, as well as supporting functions. + * + */ + class Transcript : public BaseTranscript { + public: + uint32_t circuit_size; + Commitment column_0_comm; + Commitment column_1_comm; + Commitment permutation_inverses_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) + {} + + void deserialize_full_transcript() override + { + // take current proof and put them into the struct + size_t num_bytes_read = 0; + circuit_size = BaseTranscript::template deserialize_from_buffer( + BaseTranscript::proof_data, num_bytes_read); + size_t log_n = numeric::get_msb(circuit_size); + column_0_comm = BaseTranscript::template deserialize_from_buffer( + BaseTranscript::proof_data, num_bytes_read); + column_1_comm = BaseTranscript::template deserialize_from_buffer( + BaseTranscript::proof_data, num_bytes_read); + permutation_inverses_comm = BaseTranscript::template 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>( + proof_data, num_bytes_read)); + } + sumcheck_evaluations = + deserialize_from_buffer>(proof_data, num_bytes_read); + for (size_t i = 0; i < log_n; ++i) { + zm_cq_comms.push_back(deserialize_from_buffer(proof_data, num_bytes_read)); + } + zm_cq_comm = deserialize_from_buffer(proof_data, num_bytes_read); + zm_pi_comm = deserialize_from_buffer(proof_data, num_bytes_read); + } + + void serialize_full_transcript() override + { + size_t old_proof_length = BaseTranscript::proof_data.size(); + BaseTranscript::proof_data.clear(); + size_t log_n = numeric::get_msb(circuit_size); + + BaseTranscript::template serialize_to_buffer(circuit_size, BaseTranscript::proof_data); + BaseTranscript::template serialize_to_buffer(column_0_comm, BaseTranscript::proof_data); + BaseTranscript::template serialize_to_buffer(column_1_comm, BaseTranscript::proof_data); + BaseTranscript::template serialize_to_buffer(permutation_inverses_comm, BaseTranscript::proof_data); + for (size_t i = 0; i < log_n; ++i) { + BaseTranscript::template serialize_to_buffer(sumcheck_univariates[i], proof_data); + } + BaseTranscript::template serialize_to_buffer(sumcheck_evaluations, proof_data); + for (size_t i = 0; i < log_n; ++i) { + BaseTranscript::template serialize_to_buffer(zm_cq_comms[i], proof_data); + } + BaseTranscript::template serialize_to_buffer(zm_cq_comm, proof_data); + BaseTranscript::template serialize_to_buffer(zm_pi_comm, proof_data); + + // sanity check to make sure we generate the same length of proof as before. + ASSERT(proof_data.size() == old_proof_length); + } + }; +}; + +// NOLINTEND(cppcoreguidelines-avoid-const-or-ref-data-members) + +} // namespace flavor +namespace sumcheck { + +extern template class GenericPermutationRelationImpl; + +DECLARE_SUMCHECK_RELATION_CLASS(GenericPermutationRelationImpl, flavor::AVMTemplate); + +} // namespace sumcheck +} // namespace proof_system::honk diff --git a/barretenberg/cpp/src/barretenberg/honk/proof_system/lookup_library.hpp b/barretenberg/cpp/src/barretenberg/honk/proof_system/lookup_library.hpp index c6e629db0782..e047e5fb419e 100644 --- a/barretenberg/cpp/src/barretenberg/honk/proof_system/lookup_library.hpp +++ b/barretenberg/cpp/src/barretenberg/honk/proof_system/lookup_library.hpp @@ -31,10 +31,10 @@ void compute_logderivative_inverse(Polynomials& polynomials, auto& relation_para constexpr size_t WRITE_TERMS = Relation::WRITE_TERMS; auto lookup_relation = Relation(); - auto& inverse_polynomial = lookup_relation.template get_lookup_inverse_polynomial(polynomials); + auto& inverse_polynomial = lookup_relation.template get_inverse_polynomial(polynomials); for (size_t i = 0; i < circuit_size; ++i) { auto row = polynomials.get_row(i); - bool has_inverse = lookup_relation.lookup_exists_at_row(row); + bool has_inverse = lookup_relation.operation_exists_at_row(row); if (!has_inverse) { continue; } @@ -97,7 +97,7 @@ void accumulate_logderivative_lookup_subrelation_contributions(ContainerOverSubr using Accumulator = typename std::tuple_element_t<0, ContainerOverSubrelations>; using View = typename Accumulator::View; - auto lookup_inverses = View(lookup_relation.template get_lookup_inverse_polynomial(in)); + auto lookup_inverses = View(lookup_relation.template get_inverse_polynomial(in)); constexpr size_t NUM_TOTAL_TERMS = READ_TERMS + WRITE_TERMS; std::array lookup_terms; @@ -153,4 +153,94 @@ void accumulate_logderivative_lookup_subrelation_contributions(ContainerOverSubr }); } +/** + * @brief Compute generic log-derivative set permutation subrelation accumulation + * @details The generic log-derivative lookup relation consistes of two subrelations. The first demonstrates that the + * inverse polynomial I, defined via I = 1/[(read_term) * (write_term)], has been computed correctly. The second + * establishes the correctness of the lookups themselves based on the log-derivative lookup argument. Note that the + * latter subrelation is "linearly dependent" in the sense that it establishes that a sum across all rows of the + * execution trace is zero, rather than that some expression holds independently at each row. Accordingly, this + * subrelation is not multiplied by a scaling factor at each accumulation step. The subrelation expressions are + * respectively: + * + * I * (read_term) * (write_term) - 1 = 0 + * + * \sum_{i=0}^{n-1} [q_{logderiv_enabler} * I * write_term + I * read_term] = 0 + * + * The explicit expressions for read_term and write_term are dependent upon the particular structure of the lookup being + * performed and methods for computing them must be defined in the corresponding relation class. + * + * @tparam FF + * @tparam Relation + * @tparam ContainerOverSubrelations + * @tparam AllEntities + * @tparam Parameters + * @param accumulator + * @param in + * @param params + * @param scaling_factor + */ +template +void accumulate_logderivative_permutation_subrelation_contributions(ContainerOverSubrelations& accumulator, + const AllEntities& in, + const Parameters& params, + const FF& scaling_factor) +{ + constexpr size_t READ_TERMS = Relation::READ_TERMS; + constexpr size_t WRITE_TERMS = Relation::WRITE_TERMS; + static_assert(READ_TERMS == 1); + static_assert(WRITE_TERMS == 1); + + auto permutation_relation = Relation(); + + using Accumulator = typename std::tuple_element_t<0, ContainerOverSubrelations>; + using View = typename Accumulator::View; + + auto permutation_inverses = View(permutation_relation.template get_inverse_polynomial(in)); + + constexpr size_t NUM_TOTAL_TERMS = 2; + std::array permutation_terms; + std::array denominator_accumulator; + + // The lookup relation = \sum_j (1 / read_term[j]) - \sum_k (read_counts[k] / write_term[k]) + // To get the inverses (1 / read_term[i]), (1 / write_term[i]), we have a commitment to the product of all inverses + // i.e. lookup_inverse = \prod_j (1 / read_term[j]) * \prod_k (1 / write_term[k]) + // The purpose of this next section is to derive individual inverse terms using `lookup_inverses` + // i.e. (1 / read_term[i]) = lookup_inverse * \prod_{j /ne i} (read_term[j]) * \prod_k (write_term[k]) + // (1 / write_term[i]) = lookup_inverse * \prod_j (read_term[j]) * \prod_{k ne i} (write_term[k]) + permutation_terms[0] = permutation_relation.template compute_read_term(in, params); + permutation_terms[1] = permutation_relation.template compute_write_term(in, params); + + barretenberg::constexpr_for<0, NUM_TOTAL_TERMS, 1>( + [&]() { denominator_accumulator[i] = permutation_terms[i]; }); + + barretenberg::constexpr_for<0, NUM_TOTAL_TERMS - 1, 1>( + [&]() { denominator_accumulator[i + 1] *= denominator_accumulator[i]; }); + + auto inverse_accumulator = Accumulator(permutation_inverses); // denominator_accumulator[NUM_TOTAL_TERMS - 1]; + + const auto inverse_exists = permutation_relation.template compute_inverse_exists(in); + + // Note: the lookup_inverses are computed so that the value is 0 if !inverse_exists + std::get<0>(accumulator) += + (denominator_accumulator[NUM_TOTAL_TERMS - 1] * permutation_inverses - inverse_exists) * scaling_factor; + + // After this algo, total degree of denominator_accumulator = NUM_TOTAL_TERMS + for (size_t i = 0; i < NUM_TOTAL_TERMS - 1; ++i) { + denominator_accumulator[NUM_TOTAL_TERMS - 1 - i] = + denominator_accumulator[NUM_TOTAL_TERMS - 2 - i] * inverse_accumulator; + inverse_accumulator = inverse_accumulator * permutation_terms[NUM_TOTAL_TERMS - 1 - i]; + } + denominator_accumulator[0] = inverse_accumulator; + + // each predicate is degree-1 + // degree of relation at this point = NUM_TOTAL_TERMS + 1 + std::get<1>(accumulator) += + permutation_relation.template compute_read_term_predicate(in) * denominator_accumulator[0]; + + // each predicate is degree-1, `lookup_read_counts` is degree-1 + // degree of relation = NUM_TOTAL_TERMS + 2 + std::get<1>(accumulator) -= + permutation_relation.template compute_write_term_predicate(in) * denominator_accumulator[1]; +} } // namespace proof_system::honk::lookup_library \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/avm_templates/avm_template_circuit_builder.hpp b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/avm_templates/avm_template_circuit_builder.hpp new file mode 100644 index 000000000000..bb65f86e0a2f --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/avm_templates/avm_template_circuit_builder.hpp @@ -0,0 +1,132 @@ +#pragma once + +#include "barretenberg/ecc/curves/bn254/fr.hpp" +#include "barretenberg/flavor/avm_template.hpp" +#include "barretenberg/honk/proof_system/lookup_library.hpp" +#include "barretenberg/relations/relation_parameters.hpp" + +namespace proof_system { + +template class AVMTemplateCircuitBuilder { + public: + using FF = typename Flavor::FF; + using Polynomial = typename Flavor::Polynomial; + + static constexpr size_t NUM_POLYNOMIALS = Flavor::NUM_ALL_ENTITIES; + static constexpr size_t NUM_WIRES = Flavor::NUM_WIRES; + + using AllPolynomials = typename Flavor::AllPolynomials; + size_t num_gates = 0; + std::array, NUM_WIRES> wires; + AVMTemplateCircuitBuilder() = default; + + void add_row(const std::array row) + { + for (size_t i = 0; i < NUM_WIRES; i++) { + wires[i].emplace_back(row[i]); + } + num_gates = wires[0].size(); + } + + /** + * @brief Compute the AVM Template flavor polynomial data required to generate a proof + * + * @return AllPolynomials + */ + AllPolynomials compute_polynomials() + { + + const auto num_gates_log2 = static_cast(numeric::get_msb64(num_gates)); + size_t num_gates_pow2 = 1UL << (num_gates_log2 + (1UL << num_gates_log2 == num_gates ? 0 : 1)); + + AllPolynomials polys; + for (auto* poly : polys.pointer_view()) { + *poly = Polynomial(num_gates_pow2); + } + + polys.lagrange_first[0] = 1; + + for (size_t i = 0; i < num_gates; ++i) { + polys.permutation_set_column_1[i] = wires[0][i]; + polys.permutation_set_column_2[i] = wires[1][i]; + polys.enable_set_permutation[i] = 1; + } + return polys; + } + + bool check_circuit() + { + const FF gamma = FF::random_element(); + const FF beta = FF::random_element(); + const FF beta_sqr = beta.sqr(); + const FF beta_cube = beta_sqr * beta; + proof_system::RelationParameters params{ + .eta = 0, + .beta = beta, + .gamma = gamma, + .public_input_delta = 0, + .lookup_grand_product_delta = 0, + .beta_sqr = beta_sqr, + .beta_cube = beta_cube, + .eccvm_set_permutation_delta = 0, + }; + + auto polynomials = compute_polynomials(); + const size_t num_rows = polynomials.get_polynomial_size(); + proof_system::honk::lookup_library:: + compute_logderivative_inverse>( + polynomials, params, num_rows); + + // const auto evaluate_relation = [&](const std::string& relation_name) { + // typename Relation::SumcheckArrayOfValuesOverSubrelations result; + // for (auto& r : result) { + // r = 0; + // } + // constexpr size_t NUM_SUBRELATIONS = result.size(); + + // for (size_t i = 0; i < num_rows; ++i) { + // Relation::accumulate(result, polynomials.get_row(i), params, 1); + + // bool x = true; + // for (size_t j = 0; j < NUM_SUBRELATIONS; ++j) { + // if (result[j] != 0) { + // info("Relation ", relation_name, ", subrelation index ", j, " failed at row ", i); + // x = false; + // } + // } + // if (!x) { + // return false; + // } + // } + // return true; + // }; + + using PermutationRelation = honk::sumcheck::GenericPermutationRelation; + typename honk::sumcheck::GenericPermutationRelation::SumcheckArrayOfValuesOverSubrelations + permutation_result; + for (auto& r : permutation_result) { + r = 0; + } + for (size_t i = 0; i < num_rows; ++i) { + PermutationRelation::accumulate(permutation_result, polynomials.get_row(i), params, 1); + } + for (auto r : permutation_result) { + if (r != 0) { + info("Relation GenericPermutationRelation failed."); + return false; + } + } + return true; + } + + [[nodiscard]] size_t get_num_gates() const { return num_gates; } + + [[nodiscard]] size_t get_circuit_subgroup_size(const size_t num_rows) const + { + + const auto num_rows_log2 = static_cast(numeric::get_msb64(num_rows)); + size_t num_rows_pow2 = 1UL << (num_rows_log2 + (1UL << num_rows_log2 == num_rows ? 0 : 1)); + return num_rows_pow2; + } +}; +} // namespace proof_system diff --git a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/avm_templates/avm_template_circuit_builder.test.cpp b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/avm_templates/avm_template_circuit_builder.test.cpp new file mode 100644 index 000000000000..73e269193561 --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/avm_templates/avm_template_circuit_builder.test.cpp @@ -0,0 +1,40 @@ +#include "avm_template_circuit_builder.hpp" +#include "barretenberg/crypto/generators/generator_data.hpp" +#include "barretenberg/crypto/pedersen_commitment/pedersen.hpp" +#include + +using namespace barretenberg; + +namespace { +auto& engine = numeric::random::get_debug_engine(); +} + +namespace avm_template_circuit_builder_tests { + +template class AVMTemplateCircuitBuilderTests : public ::testing::Test {}; + +using FlavorTypes = ::testing::Types; +TYPED_TEST_SUITE(AVMTemplateCircuitBuilderTests, FlavorTypes); + +TYPED_TEST(AVMTemplateCircuitBuilderTests, BaseCase) +{ + using Flavor = TypeParam; + using FF = typename Flavor::FF; + + proof_system::AVMTemplateCircuitBuilder circuit_builder; + + std::vector column_0; + for (size_t i = 0; i < 16; i++) { + column_0.emplace_back(FF::random_element()); + } + for (size_t i = 0; i < 16; i++) { + circuit_builder.add_row({ column_0[i], column_0[15 - i] }); + } + + bool result = circuit_builder.check_circuit(); + EXPECT_EQ(result, true); + circuit_builder.wires[0][5] = FF::random_element(); + result = circuit_builder.check_circuit(); + EXPECT_EQ(result, false); +} +} // namespace avm_template_circuit_builder_tests \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/relations/avm_templates/generic_permutation_relation.cpp b/barretenberg/cpp/src/barretenberg/relations/avm_templates/generic_permutation_relation.cpp new file mode 100644 index 000000000000..28d1eecbb621 --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/relations/avm_templates/generic_permutation_relation.cpp @@ -0,0 +1,36 @@ +#include "generic_permutation_relation.hpp" +#include "barretenberg/flavor/avm_template.hpp" +#include "barretenberg/flavor/relation_definitions_fwd.hpp" +#include "barretenberg/honk/proof_system/lookup_library.hpp" + +namespace proof_system::honk::sumcheck { + +/** + * @brief Expression for ECCVM lookup tables. + * @details We use log-derivative lookup tables for the following case: + * Table writes: ECCVMPointTable columns: we define Straus point table: + * { {0, -15[P]}, {1, -13[P]}, ..., {15, 15[P]} } + * write source: { precompute_round, precompute_tx, precompute_ty } + * Table reads: ECCVMMSM columns. Each row adds up to 4 points into MSM accumulator + * read source: { msm_slice1, msm_x1, msm_y1 }, ..., { msm_slice4, msm_x4, msm_y4 } + * @param evals transformed to `evals + C(in(X)...)*scaling_factor` + * @param in an std::array containing the fully extended Accumulator edges. + * @param parameters contains beta, gamma, and public_input_delta, .... + * @param scaling_factor optional term to scale the evaluation before adding to evals. + */ +template +template +void GenericPermutationRelationImpl::accumulate(ContainerOverSubrelations& accumulator, + const AllEntities& in, + const Parameters& params, + const FF& scaling_factor) +{ + lookup_library::accumulate_logderivative_permutation_subrelation_contributions>( + accumulator, in, params, scaling_factor); +} + +template class GenericPermutationRelationImpl; +DEFINE_SUMCHECK_RELATION_CLASS(GenericPermutationRelationImpl, flavor::AVMTemplate); + +} // namespace proof_system::honk::sumcheck diff --git a/barretenberg/cpp/src/barretenberg/relations/avm_templates/generic_permutation_relation.hpp b/barretenberg/cpp/src/barretenberg/relations/avm_templates/generic_permutation_relation.hpp new file mode 100644 index 000000000000..76bc4f646316 --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/relations/avm_templates/generic_permutation_relation.hpp @@ -0,0 +1,118 @@ +#pragma once +#include +#include + +#include "barretenberg/common/constexpr_utils.hpp" +#include "barretenberg/polynomials/polynomial.hpp" +#include "barretenberg/polynomials/univariate.hpp" +#include "barretenberg/relations/relation_types.hpp" + +namespace proof_system::honk::sumcheck { + +template class GenericPermutationRelationImpl { + public: + using FF = FF_; + static constexpr size_t READ_TERMS = 1; + static constexpr size_t WRITE_TERMS = 1; + // 1 + polynomial degree of this relation + static constexpr size_t LENGTH = READ_TERMS + WRITE_TERMS + 3; // 9 + + static constexpr std::array SUBRELATION_PARTIAL_LENGTHS{ + LENGTH, // grand product construction sub-relation + LENGTH // left-shiftable polynomial sub-relation + }; + + static constexpr std::array SUBRELATION_LINEARLY_INDEPENDENT = { true, false }; + + template static bool operation_exists_at_row(const AllValues& row) + + { + return (row.enable_set_permutation == 1); + } + + /** + * @brief Get the inverse permutation polynomial + * + * @tparam AllEntities + * @param in + * @return auto& + */ + template static auto& get_inverse_polynomial(AllEntities& in) + { + return in.permutation_inverses; + } + + template + static Accumulator compute_inverse_exists(const AllEntities& in) + { + using View = typename Accumulator::View; + + return Accumulator(View(in.enable_set_permutation)); + } + + template + static Accumulator compute_read_term_predicate(const AllEntities& in) + + { + static_assert(read_index < WRITE_TERMS); + using View = typename Accumulator::View; + + return Accumulator(View(in.enable_set_permutation)); + } + + template + static Accumulator compute_write_term_predicate(const AllEntities& in) + { + static_assert(write_index < WRITE_TERMS); + using View = typename Accumulator::View; + + return Accumulator(View(in.enable_set_permutation)); + } + + template + static Accumulator compute_write_term(const AllEntities& in, const Parameters& params) + { + using View = typename Accumulator::View; + + static_assert(write_index < WRITE_TERMS); + + const auto& permutation_set_1 = View(in.permutation_set_column_1); + const auto& gamma = params.gamma; + return permutation_set_1 + gamma; + } + + template + static Accumulator compute_read_term(const AllEntities& in, const Parameters& params) + { + using View = typename Accumulator::View; + + // read term: + static_assert(read_index < READ_TERMS); + const auto& permutation_set_2 = View(in.permutation_set_column_2); + const auto& gamma = params.gamma; + return permutation_set_2 + gamma; + } + + /** + * @brief Expression for ECCVM lookup tables. + * @details We use log-derivative lookup tables for the following case: + * Table writes: ECCVMPointTable columns: we define Straus point table: + * { {0, -15[P]}, {1, -13[P]}, ..., {15, 15[P]} } + * write source: { precompute_round, precompute_tx, precompute_ty } + * Table reads: ECCVMMSM columns. Each row adds up to 4 points into MSM accumulator + * read source: { msm_slice1, msm_x1, msm_y1 }, ..., { msm_slice4, msm_x4, msm_y4 } + * @param accumulator transformed to `evals + C(in(X)...)*scaling_factor` + * @param in an std::array containing the fully extended Accumulator edges. + * @param relation_params contains beta, gamma, and public_input_delta, .... + * @param scaling_factor optional term to scale the evaluation before adding to evals. + */ + template + static void accumulate(ContainerOverSubrelations& accumulator, + const AllEntities& in, + const Parameters& params, + const FF& scaling_factor); +}; + +template using GenericPermutationRelation = Relation>; + +} // namespace proof_system::honk::sumcheck diff --git a/barretenberg/cpp/src/barretenberg/relations/databus_lookup_relation.hpp b/barretenberg/cpp/src/barretenberg/relations/databus_lookup_relation.hpp index eb8c426b3558..719611d1433d 100644 --- a/barretenberg/cpp/src/barretenberg/relations/databus_lookup_relation.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/databus_lookup_relation.hpp @@ -37,7 +37,7 @@ template class DatabusLookupRelationImpl { * @return true * @return false */ - template static bool lookup_exists_at_row(const AllValues& row) + template static bool operation_exists_at_row(const AllValues& row) { return (row.q_busread == 1 || row.calldata_read_counts > 0); } @@ -49,7 +49,7 @@ template class DatabusLookupRelationImpl { * @param in * @return auto& */ - template static auto& get_lookup_inverse_polynomial(AllEntities& in) + template static auto& get_inverse_polynomial(AllEntities& in) { return in.lookup_inverses; } diff --git a/barretenberg/cpp/src/barretenberg/relations/ecc_vm/ecc_lookup_relation.hpp b/barretenberg/cpp/src/barretenberg/relations/ecc_vm/ecc_lookup_relation.hpp index d032f5647d37..e2270790e473 100644 --- a/barretenberg/cpp/src/barretenberg/relations/ecc_vm/ecc_lookup_relation.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/ecc_vm/ecc_lookup_relation.hpp @@ -24,7 +24,7 @@ template class ECCVMLookupRelationImpl { static constexpr std::array SUBRELATION_LINEARLY_INDEPENDENT = { true, false }; - template static bool lookup_exists_at_row(const AllValues& row) + template static bool operation_exists_at_row(const AllValues& row) { return (row.msm_add == 1) || (row.msm_skew == 1) || (row.precompute_select == 1); @@ -37,7 +37,7 @@ template class ECCVMLookupRelationImpl { * @param in * @return auto& */ - template static auto& get_lookup_inverse_polynomial(AllEntities& in) + template static auto& get_inverse_polynomial(AllEntities& in) { return in.lookup_inverses; } From 262a76cb0e39afca52a4644c5b9508e7d68a295f Mon Sep 17 00:00:00 2001 From: Rumata888 Date: Mon, 27 Nov 2023 18:11:16 +0000 Subject: [PATCH 03/15] Generic log-derivative-based permutations --- .../src/barretenberg/flavor/avm_template.hpp | 45 ++++++++++++++----- .../avm_template_circuit_builder.hpp | 2 + .../avm_template_circuit_builder.test.cpp | 4 +- .../generic_permutation_relation.hpp | 20 +++++++-- 4 files changed, 54 insertions(+), 17 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/flavor/avm_template.hpp b/barretenberg/cpp/src/barretenberg/flavor/avm_template.hpp index 73e4eec2372e..28931da33000 100644 --- a/barretenberg/cpp/src/barretenberg/flavor/avm_template.hpp +++ b/barretenberg/cpp/src/barretenberg/flavor/avm_template.hpp @@ -33,17 +33,17 @@ class AVMTemplate { using CommitmentKey = pcs::CommitmentKey; using VerifierCommitmentKey = pcs::VerifierCommitmentKey; - static constexpr size_t NUM_WIRES = 2; + static constexpr size_t NUM_WIRES = 4; // 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 = 5; + static constexpr size_t NUM_ALL_ENTITIES = 7; // 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 = 2; // The total number of witness entities not including shifts. - static constexpr size_t NUM_WITNESS_ENTITIES = 3; + static constexpr size_t NUM_WITNESS_ENTITIES = 5; // define the tuple of Relations that comprise the Sumcheck relation using Relations = std::tuple>; @@ -88,12 +88,24 @@ class AVMTemplate { template class WitnessEntities : public WitnessEntities_ { public: - DataType column_0; // column 0 - DataType column_1; // column 1 - DataType permutation_inverses; // column 2 + DataType permutation_set_column_1; // column 0 + DataType permutation_set_column_2; // column 1 + DataType permutation_set_column_3; // column 1 + DataType permutation_set_column_4; // column 1 + DataType permutation_inverses; // column 2 - DEFINE_POINTER_VIEW(NUM_WITNESS_ENTITIES, &column_0, &column_1, &permutation_inverses) - std::vector get_wires() override { return { column_0, column_1 }; }; + DEFINE_POINTER_VIEW(NUM_WITNESS_ENTITIES, + &permutation_set_column_1, + &permutation_set_column_2, + &permutation_set_column_3, + &permutation_set_column_4, + &permutation_inverses) + std::vector get_wires() override + { + return { + permutation_set_column_1, permutation_set_column_2, permutation_set_column_3, permutation_set_column_4 + }; + }; // The sorted concatenations of table and witness data needed for plookup. std::vector get_sorted_polynomials() { return {}; }; }; @@ -114,6 +126,8 @@ class AVMTemplate { DataType enable_set_permutation; // column 0 DataType permutation_set_column_1; // column 1 DataType permutation_set_column_2; // column 2 + DataType permutation_set_column_3; // column 2 + DataType permutation_set_column_4; // column 2 DataType permutation_inverses; // column 3 // defines a method pointer_view that returns the following, with const and non-const variants @@ -122,20 +136,21 @@ class AVMTemplate { &enable_set_permutation, &permutation_set_column_1, &permutation_set_column_2, + &permutation_set_column_3, + &permutation_set_column_4, &permutation_inverses) std::vector get_wires() override { return { - permutation_set_column_1, - permutation_set_column_2, + permutation_set_column_1, permutation_set_column_2, permutation_set_column_3, permutation_set_column_4 }; }; // Gemini-specific getters. std::vector get_unshifted() override { return { - lagrange_first, enable_set_permutation, permutation_set_column_1, - permutation_set_column_2, permutation_inverses, + lagrange_first, enable_set_permutation, permutation_set_column_1, permutation_set_column_2, + permutation_set_column_3, permutation_set_column_4, permutation_inverses, }; }; @@ -278,6 +293,8 @@ class AVMTemplate { { Base::permutation_set_column_1 = "PERMUTATION_SET_COLUMN_1"; Base::permutation_set_column_2 = "PERMUTATION_SET_COLUMN_2"; + Base::permutation_set_column_3 = "PERMUTATION_SET_COLUMN_3"; + Base::permutation_set_column_4 = "PERMUTATION_SET_COLUMN_4"; Base::permutation_inverses = "PERMUTATION_INVERSES"; // The ones beginning with "__" are only used for debugging Base::lagrange_first = "__LAGRANGE_FIRST"; @@ -323,6 +340,8 @@ class AVMTemplate { void deserialize_full_transcript() override { + // TODO + abort(); // take current proof and put them into the struct size_t num_bytes_read = 0; circuit_size = BaseTranscript::template deserialize_from_buffer( @@ -351,6 +370,8 @@ class AVMTemplate { void serialize_full_transcript() override { + // TODO + abort(); size_t old_proof_length = BaseTranscript::proof_data.size(); BaseTranscript::proof_data.clear(); size_t log_n = numeric::get_msb(circuit_size); diff --git a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/avm_templates/avm_template_circuit_builder.hpp b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/avm_templates/avm_template_circuit_builder.hpp index bb65f86e0a2f..b7fabe7dedbb 100644 --- a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/avm_templates/avm_template_circuit_builder.hpp +++ b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/avm_templates/avm_template_circuit_builder.hpp @@ -49,6 +49,8 @@ template class AVMTemplateCircuitBuilder { for (size_t i = 0; i < num_gates; ++i) { polys.permutation_set_column_1[i] = wires[0][i]; polys.permutation_set_column_2[i] = wires[1][i]; + polys.permutation_set_column_3[i] = wires[2][i]; + polys.permutation_set_column_4[i] = wires[3][i]; polys.enable_set_permutation[i] = 1; } return polys; diff --git a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/avm_templates/avm_template_circuit_builder.test.cpp b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/avm_templates/avm_template_circuit_builder.test.cpp index 73e269193561..d2ebea7d1395 100644 --- a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/avm_templates/avm_template_circuit_builder.test.cpp +++ b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/avm_templates/avm_template_circuit_builder.test.cpp @@ -24,11 +24,13 @@ TYPED_TEST(AVMTemplateCircuitBuilderTests, BaseCase) proof_system::AVMTemplateCircuitBuilder circuit_builder; std::vector column_0; + std::vector column_1; for (size_t i = 0; i < 16; i++) { column_0.emplace_back(FF::random_element()); + column_1.emplace_back(FF::random_element()); } for (size_t i = 0; i < 16; i++) { - circuit_builder.add_row({ column_0[i], column_0[15 - i] }); + circuit_builder.add_row({ column_0[i], column_1[i], column_0[15 - i], column_1[15 - i] }); } bool result = circuit_builder.check_circuit(); diff --git a/barretenberg/cpp/src/barretenberg/relations/avm_templates/generic_permutation_relation.hpp b/barretenberg/cpp/src/barretenberg/relations/avm_templates/generic_permutation_relation.hpp index 76bc4f646316..a19577b318c4 100644 --- a/barretenberg/cpp/src/barretenberg/relations/avm_templates/generic_permutation_relation.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/avm_templates/generic_permutation_relation.hpp @@ -27,6 +27,7 @@ template class GenericPermutationRelationImpl { template static bool operation_exists_at_row(const AllValues& row) { + // WIRE/SELECTOR enabling the permutation return (row.enable_set_permutation == 1); } @@ -76,9 +77,14 @@ template class GenericPermutationRelationImpl { static_assert(write_index < WRITE_TERMS); - const auto& permutation_set_1 = View(in.permutation_set_column_1); + const auto write_term_entities = + std::forward_as_tuple(View(in.permutation_set_column_1), View(in.permutation_set_column_2)); + auto result = Accumulator(0); + constexpr size_t tuple_size = std::tuple_size_v; + barretenberg::constexpr_for<0, tuple_size, 1>( + [&]() { result = result * params.beta + std::get(write_term_entities); }); const auto& gamma = params.gamma; - return permutation_set_1 + gamma; + return result + gamma; } template @@ -88,9 +94,15 @@ template class GenericPermutationRelationImpl { // read term: static_assert(read_index < READ_TERMS); - const auto& permutation_set_2 = View(in.permutation_set_column_2); + const auto read_term_entitites = + std::forward_as_tuple(View(in.permutation_set_column_3), View(in.permutation_set_column_4)); + auto result = Accumulator(0); + constexpr size_t tuple_size = std::tuple_size_v; + barretenberg::constexpr_for<0, tuple_size, 1>( + [&]() { result = result * params.beta + std::get(read_term_entitites); }); + const auto& gamma = params.gamma; - return permutation_set_2 + gamma; + return result + gamma; } /** From 087799eaf260138086b4b847379290f0f43e6116 Mon Sep 17 00:00:00 2001 From: Rumata888 Date: Tue, 28 Nov 2023 14:00:13 +0000 Subject: [PATCH 04/15] File rename --- .../cpp/src/barretenberg/eccvm/eccvm_prover.cpp | 4 ++-- ...okup_library.hpp => logderivative_library.hpp} | 4 ++-- .../avm_template_circuit_builder.hpp | 4 ++-- .../eccvm/eccvm_circuit_builder.hpp | 8 ++++---- .../generic_permutation_relation.cpp | 8 ++++---- .../relations/databus_lookup_relation.hpp | 15 ++++++--------- .../relations/ecc_vm/ecc_lookup_relation.cpp | 4 ++-- .../sumcheck/instance/prover_instance.cpp | 4 ++-- 8 files changed, 24 insertions(+), 27 deletions(-) rename barretenberg/cpp/src/barretenberg/honk/proof_system/{lookup_library.hpp => logderivative_library.hpp} (99%) diff --git a/barretenberg/cpp/src/barretenberg/eccvm/eccvm_prover.cpp b/barretenberg/cpp/src/barretenberg/eccvm/eccvm_prover.cpp index 16d3f3a9cfba..ca7da74e38fe 100644 --- a/barretenberg/cpp/src/barretenberg/eccvm/eccvm_prover.cpp +++ b/barretenberg/cpp/src/barretenberg/eccvm/eccvm_prover.cpp @@ -2,7 +2,7 @@ #include "barretenberg/commitment_schemes/claim.hpp" #include "barretenberg/commitment_schemes/commitment_key.hpp" #include "barretenberg/common/ref_array.hpp" -#include "barretenberg/honk/proof_system/lookup_library.hpp" +#include "barretenberg/honk/proof_system/logderivative_library.hpp" #include "barretenberg/honk/proof_system/permutation_library.hpp" #include "barretenberg/honk/proof_system/power_polynomial.hpp" #include "barretenberg/polynomials/polynomial.hpp" @@ -183,7 +183,7 @@ template void ECCVMProver_::execute_log_derivative_ gamma * (gamma + beta_sqr) * (gamma + beta_sqr + beta_sqr) * (gamma + beta_sqr + beta_sqr + beta_sqr); relation_parameters.eccvm_set_permutation_delta = relation_parameters.eccvm_set_permutation_delta.invert(); // Compute inverse polynomial for our logarithmic-derivative lookup method - lookup_library::compute_logderivative_inverse( + logderivative_library::compute_logderivative_inverse( prover_polynomials, relation_parameters, key->circuit_size); transcript->send_to_verifier(commitment_labels.lookup_inverses, commitment_key->commit(key->lookup_inverses)); prover_polynomials.lookup_inverses = key->lookup_inverses; diff --git a/barretenberg/cpp/src/barretenberg/honk/proof_system/lookup_library.hpp b/barretenberg/cpp/src/barretenberg/honk/proof_system/logderivative_library.hpp similarity index 99% rename from barretenberg/cpp/src/barretenberg/honk/proof_system/lookup_library.hpp rename to barretenberg/cpp/src/barretenberg/honk/proof_system/logderivative_library.hpp index e047e5fb419e..1f9307def306 100644 --- a/barretenberg/cpp/src/barretenberg/honk/proof_system/lookup_library.hpp +++ b/barretenberg/cpp/src/barretenberg/honk/proof_system/logderivative_library.hpp @@ -1,7 +1,7 @@ #pragma once #include -namespace proof_system::honk::lookup_library { +namespace proof_system::honk::logderivative_library { /** * @brief Compute the inverse polynomial I(X) required for logderivative lookups @@ -243,4 +243,4 @@ void accumulate_logderivative_permutation_subrelation_contributions(ContainerOve std::get<1>(accumulator) -= permutation_relation.template compute_write_term_predicate(in) * denominator_accumulator[1]; } -} // namespace proof_system::honk::lookup_library \ No newline at end of file +} // namespace proof_system::honk::logderivative_library \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/avm_templates/avm_template_circuit_builder.hpp b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/avm_templates/avm_template_circuit_builder.hpp index b7fabe7dedbb..a3d2811a3737 100644 --- a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/avm_templates/avm_template_circuit_builder.hpp +++ b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/avm_templates/avm_template_circuit_builder.hpp @@ -2,7 +2,7 @@ #include "barretenberg/ecc/curves/bn254/fr.hpp" #include "barretenberg/flavor/avm_template.hpp" -#include "barretenberg/honk/proof_system/lookup_library.hpp" +#include "barretenberg/honk/proof_system/logderivative_library.hpp" #include "barretenberg/relations/relation_parameters.hpp" namespace proof_system { @@ -75,7 +75,7 @@ template class AVMTemplateCircuitBuilder { auto polynomials = compute_polynomials(); const size_t num_rows = polynomials.get_polynomial_size(); - proof_system::honk::lookup_library:: + proof_system::honk::logderivative_library:: compute_logderivative_inverse>( polynomials, params, num_rows); diff --git a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/eccvm/eccvm_circuit_builder.hpp b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/eccvm/eccvm_circuit_builder.hpp index 4abbd5bc91f0..bdcbd4fa4add 100644 --- a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/eccvm/eccvm_circuit_builder.hpp +++ b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/eccvm/eccvm_circuit_builder.hpp @@ -7,7 +7,7 @@ #include "barretenberg/ecc/curves/bn254/fr.hpp" #include "barretenberg/ecc/curves/grumpkin/grumpkin.hpp" #include "barretenberg/flavor/ecc_vm.hpp" -#include "barretenberg/honk/proof_system/lookup_library.hpp" +#include "barretenberg/honk/proof_system/logderivative_library.hpp" #include "barretenberg/honk/proof_system/permutation_library.hpp" #include "barretenberg/proof_system/op_queue/ecc_op_queue.hpp" #include "barretenberg/relations/relation_parameters.hpp" @@ -505,9 +505,9 @@ template class ECCVMCircuitBuilder { auto polynomials = compute_polynomials(); const size_t num_rows = polynomials.get_polynomial_size(); - proof_system::honk::lookup_library::compute_logderivative_inverse>( - polynomials, params, num_rows); + proof_system::honk::logderivative_library:: + compute_logderivative_inverse>( + polynomials, params, num_rows); honk::permutation_library::compute_permutation_grand_product>( num_rows, polynomials, params); diff --git a/barretenberg/cpp/src/barretenberg/relations/avm_templates/generic_permutation_relation.cpp b/barretenberg/cpp/src/barretenberg/relations/avm_templates/generic_permutation_relation.cpp index 28d1eecbb621..c428892370f1 100644 --- a/barretenberg/cpp/src/barretenberg/relations/avm_templates/generic_permutation_relation.cpp +++ b/barretenberg/cpp/src/barretenberg/relations/avm_templates/generic_permutation_relation.cpp @@ -1,7 +1,7 @@ #include "generic_permutation_relation.hpp" #include "barretenberg/flavor/avm_template.hpp" #include "barretenberg/flavor/relation_definitions_fwd.hpp" -#include "barretenberg/honk/proof_system/lookup_library.hpp" +#include "barretenberg/honk/proof_system/logderivative_library.hpp" namespace proof_system::honk::sumcheck { @@ -25,9 +25,9 @@ void GenericPermutationRelationImpl::accumulate(ContainerOverSubrelations& a const Parameters& params, const FF& scaling_factor) { - lookup_library::accumulate_logderivative_permutation_subrelation_contributions>( - accumulator, in, params, scaling_factor); + logderivative_library:: + accumulate_logderivative_permutation_subrelation_contributions>( + accumulator, in, params, scaling_factor); } template class GenericPermutationRelationImpl; diff --git a/barretenberg/cpp/src/barretenberg/relations/databus_lookup_relation.hpp b/barretenberg/cpp/src/barretenberg/relations/databus_lookup_relation.hpp index 719611d1433d..5508a72c292c 100644 --- a/barretenberg/cpp/src/barretenberg/relations/databus_lookup_relation.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/databus_lookup_relation.hpp @@ -3,7 +3,7 @@ #include #include "barretenberg/common/constexpr_utils.hpp" -#include "barretenberg/honk/proof_system/lookup_library.hpp" +#include "barretenberg/honk/proof_system/logderivative_library.hpp" #include "barretenberg/polynomials/polynomial.hpp" #include "barretenberg/polynomials/univariate.hpp" #include "barretenberg/relations/relation_types.hpp" @@ -49,10 +49,7 @@ template class DatabusLookupRelationImpl { * @param in * @return auto& */ - template static auto& get_inverse_polynomial(AllEntities& in) - { - return in.lookup_inverses; - } + template static auto& get_inverse_polynomial(AllEntities& in) { return in.lookup_inverses; } /** * @brief Compute the Accumulator whose values indicate whether the inverse is computed or not * @details This is needed for efficiency since we don't need to compute the inverse unless the log derivative @@ -165,7 +162,7 @@ template class DatabusLookupRelationImpl { /** * @brief Accumulate the contribution from two surelations for the log derivative databus lookup argument - * @details See lookup_library.hpp for details of the generic log-derivative lookup argument + * @details See logderivative_library.hpp for details of the generic log-derivative lookup argument * * @param accumulator transformed to `evals + C(in(X)...)*scaling_factor` * @param in an std::array containing the fully extended Accumulator edges. @@ -178,9 +175,9 @@ template class DatabusLookupRelationImpl { const Parameters& params, const FF& scaling_factor) { - honk::lookup_library::accumulate_logderivative_lookup_subrelation_contributions>( - accumulator, in, params, scaling_factor); + honk::logderivative_library:: + accumulate_logderivative_lookup_subrelation_contributions>( + accumulator, in, params, scaling_factor); } }; diff --git a/barretenberg/cpp/src/barretenberg/relations/ecc_vm/ecc_lookup_relation.cpp b/barretenberg/cpp/src/barretenberg/relations/ecc_vm/ecc_lookup_relation.cpp index 1daf3469bc72..e52e297cfa4e 100644 --- a/barretenberg/cpp/src/barretenberg/relations/ecc_vm/ecc_lookup_relation.cpp +++ b/barretenberg/cpp/src/barretenberg/relations/ecc_vm/ecc_lookup_relation.cpp @@ -1,6 +1,6 @@ #include "barretenberg/flavor/ecc_vm.hpp" #include "barretenberg/flavor/relation_definitions_fwd.hpp" -#include "barretenberg/honk/proof_system/lookup_library.hpp" +#include "barretenberg/honk/proof_system/logderivative_library.hpp" #include "ecc_msm_relation.hpp" namespace proof_system::honk::sumcheck { @@ -25,7 +25,7 @@ void ECCVMLookupRelationImpl::accumulate(ContainerOverSubrelations& accumula const Parameters& params, const FF& scaling_factor) { - lookup_library::accumulate_logderivative_lookup_subrelation_contributions>( + logderivative_library::accumulate_logderivative_lookup_subrelation_contributions>( accumulator, in, params, scaling_factor); } diff --git a/barretenberg/cpp/src/barretenberg/sumcheck/instance/prover_instance.cpp b/barretenberg/cpp/src/barretenberg/sumcheck/instance/prover_instance.cpp index 3a62affd0ace..8e1a6ede9498 100644 --- a/barretenberg/cpp/src/barretenberg/sumcheck/instance/prover_instance.cpp +++ b/barretenberg/cpp/src/barretenberg/sumcheck/instance/prover_instance.cpp @@ -1,5 +1,5 @@ #include "prover_instance.hpp" -#include "barretenberg/honk/proof_system/lookup_library.hpp" +#include "barretenberg/honk/proof_system/logderivative_library.hpp" #include "barretenberg/proof_system/circuit_builder/ultra_circuit_builder.hpp" #include "barretenberg/proof_system/composer/permutation_lib.hpp" #include "barretenberg/proof_system/library/grand_product_delta.hpp" @@ -453,7 +453,7 @@ void ProverInstance_::compute_logderivative_inverse(FF beta, FF gamma) relation_parameters.gamma = gamma; // Compute permutation and lookup grand product polynomials - lookup_library::compute_logderivative_inverse( + logderivative_library::compute_logderivative_inverse( prover_polynomials, relation_parameters, proving_key->circuit_size); } From 3a38cbc07f44b288e021b5e7f47ac81b501d8b51 Mon Sep 17 00:00:00 2001 From: Rumata888 Date: Tue, 28 Nov 2023 16:47:34 +0000 Subject: [PATCH 05/15] Comments in the relation --- .../generic_permutation_relation.hpp | 145 ++++++++++++++---- 1 file changed, 119 insertions(+), 26 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/relations/avm_templates/generic_permutation_relation.hpp b/barretenberg/cpp/src/barretenberg/relations/avm_templates/generic_permutation_relation.hpp index a19577b318c4..2ec1bb93b5bb 100644 --- a/barretenberg/cpp/src/barretenberg/relations/avm_templates/generic_permutation_relation.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/avm_templates/generic_permutation_relation.hpp @@ -1,3 +1,10 @@ +/** + * @file generic_permutation_relation.hpp + * @author Rumata888 + * @brief This file contains an example relation that is used as a basis for generic permutation relations generated + * with PIL + * + */ #pragma once #include #include @@ -12,22 +19,39 @@ namespace proof_system::honk::sumcheck { template class GenericPermutationRelationImpl { public: using FF = FF_; + // Read and write terms counts should stay set to 1 unless we want to permute several columns at once as accumulated + // sets (not as tuples). static constexpr size_t READ_TERMS = 1; static constexpr size_t WRITE_TERMS = 1; // 1 + polynomial degree of this relation - static constexpr size_t LENGTH = READ_TERMS + WRITE_TERMS + 3; // 9 + static constexpr size_t LENGTH = READ_TERMS + WRITE_TERMS + 3; // 5 static constexpr std::array SUBRELATION_PARTIAL_LENGTHS{ - LENGTH, // grand product construction sub-relation - LENGTH // left-shiftable polynomial sub-relation + LENGTH, // inverse polynomial correctness sub-relation + LENGTH // log-derived terms subrelation }; + /** + * @brief We apply the power polynomial only to the first subrelation + * + *@details The first subrelation establishes correspondence between the inverse polynomial elements and the terms. + *The second relation computes the inverses of individual terms, which are then summed up with sumcheck + * + * + */ static constexpr std::array SUBRELATION_LINEARLY_INDEPENDENT = { true, false }; + /** + * @brief Check if we need to compute the inverse polynomial element value for this row + * + * @tparam AllValues + * @param row + */ template static bool operation_exists_at_row(const AllValues& row) { // WIRE/SELECTOR enabling the permutation + // N.B. PIL TEMPLATED VALUE return (row.enable_set_permutation == 1); } @@ -40,17 +64,39 @@ template class GenericPermutationRelationImpl { */ template static auto& get_inverse_polynomial(AllEntities& in) { + // WIRE containing the inverse of the product of terms at this row. Used to reconstruct individual inversed + // terms + // N.B. PIL TEMPLATED VALUE return in.permutation_inverses; } + /** + * @brief Get selector/wire switching on(1) or off(0) inverse computation + * + * @tparam Accumulator + * @tparam AllEntities + * @param in + * @return Accumulator + */ template static Accumulator compute_inverse_exists(const AllEntities& in) { using View = typename Accumulator::View; + // WIRE/SELECTOR enabling the permutation used in the sumcheck computation. This affects the first subrelation + // N.B. PIL TEMPLATED VALUE return Accumulator(View(in.enable_set_permutation)); } + /** + * @brief Compute if the value from the first set exists in this row + * + * @tparam Accumulator + * @tparam read_index Kept for compatibility with lookups, behavior doesn't change + * @tparam AllEntities + * @param in + * @return Accumulator + */ template static Accumulator compute_read_term_predicate(const AllEntities& in) @@ -58,61 +104,108 @@ template class GenericPermutationRelationImpl { static_assert(read_index < WRITE_TERMS); using View = typename Accumulator::View; + // The selector/wire value that determines that an element from the first set needs to be included. Can be + // different from the wire used in the write part. + // N.B. PIL TEMPLATED VALUE return Accumulator(View(in.enable_set_permutation)); } + /** + * @brief Compute if the value from the second set exists in this row + * + * @tparam Accumulator + * @tparam write_index Kept for compatibility with lookups, behavior doesn't change + * @tparam AllEntities + * @param in + * @return Accumulator + */ template static Accumulator compute_write_term_predicate(const AllEntities& in) { static_assert(write_index < WRITE_TERMS); using View = typename Accumulator::View; + // The selector/wire value that determines that an element from the second set needs to be included. Can be + // different from the wire used in the read part. + // N.B. PIL TEMPLATED VALUE return Accumulator(View(in.enable_set_permutation)); } - template - static Accumulator compute_write_term(const AllEntities& in, const Parameters& params) + /** + * @brief Compute the value of a single item in the set + * + * @details Computes the polynomial \gamma + \sum_{i=0}^{num_columns}(column_i*\beta^i), so the tuple of columnes is + * in the first set + * @tparam Accumulator + * @tparam read_index Kept for compatibility with lookups, behavior doesn't change + + * @tparam AllEntities + * @tparam Parameters + * @param in + * @param params Used for beta and gamma + * @return Accumulator + */ + template + static Accumulator compute_read_term(const AllEntities& in, const Parameters& params) { using View = typename Accumulator::View; - static_assert(write_index < WRITE_TERMS); + static_assert(read_index < READ_TERMS); + + // The tuple of columns a single row of which represents a single element of the first set (we are doing a + // permutation of tuples). The length is 1+ + // N.B. PIL TEMPLATED VALUE + const auto read_term_entitites = + std::forward_as_tuple(View(in.permutation_set_column_3), View(in.permutation_set_column_4)); - const auto write_term_entities = - std::forward_as_tuple(View(in.permutation_set_column_1), View(in.permutation_set_column_2)); auto result = Accumulator(0); - constexpr size_t tuple_size = std::tuple_size_v; + constexpr size_t tuple_size = std::tuple_size_v; + // Iterate over tuple and sum as a polynomial over beta barretenberg::constexpr_for<0, tuple_size, 1>( - [&]() { result = result * params.beta + std::get(write_term_entities); }); + [&]() { result = result * params.beta + std::get(read_term_entitites); }); + const auto& gamma = params.gamma; return result + gamma; } - template - static Accumulator compute_read_term(const AllEntities& in, const Parameters& params) + /** + * @brief Compute the value of a single item in the set + * + * @details Computes the polynomial \gamma + \sum_{i=0}^{num_columns}(column_i*\beta^i), so the tuple of columnes is + * in the second set + * + * @tparam Accumulator + * @tparam write_index Kept for compatibility with lookups, behavior doesn't change + * @tparam AllEntities + * @tparam Parameters + * @param in + * @param params + * @return Accumulator + */ + template + static Accumulator compute_write_term(const AllEntities& in, const Parameters& params) { using View = typename Accumulator::View; - // read term: - static_assert(read_index < READ_TERMS); - const auto read_term_entitites = - std::forward_as_tuple(View(in.permutation_set_column_3), View(in.permutation_set_column_4)); + static_assert(write_index < WRITE_TERMS); + + // The tuple of columns a single row of which represents a single element of the second set (we are doing a + // permutation of tuples). The length is 1+ + // N.B. PIL TEMPLATED VALUE + const auto write_term_entities = + std::forward_as_tuple(View(in.permutation_set_column_1), View(in.permutation_set_column_2)); auto result = Accumulator(0); - constexpr size_t tuple_size = std::tuple_size_v; - barretenberg::constexpr_for<0, tuple_size, 1>( - [&]() { result = result * params.beta + std::get(read_term_entitites); }); + constexpr size_t tuple_size = std::tuple_size_v; + // Iterate over tuple and sum as a polynomial over beta + barretenberg::constexpr_for<0, tuple_size, 1>( + [&]() { result = result * params.beta + std::get(write_term_entities); }); const auto& gamma = params.gamma; return result + gamma; } /** - * @brief Expression for ECCVM lookup tables. - * @details We use log-derivative lookup tables for the following case: - * Table writes: ECCVMPointTable columns: we define Straus point table: - * { {0, -15[P]}, {1, -13[P]}, ..., {15, 15[P]} } - * write source: { precompute_round, precompute_tx, precompute_ty } - * Table reads: ECCVMMSM columns. Each row adds up to 4 points into MSM accumulator - * read source: { msm_slice1, msm_x1, msm_y1 }, ..., { msm_slice4, msm_x4, msm_y4 } + * @brief Expression for generic log-derivative-based set permutation. * @param accumulator transformed to `evals + C(in(X)...)*scaling_factor` * @param in an std::array containing the fully extended Accumulator edges. * @param relation_params contains beta, gamma, and public_input_delta, .... From 26dec330302e5b0eaf84e86eb7c819fe7af60005 Mon Sep 17 00:00:00 2001 From: Rumata888 Date: Tue, 28 Nov 2023 16:50:57 +0000 Subject: [PATCH 06/15] A few more small updates --- .../generic_permutation_relation.hpp | 35 +++---------------- 1 file changed, 5 insertions(+), 30 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/relations/avm_templates/generic_permutation_relation.hpp b/barretenberg/cpp/src/barretenberg/relations/avm_templates/generic_permutation_relation.hpp index 2ec1bb93b5bb..a15849d411b1 100644 --- a/barretenberg/cpp/src/barretenberg/relations/avm_templates/generic_permutation_relation.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/avm_templates/generic_permutation_relation.hpp @@ -37,15 +37,13 @@ template class GenericPermutationRelationImpl { *@details The first subrelation establishes correspondence between the inverse polynomial elements and the terms. *The second relation computes the inverses of individual terms, which are then summed up with sumcheck * - * */ static constexpr std::array SUBRELATION_LINEARLY_INDEPENDENT = { true, false }; /** * @brief Check if we need to compute the inverse polynomial element value for this row * - * @tparam AllValues - * @param row + * @param row All values at row */ template static bool operation_exists_at_row(const AllValues& row) @@ -58,9 +56,6 @@ template class GenericPermutationRelationImpl { /** * @brief Get the inverse permutation polynomial * - * @tparam AllEntities - * @param in - * @return auto& */ template static auto& get_inverse_polynomial(AllEntities& in) { @@ -73,10 +68,6 @@ template class GenericPermutationRelationImpl { /** * @brief Get selector/wire switching on(1) or off(0) inverse computation * - * @tparam Accumulator - * @tparam AllEntities - * @param in - * @return Accumulator */ template static Accumulator compute_inverse_exists(const AllEntities& in) @@ -91,11 +82,7 @@ template class GenericPermutationRelationImpl { /** * @brief Compute if the value from the first set exists in this row * - * @tparam Accumulator * @tparam read_index Kept for compatibility with lookups, behavior doesn't change - * @tparam AllEntities - * @param in - * @return Accumulator */ template static Accumulator compute_read_term_predicate(const AllEntities& in) @@ -113,11 +100,7 @@ template class GenericPermutationRelationImpl { /** * @brief Compute if the value from the second set exists in this row * - * @tparam Accumulator * @tparam write_index Kept for compatibility with lookups, behavior doesn't change - * @tparam AllEntities - * @param in - * @return Accumulator */ template static Accumulator compute_write_term_predicate(const AllEntities& in) @@ -136,14 +119,10 @@ template class GenericPermutationRelationImpl { * * @details Computes the polynomial \gamma + \sum_{i=0}^{num_columns}(column_i*\beta^i), so the tuple of columnes is * in the first set - * @tparam Accumulator + * * @tparam read_index Kept for compatibility with lookups, behavior doesn't change - - * @tparam AllEntities - * @tparam Parameters - * @param in + * * @param params Used for beta and gamma - * @return Accumulator */ template static Accumulator compute_read_term(const AllEntities& in, const Parameters& params) @@ -174,13 +153,9 @@ template class GenericPermutationRelationImpl { * @details Computes the polynomial \gamma + \sum_{i=0}^{num_columns}(column_i*\beta^i), so the tuple of columnes is * in the second set * - * @tparam Accumulator * @tparam write_index Kept for compatibility with lookups, behavior doesn't change - * @tparam AllEntities - * @tparam Parameters - * @param in - * @param params - * @return Accumulator + * + * @param params Used for beta and gamma */ template static Accumulator compute_write_term(const AllEntities& in, const Parameters& params) From b4a3ee7fec3fd683336a0b30689d68d1fc919734 Mon Sep 17 00:00:00 2001 From: Rumata888 Date: Tue, 28 Nov 2023 17:16:26 +0000 Subject: [PATCH 07/15] LIbrary update --- .../src/barretenberg/flavor/avm_template.hpp | 22 ++++++++-------- .../proof_system/logderivative_library.hpp | 26 +++++++++++-------- 2 files changed, 26 insertions(+), 22 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/flavor/avm_template.hpp b/barretenberg/cpp/src/barretenberg/flavor/avm_template.hpp index 28931da33000..75a871ab5247 100644 --- a/barretenberg/cpp/src/barretenberg/flavor/avm_template.hpp +++ b/barretenberg/cpp/src/barretenberg/flavor/avm_template.hpp @@ -90,9 +90,9 @@ class AVMTemplate { public: DataType permutation_set_column_1; // column 0 DataType permutation_set_column_2; // column 1 - DataType permutation_set_column_3; // column 1 - DataType permutation_set_column_4; // column 1 - DataType permutation_inverses; // column 2 + DataType permutation_set_column_3; // column 2 + DataType permutation_set_column_4; // column 3 + DataType permutation_inverses; // column 4 DEFINE_POINTER_VIEW(NUM_WITNESS_ENTITIES, &permutation_set_column_1, @@ -123,12 +123,12 @@ class AVMTemplate { class AllEntities : public AllEntities_ { public: DataType lagrange_first; // column 0 - DataType enable_set_permutation; // column 0 - DataType permutation_set_column_1; // column 1 - DataType permutation_set_column_2; // column 2 - DataType permutation_set_column_3; // column 2 - DataType permutation_set_column_4; // column 2 - DataType permutation_inverses; // column 3 + DataType enable_set_permutation; // column 1 + DataType permutation_set_column_1; // column 2 + DataType permutation_set_column_2; // column 3 + DataType permutation_set_column_3; // column 4 + DataType permutation_set_column_4; // column 5 + DataType permutation_inverses; // column 6 // defines a method pointer_view that returns the following, with const and non-const variants DEFINE_POINTER_VIEW(NUM_ALL_ENTITIES, @@ -340,7 +340,7 @@ class AVMTemplate { void deserialize_full_transcript() override { - // TODO + // TODO. Codepath is dead for now, becaused there is no composer abort(); // take current proof and put them into the struct size_t num_bytes_read = 0; @@ -370,7 +370,7 @@ class AVMTemplate { void serialize_full_transcript() override { - // TODO + // TODO. Codepath is dead for now, becaused there is no composer abort(); size_t old_proof_length = BaseTranscript::proof_data.size(); BaseTranscript::proof_data.clear(); diff --git a/barretenberg/cpp/src/barretenberg/honk/proof_system/logderivative_library.hpp b/barretenberg/cpp/src/barretenberg/honk/proof_system/logderivative_library.hpp index 1f9307def306..5c37b0884c0c 100644 --- a/barretenberg/cpp/src/barretenberg/honk/proof_system/logderivative_library.hpp +++ b/barretenberg/cpp/src/barretenberg/honk/proof_system/logderivative_library.hpp @@ -157,18 +157,20 @@ void accumulate_logderivative_lookup_subrelation_contributions(ContainerOverSubr * @brief Compute generic log-derivative set permutation subrelation accumulation * @details The generic log-derivative lookup relation consistes of two subrelations. The first demonstrates that the * inverse polynomial I, defined via I = 1/[(read_term) * (write_term)], has been computed correctly. The second - * establishes the correctness of the lookups themselves based on the log-derivative lookup argument. Note that the + * establishes the correctness of the permutation itself based on the log-derivative argument. Note that the * latter subrelation is "linearly dependent" in the sense that it establishes that a sum across all rows of the * execution trace is zero, rather than that some expression holds independently at each row. Accordingly, this * subrelation is not multiplied by a scaling factor at each accumulation step. The subrelation expressions are * respectively: * - * I * (read_term) * (write_term) - 1 = 0 + * I * (read_term) * (write_term) - q_{permutation_enabler} = 0 * - * \sum_{i=0}^{n-1} [q_{logderiv_enabler} * I * write_term + I * read_term] = 0 + * \sum_{i=0}^{n-1} [q_{write_enabler} * I * write_term + q_{read_enabler} * I * read_term] = 0 * - * The explicit expressions for read_term and write_term are dependent upon the particular structure of the lookup being - * performed and methods for computing them must be defined in the corresponding relation class. + * The explicit expressions for read_term and write_term are dependent upon the particular structure of the permutation + * being performed and methods for computing them must be defined in the corresponding relation class. The entities + * which are used to determine the use of permutation (is it enabled, is the first "read" set enabled, is the second + * "write" set enabled) must be defined in the relation class. * * @tparam FF * @tparam Relation @@ -188,6 +190,8 @@ void accumulate_logderivative_permutation_subrelation_contributions(ContainerOve { constexpr size_t READ_TERMS = Relation::READ_TERMS; constexpr size_t WRITE_TERMS = Relation::WRITE_TERMS; + + // For now we only do simple permutations over tuples with 1 read and 1 write term static_assert(READ_TERMS == 1); static_assert(WRITE_TERMS == 1); @@ -202,12 +206,12 @@ void accumulate_logderivative_permutation_subrelation_contributions(ContainerOve std::array permutation_terms; std::array denominator_accumulator; - // The lookup relation = \sum_j (1 / read_term[j]) - \sum_k (read_counts[k] / write_term[k]) - // To get the inverses (1 / read_term[i]), (1 / write_term[i]), we have a commitment to the product of all inverses - // i.e. lookup_inverse = \prod_j (1 / read_term[j]) * \prod_k (1 / write_term[k]) - // The purpose of this next section is to derive individual inverse terms using `lookup_inverses` - // i.e. (1 / read_term[i]) = lookup_inverse * \prod_{j /ne i} (read_term[j]) * \prod_k (write_term[k]) - // (1 / write_term[i]) = lookup_inverse * \prod_j (read_term[j]) * \prod_{k ne i} (write_term[k]) + // The permutation relation = 1 / read_term - 1 / write_term + // To get the inverses (1 / read_term), (1 / write_term), we have a commitment to the product ofinver ses + // i.e. permutation_inverses = (1 / read_term) * (1 / write_term) + // The purpose of this next section is to derive individual inverse terms using `permutation_inverses` + // i.e. (1 / read_term) = permutation_inverse * write_term + // (1 / write_term) = permutation_inverse * read_term permutation_terms[0] = permutation_relation.template compute_read_term(in, params); permutation_terms[1] = permutation_relation.template compute_write_term(in, params); From d8e4c7898fdfe845a2b24353da072851734b5a1a Mon Sep 17 00:00:00 2001 From: Rumata888 Date: Tue, 28 Nov 2023 17:32:24 +0000 Subject: [PATCH 08/15] Small updates --- .../proof_system/logderivative_library.hpp | 8 ++-- .../avm_template_circuit_builder.hpp | 42 +++++++------------ .../avm_template_circuit_builder.test.cpp | 3 ++ .../generic_permutation_relation.cpp | 12 ++---- 4 files changed, 24 insertions(+), 41 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/honk/proof_system/logderivative_library.hpp b/barretenberg/cpp/src/barretenberg/honk/proof_system/logderivative_library.hpp index 5c37b0884c0c..4a86cf74075d 100644 --- a/barretenberg/cpp/src/barretenberg/honk/proof_system/logderivative_library.hpp +++ b/barretenberg/cpp/src/barretenberg/honk/proof_system/logderivative_library.hpp @@ -210,8 +210,8 @@ void accumulate_logderivative_permutation_subrelation_contributions(ContainerOve // To get the inverses (1 / read_term), (1 / write_term), we have a commitment to the product ofinver ses // i.e. permutation_inverses = (1 / read_term) * (1 / write_term) // The purpose of this next section is to derive individual inverse terms using `permutation_inverses` - // i.e. (1 / read_term) = permutation_inverse * write_term - // (1 / write_term) = permutation_inverse * read_term + // i.e. (1 / read_term) = permutation_inverses * write_term + // (1 / write_term) = permutation_inverses * read_term permutation_terms[0] = permutation_relation.template compute_read_term(in, params); permutation_terms[1] = permutation_relation.template compute_write_term(in, params); @@ -242,8 +242,8 @@ void accumulate_logderivative_permutation_subrelation_contributions(ContainerOve std::get<1>(accumulator) += permutation_relation.template compute_read_term_predicate(in) * denominator_accumulator[0]; - // each predicate is degree-1, `lookup_read_counts` is degree-1 - // degree of relation = NUM_TOTAL_TERMS + 2 + // each predicate is degree-1 + // degree of relation = NUM_TOTAL_TERMS + 1 std::get<1>(accumulator) -= permutation_relation.template compute_write_term_predicate(in) * denominator_accumulator[1]; } diff --git a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/avm_templates/avm_template_circuit_builder.hpp b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/avm_templates/avm_template_circuit_builder.hpp index a3d2811a3737..ed5cfda2c7a9 100644 --- a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/avm_templates/avm_template_circuit_builder.hpp +++ b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/avm_templates/avm_template_circuit_builder.hpp @@ -1,3 +1,9 @@ +/** + * @file avm_template_circuit_builder.hpp + * @author Rumata888 + * @brief A circuit builder for the AVM toy version used to showcase permutation and lookup mechanisms for PIL + * + */ #pragma once #include "barretenberg/ecc/curves/bn254/fr.hpp" @@ -51,25 +57,29 @@ template class AVMTemplateCircuitBuilder { polys.permutation_set_column_2[i] = wires[1][i]; polys.permutation_set_column_3[i] = wires[2][i]; polys.permutation_set_column_4[i] = wires[3][i]; + // By default the permutation is over all rows where we place data polys.enable_set_permutation[i] = 1; } return polys; } + /** + * @brief Check that the circuit is correct (proof should work) + * + */ bool check_circuit() { + // For now only gamma and beta are used const FF gamma = FF::random_element(); const FF beta = FF::random_element(); - const FF beta_sqr = beta.sqr(); - const FF beta_cube = beta_sqr * beta; proof_system::RelationParameters params{ .eta = 0, .beta = beta, .gamma = gamma, .public_input_delta = 0, .lookup_grand_product_delta = 0, - .beta_sqr = beta_sqr, - .beta_cube = beta_cube, + .beta_sqr = 0, + .beta_cube = 0, .eccvm_set_permutation_delta = 0, }; @@ -79,30 +89,6 @@ template class AVMTemplateCircuitBuilder { compute_logderivative_inverse>( polynomials, params, num_rows); - // const auto evaluate_relation = [&](const std::string& relation_name) { - // typename Relation::SumcheckArrayOfValuesOverSubrelations result; - // for (auto& r : result) { - // r = 0; - // } - // constexpr size_t NUM_SUBRELATIONS = result.size(); - - // for (size_t i = 0; i < num_rows; ++i) { - // Relation::accumulate(result, polynomials.get_row(i), params, 1); - - // bool x = true; - // for (size_t j = 0; j < NUM_SUBRELATIONS; ++j) { - // if (result[j] != 0) { - // info("Relation ", relation_name, ", subrelation index ", j, " failed at row ", i); - // x = false; - // } - // } - // if (!x) { - // return false; - // } - // } - // return true; - // }; - using PermutationRelation = honk::sumcheck::GenericPermutationRelation; typename honk::sumcheck::GenericPermutationRelation::SumcheckArrayOfValuesOverSubrelations permutation_result; diff --git a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/avm_templates/avm_template_circuit_builder.test.cpp b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/avm_templates/avm_template_circuit_builder.test.cpp index d2ebea7d1395..fedf897ef01d 100644 --- a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/avm_templates/avm_template_circuit_builder.test.cpp +++ b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/avm_templates/avm_template_circuit_builder.test.cpp @@ -30,11 +30,14 @@ TYPED_TEST(AVMTemplateCircuitBuilderTests, BaseCase) column_1.emplace_back(FF::random_element()); } for (size_t i = 0; i < 16; i++) { + // Put the same values but in inverse order circuit_builder.add_row({ column_0[i], column_1[i], column_0[15 - i], column_1[15 - i] }); } + // Test that the permutation with correct values works bool result = circuit_builder.check_circuit(); EXPECT_EQ(result, true); + // And that it fails with incorrct values circuit_builder.wires[0][5] = FF::random_element(); result = circuit_builder.check_circuit(); EXPECT_EQ(result, false); diff --git a/barretenberg/cpp/src/barretenberg/relations/avm_templates/generic_permutation_relation.cpp b/barretenberg/cpp/src/barretenberg/relations/avm_templates/generic_permutation_relation.cpp index c428892370f1..b41486dd9902 100644 --- a/barretenberg/cpp/src/barretenberg/relations/avm_templates/generic_permutation_relation.cpp +++ b/barretenberg/cpp/src/barretenberg/relations/avm_templates/generic_permutation_relation.cpp @@ -6,16 +6,10 @@ namespace proof_system::honk::sumcheck { /** - * @brief Expression for ECCVM lookup tables. - * @details We use log-derivative lookup tables for the following case: - * Table writes: ECCVMPointTable columns: we define Straus point table: - * { {0, -15[P]}, {1, -13[P]}, ..., {15, 15[P]} } - * write source: { precompute_round, precompute_tx, precompute_ty } - * Table reads: ECCVMMSM columns. Each row adds up to 4 points into MSM accumulator - * read source: { msm_slice1, msm_x1, msm_y1 }, ..., { msm_slice4, msm_x4, msm_y4 } - * @param evals transformed to `evals + C(in(X)...)*scaling_factor` + * @brief Expression for generic log-derivative-based set permutation. + * @param accumulator transformed to `evals + C(in(X)...)*scaling_factor` * @param in an std::array containing the fully extended Accumulator edges. - * @param parameters contains beta, gamma, and public_input_delta, .... + * @param relation_params contains beta, gamma, and public_input_delta, .... * @param scaling_factor optional term to scale the evaluation before adding to evals. */ template From fd0f20e1610bac911923f010a95305dcb1211eb0 Mon Sep 17 00:00:00 2001 From: Rumata888 Date: Tue, 28 Nov 2023 18:03:41 +0000 Subject: [PATCH 09/15] Format --- .../barretenberg/relations/ecc_vm/ecc_lookup_relation.hpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/relations/ecc_vm/ecc_lookup_relation.hpp b/barretenberg/cpp/src/barretenberg/relations/ecc_vm/ecc_lookup_relation.hpp index e2270790e473..aa3afffc87f0 100644 --- a/barretenberg/cpp/src/barretenberg/relations/ecc_vm/ecc_lookup_relation.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/ecc_vm/ecc_lookup_relation.hpp @@ -37,10 +37,7 @@ template class ECCVMLookupRelationImpl { * @param in * @return auto& */ - template static auto& get_inverse_polynomial(AllEntities& in) - { - return in.lookup_inverses; - } + template static auto& get_inverse_polynomial(AllEntities& in) { return in.lookup_inverses; } template static Accumulator compute_inverse_exists(const AllEntities& in) From b05fe16f94a1258acb625831a68b6ffd53e64726 Mon Sep 17 00:00:00 2001 From: Rumata888 Date: Tue, 5 Dec 2023 18:44:43 +0000 Subject: [PATCH 10/15] Before making circuit builder flavorless --- .../src/barretenberg/flavor/avm_template.hpp | 103 ++++++--- .../avm_template_circuit_builder.hpp | 51 ++++- .../avm_template_circuit_builder.test.cpp | 54 ++++- .../generic_permutation_relation.cpp | 24 +- .../generic_permutation_relation.hpp | 82 ++++--- .../avm_templates/relation_definer.hpp | 213 ++++++++++++++++++ 6 files changed, 425 insertions(+), 102 deletions(-) create mode 100644 barretenberg/cpp/src/barretenberg/relations/avm_templates/relation_definer.hpp diff --git a/barretenberg/cpp/src/barretenberg/flavor/avm_template.hpp b/barretenberg/cpp/src/barretenberg/flavor/avm_template.hpp index 75a871ab5247..54d128e966eb 100644 --- a/barretenberg/cpp/src/barretenberg/flavor/avm_template.hpp +++ b/barretenberg/cpp/src/barretenberg/flavor/avm_template.hpp @@ -5,6 +5,7 @@ #include "barretenberg/flavor/flavor.hpp" #include "barretenberg/polynomials/univariate.hpp" #include "barretenberg/relations/avm_templates/generic_permutation_relation.hpp" +#include "barretenberg/relations/avm_templates/relation_definer.hpp" #include "barretenberg/relations/relation_parameters.hpp" #include "barretenberg/relations/relation_types.hpp" #include "relation_definitions_fwd.hpp" @@ -20,6 +21,11 @@ namespace proof_system::honk { namespace flavor { +/** + * @brief This class provides an example flavor for using GenericPermutationRelations with various settings to make + * integrating those mechanisms into AVM easier + * + */ class AVMTemplate { public: using Curve = curve::BN254; @@ -33,20 +39,23 @@ class AVMTemplate { using CommitmentKey = pcs::CommitmentKey; using VerifierCommitmentKey = pcs::VerifierCommitmentKey; - static constexpr size_t NUM_WIRES = 4; + // The number of wires is 5. The set of tuples (permutation_set_column_1,permutation_set_column_2) should be + // equivalent to (permutation_set_column_3, permutation_set_column_4) and the self_permutation_column contains 2 + // subsets which are permutations of each other + static constexpr size_t NUM_WIRES = 5; // 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 = 7; + static constexpr size_t NUM_ALL_ENTITIES = 12; // 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 = 2; + static constexpr size_t NUM_PRECOMPUTED_ENTITIES = 5; // The total number of witness entities not including shifts. - static constexpr size_t NUM_WITNESS_ENTITIES = 5; + static constexpr size_t NUM_WITNESS_ENTITIES = 7; // define the tuple of Relations that comprise the Sumcheck relation - using Relations = std::tuple>; + using Relations = std::tuple>; static constexpr size_t MAX_PARTIAL_RELATION_LENGTH = compute_max_partial_relation_length(); @@ -70,8 +79,8 @@ class AVMTemplate { template class PrecomputedEntities : public PrecomputedEntities_ { public: - DataType lagrange_first; // column 0 - DataType enable_set_permutation; // column 1 + DataType lagrange_first; // column 0 + DataType enable_tuple_set_permutation; // column 1 DEFINE_POINTER_VIEW(NUM_PRECOMPUTED_ENTITIES, &lagrange_first) @@ -88,23 +97,29 @@ class AVMTemplate { template class WitnessEntities : public WitnessEntities_ { public: - DataType permutation_set_column_1; // column 0 - DataType permutation_set_column_2; // column 1 - DataType permutation_set_column_3; // column 2 - DataType permutation_set_column_4; // column 3 - DataType permutation_inverses; // column 4 + DataType permutation_set_column_1; // column 0 + DataType permutation_set_column_2; // column 1 + DataType permutation_set_column_3; // column 2 + DataType permutation_set_column_4; // column 3 + DataType self_permutation_column; // column 4 + DataType tuple_permutation_inverses; // column 5 + DataType single_permutation_inverses; // column 6 DEFINE_POINTER_VIEW(NUM_WITNESS_ENTITIES, &permutation_set_column_1, &permutation_set_column_2, &permutation_set_column_3, &permutation_set_column_4, - &permutation_inverses) + &self_permutation_column, + &tuple_permutation_inverses, + &single_permutation_inverses) std::vector get_wires() override { - return { - permutation_set_column_1, permutation_set_column_2, permutation_set_column_3, permutation_set_column_4 - }; + return { permutation_set_column_1, + permutation_set_column_2, + permutation_set_column_3, + permutation_set_column_4, + self_permutation_column }; }; // The sorted concatenations of table and witness data needed for plookup. std::vector get_sorted_polynomials() { return {}; }; @@ -122,23 +137,33 @@ class AVMTemplate { template class AllEntities : public AllEntities_ { public: - DataType lagrange_first; // column 0 - DataType enable_set_permutation; // column 1 - DataType permutation_set_column_1; // column 2 - DataType permutation_set_column_2; // column 3 - DataType permutation_set_column_3; // column 4 - DataType permutation_set_column_4; // column 5 - DataType permutation_inverses; // column 6 + DataType lagrange_first; // column 0 + DataType enable_tuple_set_permutation; // column 1 + DataType enable_single_column_permutation; // column 1 + DataType enable_first_set_permutation; // column 1 + DataType enable_second_set_permutation; // column 1 + DataType permutation_set_column_1; // column 0 + DataType permutation_set_column_2; // column 1 + DataType permutation_set_column_3; // column 2 + DataType permutation_set_column_4; // column 3 + DataType self_permutation_column; // column 4 + DataType tuple_permutation_inverses; // column 5 + DataType single_permutation_inverses; // column 6 // defines a method pointer_view that returns the following, with const and non-const variants DEFINE_POINTER_VIEW(NUM_ALL_ENTITIES, &lagrange_first, - &enable_set_permutation, + &enable_tuple_set_permutation, + &enable_single_column_permutation, + &enable_first_set_permutation, + &enable_second_set_permutation, &permutation_set_column_1, &permutation_set_column_2, &permutation_set_column_3, &permutation_set_column_4, - &permutation_inverses) + &self_permutation_column, + &tuple_permutation_inverses, + &single_permutation_inverses) std::vector get_wires() override { return { @@ -148,10 +173,18 @@ class AVMTemplate { // Gemini-specific getters. std::vector get_unshifted() override { - return { - lagrange_first, enable_set_permutation, permutation_set_column_1, permutation_set_column_2, - permutation_set_column_3, permutation_set_column_4, permutation_inverses, - }; + return { lagrange_first, + enable_tuple_set_permutation, + enable_single_column_permutation, + enable_first_set_permutation, + enable_second_set_permutation, + permutation_set_column_1, + permutation_set_column_2, + permutation_set_column_3, + permutation_set_column_4, + self_permutation_column, + tuple_permutation_inverses, + single_permutation_inverses }; }; std::vector get_to_be_shifted() override { return {}; }; @@ -295,10 +328,10 @@ class AVMTemplate { Base::permutation_set_column_2 = "PERMUTATION_SET_COLUMN_2"; Base::permutation_set_column_3 = "PERMUTATION_SET_COLUMN_3"; Base::permutation_set_column_4 = "PERMUTATION_SET_COLUMN_4"; - Base::permutation_inverses = "PERMUTATION_INVERSES"; + Base::tuple_permutation_inverses = "TUPLE_PERMUTATION_INVERSES"; // The ones beginning with "__" are only used for debugging Base::lagrange_first = "__LAGRANGE_FIRST"; - Base::enable_set_permutation = "__ENABLE_SET_PERMUTATION"; + Base::enable_tuple_set_permutation = "__ENABLE_SET_PERMUTATION"; }; }; @@ -340,7 +373,7 @@ class AVMTemplate { void deserialize_full_transcript() override { - // TODO. Codepath is dead for now, becaused there is no composer + // TODO. Codepath is dead for now, because there is no composer abort(); // take current proof and put them into the struct size_t num_bytes_read = 0; @@ -370,7 +403,7 @@ class AVMTemplate { void serialize_full_transcript() override { - // TODO. Codepath is dead for now, becaused there is no composer + // TODO. Codepath is dead for now, because there is no composer abort(); size_t old_proof_length = BaseTranscript::proof_data.size(); BaseTranscript::proof_data.clear(); @@ -401,9 +434,7 @@ class AVMTemplate { } // namespace flavor namespace sumcheck { -extern template class GenericPermutationRelationImpl; - -DECLARE_SUMCHECK_RELATION_CLASS(GenericPermutationRelationImpl, flavor::AVMTemplate); +DECLARE_IMPLEMENTATIONS_FOR_ALL_SETTINGS(GenericPermutationRelationImpl, flavor::AVMTemplate) } // namespace sumcheck } // namespace proof_system::honk diff --git a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/avm_templates/avm_template_circuit_builder.hpp b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/avm_templates/avm_template_circuit_builder.hpp index ed5cfda2c7a9..4c065fb195aa 100644 --- a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/avm_templates/avm_template_circuit_builder.hpp +++ b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/avm_templates/avm_template_circuit_builder.hpp @@ -13,7 +13,7 @@ namespace proof_system { -template class AVMTemplateCircuitBuilder { +template class ToyAVMCircuitBuilder { public: using FF = typename Flavor::FF; using Polynomial = typename Flavor::Polynomial; @@ -24,7 +24,7 @@ template class AVMTemplateCircuitBuilder { using AllPolynomials = typename Flavor::AllPolynomials; size_t num_gates = 0; std::array, NUM_WIRES> wires; - AVMTemplateCircuitBuilder() = default; + ToyAVMCircuitBuilder() = default; void add_row(const std::array row) { @@ -57,8 +57,12 @@ template class AVMTemplateCircuitBuilder { polys.permutation_set_column_2[i] = wires[1][i]; polys.permutation_set_column_3[i] = wires[2][i]; polys.permutation_set_column_4[i] = wires[3][i]; + polys.self_permutation_column[i] = wires[4][i]; // By default the permutation is over all rows where we place data - polys.enable_set_permutation[i] = 1; + polys.enable_tuple_set_permutation[i] = 1; + polys.enable_single_column_permutation[i] = 1; + polys.enable_first_set_permutation[i] = i & 1; + polys.enable_second_set_permutation[i] = 1 - (i & 1); } return polys; } @@ -69,6 +73,7 @@ template class AVMTemplateCircuitBuilder { */ bool check_circuit() { + // using FirstPermutationRelation = typename std::tuple_element_t<0, Flavor::Relations>; // For now only gamma and beta are used const FF gamma = FF::random_element(); const FF beta = FF::random_element(); @@ -85,12 +90,16 @@ template class AVMTemplateCircuitBuilder { auto polynomials = compute_polynomials(); const size_t num_rows = polynomials.get_polynomial_size(); - proof_system::honk::logderivative_library:: - compute_logderivative_inverse>( - polynomials, params, num_rows); - - using PermutationRelation = honk::sumcheck::GenericPermutationRelation; - typename honk::sumcheck::GenericPermutationRelation::SumcheckArrayOfValuesOverSubrelations + // Check the tuple permutation relation + proof_system::honk::logderivative_library::compute_logderivative_inverse< + Flavor, + honk::sumcheck::GenericPermutationRelation>( + polynomials, params, num_rows); + + using PermutationRelation = + honk::sumcheck::GenericPermutationRelation; + typename honk::sumcheck::GenericPermutationRelation::SumcheckArrayOfValuesOverSubrelations permutation_result; for (auto& r : permutation_result) { r = 0; @@ -100,7 +109,29 @@ template class AVMTemplateCircuitBuilder { } for (auto r : permutation_result) { if (r != 0) { - info("Relation GenericPermutationRelation failed."); + info("Tuple GenericPermutationRelation failed."); + return false; + } + } + proof_system::honk::logderivative_library::compute_logderivative_inverse< + Flavor, + honk::sumcheck::GenericPermutationRelation>( + polynomials, params, num_rows); + + using SameWirePermutationRelation = + honk::sumcheck::GenericPermutationRelation; + typename honk::sumcheck::GenericPermutationRelation::SumcheckArrayOfValuesOverSubrelations + second_permutation_result; + for (auto& r : second_permutation_result) { + r = 0; + } + for (size_t i = 0; i < num_rows; ++i) { + SameWirePermutationRelation::accumulate(second_permutation_result, polynomials.get_row(i), params, 1); + } + for (auto r : second_permutation_result) { + if (r != 0) { + info("Same wire GenericPermutationRelation failed."); return false; } } diff --git a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/avm_templates/avm_template_circuit_builder.test.cpp b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/avm_templates/avm_template_circuit_builder.test.cpp index fedf897ef01d..860356851372 100644 --- a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/avm_templates/avm_template_circuit_builder.test.cpp +++ b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/avm_templates/avm_template_circuit_builder.test.cpp @@ -9,37 +9,69 @@ namespace { auto& engine = numeric::random::get_debug_engine(); } -namespace avm_template_circuit_builder_tests { +namespace toy_avm_circuit_builder_tests { -template class AVMTemplateCircuitBuilderTests : public ::testing::Test {}; +template class ToyAVMCircuitBuilderTests : public ::testing::Test {}; using FlavorTypes = ::testing::Types; TYPED_TEST_SUITE(AVMTemplateCircuitBuilderTests, FlavorTypes); -TYPED_TEST(AVMTemplateCircuitBuilderTests, BaseCase) +/** + * @brief A test explaining the work of the permutations in Toy AVM + * + */ +TYPED_TEST(ToyAVMCircuitBuilderTests, BaseCase) { using Flavor = TypeParam; using FF = typename Flavor::FF; - proof_system::AVMTemplateCircuitBuilder circuit_builder; + const size_t circuit_size = 16; + proof_system::ToyAVMCircuitBuilder circuit_builder; + // Sample 2*16 random elements for the tuple permutation example std::vector column_0; std::vector column_1; - for (size_t i = 0; i < 16; i++) { + for (size_t i = 0; i < circuit_size; i++) { column_0.emplace_back(FF::random_element()); column_1.emplace_back(FF::random_element()); } - for (size_t i = 0; i < 16; i++) { - // Put the same values but in inverse order - circuit_builder.add_row({ column_0[i], column_1[i], column_0[15 - i], column_1[15 - i] }); + + // Sample 8 random elements for the single column permutation + std::vector column_2; + for (size_t i = 0; i < circuit_size / 2; i++) { + column_2.emplace_back(FF::random_element()); + } + + for (size_t i = 0; i < circuit_size; i++) { + // We put the same tuple of values in the first 2 wires and in the next 2 to at different rows + // We also put the same value in the self_permutation column in 2 consecutive rows + circuit_builder.add_row({ column_0[i], column_1[i], column_0[15 - i], column_1[15 - i], column_2[i / 2] }); } - // Test that the permutation with correct values works + // Test that permutations with correct values work bool result = circuit_builder.check_circuit(); EXPECT_EQ(result, true); - // And that it fails with incorrct values + + // Store value temporarily + FF tmp = circuit_builder.wires[0][5]; + + // Replace one of the values in a tuple permutation column with a random one, breaking the permutation circuit_builder.wires[0][5] = FF::random_element(); + + // Check that it fails + result = circuit_builder.check_circuit(); + EXPECT_EQ(result, false); + + // Restore value + circuit_builder.wires[0][5] = tmp; + + // Check circuit passes + result = circuit_builder.check_circuit(); + EXPECT_EQ(result, true); + + // Break single-column permutation + circuit_builder.wires[circuit_builder.wires.size() - 1][0] = FF::random_element(); result = circuit_builder.check_circuit(); EXPECT_EQ(result, false); } -} // namespace avm_template_circuit_builder_tests \ No newline at end of file +} // namespace toy_avm_circuit_builder_tests \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/relations/avm_templates/generic_permutation_relation.cpp b/barretenberg/cpp/src/barretenberg/relations/avm_templates/generic_permutation_relation.cpp index b41486dd9902..efeb6b5336e3 100644 --- a/barretenberg/cpp/src/barretenberg/relations/avm_templates/generic_permutation_relation.cpp +++ b/barretenberg/cpp/src/barretenberg/relations/avm_templates/generic_permutation_relation.cpp @@ -2,6 +2,7 @@ #include "barretenberg/flavor/avm_template.hpp" #include "barretenberg/flavor/relation_definitions_fwd.hpp" #include "barretenberg/honk/proof_system/logderivative_library.hpp" +#include "relation_definer.hpp" namespace proof_system::honk::sumcheck { @@ -12,19 +13,22 @@ namespace proof_system::honk::sumcheck { * @param relation_params contains beta, gamma, and public_input_delta, .... * @param scaling_factor optional term to scale the evaluation before adding to evals. */ -template +template template -void GenericPermutationRelationImpl::accumulate(ContainerOverSubrelations& accumulator, - const AllEntities& in, - const Parameters& params, - const FF& scaling_factor) +void GenericPermutationRelationImpl::accumulate(ContainerOverSubrelations& accumulator, + const AllEntities& in, + const Parameters& params, + const FF& scaling_factor) { - logderivative_library:: - accumulate_logderivative_permutation_subrelation_contributions>( - accumulator, in, params, scaling_factor); + logderivative_library::accumulate_logderivative_permutation_subrelation_contributions< + FF, + GenericPermutationRelationImpl>(accumulator, in, params, scaling_factor); } -template class GenericPermutationRelationImpl; -DEFINE_SUMCHECK_RELATION_CLASS(GenericPermutationRelationImpl, flavor::AVMTemplate); +// template class GenericPermutationRelationImpl; +// template +// using GenericPermutationRelationExampleSettingsImpl = GenericPermutationRelationImpl; DEFINE_SUMCHECK_RELATION_CLASS(GenericPermutationRelationExampleSettingsImpl, flavor::AVMTemplate); +DEFINE_IMPLEMENTATIONS_FOR_ALL_SETTINGS(GenericPermutationRelationImpl, flavor::AVMTemplate); } // namespace proof_system::honk::sumcheck diff --git a/barretenberg/cpp/src/barretenberg/relations/avm_templates/generic_permutation_relation.hpp b/barretenberg/cpp/src/barretenberg/relations/avm_templates/generic_permutation_relation.hpp index a15849d411b1..d4246a423f5c 100644 --- a/barretenberg/cpp/src/barretenberg/relations/avm_templates/generic_permutation_relation.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/avm_templates/generic_permutation_relation.hpp @@ -1,8 +1,8 @@ /** * @file generic_permutation_relation.hpp * @author Rumata888 - * @brief This file contains an example relation that is used as a basis for generic permutation relations generated - * with PIL + * @brief This file contains the template for the generic permutation that can be specialized to enforce various + * permutations (for explanation on how to define them, see "relation_definer.hpp") * */ #pragma once @@ -15,8 +15,23 @@ #include "barretenberg/relations/relation_types.hpp" namespace proof_system::honk::sumcheck { +/** + * @brief Specifies positions of elements in the tuple of entities received from methods in the Settings class + * + */ +enum GenericPermutationSettingIndices { + INVERSE_POLYNOMIAL_INDEX, /* The index of the inverse polynomial*/ + ENABLE_INVERSE_CORRECTNESS_CHECK_POLYNOMIAL_INDEX, /* The index of the polynomial enabling first subrelation*/ + FIRST_PERMUTATION_SET_ENABLE_POLYNOMIAL_INDEX, /* The index of the polynomial that adds an element from the first + set to the sum*/ + SECOND_PERMUTATION_SET_ENABLE_POLYNOMIAL_INDEX, /* The index of the polynomial that adds an element from the second + set to the sum*/ + + PERMUTATION_SETS_START_POLYNOMIAL_INDEX, /* The starting index of the polynomials that are used in the permutation + sets*/ +}; -template class GenericPermutationRelationImpl { +template class GenericPermutationRelationImpl { public: using FF = FF_; // Read and write terms counts should stay set to 1 unless we want to permute several columns at once as accumulated @@ -42,27 +57,25 @@ template class GenericPermutationRelationImpl { /** * @brief Check if we need to compute the inverse polynomial element value for this row + * @details This proxies to a method in the Settings class * * @param row All values at row */ template static bool operation_exists_at_row(const AllValues& row) { - // WIRE/SELECTOR enabling the permutation - // N.B. PIL TEMPLATED VALUE - return (row.enable_set_permutation == 1); + return Settings::inverse_polynomial_is_computed_at_row(row); } /** - * @brief Get the inverse permutation polynomial + * @brief Get the inverse permutation polynomial (needed to compute its value) * */ template static auto& get_inverse_polynomial(AllEntities& in) { // WIRE containing the inverse of the product of terms at this row. Used to reconstruct individual inversed // terms - // N.B. PIL TEMPLATED VALUE - return in.permutation_inverses; + return std::get(Settings::get_nonconst_entities(in)); } /** @@ -75,8 +88,8 @@ template class GenericPermutationRelationImpl { using View = typename Accumulator::View; // WIRE/SELECTOR enabling the permutation used in the sumcheck computation. This affects the first subrelation - // N.B. PIL TEMPLATED VALUE - return Accumulator(View(in.enable_set_permutation)); + return Accumulator( + View(std::get(Settings::get_const_entities(in)))); } /** @@ -93,8 +106,8 @@ template class GenericPermutationRelationImpl { // The selector/wire value that determines that an element from the first set needs to be included. Can be // different from the wire used in the write part. - // N.B. PIL TEMPLATED VALUE - return Accumulator(View(in.enable_set_permutation)); + return Accumulator( + View(std::get(Settings::get_const_entities(in)))); } /** @@ -110,14 +123,14 @@ template class GenericPermutationRelationImpl { // The selector/wire value that determines that an element from the second set needs to be included. Can be // different from the wire used in the read part. - // N.B. PIL TEMPLATED VALUE - return Accumulator(View(in.enable_set_permutation)); + return Accumulator( + View(std::get(Settings::get_const_entities(in)))); } /** * @brief Compute the value of a single item in the set * - * @details Computes the polynomial \gamma + \sum_{i=0}^{num_columns}(column_i*\beta^i), so the tuple of columnes is + * @details Computes the polynomial \gamma + \sum_{i=0}^{num_columns}(column_i*\beta^i), so the tuple of columns is * in the first set * * @tparam read_index Kept for compatibility with lookups, behavior doesn't change @@ -131,17 +144,16 @@ template class GenericPermutationRelationImpl { static_assert(read_index < READ_TERMS); - // The tuple of columns a single row of which represents a single element of the first set (we are doing a - // permutation of tuples). The length is 1+ - // N.B. PIL TEMPLATED VALUE - const auto read_term_entitites = - std::forward_as_tuple(View(in.permutation_set_column_3), View(in.permutation_set_column_4)); + // Retrieve all polynomials used + const auto all_polynomials = Settings::get_const_entities(in); auto result = Accumulator(0); - constexpr size_t tuple_size = std::tuple_size_v; + // Iterate over tuple and sum as a polynomial over beta - barretenberg::constexpr_for<0, tuple_size, 1>( - [&]() { result = result * params.beta + std::get(read_term_entitites); }); + barretenberg::constexpr_for( + [&]() { result = result * params.beta + View(std::get(all_polynomials)); }); const auto& gamma = params.gamma; return result + gamma; @@ -150,7 +162,7 @@ template class GenericPermutationRelationImpl { /** * @brief Compute the value of a single item in the set * - * @details Computes the polynomial \gamma + \sum_{i=0}^{num_columns}(column_i*\beta^i), so the tuple of columnes is + * @details Computes the polynomial \gamma + \sum_{i=0}^{num_columns}(column_i*\beta^i), so the tuple of columns is * in the second set * * @tparam write_index Kept for compatibility with lookups, behavior doesn't change @@ -164,17 +176,16 @@ template class GenericPermutationRelationImpl { static_assert(write_index < WRITE_TERMS); - // The tuple of columns a single row of which represents a single element of the second set (we are doing a - // permutation of tuples). The length is 1+ - // N.B. PIL TEMPLATED VALUE - const auto write_term_entities = - std::forward_as_tuple(View(in.permutation_set_column_1), View(in.permutation_set_column_2)); - auto result = Accumulator(0); - constexpr size_t tuple_size = std::tuple_size_v; + // Get all used entities + const auto& used_entities = Settings::get_const_entities(in); + auto result = Accumulator(0); // Iterate over tuple and sum as a polynomial over beta - barretenberg::constexpr_for<0, tuple_size, 1>( - [&]() { result = result * params.beta + std::get(write_term_entities); }); + barretenberg::constexpr_for( + [&]() { result = result * params.beta + View(std::get(used_entities)); }); + const auto& gamma = params.gamma; return result + gamma; } @@ -193,6 +204,7 @@ template class GenericPermutationRelationImpl { const FF& scaling_factor); }; -template using GenericPermutationRelation = Relation>; +template +using GenericPermutationRelation = Relation>; } // namespace proof_system::honk::sumcheck diff --git a/barretenberg/cpp/src/barretenberg/relations/avm_templates/relation_definer.hpp b/barretenberg/cpp/src/barretenberg/relations/avm_templates/relation_definer.hpp new file mode 100644 index 000000000000..4771c1260b7d --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/relations/avm_templates/relation_definer.hpp @@ -0,0 +1,213 @@ +/** + * @file relation_definer.hpp + * @author Rumata888 + * @brief This file contains settings for the General Permutation Relation implementations and (in the future) Lookup + * implementations + * + */ +#pragma once +#include +#include +namespace proof_system::honk::sumcheck { + +/** + * @brief This class contains an example of how to set PermutationSettings classes used by the + * GenericPermutationRelationImpl class to specify a concrete permutation + * + * @details To create your own permutation: + * 1) Create a copy of this class and rename it + * 2) Update all the values with the ones needed for your permutation + * 3) Update "DECLARE_IMPLEMENTATIONS_FOR_ALL_SETTINGS" and "DEFINE_IMPLEMENTATIONS_FOR_ALL_SETTINGS" to include the new + * settings + * 4) Add the relation with the chosen settings to Relations in the flavor (for example,"` + * using Relations = std::tuple>;)` + * + */ +class ExampleTuplePermutationSettings { + public: + // This constant defines how many columns are bundled together to form each set. For example, in this case we are + // bundling tuples of (permutation_set_column_1, permutation_set_column_2) to be a permutation of + // (permutation_set_column_3,permutation_set_column_4). As the tuple has 2 elements, set the value to 2 + constexpr static size_t COLUMNS_PER_SET = 2; + + /** + * @brief If this method returns true on a row of values, then the inverse polynomial at this index. Otherwise the + * value needs to be set to zero. + * + * @details If this is true then permutation takes place in this row + * + */ + template static inline bool inverse_polynomial_is_computed_at_row(const AllEntities& in) + { + return (in.enable_tuple_set_permutation == 1); + } + + /** + * @brief Get all the entities for the permutation when we don't need to update them + * + * @details The entities are returned as a tuple of references in the following order: + * - The entity/polynomial used to store the product of the inverse values + * - The entity/polynomial that switches on the subrelation of the permutation relation that ensures correctness of + * the inverse polynomial + * - The entity/polynomial that enables adding a tuple-generated value from the first set to the logderivative sum + * subrelation + * - The entity/polynomial that enables adding a tuple-generated value from the second set to the logderivative sum + * subrelation + * - A sequence of COLUMNS_PER_SET entities/polynomials that represent the first set (N.B. ORDER IS IMPORTANT!) + * - A sequence of COLUMNS_PER_SET entities/polynomials that represent the second set (N.B. ORDER IS IMPORTANT!) + * + * @return All the entities needed for the permutation + */ + template static inline auto get_const_entities(const AllEntities& in) + { + + return std::forward_as_tuple( + in.tuple_permutation_inverses, /* The polynomial containing the inverse product*/ + in.enable_tuple_set_permutation, /* The polynomial enabling the product check subrelation */ + in.enable_tuple_set_permutation, /* Enables adding first set to the sum */ + in.enable_tuple_set_permutation, /* Enables adding second set to the sum */ + in.permutation_set_column_3, /* The first entry in the first set tuple */ + in.permutation_set_column_4, /* The second entry in the first set tuple */ + in.permutation_set_column_1, /* The first entry in the second set tuple */ + in.permutation_set_column_2); /* The second entry in the second set tuple */ + } + + /** + * @brief Get all the entities for the permutation when need to update them + * + * @details The entities are returned as a tuple of references in the following order: + * - The entity/polynomial used to store the product of the inverse values + * - The entity/polynomial that switches on the subrelation of the permutation relation that ensures correctness of + * the inverse polynomial + * - The entity/polynomial that enables adding a tuple-generated value from the first set to the logderivative sum + * subrelation + * - The entity/polynomial that enables adding a tuple-generated value from the second set to the logderivative sum + * subrelation + * - A sequence of COLUMNS_PER_SET entities/polynomials that represent the first set (N.B. ORDER IS IMPORTANT!) + * - A sequence of COLUMNS_PER_SET entities/polynomials that represent the second set (N.B. ORDER IS IMPORTANT!) + * + * @return All the entities needed for the permutation + */ + template static inline auto get_nonconst_entities(AllEntities& in) + { + return std::forward_as_tuple( + in.tuple_permutation_inverses, /* The polynomial containing the inverse product*/ + in.enable_tuple_set_permutation, /* The polynomial enabling the product check subrelation */ + in.enable_tuple_set_permutation, /* Enables adding first set to the sum */ + in.enable_tuple_set_permutation, /* Enables adding second set to the sum */ + in.permutation_set_column_3, /* The first entry in the first set tuple */ + in.permutation_set_column_4, /* The second entry in the first set tuple */ + in.permutation_set_column_1, /* The first entry in the second set tuple */ + in.permutation_set_column_2); /* The second entry in the second set tuple */ + } +}; + +/** + * @brief This class contains an example of how to set PermutationSettings classes used by the + * GenericPermutationRelationImpl class to specify a concrete permutation + * + * @details To create your own permutation: + * 1) Create a copy of this class and rename it + * 2) Update all the values with the ones needed for your permutation + * 3) Update "DECLARE_IMPLEMENTATIONS_FOR_ALL_SETTINGS" and "DEFINE_IMPLEMENTATIONS_FOR_ALL_SETTINGS" to include the new + * settings + * 4) Add the relation with the chosen settings to Relations in the flavor (for example,"` + * using Relations = std::tuple>;)` + * + */ +class ExampleSameWirePermutationSettings { + public: + // This constant defines how many columns are bundled together to form each set. For example, in this case we are + // permuting entries in the column with itself (self_permutation_column), so we choose just one + constexpr static size_t COLUMNS_PER_SET = 1; + + /** + * @brief If this method returns true on a row of values, then the inverse polynomial at this index. Otherwise the + * value needs to be set to zero. + * + * @details If this is true then permutation takes place in this row + * + */ + template static inline bool inverse_polynomial_is_computed_at_row(const AllEntities& in) + { + return (in.enable_single_column_permutation == 1); + } + + /** + * @brief Get all the entities for the permutation when we don't need to update them + * + * @details The entities are returned as a tuple of references in the following order: + * - The entity/polynomial used to store the product of the inverse values + * - The entity/polynomial that switches on the subrelation of the permutation relation that ensures correctness of + * the inverse polynomial + * - The entity/polynomial that enables adding a tuple-generated value from the first set to the logderivative sum + * subrelation + * - The entity/polynomial that enables adding a tuple-generated value from the second set to the logderivative sum + * subrelation + * - A sequence of COLUMNS_PER_SET entities/polynomials that represent the first set (N.B. ORDER IS IMPORTANT!) + * - A sequence of COLUMNS_PER_SET entities/polynomials that represent the second set (N.B. ORDER IS IMPORTANT!) + * + * @return All the entities needed for the permutation + */ + template static inline auto get_const_entities(const AllEntities& in) + { + + return std::forward_as_tuple( + in.single_permutation_inverses, /* The polynomial containing the inverse product*/ + in.enable_single_column_permutation, /* The polynomial enabling the product check subrelation */ + in.enable_first_set_permutation, /* Enables adding first set to the sum */ + in.enable_second_set_permutation, /* Enables adding second set to the sum */ + in.self_permutation_column, /* The first set column */ + in.self_permutation_column /* The second set column which in this case is the same as the first set column + */ + ); + } + + /** + * @brief Get all the entities for the permutation when need to update them + * + * @details The entities are returned as a tuple of references in the following order: + * - The entity/polynomial used to store the product of the inverse values + * - The entity/polynomial that switches on the subrelation of the permutation relation that ensures correctness of + * the inverse polynomial + * - The entity/polynomial that enables adding a tuple-generated value from the first set to the logderivative sum + * subrelation + * - The entity/polynomial that enables adding a tuple-generated value from the second set to the logderivative sum + * subrelation + * - A sequence of COLUMNS_PER_SET entities/polynomials that represent the first set (N.B. ORDER IS IMPORTANT!) + * - A sequence of COLUMNS_PER_SET entities/polynomials that represent the second set (N.B. ORDER IS IMPORTANT!) + * + * @return All the entities needed for the permutation + */ + template static inline auto get_nonconst_entities(AllEntities& in) + { + return std::forward_as_tuple( + in.single_permutation_inverses, /* The polynomial containing the inverse product*/ + in.enable_single_column_permutation, /* The polynomial enabling the product check subrelation */ + in.enable_first_set_permutation, /* Enables adding first set to the sum */ + in.enable_second_set_permutation, /* Enables adding second set to the sum */ + in.self_permutation_column, /* The first set column */ + in.self_permutation_column /* The second set column which in this case is the same as the first set column + */ + ); + } +}; + +#define DEFINE_IMPLEMENTATIONS_FOR_SETTINGS(RelationImplementation, flavor, Settings) \ + template class RelationImplementation; \ + template using RelationImplementation##Settings = RelationImplementation; \ + DEFINE_SUMCHECK_RELATION_CLASS(RelationImplementation##Settings, flavor); + +#define DEFINE_IMPLEMENTATIONS_FOR_ALL_SETTINGS(RelationImplementation, flavor) \ + DEFINE_IMPLEMENTATIONS_FOR_SETTINGS(RelationImplementation, flavor, ExampleTuplePermutationSettings); \ + DEFINE_IMPLEMENTATIONS_FOR_SETTINGS(RelationImplementation, flavor, ExampleSameWirePermutationSettings); + +#define DECLARE_IMPLEMENTATIONS_FOR_SETTINGS(RelationImplementation, flavor, Settings) \ + extern template class RelationImplementation; \ + template using RelationImplementation##Settings = RelationImplementation; \ + DECLARE_SUMCHECK_RELATION_CLASS(RelationImplementation##Settings, flavor); + +#define DECLARE_IMPLEMENTATIONS_FOR_ALL_SETTINGS(RelationImplementation, flavor) \ + DECLARE_IMPLEMENTATIONS_FOR_SETTINGS(RelationImplementation, flavor, ExampleTuplePermutationSettings); \ + DECLARE_IMPLEMENTATIONS_FOR_SETTINGS(RelationImplementation, flavor, ExampleSameWirePermutationSettings); +} // namespace proof_system::honk::sumcheck \ No newline at end of file From 93e3f71ea875c8f4b939842625efd354d05b13c9 Mon Sep 17 00:00:00 2001 From: Rumata888 Date: Wed, 6 Dec 2023 13:47:13 +0000 Subject: [PATCH 11/15] Renames --- .../flavor/{avm_template.hpp => toy_avm.hpp} | 8 ++++---- .../toy_avm_circuit_builder.hpp} | 6 ++++-- .../toy_avm_circuit_builder.test.cpp} | 15 ++++----------- .../generic_permutation_relation.cpp | 4 ++-- .../generic_permutation_relation.hpp | 0 .../relation_definer.hpp | 0 6 files changed, 14 insertions(+), 19 deletions(-) rename barretenberg/cpp/src/barretenberg/flavor/{avm_template.hpp => toy_avm.hpp} (99%) rename barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/{avm_templates/avm_template_circuit_builder.hpp => toy_avm/toy_avm_circuit_builder.hpp} (96%) rename barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/{avm_templates/avm_template_circuit_builder.test.cpp => toy_avm/toy_avm_circuit_builder.test.cpp} (80%) rename barretenberg/cpp/src/barretenberg/relations/{avm_templates => toy_avm}/generic_permutation_relation.cpp (95%) rename barretenberg/cpp/src/barretenberg/relations/{avm_templates => toy_avm}/generic_permutation_relation.hpp (100%) rename barretenberg/cpp/src/barretenberg/relations/{avm_templates => toy_avm}/relation_definer.hpp (100%) diff --git a/barretenberg/cpp/src/barretenberg/flavor/avm_template.hpp b/barretenberg/cpp/src/barretenberg/flavor/toy_avm.hpp similarity index 99% rename from barretenberg/cpp/src/barretenberg/flavor/avm_template.hpp rename to barretenberg/cpp/src/barretenberg/flavor/toy_avm.hpp index 54d128e966eb..66d5415e6824 100644 --- a/barretenberg/cpp/src/barretenberg/flavor/avm_template.hpp +++ b/barretenberg/cpp/src/barretenberg/flavor/toy_avm.hpp @@ -4,10 +4,10 @@ #include "barretenberg/ecc/curves/bn254/bn254.hpp" #include "barretenberg/flavor/flavor.hpp" #include "barretenberg/polynomials/univariate.hpp" -#include "barretenberg/relations/avm_templates/generic_permutation_relation.hpp" -#include "barretenberg/relations/avm_templates/relation_definer.hpp" #include "barretenberg/relations/relation_parameters.hpp" #include "barretenberg/relations/relation_types.hpp" +#include "barretenberg/relations/toy_avm/generic_permutation_relation.hpp" +#include "barretenberg/relations/toy_avm/relation_definer.hpp" #include "relation_definitions_fwd.hpp" #include #include @@ -26,7 +26,7 @@ namespace flavor { * integrating those mechanisms into AVM easier * */ -class AVMTemplate { +class ToyAVM { public: using Curve = curve::BN254; using FF = Curve::ScalarField; @@ -434,7 +434,7 @@ class AVMTemplate { } // namespace flavor namespace sumcheck { -DECLARE_IMPLEMENTATIONS_FOR_ALL_SETTINGS(GenericPermutationRelationImpl, flavor::AVMTemplate) +DECLARE_IMPLEMENTATIONS_FOR_ALL_SETTINGS(GenericPermutationRelationImpl, flavor::ToyAVM) } // namespace sumcheck } // namespace proof_system::honk diff --git a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/avm_templates/avm_template_circuit_builder.hpp b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/toy_avm/toy_avm_circuit_builder.hpp similarity index 96% rename from barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/avm_templates/avm_template_circuit_builder.hpp rename to barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/toy_avm/toy_avm_circuit_builder.hpp index 4c065fb195aa..26ace2d851a5 100644 --- a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/avm_templates/avm_template_circuit_builder.hpp +++ b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/toy_avm/toy_avm_circuit_builder.hpp @@ -6,16 +6,18 @@ */ #pragma once +#include "barretenberg/common/constexpr_utils.hpp" #include "barretenberg/ecc/curves/bn254/fr.hpp" -#include "barretenberg/flavor/avm_template.hpp" +#include "barretenberg/flavor/toy_avm.hpp" #include "barretenberg/honk/proof_system/logderivative_library.hpp" #include "barretenberg/relations/relation_parameters.hpp" +#include "barretenberg/relations/toy_avm/generic_permutation_relation.hpp" namespace proof_system { template class ToyAVMCircuitBuilder { public: - using FF = typename Flavor::FF; + using FF = Flavor::FF; using Polynomial = typename Flavor::Polynomial; static constexpr size_t NUM_POLYNOMIALS = Flavor::NUM_ALL_ENTITIES; diff --git a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/avm_templates/avm_template_circuit_builder.test.cpp b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/toy_avm/toy_avm_circuit_builder.test.cpp similarity index 80% rename from barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/avm_templates/avm_template_circuit_builder.test.cpp rename to barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/toy_avm/toy_avm_circuit_builder.test.cpp index 860356851372..62b2e4d83c3b 100644 --- a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/avm_templates/avm_template_circuit_builder.test.cpp +++ b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/toy_avm/toy_avm_circuit_builder.test.cpp @@ -1,6 +1,5 @@ -#include "avm_template_circuit_builder.hpp" +#include "toy_avm_circuit_builder.hpp" #include "barretenberg/crypto/generators/generator_data.hpp" -#include "barretenberg/crypto/pedersen_commitment/pedersen.hpp" #include using namespace barretenberg; @@ -11,22 +10,16 @@ auto& engine = numeric::random::get_debug_engine(); namespace toy_avm_circuit_builder_tests { -template class ToyAVMCircuitBuilderTests : public ::testing::Test {}; - -using FlavorTypes = ::testing::Types; -TYPED_TEST_SUITE(AVMTemplateCircuitBuilderTests, FlavorTypes); - /** * @brief A test explaining the work of the permutations in Toy AVM * */ -TYPED_TEST(ToyAVMCircuitBuilderTests, BaseCase) +TEST(ToyAVMCircuitBuilder, BaseCase) { - using Flavor = TypeParam; - using FF = typename Flavor::FF; + using FF = proof_system::honk::flavor::ToyAVM::FF; const size_t circuit_size = 16; - proof_system::ToyAVMCircuitBuilder circuit_builder; + proof_system::ToyAVMCircuitBuilder circuit_builder; // Sample 2*16 random elements for the tuple permutation example std::vector column_0; diff --git a/barretenberg/cpp/src/barretenberg/relations/avm_templates/generic_permutation_relation.cpp b/barretenberg/cpp/src/barretenberg/relations/toy_avm/generic_permutation_relation.cpp similarity index 95% rename from barretenberg/cpp/src/barretenberg/relations/avm_templates/generic_permutation_relation.cpp rename to barretenberg/cpp/src/barretenberg/relations/toy_avm/generic_permutation_relation.cpp index efeb6b5336e3..1822c388c4e7 100644 --- a/barretenberg/cpp/src/barretenberg/relations/avm_templates/generic_permutation_relation.cpp +++ b/barretenberg/cpp/src/barretenberg/relations/toy_avm/generic_permutation_relation.cpp @@ -1,6 +1,6 @@ #include "generic_permutation_relation.hpp" -#include "barretenberg/flavor/avm_template.hpp" #include "barretenberg/flavor/relation_definitions_fwd.hpp" +#include "barretenberg/flavor/toy_avm.hpp" #include "barretenberg/honk/proof_system/logderivative_library.hpp" #include "relation_definer.hpp" @@ -30,5 +30,5 @@ void GenericPermutationRelationImpl::accumulate(ContainerOverSubre // using GenericPermutationRelationExampleSettingsImpl = GenericPermutationRelationImpl; DEFINE_SUMCHECK_RELATION_CLASS(GenericPermutationRelationExampleSettingsImpl, flavor::AVMTemplate); -DEFINE_IMPLEMENTATIONS_FOR_ALL_SETTINGS(GenericPermutationRelationImpl, flavor::AVMTemplate); +DEFINE_IMPLEMENTATIONS_FOR_ALL_SETTINGS(GenericPermutationRelationImpl, flavor::ToyAVM); } // namespace proof_system::honk::sumcheck diff --git a/barretenberg/cpp/src/barretenberg/relations/avm_templates/generic_permutation_relation.hpp b/barretenberg/cpp/src/barretenberg/relations/toy_avm/generic_permutation_relation.hpp similarity index 100% rename from barretenberg/cpp/src/barretenberg/relations/avm_templates/generic_permutation_relation.hpp rename to barretenberg/cpp/src/barretenberg/relations/toy_avm/generic_permutation_relation.hpp diff --git a/barretenberg/cpp/src/barretenberg/relations/avm_templates/relation_definer.hpp b/barretenberg/cpp/src/barretenberg/relations/toy_avm/relation_definer.hpp similarity index 100% rename from barretenberg/cpp/src/barretenberg/relations/avm_templates/relation_definer.hpp rename to barretenberg/cpp/src/barretenberg/relations/toy_avm/relation_definer.hpp From 01de17cfb27bd819e886ca58f85c318433800c37 Mon Sep 17 00:00:00 2001 From: Rumata888 Date: Wed, 6 Dec 2023 13:50:55 +0000 Subject: [PATCH 12/15] A few comments --- .../toy_avm/toy_avm_circuit_builder.hpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/toy_avm/toy_avm_circuit_builder.hpp b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/toy_avm/toy_avm_circuit_builder.hpp index 26ace2d851a5..c5e4a8758e00 100644 --- a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/toy_avm/toy_avm_circuit_builder.hpp +++ b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/toy_avm/toy_avm_circuit_builder.hpp @@ -15,6 +15,11 @@ namespace proof_system { +/** + * @brief Circuit builder for the ToyAVM that is used to explain generic permutation settings + * + * @tparam Flavor + */ template class ToyAVMCircuitBuilder { public: using FF = Flavor::FF; @@ -55,6 +60,7 @@ template class ToyAVMCircuitBuilder { polys.lagrange_first[0] = 1; for (size_t i = 0; i < num_gates; ++i) { + // Fill out the witness polynomials polys.permutation_set_column_1[i] = wires[0][i]; polys.permutation_set_column_2[i] = wires[1][i]; polys.permutation_set_column_3[i] = wires[2][i]; @@ -62,6 +68,7 @@ template class ToyAVMCircuitBuilder { polys.self_permutation_column[i] = wires[4][i]; // By default the permutation is over all rows where we place data polys.enable_tuple_set_permutation[i] = 1; + // The same column permutation alternates between even and odd values polys.enable_single_column_permutation[i] = 1; polys.enable_first_set_permutation[i] = i & 1; polys.enable_second_set_permutation[i] = 1 - (i & 1); @@ -90,8 +97,10 @@ template class ToyAVMCircuitBuilder { .eccvm_set_permutation_delta = 0, }; + // Compute polynomial values auto polynomials = compute_polynomials(); const size_t num_rows = polynomials.get_polynomial_size(); + // Check the tuple permutation relation proof_system::honk::logderivative_library::compute_logderivative_inverse< Flavor, @@ -115,6 +124,7 @@ template class ToyAVMCircuitBuilder { return false; } } + // Check the single permutation relation proof_system::honk::logderivative_library::compute_logderivative_inverse< Flavor, honk::sumcheck::GenericPermutationRelation>( From ff5b5a1fffc8d752701aae23e7ac2417ad3d8d0d Mon Sep 17 00:00:00 2001 From: Rumata888 Date: Wed, 6 Dec 2023 15:40:27 +0000 Subject: [PATCH 13/15] After rebase (pain) --- .../cpp/src/barretenberg/flavor/toy_avm.hpp | 274 +++++++----------- .../toy_avm/toy_avm_circuit_builder.hpp | 4 +- .../vm/generated/AvmMini_prover.cpp | 2 +- .../barretenberg/vm/generated/Fib_prover.cpp | 2 +- 4 files changed, 109 insertions(+), 173 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/flavor/toy_avm.hpp b/barretenberg/cpp/src/barretenberg/flavor/toy_avm.hpp index 66d5415e6824..89b4249ba80d 100644 --- a/barretenberg/cpp/src/barretenberg/flavor/toy_avm.hpp +++ b/barretenberg/cpp/src/barretenberg/flavor/toy_avm.hpp @@ -3,6 +3,7 @@ #include "barretenberg/commitment_schemes/kzg/kzg.hpp" #include "barretenberg/ecc/curves/bn254/bn254.hpp" #include "barretenberg/flavor/flavor.hpp" +#include "barretenberg/flavor/flavor_macros.hpp" #include "barretenberg/polynomials/univariate.hpp" #include "barretenberg/relations/relation_parameters.hpp" #include "barretenberg/relations/relation_types.hpp" @@ -76,44 +77,46 @@ class ToyAVM { * @brief A base class labelling precomputed entities and (ordered) subsets of interest. * @details Used to build the proving key and verification key. */ - template - class PrecomputedEntities : public PrecomputedEntities_ { + template class PrecomputedEntities : public PrecomputedEntitiesBase { public: - DataType lagrange_first; // column 0 - DataType enable_tuple_set_permutation; // column 1 - - DEFINE_POINTER_VIEW(NUM_PRECOMPUTED_ENTITIES, &lagrange_first) - - std::vector get_selectors() override { return { lagrange_first }; }; - std::vector get_sigma_polynomials() override { return {}; }; - std::vector get_id_polynomials() override { return {}; }; - std::vector get_table_polynomials() { return {}; }; + using DataType = DataType_; + DEFINE_FLAVOR_MEMBERS(DataType, + lagrange_first, // column 0 + enable_tuple_set_permutation, // column 1 + enable_single_column_permutation, // column 2 + enable_first_set_permutation, // column 3 + enable_second_set_permutation) // column 4 + + RefVector get_selectors() + { + return { lagrange_first, + enable_tuple_set_permutation, + enable_single_column_permutation, + enable_first_set_permutation, + enable_second_set_permutation }; + }; + RefVector get_sigma_polynomials() { return {}; }; + RefVector get_id_polynomials() { return {}; }; + RefVector get_table_polynomials() { return {}; }; }; /** * @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 WitnessEntities_ { + + template class WitnessEntities { public: - DataType permutation_set_column_1; // column 0 - DataType permutation_set_column_2; // column 1 - DataType permutation_set_column_3; // column 2 - DataType permutation_set_column_4; // column 3 - DataType self_permutation_column; // column 4 - DataType tuple_permutation_inverses; // column 5 - DataType single_permutation_inverses; // column 6 - - DEFINE_POINTER_VIEW(NUM_WITNESS_ENTITIES, - &permutation_set_column_1, - &permutation_set_column_2, - &permutation_set_column_3, - &permutation_set_column_4, - &self_permutation_column, - &tuple_permutation_inverses, - &single_permutation_inverses) - std::vector get_wires() override + DEFINE_FLAVOR_MEMBERS(DataType, + permutation_set_column_1, // Column 0 + permutation_set_column_2, // Column 1 + permutation_set_column_3, // Column 2 + permutation_set_column_4, // Column 3 + self_permutation_column, // Column 4 + tuple_permutation_inverses, // Column 5 + single_permutation_inverses) // Column 6 + + RefVector get_wires() { return { permutation_set_column_1, permutation_set_column_2, @@ -121,8 +124,6 @@ class ToyAVM { permutation_set_column_4, self_permutation_column }; }; - // The sorted concatenations of table and witness data needed for plookup. - std::vector get_sorted_polynomials() { return {}; }; }; /** @@ -134,44 +135,30 @@ class ToyAVM { * Symbolically we have: AllEntities = PrecomputedEntities + WitnessEntities + "ShiftedEntities". It could be * implemented as such, but we have this now. */ - template - class AllEntities : public AllEntities_ { + + template class AllEntities { public: - DataType lagrange_first; // column 0 - DataType enable_tuple_set_permutation; // column 1 - DataType enable_single_column_permutation; // column 1 - DataType enable_first_set_permutation; // column 1 - DataType enable_second_set_permutation; // column 1 - DataType permutation_set_column_1; // column 0 - DataType permutation_set_column_2; // column 1 - DataType permutation_set_column_3; // column 2 - DataType permutation_set_column_4; // column 3 - DataType self_permutation_column; // column 4 - DataType tuple_permutation_inverses; // column 5 - DataType single_permutation_inverses; // column 6 - - // defines a method pointer_view that returns the following, with const and non-const variants - DEFINE_POINTER_VIEW(NUM_ALL_ENTITIES, - &lagrange_first, - &enable_tuple_set_permutation, - &enable_single_column_permutation, - &enable_first_set_permutation, - &enable_second_set_permutation, - &permutation_set_column_1, - &permutation_set_column_2, - &permutation_set_column_3, - &permutation_set_column_4, - &self_permutation_column, - &tuple_permutation_inverses, - &single_permutation_inverses) - std::vector get_wires() override + DEFINE_FLAVOR_MEMBERS(DataType, + lagrange_first, // Column 0 + enable_tuple_set_permutation, // Column 1 + enable_single_column_permutation, // Column 2 + enable_first_set_permutation, // Column 3 + enable_second_set_permutation, // Column 4 + permutation_set_column_1, // Column 5 + permutation_set_column_2, // Column 6 + permutation_set_column_3, // Column 7 + permutation_set_column_4, // Column 8 + self_permutation_column, // Column 9 + tuple_permutation_inverses, // Column 10 + single_permutation_inverses) // Column 11 + + RefVector get_wires() { return { permutation_set_column_1, permutation_set_column_2, permutation_set_column_3, permutation_set_column_4 }; }; - // Gemini-specific getters. - std::vector get_unshifted() override + RefVector get_unshifted() { return { lagrange_first, enable_tuple_set_permutation, @@ -186,9 +173,8 @@ class ToyAVM { tuple_permutation_inverses, single_permutation_inverses }; }; - - std::vector get_to_be_shifted() override { return {}; }; - std::vector get_shifted() override { return {}; }; + RefVector get_to_be_shifted() { return {}; }; + RefVector get_shifted() { return {}; }; }; public: @@ -197,12 +183,10 @@ class ToyAVM { * @note TODO(Cody): Maybe multiple inheritance is the right thing here. In that case, nothing should eve inherit * from ProvingKey. */ - class ProvingKey : public ProvingKey_, - WitnessEntities> { + class ProvingKey : public ProvingKey_, WitnessEntities> { public: // Expose constructors on the base class - using Base = ProvingKey_, - WitnessEntities>; + using Base = ProvingKey_, WitnessEntities>; using Base::Base; // The plookup wires that store plookup read data. @@ -217,74 +201,77 @@ class ToyAVM { * that, and split out separate PrecomputedPolynomials/Commitments data for clarity but also for portability of our * circuits. */ - using VerificationKey = VerificationKey_>; - - /** - * @brief A container for polynomials produced after the first round of sumcheck. - * @todo TODO(#394) Use polynomial classes for guaranteed memory alignment. - */ - using FoldedPolynomials = AllEntities, PolynomialHandle>; + using VerificationKey = VerificationKey_>; /** * @brief A field element for each entity of the flavor. These entities represent the prover polynomials evaluated * at one point. */ - class AllValues : public AllEntities { + class AllValues : public AllEntities { public: - using Base = AllEntities; + using Base = AllEntities; using Base::Base; }; /** * @brief An owning container of polynomials. * @warning When this was introduced it broke some of our design principles. - * - Execution trace builders don't handle "polynomials" because the interpretation of the execution trace columns - * as polynomials is a detail of the proving system, and trace builders are (sometimes in practice, always in - * principle) reusable for different proving protocols (e.g., Plonk and Honk). + * - Execution trace builders don't handle "polynomials" because the interpretation of the execution trace + * columns as polynomials is a detail of the proving system, and trace builders are (sometimes in practice, + * always in principle) reusable for different proving protocols (e.g., Plonk and Honk). * - Polynomial storage is handled by key classes. Polynomials aren't moved, but are accessed elsewhere by * std::spans. * * We will consider revising this data model: TODO(https://github.com/AztecProtocol/barretenberg/issues/743) */ - class AllPolynomials : public AllEntities { + class AllPolynomials : public AllEntities { public: [[nodiscard]] size_t get_polynomial_size() const { return this->lagrange_first.size(); } AllValues get_row(const size_t row_idx) const { AllValues result; - for (auto [result_field, polynomial] : zip_view(result.pointer_view(), this->pointer_view())) { - *result_field = (*polynomial)[row_idx]; + for (auto [result_field, polynomial] : zip_view(result.get_all(), this->get_all())) { + result_field = polynomial[row_idx]; } return result; } }; /** - * @brief A container for polynomials produced after the first round of sumcheck. - * @todo TODO(#394) Use polynomial classes for guaranteed memory alignment. + * @brief A container for polynomials handles; only stores spans. */ - using RowPolynomials = AllEntities; + class ProverPolynomials : public AllEntities { + public: + [[nodiscard]] size_t get_polynomial_size() const { return enable_tuple_set_permutation.size(); } + [[nodiscard]] AllValues get_row(const size_t row_idx) const + { + AllValues result; + for (auto [result_field, polynomial] : zip_view(result.get_all(), get_all())) { + result_field = polynomial[row_idx]; + } + return result; + } + }; /** * @brief A container for storing the partially evaluated multivariates produced by sumcheck. */ - class PartiallyEvaluatedMultivariates : public AllEntities { + class PartiallyEvaluatedMultivariates : public AllEntities { public: PartiallyEvaluatedMultivariates() = default; PartiallyEvaluatedMultivariates(const size_t circuit_size) { // Storage is only needed after the first partial evaluation, hence polynomials of size (n / 2) - for (auto* poly : this->pointer_view()) { - *poly = Polynomial(circuit_size / 2); + for (auto& poly : this->get_all()) { + poly = Polynomial(circuit_size / 2); } } }; - /** - * @brief A container for univariates used during sumcheck. + * @brief A container for univariates used during Protogalaxy folding and sumcheck. + * @details During folding and sumcheck, the prover evaluates the relations on these univariates. */ - template - using ProverUnivariates = AllEntities, barretenberg::Univariate>; + template using ProverUnivariates = AllEntities>; /** * @brief A container for univariates produced during the hot loop in sumcheck. @@ -292,23 +279,10 @@ class ToyAVM { using ExtendedEdges = ProverUnivariates; /** - * @brief A container for the prover polynomials handles; only stores spans. + * @brief A container for the witness commitments. */ - class ProverPolynomials : public AllEntities { - public: - /** - * @brief Returns the evaluations of all prover polynomials at one point on the boolean hypercube, which - * represents one row in the execution trace. - */ - AllValues get_row(const size_t row_idx) - { - AllValues result; - for (auto [result_field, polynomial] : zip_view(result.pointer_view(), this->pointer_view())) { - *result_field = (*polynomial)[row_idx]; - } - return result; - } - }; + + using WitnessCommitments = WitnessEntities; /** * @brief A container for commitment labels. @@ -316,13 +290,13 @@ class ToyAVM { * has, however, been useful during debugging to have these labels available. * */ - class CommitmentLabels : public AllEntities { + class CommitmentLabels : public AllEntities { private: - using Base = AllEntities; + using Base = AllEntities; public: CommitmentLabels() - : AllEntities() + : AllEntities() { Base::permutation_set_column_1 = "PERMUTATION_SET_COLUMN_1"; Base::permutation_set_column_2 = "PERMUTATION_SET_COLUMN_2"; @@ -332,19 +306,24 @@ class ToyAVM { // The ones beginning with "__" are only used for debugging Base::lagrange_first = "__LAGRANGE_FIRST"; Base::enable_tuple_set_permutation = "__ENABLE_SET_PERMUTATION"; + Base::enable_single_column_permutation = "__ENABLE_SINGLE_COLUMN_PERMUTATION"; + Base::enable_first_set_permutation = "__ENABLE_FIRST_SET_PERMUTATION"; + Base::enable_second_set_permutation = "__ENABLE_SECOND_SET_PERMUTATION"; + permutation_set_column_1, permutation_set_column_2, permutation_set_column_3, permutation_set_column_4, + self_permutation_column, tuple_permutation_inverses, single_permutation_inverses }; }; - class VerifierCommitments : public AllEntities { - private: - using Base = AllEntities; + class VerifierCommitments : public 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; + lagrange_first = verification_key->lagrange_first; + enable_tuple_set_permutation = verification_key->enable_tuple_set_permutation; + enable_single_column_permutation = verification_key->enable_single_column_permutation; + enable_first_set_permutation = verification_key->enable_first_set_permutation; + enable_second_set_permutation = verification_key->enable_second_set_permutation; } }; @@ -352,7 +331,7 @@ class ToyAVM { * @brief Derived class that defines proof structure for ECCVM proofs, as well as supporting functions. * */ - class Transcript : public BaseTranscript { + class Transcript : public BaseTranscript { public: uint32_t circuit_size; Commitment column_0_comm; @@ -368,63 +347,20 @@ class ToyAVM { Transcript() = default; Transcript(const std::vector& proof) - : BaseTranscript(proof) + : BaseTranscript(proof) {} - void deserialize_full_transcript() override + void deserialize_full_transcript() { // TODO. Codepath is dead for now, because there is no composer abort(); // take current proof and put them into the struct - size_t num_bytes_read = 0; - circuit_size = BaseTranscript::template deserialize_from_buffer( - BaseTranscript::proof_data, num_bytes_read); - size_t log_n = numeric::get_msb(circuit_size); - column_0_comm = BaseTranscript::template deserialize_from_buffer( - BaseTranscript::proof_data, num_bytes_read); - column_1_comm = BaseTranscript::template deserialize_from_buffer( - BaseTranscript::proof_data, num_bytes_read); - permutation_inverses_comm = BaseTranscript::template 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>( - proof_data, num_bytes_read)); - } - sumcheck_evaluations = - deserialize_from_buffer>(proof_data, num_bytes_read); - for (size_t i = 0; i < log_n; ++i) { - zm_cq_comms.push_back(deserialize_from_buffer(proof_data, num_bytes_read)); - } - zm_cq_comm = deserialize_from_buffer(proof_data, num_bytes_read); - zm_pi_comm = deserialize_from_buffer(proof_data, num_bytes_read); } - void serialize_full_transcript() override + void serialize_full_transcript() { // TODO. Codepath is dead for now, because there is no composer abort(); - size_t old_proof_length = BaseTranscript::proof_data.size(); - BaseTranscript::proof_data.clear(); - size_t log_n = numeric::get_msb(circuit_size); - - BaseTranscript::template serialize_to_buffer(circuit_size, BaseTranscript::proof_data); - BaseTranscript::template serialize_to_buffer(column_0_comm, BaseTranscript::proof_data); - BaseTranscript::template serialize_to_buffer(column_1_comm, BaseTranscript::proof_data); - BaseTranscript::template serialize_to_buffer(permutation_inverses_comm, BaseTranscript::proof_data); - for (size_t i = 0; i < log_n; ++i) { - BaseTranscript::template serialize_to_buffer(sumcheck_univariates[i], proof_data); - } - BaseTranscript::template serialize_to_buffer(sumcheck_evaluations, proof_data); - for (size_t i = 0; i < log_n; ++i) { - BaseTranscript::template serialize_to_buffer(zm_cq_comms[i], proof_data); - } - BaseTranscript::template serialize_to_buffer(zm_cq_comm, proof_data); - BaseTranscript::template serialize_to_buffer(zm_pi_comm, proof_data); - - // sanity check to make sure we generate the same length of proof as before. - ASSERT(proof_data.size() == old_proof_length); } }; }; diff --git a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/toy_avm/toy_avm_circuit_builder.hpp b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/toy_avm/toy_avm_circuit_builder.hpp index c5e4a8758e00..ade2b40bdf12 100644 --- a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/toy_avm/toy_avm_circuit_builder.hpp +++ b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/toy_avm/toy_avm_circuit_builder.hpp @@ -53,8 +53,8 @@ template class ToyAVMCircuitBuilder { size_t num_gates_pow2 = 1UL << (num_gates_log2 + (1UL << num_gates_log2 == num_gates ? 0 : 1)); AllPolynomials polys; - for (auto* poly : polys.pointer_view()) { - *poly = Polynomial(num_gates_pow2); + for (auto& poly : polys.get_all()) { + poly = Polynomial(num_gates_pow2); } polys.lagrange_first[0] = 1; diff --git a/barretenberg/cpp/src/barretenberg/vm/generated/AvmMini_prover.cpp b/barretenberg/cpp/src/barretenberg/vm/generated/AvmMini_prover.cpp index 913dc1219887..b7daa36ddb31 100644 --- a/barretenberg/cpp/src/barretenberg/vm/generated/AvmMini_prover.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/generated/AvmMini_prover.cpp @@ -3,7 +3,7 @@ #include "AvmMini_prover.hpp" #include "barretenberg/commitment_schemes/claim.hpp" #include "barretenberg/commitment_schemes/commitment_key.hpp" -#include "barretenberg/honk/proof_system/lookup_library.hpp" +#include "barretenberg/honk/proof_system/logderivative_library.hpp" #include "barretenberg/honk/proof_system/permutation_library.hpp" #include "barretenberg/honk/proof_system/power_polynomial.hpp" #include "barretenberg/polynomials/polynomial.hpp" diff --git a/barretenberg/cpp/src/barretenberg/vm/generated/Fib_prover.cpp b/barretenberg/cpp/src/barretenberg/vm/generated/Fib_prover.cpp index b8cd3fe89077..a5ade6bdf007 100644 --- a/barretenberg/cpp/src/barretenberg/vm/generated/Fib_prover.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/generated/Fib_prover.cpp @@ -3,7 +3,7 @@ #include "Fib_prover.hpp" #include "barretenberg/commitment_schemes/claim.hpp" #include "barretenberg/commitment_schemes/commitment_key.hpp" -#include "barretenberg/honk/proof_system/lookup_library.hpp" +#include "barretenberg/honk/proof_system/logderivative_library.hpp" #include "barretenberg/honk/proof_system/permutation_library.hpp" #include "barretenberg/honk/proof_system/power_polynomial.hpp" #include "barretenberg/polynomials/polynomial.hpp" From b00dc64e3f2e36a8f43bdf16f3f09033c1c9d69e Mon Sep 17 00:00:00 2001 From: Rumata888 Date: Wed, 6 Dec 2023 15:42:27 +0000 Subject: [PATCH 14/15] Labels --- barretenberg/cpp/src/barretenberg/flavor/toy_avm.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/flavor/toy_avm.hpp b/barretenberg/cpp/src/barretenberg/flavor/toy_avm.hpp index 89b4249ba80d..ba0c7c2b465d 100644 --- a/barretenberg/cpp/src/barretenberg/flavor/toy_avm.hpp +++ b/barretenberg/cpp/src/barretenberg/flavor/toy_avm.hpp @@ -302,15 +302,15 @@ class ToyAVM { Base::permutation_set_column_2 = "PERMUTATION_SET_COLUMN_2"; Base::permutation_set_column_3 = "PERMUTATION_SET_COLUMN_3"; Base::permutation_set_column_4 = "PERMUTATION_SET_COLUMN_4"; + Base::self_permutation_column = "SELF_PERMUTATION_COLUMN"; Base::tuple_permutation_inverses = "TUPLE_PERMUTATION_INVERSES"; + Base::single_permutation_inverses = "SINGLE_PERMUTATION_INVERSES"; // The ones beginning with "__" are only used for debugging Base::lagrange_first = "__LAGRANGE_FIRST"; Base::enable_tuple_set_permutation = "__ENABLE_SET_PERMUTATION"; Base::enable_single_column_permutation = "__ENABLE_SINGLE_COLUMN_PERMUTATION"; Base::enable_first_set_permutation = "__ENABLE_FIRST_SET_PERMUTATION"; Base::enable_second_set_permutation = "__ENABLE_SECOND_SET_PERMUTATION"; - permutation_set_column_1, permutation_set_column_2, permutation_set_column_3, permutation_set_column_4, - self_permutation_column, tuple_permutation_inverses, single_permutation_inverses }; }; From a35b65cd515a6d883cb2d4ff3449819898f2e7cb Mon Sep 17 00:00:00 2001 From: Rumata888 Date: Wed, 6 Dec 2023 16:02:33 +0000 Subject: [PATCH 15/15] FIx --- .../circuit_builder/toy_avm/toy_avm_circuit_builder.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/toy_avm/toy_avm_circuit_builder.hpp b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/toy_avm/toy_avm_circuit_builder.hpp index ade2b40bdf12..659187b41313 100644 --- a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/toy_avm/toy_avm_circuit_builder.hpp +++ b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/toy_avm/toy_avm_circuit_builder.hpp @@ -22,7 +22,7 @@ namespace proof_system { */ template class ToyAVMCircuitBuilder { public: - using FF = Flavor::FF; + using FF = typename Flavor::FF; using Polynomial = typename Flavor::Polynomial; static constexpr size_t NUM_POLYNOMIALS = Flavor::NUM_ALL_ENTITIES;