Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(avm): DSL integration of AVM recursive verifier #8405

Merged
merged 7 commits into from
Sep 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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();
lucasxia01 marked this conversation as resolved.
Show resolved Hide resolved

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()) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if we ever try to create a circuit with both honk and avm recursion constraints, this will throw an error, but I think we can resolves this later.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

error comes from calling set_recursive_proof multiple times.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suggest that I add a comment and a reference to the issue 1095 to solve this. @lucasxia01 Ok?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sounds fine


// 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
Loading