Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
client_ivc.cpp
Go to the documentation of this file.
1// === AUDIT STATUS ===
2// internal: { status: not started, auditors: [], date: YYYY-MM-DD }
3// external_1: { status: not started, auditors: [], date: YYYY-MM-DD }
4// external_2: { status: not started, auditors: [], date: YYYY-MM-DD }
5// =====================
6
15
16namespace bb {
17
18// Constructor
19ClientIVC::ClientIVC(size_t num_circuits, TraceSettings trace_settings)
20 : trace_usage_tracker(trace_settings)
21 , num_circuits(num_circuits)
22 , trace_settings(trace_settings)
23 , goblin(bn254_commitment_key)
24{
25 BB_ASSERT_GT(num_circuits, 0UL, "Number of circuits must be specified and greater than 0.");
26 // Allocate BN254 commitment key based on the max dyadic Mega structured trace size and translator circuit size.
27 // https://github.com/AztecProtocol/barretenberg/issues/1319): Account for Translator only when it's necessary
28 size_t commitment_key_size =
30 info("BN254 commitment key size: ", commitment_key_size);
32}
33
45 ClientCircuit& circuit, const std::vector<std::shared_ptr<RecursiveVKAndHash>>& input_keys)
46{
47 bool vkeys_provided = !input_keys.empty();
48 if (vkeys_provided) {
50 input_keys.size(),
51 "Incorrect number of verification keys provided in "
52 "stdlib verification queue instantiation.");
53 }
54
55 size_t key_idx = 0;
56 while (!verification_queue.empty()) {
57 const VerifierInputs& entry = verification_queue.front();
58
59 // Construct stdlib proof directly from the internal native queue data
60 StdlibProof stdlib_proof(circuit, entry.proof);
61
62 // Use the provided stdlib vkey if present, otherwise construct one from the internal native queue
63 std::shared_ptr<RecursiveVKAndHash> stdlib_vk_and_hash;
64 if (vkeys_provided) {
65 stdlib_vk_and_hash = input_keys[key_idx++];
66 } else {
67 stdlib_vk_and_hash = std::make_shared<RecursiveVKAndHash>(circuit, entry.honk_vk);
68 }
69
70 stdlib_verification_queue.emplace_back(stdlib_proof, stdlib_vk_and_hash, entry.type, entry.is_kernel);
71
72 verification_queue.pop_front(); // the native data is not needed beyond this point
73 }
74}
75
77 ClientCircuit& circuit,
80 const StdlibProof& proof)
81{
82 OinkRecursiveVerifier verifier{ &circuit, verifier_instance, transcript };
83 verifier.verify_proof(proof);
84
85 verifier_instance->target_sum = StdlibFF::from_witness_index(&circuit, circuit.zero_idx);
86 // Get the gate challenges for sumcheck/combiner computation
87 verifier_instance->gate_challenges =
88 transcript->template get_powers_of_challenge<StdlibFF>("gate_challenge", CONST_PG_LOG_N);
89
90 return verifier_instance;
91}
92
94 ClientCircuit& circuit,
95 const std::shared_ptr<RecursiveDeciderVerificationKey>& verifier_accumulator,
98 const StdlibProof& proof,
99 std::optional<StdlibFF>& prev_accum_hash,
100 bool is_kernel)
101{
102 BB_ASSERT_NEQ(verifier_accumulator, nullptr, "verifier_accumulator cannot be null in PG recursive verification");
103
104 // Fiat-Shamir the accumulator. (Only needs to be performed on the first in a series of recursive PG verifications
105 // within a given kernel and by convention the kernel proof is always verified first).
106 if (is_kernel) {
107 prev_accum_hash = verifier_accumulator->hash_through_transcript("", *transcript);
108 transcript->add_to_hash_buffer("accum_hash", *prev_accum_hash);
109 info("Previous accumulator hash in PG rec verifier: ", *prev_accum_hash);
110 }
111 // Perform folding recursive verification to update the verifier accumulator
112 FoldingRecursiveVerifier verifier{ &circuit, verifier_accumulator, verifier_instance, transcript };
113 auto updated_verifier_accumulator = verifier.verify_folding_proof(proof);
114
115 return updated_verifier_accumulator;
116}
117
140 ClientCircuit& circuit,
141 const StdlibVerifierInputs& verifier_inputs,
142 const std::shared_ptr<ClientIVC::RecursiveDeciderVerificationKey>& input_verifier_accumulator,
143 const TableCommitments& T_prev_commitments,
144 const std::shared_ptr<RecursiveTranscript>& accumulation_recursive_transcript)
145{
147
148 // The pairing points produced by the verification of the decider proof
149 PairingPoints decider_pairing_points;
150
151 // Input commitments to be passed to the merge recursive verification
152 MergeCommitments merge_commitments{ .T_prev_commitments = T_prev_commitments };
153
154 auto verifier_instance =
156
158 std::optional<StdlibFF> prev_accum_hash = std::nullopt;
159 // The decider proof exists if the tail kernel has been accumulated
160 bool is_hiding_kernel = !decider_proof.empty();
161
162 switch (verifier_inputs.type) {
163 case QUEUE_TYPE::OINK: {
164 BB_ASSERT_EQ(input_verifier_accumulator, nullptr);
165
166 output_verifier_accumulator = perform_oink_recursive_verification(
167 circuit, verifier_instance, accumulation_recursive_transcript, verifier_inputs.proof);
168
169 // T_prev = 0 in the first recursive verification
170 merge_commitments.T_prev_commitments = stdlib::recursion::honk::empty_ecc_op_tables(circuit);
171 break;
172 }
173 case QUEUE_TYPE::PG:
174 case QUEUE_TYPE::PG_TAIL: {
175 BB_ASSERT_NEQ(input_verifier_accumulator, nullptr);
176
177 output_verifier_accumulator = perform_pg_recursive_verification(circuit,
178 input_verifier_accumulator,
179 verifier_instance,
180 accumulation_recursive_transcript,
181 verifier_inputs.proof,
182 prev_accum_hash,
183 verifier_inputs.is_kernel);
184 break;
185 }
187 BB_ASSERT_NEQ(input_verifier_accumulator, nullptr);
188 BB_ASSERT_EQ(stdlib_verification_queue.size(), size_t(1));
189
191
192 // Propagate the public inputs of the tail kernel by converting them to public inputs of the hiding circuit.
193 auto num_public_inputs = static_cast<size_t>(honk_vk->num_public_inputs);
194 num_public_inputs -= KernelIO::PUBLIC_INPUTS_SIZE; // exclude fixed kernel_io public inputs
195 for (size_t i = 0; i < num_public_inputs; i++) {
196 verifier_inputs.proof[i].set_public();
197 }
198
199 auto final_verifier_accumulator = perform_pg_recursive_verification(circuit,
200 input_verifier_accumulator,
201 verifier_instance,
202 accumulation_recursive_transcript,
203 verifier_inputs.proof,
204 prev_accum_hash,
205 verifier_inputs.is_kernel);
206 // Perform recursive decider verification
207 DeciderRecursiveVerifier decider{ &circuit, final_verifier_accumulator, accumulation_recursive_transcript };
208 decider_pairing_points = decider.verify_proof(decider_proof);
209
210 BB_ASSERT_EQ(output_verifier_accumulator, nullptr);
211 break;
212 }
213 default: {
214 throw_or_abort("Invalid queue type! Only OINK, PG, PG_TAIL and PG_FINAL are supported");
215 }
216 }
217
218 // Extract the witness commitments and public inputs from the incoming verifier instance
219 WitnessCommitments witness_commitments = std::move(verifier_instance->witness_commitments);
220 std::vector<StdlibFF> public_inputs = std::move(verifier_instance->public_inputs);
221
222 PairingPoints nested_pairing_points; // to be extracted from public inputs of app or kernel proof just verified
223
224 if (verifier_inputs.is_kernel) {
225 // Reconstruct the input from the previous kernel from its public inputs
226 KernelIO kernel_input; // pairing points, databus return data commitments
227 kernel_input.reconstruct_from_public(public_inputs);
228 nested_pairing_points = kernel_input.pairing_inputs;
229 // Perform databus consistency checks
230 kernel_input.kernel_return_data.assert_equal(witness_commitments.calldata);
231 kernel_input.app_return_data.assert_equal(witness_commitments.secondary_calldata);
232
233 // T_prev is read by the public input of the previous kernel K_{i-1} at the beginning of the recursive
234 // verification of of the folding of K_{i-1} (kernel), A_{i,1} (app), .., A_{i, n} (app). This verification
235 // happens in K_{i}
236 merge_commitments.T_prev_commitments = std::move(kernel_input.ecc_op_tables);
237
238 BB_ASSERT_EQ(verifier_inputs.type == QUEUE_TYPE::PG || verifier_inputs.type == QUEUE_TYPE::PG_TAIL ||
239 verifier_inputs.type == QUEUE_TYPE::PG_FINAL,
240 true,
241 "Kernel circuits should be folded.");
242 // Get the previous accum hash
243 info("PG accum hash from IO: ", kernel_input.output_pg_accum_hash);
244 ASSERT(prev_accum_hash.has_value());
245 kernel_input.output_pg_accum_hash.assert_equal(*prev_accum_hash);
246
247 if (!is_hiding_kernel) {
248 // The hiding kernel has no return data but uses the traditional public-inputs mechanism
249 bus_depot.set_kernel_return_data_commitment(witness_commitments.return_data);
250 }
251 } else {
252 // Reconstruct the input from the previous app from its public inputs
253 AppIO app_input; // pairing points
254 app_input.reconstruct_from_public(public_inputs);
255 nested_pairing_points = app_input.pairing_inputs;
256
257 // Set the app return data commitment to be propagated via the public inputs
258 bus_depot.set_app_return_data_commitment(witness_commitments.return_data);
259 }
260
261 // Extract the commitments to the subtable corresponding to the incoming circuit
262 merge_commitments.t_commitments = witness_commitments.get_ecc_op_wires().get_copy();
263
264 // Recursively verify the corresponding merge proof
265 auto [pairing_points, merged_table_commitments] =
266 goblin.recursively_verify_merge(circuit, merge_commitments, accumulation_recursive_transcript);
267
268 pairing_points.aggregate(nested_pairing_points);
269 if (is_hiding_kernel) {
270 pairing_points.aggregate(decider_pairing_points);
271 }
272
273 return { output_verifier_accumulator, pairing_points, merged_table_commitments };
274}
275
285{
286
287 // Transcript to be shared shared across recursive verification of the folding of K_{i-1} (kernel), A_{i,1} (app),
288 // .., A_{i, n} (app) (all circuits accumulated between the previous kernel and current one)
289 auto accumulation_recursive_transcript = std::make_shared<RecursiveTranscript>();
290
291 // Commitment to the previous state of the op_queue in the recursive verification
292 TableCommitments T_prev_commitments;
293
294 // Instantiate stdlib verifier inputs from their native counterparts
295 if (stdlib_verification_queue.empty()) {
297 }
298
299 bool is_init_kernel =
301
302 bool is_tail_kernel =
304
305 bool is_hiding_kernel =
307
308 // The ECC-op subtable for a kernel begins with an eq-and-reset to ensure that the preceeding circuit's subtable
309 // cannot affect the ECC-op accumulator for the kernel. For the tail kernel, we additionally add a preceeding no-op
310 // to ensure the op queue wires in translator are shiftable, i.e. their 0th coefficient is 0. (The tail kernel
311 // subtable is at the top of the final aggregate table since it is the last to be prepended).
312 if (is_tail_kernel) {
313 circuit.queue_ecc_no_op();
314 }
315 circuit.queue_ecc_eq();
316
317 // Perform Oink/PG and Merge recursive verification + databus consistency checks for each entry in the queue
318 PairingPoints points_accumulator;
319 std::shared_ptr<RecursiveDeciderVerificationKey> current_stdlib_verifier_accumulator = nullptr;
320 if (!is_init_kernel) {
321 current_stdlib_verifier_accumulator =
323 }
324 while (!stdlib_verification_queue.empty()) {
325 const StdlibVerifierInputs& verifier_input = stdlib_verification_queue.front();
326
327 auto [output_stdlib_verifier_accumulator, pairing_points, merged_table_commitments] =
329 verifier_input,
330 current_stdlib_verifier_accumulator,
331 T_prev_commitments,
332 accumulation_recursive_transcript);
333 points_accumulator.aggregate(pairing_points);
334 // Update commitment to the status of the op_queue
335 T_prev_commitments = merged_table_commitments;
336 // Update the output verifier accumulator
337 current_stdlib_verifier_accumulator = output_stdlib_verifier_accumulator;
338
339 stdlib_verification_queue.pop_front();
340 }
341 // Set the kernel output data to be propagated via the public inputs
342 if (is_hiding_kernel) {
343 BB_ASSERT_EQ(current_stdlib_verifier_accumulator, nullptr);
344 HidingKernelIO hiding_output{ points_accumulator, T_prev_commitments };
345 hiding_output.set_public();
346 } else {
347 BB_ASSERT_NEQ(current_stdlib_verifier_accumulator, nullptr);
348 // Extract native verifier accumulator from the stdlib accum for use on the next round
350 std::make_shared<DeciderVerificationKey>(current_stdlib_verifier_accumulator->get_value());
351
352 KernelIO kernel_output;
353 kernel_output.pairing_inputs = points_accumulator;
356 kernel_output.ecc_op_tables = T_prev_commitments;
357 RecursiveTranscript hash_transcript;
358 kernel_output.output_pg_accum_hash =
359 current_stdlib_verifier_accumulator->hash_through_transcript("", hash_transcript);
360 info("kernel output pg hash: ", kernel_output.output_pg_accum_hash);
361 kernel_output.set_public();
362 }
363}
364
367 const std::shared_ptr<Transcript>& transcript)
368{
369 vinfo("computing oink proof...");
370 MegaOinkProver oink_prover{ proving_key, honk_vk, transcript };
371 oink_prover.prove();
372
373 proving_key->target_sum = 0;
374 // Get the gate challenges for sumcheck/combiner computation
375 proving_key->gate_challenges =
376 prover_accumulation_transcript->template get_powers_of_challenge<FF>("gate_challenge", CONST_PG_LOG_N);
377
378 fold_output.accumulator = proving_key; // initialize the prover accum with the completed key
379
380 HonkProof oink_proof = oink_prover.export_proof();
381 vinfo("oink proof constructed");
382 return oink_proof;
383}
384
387 const std::shared_ptr<Transcript>& transcript,
388 bool is_kernel)
389{
390 vinfo("computing pg proof...");
391 // Only fiat shamir if this is a kernel with the assumption that kernels are always the first being recursively
392 // verified.
393 if (is_kernel) {
394 // Fiat-Shamir the verifier accumulator
395 FF accum_hash = native_verifier_accum->hash_through_transcript("", *prover_accumulation_transcript);
396 prover_accumulation_transcript->add_to_hash_buffer("accum_hash", accum_hash);
397 info("Accumulator hash in PG prover: ", accum_hash);
398 }
400 FoldingProver folding_prover({ fold_output.accumulator, proving_key },
401 { native_verifier_accum, verifier_instance },
404 fold_output = folding_prover.prove();
405 vinfo("pg proof constructed");
406 return fold_output.proof;
407}
408
413{
414 // first app
415 if (num_circuits_accumulated == 0) {
416 return QUEUE_TYPE::OINK;
417 }
418 // app (excluding first) or kernel (inner or reset)
420 return QUEUE_TYPE::PG;
421 }
422 // last kernel prior to tail kernel
424 return QUEUE_TYPE::PG_TAIL;
425 }
426 // tail kernel
429 }
430 // hiding kernel
432 return QUEUE_TYPE::MEGA;
433 }
434 return QUEUE_TYPE{};
435}
436
448{
450 num_circuits_accumulated, num_circuits, "ClientIVC: Attempting to accumulate more circuits than expected.");
451
452 ASSERT(precomputed_vk != nullptr, "ClientIVC::accumulate - VK expected for the provided circuit");
453
454 // Construct the proving key for circuit
456
457 // If the current circuit overflows past the current size of the commitment key, reinitialize accordingly.
458 // TODO(https://github.com/AztecProtocol/barretenberg/issues/1319)
459 if (proving_key->dyadic_size() > bn254_commitment_key.dyadic_size) {
460 bn254_commitment_key = CommitmentKey<curve::BN254>(proving_key->dyadic_size());
462 }
463 proving_key->commitment_key = bn254_commitment_key;
465
466 honk_vk = precomputed_vk;
467
468 // We're accumulating a kernel if the verification queue is empty (because the kernel circuit contains recursive
469 // verifiers for all the entries previously present in the verification queue) and if it's not the first accumulate
470 // call (which will always be for an app circuit).
471 bool is_kernel = verification_queue.empty() && num_circuits_accumulated > 0;
472
473 // Transcript to be shared across folding of K_{i} (kernel) (the current kernel), A_{i+1,1} (app), .., A_{i+1,
474 // n} (app)
475 if (is_kernel) {
477 }
478
479 // make a copy of the prover_accumulation_transcript for the verifier to use
480 auto verifier_transcript =
482
483 QUEUE_TYPE queue_type = get_queue_type();
484 HonkProof proof;
485 switch (queue_type) {
486 case QUEUE_TYPE::OINK:
487 vinfo("Accumulating first app circuit with OINK");
488 BB_ASSERT_EQ(is_kernel, false, "First circuit accumulated must always be an app");
490 break;
491 case QUEUE_TYPE::PG:
493 proof = construct_pg_proof(proving_key, honk_vk, prover_accumulation_transcript, is_kernel);
494 break;
496 proof = construct_pg_proof(proving_key, honk_vk, prover_accumulation_transcript, is_kernel);
498 break;
499 case QUEUE_TYPE::MEGA:
501 break;
502 }
503
504 VerifierInputs queue_entry{ std::move(proof), honk_vk, queue_type, is_kernel };
505 verification_queue.push_back(queue_entry);
506
507 // Update native verifier accumulator and construct merge proof (excluded for hiding kernel since PG terminates with
508 // tail kernel and hiding merge proof is constructed as part of goblin proving)
509 if (queue_entry.type != QUEUE_TYPE::MEGA) {
510 update_native_verifier_accumulator(queue_entry, verifier_transcript);
512 }
513
515}
516
529{
530 Point random_point = Point::random_element();
531 FF random_scalar = FF::random_element();
532 circuit.queue_ecc_mul_accum(random_point, random_scalar);
533 circuit.queue_ecc_eq();
534}
535
543{
544 // Note: a structured trace is not used for the hiding kernel
546 honk_vk = std::make_shared<MegaZKVerificationKey>(hiding_decider_pk->get_precomputed());
547 auto& hiding_circuit_vk = honk_vk;
548 // Hiding circuit is proven by a MegaZKProver
549 MegaZKProver prover(hiding_decider_pk, hiding_circuit_vk, transcript);
550 HonkProof proof = prover.construct_proof();
551
552 return proof;
553}
554
561{
562 // deallocate the protogalaxy accumulator
563 fold_output.accumulator = nullptr;
564 auto mega_proof = verification_queue.front().proof;
565
566 // A transcript is shared between the Hiding circuit prover and the Goblin prover
568
569 // Returns a proof for the hiding circuit and the Goblin proof. The latter consists of Translator and ECCVM proof
570 // for the whole ecc op table and the merge proof for appending the subtable coming from the hiding circuit. The
571 // final merging is done via appending to facilitate creating a zero-knowledge merge proof. This enables us to add
572 // randomness to the beginning of the tail kernel and the end of the hiding kernel, hiding the commitments and
573 // evaluations of both the previous table and the incoming subtable.
574 // https://github.com/AztecProtocol/barretenberg/issues/1360
575 return { mega_proof, goblin.prove(MergeSettings::APPEND) };
576};
577
578bool ClientIVC::verify(const Proof& proof, const VerificationKey& vk)
579{
581 // Create a transcript to be shared by MegaZK-, Merge-, ECCVM-, and Translator- Verifiers.
583 // Verify the hiding circuit proof
584 MegaZKVerifier verifier{ vk.mega, /*ipa_verification_key=*/{}, civc_verifier_transcript };
585 auto [mega_verified, T_prev_commitments] = verifier.template verify_proof<bb::HidingKernelIO>(proof.mega_proof);
586 vinfo("Mega verified: ", mega_verified);
587 // Extract the commitments to the subtable corresponding to the incoming circuit
588 TableCommitments t_commitments = verifier.verification_key->witness_commitments.get_ecc_op_wires().get_copy();
589
590 // Goblin verification (final merge, eccvm, translator)
591 bool goblin_verified = Goblin::verify(
592 proof.goblin_proof, { t_commitments, T_prev_commitments }, civc_verifier_transcript, MergeSettings::APPEND);
593 vinfo("Goblin verified: ", goblin_verified);
594
595 // TODO(https://github.com/AztecProtocol/barretenberg/issues/1396): State tracking in CIVC verifiers.
596 return goblin_verified && mega_verified;
597}
598
605bool ClientIVC::verify(const Proof& proof) const
606{
607 return verify(proof, get_vk());
608}
609
615HonkProof ClientIVC::construct_decider_proof(const std::shared_ptr<Transcript>& transcript)
616{
617 vinfo("prove decider...");
620 decider_prover.construct_proof();
621 return decider_prover.export_proof();
622}
623
631{
632 auto start = std::chrono::steady_clock::now();
633 const auto proof = prove();
634 auto end = std::chrono::steady_clock::now();
635 auto diff = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
636 vinfo("time to call ClientIVC::prove: ", diff.count(), " ms.");
637
638 start = end;
639 const bool verified = verify(proof);
640 end = std::chrono::steady_clock::now();
641
642 diff = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
643 vinfo("time to verify ClientIVC proof: ", diff.count(), " ms.");
644
645 return verified;
646}
647
648// Proof methods
650{
651 return mega_proof.size() + goblin_proof.size();
652}
653
655{
656 HonkProof proof;
657
658 proof.insert(proof.end(), mega_proof.begin(), mega_proof.end());
659 proof.insert(proof.end(), goblin_proof.merge_proof.begin(), goblin_proof.merge_proof.end());
660 proof.insert(
661 proof.end(), goblin_proof.eccvm_proof.pre_ipa_proof.begin(), goblin_proof.eccvm_proof.pre_ipa_proof.end());
662 proof.insert(proof.end(), goblin_proof.eccvm_proof.ipa_proof.begin(), goblin_proof.eccvm_proof.ipa_proof.end());
663 proof.insert(proof.end(), goblin_proof.translator_proof.begin(), goblin_proof.translator_proof.end());
664
665 return proof;
666};
667
669{
670 msgpack::sbuffer buffer;
671 msgpack::pack(buffer, *this);
672 return buffer;
673}
674
676{
677 msgpack::sbuffer buffer = to_msgpack_buffer();
678
679 std::vector<uint8_t> buf(buffer.data(), buffer.data() + buffer.size());
680 return to_heap_buffer(buf);
681}
682
684{
685 auto uint8_buffer = from_buffer<std::vector<uint8_t>>(buffer);
686
687 msgpack::sbuffer sbuf;
688 sbuf.write(reinterpret_cast<char*>(uint8_buffer.data()), uint8_buffer.size());
689
690 return from_msgpack_buffer(sbuf);
691}
692
694{
695 msgpack::object_handle oh = msgpack::unpack(buffer.data(), buffer.size());
696 msgpack::object obj = oh.get();
697 Proof proof;
698 obj.convert(proof);
699 return proof;
700}
701
702void ClientIVC::Proof::to_file_msgpack(const std::string& filename) const
703{
704 msgpack::sbuffer buffer = to_msgpack_buffer();
705 std::ofstream ofs(filename, std::ios::binary);
706 if (!ofs.is_open()) {
707 throw_or_abort("Failed to open file for writing.");
708 }
709 ofs.write(buffer.data(), static_cast<std::streamsize>(buffer.size()));
710 ofs.close();
711}
712
714{
715 std::ifstream ifs(filename, std::ios::binary);
716 if (!ifs.is_open()) {
717 throw_or_abort("Failed to open file for reading.");
718 }
719
720 ifs.seekg(0, std::ios::end);
721 size_t file_size = static_cast<size_t>(ifs.tellg());
722 ifs.seekg(0, std::ios::beg);
723
724 std::vector<char> buffer(file_size);
725 ifs.read(buffer.data(), static_cast<std::streamsize>(file_size));
726 ifs.close();
727 msgpack::sbuffer msgpack_buffer;
728 msgpack_buffer.write(buffer.data(), file_size);
729
730 return Proof::from_msgpack_buffer(msgpack_buffer);
731}
732
733// VerificationKey construction
738
740 const std::shared_ptr<Transcript>& verifier_transcript)
741{
742 auto decider_vk = std::make_shared<DeciderVerificationKey>(queue_entry.honk_vk);
743 if (queue_entry.type == QUEUE_TYPE::OINK) {
744 verifier_transcript->load_proof(queue_entry.proof);
745 OinkVerifier<Flavor> oink_verifier{ decider_vk, verifier_transcript };
746 oink_verifier.verify();
747 native_verifier_accum = decider_vk;
748 native_verifier_accum->target_sum = 0;
749 // Get the gate challenges for sumcheck/combiner computation
750 native_verifier_accum->gate_challenges =
751 verifier_transcript->template get_powers_of_challenge<FF>("gate_challenge", CONST_PG_LOG_N);
752 } else {
753 if (queue_entry.is_kernel) {
754 // Fiat-Shamir the verifier accumulator
755 FF accum_hash = native_verifier_accum->hash_through_transcript("", *verifier_transcript);
756 verifier_transcript->add_to_hash_buffer("accum_hash", accum_hash);
757 info("Accumulator hash in PG verifier: ", accum_hash);
758 }
759 FoldingVerifier folding_verifier({ native_verifier_accum, decider_vk }, verifier_transcript);
760 native_verifier_accum = folding_verifier.verify_folding_proof(queue_entry.proof);
761 }
762}
763
764} // namespace bb
#define BB_ASSERT_GT(left, right,...)
Definition assert.hpp:87
#define BB_ASSERT_NEQ(actual, expected,...)
Definition assert.hpp:73
#define BB_ASSERT_EQ(actual, expected,...)
Definition assert.hpp:59
#define BB_ASSERT_LT(left, right,...)
Definition assert.hpp:115
#define ASSERT(expression,...)
Definition assert.hpp:49
Common transcript class for both parties. Stores the data for the current round, as well as the manif...
static std::shared_ptr< BaseTranscript > convert_prover_transcript_to_verifier_transcript(const std::shared_ptr< BaseTranscript > &prover_transcript)
Convert a prover transcript to a verifier transcript.
Proof prove()
Construct a proof for the IVC, which, if verified, fully establishes its correctness.
static void hide_op_queue_accumulation_result(ClientCircuit &circuit)
Add a random operation to the op queue to hide its content in Translator computation.
MegaFlavor::CommitmentKey bn254_commitment_key
HonkProof construct_oink_proof(const std::shared_ptr< DeciderProvingKey > &proving_key, const std::shared_ptr< MegaVerificationKey > &honk_vk, const std::shared_ptr< Transcript > &transcript)
TraceSettings trace_settings
std::shared_ptr< Transcript > prover_accumulation_transcript
ExecutionTraceUsageTracker trace_usage_tracker
HonkProof construct_decider_proof(const std::shared_ptr< Transcript > &transcript)
Internal method for constructing a decider proof.
std::shared_ptr< DeciderVerificationKey > recursive_verifier_native_accum
bool prove_and_verify()
Construct and verify a proof for the IVC.
QUEUE_TYPE get_queue_type() const
Get queue type for the proof of a circuit about to be accumulated based on num circuits accumulated s...
VerificationKey get_vk() const
size_t num_circuits
void accumulate(ClientCircuit &circuit, const std::shared_ptr< MegaVerificationKey > &precomputed_vk)
Perform prover work for accumulation (e.g. PG folding, merge proving)
void complete_kernel_circuit_logic(ClientCircuit &circuit)
Append logic to complete a kernel circuit.
Flavor::Curve::AffineElement Point
HonkProof construct_pg_proof(const std::shared_ptr< DeciderProvingKey > &proving_key, const std::shared_ptr< MegaVerificationKey > &honk_vk, const std::shared_ptr< Transcript > &transcript, bool is_kernel)
size_t num_circuits_accumulated
void update_native_verifier_accumulator(const VerifierInputs &queue_entry, const std::shared_ptr< Transcript > &verifier_transcript)
Runs either Oink or PG native verifier to update the native verifier accumulator.
ClientIVC(size_t num_circuits, TraceSettings trace_settings={})
static std::shared_ptr< RecursiveDeciderVerificationKey > perform_pg_recursive_verification(ClientCircuit &circuit, const std::shared_ptr< RecursiveDeciderVerificationKey > &verifier_accumulator, const std::shared_ptr< RecursiveDeciderVerificationKey > &verifier_instance, const std::shared_ptr< RecursiveTranscript > &transcript, const StdlibProof &proof, std::optional< StdlibFF > &prev_accum_hash, bool is_kernel)
static std::shared_ptr< RecursiveDeciderVerificationKey > perform_oink_recursive_verification(ClientCircuit &circuit, const std::shared_ptr< RecursiveDeciderVerificationKey > &verifier_instance, const std::shared_ptr< RecursiveTranscript > &transcript, const StdlibProof &proof)
VerificationQueue verification_queue
std::tuple< std::shared_ptr< RecursiveDeciderVerificationKey >, PairingPoints, TableCommitments > perform_recursive_verification_and_databus_consistency_checks(ClientCircuit &circuit, const StdlibVerifierInputs &verifier_inputs, const std::shared_ptr< RecursiveDeciderVerificationKey > &input_verifier_accumulator, const TableCommitments &T_prev_commitments, const std::shared_ptr< RecursiveTranscript > &accumulation_recursive_transcript)
Populate the provided circuit with constraints for (1) recursive verification of the provided accumul...
StdlibVerificationQueue stdlib_verification_queue
HonkProof decider_proof
ProverFoldOutput fold_output
std::array< RecursiveFlavor::Commitment, ClientCircuit::NUM_WIRES > TableCommitments
std::shared_ptr< DeciderVerificationKey > native_verifier_accum
std::shared_ptr< Transcript > transcript
static bool verify(const Proof &proof, const VerificationKey &vk)
void instantiate_stdlib_verification_queue(ClientCircuit &circuit, const std::vector< std::shared_ptr< RecursiveVKAndHash > > &input_keys={})
Instantiate a stdlib verification queue for use in the kernel completion logic.
HonkProof construct_mega_proof_for_hiding_kernel(ClientCircuit &circuit)
Construct a zero-knowledge proof for the hiding circuit, which recursively verifies the last folding,...
std::shared_ptr< MegaVerificationKey > honk_vk
DataBusDepot bus_depot
stdlib::recursion::PairingPoints< ClientCircuit > PairingPoints
CommitmentKey object over a pairing group 𝔾₁.
static bool verify(const GoblinProof &proof, const MergeCommitments &merge_commitments, const std::shared_ptr< Transcript > &transcript, const MergeSettings merge_settings=MergeSettings::PREPEND)
Verify a full Goblin proof (ECCVM, Translator, merge)
Definition goblin.cpp:97
std::pair< PairingPoints, RecursiveTableCommitments > recursively_verify_merge(MegaBuilder &builder, const RecursiveMergeCommitments &merge_commitments, const std::shared_ptr< RecursiveTranscript > &transcript, const MergeSettings merge_settings=MergeSettings::PREPEND)
Recursively verify the next merge proof in the merge verification queue.
Definition goblin.cpp:77
MergeVerifier::TableCommitments TableCommitments
Definition goblin.hpp:41
void prove_merge(const std::shared_ptr< Transcript > &transcript=std::make_shared< Transcript >(), const MergeSettings merge_settings=MergeSettings::PREPEND)
Construct a merge proof for the goblin ECC ops in the provided circuit; append the proof to the merge...
Definition goblin.cpp:24
GoblinProof prove(const MergeSettings merge_settings=MergeSettings::PREPEND)
Constuct a full Goblin proof (ECCVM, Translator, merge)
Definition goblin.cpp:50
CommitmentKey< curve::BN254 > commitment_key
Definition goblin.hpp:49
std::shared_ptr< Transcript > transcript
Definition goblin.hpp:55
ecc_op_tuple queue_ecc_eq()
Add point equality operation to the op queue based on the value of the internal accumulator and add c...
ecc_op_tuple queue_ecc_mul_accum(const g1::affine_element &point, const FF &scalar)
Add point mul-then-accumulate operation to the op queue and add corresponding gates.
ecc_op_tuple queue_ecc_no_op()
Logic for a no-op operation.
Container for all witness polynomials used/constructed by the prover.
Class for all the oink rounds, which are shared between the folding prover and ultra prover.
void prove()
Oink Prover function that runs all the rounds of the verifier.
Verifier class for all the presumcheck rounds, which are shared between the folding verifier and ultr...
void verify()
Oink Verifier function that runs all the rounds of the verifier.
std::shared_ptr< DeciderVK > verify_folding_proof(const std::vector< FF > &)
Run the folding protocol on the verifier side to establish whether the public data ϕ of the new accum...
static constexpr size_t CONST_TRANSLATOR_LOG_N
Commitment get_kernel_return_data_commitment(Builder &builder)
Get the previously set kernel return data commitment if it exists, else a default one.
Definition databus.hpp:129
Commitment get_app_return_data_commitment(Builder &builder)
Get the previously set app return data commitment if it exists, else a default one.
Definition databus.hpp:142
void set_app_return_data_commitment(const Commitment &commitment)
Definition databus.hpp:106
void set_kernel_return_data_commitment(const Commitment &commitment)
Definition databus.hpp:100
Manages the data that is propagated on the public inputs of an application/function circuit.
void reconstruct_from_public(const std::vector< FF > &public_inputs)
Reconstructs the IO components from a public inputs array.
Manages the data that is propagated on the public inputs of a hiding kernel circuit.
Manages the data that is propagated on the public inputs of a kernel circuit.
void reconstruct_from_public(const std::vector< FF > &public_inputs)
Reconstructs the IO components from a public inputs array.
void set_public()
Set each IO component to be a public input of the underlying circuit.
void vinfo(Args... args)
Definition log.hpp:76
void info(Args... args)
Definition log.hpp:70
uint8_t const * buf
Definition data_store.hpp:9
uint8_t buffer[RANDOM_BUFFER_SIZE]
Definition engine.cpp:34
std::array< typename bn254< Builder >::Group, Builder::NUM_WIRES > empty_ecc_op_tables(Builder &builder)
Construct commitments to empty subtables.
Entry point for Barretenberg command-line interface.
std::vector< fr > HonkProof
Definition proof.hpp:15
VerifierCommitmentKey< Curve > vk
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13
uint8_t * to_heap_buffer(T const &value)
A full proof for the IVC scheme containing a Mega proof showing correctness of the hiding circuit (wh...
void to_file_msgpack(const std::string &filename) const
static Proof from_msgpack_buffer(uint8_t const *&buffer)
std::vector< FF > to_field_elements() const
Serialize proof to field elements.
uint8_t * to_msgpack_heap_buffer() const
Very quirky method to convert a msgpack buffer to a "heap" buffer.
size_t size() const
static Proof from_file_msgpack(const std::string &filename)
msgpack::sbuffer to_msgpack_buffer() const
GoblinProof goblin_proof
std::shared_ptr< RecursiveVKAndHash > honk_vk_and_hash
std::shared_ptr< MegaVerificationKey > honk_vk
std::shared_ptr< DeciderProvingKey_< Flavor > > accumulator
std::vector< typename Flavor::FF > proof
size_t size() const
Definition types.hpp:25
static field random_element(numeric::RNG *engine=nullptr) noexcept
An object storing two EC points that represent the inputs to a pairing check.
void aggregate(PairingPoints const &other)
Compute a linear combination of the present pairing points with an input set of pairing points.
uint32_t set_public()
Set the witness indices for the limbs of the pairing points to public.
void throw_or_abort(std::string const &err)