diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/avm_recursion_constraint.test.cpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/avm_recursion_constraint.test.cpp new file mode 100644 index 00000000000..4a022c61083 --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/avm_recursion_constraint.test.cpp @@ -0,0 +1,116 @@ +#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/flavor.hpp" +#include "barretenberg/vm/avm/generated/prover.hpp" +#include "barretenberg/vm/avm/generated/verifier.hpp" +#include "proof_surgeon.hpp" +#include +#include +#include + +using namespace acir_format; +using namespace bb; + +class AcirAvmRecursionConstraint : public ::testing::Test { + + public: + using DeciderProvingKey = DeciderProvingKey_; + using Prover = bb::UltraProver; + using VerificationKey = UltraFlavor::VerificationKey; + using Verifier = bb::UltraVerifier; + + using InnerBuilder = AvmCircuitBuilder; + using OuterBuilder = UltraCircuitBuilder; + + InnerBuilder create_inner_circuit() { return InnerBuilder{}; } + + /** + * @brief Create a circuit that recursively verifies one or more inner avm circuits + * + * @param inner_avm_circuits + * @return Composer + */ + OuterBuilder create_outer_circuit(std::vector& inner_avm_circuits) + { + std::vector avm_recursion_constraints; + + SlabVector witness; + + for (auto& avm_circuit : inner_avm_circuits) { + + auto proving_key = std::make_shared( + avm_circuit.get_circuit_subgroup_size(), 4); // Arbitrary constant 4 just to make it compile + AvmProver prover(proving_key, std::make_shared(1 << 21)); + auto verification_key = std::make_shared(proving_key); + AvmVerifier verifier(verification_key); + auto inner_proof = prover.construct_proof(); + + std::vector key_witnesses = verification_key->to_field_elements(); + std::vector proof_witnesses = inner_proof; + const size_t num_public_inputs = verification_key->num_public_inputs; + + auto [key_indices, proof_indices, inner_public_inputs] = ProofSurgeon::populate_recursion_witness_data( + witness, proof_witnesses, key_witnesses, num_public_inputs); + + RecursionConstraint avm_recursion_constraint{ + .key = key_indices, + .proof = proof_indices, + .public_inputs = inner_public_inputs, + .key_hash = 0, // not used + .proof_type = AVM, + }; + avm_recursion_constraints.push_back(avm_recursion_constraint); + } + + std::vector avm_recursion_opcode_indices(avm_recursion_constraints.size()); + std::iota(avm_recursion_opcode_indices.begin(), avm_recursion_opcode_indices.end(), 0); + + AcirFormat constraint_system{ + .varnum = static_cast(witness.size()), + .recursive = false, + .num_acir_opcodes = static_cast(avm_recursion_constraints.size()), + .public_inputs = {}, + .logic_constraints = {}, + .range_constraints = {}, + .aes128_constraints = {}, + .sha256_constraints = {}, + .sha256_compression = {}, + .schnorr_constraints = {}, + .ecdsa_k1_constraints = {}, + .ecdsa_r1_constraints = {}, + .blake2s_constraints = {}, + .blake3_constraints = {}, + .keccak_constraints = {}, + .keccak_permutations = {}, + .pedersen_constraints = {}, + .pedersen_hash_constraints = {}, + .poseidon2_constraints = {}, + .multi_scalar_mul_constraints = {}, + .ec_add_constraints = {}, + .recursion_constraints = {}, + .honk_recursion_constraints = {}, + .avm_recursion_constraints = avm_recursion_constraints, + .bigint_from_le_bytes_constraints = {}, + .bigint_to_le_bytes_constraints = {}, + .bigint_operations = {}, + .assert_equalities = {}, + .poly_triple_constraints = {}, + .quad_constraints = {}, + .block_constraints = {}, + .original_opcode_indices = create_empty_original_opcode_indices(), + }; + mock_opcode_indices(constraint_system); + auto outer_circuit = create_circuit(constraint_system, /*size_hint*/ 0, witness, /*honk recursion*/ true); + + return outer_circuit; + } + + protected: + static void SetUpTestSuite() { bb::srs::init_crs_factory("../srs_db/ignition"); } +}; \ No newline at end of file