Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
graph_description_two_layer_avm_recursive_verifier.test.cpp
Go to the documentation of this file.
14
16
17using namespace bb::avm2;
18
19class BoomerangTwoLayerAvmRecursiveVerifierTests : public ::testing::Test {
20 public:
22
24 using FF = Builder::FF;
25
28
30
32 {
34
35 AvmProver prover;
36 auto proof = prover.prove(std::move(trace));
37 proof.resize(AVM_V2_PROOF_LENGTH_IN_FIELDS_PADDED, FF::zero()); // Pad proof
38
39 const bool verified = prover.verify(proof, public_inputs);
40 EXPECT_TRUE(verified) << "native proof verification failed";
41
42 auto public_inputs_flat = PublicInputs::columns_to_flat(public_inputs.to_columns());
43 public_inputs_flat.resize(AVM_PUBLIC_INPUTS_COLUMNS_COMBINED_LENGTH, FF::zero()); // Pad public inputs
44
45 return { proof, public_inputs_flat };
46 }
47};
48
54{
56 GTEST_SKIP() << "Skipping slow test";
57 }
58
59 auto [proof, public_inputs_flat] = create_avm_data();
60
62
63 std::vector<field_t<Builder>> stdlib_public_inputs_flat;
64 stdlib_public_inputs_flat.reserve(AVM_PUBLIC_INPUTS_COLUMNS_COMBINED_LENGTH);
65 for (const auto public_input : public_inputs_flat) {
66 stdlib_public_inputs_flat.emplace_back(field_t<Builder>::from_witness(&builder, public_input));
67 // We need to fix this witness because it is only used in Poseidon, and as part of Poseidon it only appears in
68 // one gate
69 stdlib_public_inputs_flat.back().fix_witness();
70 }
71 stdlib::Proof<Builder> stdlib_proof;
72 stdlib_proof.reserve(AVM_V2_PROOF_LENGTH_IN_FIELDS_PADDED);
73 for (const auto proof_element : proof) {
74 stdlib_proof.emplace_back(field_t<Builder>::from_witness(&builder, proof_element));
75 // We need to fix this witness because it is only used in Poseidon, and as part of Poseidon it only appears in
76 // one gate
77 stdlib_proof.back().fix_witness();
78 }
79
81 PublicInputs::flat_to_columns<field_t<Builder>>(stdlib_public_inputs_flat);
82
84 auto output = goblin_avm_verifier.verify_proof(stdlib_proof, public_inputs);
85
86 IO inputs;
87 inputs.pairing_inputs = output.points_accumulator;
88 inputs.ipa_claim = output.ipa_claim;
89 inputs.set_public();
90
91 builder.ipa_proof = output.ipa_proof.get_value();
92
93 // Construct and verify a proof for the Goblin Recursive Verifier circuit
94 {
95 auto prover_instance = std::make_shared<ProverInstance>(builder);
96 auto verification_key =
97 std::make_shared<typename UltraRollupFlavor::VerificationKey>(prover_instance->get_precomputed());
98 auto vk_and_hash = std::make_shared<typename UltraRollupFlavor::VKAndHash>(verification_key);
99 UltraProver_<UltraRollupFlavor> prover(prover_instance, verification_key);
100 UltraRollupVerifier verifier(vk_and_hash);
101 auto proof = prover.construct_proof();
102 bool verified = verifier.verify_proof(proof).result;
103
104 ASSERT_TRUE(verified);
105 }
106
107 // The pairing points are public outputs from the recursive verifier that will be verified externally via a pairing
108 // check. While they are computed within the circuit (via batch_mul for P0 and negation for P1), their output
109 // coordinates may not appear in multiple constraint gates. Calling fix_witness() adds explicit constraints on these
110 // values. Without these constraints, the StaticAnalyzer detects 20 variables (the coordinate limbs) that appear in
111 // only one gate. This ensures the pairing point coordinates are properly constrained within the circuit itself,
112 // rather than relying solely on them being public outputs.
113 output.points_accumulator.P0.fix_witness();
114 output.points_accumulator.P1.fix_witness();
115 info("Recursive Verifier: num gates = ", builder.num_gates());
116 auto graph = cdg::StaticAnalyzer(builder, false);
117 auto variables_in_one_gate = graph.get_variables_in_one_gate();
118 // The variable in one gate is the last Shplonk power we compute. It is computed even though it is not used because
119 // of how the PCS is structured (more precisely, because of the interaction between gemini and interleaving).
120 EXPECT_EQ(variables_in_one_gate.size(), 1);
121}
122
123} // namespace bb::stdlib::recursion::honk
#define AVM_PUBLIC_INPUTS_COLUMNS_COMBINED_LENGTH
#define AVM_V2_PROOF_LENGTH_IN_FIELDS_PADDED
A ProverInstance is normally constructed from a finalized circuit and it contains all the information...
typename ExecutionTrace::FF FF
Output verify_proof(const Proof &proof)
Perform ultra verification.
bool verify(const Proof &proof, const PublicInputs &pi)
Proof prove(tracegen::TraceContainer &&trace)
Recursive verifier of AVM2 proofs that utilizes the Goblin mechanism for efficient EC operations.
A simple wrapper around a vector of stdlib field elements representing a proof.
Definition proof.hpp:19
The data that is propagated on the public inputs of a rollup circuit.
#define info(...)
Definition log.hpp:93
AluTraceBuilder builder
Definition alu.test.cpp:124
TestTraceContainer trace
AvmProvingInputs inputs
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.
UltraCircuitBuilder_< UltraExecutionTraceBlocks > UltraCircuitBuilder
UltraStaticAnalyzer StaticAnalyzer
Definition graph.hpp:194
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13
static std::vector< FF > columns_to_flat(std::vector< std::vector< FF > > const &columns)
Definition avm_io.cpp:289