2#include "barretenberg/aztec/aztec_constants.hpp"
17#include <gtest/gtest.h>
40 static auto [cached_verified, cached_proof_result] = []() {
43 const auto public_inputs_cols = public_inputs.to_columns();
49 const bool verified = verifier.
verify_proof(proof, public_inputs_cols);
54 ASSERT_TRUE(cached_verified) <<
"native proof verification failed";
55 proof_result = cached_proof_result;
68 GTEST_SKIP() <<
"Skipping slow test";
76 NativeProofResult proof_result;
78 std::chrono::steady_clock::time_point start = std::chrono::steady_clock::now();
79 ASSERT_NO_FATAL_FAILURE({ create_and_verify_native_proof(proof_result); });
80 std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now();
81 std::cout <<
"Time taken (native proof): " << std::chrono::duration_cast<std::chrono::seconds>(end - start).count()
84 auto [proof, public_inputs_cols] = proof_result;
87 OuterBuilder outer_circuit;
91 public_inputs_ct.reserve(public_inputs_cols.size());
92 for (
const auto& vec : public_inputs_cols) {
94 vec_ct.reserve(vec.size());
95 for (
const auto& val : vec) {
96 vec_ct.push_back(UltraFF::from_witness(&outer_circuit, val));
98 public_inputs_ct.push_back(vec_ct);
103 auto verifier_output = [&]() {
105 std::chrono::steady_clock::time_point start = std::chrono::steady_clock::now();
108 std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now();
109 std::cout <<
"Time taken (recursive verification): "
110 << std::chrono::duration_cast<std::chrono::seconds>(end - start).count() <<
"s" <<
std::endl;
115 ASSERT_TRUE(verifier_output.points_accumulator.check()) <<
"Pairing points (aggregation state) are not valid.";
119 std::move(verifier_output.triple_ipa_opening));
120 recursion_output.
finalize(outer_circuit,
false,
true);
122 ASSERT_FALSE(outer_circuit.failed()) <<
"Outer circuit has failed.";
124 vinfo(
"Recursive verifier: finalized num gates = ", outer_circuit.num_gates());
131 auto outer_proof = [&]() {
133 UltraRollupProver outer_prover(outer_proving_key, verification_key);
134 return outer_prover.construct_proof();
151 GTEST_SKIP() <<
"Skipping slow test";
156 NativeProofResult proof_result;
158 std::chrono::steady_clock::time_point start = std::chrono::steady_clock::now();
159 ASSERT_NO_FATAL_FAILURE({ create_and_verify_native_proof(proof_result); });
160 std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now();
161 std::cout <<
"Time taken (native proof): " << std::chrono::duration_cast<std::chrono::seconds>(end - start).count()
164 auto [proof, public_inputs_cols] = proof_result;
171 public_inputs_ct.reserve(public_inputs_cols.size());
172 for (
const auto& vec : public_inputs_cols) {
173 std::vector<FF> vec_ct;
174 vec_ct.reserve(vec.size());
175 for (
const auto& val : vec) {
176 vec_ct.push_back(FF::from_witness(&
builder, val));
178 public_inputs_ct.push_back(vec_ct);
183 FF final_state_full_verification;
185 transcript->enable_manifest();
188 std::chrono::steady_clock::time_point start = std::chrono::steady_clock::now();
190 [[maybe_unused]]
auto _result = avm_rec_verifier.
verify_proof(stdlib_proof, public_inputs_ct);
191 std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now();
192 std::cout <<
"Time taken (recursive verification): "
193 << std::chrono::duration_cast<std::chrono::seconds>(end - start).count() <<
"s" <<
std::endl;
198 FF final_state_transcript_operations_only;
201 std::tie(final_state_transcript_operations_only, mocked_transcript) =
206 EXPECT_EQ(final_state_full_verification.get_value(), final_state_transcript_operations_only.get_value());
209 auto manifest = transcript->get_manifest();
210 auto mocked_manifest = mocked_transcript->get_manifest();
214 for (
size_t round = 0; round < manifest.size(); ++round) {
215 ASSERT_EQ(manifest[round], mocked_manifest[round])
216 << std::format(
"Real/Mocked manifest discrepancy in round {}", round);
220 final_state_transcript_operations_only.assert_equal(final_state_full_verification);
222 EXPECT_TRUE(!
builder.failed());
229 GTEST_SKIP() <<
"Skipping slow test";
236 NativeProofResult proof_result;
238 std::chrono::steady_clock::time_point start = std::chrono::steady_clock::now();
239 ASSERT_NO_FATAL_FAILURE({ create_and_verify_native_proof(proof_result); });
240 std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now();
241 std::cout <<
"Time taken (native proof): " << std::chrono::duration_cast<std::chrono::seconds>(end - start).count()
244 auto [proof, public_inputs_cols] = proof_result;
247 OuterBuilder outer_circuit;
251 public_inputs_ct.reserve(public_inputs_cols.size());
252 for (
const auto& vec : public_inputs_cols) {
254 vec_ct.reserve(vec.size());
255 for (
const auto& val : vec) {
256 vec_ct.push_back(UltraFF::from_witness(&outer_circuit, val));
258 public_inputs_ct.push_back(vec_ct);
261 public_inputs_ct[1][5] += 1;
267 std::chrono::steady_clock::time_point start = std::chrono::steady_clock::now();
270 std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now();
271 std::cout <<
"Time taken (recursive verification): "
272 << std::chrono::duration_cast<std::chrono::seconds>(end - start).count() <<
"s" <<
std::endl;
275 ASSERT_TRUE(outer_circuit.failed()) <<
"Outer circuit SHOULD fail with bad PIs.";
#define BB_ASSERT_GT(left, right,...)
#define BB_ASSERT_EQ(actual, expected,...)
static bool check(const Builder &circuit)
Check the witness satisifies the circuit.
UltraCircuitBuilder CircuitBuilder
typename Curve::ScalarField FF
Output verify_proof(const Proof &proof)
Perform ultra verification.
Proof prove(tracegen::TraceContainer &&trace)
static std::pair< stdlib::field_t< Builder >, std::shared_ptr< TemplatedTranscript< Builder > > > hash_avm_transcript_for_testing(Builder &builder, const stdlib::Proof< Builder > &stdlib_proof, const std::vector< std::vector< stdlib::field_t< Builder > > > &public_inputs)
Testing method to hash the transcript after having replicated the operations performed on the AVM tra...
MegaCircuitBuilder CircuitBuilder
FF hash_avm_transcript()
Hash the transcript after verification is complete to produce a hash of the public inputs and proofs ...
PairingPoints verify_proof(const StdlibProof &stdlib_proof, const std::vector< std::vector< typename Flavor::FF > > &public_inputs)
Verify an AVM proof and return PairingPoints whose validity bears witness to successful verification ...
bool verify_proof(const HonkProof &proof, const std::vector< std::vector< FF > > &public_inputs)
Verify an AVM proof.
Recursive verifier of AVM2 proofs that utilizes the Goblin mechanism for efficient EC operations.
TwoLayerAvmRecursiveVerifierOutput verify_proof(const stdlib::Proof< UltraCircuitBuilder > &stdlib_proof, const std::vector< std::vector< UltraFF > > &public_inputs) const
Recursively verify an AVM proof using Goblin and two layers of recursive verification.
typename RecursiveFlavor::CircuitBuilder OuterBuilder
static void SetUpTestSuite()
static void create_and_verify_native_proof(NativeProofResult &proof_result)
A simple wrapper around a vector of stdlib field elements representing a proof.
TEST_F(AvmRecursiveTests, TwoLayerAvmRecursion)
A test of the Two Layer AVM recursive verifier.
bool skip_slow_tests()
Check if slow tests should be skipped.
std::pair< tracegen::TraceContainer, PublicInputs > get_minimal_trace_with_pi()
std::filesystem::path bb_crs_path()
void init_file_crs_factory(const std::filesystem::path &path)
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
std::vector< std::vector< FF > > public_inputs_cols