From 65fcfc490ca82394d56e97409b123c939794f5e1 Mon Sep 17 00:00:00 2001 From: jeanmon Date: Fri, 11 Oct 2024 17:38:43 +0000 Subject: [PATCH] 8849: codegen recursive_verifier.cpp --- .../acir_format/avm_recursion_constraint.cpp | 4 +- .../recursive_verifier.cpp} | 3 +- ...ursive_flavor.hpp => recursive_flavor.hpp} | 0 ...ve_verifier.hpp => recursive_verifier.hpp} | 2 +- .../recursive_verifier.test.cpp} | 4 +- .../bb-pil-backend/src/verifier_builder.rs | 28 ++++ bb-pilcom/bb-pil-backend/src/vm_builder.rs | 1 + .../templates/recursive_verifier.cpp.hbs | 158 ++++++++++++++++++ 8 files changed, 194 insertions(+), 6 deletions(-) rename barretenberg/cpp/src/barretenberg/vm/avm/{recursion/avm_recursive_verifier.cpp => generated/recursive_verifier.cpp} (98%) rename barretenberg/cpp/src/barretenberg/vm/avm/recursion/{avm_recursive_flavor.hpp => recursive_flavor.hpp} (100%) rename barretenberg/cpp/src/barretenberg/vm/avm/recursion/{avm_recursive_verifier.hpp => recursive_verifier.hpp} (96%) rename barretenberg/cpp/src/barretenberg/vm/avm/{recursion/avm_recursive_verifier.test.cpp => tests/recursive_verifier.test.cpp} (97%) create mode 100644 bb-pilcom/bb-pil-backend/templates/recursive_verifier.cpp.hbs diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/avm_recursion_constraint.cpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/avm_recursion_constraint.cpp index f963380dd8a..3de39b8d071 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/avm_recursion_constraint.cpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/avm_recursion_constraint.cpp @@ -6,8 +6,8 @@ #include "barretenberg/stdlib/plonk_recursion/aggregation_state/aggregation_state.hpp" #include "barretenberg/stdlib/primitives/curves/bn254.hpp" #include "barretenberg/stdlib_circuit_builders/ultra_flavor.hpp" -#include "barretenberg/vm/avm/recursion/avm_recursive_flavor.hpp" -#include "barretenberg/vm/avm/recursion/avm_recursive_verifier.hpp" +#include "barretenberg/vm/avm/recursion/recursive_flavor.hpp" +#include "barretenberg/vm/avm/recursion/recursive_verifier.hpp" #include "barretenberg/vm/avm/trace/common.hpp" #include "barretenberg/vm/avm/trace/helper.hpp" #include "barretenberg/vm/aztec_constants.hpp" diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/recursion/avm_recursive_verifier.cpp b/barretenberg/cpp/src/barretenberg/vm/avm/generated/recursive_verifier.cpp similarity index 98% rename from barretenberg/cpp/src/barretenberg/vm/avm/recursion/avm_recursive_verifier.cpp rename to barretenberg/cpp/src/barretenberg/vm/avm/generated/recursive_verifier.cpp index 562b630e715..3099fd8c928 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/recursion/avm_recursive_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/generated/recursive_verifier.cpp @@ -1,4 +1,5 @@ -#include "barretenberg/vm/avm/recursion/avm_recursive_verifier.hpp" +// AUTOGENERATED FILE +#include "barretenberg/vm/avm/recursion/recursive_verifier.hpp" #include "barretenberg/commitment_schemes/zeromorph/zeromorph.hpp" #include "barretenberg/plonk_honk_shared/types/aggregation_object_type.hpp" #include "barretenberg/polynomials/polynomial.hpp" diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/recursion/avm_recursive_flavor.hpp b/barretenberg/cpp/src/barretenberg/vm/avm/recursion/recursive_flavor.hpp similarity index 100% rename from barretenberg/cpp/src/barretenberg/vm/avm/recursion/avm_recursive_flavor.hpp rename to barretenberg/cpp/src/barretenberg/vm/avm/recursion/recursive_flavor.hpp diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/recursion/avm_recursive_verifier.hpp b/barretenberg/cpp/src/barretenberg/vm/avm/recursion/recursive_verifier.hpp similarity index 96% rename from barretenberg/cpp/src/barretenberg/vm/avm/recursion/avm_recursive_verifier.hpp rename to barretenberg/cpp/src/barretenberg/vm/avm/recursion/recursive_verifier.hpp index 38584040419..603e117251f 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/recursion/avm_recursive_verifier.hpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/recursion/recursive_verifier.hpp @@ -1,7 +1,7 @@ #pragma once #include "barretenberg/stdlib/plonk_recursion/aggregation_state/aggregation_state.hpp" #include "barretenberg/sumcheck/sumcheck.hpp" -#include "barretenberg/vm/avm/recursion/avm_recursive_flavor.hpp" +#include "barretenberg/vm/avm/recursion/recursive_flavor.hpp" namespace bb { template class AvmRecursiveVerifier_ { diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/recursion/avm_recursive_verifier.test.cpp b/barretenberg/cpp/src/barretenberg/vm/avm/tests/recursive_verifier.test.cpp similarity index 97% rename from barretenberg/cpp/src/barretenberg/vm/avm/recursion/avm_recursive_verifier.test.cpp rename to barretenberg/cpp/src/barretenberg/vm/avm/tests/recursive_verifier.test.cpp index 4211d3aab92..1de397a31f2 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/recursion/avm_recursive_verifier.test.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/tests/recursive_verifier.test.cpp @@ -1,4 +1,4 @@ -#include "barretenberg/vm/avm/recursion/avm_recursive_verifier.hpp" +#include "barretenberg/vm/avm/recursion/recursive_verifier.hpp" #include "barretenberg/circuit_checker/circuit_checker.hpp" #include "barretenberg/numeric/random/engine.hpp" #include "barretenberg/stdlib_circuit_builders/ultra_flavor.hpp" @@ -7,7 +7,7 @@ #include "barretenberg/ultra_honk/ultra_verifier.hpp" #include "barretenberg/vm/avm/generated/circuit_builder.hpp" #include "barretenberg/vm/avm/generated/composer.hpp" -#include "barretenberg/vm/avm/recursion/avm_recursive_flavor.hpp" +#include "barretenberg/vm/avm/recursion/recursive_flavor.hpp" #include "barretenberg/vm/avm/tests/helpers.test.hpp" #include "barretenberg/vm/avm/trace/common.hpp" #include "barretenberg/vm/avm/trace/helper.hpp" diff --git a/bb-pilcom/bb-pil-backend/src/verifier_builder.rs b/bb-pilcom/bb-pil-backend/src/verifier_builder.rs index 9de8b15fad5..5f2d4369d99 100644 --- a/bb-pilcom/bb-pil-backend/src/verifier_builder.rs +++ b/bb-pilcom/bb-pil-backend/src/verifier_builder.rs @@ -6,6 +6,8 @@ pub trait VerifierBuilder { fn create_verifier_cpp(&mut self, name: &str, public_cols: &[(usize, String)]); fn create_verifier_hpp(&mut self, name: &str); + + fn create_recursive_verifier_cpp(&mut self, name: &str, public_cols: &[(usize, String)]); } impl VerifierBuilder for BBFiles { @@ -34,6 +36,32 @@ impl VerifierBuilder for BBFiles { self.write_file(None, "verifier.cpp", &verifier_cpp); } + fn create_recursive_verifier_cpp(&mut self, name: &str, public_cols: &[(usize, String)]) { + let mut handlebars = Handlebars::new(); + + let data = &json!({ + "name": name, + "public_cols": public_cols.iter().map(|(idx, name)| { + json!({ + "col": name, + "idx": idx, + }) + }).collect::>() + }); + + handlebars + .register_template_string( + "recursive_verifier.cpp", + std::str::from_utf8(include_bytes!("../templates/recursive_verifier.cpp.hbs")) + .unwrap(), + ) + .unwrap(); + + let verifier_cpp = handlebars.render("recursive_verifier.cpp", data).unwrap(); + + self.write_file(None, "recursive_verifier.cpp", &verifier_cpp); + } + fn create_verifier_hpp(&mut self, name: &str) { let mut handlebars = Handlebars::new(); diff --git a/bb-pilcom/bb-pil-backend/src/vm_builder.rs b/bb-pilcom/bb-pil-backend/src/vm_builder.rs index 7cc4fd67c78..8ce849595d1 100644 --- a/bb-pilcom/bb-pil-backend/src/vm_builder.rs +++ b/bb-pilcom/bb-pil-backend/src/vm_builder.rs @@ -132,6 +132,7 @@ pub fn analyzed_to_cpp(analyzed: &Analyzed, vm_name: &str, d // ----------------------- Create the Verifier files ----------------------- bb_files.create_verifier_cpp(vm_name, &public_inputs); bb_files.create_verifier_hpp(vm_name); + bb_files.create_recursive_verifier_cpp(vm_name, &public_inputs); // ----------------------- Create the Prover files ----------------------- bb_files.create_prover_cpp(vm_name); diff --git a/bb-pilcom/bb-pil-backend/templates/recursive_verifier.cpp.hbs b/bb-pilcom/bb-pil-backend/templates/recursive_verifier.cpp.hbs new file mode 100644 index 00000000000..f84addd3d84 --- /dev/null +++ b/bb-pilcom/bb-pil-backend/templates/recursive_verifier.cpp.hbs @@ -0,0 +1,158 @@ +// AUTOGENERATED FILE +#include "barretenberg/vm/{{snakeCase name}}/recursion/recursive_verifier.hpp" +#include "barretenberg/commitment_schemes/zeromorph/zeromorph.hpp" +#include "barretenberg/plonk_honk_shared/types/aggregation_object_type.hpp" +#include "barretenberg/polynomials/polynomial.hpp" +#include "barretenberg/polynomials/shared_shifted_virtual_zeroes_array.hpp" +#include "barretenberg/stdlib/primitives/field/field.hpp" +#include "barretenberg/transcript/transcript.hpp" +#include "barretenberg/vm/aztec_constants.hpp" +#include +#include +#include + +namespace bb { + +template +{{name}}RecursiveVerifier_::{{name}}RecursiveVerifier_( + Builder* builder, const std::shared_ptr& native_verification_key) + : key(std::make_shared(builder, native_verification_key)) + , builder(builder) +{} + +template +{{name}}RecursiveVerifier_::{{name}}RecursiveVerifier_(Builder* builder, const std::shared_ptr& vkey) + : key(vkey) + , builder(builder) +{} + +// Evaluate the given public input column over the multivariate challenge points +template +Flavor::FF {{name}}RecursiveVerifier_::evaluate_public_input_column(const std::vector& points, + const std::vector& challenges) +{ + auto coefficients = SharedShiftedVirtualZeroesArray{ + .start_ = 0, + .end_ = points.size(), + .virtual_size_ = key->circuit_size, // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays) + .backing_memory_ = std::static_pointer_cast(get_mem_slab(sizeof(FF) * points.size())), + }; + + memcpy( + static_cast(coefficients.data()), static_cast(points.data()), sizeof(FF) * points.size()); + + return generic_evaluate_mle(challenges, coefficients); +} + +template +{{name}}RecursiveVerifier_::AggregationObject {{name}}RecursiveVerifier_::verify_proof( + const HonkProof& proof, const std::vector>& public_inputs_vec_nt, AggregationObject agg_obj) +{ + StdlibProof stdlib_proof = bb::convert_proof_to_witness(builder, proof); + + std::vector> public_inputs_ct; + public_inputs_ct.reserve(public_inputs_vec_nt.size()); + + for (const auto& vec : public_inputs_vec_nt) { + std::vector vec_ct; + vec_ct.reserve(vec.size()); + for (const auto& el : vec) { + vec_ct.push_back(bb::stdlib::witness_t(builder, el)); + } + public_inputs_ct.push_back(vec_ct); + } + + return verify_proof(stdlib_proof, public_inputs_ct, agg_obj); +} + +// TODO(#991): (see https://github.com/AztecProtocol/barretenberg/issues/991) +template +{{name}}RecursiveVerifier_::AggregationObject {{name}}RecursiveVerifier_::verify_proof( + const StdlibProof& stdlib_proof, + const std::vector>& public_inputs, + AggregationObject agg_obj) +{ + using Curve = typename Flavor::Curve; + using Zeromorph = ZeroMorphVerifier_; + using PCS = typename Flavor::PCS; + using VerifierCommitments = typename Flavor::VerifierCommitments; + using CommitmentLabels = typename Flavor::CommitmentLabels; + using RelationParams = ::bb::RelationParameters; + using Transcript = typename Flavor::Transcript; + + transcript = std::make_shared(stdlib_proof); + + RelationParams relation_parameters; + VerifierCommitments commitments{ key }; + CommitmentLabels commitment_labels; + + const auto circuit_size = transcript->template receive_from_prover("circuit_size"); + if (static_cast(circuit_size.get_value()) != key->circuit_size) { + throw_or_abort("{{name}}RecursiveVerifier::verify_proof: proof circuit size does not match verification key!"); + } + + // Get commitments to VM wires + for (auto [comm, label] : zip_view(commitments.get_wires(), commitment_labels.get_wires())) { + comm = transcript->template receive_from_prover(label); + } + + auto [beta, gamma] = transcript->template get_challenges("beta", "gamma"); + relation_parameters.beta = beta; + relation_parameters.gamma = gamma; + + // Get commitments to inverses + for (auto [label, commitment] : zip_view(commitment_labels.get_derived(), commitments.get_derived())) { + commitment = transcript->template receive_from_prover(label); + } + + // unconstrained + const size_t log_circuit_size = numeric::get_msb(static_cast(circuit_size.get_value())); + auto sumcheck = SumcheckVerifier(log_circuit_size, transcript); + + FF alpha = transcript->template get_challenge("Sumcheck:alpha"); + + auto gate_challenges = std::vector(log_circuit_size); + for (size_t idx = 0; idx < log_circuit_size; idx++) { + gate_challenges[idx] = transcript->template get_challenge("Sumcheck:gate_challenge_" + std::to_string(idx)); + } + + // No need to constrain that sumcheck_verified is true as this is guaranteed by the implementation of + // when called over a "circuit field" types. + auto [multivariate_challenge, claimed_evaluations, sumcheck_verified] = + sumcheck.verify(relation_parameters, alpha, gate_challenges); + + vinfo("verified sumcheck: ", (sumcheck_verified.has_value() && sumcheck_verified.value())); + + // Public columns evaluation checks + std::vector mle_challenge(multivariate_challenge.begin(), + multivariate_challenge.begin() + static_cast(log_circuit_size)); + + {{#each public_cols}} + FF {{col}}_evaluation = evaluate_public_input_column(public_inputs[{{idx}}], mle_challenge); + {{col}}_evaluation.assert_equal(claimed_evaluations.{{col}}, + "{{col}}_evaluation failed"); + + {{/each}} + + auto opening_claim = Zeromorph::verify(circuit_size, + commitments.get_unshifted(), + commitments.get_to_be_shifted(), + claimed_evaluations.get_unshifted(), + claimed_evaluations.get_shifted(), + multivariate_challenge, + Commitment::one(builder), + transcript); + + auto pairing_points = PCS::reduce_verify(opening_claim, transcript); + + pairing_points[0] = pairing_points[0].normalize(); + pairing_points[1] = pairing_points[1].normalize(); + // TODO(https://github.com/AztecProtocol/barretenberg/issues/995): generate this challenge properly. + typename Curve::ScalarField recursion_separator = + Curve::ScalarField::from_witness_index(builder, builder->add_variable(42)); + agg_obj.aggregate(pairing_points, recursion_separator); + return agg_obj; +} + +template class {{name}}RecursiveVerifier_<{{name}}RecursiveFlavor_>; +} // namespace bb \ No newline at end of file