From c52acf64cf00443867f8f578a1c25cda49583faf Mon Sep 17 00:00:00 2001 From: Maddiaa <47148561+Maddiaa0@users.noreply.github.com> Date: Thu, 14 Dec 2023 11:18:35 +0000 Subject: [PATCH] feat(avm-main): pil -> permutations (#3650) Replacing the toy_avm with a pil version that defines a permutation in pil. ``` pol commit q_tuple_set; // Set 1 pol commit set_1_column_1; pol commit set_1_column_2; // Set 2 pol commit set_2_column_1; pol commit set_2_column_2; // This is a column based tuple permutation #[two_column_perm] // the name of the inverse polynomial q_tuple_set { set_1_column_1, set_1_column_2 } is { set_2_column_1, set_2_column_2 }; ``` Syntax is as shown. --- barretenberg/.gitignore | 3 +- barretenberg/cpp/pil/avm/toy_avm.pil | 20 + .../flavor/generated/AvmMini_flavor.hpp | 18 +- .../flavor/generated/Toy_flavor.hpp | 304 ++++++++++++++ .../cpp/src/barretenberg/flavor/toy_avm.hpp | 376 ------------------ .../proof_system/logderivative_library.hpp | 2 +- .../generated/AvmMini_circuit_builder.hpp | 12 +- .../generated/Toy_circuit_builder.hpp | 163 ++++++++ .../toy_avm/toy_avm_circuit_builder.hpp | 163 -------- .../toy_avm/toy_avm_circuit_builder.test.cpp | 47 ++- .../relations/generated/AvmMini/avm_mini.hpp | 60 +-- .../generated/AvmMini/declare_views.hpp | 6 +- .../relations/generated/AvmMini/mem_trace.hpp | 16 +- .../relations/generated/Toy/declare_views.hpp | 13 + .../relations/generated/Toy/toy_avm.hpp | 42 ++ .../generated/Toy/two_column_perm.hpp | 94 +++++ .../generic_permutation_relation.hpp | 10 +- .../toy_avm/generic_permutation_relation.cpp | 34 -- .../relations/toy_avm/relation_definer.hpp | 213 ---------- .../vm/generated/AvmMini_prover.cpp | 7 +- .../vm/generated/Toy_composer.cpp | 89 +++++ .../vm/generated/Toy_composer.hpp | 69 ++++ .../barretenberg/vm/generated/Toy_prover.cpp | 136 +++++++ .../barretenberg/vm/generated/Toy_prover.hpp | 62 +++ .../vm/generated/Toy_verifier.cpp | 99 +++++ .../vm/generated/Toy_verifier.hpp | 33 ++ 26 files changed, 1225 insertions(+), 866 deletions(-) create mode 100644 barretenberg/cpp/pil/avm/toy_avm.pil create mode 100644 barretenberg/cpp/src/barretenberg/flavor/generated/Toy_flavor.hpp delete mode 100644 barretenberg/cpp/src/barretenberg/flavor/toy_avm.hpp create mode 100644 barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/generated/Toy_circuit_builder.hpp delete mode 100644 barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/toy_avm/toy_avm_circuit_builder.hpp create mode 100644 barretenberg/cpp/src/barretenberg/relations/generated/Toy/declare_views.hpp create mode 100644 barretenberg/cpp/src/barretenberg/relations/generated/Toy/toy_avm.hpp create mode 100644 barretenberg/cpp/src/barretenberg/relations/generated/Toy/two_column_perm.hpp rename barretenberg/cpp/src/barretenberg/relations/{toy_avm => generic_permutation}/generic_permutation_relation.hpp (95%) delete mode 100644 barretenberg/cpp/src/barretenberg/relations/toy_avm/generic_permutation_relation.cpp delete mode 100644 barretenberg/cpp/src/barretenberg/relations/toy_avm/relation_definer.hpp create mode 100644 barretenberg/cpp/src/barretenberg/vm/generated/Toy_composer.cpp create mode 100644 barretenberg/cpp/src/barretenberg/vm/generated/Toy_composer.hpp create mode 100644 barretenberg/cpp/src/barretenberg/vm/generated/Toy_prover.cpp create mode 100644 barretenberg/cpp/src/barretenberg/vm/generated/Toy_prover.hpp create mode 100644 barretenberg/cpp/src/barretenberg/vm/generated/Toy_verifier.cpp create mode 100644 barretenberg/cpp/src/barretenberg/vm/generated/Toy_verifier.hpp diff --git a/barretenberg/.gitignore b/barretenberg/.gitignore index 77989f790d4..f55585139fd 100644 --- a/barretenberg/.gitignore +++ b/barretenberg/.gitignore @@ -5,4 +5,5 @@ node_modules ts/dest .tsbuildinfo .idea -cmake-build-debug \ No newline at end of file +cmake-build-debug +*_opt.pil \ No newline at end of file diff --git a/barretenberg/cpp/pil/avm/toy_avm.pil b/barretenberg/cpp/pil/avm/toy_avm.pil new file mode 100644 index 00000000000..ed355016195 --- /dev/null +++ b/barretenberg/cpp/pil/avm/toy_avm.pil @@ -0,0 +1,20 @@ +namespace toy(256); + pol commit q_tuple_set; + + // Set 1 + pol commit set_1_column_1; + pol commit set_1_column_2; + // Set 2 + pol commit set_2_column_1; + pol commit set_2_column_2; + + // This is a column based tuple lookup + #[two_column_perm] // the name of the inverse + q_tuple_set { set_1_column_1, set_1_column_2 } is { set_2_column_1, set_2_column_2 }; + + // Relation not used -> we currently require a single relation for codegen + pol commit x; + x' - x = 0; + + // Also needs a fixed relation + pol fixed first = [1] + [0]*; \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/flavor/generated/AvmMini_flavor.hpp b/barretenberg/cpp/src/barretenberg/flavor/generated/AvmMini_flavor.hpp index c3b00281f70..c2b4e385c8f 100644 --- a/barretenberg/cpp/src/barretenberg/flavor/generated/AvmMini_flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/flavor/generated/AvmMini_flavor.hpp @@ -7,6 +7,8 @@ #include "barretenberg/polynomials/barycentric.hpp" #include "barretenberg/polynomials/univariate.hpp" +#include "barretenberg/relations/generic_permutation/generic_permutation_relation.hpp" + #include "barretenberg/flavor/flavor.hpp" #include "barretenberg/flavor/flavor_macros.hpp" #include "barretenberg/polynomials/evaluation_domain.hpp" @@ -40,7 +42,7 @@ class AvmMiniFlavor { // the unshifted and one for the shifted static constexpr size_t NUM_ALL_ENTITIES = 30; - using Relations = std::tuple, AvmMini_vm::mem_trace>; + using Relations = std::tuple, AvmMini_vm::avm_mini>; static constexpr size_t MAX_PARTIAL_RELATION_LENGTH = compute_max_partial_relation_length(); @@ -144,8 +146,8 @@ class AvmMiniFlavor { avmMini_mem_idx_c, avmMini_last, memTrace_m_rw_shift, - memTrace_m_val_shift, - memTrace_m_addr_shift) + memTrace_m_addr_shift, + memTrace_m_val_shift) RefVector get_wires() { @@ -177,8 +179,8 @@ class AvmMiniFlavor { avmMini_mem_idx_c, avmMini_last, memTrace_m_rw_shift, - memTrace_m_val_shift, - memTrace_m_addr_shift }; + memTrace_m_addr_shift, + memTrace_m_val_shift }; }; RefVector get_unshifted() { @@ -210,10 +212,10 @@ class AvmMiniFlavor { avmMini_mem_idx_c, avmMini_last }; }; - RefVector get_to_be_shifted() { return { memTrace_m_rw, memTrace_m_val, memTrace_m_addr }; }; + RefVector get_to_be_shifted() { return { memTrace_m_rw, memTrace_m_addr, memTrace_m_val }; }; RefVector get_shifted() { - return { memTrace_m_rw_shift, memTrace_m_val_shift, memTrace_m_addr_shift }; + return { memTrace_m_rw_shift, memTrace_m_addr_shift, memTrace_m_val_shift }; }; }; @@ -467,4 +469,6 @@ class AvmMiniFlavor { }; } // namespace flavor + +namespace sumcheck {} } // namespace proof_system::honk diff --git a/barretenberg/cpp/src/barretenberg/flavor/generated/Toy_flavor.hpp b/barretenberg/cpp/src/barretenberg/flavor/generated/Toy_flavor.hpp new file mode 100644 index 00000000000..540d9107b82 --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/flavor/generated/Toy_flavor.hpp @@ -0,0 +1,304 @@ + + +#pragma once +#include "../relation_definitions_fwd.hpp" +#include "barretenberg/commitment_schemes/kzg/kzg.hpp" +#include "barretenberg/ecc/curves/bn254/g1.hpp" +#include "barretenberg/polynomials/barycentric.hpp" +#include "barretenberg/polynomials/univariate.hpp" + +#include "barretenberg/relations/generic_permutation/generic_permutation_relation.hpp" + +#include "barretenberg/flavor/flavor.hpp" +#include "barretenberg/flavor/flavor_macros.hpp" +#include "barretenberg/polynomials/evaluation_domain.hpp" +#include "barretenberg/polynomials/polynomial.hpp" +#include "barretenberg/relations/generated/Toy/toy_avm.hpp" +#include "barretenberg/relations/generated/Toy/two_column_perm.hpp" +#include "barretenberg/transcript/transcript.hpp" + +namespace proof_system::honk { +namespace flavor { + +class ToyFlavor { + public: + using Curve = curve::BN254; + using G1 = Curve::Group; + using PCS = pcs::kzg::KZG; + + using FF = G1::subgroup_field; + using Polynomial = barretenberg::Polynomial; + using PolynomialHandle = std::span; + using GroupElement = G1::element; + using Commitment = G1::affine_element; + using CommitmentHandle = G1::affine_element; + using CommitmentKey = pcs::CommitmentKey; + using VerifierCommitmentKey = pcs::VerifierCommitmentKey; + + static constexpr size_t NUM_PRECOMPUTED_ENTITIES = 1; + static constexpr size_t NUM_WITNESS_ENTITIES = 7; + static constexpr size_t NUM_WIRES = NUM_WITNESS_ENTITIES + NUM_PRECOMPUTED_ENTITIES; + // We have two copies of the witness entities, so we subtract the number of fixed ones (they have no shift), one for + // the unshifted and one for the shifted + static constexpr size_t NUM_ALL_ENTITIES = 9; + + using Relations = std::tuple, sumcheck::two_column_perm_relation>; + + 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; + + template + using ProtogalaxyTupleOfTuplesOfUnivariates = + decltype(create_protogalaxy_tuple_of_tuples_of_univariates()); + using SumcheckTupleOfTuplesOfUnivariates = decltype(create_sumcheck_tuple_of_tuples_of_univariates()); + using TupleOfArraysOfValues = decltype(create_tuple_of_arrays_of_values()); + + static constexpr bool has_zero_row = true; + + private: + template class PrecomputedEntities : public PrecomputedEntitiesBase { + public: + using DataType = DataType_; + + DEFINE_FLAVOR_MEMBERS(DataType, toy_first) + + RefVector get_selectors() { return { toy_first }; }; + RefVector get_sigma_polynomials() { return {}; }; + RefVector get_id_polynomials() { return {}; }; + RefVector get_table_polynomials() { return {}; }; + }; + + template class WitnessEntities { + public: + DEFINE_FLAVOR_MEMBERS(DataType, + toy_q_tuple_set, + toy_set_1_column_1, + toy_set_1_column_2, + toy_set_2_column_1, + toy_set_2_column_2, + toy_x, + two_column_perm) + + RefVector get_wires() + { + return { toy_q_tuple_set, toy_set_1_column_1, toy_set_1_column_2, toy_set_2_column_1, toy_set_2_column_2, + toy_x, two_column_perm }; + }; + RefVector get_sorted_polynomials() { return {}; }; + }; + + template class AllEntities { + public: + DEFINE_FLAVOR_MEMBERS(DataType, + toy_first, + toy_q_tuple_set, + toy_set_1_column_1, + toy_set_1_column_2, + toy_set_2_column_1, + toy_set_2_column_2, + toy_x, + two_column_perm, + toy_x_shift) + + RefVector get_wires() + { + return { toy_first, toy_q_tuple_set, toy_set_1_column_1, toy_set_1_column_2, toy_set_2_column_1, + toy_set_2_column_2, toy_x, two_column_perm, toy_x_shift }; + }; + RefVector get_unshifted() + { + return { toy_first, toy_q_tuple_set, toy_set_1_column_1, toy_set_1_column_2, toy_set_2_column_1, + toy_set_2_column_2, toy_x, two_column_perm }; + }; + RefVector get_to_be_shifted() { return { toy_x }; }; + RefVector get_shifted() { return { toy_x_shift }; }; + }; + + public: + 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 {}; }; + }; + + using VerificationKey = VerificationKey_>; + + using ProverPolynomials = AllEntities; + + using FoldedPolynomials = AllEntities>; + + class AllValues : public AllEntities { + public: + using Base = AllEntities; + using Base::Base; + }; + + class AllPolynomials : public AllEntities { + public: + [[nodiscard]] size_t get_polynomial_size() const { return this->toy_q_tuple_set.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; + } + }; + + using RowPolynomials = 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 : get_all()) { + poly = Polynomial(circuit_size / 2); + } + } + }; + + /** + * @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>; + + /** + * @brief A container for univariates produced during the hot loop in sumcheck. + */ + using ExtendedEdges = ProverUnivariates; + + class CommitmentLabels : public AllEntities { + private: + using Base = AllEntities; + + public: + CommitmentLabels() + : AllEntities() + { + Base::toy_first = "TOY_FIRST"; + Base::toy_q_tuple_set = "TOY_Q_TUPLE_SET"; + Base::toy_set_1_column_1 = "TOY_SET_1_COLUMN_1"; + Base::toy_set_1_column_2 = "TOY_SET_1_COLUMN_2"; + Base::toy_set_2_column_1 = "TOY_SET_2_COLUMN_1"; + Base::toy_set_2_column_2 = "TOY_SET_2_COLUMN_2"; + Base::toy_x = "TOY_X"; + Base::two_column_perm = "TWO_COLUMN_PERM"; + }; + }; + + class VerifierCommitments : public AllEntities { + private: + using Base = AllEntities; + + public: + VerifierCommitments(const std::shared_ptr& verification_key) + { + toy_first = verification_key->toy_first; + } + }; + + class Transcript : public BaseTranscript { + public: + uint32_t circuit_size; + + Commitment toy_q_tuple_set; + Commitment toy_set_1_column_1; + Commitment toy_set_1_column_2; + Commitment toy_set_2_column_1; + Commitment toy_set_2_column_2; + Commitment toy_x; + Commitment two_column_perm; + + 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() + { + size_t num_bytes_read = 0; + circuit_size = deserialize_from_buffer(proof_data, num_bytes_read); + size_t log_n = numeric::get_msb(circuit_size); + + toy_q_tuple_set = deserialize_from_buffer(Transcript::proof_data, num_bytes_read); + toy_set_1_column_1 = deserialize_from_buffer(Transcript::proof_data, num_bytes_read); + toy_set_1_column_2 = deserialize_from_buffer(Transcript::proof_data, num_bytes_read); + toy_set_2_column_1 = deserialize_from_buffer(Transcript::proof_data, num_bytes_read); + toy_set_2_column_2 = deserialize_from_buffer(Transcript::proof_data, num_bytes_read); + toy_x = deserialize_from_buffer(Transcript::proof_data, num_bytes_read); + two_column_perm = deserialize_from_buffer(Transcript::proof_data, num_bytes_read); + + for (size_t i = 0; i < log_n; ++i) { + sumcheck_univariates.emplace_back( + deserialize_from_buffer>( + Transcript::proof_data, num_bytes_read)); + } + sumcheck_evaluations = + deserialize_from_buffer>(Transcript::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() + { + size_t old_proof_length = proof_data.size(); + Transcript::proof_data.clear(); + size_t log_n = numeric::get_msb(circuit_size); + + serialize_to_buffer(circuit_size, Transcript::proof_data); + + serialize_to_buffer(toy_q_tuple_set, Transcript::proof_data); + serialize_to_buffer(toy_set_1_column_1, Transcript::proof_data); + serialize_to_buffer(toy_set_1_column_2, Transcript::proof_data); + serialize_to_buffer(toy_set_2_column_1, Transcript::proof_data); + serialize_to_buffer(toy_set_2_column_2, Transcript::proof_data); + serialize_to_buffer(toy_x, Transcript::proof_data); + serialize_to_buffer(two_column_perm, Transcript::proof_data); + + for (size_t i = 0; i < log_n; ++i) { + serialize_to_buffer(sumcheck_univariates[i], Transcript::proof_data); + } + serialize_to_buffer(sumcheck_evaluations, Transcript::proof_data); + for (size_t i = 0; i < log_n; ++i) { + serialize_to_buffer(zm_cq_comms[i], proof_data); + } + serialize_to_buffer(zm_cq_comm, proof_data); + 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); + } + }; +}; + +} // namespace flavor + +namespace sumcheck { + +DECLARE_SUMCHECK_RELATION_CLASS(two_column_perm, flavor::ToyFlavor); + +} +} // namespace proof_system::honk diff --git a/barretenberg/cpp/src/barretenberg/flavor/toy_avm.hpp b/barretenberg/cpp/src/barretenberg/flavor/toy_avm.hpp deleted file mode 100644 index ba0c7c2b465..00000000000 --- a/barretenberg/cpp/src/barretenberg/flavor/toy_avm.hpp +++ /dev/null @@ -1,376 +0,0 @@ -#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/flavor/flavor_macros.hpp" -#include "barretenberg/polynomials/univariate.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 -#include -#include -#include -#include - -// NOLINTBEGIN(cppcoreguidelines-avoid-const-or-ref-data-members) - -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 ToyAVM { - 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; - - // 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 = 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 = 5; - // The total number of witness entities not including shifts. - static constexpr size_t NUM_WITNESS_ENTITIES = 7; - - // 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 PrecomputedEntitiesBase { - public: - 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: - 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, - permutation_set_column_3, - permutation_set_column_4, - self_permutation_column }; - }; - }; - - /** - * @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: - 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 - }; - }; - RefVector get_unshifted() - { - 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 }; - }; - RefVector get_to_be_shifted() { return {}; }; - RefVector get_shifted() { 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 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.get_all(), this->get_all())) { - result_field = polynomial[row_idx]; - } - return result; - } - }; - /** - * @brief A container for polynomials handles; only stores spans. - */ - 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 { - - 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->get_all()) { - poly = Polynomial(circuit_size / 2); - } - } - }; - /** - * @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>; - - /** - * @brief A container for univariates produced during the hot loop in sumcheck. - */ - using ExtendedEdges = ProverUnivariates; - - /** - * @brief A container for the witness commitments. - */ - - using WitnessCommitments = WitnessEntities; - - /** - * @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_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"; - }; - }; - - class VerifierCommitments : public AllEntities { - - public: - VerifierCommitments(const std::shared_ptr& verification_key) - { - 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; - } - }; - - /** - * @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() - { - // TODO. Codepath is dead for now, because there is no composer - abort(); - // take current proof and put them into the struct - } - - void serialize_full_transcript() - { - // TODO. Codepath is dead for now, because there is no composer - abort(); - } - }; -}; - -// NOLINTEND(cppcoreguidelines-avoid-const-or-ref-data-members) - -} // namespace flavor -namespace sumcheck { - -DECLARE_IMPLEMENTATIONS_FOR_ALL_SETTINGS(GenericPermutationRelationImpl, flavor::ToyAVM) - -} // namespace sumcheck -} // namespace proof_system::honk 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 4a86cf74075..b4dff8157ba 100644 --- a/barretenberg/cpp/src/barretenberg/honk/proof_system/logderivative_library.hpp +++ b/barretenberg/cpp/src/barretenberg/honk/proof_system/logderivative_library.hpp @@ -6,7 +6,7 @@ namespace proof_system::honk::logderivative_library { /** * @brief Compute the inverse polynomial I(X) required for logderivative lookups * * - * @details + * details * Inverse may be defined in terms of its values on X_i = 0,1,...,n-1 as Z_perm[0] = 1 and for i = 1:n-1 * 1 1 * Inverse[i] = ∏ -------------------------- * ∏' -------------------------- diff --git a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/generated/AvmMini_circuit_builder.hpp b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/generated/AvmMini_circuit_builder.hpp index 46cabaa1a0e..8470c2f7b5c 100644 --- a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/generated/AvmMini_circuit_builder.hpp +++ b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/generated/AvmMini_circuit_builder.hpp @@ -3,9 +3,12 @@ // AUTOGENERATED FILE #pragma once +#include "barretenberg/common/constexpr_utils.hpp" #include "barretenberg/common/throw_or_abort.hpp" #include "barretenberg/ecc/curves/bn254/fr.hpp" +#include "barretenberg/honk/proof_system/logderivative_library.hpp" #include "barretenberg/proof_system/circuit_builder/circuit_builder_base.hpp" +#include "barretenberg/relations/generic_permutation/generic_permutation_relation.hpp" #include "barretenberg/flavor/generated/AvmMini_flavor.hpp" #include "barretenberg/relations/generated/AvmMini/avm_mini.hpp" @@ -44,8 +47,8 @@ template struct AvmMiniFullRow { FF avmMini_mem_idx_c{}; FF avmMini_last{}; FF memTrace_m_rw_shift{}; - FF memTrace_m_val_shift{}; FF memTrace_m_addr_shift{}; + FF memTrace_m_val_shift{}; }; class AvmMiniCircuitBuilder { @@ -105,14 +108,15 @@ class AvmMiniCircuitBuilder { } polys.memTrace_m_rw_shift = Polynomial(polys.memTrace_m_rw.shifted()); - polys.memTrace_m_val_shift = Polynomial(polys.memTrace_m_val.shifted()); polys.memTrace_m_addr_shift = Polynomial(polys.memTrace_m_addr.shifted()); + polys.memTrace_m_val_shift = Polynomial(polys.memTrace_m_val.shifted()); return polys; } [[maybe_unused]] bool check_circuit() { + auto polys = compute_polynomials(); const size_t num_rows = polys.get_polynomial_size(); @@ -141,10 +145,10 @@ class AvmMiniCircuitBuilder { return true; }; - if (!evaluate_relation.template operator()>("avm_mini")) { + if (!evaluate_relation.template operator()>("mem_trace")) { return false; } - if (!evaluate_relation.template operator()>("mem_trace")) { + if (!evaluate_relation.template operator()>("avm_mini")) { return false; } diff --git a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/generated/Toy_circuit_builder.hpp b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/generated/Toy_circuit_builder.hpp new file mode 100644 index 00000000000..fade5a864e9 --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/generated/Toy_circuit_builder.hpp @@ -0,0 +1,163 @@ + + +// AUTOGENERATED FILE +#pragma once + +#include "barretenberg/common/constexpr_utils.hpp" +#include "barretenberg/common/throw_or_abort.hpp" +#include "barretenberg/ecc/curves/bn254/fr.hpp" +#include "barretenberg/honk/proof_system/logderivative_library.hpp" +#include "barretenberg/proof_system/circuit_builder/circuit_builder_base.hpp" +#include "barretenberg/relations/generic_permutation/generic_permutation_relation.hpp" + +#include "barretenberg/flavor/generated/Toy_flavor.hpp" +#include "barretenberg/relations/generated/Toy/toy_avm.hpp" +#include "barretenberg/relations/generated/Toy/two_column_perm.hpp" + +using namespace barretenberg; + +namespace proof_system { + +template struct ToyFullRow { + FF toy_first{}; + FF toy_q_tuple_set{}; + FF toy_set_1_column_1{}; + FF toy_set_1_column_2{}; + FF toy_set_2_column_1{}; + FF toy_set_2_column_2{}; + FF toy_x{}; + FF two_column_perm{}; + FF toy_x_shift{}; +}; + +class ToyCircuitBuilder { + public: + using Flavor = proof_system::honk::flavor::ToyFlavor; + using FF = Flavor::FF; + using Row = ToyFullRow; + + // TODO: template + using Polynomial = Flavor::Polynomial; + using AllPolynomials = Flavor::AllPolynomials; + + static constexpr size_t num_fixed_columns = 9; + static constexpr size_t num_polys = 8; + std::vector rows; + + void set_trace(std::vector&& trace) { rows = std::move(trace); } + + AllPolynomials compute_polynomials() + { + const auto num_rows = get_circuit_subgroup_size(); + AllPolynomials polys; + + // Allocate mem for each column + for (auto& poly : polys.get_all()) { + poly = Polynomial(num_rows); + } + + for (size_t i = 0; i < rows.size(); i++) { + polys.toy_first[i] = rows[i].toy_first; + polys.toy_q_tuple_set[i] = rows[i].toy_q_tuple_set; + polys.toy_set_1_column_1[i] = rows[i].toy_set_1_column_1; + polys.toy_set_1_column_2[i] = rows[i].toy_set_1_column_2; + polys.toy_set_2_column_1[i] = rows[i].toy_set_2_column_1; + polys.toy_set_2_column_2[i] = rows[i].toy_set_2_column_2; + polys.toy_x[i] = rows[i].toy_x; + polys.two_column_perm[i] = rows[i].two_column_perm; + } + + polys.toy_x_shift = Polynomial(polys.toy_x.shifted()); + + return polys; + } + + [[maybe_unused]] bool check_circuit() + { + + const FF gamma = FF::random_element(); + const FF beta = FF::random_element(); + proof_system::RelationParameters params{ + .eta = 0, + .beta = beta, + .gamma = gamma, + .public_input_delta = 0, + .lookup_grand_product_delta = 0, + .beta_sqr = 0, + .beta_cube = 0, + .eccvm_set_permutation_delta = 0, + }; + + auto polys = compute_polynomials(); + const size_t num_rows = polys.get_polynomial_size(); + + 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, polys.get_row(i), {}, 1); + + bool x = true; + for (size_t j = 0; j < NUM_SUBRELATIONS; ++j) { + if (result[j] != 0) { + throw_or_abort( + format("Relation ", relation_name, ", subrelation index ", j, " failed at row ", i)); + x = false; + } + } + if (!x) { + return false; + } + } + return true; + }; + + const auto evaluate_permutation = [&](const std::string& permutation_name) { + // Check the tuple permutation relation + proof_system::honk::logderivative_library::compute_logderivative_inverse( + polys, params, num_rows); + + typename PermutationSettings::SumcheckArrayOfValuesOverSubrelations permutation_result; + + for (auto& r : permutation_result) { + r = 0; + } + for (size_t i = 0; i < num_rows; ++i) { + PermutationSettings::accumulate(permutation_result, polys.get_row(i), params, 1); + } + for (auto r : permutation_result) { + if (r != 0) { + info("Tuple", permutation_name, "failed."); + return false; + } + } + return true; + }; + + if (!evaluate_relation.template operator()>("toy_avm")) { + return false; + } + + if (!evaluate_permutation.template operator()>( + "two_column_perm")) { + return false; + } + + return true; + } + + [[nodiscard]] size_t get_num_gates() const { return rows.size(); } + + [[nodiscard]] size_t get_circuit_subgroup_size() const + { + const size_t num_rows = get_num_gates(); + 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/toy_avm/toy_avm_circuit_builder.hpp b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/toy_avm/toy_avm_circuit_builder.hpp deleted file mode 100644 index 659187b4131..00000000000 --- a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/toy_avm/toy_avm_circuit_builder.hpp +++ /dev/null @@ -1,163 +0,0 @@ -/** - * @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/common/constexpr_utils.hpp" -#include "barretenberg/ecc/curves/bn254/fr.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 { - -/** - * @brief Circuit builder for the ToyAVM that is used to explain generic permutation settings - * - * @tparam Flavor - */ -template class ToyAVMCircuitBuilder { - 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; - ToyAVMCircuitBuilder() = 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.get_all()) { - poly = Polynomial(num_gates_pow2); - } - - 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]; - 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_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); - } - return polys; - } - - /** - * @brief Check that the circuit is correct (proof should work) - * - */ - 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(); - proof_system::RelationParameters params{ - .eta = 0, - .beta = beta, - .gamma = gamma, - .public_input_delta = 0, - .lookup_grand_product_delta = 0, - .beta_sqr = 0, - .beta_cube = 0, - .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, - 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; - } - 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("Tuple GenericPermutationRelation failed."); - return false; - } - } - // Check the single permutation relation - 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; - } - } - 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/toy_avm/toy_avm_circuit_builder.test.cpp b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/toy_avm/toy_avm_circuit_builder.test.cpp index 62b2e4d83c3..09750e93df3 100644 --- a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/toy_avm/toy_avm_circuit_builder.test.cpp +++ b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/toy_avm/toy_avm_circuit_builder.test.cpp @@ -1,5 +1,8 @@ -#include "toy_avm_circuit_builder.hpp" +#include "../generated/Toy_circuit_builder.hpp" #include "barretenberg/crypto/generators/generator_data.hpp" +#include "barretenberg/flavor/generated/Toy_flavor.hpp" +#include "barretenberg/proof_system/circuit_builder/generated/Toy_circuit_builder.hpp" + #include using namespace barretenberg; @@ -17,54 +20,54 @@ namespace toy_avm_circuit_builder_tests { TEST(ToyAVMCircuitBuilder, BaseCase) { - using FF = proof_system::honk::flavor::ToyAVM::FF; + using FF = proof_system::honk::flavor::ToyFlavor::FF; + using Builder = proof_system::ToyCircuitBuilder; + using Row = Builder::Row; + Builder circuit_builder; + const size_t circuit_size = 16; - proof_system::ToyAVMCircuitBuilder circuit_builder; + std::vector rows; // Sample 2*16 random elements for the tuple permutation example - std::vector column_0; - std::vector column_1; for (size_t i = 0; i < circuit_size; i++) { - column_0.emplace_back(FF::random_element()); - column_1.emplace_back(FF::random_element()); - } - - // 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()); + Row row{ + .toy_q_tuple_set = 1, + .toy_set_1_column_1 = FF::random_element(), + .toy_set_1_column_2 = FF::random_element(), + }; + rows.push_back(row); } 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] }); + Row& front_row = rows[i]; + Row& back_row = rows[circuit_size - (i + 1)]; + + back_row.toy_set_2_column_1 = front_row.toy_set_1_column_1; + back_row.toy_set_2_column_2 = front_row.toy_set_1_column_2; } // Test that permutations with correct values work + circuit_builder.set_trace(std::move(rows)); bool result = circuit_builder.check_circuit(); EXPECT_EQ(result, true); // Store value temporarily - FF tmp = circuit_builder.wires[0][5]; + FF tmp = circuit_builder.rows[5].toy_set_1_column_1; // 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(); + circuit_builder.rows[5].toy_set_1_column_1 = FF::random_element(); // Check that it fails result = circuit_builder.check_circuit(); EXPECT_EQ(result, false); // Restore value - circuit_builder.wires[0][5] = tmp; + circuit_builder.rows[5].toy_set_1_column_1 = 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 toy_avm_circuit_builder_tests \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/relations/generated/AvmMini/avm_mini.hpp b/barretenberg/cpp/src/barretenberg/relations/generated/AvmMini/avm_mini.hpp index 5596bbc94cf..bb4a3242ae0 100644 --- a/barretenberg/cpp/src/barretenberg/relations/generated/AvmMini/avm_mini.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/generated/AvmMini/avm_mini.hpp @@ -7,21 +7,21 @@ namespace proof_system::AvmMini_vm { template struct Avm_miniRow { - FF avmMini_mem_op_b{}; - FF avmMini_ib{}; - FF avmMini_ic{}; - FF avmMini_sel_op_sub{}; - FF avmMini_mem_op_c{}; - FF avmMini_op_err{}; - FF avmMini_ia{}; - FF avmMini_inv{}; FF avmMini_sel_op_div{}; - FF avmMini_mem_op_a{}; + FF avmMini_ia{}; FF avmMini_rwa{}; + FF avmMini_sel_op_sub{}; + FF avmMini_rwb{}; + FF avmMini_ic{}; + FF avmMini_inv{}; + FF avmMini_sel_op_add{}; + FF avmMini_op_err{}; FF avmMini_sel_op_mul{}; FF avmMini_rwc{}; - FF avmMini_sel_op_add{}; - FF avmMini_rwb{}; + FF avmMini_ib{}; + FF avmMini_mem_op_b{}; + FF avmMini_mem_op_a{}; + FF avmMini_mem_op_c{}; }; template class avm_miniImpl { @@ -29,7 +29,7 @@ template class avm_miniImpl { using FF = FF_; static constexpr std::array SUBRELATION_PARTIAL_LENGTHS{ - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 5, 4, 4, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 3, }; template @@ -41,7 +41,7 @@ template class avm_miniImpl { // Contribution 0 { - DECLARE_VIEWS(0); + AvmMini_DECLARE_VIEWS(0); auto tmp = (avmMini_sel_op_add * (-avmMini_sel_op_add + FF(1))); tmp *= scaling_factor; @@ -49,7 +49,7 @@ template class avm_miniImpl { } // Contribution 1 { - DECLARE_VIEWS(1); + AvmMini_DECLARE_VIEWS(1); auto tmp = (avmMini_sel_op_sub * (-avmMini_sel_op_sub + FF(1))); tmp *= scaling_factor; @@ -57,7 +57,7 @@ template class avm_miniImpl { } // Contribution 2 { - DECLARE_VIEWS(2); + AvmMini_DECLARE_VIEWS(2); auto tmp = (avmMini_sel_op_mul * (-avmMini_sel_op_mul + FF(1))); tmp *= scaling_factor; @@ -65,7 +65,7 @@ template class avm_miniImpl { } // Contribution 3 { - DECLARE_VIEWS(3); + AvmMini_DECLARE_VIEWS(3); auto tmp = (avmMini_sel_op_div * (-avmMini_sel_op_div + FF(1))); tmp *= scaling_factor; @@ -73,7 +73,7 @@ template class avm_miniImpl { } // Contribution 4 { - DECLARE_VIEWS(4); + AvmMini_DECLARE_VIEWS(4); auto tmp = (avmMini_op_err * (-avmMini_op_err + FF(1))); tmp *= scaling_factor; @@ -81,7 +81,7 @@ template class avm_miniImpl { } // Contribution 5 { - DECLARE_VIEWS(5); + AvmMini_DECLARE_VIEWS(5); auto tmp = (avmMini_mem_op_a * (-avmMini_mem_op_a + FF(1))); tmp *= scaling_factor; @@ -89,7 +89,7 @@ template class avm_miniImpl { } // Contribution 6 { - DECLARE_VIEWS(6); + AvmMini_DECLARE_VIEWS(6); auto tmp = (avmMini_mem_op_b * (-avmMini_mem_op_b + FF(1))); tmp *= scaling_factor; @@ -97,7 +97,7 @@ template class avm_miniImpl { } // Contribution 7 { - DECLARE_VIEWS(7); + AvmMini_DECLARE_VIEWS(7); auto tmp = (avmMini_mem_op_c * (-avmMini_mem_op_c + FF(1))); tmp *= scaling_factor; @@ -105,7 +105,7 @@ template class avm_miniImpl { } // Contribution 8 { - DECLARE_VIEWS(8); + AvmMini_DECLARE_VIEWS(8); auto tmp = (avmMini_rwa * (-avmMini_rwa + FF(1))); tmp *= scaling_factor; @@ -113,7 +113,7 @@ template class avm_miniImpl { } // Contribution 9 { - DECLARE_VIEWS(9); + AvmMini_DECLARE_VIEWS(9); auto tmp = (avmMini_rwb * (-avmMini_rwb + FF(1))); tmp *= scaling_factor; @@ -121,7 +121,7 @@ template class avm_miniImpl { } // Contribution 10 { - DECLARE_VIEWS(10); + AvmMini_DECLARE_VIEWS(10); auto tmp = (avmMini_rwc * (-avmMini_rwc + FF(1))); tmp *= scaling_factor; @@ -129,7 +129,7 @@ template class avm_miniImpl { } // Contribution 11 { - DECLARE_VIEWS(11); + AvmMini_DECLARE_VIEWS(11); auto tmp = (avmMini_sel_op_add * ((avmMini_ia + avmMini_ib) - avmMini_ic)); tmp *= scaling_factor; @@ -137,7 +137,7 @@ template class avm_miniImpl { } // Contribution 12 { - DECLARE_VIEWS(12); + AvmMini_DECLARE_VIEWS(12); auto tmp = (avmMini_sel_op_sub * ((avmMini_ia - avmMini_ib) - avmMini_ic)); tmp *= scaling_factor; @@ -145,7 +145,7 @@ template class avm_miniImpl { } // Contribution 13 { - DECLARE_VIEWS(13); + AvmMini_DECLARE_VIEWS(13); auto tmp = (avmMini_sel_op_mul * ((avmMini_ia * avmMini_ib) - avmMini_ic)); tmp *= scaling_factor; @@ -153,7 +153,7 @@ template class avm_miniImpl { } // Contribution 14 { - DECLARE_VIEWS(14); + AvmMini_DECLARE_VIEWS(14); auto tmp = ((avmMini_sel_op_div * (-avmMini_op_err + FF(1))) * ((avmMini_ic * avmMini_ib) - avmMini_ia)); tmp *= scaling_factor; @@ -161,7 +161,7 @@ template class avm_miniImpl { } // Contribution 15 { - DECLARE_VIEWS(15); + AvmMini_DECLARE_VIEWS(15); auto tmp = (avmMini_sel_op_div * (((avmMini_ib * avmMini_inv) - FF(1)) + avmMini_op_err)); tmp *= scaling_factor; @@ -169,7 +169,7 @@ template class avm_miniImpl { } // Contribution 16 { - DECLARE_VIEWS(16); + AvmMini_DECLARE_VIEWS(16); auto tmp = ((avmMini_sel_op_div * avmMini_op_err) * (-avmMini_inv + FF(1))); tmp *= scaling_factor; @@ -177,7 +177,7 @@ template class avm_miniImpl { } // Contribution 17 { - DECLARE_VIEWS(17); + AvmMini_DECLARE_VIEWS(17); auto tmp = (avmMini_op_err * (avmMini_sel_op_div - FF(1))); tmp *= scaling_factor; diff --git a/barretenberg/cpp/src/barretenberg/relations/generated/AvmMini/declare_views.hpp b/barretenberg/cpp/src/barretenberg/relations/generated/AvmMini/declare_views.hpp index b5d9a61651e..e2abc409ea4 100644 --- a/barretenberg/cpp/src/barretenberg/relations/generated/AvmMini/declare_views.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/generated/AvmMini/declare_views.hpp @@ -1,5 +1,5 @@ -#define DECLARE_VIEWS(index) \ +#define AvmMini_DECLARE_VIEWS(index) \ using Accumulator = typename std::tuple_element::type; \ using View = typename Accumulator::View; \ [[maybe_unused]] auto avmMini_clk = View(new_term.avmMini_clk); \ @@ -30,5 +30,5 @@ [[maybe_unused]] auto avmMini_mem_idx_c = View(new_term.avmMini_mem_idx_c); \ [[maybe_unused]] auto avmMini_last = View(new_term.avmMini_last); \ [[maybe_unused]] auto memTrace_m_rw_shift = View(new_term.memTrace_m_rw_shift); \ - [[maybe_unused]] auto memTrace_m_val_shift = View(new_term.memTrace_m_val_shift); \ - [[maybe_unused]] auto memTrace_m_addr_shift = View(new_term.memTrace_m_addr_shift); + [[maybe_unused]] auto memTrace_m_addr_shift = View(new_term.memTrace_m_addr_shift); \ + [[maybe_unused]] auto memTrace_m_val_shift = View(new_term.memTrace_m_val_shift); diff --git a/barretenberg/cpp/src/barretenberg/relations/generated/AvmMini/mem_trace.hpp b/barretenberg/cpp/src/barretenberg/relations/generated/AvmMini/mem_trace.hpp index dde059dedc6..7bfb1b223cd 100644 --- a/barretenberg/cpp/src/barretenberg/relations/generated/AvmMini/mem_trace.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/generated/AvmMini/mem_trace.hpp @@ -8,14 +8,14 @@ namespace proof_system::AvmMini_vm { template struct Mem_traceRow { FF memTrace_m_rw_shift{}; - FF memTrace_m_lastAccess{}; + FF memTrace_m_addr_shift{}; + FF memTrace_m_val{}; FF memTrace_m_addr{}; - FF memTrace_m_val_shift{}; FF memTrace_m_rw{}; FF avmMini_first{}; - FF memTrace_m_addr_shift{}; + FF memTrace_m_lastAccess{}; FF avmMini_last{}; - FF memTrace_m_val{}; + FF memTrace_m_val_shift{}; }; template class mem_traceImpl { @@ -38,7 +38,7 @@ template class mem_traceImpl { // Contribution 0 { - DECLARE_VIEWS(0); + AvmMini_DECLARE_VIEWS(0); auto tmp = (memTrace_m_lastAccess * (-memTrace_m_lastAccess + FF(1))); tmp *= scaling_factor; @@ -46,7 +46,7 @@ template class mem_traceImpl { } // Contribution 1 { - DECLARE_VIEWS(1); + AvmMini_DECLARE_VIEWS(1); auto tmp = (memTrace_m_rw * (-memTrace_m_rw + FF(1))); tmp *= scaling_factor; @@ -54,7 +54,7 @@ template class mem_traceImpl { } // Contribution 2 { - DECLARE_VIEWS(2); + AvmMini_DECLARE_VIEWS(2); auto tmp = (((-avmMini_first + FF(1)) * (-memTrace_m_lastAccess + FF(1))) * (memTrace_m_addr_shift - memTrace_m_addr)); @@ -63,7 +63,7 @@ template class mem_traceImpl { } // Contribution 3 { - DECLARE_VIEWS(3); + AvmMini_DECLARE_VIEWS(3); auto tmp = (((((-avmMini_first + FF(1)) * (-avmMini_last + FF(1))) * (-memTrace_m_lastAccess + FF(1))) * (-memTrace_m_rw_shift + FF(1))) * diff --git a/barretenberg/cpp/src/barretenberg/relations/generated/Toy/declare_views.hpp b/barretenberg/cpp/src/barretenberg/relations/generated/Toy/declare_views.hpp new file mode 100644 index 00000000000..18b7ec1d45e --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/relations/generated/Toy/declare_views.hpp @@ -0,0 +1,13 @@ + +#define Toy_DECLARE_VIEWS(index) \ + using Accumulator = typename std::tuple_element::type; \ + using View = typename Accumulator::View; \ + [[maybe_unused]] auto toy_first = View(new_term.toy_first); \ + [[maybe_unused]] auto toy_q_tuple_set = View(new_term.toy_q_tuple_set); \ + [[maybe_unused]] auto toy_set_1_column_1 = View(new_term.toy_set_1_column_1); \ + [[maybe_unused]] auto toy_set_1_column_2 = View(new_term.toy_set_1_column_2); \ + [[maybe_unused]] auto toy_set_2_column_1 = View(new_term.toy_set_2_column_1); \ + [[maybe_unused]] auto toy_set_2_column_2 = View(new_term.toy_set_2_column_2); \ + [[maybe_unused]] auto toy_x = View(new_term.toy_x); \ + [[maybe_unused]] auto two_column_perm = View(new_term.two_column_perm); \ + [[maybe_unused]] auto toy_x_shift = View(new_term.toy_x_shift); diff --git a/barretenberg/cpp/src/barretenberg/relations/generated/Toy/toy_avm.hpp b/barretenberg/cpp/src/barretenberg/relations/generated/Toy/toy_avm.hpp new file mode 100644 index 00000000000..40eb15cb6b3 --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/relations/generated/Toy/toy_avm.hpp @@ -0,0 +1,42 @@ + +#pragma once +#include "../../relation_parameters.hpp" +#include "../../relation_types.hpp" +#include "./declare_views.hpp" + +namespace proof_system::Toy_vm { + +template struct Toy_avmRow { + FF toy_x_shift{}; + FF toy_x{}; +}; + +template class toy_avmImpl { + public: + using FF = FF_; + + static constexpr std::array SUBRELATION_PARTIAL_LENGTHS{ + 2, + }; + + template + void static accumulate(ContainerOverSubrelations& evals, + const AllEntities& new_term, + [[maybe_unused]] const RelationParameters&, + [[maybe_unused]] const FF& scaling_factor) + { + + // Contribution 0 + { + Toy_DECLARE_VIEWS(0); + + auto tmp = (toy_x_shift - toy_x); + tmp *= scaling_factor; + std::get<0>(evals) += tmp; + } + } +}; + +template using toy_avm = Relation>; + +} // namespace proof_system::Toy_vm \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/relations/generated/Toy/two_column_perm.hpp b/barretenberg/cpp/src/barretenberg/relations/generated/Toy/two_column_perm.hpp new file mode 100644 index 00000000000..29d31482d9c --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/relations/generated/Toy/two_column_perm.hpp @@ -0,0 +1,94 @@ + + +#pragma once + +#include "barretenberg/relations/generic_permutation/generic_permutation_relation.hpp" + +#include +#include + +namespace proof_system::honk::sumcheck { + +class two_column_perm_permutation_settings { + public: + // This constant defines how many columns are bundled together to form each set. + 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 auto inverse_polynomial_is_computed_at_row(const AllEntities& in) + { + return (in.toy_q_tuple_set == 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.two_column_perm, + in.toy_q_tuple_set, + in.toy_q_tuple_set, + in.toy_q_tuple_set, + in.toy_set_1_column_1, + in.toy_set_1_column_2, + in.toy_set_2_column_1, + in.toy_set_2_column_2); + } + + /** + * @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.two_column_perm, + in.toy_q_tuple_set, + in.toy_q_tuple_set, + in.toy_q_tuple_set, + in.toy_set_1_column_1, + in.toy_set_1_column_2, + in.toy_set_2_column_1, + in.toy_set_2_column_2); + } +}; + +template +using two_column_perm_relation = GenericPermutationRelation; +template using two_column_perm = GenericPermutation; + +} // namespace proof_system::honk::sumcheck diff --git a/barretenberg/cpp/src/barretenberg/relations/toy_avm/generic_permutation_relation.hpp b/barretenberg/cpp/src/barretenberg/relations/generic_permutation/generic_permutation_relation.hpp similarity index 95% rename from barretenberg/cpp/src/barretenberg/relations/toy_avm/generic_permutation_relation.hpp rename to barretenberg/cpp/src/barretenberg/relations/generic_permutation/generic_permutation_relation.hpp index d4246a423f5..b0b917885f4 100644 --- a/barretenberg/cpp/src/barretenberg/relations/toy_avm/generic_permutation_relation.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/generic_permutation/generic_permutation_relation.hpp @@ -10,6 +10,7 @@ #include #include "barretenberg/common/constexpr_utils.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" @@ -201,10 +202,17 @@ template class GenericPermutationRelationImpl static void accumulate(ContainerOverSubrelations& accumulator, const AllEntities& in, const Parameters& params, - const FF& scaling_factor); + const FF& scaling_factor) + { + logderivative_library::accumulate_logderivative_permutation_subrelation_contributions< + FF, + GenericPermutationRelationImpl>(accumulator, in, params, scaling_factor); + } }; template using GenericPermutationRelation = Relation>; +template using GenericPermutation = GenericPermutationRelationImpl; + } // namespace proof_system::honk::sumcheck diff --git a/barretenberg/cpp/src/barretenberg/relations/toy_avm/generic_permutation_relation.cpp b/barretenberg/cpp/src/barretenberg/relations/toy_avm/generic_permutation_relation.cpp deleted file mode 100644 index 1822c388c4e..00000000000 --- a/barretenberg/cpp/src/barretenberg/relations/toy_avm/generic_permutation_relation.cpp +++ /dev/null @@ -1,34 +0,0 @@ -#include "generic_permutation_relation.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" - -namespace proof_system::honk::sumcheck { - -/** - * @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, .... - * @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) -{ - logderivative_library::accumulate_logderivative_permutation_subrelation_contributions< - FF, - GenericPermutationRelationImpl>(accumulator, in, params, scaling_factor); -} - -// template class GenericPermutationRelationImpl; -// template -// using GenericPermutationRelationExampleSettingsImpl = GenericPermutationRelationImpl; DEFINE_SUMCHECK_RELATION_CLASS(GenericPermutationRelationExampleSettingsImpl, flavor::AVMTemplate); - -DEFINE_IMPLEMENTATIONS_FOR_ALL_SETTINGS(GenericPermutationRelationImpl, flavor::ToyAVM); -} // namespace proof_system::honk::sumcheck diff --git a/barretenberg/cpp/src/barretenberg/relations/toy_avm/relation_definer.hpp b/barretenberg/cpp/src/barretenberg/relations/toy_avm/relation_definer.hpp deleted file mode 100644 index 4771c1260b7..00000000000 --- a/barretenberg/cpp/src/barretenberg/relations/toy_avm/relation_definer.hpp +++ /dev/null @@ -1,213 +0,0 @@ -/** - * @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 diff --git a/barretenberg/cpp/src/barretenberg/vm/generated/AvmMini_prover.cpp b/barretenberg/cpp/src/barretenberg/vm/generated/AvmMini_prover.cpp index da10ff83a40..86a691495c0 100644 --- a/barretenberg/cpp/src/barretenberg/vm/generated/AvmMini_prover.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/generated/AvmMini_prover.cpp @@ -3,6 +3,7 @@ #include "AvmMini_prover.hpp" #include "barretenberg/commitment_schemes/claim.hpp" #include "barretenberg/commitment_schemes/commitment_key.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" @@ -60,12 +61,12 @@ AvmMiniProver::AvmMiniProver(std::shared_ptr input_key, prover_polynomials.memTrace_m_rw = key->memTrace_m_rw; prover_polynomials.memTrace_m_rw_shift = key->memTrace_m_rw.shifted(); - prover_polynomials.memTrace_m_val = key->memTrace_m_val; - prover_polynomials.memTrace_m_val_shift = key->memTrace_m_val.shifted(); - prover_polynomials.memTrace_m_addr = key->memTrace_m_addr; prover_polynomials.memTrace_m_addr_shift = key->memTrace_m_addr.shifted(); + prover_polynomials.memTrace_m_val = key->memTrace_m_val; + prover_polynomials.memTrace_m_val_shift = key->memTrace_m_val.shifted(); + // prover_polynomials.lookup_inverses = key->lookup_inverses; // key->z_perm = Polynomial(key->circuit_size); // prover_polynomials.z_perm = key->z_perm; diff --git a/barretenberg/cpp/src/barretenberg/vm/generated/Toy_composer.cpp b/barretenberg/cpp/src/barretenberg/vm/generated/Toy_composer.cpp new file mode 100644 index 00000000000..4d2ec73e118 --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/vm/generated/Toy_composer.cpp @@ -0,0 +1,89 @@ + + +#include "./Toy_composer.hpp" +#include "barretenberg/proof_system/circuit_builder/generated/Toy_circuit_builder.hpp" +#include "barretenberg/proof_system/composer/composer_lib.hpp" +#include "barretenberg/proof_system/composer/permutation_lib.hpp" +#include "barretenberg/vm/generated/Toy_verifier.hpp" + +namespace proof_system::honk { + +using Flavor = honk::flavor::ToyFlavor; +void ToyComposer::compute_witness(CircuitConstructor& circuit) +{ + if (computed_witness) { + return; + } + + auto polynomials = circuit.compute_polynomials(); + + proving_key->toy_first = polynomials.toy_first; + proving_key->toy_q_tuple_set = polynomials.toy_q_tuple_set; + proving_key->toy_set_1_column_1 = polynomials.toy_set_1_column_1; + proving_key->toy_set_1_column_2 = polynomials.toy_set_1_column_2; + proving_key->toy_set_2_column_1 = polynomials.toy_set_2_column_1; + proving_key->toy_set_2_column_2 = polynomials.toy_set_2_column_2; + proving_key->toy_x = polynomials.toy_x; + proving_key->two_column_perm = polynomials.two_column_perm; + + computed_witness = true; +} + +ToyProver ToyComposer::create_prover(CircuitConstructor& circuit_constructor) +{ + compute_proving_key(circuit_constructor); + compute_witness(circuit_constructor); + compute_commitment_key(circuit_constructor.get_circuit_subgroup_size()); + + ToyProver output_state(proving_key, commitment_key); + + return output_state; +} + +ToyVerifier ToyComposer::create_verifier(CircuitConstructor& circuit_constructor) +{ + auto verification_key = compute_verification_key(circuit_constructor); + + ToyVerifier output_state(verification_key); + + auto pcs_verification_key = std::make_unique(verification_key->circuit_size, crs_factory_); + + output_state.pcs_verification_key = std::move(pcs_verification_key); + + return output_state; +} + +std::shared_ptr ToyComposer::compute_proving_key(CircuitConstructor& circuit_constructor) +{ + if (proving_key) { + return proving_key; + } + + // Initialize proving_key + { + const size_t subgroup_size = circuit_constructor.get_circuit_subgroup_size(); + proving_key = std::make_shared(subgroup_size, 0); + } + + proving_key->contains_recursive_proof = false; + + return proving_key; +} + +std::shared_ptr ToyComposer::compute_verification_key(CircuitConstructor& circuit_constructor) +{ + if (verification_key) { + return verification_key; + } + + if (!proving_key) { + compute_proving_key(circuit_constructor); + } + + verification_key = + std::make_shared(proving_key->circuit_size, proving_key->num_public_inputs); + + return verification_key; +} + +} // namespace proof_system::honk diff --git a/barretenberg/cpp/src/barretenberg/vm/generated/Toy_composer.hpp b/barretenberg/cpp/src/barretenberg/vm/generated/Toy_composer.hpp new file mode 100644 index 00000000000..ad7877b7073 --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/vm/generated/Toy_composer.hpp @@ -0,0 +1,69 @@ + + +#pragma once + +#include "barretenberg/proof_system/circuit_builder/generated/Toy_circuit_builder.hpp" +#include "barretenberg/proof_system/composer/composer_lib.hpp" +#include "barretenberg/srs/global_crs.hpp" +#include "barretenberg/vm/generated/Toy_prover.hpp" +#include "barretenberg/vm/generated/Toy_verifier.hpp" + +namespace proof_system::honk { +class ToyComposer { + public: + using Flavor = honk::flavor::ToyFlavor; + using CircuitConstructor = ToyCircuitBuilder; + using ProvingKey = Flavor::ProvingKey; + using VerificationKey = Flavor::VerificationKey; + using PCS = Flavor::PCS; + using CommitmentKey = Flavor::CommitmentKey; + using VerifierCommitmentKey = Flavor::VerifierCommitmentKey; + + // TODO: which of these will we really need + static constexpr std::string_view NAME_STRING = "Toy"; + static constexpr size_t NUM_RESERVED_GATES = 0; + static constexpr size_t NUM_WIRES = Flavor::NUM_WIRES; + + std::shared_ptr proving_key; + std::shared_ptr verification_key; + + // The crs_factory holds the path to the srs and exposes methods to extract the srs elements + std::shared_ptr> crs_factory_; + + // The commitment key is passed to the prover but also used herein to compute the verfication key commitments + std::shared_ptr commitment_key; + + std::vector recursive_proof_public_input_indices; + bool contains_recursive_proof = false; + bool computed_witness = false; + + ToyComposer() { crs_factory_ = barretenberg::srs::get_crs_factory(); } + + ToyComposer(std::shared_ptr p_key, std::shared_ptr v_key) + : proving_key(std::move(p_key)) + , verification_key(std::move(v_key)) + {} + + ToyComposer(ToyComposer&& other) noexcept = default; + ToyComposer(ToyComposer const& other) noexcept = default; + ToyComposer& operator=(ToyComposer&& other) noexcept = default; + ToyComposer& operator=(ToyComposer const& other) noexcept = default; + ~ToyComposer() = default; + + std::shared_ptr compute_proving_key(CircuitConstructor& circuit_constructor); + std::shared_ptr compute_verification_key(CircuitConstructor& circuit_constructor); + + void compute_witness(CircuitConstructor& circuit_constructor); + + ToyProver create_prover(CircuitConstructor& circuit_constructor); + ToyVerifier create_verifier(CircuitConstructor& circuit_constructor); + + void add_table_column_selector_poly_to_proving_key(barretenberg::polynomial& small, const std::string& tag); + + void compute_commitment_key(size_t circuit_size) + { + commitment_key = std::make_shared(circuit_size, crs_factory_); + }; +}; + +} // namespace proof_system::honk diff --git a/barretenberg/cpp/src/barretenberg/vm/generated/Toy_prover.cpp b/barretenberg/cpp/src/barretenberg/vm/generated/Toy_prover.cpp new file mode 100644 index 00000000000..3d7738d13ef --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/vm/generated/Toy_prover.cpp @@ -0,0 +1,136 @@ + + +#include "Toy_prover.hpp" +#include "barretenberg/commitment_schemes/claim.hpp" +#include "barretenberg/commitment_schemes/commitment_key.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" +#include "barretenberg/proof_system/library/grand_product_library.hpp" +#include "barretenberg/relations/lookup_relation.hpp" +#include "barretenberg/relations/permutation_relation.hpp" +#include "barretenberg/sumcheck/sumcheck.hpp" + +namespace proof_system::honk { + +using Flavor = honk::flavor::ToyFlavor; + +/** + * Create ToyProver from proving key, witness and manifest. + * + * @param input_key Proving key. + * @param input_manifest Input manifest + * + * @tparam settings Settings class. + * */ +ToyProver::ToyProver(std::shared_ptr input_key, std::shared_ptr commitment_key) + : key(input_key) + , commitment_key(commitment_key) +{ + // TODO: take every polynomial and assign it to the key!! + prover_polynomials.toy_first = key->toy_first; + prover_polynomials.toy_q_tuple_set = key->toy_q_tuple_set; + prover_polynomials.toy_set_1_column_1 = key->toy_set_1_column_1; + prover_polynomials.toy_set_1_column_2 = key->toy_set_1_column_2; + prover_polynomials.toy_set_2_column_1 = key->toy_set_2_column_1; + prover_polynomials.toy_set_2_column_2 = key->toy_set_2_column_2; + prover_polynomials.toy_x = key->toy_x; + prover_polynomials.two_column_perm = key->two_column_perm; + + prover_polynomials.toy_x = key->toy_x; + prover_polynomials.toy_x_shift = key->toy_x.shifted(); + + // prover_polynomials.lookup_inverses = key->lookup_inverses; + // key->z_perm = Polynomial(key->circuit_size); + // prover_polynomials.z_perm = key->z_perm; +} + +/** + * @brief Add circuit size, public input size, and public inputs to transcript + * + */ +void ToyProver::execute_preamble_round() +{ + const auto circuit_size = static_cast(key->circuit_size); + + transcript->send_to_verifier("circuit_size", circuit_size); +} + +/** + * @brief Compute commitments to the first three wires + * + */ +void ToyProver::execute_wire_commitments_round() +{ + auto wire_polys = key->get_wires(); + auto labels = commitment_labels.get_wires(); + for (size_t idx = 0; idx < wire_polys.size(); ++idx) { + transcript->send_to_verifier(labels[idx], commitment_key->commit(wire_polys[idx])); + } +} + +/** + * @brief Run Sumcheck resulting in u = (u_1,...,u_d) challenges and all evaluations at u being calculated. + * + */ +void ToyProver::execute_relation_check_rounds() +{ + using Sumcheck = sumcheck::SumcheckProver; + + auto sumcheck = Sumcheck(key->circuit_size, transcript); + auto alpha = transcript->get_challenge("alpha"); + + sumcheck_output = sumcheck.prove(prover_polynomials, relation_parameters, alpha); +} + +/** + * @brief Execute the ZeroMorph protocol to prove the multilinear evaluations produced by Sumcheck + * @details See https://hackmd.io/dlf9xEwhTQyE3hiGbq4FsA?view for a complete description of the unrolled protocol. + * + * */ +void ToyProver::execute_zeromorph_rounds() +{ + ZeroMorph::prove(prover_polynomials.get_unshifted(), + prover_polynomials.get_to_be_shifted(), + sumcheck_output.claimed_evaluations.get_unshifted(), + sumcheck_output.claimed_evaluations.get_shifted(), + sumcheck_output.challenge, + commitment_key, + transcript); +} + +plonk::proof& ToyProver::export_proof() +{ + proof.proof_data = transcript->proof_data; + return proof; +} + +plonk::proof& ToyProver::construct_proof() +{ + // Add circuit size public input size and public inputs to transcript. + execute_preamble_round(); + + // Compute wire commitments + execute_wire_commitments_round(); + + // TODO: not implemented for codegen just yet + // Compute sorted list accumulator and commitment + // execute_log_derivative_commitments_round(); + + // Fiat-Shamir: bbeta & gamma + // Compute grand product(s) and commitments. + // execute_grand_product_computation_round(); + + // Fiat-Shamir: alpha + // Run sumcheck subprotocol. + execute_relation_check_rounds(); + + // Fiat-Shamir: rho, y, x, z + // Execute Zeromorph multilinear PCS + execute_zeromorph_rounds(); + + return export_proof(); +} + +} // namespace proof_system::honk diff --git a/barretenberg/cpp/src/barretenberg/vm/generated/Toy_prover.hpp b/barretenberg/cpp/src/barretenberg/vm/generated/Toy_prover.hpp new file mode 100644 index 00000000000..bfd4db05ba6 --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/vm/generated/Toy_prover.hpp @@ -0,0 +1,62 @@ + + +#pragma once +#include "barretenberg/commitment_schemes/zeromorph/zeromorph.hpp" +#include "barretenberg/flavor/generated/Toy_flavor.hpp" +#include "barretenberg/plonk/proof_system/types/proof.hpp" +#include "barretenberg/relations/relation_parameters.hpp" +#include "barretenberg/sumcheck/sumcheck_output.hpp" +#include "barretenberg/transcript/transcript.hpp" + +namespace proof_system::honk { + +class ToyProver { + + using Flavor = honk::flavor::ToyFlavor; + using FF = Flavor::FF; + using PCS = Flavor::PCS; + using PCSCommitmentKey = Flavor::CommitmentKey; + using ProvingKey = Flavor::ProvingKey; + using Polynomial = Flavor::Polynomial; + using ProverPolynomials = Flavor::ProverPolynomials; + using CommitmentLabels = Flavor::CommitmentLabels; + using Curve = Flavor::Curve; + using Transcript = Flavor::Transcript; + + public: + explicit ToyProver(std::shared_ptr input_key, std::shared_ptr commitment_key); + + void execute_preamble_round(); + void execute_wire_commitments_round(); + void execute_relation_check_rounds(); + void execute_zeromorph_rounds(); + + plonk::proof& export_proof(); + plonk::proof& construct_proof(); + + std::shared_ptr transcript = std::make_shared(); + + std::vector public_inputs; + + proof_system::RelationParameters relation_parameters; + + std::shared_ptr key; + + // Container for spans of all polynomials required by the prover (i.e. all multivariates evaluated by Sumcheck). + ProverPolynomials prover_polynomials; + + CommitmentLabels commitment_labels; + + Polynomial quotient_W; + + sumcheck::SumcheckOutput sumcheck_output; + + std::shared_ptr commitment_key; + + using ZeroMorph = pcs::zeromorph::ZeroMorphProver_; + + private: + plonk::proof proof; +}; + +} // namespace proof_system::honk diff --git a/barretenberg/cpp/src/barretenberg/vm/generated/Toy_verifier.cpp b/barretenberg/cpp/src/barretenberg/vm/generated/Toy_verifier.cpp new file mode 100644 index 00000000000..e92eb206f29 --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/vm/generated/Toy_verifier.cpp @@ -0,0 +1,99 @@ + + +#include "./Toy_verifier.hpp" +#include "barretenberg/commitment_schemes/zeromorph/zeromorph.hpp" +#include "barretenberg/honk/proof_system/power_polynomial.hpp" +#include "barretenberg/numeric/bitop/get_msb.hpp" +#include "barretenberg/transcript/transcript.hpp" + +using namespace barretenberg; +using namespace proof_system::honk::sumcheck; + +namespace proof_system::honk { +ToyVerifier::ToyVerifier(std::shared_ptr verifier_key) + : key(verifier_key) +{} + +ToyVerifier::ToyVerifier(ToyVerifier&& other) noexcept + : key(std::move(other.key)) + , pcs_verification_key(std::move(other.pcs_verification_key)) +{} + +ToyVerifier& ToyVerifier::operator=(ToyVerifier&& other) noexcept +{ + key = other.key; + pcs_verification_key = (std::move(other.pcs_verification_key)); + commitments.clear(); + return *this; +} + +/** + * @brief This function verifies an Toy Honk proof for given program settings. + * + */ +bool ToyVerifier::verify_proof(const plonk::proof& proof) +{ + using Flavor = honk::flavor::ToyFlavor; + using FF = Flavor::FF; + using Commitment = Flavor::Commitment; + // using Curve = Flavor::Curve; + // using ZeroMorph = pcs::zeromorph::ZeroMorphVerifier_; + using VerifierCommitments = Flavor::VerifierCommitments; + using CommitmentLabels = Flavor::CommitmentLabels; + + RelationParameters relation_parameters; + + transcript = std::make_shared(proof.proof_data); + + VerifierCommitments commitments{ key }; + CommitmentLabels commitment_labels; + + const auto circuit_size = transcript->template receive_from_prover("circuit_size"); + + if (circuit_size != key->circuit_size) { + return false; + } + + // Get commitments to VM wires + commitments.toy_q_tuple_set = + transcript->template receive_from_prover(commitment_labels.toy_q_tuple_set); + commitments.toy_set_1_column_1 = + transcript->template receive_from_prover(commitment_labels.toy_set_1_column_1); + commitments.toy_set_1_column_2 = + transcript->template receive_from_prover(commitment_labels.toy_set_1_column_2); + commitments.toy_set_2_column_1 = + transcript->template receive_from_prover(commitment_labels.toy_set_2_column_1); + commitments.toy_set_2_column_2 = + transcript->template receive_from_prover(commitment_labels.toy_set_2_column_2); + commitments.toy_x = transcript->template receive_from_prover(commitment_labels.toy_x); + commitments.two_column_perm = + transcript->template receive_from_prover(commitment_labels.two_column_perm); + + // Execute Sumcheck Verifier + auto sumcheck = SumcheckVerifier(circuit_size); + + auto alpha = transcript->get_challenge("alpha"); + auto [multivariate_challenge, claimed_evaluations, sumcheck_verified] = + sumcheck.verify(relation_parameters, alpha, transcript); + + // If Sumcheck did not verify, return false + if (sumcheck_verified.has_value() && !sumcheck_verified.value()) { + return false; + } + + // Execute ZeroMorph rounds. See https://hackmd.io/dlf9xEwhTQyE3hiGbq4FsA?view for a complete description of the + // unrolled protocol. + // NOTE: temporarily disabled - facing integration issues + // auto pairing_points = ZeroMorph::verify(commitments.get_unshifted(), + // commitments.get_to_be_shifted(), + // claimed_evaluations.get_unshifted(), + // claimed_evaluations.get_shifted(), + // multivariate_challenge, + // transcript); + + // auto verified = pcs_verification_key->pairing_check(pairing_points[0], pairing_points[1]); + // return sumcheck_verified.value() && verified; + return sumcheck_verified.value(); +} + +} // namespace proof_system::honk diff --git a/barretenberg/cpp/src/barretenberg/vm/generated/Toy_verifier.hpp b/barretenberg/cpp/src/barretenberg/vm/generated/Toy_verifier.hpp new file mode 100644 index 00000000000..30b5e78e5c8 --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/vm/generated/Toy_verifier.hpp @@ -0,0 +1,33 @@ + + +#pragma once +#include "barretenberg/flavor/generated/Toy_flavor.hpp" +#include "barretenberg/plonk/proof_system/types/proof.hpp" +#include "barretenberg/sumcheck/sumcheck.hpp" + +namespace proof_system::honk { +class ToyVerifier { + using Flavor = honk::flavor::ToyFlavor; + using FF = Flavor::FF; + using Commitment = Flavor::Commitment; + using VerificationKey = Flavor::VerificationKey; + using VerifierCommitmentKey = Flavor::VerifierCommitmentKey; + using Transcript = Flavor::Transcript; + + public: + explicit ToyVerifier(std::shared_ptr verifier_key = nullptr); + ToyVerifier(ToyVerifier&& other) noexcept; + ToyVerifier(const ToyVerifier& other) = delete; + + ToyVerifier& operator=(const ToyVerifier& other) = delete; + ToyVerifier& operator=(ToyVerifier&& other) noexcept; + + bool verify_proof(const plonk::proof& proof); + + std::shared_ptr key; + std::map commitments; + std::shared_ptr pcs_verification_key; + std::shared_ptr transcript; +}; + +} // namespace proof_system::honk