Skip to content

Commit

Permalink
8285: unit test for dsl avm recursive verifier
Browse files Browse the repository at this point in the history
  • Loading branch information
jeanmon committed Sep 9, 2024
1 parent 5fb3335 commit db13979
Show file tree
Hide file tree
Showing 3 changed files with 147 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -94,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
@@ -0,0 +1,140 @@
#ifndef DISABLE_AZTEC_VM

#include "avm_recursion_constraint.hpp"
#include "acir_format.hpp"
#include "acir_format_mocks.hpp"
#include "barretenberg/stdlib/primitives/circuit_builders/circuit_builders_fwd.hpp"
#include "barretenberg/sumcheck/instance/prover_instance.hpp"
#include "barretenberg/ultra_honk/ultra_prover.hpp"
#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/generated/flavor.hpp"
#include "barretenberg/vm/avm/generated/prover.hpp"
#include "barretenberg/vm/avm/generated/verifier.hpp"
#include "barretenberg/vm/avm/tests/helpers.test.hpp"
#include "barretenberg/vm/avm/trace/trace.hpp"
#include "proof_surgeon.hpp"
#include <gtest/gtest.h>
#include <memory>
#include <vector>

using namespace acir_format;
using namespace bb;
using namespace bb::avm_trace;

class AcirAvmRecursionConstraint : public ::testing::Test {
public:
using InnerBuilder = AvmCircuitBuilder;
using InnerProver = AvmProver;
using InnerVerifier = AvmVerifier;

using OuterProver = UltraProver;
using OuterVerifier = UltraVerifier;
using OuterDeciderProvingKey = DeciderProvingKey_<UltraFlavor>;

using DeciderProvingKey = DeciderProvingKey_<UltraFlavor>;
using OuterVerificationKey = UltraFlavor::VerificationKey;
using OuterBuilder = UltraCircuitBuilder;

static void SetUpTestSuite() { bb::srs::init_crs_factory("../srs_db/ignition"); }

static InnerBuilder create_inner_circuit()
{
VmPublicInputs public_inputs;
std::array<FF, KERNEL_INPUTS_LENGTH> kernel_inputs{};
kernel_inputs.at(DA_GAS_LEFT_CONTEXT_INPUTS_OFFSET) = 1000000;
kernel_inputs.at(L2_GAS_LEFT_CONTEXT_INPUTS_OFFSET) = 1000000;
std::get<0>(public_inputs) = kernel_inputs;

AvmTraceBuilder trace_builder(public_inputs);
InnerBuilder builder;

trace_builder.op_set(0, 15, 1, AvmMemoryTag::U8);
trace_builder.op_set(0, 12, 2, AvmMemoryTag::U8);
trace_builder.op_add(0, 1, 2, 3, AvmMemoryTag::U8);
trace_builder.op_sub(0, 3, 2, 3, AvmMemoryTag::U8);
trace_builder.op_mul(0, 1, 1, 3, AvmMemoryTag::U8);
trace_builder.op_return(0, 0, 0);
auto trace = trace_builder.finalize(); // Passing true enables a longer trace with lookups

builder.set_trace(std::move(trace));
builder.check_circuit();
return builder;
}

/**
* @brief Create a circuit that recursively verifies one or more inner avm circuits
*/
static OuterBuilder create_outer_circuit(std::vector<InnerBuilder>& inner_avm_circuits)
{
std::vector<RecursionConstraint> avm_recursion_constraints;

SlabVector<fr> witness;

for (auto& avm_circuit : inner_avm_circuits) {
AvmComposer composer = AvmComposer();
InnerProver prover = composer.create_prover(avm_circuit);
InnerVerifier verifier = composer.create_verifier(avm_circuit);

std::vector<fr> key_witnesses = verifier.key->to_field_elements();
std::vector<fr> proof_witnesses = prover.construct_proof();
// const size_t num_public_inputs = verifier.key->num_public_inputs;

// Helper to append some values to the witness vector and return their corresponding indices
auto add_to_witness_and_track_indices =
[&witness](const std::vector<bb::fr>& input) -> std::vector<uint32_t> {
std::vector<uint32_t> indices;
indices.reserve(input.size());
auto witness_idx = static_cast<uint32_t>(witness.size());
for (const auto& value : input) {
witness.push_back(value);
indices.push_back(witness_idx++);
}
return indices;
};

RecursionConstraint avm_recursion_constraint{
.key = add_to_witness_and_track_indices(key_witnesses),
.proof = add_to_witness_and_track_indices(proof_witnesses),
.public_inputs = {},
.key_hash = 0, // not used
.proof_type = AVM,
};
avm_recursion_constraints.push_back(avm_recursion_constraint);
}

std::vector<size_t> avm_recursion_opcode_indices(avm_recursion_constraints.size());
std::iota(avm_recursion_opcode_indices.begin(), avm_recursion_opcode_indices.end(), 0);

AcirFormat constraint_system;
constraint_system.varnum = static_cast<uint32_t>(witness.size());
constraint_system.recursive = false;
constraint_system.num_acir_opcodes = static_cast<uint32_t>(avm_recursion_constraints.size());
constraint_system.avm_recursion_constraints = avm_recursion_constraints;
constraint_system.original_opcode_indices = create_empty_original_opcode_indices();

mock_opcode_indices(constraint_system);
auto outer_circuit = create_circuit(constraint_system, /*size_hint*/ 0, witness);
return outer_circuit;
}
};

TEST_F(AcirAvmRecursionConstraint, TestBasicSingleAvmRecursionConstraint)
{
std::vector<InnerBuilder> layer_1_circuits;
layer_1_circuits.push_back(create_inner_circuit());
auto layer_2_circuit = create_outer_circuit(layer_1_circuits);

info("circuit gates = ", layer_2_circuit.get_num_gates());

auto proving_key = std::make_shared<DeciderProvingKey>(layer_2_circuit);
OuterProver prover(proving_key);
info("prover gates = ", proving_key->proving_key.circuit_size);
auto proof = prover.construct_proof();
auto verification_key = std::make_shared<OuterVerificationKey>(proving_key->proving_key);
OuterVerifier verifier(verification_key);
EXPECT_EQ(verifier.verify_proof(proof), true);
}

#endif // DISABLE_AZTEC_VM
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ class AvmRecursiveTests : public ::testing::Test {
using RecursiveVerifier = AvmRecursiveVerifier_<RecursiveFlavor>;

using OuterBuilder = typename RecursiveFlavor::CircuitBuilder;
using OuterProver = UltraProver_<UltraFlavor>;
using OuterVerifier = UltraVerifier_<UltraFlavor>;
using OuterProver = UltraProver;
using OuterVerifier = UltraVerifier;
using OuterDeciderProvingKey = DeciderProvingKey_<UltraFlavor>;

static void SetUpTestSuite() { bb::srs::init_crs_factory("../srs_db/ignition"); }
Expand Down Expand Up @@ -65,8 +65,8 @@ TEST_F(AvmRecursiveTests, recursion)
{
AvmCircuitBuilder circuit_builder = generate_avm_circuit();
AvmComposer composer = AvmComposer();
AvmProver prover = composer.create_prover(circuit_builder);
AvmVerifier verifier = composer.create_verifier(circuit_builder);
InnerProver prover = composer.create_prover(circuit_builder);
InnerVerifier verifier = composer.create_verifier(circuit_builder);

HonkProof proof = prover.construct_proof();

Expand Down

0 comments on commit db13979

Please sign in to comment.