Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
graph_description_protogalaxy.test.cpp
Go to the documentation of this file.
14
16
18class BoomerangProtogalaxyRecursiveTests : public testing::Test {
19 public:
20 // Define types for the inner circuit, i.e. the circuit whose proof will be recursively verified
32
33 // Defines types for the outer circuit, i.e. the circuit of the recursive verifier
39
50
51 static void create_function_circuit(InnerBuilder& builder, size_t log_num_gates = 10)
52 {
53 using fr_ct = typename InnerCurve::ScalarField;
56 using witness_ct = typename InnerCurve::witness_ct;
58 using fr = typename InnerCurve::ScalarFieldNative;
59
60 // Create 2^log_n many add gates based on input log num gates
61 const size_t num_gates = 1 << log_num_gates;
62 for (size_t i = 0; i < num_gates; ++i) {
64 uint32_t a_idx = builder.add_variable(a);
65
68 fr d = a + b + c;
69 uint32_t b_idx = builder.add_variable(b);
70 uint32_t c_idx = builder.add_variable(c);
71 uint32_t d_idx = builder.add_variable(d);
72
73 builder.create_big_add_gate({ a_idx, b_idx, c_idx, d_idx, fr(1), fr(1), fr(1), fr(-1), fr(0) });
74 }
75
76 // Define some additional non-trivial but arbitrary circuit logic
80
81 for (size_t i = 0; i < 32; ++i) {
82 a = (a * b) + b + a;
83 a = a.madd(b, c);
84 }
86 byte_array_ct to_hash(&builder, "nonsense test data");
88
89 fr bigfield_data = fr::random_element(&engine);
90 fr bigfield_data_a{ bigfield_data.data[0], bigfield_data.data[1], 0, 0 };
91 fr bigfield_data_b{ bigfield_data.data[2], bigfield_data.data[3], 0, 0 };
92
93 fq_ct big_a(fr_ct(witness_ct(&builder, bigfield_data_a.to_montgomery_form())), fr_ct(witness_ct(&builder, 0)));
94 fq_ct big_b(fr_ct(witness_ct(&builder, bigfield_data_b.to_montgomery_form())), fr_ct(witness_ct(&builder, 0)));
95
96 big_a* big_b;
97
99 };
100
101 static void test_recursive_folding(const size_t num_verifiers = 1)
102 {
103 // Create two arbitrary circuits for the first round of folding
104 InnerBuilder builder1;
105 create_function_circuit(builder1);
106 InnerBuilder builder2;
107 builder2.add_public_variable(FF(1));
108 create_function_circuit(builder2);
109
110 auto prover_inst_1 = std::make_shared<InnerProverInstance>(builder1);
111 auto honk_vk_1 = std::make_shared<InnerVerificationKey>(prover_inst_1->get_precomputed());
112 auto verifier_inst_1 = std::make_shared<InnerVerifierInstance>(honk_vk_1);
113 auto prover_inst_2 = std::make_shared<InnerProverInstance>(builder2);
114 auto honk_vk_2 = std::make_shared<InnerVerificationKey>(prover_inst_2->get_precomputed());
115 auto verifier_inst_2 = std::make_shared<InnerVerifierInstance>(honk_vk_2);
116 // Generate a folding proof
117 InnerFoldingProver folding_prover({ prover_inst_1, prover_inst_2 },
118 { verifier_inst_1, verifier_inst_2 },
120 auto folding_proof = folding_prover.prove();
121
122 // Create a folding verifier circuit
123 OuterBuilder folding_circuit;
124
125 auto recursive_verifier_inst_1 = std::make_shared<RecursiveVerifierInstance>(&folding_circuit, verifier_inst_1);
126 auto recursive_vk_and_hash_2 = std::make_shared<RecursiveVKAndHash>(folding_circuit, verifier_inst_2->vk);
127 stdlib::Proof<OuterBuilder> stdlib_proof(folding_circuit, folding_proof.proof);
128
130 auto verifier = FoldingRecursiveVerifier{
131 &folding_circuit, recursive_verifier_inst_1, recursive_vk_and_hash_2, recursive_transcript
132 };
134 for (size_t idx = 0; idx < num_verifiers; idx++) {
135 verifier.transcript->enable_manifest();
136 accumulator = verifier.verify_folding_proof(stdlib_proof);
137 if (idx < num_verifiers - 1) { // else the transcript is null in the test below
138 auto recursive_vk_and_hash = std::make_shared<RecursiveVKAndHash>(folding_circuit, verifier_inst_1->vk);
139 verifier = FoldingRecursiveVerifier{
140 &folding_circuit, accumulator, recursive_vk_and_hash, recursive_transcript
141 };
142 }
143 }
144 {
146 // inefficiently check finalized size
147 folding_circuit.finalize_circuit(/* ensure_nonzero= */ true);
148 info("Folding Recursive Verifier: num gates finalized = ", folding_circuit.num_gates);
149 auto decider_pk = std::make_shared<OuterProverInstance>(folding_circuit);
150 info("Dyadic size of verifier circuit: ", decider_pk->dyadic_size());
151 auto honk_vk = std::make_shared<typename OuterFlavor::VerificationKey>(decider_pk->get_precomputed());
152 OuterProver prover(decider_pk, honk_vk);
153 OuterVerifier verifier(honk_vk);
154 auto proof = prover.construct_proof();
155 bool verified = verifier.template verify_proof<bb::DefaultIO>(proof).result;
156
157 ASSERT_TRUE(verified);
158 }
159 EXPECT_EQ(folding_circuit.failed(), false) << folding_circuit.err();
160 auto graph = cdg::MegaStaticAnalyzer(folding_circuit);
161 auto variables_in_one_gate = graph.get_variables_in_one_gate();
162 EXPECT_EQ(variables_in_one_gate.size(), 0);
163 auto connected_components = graph.find_connected_components(/*return_all_connected_components==*/false);
164 EXPECT_EQ(connected_components.size(), 1);
165 if (connected_components.size() > 1) {
166 graph.print_connected_components_info();
167 }
168 }
169
171 {
172 // Create two arbitrary circuits for the first round of folding
173 InnerBuilder builder1;
174 create_function_circuit(builder1);
175 InnerBuilder builder2;
176 builder2.add_public_variable(FF(1));
177 create_function_circuit(builder2);
178
179 auto prover_inst_1 = std::make_shared<InnerProverInstance>(builder1);
180 auto honk_vk_1 = std::make_shared<InnerVerificationKey>(prover_inst_1->get_precomputed());
181 auto verifier_inst_1 = std::make_shared<InnerVerifierInstance>(honk_vk_1);
182 auto prover_inst_2 = std::make_shared<InnerProverInstance>(builder2);
183 auto honk_vk_2 = std::make_shared<InnerVerificationKey>(prover_inst_2->get_precomputed());
184 auto verifier_inst_2 = std::make_shared<InnerVerifierInstance>(honk_vk_2);
185 // Generate a folding proof
186 InnerFoldingProver folding_prover({ prover_inst_1, prover_inst_2 },
187 { verifier_inst_1, verifier_inst_2 },
189 auto folding_proof = folding_prover.prove();
190
191 // Create a folding verifier circuit
192 OuterBuilder folding_circuit;
193 auto recursive_verifier_inst_1 = std::make_shared<RecursiveVerifierInstance>(&folding_circuit, verifier_inst_1);
194 auto recursive_vk_and_hash_2 = std::make_shared<RecursiveVKAndHash>(folding_circuit, verifier_inst_2->vk);
195 stdlib::Proof<OuterBuilder> stdlib_proof(folding_circuit, folding_proof.proof);
196
197 auto verifier = FoldingRecursiveVerifier{ &folding_circuit,
198 recursive_verifier_inst_1,
199 recursive_vk_and_hash_2,
201 verifier.transcript->enable_manifest();
202 auto recursive_verifier_native_accum = verifier.verify_folding_proof(stdlib_proof);
203 auto native_verifier_acc =
204 std::make_shared<InnerVerifierInstance>(recursive_verifier_native_accum->get_value());
205
206 // Perform native folding verification and ensure it returns the same result (either true or false) as
207 // calling check_circuit on the recursive folding verifier
208 InnerFoldingVerifier native_folding_verifier({ verifier_inst_1, verifier_inst_2 },
210 native_folding_verifier.transcript->enable_manifest();
211 auto verifier_accumulator = native_folding_verifier.verify_folding_proof(folding_proof.proof);
212
213 auto native_decider_transcript = std::make_shared<typename InnerFlavor::Transcript>();
214 auto native_accum_hash = verifier_accumulator->hash_through_transcript("", *native_decider_transcript);
215 native_decider_transcript->add_to_hash_buffer("accum_hash", native_accum_hash);
216
217 InnerDeciderProver decider_prover(folding_proof.accumulator, native_decider_transcript);
218 decider_prover.construct_proof();
219 auto decider_proof = decider_prover.export_proof();
220
221 OuterBuilder decider_circuit;
222
223 auto stdlib_verifier_acc = std::make_shared<RecursiveVerifierInstance>(&decider_circuit, native_verifier_acc);
224 auto stdlib_verifier_transcript = std::make_shared<typename RecursiveFlavor::Transcript>();
225 auto stdlib_accum_hash = stdlib_verifier_acc->hash_through_transcript("", *stdlib_verifier_transcript);
226
227 // Manually hashing the accumulator to ensure it gets a proper origin tag
228 stdlib_verifier_transcript->add_to_hash_buffer("accum_hash", stdlib_accum_hash);
229 DeciderRecursiveVerifier decider_verifier{ &decider_circuit, stdlib_verifier_acc, stdlib_verifier_transcript };
230 auto pairing_points = decider_verifier.verify_proof(decider_proof);
231
232 // IO
234 inputs.pairing_inputs = pairing_points;
235 inputs.set_public();
236
237 info("Decider Recursive Verifier: num gates = ", decider_circuit.num_gates);
238 // Check for a failure flag in the recursive verifier circuit
239 EXPECT_EQ(decider_circuit.failed(), false) << decider_circuit.err();
240 auto graph = cdg::MegaStaticAnalyzer(decider_circuit);
241 auto variables_in_one_gate = graph.get_variables_in_one_gate();
242 EXPECT_EQ(variables_in_one_gate.size(), 0);
243 auto connected_components = graph.find_connected_components(/*return_all_connected_components==*/false);
244 EXPECT_EQ(connected_components.size(), 1);
245 if (variables_in_one_gate.size() > 0) {
246 for (const auto& elem : variables_in_one_gate) {
247 info("elem == ", elem);
248 }
249 }
250 };
251};
252
253TEST_F(BoomerangProtogalaxyRecursiveTests, RecursiveFoldingTestOneVerifier)
254{
256}
257
258TEST_F(BoomerangProtogalaxyRecursiveTests, RecursiveFoldingTestTwoVerifiers)
259{
261}
262
267} // namespace bb::stdlib::recursion::honk
virtual uint32_t add_public_variable(const FF &in)
The verification key is responsible for storing the commitments to the precomputed (non-witness) poly...
Curve::ScalarField FF
MegaCircuitBuilder CircuitBuilder
Curve::AffineElement Commitment
The recursive counterpart to the "native" Mega flavor.
BB_PROFILE FoldingResult< Flavor > prove()
Execute the folding prover.
std::shared_ptr< Transcript > transcript
A ProverInstance is normally constructed from a finalized circuit and it contains all the information...
The VerifierInstance encapsulates all the necessary information for a Mega Honk Verifier to verify a ...
static byte_array_ct hash(const byte_array_ct &input)
Definition blake3s.cpp:183
A simple wrapper around a vector of stdlib field elements representing a proof.
Definition proof.hpp:19
Represents a dynamic array of bytes in-circuit.
static field_ct hash(const std::vector< field_ct > &in, GeneratorContext context={})
Computes a pedersen hash of the provided inputs.
Definition pedersen.cpp:29
static void create_function_circuit(InnerBuilder &builder, size_t log_num_gates=10)
std::conditional_t< IsMegaBuilder< OuterBuilder >, MegaFlavor, UltraFlavor > OuterFlavor
PairingPoints verify_proof(const HonkProof &proof)
Creates a circuit that executes the decider verifier algorithm up to the final pairing check.
Manages the data that is propagated on the public inputs of an application/function circuit.
void set_public()
Set each IO component to be a public input of the underlying circuit.
static void add_default(Builder &builder)
Add default public inputs when they are not present.
The stdlib counterpart of VerifierInstance, used in recursive folding verification.
void info(Args... args)
Definition log.hpp:74
AluTraceBuilder builder
Definition alu.test.cpp:123
FF a
FF b
bn254::ScalarField fr_ct
bn254::BaseField fq_ct
bn254::public_witness_ct public_witness_ct
bn254::witness_ct witness_ct
RNG & get_debug_randomness(bool reset, std::uint_fast64_t seed)
Definition engine.cpp:190
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.
field< Bn254FrParams > fr
Definition fr.hpp:174
StaticAnalyzer_< bb::fr, bb::MegaCircuitBuilder > MegaStaticAnalyzer
Definition graph.hpp:183
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13
static field random_element(numeric::RNG *engine=nullptr) noexcept
field_t< CircuitBuilder > ScalarField
Definition bn254.hpp:33
byte_array< CircuitBuilder > byte_array_ct
Definition bn254.hpp:43
curve::BN254::ScalarField ScalarFieldNative
Definition bn254.hpp:24
public_witness_t< CircuitBuilder > public_witness_ct
Definition bn254.hpp:42
witness_t< CircuitBuilder > witness_ct
Definition bn254.hpp:41
static void add_default_to_public_inputs(Builder &builder)
Adds default public inputs to the builder.