Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
avm2_recursion_constraint.test.cpp
Go to the documentation of this file.
17
18#include <gtest/gtest.h>
19#include <memory>
20#include <vector>
21
22using namespace acir_format;
23using namespace bb;
24using namespace bb::avm2;
25
28 std::shared_ptr<AvmFlavor::VerificationKey> verification_key;
29 std::vector<FF> public_inputs_flat;
30};
31
32class AcirAvm2RecursionConstraint : public ::testing::Test {
33 public:
36
41
44
46
48 {
49 auto [trace, public_inputs] = avm2::testing::get_minimal_trace_with_pi();
50
51 InnerProver prover;
52 auto [proof, vk_data] = prover.prove(std::move(trace));
53 const auto verification_key = InnerProver::create_verification_key(vk_data);
54
55 const bool verified = prover.verify(proof, public_inputs, vk_data);
56 EXPECT_TRUE(verified) << "native proof verification failed";
57
58 const auto public_inputs_flat = PublicInputs::columns_to_flat(public_inputs.to_columns());
59
60 // TODO(#14234)[Unconditional PIs validation]: Remove next line
61 proof.insert(proof.begin(), 0);
62 return { proof, verification_key, public_inputs_flat };
63 }
64
69 {
70 std::vector<RecursionConstraint> avm_recursion_constraints;
71
72 AcirProgram program;
73
74 std::vector<fr>& witness = program.witness;
75
76 for (const auto& inner_circuit_data : inner_circuits) {
77 const std::vector<fr> key_witnesses = inner_circuit_data.verification_key->to_field_elements();
78 const std::vector<fr> proof_witnesses = inner_circuit_data.proof;
79 const std::vector<fr> public_inputs_witnesses = inner_circuit_data.public_inputs_flat;
80
81 RecursionConstraint avm_recursion_constraint{
82 .key = add_to_witness_and_track_indices(witness, key_witnesses),
83 .proof = add_to_witness_and_track_indices(witness, proof_witnesses),
84 .public_inputs = add_to_witness_and_track_indices(witness, public_inputs_witnesses),
85 .key_hash = 0, // not used
86 .proof_type = AVM,
87 };
88 avm_recursion_constraints.push_back(avm_recursion_constraint);
89 }
90
91 std::vector<size_t> avm_recursion_opcode_indices(avm_recursion_constraints.size());
92 std::iota(avm_recursion_opcode_indices.begin(), avm_recursion_opcode_indices.end(), 0);
93
94 AcirFormat& constraint_system = program.constraints;
95 constraint_system.max_witness_index = static_cast<uint32_t>(witness.size() - 1);
96 constraint_system.num_acir_opcodes = static_cast<uint32_t>(avm_recursion_constraints.size());
97 constraint_system.avm_recursion_constraints = avm_recursion_constraints;
99
100 mock_opcode_indices(constraint_system);
101
102 return program;
103 }
104};
105
106TEST_F(AcirAvm2RecursionConstraint, TestBasicSingleAvm2RecursionConstraint)
107{
108 // Skip this test since it is redundant with the one below (which also does proving and verification for the AVM
109 // recursive verifier circuit) and both are expensive to run. It would be nice to reinstate this as a standalone in
110 // the future if possible.
111 GTEST_SKIP();
112
113 std::vector<InnerCircuitData> layer_1_circuits;
114 layer_1_circuits.push_back(create_inner_circuit_data());
115 AcirProgram avm_verifier_program = construct_avm_verifier_program(layer_1_circuits);
116 auto layer_2_circuit = create_circuit<OuterBuilder>(avm_verifier_program);
117
118 info("circuit gates = ", layer_2_circuit.get_num_finalized_gates_inefficient());
119
120 auto prover_instance = std::make_shared<OuterProverInstance>(layer_2_circuit);
121 auto verification_key = std::make_shared<OuterVerificationKey>(prover_instance->get_precomputed());
122 OuterProver prover(prover_instance, verification_key);
123 info("prover gates = ", prover_instance->dyadic_size());
124 auto proof = prover.construct_proof();
125 VerifierCommitmentKey<curve::Grumpkin> ipa_verification_key(1 << CONST_ECCVM_LOG_N);
126 OuterVerifier verifier(verification_key, ipa_verification_key);
127 bool result = verifier.template verify_proof<bb::RollupIO>(proof, prover_instance->ipa_proof).result;
128 EXPECT_TRUE(result);
129}
130
138TEST_F(AcirAvm2RecursionConstraint, TestGenerateVKFromConstraintsWithoutWitness)
139{
141 GTEST_SKIP() << "Skipping slow test";
142 }
143
144 // Generate AVM proof, verification key and public inputs
145 InnerCircuitData avm_prover_output = create_inner_circuit_data();
146
147 // First, construct an AVM2 recursive verifier circuit VK by providing a valid program witness
149 {
150 AcirProgram avm_verifier_program = construct_avm_verifier_program({ avm_prover_output });
151 const ProgramMetadata metadata{
152 .has_ipa_claim = true,
153 };
154 auto layer_2_circuit = create_circuit<OuterBuilder>(avm_verifier_program, metadata);
155
156 info("circuit gates = ", layer_2_circuit.get_num_finalized_gates_inefficient());
157
158 auto prover_instance = std::make_shared<OuterProverInstance>(layer_2_circuit);
159 expected_vk = std::make_shared<OuterVerificationKey>(prover_instance->get_precomputed());
160 OuterProver prover(prover_instance, expected_vk);
161 info("prover gates = ", prover_instance->dyadic_size());
162
163 // Construct and verify a proof of the outer AVM verifier circuits
164 auto proof = prover.construct_proof();
165 VerifierCommitmentKey<curve::Grumpkin> ipa_verification_key(1 << CONST_ECCVM_LOG_N);
166 OuterVerifier verifier(expected_vk, ipa_verification_key);
167
168 bool result = verifier.template verify_proof<bb::RollupIO>(proof, prover_instance->ipa_proof).result;
169 EXPECT_TRUE(result);
170 }
171
172 // Now, construct the AVM2 recursive verifier circuit VK by providing the program without a witness
174 {
175 AcirProgram avm_verifier_program = construct_avm_verifier_program({ avm_prover_output });
176
177 // Clear the program witness then construct the bberg circuit as normal
178 avm_verifier_program.witness.clear();
179 const ProgramMetadata metadata{ .has_ipa_claim = true };
180 auto layer_2_circuit = create_circuit<OuterBuilder>(avm_verifier_program, metadata);
181
182 info("circuit gates = ", layer_2_circuit.get_num_finalized_gates_inefficient());
183
184 auto prover_instance = std::make_shared<OuterProverInstance>(layer_2_circuit);
185 actual_vk = std::make_shared<OuterVerificationKey>(prover_instance->get_precomputed());
186 OuterProver prover(prover_instance, actual_vk);
187 info("prover gates = ", prover_instance->dyadic_size());
188 }
189
190 // Compare the VK constructed via running the IVC with the one constructed via mocking
191 EXPECT_EQ(*actual_vk.get(), *expected_vk.get());
192}
acir_format::AcirFormatOriginalOpcodeIndices create_empty_original_opcode_indices()
void mock_opcode_indices(acir_format::AcirFormat &constraint_system)
static AcirProgram construct_avm_verifier_program(const std::vector< InnerCircuitData > &inner_circuits)
Create a circuit that recursively verifies one or more inner avm2 circuits.
static InnerCircuitData create_inner_circuit_data()
A ProverInstance is normally constructed from a finalized circuit and it contains all the information...
The verification key is responsible for storing the commitments to the precomputed (non-witnessk) pol...
Representation of the Grumpkin Verifier Commitment Key inside a bn254 circuit.
bool verify(const Proof &proof, const PublicInputs &pi, const VkData &vk_data)
std::pair< Proof, VkData > prove(tracegen::TraceContainer &&trace)
static std::shared_ptr< AvmVerifier::VerificationKey > create_verification_key(const VkData &vk_data)
void info(Args... args)
Definition log.hpp:75
TestTraceContainer trace
std::vector< uint32_t > add_to_witness_and_track_indices(WitnessVector &witness, const T &input)
Append values to a witness vector and track their indices.
Definition utils.hpp:70
bool skip_slow_tests()
Check if slow tests should be skipped.
Definition fixtures.cpp:199
std::pair< tracegen::TraceContainer, PublicInputs > get_minimal_trace_with_pi()
Definition fixtures.cpp:183
std::filesystem::path bb_crs_path()
void init_file_crs_factory(const std::filesystem::path &path)
TEST_F(BoomerangGoblinRecursiveVerifierTests, graph_description_basic)
Construct and check a goblin recursive verification circuit.
Entry point for Barretenberg command-line interface.
Definition api.hpp:5
UltraCircuitBuilder_< UltraExecutionTraceBlocks > UltraCircuitBuilder
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13
std::shared_ptr< AvmFlavor::VerificationKey > verification_key
AvmProvingHelper::Proof proof
AcirFormatOriginalOpcodeIndices original_opcode_indices
std::vector< RecursionConstraint > avm_recursion_constraints
RecursionConstraint struct contains information required to recursively verify a proof!
static std::vector< FF > columns_to_flat(std::vector< std::vector< FF > > const &columns)
Definition avm_io.cpp:289