From 9015bef30e08375933d183e55c2217db924496cb Mon Sep 17 00:00:00 2001 From: Maddiaa <47148561+Maddiaa0@users.noreply.github.com> Date: Tue, 21 Nov 2023 18:22:32 +0000 Subject: [PATCH] chore: sync bb master (#17) * fix: resync master * fix: reenable opt --- bberg/src/arith_builder.rs | 24 --- bberg/src/circuit_builder.rs | 21 +-- bberg/src/composer_builder.rs | 85 ++++----- bberg/src/file_writer.rs | 11 +- bberg/src/flavor_builder.rs | 335 +++++++++++++++++++++++----------- bberg/src/prover_builder.rs | 284 ++++++---------------------- bberg/src/relation_builder.rs | 5 +- bberg/src/trace_builder.rs | 36 ++-- bberg/src/verifier_builder.rs | 191 ++++++------------- compiler/src/lib.rs | 2 +- 10 files changed, 416 insertions(+), 578 deletions(-) diff --git a/bberg/src/arith_builder.rs b/bberg/src/arith_builder.rs index 365faa8d70..8b13789179 100644 --- a/bberg/src/arith_builder.rs +++ b/bberg/src/arith_builder.rs @@ -1,25 +1 @@ -use crate::file_writer::BBFiles; -pub trait ArithmetizationBuilder { - fn create_arith_hpp(&mut self, name: &str, num_cols: usize); -} - -impl ArithmetizationBuilder for BBFiles { - // We have no selectors so we can easily create a boilerplate file - fn create_arith_hpp(&mut self, name: &str, num_cols: usize) { - let arith = format!( - " -#pragma once -#include \"barretenberg/proof_system/arithmetization/arithmetization.hpp\" -namespace arithmetization {{ - class {name}Arithmetization : public Arithmetization<{num_cols}, 0> {{ - public: - using FF = barretenberg::fr; - struct Selectors {{}}; - }}; -}} // namespace arithmetization -" - ); - self.arith_hpp = Some(arith); - } -} diff --git a/bberg/src/circuit_builder.rs b/bberg/src/circuit_builder.rs index 3e883464c7..7cf2ae27e1 100644 --- a/bberg/src/circuit_builder.rs +++ b/bberg/src/circuit_builder.rs @@ -4,7 +4,6 @@ use itertools::Itertools; use number::FieldElement; use pil_analyzer::pil_analyzer::inline_intermediate_polynomials; -use crate::arith_builder::ArithmetizationBuilder; use crate::composer_builder::ComposerBuilder; use crate::file_writer::BBFiles; use crate::flavor_builder::FlavorBuilder; @@ -26,13 +25,13 @@ pub(crate) fn analyzed_to_cpp<F: FieldElement>( // Collect all column names and determine if they need a shift or not // TODO: currently we provide shifts for both the fixed and witness columns, in the long term we need to work out what needs a shift and what doesn't - let _fixed_names = fixed + let fixed_names = fixed .iter() - .map(|(name, _)| (*name).to_owned()) + .map(|(name, _)| (*name.replace(".", "_")).to_owned()) .collect::<Vec<_>>(); - let _witness_names = witness + let witness_names = witness .iter() - .map(|(name, _)| (*name).to_owned()) + .map(|(name, _)| (*name.replace(".", "_")).to_owned()) .collect::<Vec<_>>(); // Inlining step to remove the intermediate poly definitions @@ -41,7 +40,7 @@ pub(crate) fn analyzed_to_cpp<F: FieldElement>( let (subrelations, identities, mut collected_shifts) = create_identities(&analyzed_identities); let shifted_polys: Vec<String> = collected_shifts.drain().collect_vec(); - let (all_cols, unshifted, to_be_shifted, _shifted, all_cols_with_shifts) = + let (all_cols, unshifted, to_be_shifted, shifted, all_cols_with_shifts) = get_all_col_names(fixed, witness, &shifted_polys); let num_cols = all_cols_with_shifts.len(); @@ -56,9 +55,6 @@ pub(crate) fn analyzed_to_cpp<F: FieldElement>( &all_cols_with_shifts, ); - // ----------------------- Create the arithmetization file ----------------------- - bb_files.create_arith_hpp(file_name, num_cols); - // ----------------------- Create the trace builder file ----------------------- bb_files.create_trace_builder_hpp(file_name, &all_cols, &to_be_shifted); @@ -66,17 +62,20 @@ pub(crate) fn analyzed_to_cpp<F: FieldElement>( bb_files.create_flavor_hpp( file_name, &subrelations, + &fixed_names, + &witness_names, &all_cols, &to_be_shifted, + &shifted, // &shifted, ); // ----------------------- Create the composer files ----------------------- - bb_files.create_composer_cpp(file_name); + bb_files.create_composer_cpp(file_name, &all_cols); bb_files.create_composer_hpp(file_name); // ----------------------- Create the Verifier files ----------------------- - bb_files.create_verifier_cpp(file_name, &all_cols); + bb_files.create_verifier_cpp(file_name, &witness_names); bb_files.create_verifier_hpp(file_name); // ----------------------- Create the Prover files ----------------------- diff --git a/bberg/src/composer_builder.rs b/bberg/src/composer_builder.rs index 4ec955fac4..278beedd76 100644 --- a/bberg/src/composer_builder.rs +++ b/bberg/src/composer_builder.rs @@ -1,22 +1,29 @@ use crate::file_writer::BBFiles; pub trait ComposerBuilder { - fn create_composer_cpp(&mut self, name: &str); + fn create_composer_cpp(&mut self, name: &str, all_cols: &[String]); fn create_composer_hpp(&mut self, name: &str); } impl ComposerBuilder for BBFiles { - fn create_composer_cpp(&mut self, name: &str) { + fn create_composer_cpp(&mut self, name: &str, all_cols: &[String]) { // Create a composer file, this is used to a prover and verifier for our flavour let include_str = cpp_includes(name); + let polys_to_key = all_cols + .iter() + .map(|name| format!("proving_key->{name} = polynomials.{name};", name = name)) + .collect::<Vec<String>>() + .join("\n"); + let composer_cpp = format!( " {include_str} namespace proof_system::honk {{ -template <typename Flavor> void {name}Composer_<Flavor>::compute_witness(CircuitConstructor& circuit) +using Flavor = honk::flavor::{name}Flavor; +void {name}Composer::compute_witness(CircuitConstructor& circuit) {{ if (computed_witness) {{ return; @@ -24,35 +31,28 @@ template <typename Flavor> void {name}Composer_<Flavor>::compute_witness(Circuit auto polynomials = circuit.compute_polynomials(); - auto key_wires = proving_key->get_wires(); - auto poly_wires = polynomials.get_wires(); - - for (size_t i = 0; i < key_wires.size(); ++i) {{ - std::copy(poly_wires[i].begin(), poly_wires[i].end(), key_wires[i].begin()); - }} + {polys_to_key} computed_witness = true; }} -template <typename Flavor> -{name}Prover_<Flavor> {name}Composer_<Flavor>::create_prover(CircuitConstructor& circuit_constructor) +{name}Prover {name}Composer::create_prover(CircuitConstructor& circuit_constructor) {{ compute_proving_key(circuit_constructor); compute_witness(circuit_constructor); compute_commitment_key(circuit_constructor.get_circuit_subgroup_size()); - {name}Prover_<Flavor> output_state(proving_key, commitment_key); + {name}Prover output_state(proving_key, commitment_key); return output_state; }} -template <typename Flavor> -{name}Verifier_<Flavor> {name}Composer_<Flavor>::create_verifier( +{name}Verifier {name}Composer::create_verifier( CircuitConstructor& circuit_constructor) {{ auto verification_key = compute_verification_key(circuit_constructor); - {name}Verifier_<Flavor> output_state(verification_key); + {name}Verifier output_state(verification_key); auto pcs_verification_key = std::make_unique<VerifierCommitmentKey>(verification_key->circuit_size, crs_factory_); @@ -61,8 +61,7 @@ template <typename Flavor> return output_state; }} -template <typename Flavor> -std::shared_ptr<typename Flavor::ProvingKey> {name}Composer_<Flavor>::compute_proving_key( +std::shared_ptr<Flavor::ProvingKey> {name}Composer::compute_proving_key( CircuitConstructor& circuit_constructor) {{ if (proving_key) {{ @@ -72,7 +71,7 @@ std::shared_ptr<typename Flavor::ProvingKey> {name}Composer_<Flavor>::compute_pr // Initialize proving_key {{ const size_t subgroup_size = circuit_constructor.get_circuit_subgroup_size(); - proving_key = std::make_shared<typename Flavor::ProvingKey>(subgroup_size, 0); + proving_key = std::make_shared<Flavor::ProvingKey>(subgroup_size, 0); }} proving_key->contains_recursive_proof = false; @@ -80,8 +79,7 @@ std::shared_ptr<typename Flavor::ProvingKey> {name}Composer_<Flavor>::compute_pr return proving_key; }} -template <typename Flavor> -std::shared_ptr<typename Flavor::VerificationKey> {name}Composer_<Flavor>::compute_verification_key( +std::shared_ptr<Flavor::VerificationKey> {name}Composer::compute_verification_key( CircuitConstructor& circuit_constructor) {{ if (verification_key) {{ @@ -93,13 +91,11 @@ std::shared_ptr<typename Flavor::VerificationKey> {name}Composer_<Flavor>::compu }} verification_key = - std::make_shared<typename Flavor::VerificationKey>(proving_key->circuit_size, proving_key->num_public_inputs); + std::make_shared<Flavor::VerificationKey>(proving_key->circuit_size, proving_key->num_public_inputs); return verification_key; }} -template class {name}Composer_<honk::flavor::{name}Flavor>; - }} "); self.composer_cpp = Some(composer_cpp); @@ -113,14 +109,15 @@ template class {name}Composer_<honk::flavor::{name}Flavor>; {include_str} namespace proof_system::honk {{ -template <typename Flavor> class {name}Composer_ {{ +class {name}Composer {{ public: + using Flavor = honk::flavor::{name}Flavor; using CircuitConstructor = {name}TraceBuilder; - using ProvingKey = typename Flavor::ProvingKey; - using VerificationKey = typename Flavor::VerificationKey; - using PCS = typename Flavor::PCS; - using CommitmentKey = typename Flavor::CommitmentKey; - using VerifierCommitmentKey = typename Flavor::VerifierCommitmentKey; + 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 = \"{name}\"; @@ -131,7 +128,7 @@ template <typename Flavor> class {name}Composer_ {{ std::shared_ptr<VerificationKey> verification_key; // The crs_factory holds the path to the srs and exposes methods to extract the srs elements - std::shared_ptr<barretenberg::srs::factories::CrsFactory<typename Flavor::Curve>> crs_factory_; + std::shared_ptr<barretenberg::srs::factories::CrsFactory<Flavor::Curve>> crs_factory_; // The commitment key is passed to the prover but also used herein to compute the verfication key commitments std::shared_ptr<CommitmentKey> commitment_key; @@ -140,29 +137,29 @@ template <typename Flavor> class {name}Composer_ {{ bool contains_recursive_proof = false; bool computed_witness = false; - {name}Composer_() requires(std::same_as<Flavor, honk::flavor::{name}Flavor>) + {name}Composer() {{ crs_factory_ = barretenberg::srs::get_crs_factory(); }} - {name}Composer_(std::shared_ptr<ProvingKey> p_key, std::shared_ptr<VerificationKey> v_key) + {name}Composer(std::shared_ptr<ProvingKey> p_key, std::shared_ptr<VerificationKey> v_key) : proving_key(std::move(p_key)) , verification_key(std::move(v_key)) {{}} - {name}Composer_({name}Composer_&& other) noexcept = default; - {name}Composer_({name}Composer_ const& other) noexcept = default; - {name}Composer_& operator=({name}Composer_&& other) noexcept = default; - {name}Composer_& operator=({name}Composer_ const& other) noexcept = default; - ~{name}Composer_() = default; + {name}Composer({name}Composer&& other) noexcept = default; + {name}Composer({name}Composer const& other) noexcept = default; + {name}Composer& operator=({name}Composer&& other) noexcept = default; + {name}Composer& operator=({name}Composer const& other) noexcept = default; + ~{name}Composer() = default; std::shared_ptr<ProvingKey> compute_proving_key(CircuitConstructor& circuit_constructor); std::shared_ptr<VerificationKey> compute_verification_key(CircuitConstructor& circuit_constructor); void compute_witness(CircuitConstructor& circuit_constructor); - {name}Prover_<Flavor> create_prover(CircuitConstructor& circuit_constructor); - {name}Verifier_<Flavor> create_verifier(CircuitConstructor& circuit_constructor); + {name}Prover create_prover(CircuitConstructor& circuit_constructor); + {name}Verifier create_verifier(CircuitConstructor& circuit_constructor); void add_table_column_selector_poly_to_proving_key(barretenberg::polynomial& small, const std::string& tag); @@ -172,9 +169,6 @@ template <typename Flavor> class {name}Composer_ {{ }}; }}; -extern template class {name}Composer_<honk::flavor::{name}Flavor>; -using {name}Composer = {name}Composer_<honk::flavor::{name}Flavor>; - }} // namespace proof_system::honk " ); @@ -186,8 +180,7 @@ fn cpp_includes(name: &str) -> String { format!( " #include \"./{name}_composer.hpp\" -#include \"barretenberg/honk/proof_system/generated/{name}_verifier.hpp\" -#include \"barretenberg/honk/proof_system/grand_product_library.hpp\" +#include \"barretenberg/vm/generated/{name}_verifier.hpp\" #include \"barretenberg/proof_system/circuit_builder/generated/{name}_trace.hpp\" #include \"barretenberg/proof_system/composer/composer_lib.hpp\" #include \"barretenberg/proof_system/composer/permutation_lib.hpp\" @@ -200,8 +193,8 @@ pub fn hpp_includes(name: &str) -> String { " #pragma once -#include \"barretenberg/honk/proof_system/generated/{name}_prover.hpp\" -#include \"barretenberg/honk/proof_system/generated/{name}_verifier.hpp\" +#include \"barretenberg/vm/generated/{name}_prover.hpp\" +#include \"barretenberg/vm/generated/{name}_verifier.hpp\" #include \"barretenberg/proof_system/circuit_builder/generated/{name}_trace.hpp\" #include \"barretenberg/proof_system/composer/composer_lib.hpp\" #include \"barretenberg/srs/global_crs.hpp\" diff --git a/bberg/src/file_writer.rs b/bberg/src/file_writer.rs index bc7f5d59ee..a3194b0dbf 100644 --- a/bberg/src/file_writer.rs +++ b/bberg/src/file_writer.rs @@ -3,7 +3,6 @@ use std::io::Write; pub struct BBFiles { pub relation_hpp: Option<String>, - pub arith_hpp: Option<String>, pub flavor_hpp: Option<String>, // trace pub trace_hpp: Option<String>, @@ -46,17 +45,16 @@ impl BBFiles { prover: Option<String>, ) -> Self { let base = base.unwrap_or("src/barretenberg".to_owned()); - let rel = rel.unwrap_or("proof_system/relations/generated".to_owned()); + let rel = rel.unwrap_or("relations/generated".to_owned()); let arith = arith.unwrap_or("proof_system/arithmetization/generated".to_owned()); let trace = trace.unwrap_or("proof_system/circuit_builder/generated".to_owned()); - let flavor = flavor.unwrap_or("honk/flavor/generated".to_owned()); - let composer = composer.unwrap_or("honk/composer/generated".to_owned()); - let prover = prover.unwrap_or("honk/proof_system/generated".to_owned()); + let flavor = flavor.unwrap_or("flavor/generated".to_owned()); + let composer = composer.unwrap_or("vm/generated".to_owned()); + let prover = prover.unwrap_or("vm/generated".to_owned()); Self { file_name, relation_hpp: None, - arith_hpp: None, flavor_hpp: None, trace_hpp: None, composer_cpp: None, @@ -88,7 +86,6 @@ impl BBFiles { }; } write_file!(self.rel, ".hpp", self.relation_hpp); - write_file!(self.arith, "_arith.hpp", self.arith_hpp); // Trace write_file!(self.trace, "_trace.hpp", self.trace_hpp); diff --git a/bberg/src/flavor_builder.rs b/bberg/src/flavor_builder.rs index 1f2726b9e4..1c138497d4 100644 --- a/bberg/src/flavor_builder.rs +++ b/bberg/src/flavor_builder.rs @@ -5,7 +5,10 @@ pub trait FlavorBuilder { &mut self, name: &str, relations: &[String], + fixed: &[String], + witness: &[String], all_cols: &[String], + to_be_shifted: &[String], shifted: &[String], ); } @@ -16,38 +19,44 @@ impl FlavorBuilder for BBFiles { &mut self, name: &str, relations: &[String], + fixed: &[String], + witness: &[String], all_cols: &[String], + to_be_shifted: &[String], shifted: &[String], // shifted: &[String], ) { + let first_poly = &fixed[0]; let includes = flavor_includes(name, relations); - let num_witness = all_cols.len(); - let num_all = num_witness + shifted.len(); - // Note: includes all witness shifts + let num_precomputed = &fixed.len(); + let num_witness = witness.len(); + let num_all = num_witness + shifted.len() + to_be_shifted.len(); // TODO: for now we include a shift OF ALL witness wires, however this is not necessarily true - let precomputed = witness_get(all_cols, 0, false); - let witness_str = create_witness_entities(all_cols); - let all_shift = witness_get(shifted, num_witness, true); + let precomputed = witness_get(fixed, false); + + let witnesses = witness_get(witness, false); + let precomputed_str = create_precomputed_entities(&fixed); + let witness_str = create_witness_entities(&witness); + let all_shift = witness_get(shifted, false); + + let all_cols_and_shifts = &[all_cols.to_vec(), shifted.to_vec()] + .into_iter() + .flatten() + .collect::<Vec<String>>(); + let all_entities_get_wires = make_wires_set(&all_cols_and_shifts); + let all_entities_pointer_view = + create_pointer_view("NUM_ALL_ENTITIES", &all_cols_and_shifts); - let all_entities_get_wires = make_wires_set( - &[all_cols.to_vec(), shifted.to_vec()] - .into_iter() - .flatten() - .collect::<Vec<String>>(), - ); let all_entities_get_unshifted = make_wires_set(all_cols); - let all_entities_get_to_be_shifted = make_wires_set(shifted); - let all_entities_get_shifted = make_wires_set( - &shifted - .iter() - .map(|w| format!("{}_shift", w)) - .collect::<Vec<String>>(), - ); + let all_entities_get_to_be_shifted = make_wires_set(to_be_shifted); + let all_entities_get_shifted = make_wires_set(shifted); let commitment_labels_class = create_commitment_labels(all_cols); - let verification_commitments = create_verifier_commitments(); + let verification_commitments = create_verifier_commitments(fixed); + + let transcript = generate_transcript(witness); // TODO: make this work when we have multiple relation files, for now we just have the one let relations_tuple = format!("{name}_vm::{name}<FF>"); @@ -64,48 +73,53 @@ impl FlavorBuilder for BBFiles { namespace proof_system::honk {{ namespace flavor {{ -template <typename CycleGroup_T, typename Curve_T, typename PCS_T> class {name}FlavorBase {{ +class {name}Flavor {{ public: - // forward template params into the ECCVMBase namespace - using CycleGroup = CycleGroup_T; - using Curve = Curve_T; - using G1 = typename Curve::Group; - using PCS = PCS_T; + using Curve = curve::BN254; + using G1 = Curve::Group; + using PCS = pcs::kzg::KZG<Curve>; - using FF = typename G1::subgroup_field; + using FF = G1::subgroup_field; using Polynomial = barretenberg::Polynomial<FF>; using PolynomialHandle = std::span<FF>; - using GroupElement = typename G1::element; - using Commitment = typename G1::affine_element; - using CommitmentHandle = typename G1::affine_element; + using GroupElement = G1::element; + using Commitment = G1::affine_element; + using CommitmentHandle = G1::affine_element; using CommitmentKey = pcs::CommitmentKey<Curve>; using VerifierCommitmentKey = pcs::VerifierCommitmentKey<Curve>; - static constexpr size_t NUM_WIRES = {num_witness}; - static constexpr size_t NUM_PRECOMPUTED_ENTITIES = 0; // This is zero for now + static constexpr size_t NUM_PRECOMPUTED_ENTITIES = {num_precomputed}; static constexpr size_t NUM_WITNESS_ENTITIES = {num_witness}; + 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 = {num_all}; - // using GrandProductRelations = std::tuple<>; using Relations = std::tuple<{relations_tuple}>; - // using LookupRelation = sumcheck::LookupRelation<FF>; - static constexpr size_t MAX_RELATION_LENGTH = get_max_relation_length<Relations>(); - static constexpr size_t MAX_RANDOM_RELATION_LENGTH = MAX_RELATION_LENGTH + 1; + static constexpr size_t MAX_PARTIAL_RELATION_LENGTH = compute_max_partial_relation_length<Relations>(); + + // 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<Relations>::value; - // define the containers for storing the contributions from each relation in Sumcheck - using TupleOfTuplesOfUnivariates = decltype(create_relation_univariates_container<FF, Relations>()); - using TupleOfArraysOfValues = decltype(create_relation_values_container<FF, Relations>()); + template <size_t NUM_INSTANCES> + using ProtogalaxyTupleOfTuplesOfUnivariates = + decltype(create_protogalaxy_tuple_of_tuples_of_univariates<Relations, NUM_INSTANCES>()); + using SumcheckTupleOfTuplesOfUnivariates = decltype(create_sumcheck_tuple_of_tuples_of_univariates<Relations>()); + using TupleOfArraysOfValues = decltype(create_tuple_of_arrays_of_values<Relations>()); + + + static constexpr bool has_zero_row = true; private: template<typename DataType, typename HandleType> class PrecomputedEntities : public PrecomputedEntities_<DataType, HandleType, NUM_PRECOMPUTED_ENTITIES> {{ public: + {precomputed_str} - std::vector<HandleType> get_selectors() override {{ return {{}}; }}; std::vector<HandleType> get_sigma_polynomials() override {{ return {{}}; }}; std::vector<HandleType> get_id_polynomials() override {{ return {{}}; }}; std::vector<HandleType> get_table_polynomials() {{ return {{}}; }}; @@ -123,8 +137,11 @@ template <typename CycleGroup_T, typename Curve_T, typename PCS_T> class {name}F public: {precomputed} + {witnesses} {all_shift} + {all_entities_pointer_view} + std::vector<HandleType> get_wires() override {{ return {{ @@ -150,30 +167,6 @@ template <typename CycleGroup_T, typename Curve_T, typename PCS_T> class {name}F }}; }}; - AllEntities() = default; - - AllEntities(const AllEntities& other) - : AllEntities_<DataType, HandleType, NUM_ALL_ENTITIES>(other){{}}; - - AllEntities(AllEntities&& other) noexcept - : AllEntities_<DataType, HandleType, NUM_ALL_ENTITIES>(other){{}}; - - AllEntities& operator=(const AllEntities& other) - {{ - if (this == &other) {{ - return *this; - }} - AllEntities_<DataType, HandleType, NUM_ALL_ENTITIES>::operator=(other); - return *this; - }} - - AllEntities& operator=(AllEntities&& other) noexcept - {{ - AllEntities_<DataType, HandleType, NUM_ALL_ENTITIES>::operator=(other); - return *this; - }} - - ~AllEntities() override = default; }}; public: @@ -199,54 +192,54 @@ template <typename CycleGroup_T, typename Curve_T, typename PCS_T> class {name}F public: using Base = AllEntities<FF, FF>; using Base::Base; - AllValues(std::array<FF, NUM_ALL_ENTITIES> _data_in) {{ this->_data = _data_in; }} }}; class AllPolynomials : public AllEntities<Polynomial, PolynomialHandle> {{ public: - AllValues get_row(const size_t row_idx) const + [[nodiscard]] size_t get_polynomial_size() const {{ return this->{first_poly}.size(); }} + [[nodiscard]] AllValues get_row(const size_t row_idx) const {{ AllValues result; - size_t column_idx = 0; // // TODO(https://github.com/AztecProtocol/barretenberg/issues/391) zip - for (auto& column : this->_data) {{ - result[column_idx] = column[row_idx]; - column_idx++; + for (auto [result_field, polynomial] : zip_view(result.pointer_view(), pointer_view())) {{ + *result_field = (*polynomial)[row_idx]; }} return result; }} }}; + using RowPolynomials = AllEntities<FF, FF>; class PartiallyEvaluatedMultivariates : public AllEntities<Polynomial, PolynomialHandle> {{ - public: + 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->_data) {{ - poly = Polynomial(circuit_size / 2); + for (auto* poly : pointer_view()) {{ + *poly = Polynomial(circuit_size / 2); }} }} }}; - template <size_t MAX_RELATION_LENGTH> - using ExtendedEdges = AllEntities<barretenberg::Univariate<FF, MAX_RELATION_LENGTH>, - barretenberg::Univariate<FF, MAX_RELATION_LENGTH>>; + /** + * @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 <size_t LENGTH> + using ProverUnivariates = AllEntities<barretenberg::Univariate<FF, LENGTH>, barretenberg::Univariate<FF, LENGTH>>; - class ClaimedEvaluations : public AllEntities<FF, FF> {{ - public: - using Base = AllEntities<FF, FF>; - using Base::Base; - ClaimedEvaluations(std::array<FF, NUM_ALL_ENTITIES> _data_in) {{ this->_data = _data_in; }} - }}; + /** + * @brief A container for univariates produced during the hot loop in sumcheck. + */ + using ExtendedEdges = ProverUnivariates<MAX_PARTIAL_RELATION_LENGTH>; {commitment_labels_class} {verification_commitments} -}}; -class {name}Flavor : public {name}FlavorBase<grumpkin::g1, curve::BN254, pcs::kzg::KZG<curve::BN254>> {{}}; + {transcript} +}}; }} // namespace proof_system::honk::flavor }} // namespace proof_system::honk @@ -265,49 +258,66 @@ fn flavor_includes(name: &str, _relations: &[String]) -> String { format!( " #pragma once +#include \"../relation_definitions_fwd.hpp\" #include \"barretenberg/ecc/curves/bn254/g1.hpp\" -#include \"barretenberg/honk/pcs/kzg/kzg.hpp\" +#include \"barretenberg/commitment_schemes/kzg/kzg.hpp\" #include \"barretenberg/polynomials/barycentric.hpp\" #include \"barretenberg/polynomials/univariate.hpp\" -#include \"barretenberg/honk/transcript/transcript.hpp\" +#include \"barretenberg/transcript/transcript.hpp\" #include \"barretenberg/polynomials/evaluation_domain.hpp\" #include \"barretenberg/polynomials/polynomial.hpp\" -// #include \"barretenberg/proof_system/circuit_builder/ultra_circuit_builder.hpp\" -#include \"barretenberg/proof_system/flavor/flavor.hpp\" -#include \"barretenberg/proof_system/relations/generated/{name}.hpp\" +#include \"barretenberg/flavor/flavor.hpp\" +#include \"barretenberg/relations/generated/{name}.hpp\" " ) } fn create_precomputed_entities(fixed: &[String]) -> String { + let data_types = witness_get(fixed, false); let mut name_set = String::new(); for name in fixed { let n = name.replace('.', "_"); name_set.push_str(&format!("{n}, ", n = n)); } - let get_selectors = format!( + let pointer_view = create_pointer_view("NUM_PRECOMPUTED_ENTITIES", fixed); + + format!( " + {data_types} + {pointer_view} + std::vector<HandleType> get_selectors() override {{ return {{ {name_set} }}; }}; ", name_set = name_set - ); + ) +} - get_selectors +fn create_pointer_view(label: &str, entities: &[String]) -> String { + let pointer_list = entities + .iter() + .map(|e| format!("&{}", e.replace('.', "_"))) + .collect::<Vec<_>>() + .join(", "); + + format!( + "DEFINE_POINTER_VIEW({label}, {pointer_list})", + label = label, + pointer_list = pointer_list + ) } -fn witness_get(witness: &[String], offset: usize, shift: bool) -> String { +fn witness_get(witness: &[String], shift: bool) -> String { let mut return_string = String::new(); - for (i, name) in witness.iter().enumerate() { + for name in witness.iter() { let n = name.replace('.', "_"); let n = if shift { format!("{}_shift", n) } else { n }; - let index = i + offset; return_string.push_str(&format!( " - DataType& {n} = std::get<{index}>(this->_data);", + DataType {n};", n = n )); } @@ -337,13 +347,16 @@ fn make_wires_set(set: &[String]) -> String { } fn create_witness_entities(witness: &[String]) -> String { - let data_types = witness_get(witness, 0, false); + let data_types = witness_get(witness, false); let get_wires = make_wires_set(witness); + let pointer_view = create_pointer_view("NUM_WITNESS_ENTITIES", witness); format!( " {data_types} + {pointer_view} + std::vector<HandleType> get_wires() override {{ return {{ {get_wires} @@ -388,19 +401,129 @@ fn create_commitment_labels(all_ents: &[String]) -> String { ) } -fn create_verifier_commitments() -> &'static str { - r#" - class VerifierCommitments : public AllEntities<Commitment, CommitmentHandle> { +fn create_key_dereference(fixed: &[String]) -> String { + fixed + .iter() + .map(|f| { + let name = f.replace('.', "_"); + format!("{name} = verification_key->{name};") + }) + .collect::<Vec<_>>() + .join("\n") +} + +fn create_verifier_commitments(fixed: &[String]) -> String { + let key_dereference = create_key_dereference(fixed); + + format!( + " + class VerifierCommitments : public AllEntities<Commitment, CommitmentHandle> {{ private: using Base = AllEntities<Commitment, CommitmentHandle>; public: VerifierCommitments(const std::shared_ptr<VerificationKey>& verification_key, - const VerifierTranscript<FF>& transcript) - { + const BaseTranscript<FF>& transcript) + {{ static_cast<void>(transcript); - static_cast<void>(verification_key); - } - }; -"# + {key_dereference} + }} + }}; +" + ) +} + +fn generate_transcript(witness: &[String]) -> String { + let declarations = witness + .iter() + .map(|f| format!("Commitment {};", f.replace('.', "_"))) + .collect::<Vec<_>>() + .join("\n"); + let deserialize_wires = witness + .iter() + .map(|f| { + format!( + "{} = deserialize_from_buffer<Commitment>(BaseTranscript<FF>::proof_data, num_bytes_read);", + f.replace('.', "_") + ) + }) + .collect::<Vec<_>>() + .join("\n"); + let serialize_wires = witness + .iter() + .map(|f| { + format!( + "serialize_to_buffer<Commitment>({}, BaseTranscript<FF>::proof_data);", + f.replace('.', "_") + ) + }) + .collect::<Vec<_>>() + .join("\n"); + + format!(" + class Transcript : public BaseTranscript<FF> {{ + public: + uint32_t circuit_size; + + {declarations} + + std::vector<barretenberg::Univariate<FF, BATCHED_RELATION_PARTIAL_LENGTH>> sumcheck_univariates; + std::array<FF, NUM_ALL_ENTITIES> sumcheck_evaluations; + std::vector<Commitment> zm_cq_comms; + Commitment zm_cq_comm; + Commitment zm_pi_comm; + + Transcript() = default; + + Transcript(const std::vector<uint8_t>& proof) + : BaseTranscript<FF>(proof) + {{}} + + void deserialize_full_transcript() override + {{ + size_t num_bytes_read = 0; + circuit_size = deserialize_from_buffer<uint32_t>(proof_data, num_bytes_read); + size_t log_n = numeric::get_msb(circuit_size); + + {deserialize_wires} + + for (size_t i = 0; i < log_n; ++i) {{ + sumcheck_univariates.emplace_back( + deserialize_from_buffer<barretenberg::Univariate<FF, BATCHED_RELATION_PARTIAL_LENGTH>>( + BaseTranscript<FF>::proof_data, num_bytes_read)); + }} + sumcheck_evaluations = deserialize_from_buffer<std::array<FF, NUM_ALL_ENTITIES>>( + BaseTranscript<FF>::proof_data, num_bytes_read); + for (size_t i = 0; i < log_n; ++i) {{ + zm_cq_comms.push_back(deserialize_from_buffer<Commitment>(proof_data, num_bytes_read)); + }} + zm_cq_comm = deserialize_from_buffer<Commitment>(proof_data, num_bytes_read); + zm_pi_comm = deserialize_from_buffer<Commitment>(proof_data, num_bytes_read); + }} + + void serialize_full_transcript() override + {{ + size_t old_proof_length = proof_data.size(); + BaseTranscript<FF>::proof_data.clear(); + size_t log_n = numeric::get_msb(circuit_size); + + serialize_to_buffer(circuit_size, BaseTranscript<FF>::proof_data); + + {serialize_wires} + + for (size_t i = 0; i < log_n; ++i) {{ + serialize_to_buffer(sumcheck_univariates[i], BaseTranscript<FF>::proof_data); + }} + serialize_to_buffer(sumcheck_evaluations, BaseTranscript<FF>::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); + }} + }}; + ") } diff --git a/bberg/src/prover_builder.rs b/bberg/src/prover_builder.rs index 8ee21e9b91..3f926843a2 100644 --- a/bberg/src/prover_builder.rs +++ b/bberg/src/prover_builder.rs @@ -13,37 +13,31 @@ impl ProverBuilder for BBFiles { {include_str} namespace proof_system::honk {{ - template <typename Flavor> class {name}Prover_ {{ - - using FF = typename Flavor::FF; - using PCS = typename Flavor::PCS; - using PCSCommitmentKey = typename Flavor::CommitmentKey; - using ProvingKey = typename Flavor::ProvingKey; - using Polynomial = typename Flavor::Polynomial; - using ProverPolynomials = typename Flavor::ProverPolynomials; - using CommitmentLabels = typename Flavor::CommitmentLabels; - using Curve = typename Flavor::Curve; + class {name}Prover {{ + + using Flavor = honk::flavor::{name}Flavor; + 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 {name}Prover_(std::shared_ptr<ProvingKey> input_key, std::shared_ptr<PCSCommitmentKey> commitment_key); + explicit {name}Prover(std::shared_ptr<ProvingKey> input_key, std::shared_ptr<PCSCommitmentKey> commitment_key); void execute_preamble_round(); void execute_wire_commitments_round(); - // void execute_log_derivative_commitments_round(); - // void execute_grand_product_computation_round(); void execute_relation_check_rounds(); - void execute_univariatization_round(); - void execute_pcs_evaluation_round(); - void execute_shplonk_batched_quotient_round(); - void execute_shplonk_partial_evaluation_round(); - void execute_final_pcs_round(); - - void compute_wire_commitments(); + void execute_zeromorph_rounds(); plonk::proof& export_proof(); plonk::proof& construct_proof(); - ProverTranscript<FF> transcript; + Transcript transcript; std::vector<FF> public_inputs; @@ -55,31 +49,19 @@ impl ProverBuilder for BBFiles { ProverPolynomials prover_polynomials; CommitmentLabels commitment_labels; - - // Container for d + 1 Fold polynomials produced by Gemini - std::vector<Polynomial> gemini_polynomials; - - Polynomial batched_quotient_Q; // batched quotient poly computed by Shplonk - FF nu_challenge; // needed in both Shplonk rounds - + Polynomial quotient_W; sumcheck::SumcheckOutput<Flavor> sumcheck_output; - pcs::gemini::ProverOutput<Curve> gemini_output; - pcs::shplonk::ProverOutput<Curve> shplonk_output; + std::shared_ptr<PCSCommitmentKey> commitment_key; - using Gemini = pcs::gemini::GeminiProver_<Curve>; - using Shplonk = pcs::shplonk::ShplonkProver_<Curve>; + using ZeroMorph = pcs::zeromorph::ZeroMorphProver_<Curve>; private: plonk::proof proof; }}; - extern template class {name}Prover_<honk::flavor::{name}Flavor>; - - using {name}Prover = {name}Prover_<honk::flavor::{name}Flavor>; - }} // namespace proof_system::honk "); @@ -126,17 +108,18 @@ prover_polynomials.{n}_shift = key->{n}.shifted(); {include_str} namespace proof_system::honk {{ + + using Flavor = honk::flavor::{name}Flavor; /** - * Create {name}Prover_ from proving key, witness and manifest. + * Create {name}Prover from proving key, witness and manifest. * * @param input_key Proving key. * @param input_manifest Input manifest * * @tparam settings Settings class. * */ - template <typename Flavor> - {name}Prover_<Flavor>::{name}Prover_(std::shared_ptr<typename Flavor::ProvingKey> input_key, + {name}Prover::{name}Prover(std::shared_ptr<Flavor::ProvingKey> input_key, std::shared_ptr<PCSCommitmentKey> commitment_key) : key(input_key) , commitment_key(commitment_key) @@ -149,24 +132,12 @@ prover_polynomials.{n}_shift = key->{n}.shifted(); // prover_polynomials.z_perm = key->z_perm; }} - /** - * @brief Commit to the wires - * - */ - template <typename Flavor> void {name}Prover_<Flavor>::compute_wire_commitments() - {{ - 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 Add circuit size, public input size, and public inputs to transcript * */ - template <typename Flavor> void {name}Prover_<Flavor>::execute_preamble_round() + void {name}Prover::execute_preamble_round() {{ const auto circuit_size = static_cast<uint32_t>(key->circuit_size); @@ -177,7 +148,7 @@ prover_polynomials.{n}_shift = key->{n}.shifted(); * @brief Compute commitments to the first three wires * */ - template <typename Flavor> void {name}Prover_<Flavor>::execute_wire_commitments_round() + void {name}Prover::execute_wire_commitments_round() {{ auto wire_polys = key->get_wires(); auto labels = commitment_labels.get_wires(); @@ -186,155 +157,48 @@ prover_polynomials.{n}_shift = key->{n}.shifted(); }} }} - /** - * @brief Compute sorted witness-table accumulator - * - */ - // template <typename Flavor> void {name}Prover_<Flavor>::execute_log_derivative_commitments_round() - // {{ - // // Compute and add beta to relation parameters - // auto [beta, gamma] = transcript.get_challenges(\"beta\", \"gamma\"); - // // TODO(#583)(@zac-williamson): fix Transcript to be able to generate more than 2 challenges per round! oof. - // auto beta_sqr = beta * beta; - // relation_parameters.gamma = gamma; - // relation_parameters.beta = beta; - // relation_parameters.beta_sqr = beta_sqr; - // relation_parameters.beta_cube = beta_sqr * beta; - // relation_parameters.{name}_set_permutation_delta = - // gamma * (gamma + beta_sqr) * (gamma + beta_sqr + beta_sqr) * (gamma + beta_sqr + beta_sqr + beta_sqr); - // relation_parameters.{name}_set_permutation_delta = relation_parameters.{name}_set_permutation_delta.invert(); - // // Compute inverse polynomial for our logarithmic-derivative lookup method - // lookup_library::compute_logderivative_inverse<Flavor, typename Flavor::LookupRelation>( - // prover_polynomials, relation_parameters, key->circuit_size); - // transcript.send_to_verifier(commitment_labels.lookup_inverses, commitment_key->commit(key->lookup_inverses)); - // prover_polynomials.lookup_inverses = key->lookup_inverses; - // }} - - /** - * @brief Compute permutation and lookup grand product polynomials and commitments - * - */ - // template <typename Flavor> void {name}Prover_<Flavor>::execute_grand_product_computation_round() - // {{ - // // Compute permutation grand product and their commitments - // permutation_library::compute_permutation_grand_products<Flavor>(key, prover_polynomials, relation_parameters); - - // transcript.send_to_verifier(commitment_labels.z_perm, commitment_key->commit(key->z_perm)); - // }} + /** * @brief Run Sumcheck resulting in u = (u_1,...,u_d) challenges and all evaluations at u being calculated. * */ - template <typename Flavor> void {name}Prover_<Flavor>::execute_relation_check_rounds() + void {name}Prover::execute_relation_check_rounds() {{ using Sumcheck = sumcheck::SumcheckProver<Flavor>; auto sumcheck = Sumcheck(key->circuit_size, transcript); + auto alpha = transcript.get_challenge(\"alpha\"); - sumcheck_output = sumcheck.prove(prover_polynomials, relation_parameters); + sumcheck_output = sumcheck.prove(prover_polynomials, relation_parameters, alpha); }} - + + /** - * - Get rho challenge - * - Compute d+1 Fold polynomials and their evaluations. + * @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. * * */ - template <typename Flavor> void {name}Prover_<Flavor>::execute_univariatization_round() + void FibProver::execute_zeromorph_rounds() {{ - const size_t NUM_POLYNOMIALS = Flavor::NUM_ALL_ENTITIES; - - // Generate batching challenge ρ and powers 1,ρ,…,ρᵐ⁻¹ - FF rho = transcript.get_challenge(\"rho\"); - std::vector<FF> rhos = pcs::gemini::powers_of_rho(rho, NUM_POLYNOMIALS); - - // Batch the unshifted polynomials and the to-be-shifted polynomials using ρ - Polynomial batched_poly_unshifted(key->circuit_size); // batched unshifted polynomials - size_t poly_idx = 0; // TODO(#391) zip - for (auto& unshifted_poly : prover_polynomials.get_unshifted()) {{ - batched_poly_unshifted.add_scaled(unshifted_poly, rhos[poly_idx]); - ++poly_idx; - }} - - Polynomial batched_poly_to_be_shifted(key->circuit_size); // batched to-be-shifted polynomials - for (auto& to_be_shifted_poly : prover_polynomials.get_to_be_shifted()) {{ - batched_poly_to_be_shifted.add_scaled(to_be_shifted_poly, rhos[poly_idx]); - ++poly_idx; - }}; - - // Compute d-1 polynomials Fold^(i), i = 1, ..., d-1. - gemini_polynomials = Gemini::compute_gemini_polynomials( - sumcheck_output.challenge, std::move(batched_poly_unshifted), std::move(batched_poly_to_be_shifted)); - - // Compute and add to trasnscript the commitments [Fold^(i)], i = 1, ..., d-1 - for (size_t l = 0; l < key->log_circuit_size - 1; ++l) {{ - transcript.send_to_verifier(\"Gemini:FOLD_\" + std::to_string(l + 1), - commitment_key->commit(gemini_polynomials[l + 2])); - }} - }} - - /** - * - Do Fiat-Shamir to get \"r\" challenge - * - Compute remaining two partially evaluated Fold polynomials Fold_{{r}}^(0) and Fold_{{-r}}^(0). - * - Compute and aggregate opening pairs (challenge, evaluation) for each of d Fold polynomials. - * - Add d-many Fold evaluations a_i, i = 0, ..., d-1 to the transcript, excluding eval of Fold_{{r}}^(0) - * */ - template <typename Flavor> void {name}Prover_<Flavor>::execute_pcs_evaluation_round() - {{ - const FF r_challenge = transcript.get_challenge(\"Gemini:r\"); - gemini_output = Gemini::compute_fold_polynomial_evaluations( - sumcheck_output.challenge, std::move(gemini_polynomials), r_challenge); - - for (size_t l = 0; l < key->log_circuit_size; ++l) {{ - std::string label = \"Gemini:a_\" + std::to_string(l); - const auto& evaluation = gemini_output.opening_pairs[l + 1].evaluation; - transcript.send_to_verifier(label, evaluation); - }} - }} - - /** - * - Do Fiat-Shamir to get \"nu\" challenge. - * - Compute commitment [Q]_1 - * */ - template <typename Flavor> void {name}Prover_<Flavor>::execute_shplonk_batched_quotient_round() - {{ - nu_challenge = transcript.get_challenge(\"Shplonk:nu\"); - - batched_quotient_Q = - Shplonk::compute_batched_quotient(gemini_output.opening_pairs, gemini_output.witnesses, nu_challenge); - - // commit to Q(X) and add [Q] to the transcript - transcript.send_to_verifier(\"Shplonk:Q\", commitment_key->commit(batched_quotient_Q)); - }} - - /** - * - Do Fiat-Shamir to get \"z\" challenge. - * - Compute polynomial Q(X) - Q_z(X) - * */ - template <typename Flavor> void {name}Prover_<Flavor>::execute_shplonk_partial_evaluation_round() - {{ - const FF z_challenge = transcript.get_challenge(\"Shplonk:z\"); - - shplonk_output = Shplonk::compute_partially_evaluated_batched_quotient( - gemini_output.opening_pairs, gemini_output.witnesses, std::move(batched_quotient_Q), nu_challenge, z_challenge); - }} - /** - * - Compute final PCS opening proof: - * - For KZG, this is the quotient commitment [W]_1 - * - For IPA, the vectors L and R - * */ - template <typename Flavor> void {name}Prover_<Flavor>::execute_final_pcs_round() - {{ - PCS::compute_opening_proof(commitment_key, shplonk_output.opening_pair, shplonk_output.witness, transcript); + 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); + }} + - template <typename Flavor> plonk::proof& {name}Prover_<Flavor>::export_proof() + plonk::proof& {name}Prover::export_proof() {{ proof.proof_data = transcript.proof_data; return proof; }} - template <typename Flavor> plonk::proof& {name}Prover_<Flavor>::construct_proof() + plonk::proof& {name}Prover::construct_proof() {{ // Add circuit size public input size and public inputs to transcript. execute_preamble_round(); @@ -354,31 +218,13 @@ prover_polynomials.{n}_shift = key->{n}.shifted(); // Run sumcheck subprotocol. execute_relation_check_rounds(); - // Fiat-Shamir: rho - // Compute Fold polynomials and their commitments. - execute_univariatization_round(); - - // Fiat-Shamir: r - // Compute Fold evaluations - execute_pcs_evaluation_round(); - - // Fiat-Shamir: nu - // Compute Shplonk batched quotient commitment Q - execute_shplonk_batched_quotient_round(); - - // Fiat-Shamir: z - // Compute partial evaluation Q_z - execute_shplonk_partial_evaluation_round(); - - // Fiat-Shamir: z - // Compute PCS opening proof (either KZG quotient commitment or IPA opening proof) - execute_final_pcs_round(); + // Fiat-Shamir: rho, y, x, z + // Execute Zeromorph multilinear PCS + execute_zeromorph_rounds(); return export_proof(); }} - template class {name}Prover_<honk::flavor::{name}Flavor>; - }} // namespace proof_system::honk @@ -391,13 +237,12 @@ fn includes_hpp(name: &str) -> String { format!( " #pragma once -#include \"barretenberg/honk/flavor/generated/{name}_flavor.hpp\" -#include \"barretenberg/honk/pcs/gemini/gemini.hpp\" -#include \"barretenberg/honk/pcs/shplonk/shplonk.hpp\" -#include \"barretenberg/honk/sumcheck/sumcheck_output.hpp\" -#include \"barretenberg/honk/transcript/transcript.hpp\" +#include \"barretenberg/flavor/generated/{name}_flavor.hpp\" +#include \"barretenberg/commitment_schemes/zeromorph/zeromorph.hpp\" +#include \"barretenberg/sumcheck/sumcheck_output.hpp\" +#include \"barretenberg/transcript/transcript.hpp\" #include \"barretenberg/plonk/proof_system/types/proof.hpp\" -#include \"barretenberg/proof_system/relations/relation_parameters.hpp\" +#include \"barretenberg/relations/relation_parameters.hpp\" " ) @@ -408,25 +253,16 @@ fn includes_cpp(name: &str) -> String { " #include \"{name}_prover.hpp\" - #include \"barretenberg/honk/pcs/claim.hpp\" - #include \"barretenberg/honk/pcs/commitment_key.hpp\" + #include \"barretenberg/commitment_schemes/claim.hpp\" + #include \"barretenberg/commitment_schemes/commitment_key.hpp\" #include \"barretenberg/honk/proof_system/lookup_library.hpp\" #include \"barretenberg/honk/proof_system/permutation_library.hpp\" - #include \"barretenberg/honk/sumcheck/sumcheck.hpp\" - #include \"barretenberg/honk/utils/power_polynomial.hpp\" + #include \"barretenberg/honk/proof_system/power_polynomial.hpp\" #include \"barretenberg/polynomials/polynomial.hpp\" - #include \"barretenberg/polynomials/univariate.hpp\" // will go away - #include \"barretenberg/proof_system/relations/lookup_relation.hpp\" - #include \"barretenberg/proof_system/relations/permutation_relation.hpp\" - #include \"barretenberg/transcript/transcript_wrappers.hpp\" - #include <algorithm> - #include <array> - #include <cstddef> - #include <memory> - #include <span> - #include <string> - #include <utility> - #include <vector> + #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\" " ) } diff --git a/bberg/src/relation_builder.rs b/bberg/src/relation_builder.rs index 110e06a0b9..1a12e2b331 100644 --- a/bberg/src/relation_builder.rs +++ b/bberg/src/relation_builder.rs @@ -110,8 +110,9 @@ fn get_degree_boilerplate(degrees: Vec<DegreeType>) -> String { let max = degrees.iter().max().unwrap(); let num_degrees = degrees.len(); - let mut degree_boilerplate = - format!("static constexpr std::array<size_t, {num_degrees}> SUBRELATION_LENGTHS{{\n"); + let mut degree_boilerplate = format!( + "static constexpr std::array<size_t, {num_degrees}> SUBRELATION_PARTIAL_LENGTHS{{\n" + ); // for i in 0..degrees.len() { // degree_boilerplate.push_str(&format!(" {},\n", degrees[i])); // } diff --git a/bberg/src/trace_builder.rs b/bberg/src/trace_builder.rs index e4cf0f777a..a47ca9529c 100644 --- a/bberg/src/trace_builder.rs +++ b/bberg/src/trace_builder.rs @@ -12,12 +12,10 @@ fn trace_hpp_includes(name: &str) -> String { #include \"barretenberg/common/throw_or_abort.hpp\" #include \"barretenberg/ecc/curves/bn254/fr.hpp\" - #include \"barretenberg/proof_system/arithmetization/arithmetization.hpp\" #include \"barretenberg/proof_system/circuit_builder/circuit_builder_base.hpp\" - #include \"barretenberg/honk/flavor/generated/{name}_flavor.hpp\" - #include \"barretenberg/proof_system/arithmetization/generated/{name}_arith.hpp\" - #include \"barretenberg/proof_system/relations/generated/{name}.hpp\" + #include \"barretenberg/flavor/generated/{name}_flavor.hpp\" + #include \"barretenberg/relations/generated/{name}.hpp\" " ) } @@ -57,12 +55,13 @@ namespace proof_system {{ class {name}TraceBuilder {{ public: - using FF = arithmetization::{name}Arithmetization::FF; + using Flavor = proof_system::honk::flavor::{name}Flavor; + using FF = Flavor::FF; using Row = {name}_vm::Row<FF>; // TODO: tempalte - using Polynomial = honk::flavor::{name}Flavor::Polynomial; - using AllPolynomials = honk::flavor::{name}Flavor::AllPolynomials; + using Polynomial = Flavor::Polynomial; + using AllPolynomials = Flavor::AllPolynomials; static constexpr size_t num_fixed_columns = {num_cols}; static constexpr size_t num_polys = {num_polys}; @@ -75,8 +74,8 @@ class {name}TraceBuilder {{ AllPolynomials polys; // Allocate mem for each column - for (size_t i = 0; i < num_fixed_columns; ++i) {{ - polys[i] = Polynomial(num_rows); + for (auto* poly : polys.pointer_view()) {{ + *poly = Polynomial(num_rows); }} for (size_t i = 0; i < rows.size(); i++) {{ @@ -88,24 +87,26 @@ class {name}TraceBuilder {{ return polys; }} - [[maybe_unused]] bool check_circuit() {{ + [[maybe_unused]] bool check_circuit() + {{ auto polys = compute_polynomials(); - const size_t num_rows = polys[0].size(); - + const size_t num_rows = polys.get_polynomial_size(); + const auto evaluate_relation = [&]<typename Relation>(const std::string& relation_name) {{ - typename Relation::ArrayOfValuesOverSubrelations result; + 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)); + throw_or_abort( + format(\"Relation \", relation_name, \", subrelation index \", j, \" failed at row \", i)); x = false; }} }} @@ -116,8 +117,9 @@ class {name}TraceBuilder {{ return true; }}; - return evaluate_relation.template operator()<{name}_vm::{name}<FF>>(\"{name}\"); + return evaluate_relation.template operator()<Fib_vm::Fib<FF>>(\"Fib\"); }} + [[nodiscard]] size_t get_num_gates() const {{ return rows.size(); }} diff --git a/bberg/src/verifier_builder.rs b/bberg/src/verifier_builder.rs index d9558b04e8..c75438d0c6 100644 --- a/bberg/src/verifier_builder.rs +++ b/bberg/src/verifier_builder.rs @@ -1,16 +1,16 @@ use crate::file_writer::BBFiles; pub trait VerifierBuilder { - fn create_verifier_cpp(&mut self, name: &str, all_wires: &[String]); + fn create_verifier_cpp(&mut self, name: &str, witness: &[String]); fn create_verifier_hpp(&mut self, name: &str); } impl VerifierBuilder for BBFiles { - fn create_verifier_cpp(&mut self, name: &str, all_wires: &[String]) { + fn create_verifier_cpp(&mut self, name: &str, witness: &[String]) { let include_str = includes_cpp(name); - let wire_commitments = all_wires.iter().map(|name|{ + let wire_commitments = witness.iter().map(|name|{ let n = name.replace('.',"_"); format!("commitments.{n} = transcript.template receive_from_prover<Commitment>(commitment_labels.{n});", n=n) }).collect::<Vec<String>>().join("\n"); @@ -22,23 +22,20 @@ impl VerifierBuilder for BBFiles { using namespace proof_system::honk::sumcheck; namespace proof_system::honk {{ - template <typename Flavor> - {name}Verifier_<Flavor>::{name}Verifier_(std::shared_ptr<typename Flavor::VerificationKey> verifier_key) + {name}Verifier::{name}Verifier(std::shared_ptr<Flavor::VerificationKey> verifier_key) : key(verifier_key) {{}} - template <typename Flavor> - {name}Verifier_<Flavor>::{name}Verifier_({name}Verifier_&& other) noexcept + {name}Verifier::{name}Verifier({name}Verifier&& other) noexcept : key(std::move(other.key)) , pcs_verification_key(std::move(other.pcs_verification_key)) {{}} - template <typename Flavor> {name}Verifier_<Flavor>& {name}Verifier_<Flavor>::operator=({name}Verifier_&& other) noexcept + {name}Verifier& {name}Verifier::operator=({name}Verifier&& other) noexcept {{ key = other.key; pcs_verification_key = (std::move(other.pcs_verification_key)); commitments.clear(); - pcs_fr_elements.clear(); return *this; }} @@ -46,21 +43,19 @@ impl VerifierBuilder for BBFiles { * @brief This function verifies an {name} Honk proof for given program settings. * */ - template <typename Flavor> bool {name}Verifier_<Flavor>::verify_proof(const plonk::proof& proof) + bool {name}Verifier::verify_proof(const plonk::proof& proof) {{ - using FF = typename Flavor::FF; - using GroupElement = typename Flavor::GroupElement; - using Commitment = typename Flavor::Commitment; - using PCS = typename Flavor::PCS; - using Curve = typename Flavor::Curve; - using Gemini = pcs::gemini::GeminiVerifier_<Curve>; - using Shplonk = pcs::shplonk::ShplonkVerifier_<Curve>; - using VerifierCommitments = typename Flavor::VerifierCommitments; - using CommitmentLabels = typename Flavor::CommitmentLabels; + using Flavor = honk::flavor::{name}Flavor; + using FF = Flavor::FF; + using Commitment = Flavor::Commitment; + // using Curve = Flavor::Curve; + // using ZeroMorph = pcs::zeromorph::ZeroMorphVerifier_<Curve>; + using VerifierCommitments = Flavor::VerifierCommitments; + using CommitmentLabels = Flavor::CommitmentLabels; RelationParameters<FF> relation_parameters; - transcript = VerifierTranscript<FF>{{ proof.proof_data }}; + transcript = BaseTranscript<FF>{{ proof.proof_data }}; auto commitments = VerifierCommitments(key, transcript); auto commitment_labels = CommitmentLabels(); @@ -74,100 +69,33 @@ impl VerifierBuilder for BBFiles { // Get commitments to VM wires {wire_commitments} - // Permutation / logup related stuff? - // Get challenge for sorted list batching and wire four memory records - // auto [beta, gamma] = transcript.get_challenges(\"bbeta\", \"gamma\"); - // relation_parameters.gamma = gamma; - // auto beta_sqr = beta * beta; - // relation_parameters.beta = beta; - // relation_parameters.beta_sqr = beta_sqr; - // relation_parameters.beta_cube = beta_sqr * beta; - // relation_parameters.{name}_set_permutation_delta = - // gamma * (gamma + beta_sqr) * (gamma + beta_sqr + beta_sqr) * (gamma + beta_sqr + beta_sqr + beta_sqr); - // relation_parameters.{name}_set_permutation_delta = relation_parameters.{name}_set_permutation_delta.invert(); - - // Get commitment to permutation and lookup grand products - // commitments.lookup_inverses = - // transcript.template receive_from_prover<Commitment>(commitment_labels.lookup_inverses); - // commitments.z_perm = transcript.template receive_from_prover<Commitment>(commitment_labels.z_perm); - // Execute Sumcheck Verifier auto sumcheck = SumcheckVerifier<Flavor>(circuit_size); - auto [multivariate_challenge, purported_evaluations, sumcheck_verified] = - sumcheck.verify(relation_parameters, transcript); + 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 Gemini/Shplonk verification: - - // Construct inputs for Gemini verifier: - // - Multivariate opening point u = (u_0, ..., u_{{d-1}}) - // - batched unshifted and to-be-shifted polynomial commitments - auto batched_commitment_unshifted = GroupElement::zero(); - auto batched_commitment_to_be_shifted = GroupElement::zero(); - const size_t NUM_POLYNOMIALS = Flavor::NUM_ALL_ENTITIES; - // Compute powers of batching challenge rho - FF rho = transcript.get_challenge(\"rho\"); - std::vector<FF> rhos = pcs::gemini::powers_of_rho(rho, NUM_POLYNOMIALS); - - // Compute batched multivariate evaluation - FF batched_evaluation = FF::zero(); - size_t evaluation_idx = 0; - for (auto& value : purported_evaluations.get_unshifted()) {{ - batched_evaluation += value * rhos[evaluation_idx]; - ++evaluation_idx; - }} - for (auto& value : purported_evaluations.get_shifted()) {{ - batched_evaluation += value * rhos[evaluation_idx]; - ++evaluation_idx; - }} - - // Construct batched commitment for NON-shifted polynomials - size_t commitment_idx = 0; - for (auto& commitment : commitments.get_unshifted()) {{ - // TODO(@zac-williamson) ensure {name} polynomial commitments are never points at infinity (#2214) - if (commitment.y != 0) {{ - batched_commitment_unshifted += commitment * rhos[commitment_idx]; - }} else {{ - info(\"point at infinity (unshifted)\"); - }} - ++commitment_idx; - }} - - // Construct batched commitment for to-be-shifted polynomials - for (auto& commitment : commitments.get_to_be_shifted()) {{ - // TODO(@zac-williamson) ensure {name} polynomial commitments are never points at infinity (#2214) - if (commitment.y != 0) {{ - batched_commitment_to_be_shifted += commitment * rhos[commitment_idx]; - }} else {{ - info(\"point at infinity (to be shifted)\"); - }} - ++commitment_idx; - }} - - // Produce a Gemini claim consisting of: - // - d+1 commitments [Fold_{{r}}^(0)], [Fold_{{-r}}^(0)], and [Fold^(l)], l = 1:d-1 - // - d+1 evaluations a_0_pos, and a_l, l = 0:d-1 - auto gemini_claim = Gemini::reduce_verification(multivariate_challenge, - batched_evaluation, - batched_commitment_unshifted, - batched_commitment_to_be_shifted, - transcript); - - // Produce a Shplonk claim: commitment [Q] - [Q_z], evaluation zero (at random challenge z) - auto shplonk_claim = Shplonk::reduce_verification(pcs_verification_key, gemini_claim, transcript); - - // Verify the Shplonk claim with KZG or IPA - auto verified = PCS::verify(pcs_verification_key, shplonk_claim, transcript); - - return sumcheck_verified.value() && verified; + // 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(); }} - template class {name}Verifier_<honk::flavor::{name}Flavor>; }} // namespace proof_system::honk @@ -183,45 +111,29 @@ impl VerifierBuilder for BBFiles { {include_str} namespace proof_system::honk {{ - template <typename Flavor> class {name}Verifier_ {{ - using FF = typename Flavor::FF; - using Commitment = typename Flavor::Commitment; - using VerificationKey = typename Flavor::VerificationKey; - using VerifierCommitmentKey = typename Flavor::VerifierCommitmentKey; + class {name}Verifier {{ + using Flavor = honk::flavor::{name}Flavor; + using FF = Flavor::FF; + using Commitment = Flavor::Commitment; + using VerificationKey = Flavor::VerificationKey; + using VerifierCommitmentKey = Flavor::VerifierCommitmentKey; - public: - explicit {name}Verifier_(std::shared_ptr<VerificationKey> verifier_key = nullptr); - {name}Verifier_(std::shared_ptr<VerificationKey> key, - std::map<std::string, Commitment> commitments, - std::map<std::string, FF> pcs_fr_elements, - std::shared_ptr<VerifierCommitmentKey> pcs_verification_key, - VerifierTranscript<FF> transcript) - : key(std::move(key)) - , commitments(std::move(commitments)) - , pcs_fr_elements(std::move(pcs_fr_elements)) - , pcs_verification_key(std::move(pcs_verification_key)) - , transcript(std::move(transcript)) - {{}} - - {name}Verifier_({name}Verifier_&& other) noexcept; - {name}Verifier_(const {name}Verifier_& other) = delete; - {name}Verifier_& operator=(const {name}Verifier_& other) = delete; - {name}Verifier_& operator=({name}Verifier_&& other) noexcept; - ~{name}Verifier_() = default; + public: + explicit FibVerifier(std::shared_ptr<VerificationKey> verifier_key = nullptr); + FibVerifier(FibVerifier&& other) noexcept; + FibVerifier(const FibVerifier& other) = delete; + + FibVerifier& operator=(const FibVerifier& other) = delete; + FibVerifier& operator=(FibVerifier&& other) noexcept; bool verify_proof(const plonk::proof& proof); std::shared_ptr<VerificationKey> key; std::map<std::string, Commitment> commitments; - std::map<std::string, FF> pcs_fr_elements; std::shared_ptr<VerifierCommitmentKey> pcs_verification_key; - VerifierTranscript<FF> transcript; + BaseTranscript<FF> transcript; }}; - extern template class {name}Verifier_<honk::flavor::{name}Flavor>; - - using {name}Verifier = {name}Verifier_<honk::flavor::{name}Flavor>; - }} // namespace proof_system::honk @@ -235,8 +147,8 @@ fn include_hpp(name: &str) -> String { format!( " #pragma once -#include \"barretenberg/honk/flavor/generated/{name}_flavor.hpp\" -#include \"barretenberg/honk/sumcheck/sumcheck.hpp\" +#include \"barretenberg/flavor/generated/{name}_flavor.hpp\" +#include \"barretenberg/sumcheck/sumcheck.hpp\" #include \"barretenberg/plonk/proof_system/types/proof.hpp\" " ) @@ -246,12 +158,11 @@ fn includes_cpp(name: &str) -> String { format!( " #include \"./{name}_verifier.hpp\" - #include \"barretenberg/honk/flavor/generated/{name}_flavor.hpp\" - #include \"barretenberg/honk/pcs/gemini/gemini.hpp\" - #include \"barretenberg/honk/pcs/shplonk/shplonk.hpp\" - #include \"barretenberg/honk/transcript/transcript.hpp\" - #include \"barretenberg/honk/utils/power_polynomial.hpp\" + #include \"./{name}_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\" " ) } diff --git a/compiler/src/lib.rs b/compiler/src/lib.rs index 2e6ccb010c..f1593ea929 100644 --- a/compiler/src/lib.rs +++ b/compiler/src/lib.rs @@ -230,7 +230,7 @@ fn compile<T: FieldElement, Q: QueryCallback<T>>( bname: Option<String>, ) -> CompilationResult<T> { log::info!("Optimizing pil..."); - // let analyzed = pilopt::optimize(analyzed); + let analyzed = pilopt::optimize(analyzed); // md: we inline intermediate polynomials here, as honk does not have a notion of an intermediate let mut mut_analyzed = analyzed;