Skip to content

Commit

Permalink
feat(avm): DSL integration of AVM recursive verifier (#8405)
Browse files Browse the repository at this point in the history
Resolves #8285
  • Loading branch information
jeanmon authored Sep 9, 2024
1 parent a934e85 commit 467120e
Show file tree
Hide file tree
Showing 40 changed files with 1,379 additions and 856 deletions.
7 changes: 1 addition & 6 deletions barretenberg/cpp/src/barretenberg/bb/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -951,12 +951,7 @@ void avm_prove(const std::filesystem::path& bytecode_path,
auto const [verification_key, proof] =
AVM_TRACK_TIME_V("prove/all", avm_trace::Execution::prove(bytecode, calldata, public_inputs_vec, avm_hints));

std::vector<fr> vk_as_fields = { fr(verification_key.circuit_size), fr(verification_key.num_public_inputs) };

for (auto const& comm : verification_key.get_all()) {
std::vector<fr> comm_as_fields = field_conversion::convert_to_bn254_frs(comm);
vk_as_fields.insert(vk_as_fields.end(), comm_as_fields.begin(), comm_as_fields.end());
}
std::vector<fr> vk_as_fields = verification_key.to_field_elements();

vinfo("vk fields size: ", vk_as_fields.size());
vinfo("circuit size: ", vk_as_fields[0]);
Expand Down
4 changes: 2 additions & 2 deletions barretenberg/cpp/src/barretenberg/dsl/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@ set(DSL_DEPENDENCIES
stdlib_honk_verifier)

if (NOT WASM)
list(APPEND DSL_DEPENDENCIES libdeflate::libdeflate_static)
list(APPEND DSL_DEPENDENCIES libdeflate::libdeflate_static vm)
endif()

barretenberg_module(
dsl
${DSL_DEPENDENCIES}
)
)
2 changes: 1 addition & 1 deletion barretenberg/cpp/src/barretenberg/dsl/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ This package adds support to use [ACIR](https://github.com/noir-lang/noir/tree/m

## Serialization Changes

There are two types of breaking serialization changes. One that alters that alters the internal ACIR structure passed to barretenberg, and one that changes how we serialize the buffer passed to barretenberg.
There are two types of breaking serialization changes. One that alters the internal ACIR structure passed to barretenberg, and one that changes how we serialize the buffer passed to barretenberg.

1. Internal Structure Change

Expand Down
53 changes: 51 additions & 2 deletions barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_format.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -231,10 +231,17 @@ void build_constraints(Builder& builder,
if (!constraint_system.honk_recursion_constraints.empty()) {
info("WARNING: this circuit contains unhandled honk_recursion_constraints!");
}
if (!constraint_system.avm_recursion_constraints.empty()) {
info("WARNING: this circuit contains unhandled avm_recursion_constraints!");
}
} else {
process_plonk_recursion_constraints(builder, constraint_system, has_valid_witness_assignments, gate_counter);
process_honk_recursion_constraints(builder, constraint_system, has_valid_witness_assignments, gate_counter);

#ifndef DISABLE_AZTEC_VM
process_avm_recursion_constraints(builder, constraint_system, has_valid_witness_assignments, gate_counter);
#endif

// If the circuit does not itself contain honk recursion constraints but is going to be
// proven with honk then recursively verified, add a default aggregation object
if (constraint_system.honk_recursion_constraints.empty() && honk_recursion &&
Expand Down Expand Up @@ -335,7 +342,7 @@ void process_plonk_recursion_constraints(Builder& builder,
// final recursion output.
builder.set_recursive_proof(current_output_aggregation_object);
}
};
}

void process_honk_recursion_constraints(Builder& builder,
AcirFormat& constraint_system,
Expand Down Expand Up @@ -370,7 +377,49 @@ void process_honk_recursion_constraints(Builder& builder,
// final recursion output.
builder.set_recursive_proof(current_aggregation_object);
}
};
}

// TODO(https://github.com/AztecProtocol/barretenberg/issues/1095): Probably makes sense to aggregate Honk and AVM
// proofs together.
#ifndef DISABLE_AZTEC_VM
void process_avm_recursion_constraints(Builder& builder,
AcirFormat& constraint_system,
bool has_valid_witness_assignments,
GateCounter<Builder>& gate_counter)
{
AggregationObjectIndices current_aggregation_object =
stdlib::recursion::init_default_agg_obj_indices<Builder>(builder);

// Add recursion constraints
size_t idx = 0;
for (auto& constraint : constraint_system.avm_recursion_constraints) {
current_aggregation_object = create_avm_recursion_constraints(
builder, constraint, current_aggregation_object, has_valid_witness_assignments);

gate_counter.track_diff(constraint_system.gates_per_opcode,
constraint_system.original_opcode_indices.avm_recursion_constraints.at(idx++));
}

// TODO(https://github.com/AztecProtocol/barretenberg/issues/1095): The following code will have to be adapted to
// support a circuit with both honk and avm recursion constraints.

// Now that the circuit has been completely built, we add
// the output aggregation as public inputs.
if (!constraint_system.avm_recursion_constraints.empty()) {

// First add the output aggregation object as public inputs
// Set the indices as public inputs because they are no longer being
// created in ACIR
for (const auto& idx : current_aggregation_object) {
builder.set_public_input(idx);
}

// Make sure the verification key records the public input indices of the
// final recursion output.
builder.set_recursive_proof(current_aggregation_object);
}
}
#endif // DISABLE_AZTEC_VM

/**
* @brief Specialization for creating Ultra circuit from acir constraints and optionally a witness
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
#pragma once
#include "aes128_constraint.hpp"

#ifndef DISABLE_AZTEC_VM
#include "avm_recursion_constraint.hpp"
#endif

#include "barretenberg/aztec_ivc/aztec_ivc.hpp"
#include "barretenberg/common/slab_allocator.hpp"
#include "barretenberg/serialize/msgpack.hpp"
Expand Down Expand Up @@ -51,6 +56,7 @@ struct AcirFormatOriginalOpcodeIndices {
std::vector<size_t> ec_add_constraints;
std::vector<size_t> recursion_constraints;
std::vector<size_t> honk_recursion_constraints;
std::vector<size_t> avm_recursion_constraints;
std::vector<size_t> ivc_recursion_constraints;
std::vector<size_t> bigint_from_le_bytes_constraints;
std::vector<size_t> bigint_to_le_bytes_constraints;
Expand Down Expand Up @@ -99,6 +105,7 @@ struct AcirFormat {
std::vector<EcAdd> ec_add_constraints;
std::vector<RecursionConstraint> recursion_constraints;
std::vector<RecursionConstraint> honk_recursion_constraints;
std::vector<RecursionConstraint> avm_recursion_constraints;
std::vector<RecursionConstraint> ivc_recursion_constraints;
std::vector<BigIntFromLeBytes> bigint_from_le_bytes_constraints;
std::vector<BigIntToLeBytes> bigint_to_le_bytes_constraints;
Expand Down Expand Up @@ -144,6 +151,7 @@ struct AcirFormat {
ec_add_constraints,
recursion_constraints,
honk_recursion_constraints,
avm_recursion_constraints,
ivc_recursion_constraints,
poly_triple_constraints,
block_constraints,
Expand Down Expand Up @@ -258,7 +266,12 @@ void process_plonk_recursion_constraints(Builder& builder,
void process_honk_recursion_constraints(Builder& builder,
AcirFormat& constraint_system,
bool has_valid_witness_assignments,
bool honk_recursion,
GateCounter<Builder>& gate_counter);

#ifndef DISABLE_AZTEC_VM
void process_avm_recursion_constraints(Builder& builder,
AcirFormat& constraint_system,
GateCounter<Builder>& gate_counter);
#endif

} // namespace acir_format
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ TEST_F(AcirFormatTests, TestASingleConstraintNoPubInputs)
.ec_add_constraints = {},
.recursion_constraints = {},
.honk_recursion_constraints = {},
.avm_recursion_constraints = {},
.ivc_recursion_constraints = {},
.bigint_from_le_bytes_constraints = {},
.bigint_to_le_bytes_constraints = {},
Expand Down Expand Up @@ -184,6 +185,7 @@ TEST_F(AcirFormatTests, TestLogicGateFromNoirCircuit)
.ec_add_constraints = {},
.recursion_constraints = {},
.honk_recursion_constraints = {},
.avm_recursion_constraints = {},
.ivc_recursion_constraints = {},
.bigint_from_le_bytes_constraints = {},
.bigint_to_le_bytes_constraints = {},
Expand Down Expand Up @@ -265,6 +267,7 @@ TEST_F(AcirFormatTests, TestSchnorrVerifyPass)
.ec_add_constraints = {},
.recursion_constraints = {},
.honk_recursion_constraints = {},
.avm_recursion_constraints = {},
.ivc_recursion_constraints = {},
.bigint_from_le_bytes_constraints = {},
.bigint_to_le_bytes_constraints = {},
Expand Down Expand Up @@ -373,6 +376,7 @@ TEST_F(AcirFormatTests, TestSchnorrVerifySmallRange)
.ec_add_constraints = {},
.recursion_constraints = {},
.honk_recursion_constraints = {},
.avm_recursion_constraints = {},
.ivc_recursion_constraints = {},
.bigint_from_le_bytes_constraints = {},
.bigint_to_le_bytes_constraints = {},
Expand Down Expand Up @@ -494,6 +498,7 @@ TEST_F(AcirFormatTests, TestVarKeccak)
.ec_add_constraints = {},
.recursion_constraints = {},
.honk_recursion_constraints = {},
.avm_recursion_constraints = {},
.ivc_recursion_constraints = {},
.bigint_from_le_bytes_constraints = {},
.bigint_to_le_bytes_constraints = {},
Expand Down Expand Up @@ -575,6 +580,7 @@ TEST_F(AcirFormatTests, TestKeccakPermutation)
.ec_add_constraints = {},
.recursion_constraints = {},
.honk_recursion_constraints = {},
.avm_recursion_constraints = {},
.ivc_recursion_constraints = {},
.bigint_from_le_bytes_constraints = {},
.bigint_to_le_bytes_constraints = {},
Expand Down Expand Up @@ -653,6 +659,7 @@ TEST_F(AcirFormatTests, TestCollectsGateCounts)
.ec_add_constraints = {},
.recursion_constraints = {},
.honk_recursion_constraints = {},
.avm_recursion_constraints = {},
.ivc_recursion_constraints = {},
.bigint_from_le_bytes_constraints = {},
.bigint_to_le_bytes_constraints = {},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ acir_format::AcirFormatOriginalOpcodeIndices create_empty_original_opcode_indice
.ec_add_constraints = {},
.recursion_constraints = {},
.honk_recursion_constraints = {},
.avm_recursion_constraints = {},
.ivc_recursion_constraints = {},
.bigint_from_le_bytes_constraints = {},
.bigint_to_le_bytes_constraints = {},
Expand Down Expand Up @@ -93,6 +94,9 @@ void mock_opcode_indices(acir_format::AcirFormat& constraint_system)
for (size_t i = 0; i < constraint_system.honk_recursion_constraints.size(); i++) {
constraint_system.original_opcode_indices.honk_recursion_constraints.push_back(current_opcode++);
}
for (size_t i = 0; i < constraint_system.avm_recursion_constraints.size(); i++) {
constraint_system.original_opcode_indices.avm_recursion_constraints.push_back(current_opcode++);
}
for (size_t i = 0; i < constraint_system.ivc_recursion_constraints.size(); i++) {
constraint_system.original_opcode_indices.ivc_recursion_constraints.push_back(current_opcode++);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "acir_to_constraint_buf.hpp"
#include "barretenberg/common/container.hpp"
#include "barretenberg/dsl/acir_format/recursion_constraint.hpp"
#include "barretenberg/numeric/uint256/uint256.hpp"
#include "barretenberg/plonk_honk_shared/arithmetization/gate_data.hpp"
#include <cstddef>
Expand Down Expand Up @@ -466,7 +467,7 @@ void handle_blackbox_func_call(Program::Opcode::BlackBoxFuncCall const& arg,
// TODO(https://github.com/AztecProtocol/barretenberg/issues/1074): Eventually arg.proof_type will be
// the only means for setting the proof type. use of honk_recursion flag in this context can go away
// once all noir programs (e.g. protocol circuits) are updated to use the new pattern.
if (honk_recursion && proof_type_in != HONK) {
if (honk_recursion && proof_type_in != HONK && proof_type_in != AVM) {
proof_type_in = HONK;
}

Expand All @@ -477,14 +478,22 @@ void handle_blackbox_func_call(Program::Opcode::BlackBoxFuncCall const& arg,
.key_hash = input_key,
.proof_type = proof_type_in,
};

// Add the recursion constraint to the appropriate container based on proof type
if (c.proof_type == PLONK) {
switch (c.proof_type) {
case PLONK:
af.recursion_constraints.push_back(c);
af.original_opcode_indices.recursion_constraints.push_back(opcode_index);
} else if (c.proof_type == HONK) {
break;
case HONK:
af.honk_recursion_constraints.push_back(c);
af.original_opcode_indices.honk_recursion_constraints.push_back(opcode_index);
} else {
break;
case AVM:
af.avm_recursion_constraints.push_back(c);
af.original_opcode_indices.avm_recursion_constraints.push_back(opcode_index);
break;
default:
info("Invalid PROOF_TYPE in RecursionConstraint!");
ASSERT(false);
}
Expand Down
Loading

0 comments on commit 467120e

Please sign in to comment.