66#include " barretenberg/ultra_honk/prover_instance.hpp"
77#include " barretenberg/ultra_honk/ultra_prover.hpp"
88#include " barretenberg/ultra_honk/ultra_verifier.hpp"
9+ #include " barretenberg/vm2/common/aztec_constants.hpp"
910#include " barretenberg/vm2/constraining/prover.hpp"
1011#include " barretenberg/vm2/constraining/recursion/goblin_avm_recursive_verifier.hpp"
1112#include " barretenberg/vm2/constraining/recursion/recursive_flavor.hpp"
@@ -57,19 +58,26 @@ class AvmRecursiveTests : public ::testing::Test {
5758 }
5859};
5960
61+ // Parameterized test class for testing with and without proof padding
62+ class AvmRecursiveTestsParameterized : public AvmRecursiveTests , public ::testing::WithParamInterface<bool > {};
63+
6064/* *
6165 * @brief A test of the Goblinized AVM recursive verifier.
6266 * @details Constructs a simple AVM circuit for which a proof is verified using the Goblinized AVM recursive verifier. A
6367 * proof is constructed and verified for the outer (Ultra) circuit produced by this algorithm. See the documentation in
6468 * AvmGoblinRecursiveVerifier for details of the recursive verification algorithm.
6569 *
70+ * When pad_proof=true (Padded variant), the proof is padded to AVM_V2_PROOF_LENGTH_IN_FIELDS_PADDED to match production
71+ * behavior where TypeScript pads the proof before passing it to noir circuits.
6672 */
67- TEST_F (AvmRecursiveTests , GoblinRecursion)
73+ TEST_P (AvmRecursiveTestsParameterized , GoblinRecursion)
6874{
6975 if (testing::skip_slow_tests ()) {
7076 GTEST_SKIP () << " Skipping slow test" ;
7177 }
7278
79+ const bool pad_proof = GetParam ();
80+
7381 // Type aliases specific to GoblinRecursion test
7482 using AvmRecursiveVerifier = AvmGoblinRecursiveVerifier;
7583 using OuterBuilder = typename UltraRollupFlavor::CircuitBuilder;
@@ -86,7 +94,14 @@ TEST_F(AvmRecursiveTests, GoblinRecursion)
8694 << " s" << std::endl;
8795
8896 auto [proof, public_inputs_cols] = proof_result;
89- proof.insert (proof.begin (), 0 ); // TODO(#14234)[Unconditional PIs validation]: remove this
97+
98+ // Optionally pad the proof to match production behavior
99+ if (pad_proof) {
100+ std::cout << " Padding proof from " << proof.size () << " to " << AVM_V2_PROOF_LENGTH_IN_FIELDS_PADDED
101+ << " fields" << std::endl;
102+ ASSERT_LE (proof.size (), AVM_V2_PROOF_LENGTH_IN_FIELDS_PADDED) << " Proof exceeds padded length" ;
103+ proof.resize (AVM_V2_PROOF_LENGTH_IN_FIELDS_PADDED, 0 );
104+ }
90105
91106 // Construct stdlib representations of the proof, public inputs and verification key
92107 OuterBuilder outer_circuit;
@@ -106,7 +121,8 @@ TEST_F(AvmRecursiveTests, GoblinRecursion)
106121 // Construct the AVM recursive verifier and verify the proof
107122 // Scoped to free memory of AvmRecursiveVerifier.
108123 auto verifier_output = [&]() {
109- std::cout << " Constructing AvmRecursiveVerifier and verifying proof..." << std::endl;
124+ std::cout << " Constructing AvmRecursiveVerifier and verifying " << (pad_proof ? " padded " : " " ) << " proof..."
125+ << std::endl;
110126 std::chrono::steady_clock::time_point start = std::chrono::steady_clock::now ();
111127 AvmRecursiveVerifier avm_rec_verifier (outer_circuit);
112128 auto result = avm_rec_verifier.verify_proof (stdlib_proof, public_inputs_ct);
@@ -129,7 +145,10 @@ TEST_F(AvmRecursiveTests, GoblinRecursion)
129145 ASSERT_TRUE (agg_output_valid) << " Pairing points (aggregation state) are not valid." ;
130146 ASSERT_FALSE (outer_circuit.failed ()) << " Outer circuit has failed." ;
131147
132- vinfo (" Recursive verifier: finalized num gates = " , outer_circuit.num_gates ());
148+ vinfo (" Recursive verifier" ,
149+ (pad_proof ? " (padded proof)" : " " ),
150+ " : finalized num gates = " ,
151+ outer_circuit.num_gates ());
133152
134153 // Construct and verify an Ultra Rollup proof of the AVM recursive verifier circuit. This proof carries an IPA claim
135154 // from ECCVM recursive verification in its public inputs that will be verified as part of the UltraRollupVerifier.
@@ -153,99 +172,10 @@ TEST_F(AvmRecursiveTests, GoblinRecursion)
153172 EXPECT_TRUE (result);
154173}
155174
156- // Similar to GoblinRecursion, but with PI validation disabled and garbage PIs in the public inputs.
157- // This is important as long as we use a fallback mechanism for the AVM proofs.
158- TEST_F (AvmRecursiveTests, GoblinRecursionWithoutPIValidation)
159- {
160- if (testing::skip_slow_tests ()) {
161- GTEST_SKIP () << " Skipping slow test" ;
162- }
163-
164- // Type aliases specific to GoblinRecursion test
165- using AvmRecursiveVerifier = AvmGoblinRecursiveVerifier;
166- using OuterBuilder = typename UltraRollupFlavor::CircuitBuilder;
167- using UltraFF = UltraRecursiveFlavor_<OuterBuilder>::FF;
168- using UltraRollupProver = UltraProver_<UltraRollupFlavor>;
169- using NativeVerifierCommitmentKey = typename AvmFlavor::VerifierCommitmentKey;
170-
171- NativeProofResult proof_result;
172- std::cout << " Creating and verifying native proof..." << std::endl;
173- std::chrono::steady_clock::time_point start = std::chrono::steady_clock::now ();
174- ASSERT_NO_FATAL_FAILURE ({ create_and_verify_native_proof (proof_result); });
175- std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now ();
176- std::cout << " Time taken (native proof): " << std::chrono::duration_cast<std::chrono::seconds>(end - start).count ()
177- << " s" << std::endl;
178-
179- auto [proof, public_inputs_cols] = proof_result;
180- // Set fallback / disable PI validation
181- proof.insert (proof.begin (),
182- 1 ); // TODO(#14234)[Unconditional PIs validation]: PI validation is disabled for this test.
183-
184- // Construct stdlib representations of the proof, public inputs and verification key
185- OuterBuilder outer_circuit;
186- stdlib::Proof<OuterBuilder> stdlib_proof (outer_circuit, proof);
187-
188- std::vector<std::vector<UltraFF>> public_inputs_ct;
189- public_inputs_ct.reserve (public_inputs_cols.size ());
190- // Use GARBAGE in public inputs and confirm that PI validation is disabled!
191- for (const auto & vec : public_inputs_cols) {
192- std::vector<UltraFF> vec_ct;
193- vec_ct.reserve (vec.size ());
194- for (const auto & _ : vec) {
195- vec_ct.push_back (UltraFF::from_witness (&outer_circuit, FF::random_element ()));
196- }
197- public_inputs_ct.push_back (vec_ct);
198- }
199-
200- // Construct the AVM recursive verifier and verify the proof
201- // Scoped to free memory of AvmRecursiveVerifier.
202- auto verifier_output = [&]() {
203- std::cout << " Constructing AvmRecursiveVerifier and verifying proof..." << std::endl;
204- std::chrono::steady_clock::time_point start = std::chrono::steady_clock::now ();
205- AvmRecursiveVerifier avm_rec_verifier (outer_circuit);
206- auto result = avm_rec_verifier.verify_proof (stdlib_proof, public_inputs_ct);
207- std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now ();
208- std::cout << " Time taken (recursive verification): "
209- << std::chrono::duration_cast<std::chrono::seconds>(end - start).count () << " s" << std::endl;
210- return result;
211- }();
212-
213- stdlib::recursion::honk::RollupIO inputs;
214- inputs.pairing_inputs = verifier_output.points_accumulator ;
215- inputs.ipa_claim = verifier_output.ipa_claim ;
216- inputs.set_public ();
217- outer_circuit.ipa_proof = verifier_output.ipa_proof .get_value ();
218-
219- // Ensure that the pairing check is satisfied on the outputs of the recursive verifier
220- NativeVerifierCommitmentKey pcs_vkey{};
221- bool agg_output_valid = pcs_vkey.pairing_check (verifier_output.points_accumulator .P0 .get_value (),
222- verifier_output.points_accumulator .P1 .get_value ());
223- ASSERT_TRUE (agg_output_valid) << " Pairing points (aggregation state) are not valid." ;
224- ASSERT_FALSE (outer_circuit.failed ()) << " Outer circuit has failed." ;
225-
226- vinfo (" Recursive verifier: finalized num gates = " , outer_circuit.num_gates ());
227-
228- // Construct and verify an Ultra Rollup proof of the AVM recursive verifier circuit. This proof carries an IPA claim
229- // from ECCVM recursive verification in its public inputs that will be verified as part of the UltraRollupVerifier.
230- auto outer_proving_key = std::make_shared<ProverInstance_<UltraRollupFlavor>>(outer_circuit);
231-
232- // Scoped to free memory of UltraRollupProver.
233- auto outer_proof = [&]() {
234- auto verification_key =
235- std::make_shared<UltraRollupFlavor::VerificationKey>(outer_proving_key->get_precomputed ());
236- UltraRollupProver outer_prover (outer_proving_key, verification_key);
237- return outer_prover.construct_proof ();
238- }();
239-
240- // Verify the proof of the Ultra circuit that verified the AVM recursive verifier circuit
241- auto outer_verification_key =
242- std::make_shared<UltraRollupFlavor::VerificationKey>(outer_proving_key->get_precomputed ());
243- auto outer_vk_and_hash = std::make_shared<UltraRollupFlavor::VKAndHash>(outer_verification_key);
244- UltraRollupVerifier final_verifier (outer_vk_and_hash);
245-
246- bool result = final_verifier.verify_proof (outer_proof).result ;
247- EXPECT_TRUE (result);
248- }
175+ INSTANTIATE_TEST_SUITE_P (PaddingVariants,
176+ AvmRecursiveTestsParameterized,
177+ ::testing::Values (false , true ),
178+ [](const auto & info) { return info.param ? " Padded" : " Unpadded" ; });
249179
250180// Ensures that the recursive verifier fails with wrong PIs.
251181TEST_F (AvmRecursiveTests, GoblinRecursionFailsWithWrongPIs)
@@ -268,8 +198,6 @@ TEST_F(AvmRecursiveTests, GoblinRecursionFailsWithWrongPIs)
268198 << " s" << std::endl;
269199
270200 auto [proof, public_inputs_cols] = proof_result;
271- // PI validation is enabled.
272- proof.insert (proof.begin (), 0 ); // TODO(#14234)[Unconditional PIs validation]: remove this
273201
274202 // Construct stdlib representations of the proof, public inputs and verification key
275203 OuterBuilder outer_circuit;
@@ -285,7 +213,7 @@ TEST_F(AvmRecursiveTests, GoblinRecursionFailsWithWrongPIs)
285213 }
286214 public_inputs_ct.push_back (vec_ct);
287215 }
288- // Mutate some PI entry so that we can confirm that PI validation is enabled and fails!
216+ // Mutate a PI entry to verify that validation correctly fails with incorrect public inputs
289217 public_inputs_ct[1 ][5 ] += 1 ;
290218
291219 // Construct the AVM recursive verifier and verify the proof
0 commit comments