Skip to content

Commit

Permalink
8849: codegen recursive_verifier.cpp
Browse files Browse the repository at this point in the history
  • Loading branch information
jeanmon committed Oct 11, 2024
1 parent d8131bc commit 65fcfc4
Show file tree
Hide file tree
Showing 8 changed files with 194 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
Original file line number Diff line number Diff line change
@@ -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"
Expand Down
Original file line number Diff line number Diff line change
@@ -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 <typename Flavor> class AvmRecursiveVerifier_ {
Expand Down
Original file line number Diff line number Diff line change
@@ -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"
Expand All @@ -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"
Expand Down
28 changes: 28 additions & 0 deletions bb-pilcom/bb-pil-backend/src/verifier_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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::<Vec<_>>()
});

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();

Expand Down
1 change: 1 addition & 0 deletions bb-pilcom/bb-pil-backend/src/vm_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ pub fn analyzed_to_cpp<F: FieldElement>(analyzed: &Analyzed<F>, 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);
Expand Down
158 changes: 158 additions & 0 deletions bb-pilcom/bb-pil-backend/templates/recursive_verifier.cpp.hbs
Original file line number Diff line number Diff line change
@@ -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 <algorithm>
#include <cstddef>
#include <memory>

namespace bb {

template <typename Flavor>
{{name}}RecursiveVerifier_<Flavor>::{{name}}RecursiveVerifier_(
Builder* builder, const std::shared_ptr<NativeVerificationKey>& native_verification_key)
: key(std::make_shared<VerificationKey>(builder, native_verification_key))
, builder(builder)
{}

template <typename Flavor>
{{name}}RecursiveVerifier_<Flavor>::{{name}}RecursiveVerifier_(Builder* builder, const std::shared_ptr<VerificationKey>& vkey)
: key(vkey)
, builder(builder)
{}

// Evaluate the given public input column over the multivariate challenge points
template <typename Flavor>
Flavor::FF {{name}}RecursiveVerifier_<Flavor>::evaluate_public_input_column(const std::vector<FF>& points,
const std::vector<FF>& challenges)
{
auto coefficients = SharedShiftedVirtualZeroesArray<FF>{
.start_ = 0,
.end_ = points.size(),
.virtual_size_ = key->circuit_size, // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays)
.backing_memory_ = std::static_pointer_cast<FF[]>(get_mem_slab(sizeof(FF) * points.size())),
};

memcpy(
static_cast<void*>(coefficients.data()), static_cast<const void*>(points.data()), sizeof(FF) * points.size());

return generic_evaluate_mle<FF>(challenges, coefficients);
}

template <typename Flavor>
{{name}}RecursiveVerifier_<Flavor>::AggregationObject {{name}}RecursiveVerifier_<Flavor>::verify_proof(
const HonkProof& proof, const std::vector<std::vector<bb::fr>>& public_inputs_vec_nt, AggregationObject agg_obj)
{
StdlibProof<Builder> stdlib_proof = bb::convert_proof_to_witness(builder, proof);

std::vector<std::vector<FF>> public_inputs_ct;
public_inputs_ct.reserve(public_inputs_vec_nt.size());

for (const auto& vec : public_inputs_vec_nt) {
std::vector<FF> vec_ct;
vec_ct.reserve(vec.size());
for (const auto& el : vec) {
vec_ct.push_back(bb::stdlib::witness_t<Builder>(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 <typename Flavor>
{{name}}RecursiveVerifier_<Flavor>::AggregationObject {{name}}RecursiveVerifier_<Flavor>::verify_proof(
const StdlibProof<Builder>& stdlib_proof,
const std::vector<std::vector<FF>>& public_inputs,
AggregationObject agg_obj)
{
using Curve = typename Flavor::Curve;
using Zeromorph = ZeroMorphVerifier_<Curve>;
using PCS = typename Flavor::PCS;
using VerifierCommitments = typename Flavor::VerifierCommitments;
using CommitmentLabels = typename Flavor::CommitmentLabels;
using RelationParams = ::bb::RelationParameters<typename Flavor::FF>;
using Transcript = typename Flavor::Transcript;

transcript = std::make_shared<Transcript>(stdlib_proof);

RelationParams relation_parameters;
VerifierCommitments commitments{ key };
CommitmentLabels commitment_labels;

const auto circuit_size = transcript->template receive_from_prover<FF>("circuit_size");
if (static_cast<uint32_t>(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<Commitment>(label);
}

auto [beta, gamma] = transcript->template get_challenges<FF>("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<Commitment>(label);
}

// unconstrained
const size_t log_circuit_size = numeric::get_msb(static_cast<uint32_t>(circuit_size.get_value()));
auto sumcheck = SumcheckVerifier<Flavor>(log_circuit_size, transcript);

FF alpha = transcript->template get_challenge<FF>("Sumcheck:alpha");

auto gate_challenges = std::vector<FF>(log_circuit_size);
for (size_t idx = 0; idx < log_circuit_size; idx++) {
gate_challenges[idx] = transcript->template get_challenge<FF>("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<FF> mle_challenge(multivariate_challenge.begin(),
multivariate_challenge.begin() + static_cast<int>(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_<UltraCircuitBuilder>>;
} // namespace bb

0 comments on commit 65fcfc4

Please sign in to comment.