17#include <gtest/gtest.h>
41 static auto [cached_verified, cached_proof_result] = []() {
44 const auto public_inputs_cols = public_inputs.to_columns();
51 const bool verified = verifier.
verify_proof(proof, public_inputs_cols);
56 ASSERT_TRUE(cached_verified) <<
"native proof verification failed";
57 proof_result = cached_proof_result;
76 GTEST_SKIP() <<
"Skipping slow test";
79 const bool pad_proof = GetParam();
87 NativeProofResult proof_result;
89 std::chrono::steady_clock::time_point start = std::chrono::steady_clock::now();
90 ASSERT_NO_FATAL_FAILURE({ create_and_verify_native_proof(proof_result); });
91 std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now();
92 std::cout <<
"Time taken (native proof): " << std::chrono::duration_cast<std::chrono::seconds>(end - start).count()
95 auto [proof, public_inputs_cols] = proof_result;
106 OuterBuilder outer_circuit;
110 public_inputs_ct.reserve(public_inputs_cols.size());
111 for (
const auto& vec : public_inputs_cols) {
113 vec_ct.reserve(vec.size());
114 for (
const auto& val : vec) {
115 vec_ct.push_back(UltraFF::from_witness(&outer_circuit, val));
117 public_inputs_ct.push_back(vec_ct);
122 auto verifier_output = [&]() {
123 std::cout <<
"Constructing AvmRecursiveVerifier and verifying " << (pad_proof ?
"padded " :
"") <<
"proof..."
125 std::chrono::steady_clock::time_point start = std::chrono::steady_clock::now();
127 auto result = avm_rec_verifier.
verify_proof(stdlib_proof, public_inputs_ct);
128 std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now();
129 std::cout <<
"Time taken (recursive verification): "
130 << std::chrono::duration_cast<std::chrono::seconds>(end - start).count() <<
"s" <<
std::endl;
135 inputs.pairing_inputs = verifier_output.points_accumulator;
136 inputs.ipa_claim = verifier_output.ipa_claim;
138 outer_circuit.ipa_proof = verifier_output.ipa_proof.get_value();
141 NativeVerifierCommitmentKey pcs_vkey{};
142 bool agg_output_valid = pcs_vkey.pairing_check(verifier_output.points_accumulator.P0.get_value(),
143 verifier_output.points_accumulator.P1.get_value());
144 ASSERT_TRUE(agg_output_valid) <<
"Pairing points (aggregation state) are not valid.";
145 ASSERT_FALSE(outer_circuit.failed()) <<
"Outer circuit has failed.";
147 vinfo(
"Recursive verifier",
148 (pad_proof ?
" (padded proof)" :
""),
149 ": finalized num gates = ",
150 outer_circuit.num_gates());
157 auto outer_proof = [&]() {
158 auto verification_key =
160 UltraRollupProver outer_prover(outer_proving_key, verification_key);
161 return outer_prover.construct_proof();
165 auto outer_verification_key =
170 bool result = final_verifier.
verify_proof(outer_proof).result;
179 GTEST_SKIP() <<
"Skipping slow test";
184 const bool pad_proof = GetParam();
186 NativeProofResult proof_result;
188 std::chrono::steady_clock::time_point start = std::chrono::steady_clock::now();
189 ASSERT_NO_FATAL_FAILURE({ create_and_verify_native_proof(proof_result); });
190 std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now();
191 std::cout <<
"Time taken (native proof): " << std::chrono::duration_cast<std::chrono::seconds>(end - start).count()
194 auto [proof, public_inputs_cols] = proof_result;
209 public_inputs_ct.reserve(public_inputs_cols.size());
210 for (
const auto& vec : public_inputs_cols) {
211 std::vector<FF> vec_ct;
212 vec_ct.reserve(vec.size());
213 for (
const auto& val : vec) {
214 vec_ct.push_back(FF::from_witness(&
builder, val));
216 public_inputs_ct.push_back(vec_ct);
221 FF final_state_full_verification;
223 transcript->enable_manifest();
226 std::chrono::steady_clock::time_point start = std::chrono::steady_clock::now();
228 [[maybe_unused]]
auto _result = avm_rec_verifier.
verify_proof(stdlib_proof, public_inputs_ct);
229 std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now();
230 std::cout <<
"Time taken (recursive verification): "
231 << std::chrono::duration_cast<std::chrono::seconds>(end - start).count() <<
"s" <<
std::endl;
236 FF final_state_transcript_operations_only;
239 std::tie(final_state_transcript_operations_only, mocked_transcript) =
244 EXPECT_EQ(final_state_full_verification.get_value(), final_state_transcript_operations_only.get_value());
247 auto manifest = transcript->get_manifest();
248 auto mocked_manifest = mocked_transcript->get_manifest();
253 for (
size_t round = 0; round < manifest.size(); ++round) {
254 ASSERT_EQ(manifest[round], mocked_manifest[round])
255 << std::format(
"Real/Mocked manifest discrepency in round {}", round);
259 final_state_transcript_operations_only.assert_equal(final_state_full_verification);
261 EXPECT_TRUE(!
builder.failed());
266 ::testing::Values(
false,
true),
267 [](
const auto&
info) {
return info.param ?
"Padded" :
"Unpadded"; });
273 GTEST_SKIP() <<
"Skipping slow test";
280 NativeProofResult proof_result;
282 std::chrono::steady_clock::time_point start = std::chrono::steady_clock::now();
283 ASSERT_NO_FATAL_FAILURE({ create_and_verify_native_proof(proof_result); });
284 std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now();
285 std::cout <<
"Time taken (native proof): " << std::chrono::duration_cast<std::chrono::seconds>(end - start).count()
288 auto [proof, public_inputs_cols] = proof_result;
291 OuterBuilder outer_circuit;
295 public_inputs_ct.reserve(public_inputs_cols.size());
296 for (
const auto& vec : public_inputs_cols) {
298 vec_ct.reserve(vec.size());
299 for (
const auto& val : vec) {
300 vec_ct.push_back(UltraFF::from_witness(&outer_circuit, val));
302 public_inputs_ct.push_back(vec_ct);
305 public_inputs_ct[1][5] += 1;
311 std::chrono::steady_clock::time_point start = std::chrono::steady_clock::now();
313 auto result = avm_rec_verifier.
verify_proof(stdlib_proof, public_inputs_ct);
314 std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now();
315 std::cout <<
"Time taken (recursive verification): "
316 << std::chrono::duration_cast<std::chrono::seconds>(end - start).count() <<
"s" <<
std::endl;
319 ASSERT_TRUE(outer_circuit.failed()) <<
"Outer circuit SHOULD fail with bad PIs.";
#define BB_ASSERT_GT(left, right,...)
#define BB_ASSERT_EQ(actual, expected,...)
#define AVM_V2_PROOF_LENGTH_IN_FIELDS_PADDED
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.
AvmFlavorSettings::VerifierCommitmentKey VerifierCommitmentKey
Proof prove(tracegen::TraceContainer &&trace)
static std::shared_ptr< AvmVerifier::VerificationKey > create_verification_key(const VkData &vk_data)
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...
AvmRecursiveFlavorSettings::CircuitBuilder CircuitBuilder
FF hash_avm_transcript(const StdlibProof &stdlib_proof)
Hash the transcript after verification is complete to produce a hash of the public inputs and proofs ...
PairingPoints verify_proof(const HonkProof &proof, const std::vector< std::vector< fr > > &public_inputs_vec_nt)
virtual bool verify_proof(const HonkProof &proof, const std::vector< std::vector< FF > > &public_inputs)
This function verifies an Avm Honk proof for given program settings.
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
AvmProvingHelper InnerProver
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.
The data that is propagated on the public inputs of a rollup circuit.
INSTANTIATE_TEST_SUITE_P(PaddingVariants, AvmRecursiveTestsParameterized, ::testing::Values(false, true), [](const auto &info) { return info.param ? "Padded" :"Unpadded";})
TEST_F(AvmRecursiveTests, GoblinRecursionFailsWithWrongPIs)
TEST_P(AvmRecursiveTestsParameterized, GoblinRecursion)
A test of the Goblinized 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