-
Notifications
You must be signed in to change notification settings - Fork 234
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
8285: unit test for dsl avm recursive verifier
- Loading branch information
Showing
3 changed files
with
147 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
140 changes: 140 additions & 0 deletions
140
barretenberg/cpp/src/barretenberg/dsl/acir_format/avm_recursion_constraint.test.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters