Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
chonk.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
17
18namespace bb {
19
20// Constructor
21Chonk::Chonk(size_t num_circuits)
22 : num_circuits(num_circuits)
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 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 = 1UL << TranslatorFlavor::CONST_TRANSLATOR_LOG_N;
29 info("BN254 commitment key size: ", commitment_key_size);
31}
32
44 const std::vector<std::shared_ptr<RecursiveVKAndHash>>& input_keys)
45{
46 bool vkeys_provided = !input_keys.empty();
47 if (vkeys_provided) {
49 input_keys.size(),
50 "Incorrect number of verification keys provided in "
51 "stdlib verification queue instantiation.");
52 }
53
54 size_t key_idx = 0;
55 while (!verification_queue.empty()) {
56 const VerifierInputs& entry = verification_queue.front();
57
58 // Construct stdlib proof directly from the internal native queue data
59 StdlibProof stdlib_proof(circuit, entry.proof);
60
61 // Use the provided stdlib vkey if present, otherwise construct one from the internal native queue
62 std::shared_ptr<RecursiveVKAndHash> stdlib_vk_and_hash;
63 if (vkeys_provided) {
64 stdlib_vk_and_hash = input_keys[key_idx++];
65 } else {
66 stdlib_vk_and_hash = std::make_shared<RecursiveVKAndHash>(circuit, entry.honk_vk);
67 }
68
69 stdlib_verification_queue.emplace_back(stdlib_proof, stdlib_vk_and_hash, entry.type, entry.is_kernel);
70
71 verification_queue.pop_front(); // the native data is not needed beyond this point
72 }
73}
74
97 ClientCircuit& circuit,
98 const StdlibVerifierInputs& verifier_inputs,
99 const std::optional<RecursiveVerifierAccumulator>& input_verifier_accumulator,
100 const TableCommitments& T_prev_commitments,
101 const std::shared_ptr<RecursiveTranscript>& accumulation_recursive_transcript)
102{
104
105 // PairingPoints to be returned for aggregation
106 std::vector<PairingPoints> pairing_points;
107
108 // Input commitments to be passed to the merge recursive verification
109 MergeCommitments merge_commitments{ .T_prev_commitments = T_prev_commitments };
110
111 auto verifier_instance = std::make_shared<RecursiveVerifierInstance>(&circuit, verifier_inputs.honk_vk_and_hash);
112
113 std::optional<RecursiveVerifierAccumulator> output_verifier_accumulator;
114 std::optional<StdlibFF> prev_accum_hash = std::nullopt;
115
116 // Update previous accumulator hash so that we can check it against the one extracted from the public inputs
117 if (verifier_inputs.is_kernel) {
118 prev_accum_hash = input_verifier_accumulator->hash_with_origin_tagging("", *accumulation_recursive_transcript);
119 }
120
121 RecursiveFoldingVerifier folding_verifier(accumulation_recursive_transcript);
122 switch (verifier_inputs.type) {
123 case QUEUE_TYPE::OINK: {
124 vinfo("Recursively verifying accumulation of the first app circuit.");
125 BB_ASSERT_EQ(input_verifier_accumulator.has_value(), false);
126
127 auto [_, new_verifier_accumulator] =
128 folding_verifier.instance_to_accumulator(verifier_instance, verifier_inputs.proof);
129 output_verifier_accumulator = std::move(new_verifier_accumulator);
130
131 // T_prev = 0 in the first recursive verification
132 merge_commitments.T_prev_commitments = stdlib::recursion::honk::empty_ecc_op_tables(circuit);
133 break;
134 }
135 case QUEUE_TYPE::HN:
136 case QUEUE_TYPE::HN_TAIL: {
137 vinfo("Recursively verifying inner accumulation.");
138 auto [_first_verified, _second_verified, new_verifier_accumulator] =
139 folding_verifier.verify_folding_proof(verifier_instance, verifier_inputs.proof);
140 output_verifier_accumulator = std::move(new_verifier_accumulator);
141 break;
142 }
144 vinfo("Recursively verifying accumulation of the tail kernel.");
145 BB_ASSERT_EQ(stdlib_verification_queue.size(), size_t(1));
146
147 auto [_first_verified, _second_verified, final_verifier_accumulator] =
148 folding_verifier.verify_folding_proof(verifier_instance, verifier_inputs.proof);
149
150 RecursiveDeciderVerifier decider_verifier(accumulation_recursive_transcript);
151 StdlibProof stdlib_decider_proof(circuit, decider_proof);
152 pairing_points.emplace_back(decider_verifier.verify_proof(final_verifier_accumulator, stdlib_decider_proof));
153
154 BB_ASSERT_EQ(output_verifier_accumulator.has_value(), false);
155 break;
156 }
157 default: {
158 throw_or_abort("Invalid queue type! Only OINK, HN, HN_TAIL and HN_FINAL are supported");
159 }
160 }
161
162 // Extract the witness commitments and public inputs from the incoming verifier instance
163 WitnessCommitments witness_commitments = std::move(verifier_instance->witness_commitments);
164 std::vector<StdlibFF> public_inputs = std::move(verifier_instance->public_inputs);
165
166 if (verifier_inputs.is_kernel) {
167 // Reconstruct the input from the previous kernel from its public inputs
168 KernelIO kernel_input; // pairing points, databus return data commitments
169 kernel_input.reconstruct_from_public(public_inputs);
170 // Add pairing points for aggregation
171 pairing_points.emplace_back(kernel_input.pairing_inputs);
172 // Perform databus consistency checks
173 kernel_input.kernel_return_data.incomplete_assert_equal(witness_commitments.calldata);
174 kernel_input.app_return_data.incomplete_assert_equal(witness_commitments.secondary_calldata);
175
176 // T_prev is read by the public input of the previous kernel K_{i-1} at the beginning of the recursive
177 // verification of of the folding of K_{i-1} (kernel), A_{i} (app). This verification happens in K_{i}
178 merge_commitments.T_prev_commitments = std::move(kernel_input.ecc_op_tables);
179
180 BB_ASSERT_EQ(verifier_inputs.type == QUEUE_TYPE::HN || verifier_inputs.type == QUEUE_TYPE::HN_TAIL ||
181 verifier_inputs.type == QUEUE_TYPE::HN_FINAL,
182 true,
183 "Kernel circuits should be folded.");
184 // Get the previous accum hash
185 info("Accumulator hash from IO: ", kernel_input.output_hn_accum_hash);
186 BB_ASSERT(prev_accum_hash.has_value());
187 kernel_input.output_hn_accum_hash.assert_equal(*prev_accum_hash);
188
189 // Set the kernel return data commitment to be propagated via the public inputs
190 bus_depot.set_kernel_return_data_commitment(witness_commitments.return_data);
191 } else {
192 // Reconstruct the input from the previous app from its public inputs
193 AppIO app_input; // pairing points
194 app_input.reconstruct_from_public(public_inputs);
195 // Add pairing points for aggregation
196 pairing_points.emplace_back(app_input.pairing_inputs);
197
198 // Set the app return data commitment to be propagated via the public inputs
199 bus_depot.set_app_return_data_commitment(witness_commitments.return_data);
200 }
201
202 // Extract the commitments to the subtable corresponding to the incoming circuit
203 merge_commitments.t_commitments = witness_commitments.get_ecc_op_wires().get_copy();
204
205 // Recursively verify the corresponding merge proof
206 auto [merge_pairing_points, merged_table_commitments] =
207 goblin.recursively_verify_merge(circuit, merge_commitments, accumulation_recursive_transcript);
208 pairing_points.emplace_back(merge_pairing_points);
209
210 return { output_verifier_accumulator, pairing_points, merged_table_commitments };
211}
212
222{
223 // Transcript to be shared across recursive verification of the folding of K_{i-1} (kernel), A_{i} (app)
224 auto accumulation_recursive_transcript = std::make_shared<RecursiveTranscript>();
225
226 // Commitment to the previous state of the op_queue in the recursive verification
227 TableCommitments T_prev_commitments;
228
229 // Instantiate stdlib verifier inputs from their native counterparts
230 if (stdlib_verification_queue.empty()) {
232 }
233
234 bool is_init_kernel =
236
237 bool is_tail_kernel =
239
240 bool is_hiding_kernel =
242
243 // The ECC-op subtable for a kernel begins with an eq-and-reset to ensure that the preceeding circuit's subtable
244 // cannot affect the ECC-op accumulator for the kernel. For the tail kernel, we additionally add a preceeding no-op
245 // to ensure the op queue wires in translator are shiftable, i.e. their 0th coefficient is 0. (The tail kernel
246 // subtable is at the top of the final aggregate table since it is the last to be prepended).
247 if (is_tail_kernel) {
248 BB_ASSERT_EQ(circuit.op_queue->get_current_subtable_size(),
249 0U,
250 "tail kernel ecc ops table should be empty at this point");
251 circuit.queue_ecc_no_op();
252 // Add randomness at the begining of the tail kernel (whose ecc ops fall at the beginning of the op queue table)
253 // to ensure the CHONK proof doesn't leak information about the actual content of the op queue
255
256 // Add the hiding op with random (non-curve) Px, Py values for statistical hiding of accumulated_result.
258 }
259 circuit.queue_ecc_eq();
260
261 // Perform Oink/HN and Merge recursive verification + databus consistency checks for each entry in the queue
262 std::vector<PairingPoints> points_accumulator;
263 std::optional<RecursiveVerifierAccumulator> current_stdlib_verifier_accumulator;
264 if (!is_init_kernel) {
265 current_stdlib_verifier_accumulator = RecursiveVerifierAccumulator::stdlib_from_native<RecursiveFlavor::Curve>(
267 }
268 while (!stdlib_verification_queue.empty()) {
269 const StdlibVerifierInputs& verifier_input = stdlib_verification_queue.front();
270
271 auto [output_stdlib_verifier_accumulator, pairing_points, merged_table_commitments] =
273 verifier_input,
274 current_stdlib_verifier_accumulator,
275 T_prev_commitments,
276 accumulation_recursive_transcript);
277 points_accumulator.insert(points_accumulator.end(), pairing_points.begin(), pairing_points.end());
278 // Update commitment to the status of the op_queue
279 T_prev_commitments = merged_table_commitments;
280 // Update the output verifier accumulator
281 current_stdlib_verifier_accumulator = output_stdlib_verifier_accumulator;
282
283 stdlib_verification_queue.pop_front();
284 }
285
286 // PairingPoint aggregation
287 PairingPoints pairing_points_aggregator = PairingPoints::aggregate_multiple(points_accumulator);
288
289 // Set the kernel output data to be propagated via the public inputs
290 if (is_hiding_kernel) {
291 BB_ASSERT_EQ(current_stdlib_verifier_accumulator.has_value(), false);
292 // Add randomness at the end of the hiding kernel (whose ecc ops fall right at the end of the op queue table) to
293 // ensure the Chonk proof doesn't leak information about the actual content of the op queue
295
296 HidingKernelIO hiding_output{ pairing_points_aggregator,
298 T_prev_commitments };
299 hiding_output.set_public();
300 } else {
301 BB_ASSERT_NEQ(current_stdlib_verifier_accumulator.has_value(), false);
302 // Extract native verifier accumulator from the stdlib accum for use on the next round
303 recursive_verifier_native_accum = current_stdlib_verifier_accumulator->get_value<VerifierAccumulator>();
304
305 KernelIO kernel_output;
306 kernel_output.pairing_inputs = pairing_points_aggregator;
307 kernel_output.kernel_return_data = bus_depot.get_kernel_return_data_commitment(circuit);
308 kernel_output.app_return_data = bus_depot.get_app_return_data_commitment(circuit);
309 kernel_output.ecc_op_tables = T_prev_commitments;
310 RecursiveTranscript hash_transcript;
311 kernel_output.output_hn_accum_hash =
312 current_stdlib_verifier_accumulator->hash_with_origin_tagging("", hash_transcript);
313 info("Kernel output accumulator hash: ", kernel_output.output_hn_accum_hash);
314#ifndef NDEBUG
315 info("Chonk recursive verification: accumulator hash set in the public inputs matches the one "
316 "computed natively: ",
317 kernel_output.output_hn_accum_hash.get_value() == native_verifier_accum_hash ? "true" : "false");
318#endif
319 kernel_output.set_public();
320 }
321}
322
327{
328 // first app
329 if (num_circuits_accumulated == 0) {
330 return QUEUE_TYPE::OINK;
331 }
332 // app (excluding first) or kernel (inner or reset)
334 return QUEUE_TYPE::HN;
335 }
336 // last kernel prior to tail kernel
338 return QUEUE_TYPE::HN_TAIL;
339 }
340 // tail kernel
343 }
344 // hiding kernel
346 return QUEUE_TYPE::MEGA;
347 }
348 return QUEUE_TYPE{};
349}
350
362{
364 num_circuits_accumulated, num_circuits, "Chonk: Attempting to accumulate more circuits than expected.");
365
366 BB_ASSERT(precomputed_vk != nullptr, "Chonk::accumulate - VK expected for the provided circuit");
367
368 // Construct the prover instance for circuit
370
371#ifndef NDEBUG
372 debug_incoming_circuit(circuit, prover_instance, precomputed_vk);
373#endif
374
375 // If the current circuit exceeds the current size of the commitment key, reinitialize accordingly.
376 // TODO(https://github.com/AztecProtocol/barretenberg/issues/1319)
377 if (prover_instance->dyadic_size() > bn254_commitment_key.dyadic_size) {
378 bn254_commitment_key = CommitmentKey<curve::BN254>(prover_instance->dyadic_size());
380 }
381 prover_instance->commitment_key = bn254_commitment_key;
382
383 // We're accumulating a kernel if the verification queue is empty (because the kernel circuit contains recursive
384 // verifiers for all the entries previously present in the verification queue) and if it's not the first accumulate
385 // call (which will always be for an app circuit).
386 bool is_kernel = verification_queue.empty() && num_circuits_accumulated > 0;
387
388 // Transcript to be shared across folding of K_{i} (kernel) (the current kernel), A_{i+1,1} (app), .., A_{i+1,
389 // n} (app)
390 if (is_kernel) {
392 }
393
394#ifndef NDEBUG
395 // Make a copy of the prover_accumulation_transcript for the native verifier to use, only happens in debugging
396 // builds
397 auto verifier_transcript =
399#endif
400
401 QUEUE_TYPE queue_type = get_queue_type();
402
404 HonkProof proof;
405 switch (queue_type) {
406 case QUEUE_TYPE::OINK:
407 vinfo("Accumulating first app circuit");
408 BB_ASSERT_EQ(is_kernel, false, "First circuit accumulated must always be an app");
409
410 prover_accumulator = prover.instance_to_accumulator(prover_instance, precomputed_vk);
411 proof = prover.export_proof();
412 break;
413 case QUEUE_TYPE::HN:
415 vinfo("Accumulating circuit number ", num_circuits_accumulated + 1);
416 std::tie(proof, prover_accumulator) = prover.fold(prover_accumulator, prover_instance, precomputed_vk);
417 break;
419 vinfo("Accumulating tail kernel");
420 std::tie(proof, prover_accumulator) = prover.fold(prover_accumulator, prover_instance, precomputed_vk);
423 break;
424 }
425 case QUEUE_TYPE::MEGA:
426 vinfo("Generating proof for hiding kernel");
427 // TODO(https://github.com/AztecProtocol/barretenberg/issues/1555): Method for constructing hiding kernel proof
428 // constructs a new ProverInstance (with ZK Flavor). For now just do a hacky shared ptr deallocation to avoid
429 // double memory for storing two instances.
430 prover_instance.reset();
431 proof = construct_honk_proof_for_hiding_kernel(circuit, precomputed_vk);
432 break;
433 }
434
435 VerifierInputs queue_entry{ std::move(proof), precomputed_vk, queue_type, is_kernel };
436 verification_queue.push_back(queue_entry);
437
438 // Construct merge proof (excluded for hiding kernel since accumulation terminates with
439 // tail kernel and hiding merge proof is constructed as part of goblin proving)
440 if (queue_entry.type != QUEUE_TYPE::MEGA) {
441#ifndef NDEBUG
442 // In debugging builds update native verifier accumulator
443 update_native_verifier_accumulator(queue_entry, verifier_transcript);
444#endif
446 }
447
449}
450
461{
462 // Use random Fq field elements as Px and Py.
463 using Fq = curve::Grumpkin::ScalarField; // Same as BN254::BaseField
464 circuit.queue_ecc_hiding_op(Fq::random_element(), Fq::random_element());
465}
466
473{
474 circuit.queue_ecc_random_op();
475 circuit.queue_ecc_random_op();
476 circuit.queue_ecc_random_op();
477}
478
489
495 const std::shared_ptr<MegaVerificationKey>& verification_key)
496{
497 auto hiding_prover_inst = std::make_shared<DeciderZKProvingKey>(circuit, bn254_commitment_key);
498
499 // Hiding kernel is proven by a MegaZKProver
500 MegaZKProver prover(hiding_prover_inst, verification_key, transcript);
501 HonkProof proof = prover.construct_proof();
502
503 return proof;
504}
505
512{
513 // deallocate the accumulator
515 auto mega_proof = verification_queue.front().proof;
516
517 // A transcript is shared between the Hiding kernel prover and the Goblin prover
519
520 // Returns a proof for the Hiding kernel and the Goblin proof. The latter consists of Translator and ECCVM proof
521 // for the whole ecc op table and the merge proof for appending the subtable coming from the Hiding kernel. The
522 // final merging is done via appending to facilitate creating a zero-knowledge merge proof. This enables us to add
523 // randomness to the beginning of the tail kernel and the end of the hiding kernel, hiding the commitments and
524 // evaluations of both the previous table and the incoming subtable.
525 return { mega_proof, goblin.prove(MergeSettings::APPEND) };
526};
527
528bool Chonk::verify(const Proof& proof, const VerificationKey& vk)
529{
531 // Create a transcript to be shared by MegaZK-, Merge-, ECCVM-, and Translator- Verifiers.
533 // Verify the Hiding kernel proof
534 MegaZKVerifier verifier{ vk.mega, /*ipa_verification_key=*/{}, chonk_verifier_transcript };
535 auto [mega_verified, kernel_return_data, T_prev_commitments] =
536 verifier.template verify_proof<bb::HidingKernelIO>(proof.mega_proof);
537 vinfo("Mega verified: ", mega_verified);
538 // Perform databus consistency checks
539 bool databus_consistency_verified = kernel_return_data == verifier.verifier_instance->witness_commitments.calldata;
540 vinfo("Databus consistency verified: ", databus_consistency_verified);
541 // Extract the commitments to the subtable corresponding to the incoming circuit
542 TableCommitments t_commitments = verifier.verifier_instance->witness_commitments.get_ecc_op_wires().get_copy();
543
544 // Goblin verification (final merge, eccvm, translator)
545 bool goblin_verified = Goblin::verify(
546 proof.goblin_proof, { t_commitments, T_prev_commitments }, chonk_verifier_transcript, MergeSettings::APPEND);
547 vinfo("Goblin verified: ", goblin_verified);
548
549 // TODO(https://github.com/AztecProtocol/barretenberg/issues/1396): State tracking in Chonk verifiers.
550 return goblin_verified && mega_verified && databus_consistency_verified;
551}
552
553// Proof methods
554size_t Chonk::Proof::size() const
555{
556 return mega_proof.size() + goblin_proof.size();
557}
558
560{
561 HonkProof proof;
562
563 proof.insert(proof.end(), mega_proof.begin(), mega_proof.end());
564 proof.insert(proof.end(), goblin_proof.merge_proof.begin(), goblin_proof.merge_proof.end());
565 proof.insert(proof.end(), goblin_proof.eccvm_proof.begin(), goblin_proof.eccvm_proof.end());
566 proof.insert(proof.end(), goblin_proof.ipa_proof.begin(), goblin_proof.ipa_proof.end());
567 proof.insert(proof.end(), goblin_proof.translator_proof.begin(), goblin_proof.translator_proof.end());
568 return proof;
569};
570
572{
573 HonkProof mega_proof;
574 GoblinProof goblin_proof;
575
576 size_t custom_public_inputs_size = fields.size() - Chonk::Proof::PROOF_LENGTH();
577
578 // Mega proof
579 auto start_idx = fields.begin();
580 auto end_idx = start_idx + static_cast<std::ptrdiff_t>(
582 bb::HidingKernelIO::PUBLIC_INPUTS_SIZE + custom_public_inputs_size);
583 mega_proof.insert(mega_proof.end(), start_idx, end_idx);
584
585 // Merge proof
586 start_idx = end_idx;
587 end_idx += static_cast<std::ptrdiff_t>(MERGE_PROOF_SIZE);
588 goblin_proof.merge_proof.insert(goblin_proof.merge_proof.end(), start_idx, end_idx);
589
590 // ECCVM proof
591 start_idx = end_idx;
593 goblin_proof.eccvm_proof.insert(goblin_proof.eccvm_proof.end(), start_idx, end_idx);
594
595 // IPA proof
596 start_idx = end_idx;
597 end_idx += static_cast<std::ptrdiff_t>(IPA_PROOF_LENGTH);
598 goblin_proof.ipa_proof.insert(goblin_proof.ipa_proof.end(), start_idx, end_idx);
599
600 // Translator proof
601 start_idx = end_idx;
603 goblin_proof.translator_proof.insert(goblin_proof.translator_proof.end(), start_idx, end_idx);
604
605 return { mega_proof, goblin_proof };
606};
607
608msgpack::sbuffer Chonk::Proof::to_msgpack_buffer() const
609{
610 msgpack::sbuffer buffer;
611 msgpack::pack(buffer, *this);
612 return buffer;
613}
614
616{
617 msgpack::sbuffer buffer = to_msgpack_buffer();
618
619 std::vector<uint8_t> buf(buffer.data(), buffer.data() + buffer.size());
620 return to_heap_buffer(buf);
621}
622
624{
625 auto uint8_buffer = from_buffer<std::vector<uint8_t>>(buffer);
626
627 msgpack::sbuffer sbuf;
628 sbuf.write(reinterpret_cast<char*>(uint8_buffer.data()), uint8_buffer.size());
629
630 return from_msgpack_buffer(sbuf);
631}
632
634{
635 msgpack::object_handle oh = msgpack::unpack(buffer.data(), buffer.size());
636 msgpack::object obj = oh.get();
637 Proof proof;
638 obj.convert(proof);
639 return proof;
640}
641
642void Chonk::Proof::to_file_msgpack(const std::string& filename) const
643{
644 msgpack::sbuffer buffer = to_msgpack_buffer();
645 std::ofstream ofs(filename, std::ios::binary);
646 if (!ofs.is_open()) {
647 throw_or_abort("Failed to open file for writing.");
648 }
649 ofs.write(buffer.data(), static_cast<std::streamsize>(buffer.size()));
650 ofs.close();
651}
652
654{
655 std::ifstream ifs(filename, std::ios::binary);
656 if (!ifs.is_open()) {
657 throw_or_abort("Failed to open file for reading.");
658 }
659
660 ifs.seekg(0, std::ios::end);
661 size_t file_size = static_cast<size_t>(ifs.tellg());
662 ifs.seekg(0, std::ios::beg);
663
664 std::vector<char> buffer(file_size);
665 ifs.read(buffer.data(), static_cast<std::streamsize>(file_size));
666 ifs.close();
667 msgpack::sbuffer msgpack_buffer;
668 msgpack_buffer.write(buffer.data(), file_size);
669
670 return Proof::from_msgpack_buffer(msgpack_buffer);
671}
672
673// VerificationKey construction
675{
676 BB_ASSERT_EQ(verification_queue.size(), 1UL);
677 BB_ASSERT_EQ(verification_queue.front().type == QUEUE_TYPE::MEGA, true);
678 auto verification_key = verification_queue.front().honk_vk;
679 return { verification_key,
682}
683
684#ifndef NDEBUG
686 const std::shared_ptr<Transcript>& verifier_transcript)
687{
688 info("======= DEBUGGING INFO FOR NATIVE FOLDING STEP =======");
689
690 auto verifier_inst = std::make_shared<VerifierInstance>(queue_entry.honk_vk);
691
692 FoldingVerifier native_verifier(verifier_transcript);
693 if (queue_entry.type == QUEUE_TYPE::OINK) {
694 auto [_first_verified, new_accumulator] =
695 native_verifier.instance_to_accumulator(verifier_inst, queue_entry.proof);
696 native_verifier_accum = std::move(new_accumulator);
697
698 info("Sumcheck: instance to accumulator verified: ", _first_verified ? "true" : "false");
699 } else {
700 auto [_first_verified, _second_verified, new_accumulator] =
701 native_verifier.verify_folding_proof(verifier_inst, queue_entry.proof);
702 native_verifier_accum = std::move(new_accumulator);
703
704 info("Sumcheck: instance to accumulator verified: ", _first_verified ? "true" : "false");
705 info("Sumcheck: batch two accumulators verified: ", _second_verified ? "true" : "false");
706
707 if (queue_entry.type == QUEUE_TYPE::HN_FINAL) {
708 HypernovaDeciderVerifier<MegaFlavor> decider_verifier(verifier_transcript);
709 bb::PairingPoints<curve::BN254> pairing_points =
711
712 info("Decider: pairing points verified? ", pairing_points.check() ? "true" : "false");
713 }
714 }
715
716 if (!queue_entry.is_kernel) {
717 native_verifier_accum_hash = native_verifier_accum.hash_with_origin_tagging("", *verifier_transcript);
718 }
719
720 info("Chonk accumulate: prover and verifier accumulators match: ",
722 info("Chonk accumulate: hash of verifier accumulator computed natively ", native_verifier_accum_hash);
723
724 info("======= END OF DEBUGGING INFO FOR NATIVE FOLDING STEP =======");
725}
726
728 const std::shared_ptr<ProverInstance>& prover_instance,
729 const std::shared_ptr<MegaVerificationKey>& precomputed_vk)
730{
731 info("======= DEBUGGING INFO FOR INCOMING CIRCUIT =======");
732
733 info("Accumulating circuit ", num_circuits_accumulated + 1, " of ", num_circuits);
734 info("Is the circuit valid? ", CircuitChecker::check(circuit) ? "true" : "false");
735 info("Did we find a failure? ", circuit.failed() ? "true" : "false");
736 if (circuit.failed()) {
737 info("\t\t\tError message? ", circuit.err());
738 }
739
740 // Compare precomputed VK with the one generated during accumulation
741 auto vk = std::make_shared<MegaVerificationKey>(prover_instance->get_precomputed());
742 info("Does the precomputed vk match with the one generated during accumulation? ",
743 vk->compare(*precomputed_vk) ? "true" : "false");
744
745 info("======= END OF DEBUGGING INFO FOR INCOMING CIRCUIT =======");
746}
747#endif
748
749} // namespace bb
#define BB_ASSERT(expression,...)
Definition assert.hpp:67
#define BB_ASSERT_GT(left, right,...)
Definition assert.hpp:107
#define BB_ASSERT_NEQ(actual, expected,...)
Definition assert.hpp:92
#define BB_ASSERT_EQ(actual, expected,...)
Definition assert.hpp:77
#define BB_ASSERT_LT(left, right,...)
Definition assert.hpp:137
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.
ProverAccumulator prover_accumulator
Definition chonk.hpp:262
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.
Definition chonk.cpp:43
HonkProof construct_honk_proof_for_hiding_kernel(ClientCircuit &circuit, const std::shared_ptr< MegaVerificationKey > &verification_key)
Construct a zero-knowledge proof for the Hiding kernel, which recursively verifies the last folding,...
Definition chonk.cpp:494
void complete_kernel_circuit_logic(ClientCircuit &circuit)
Append logic to complete a kernel circuit.
Definition chonk.cpp:221
std::tuple< std::optional< RecursiveVerifierAccumulator >, std::vector< PairingPoints >, TableCommitments > perform_recursive_verification_and_databus_consistency_checks(ClientCircuit &circuit, const StdlibVerifierInputs &verifier_inputs, const std::optional< RecursiveVerifierAccumulator > &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...
Definition chonk.cpp:96
VerifierAccumulator native_verifier_accum
Definition chonk.hpp:268
Chonk(size_t num_circuits)
Definition chonk.cpp:21
void update_native_verifier_accumulator(const VerifierInputs &queue_entry, const std::shared_ptr< Transcript > &verifier_transcript)
Update native verifier accumulator. Useful for debugging.
Definition chonk.cpp:685
Proof prove()
Construct a proof for the IVC, which, if verified, fully establishes its correctness.
Definition chonk.cpp:511
static void hide_op_queue_content_in_hiding(ClientCircuit &circuit)
Adds two random non-ops to the hiding kernel for zero-knowledge.
Definition chonk.cpp:484
std::array< RecursiveFlavor::Commitment, ClientCircuit::NUM_WIRES > TableCommitments
Definition chonk.hpp:73
DataBusDepot bus_depot
Definition chonk.hpp:278
std::shared_ptr< Transcript > transcript
Definition chonk.hpp:253
size_t num_circuits_accumulated
Definition chonk.hpp:260
void debug_incoming_circuit(ClientCircuit &circuit, const std::shared_ptr< ProverInstance > &prover_instance, const std::shared_ptr< MegaVerificationKey > &precomputed_vk)
Definition chonk.cpp:727
HonkProof decider_proof
Definition chonk.hpp:264
FF native_verifier_accum_hash
Definition chonk.hpp:269
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...
Definition chonk.cpp:326
static void hide_op_queue_content_in_tail(ClientCircuit &circuit)
Adds three random non-ops to the tail kernel for zero-knowledge.
Definition chonk.cpp:472
FoldingProver::Accumulator ProverAccumulator
Definition chonk.hpp:80
VerifierAccumulator recursive_verifier_native_accum
Definition chonk.hpp:266
static void hide_op_queue_accumulation_result(ClientCircuit &circuit)
Add a hiding op with fully random Px, Py field elements to prevent information leakage in Translator ...
Definition chonk.cpp:460
MegaFlavor::CommitmentKey bn254_commitment_key
Definition chonk.hpp:280
void accumulate(ClientCircuit &circuit, const std::shared_ptr< MegaVerificationKey > &precomputed_vk) override
Perform prover work for accumulation (e.g. HN folding, merge proving)
Definition chonk.cpp:361
VerificationKey get_vk() const
Definition chonk.cpp:674
size_t num_circuits
Definition chonk.hpp:258
VerificationQueue verification_queue
Definition chonk.hpp:273
Goblin goblin
Definition chonk.hpp:282
std::shared_ptr< Transcript > prover_accumulation_transcript
Definition chonk.hpp:256
static bool verify(const Proof &proof, const VerificationKey &vk)
Definition chonk.cpp:528
StdlibVerificationQueue stdlib_verification_queue
Definition chonk.hpp:275
const std::string & err() const
CommitmentKey object over a pairing group 𝔾₁.
static constexpr size_t PROOF_LENGTH_WITHOUT_PUB_INPUTS
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:102
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:82
MergeVerifier::TableCommitments TableCommitments
Definition goblin.hpp:40
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:28
GoblinProof prove(const MergeSettings merge_settings=MergeSettings::PREPEND)
Constuct a full Goblin proof (ECCVM, Translator, merge)
Definition goblin.cpp:61
CommitmentKey< curve::BN254 > commitment_key
Definition goblin.hpp:49
std::shared_ptr< Transcript > transcript
Definition goblin.hpp:55
static constexpr size_t PUBLIC_INPUTS_SIZE
HonkProof construct_proof(const CommitmentKey &ck, Accumulator &accumulator)
PairingPoints verify_proof(Accumulator &accumulator, const Proof &proof)
HonkProof export_proof()
Export the proof contained in the transcript.
std::pair< HonkProof, Accumulator > fold(const Accumulator &accumulator, const std::shared_ptr< ProverInstance > &instance, const std::shared_ptr< VerificationKey > &honk_vk=nullptr)
Fold an instance into an accumulator. Folding happens in place.
Accumulator instance_to_accumulator(const std::shared_ptr< ProverInstance > &instance, const std::shared_ptr< VerificationKey > &honk_vk=nullptr)
Turn an instance into an accumulator by running Sumcheck.
std::tuple< bool, bool, Accumulator > verify_folding_proof(const std::shared_ptr< typename HypernovaFoldingVerifier::VerifierInstance > &instance, const Proof &proof)
Verify folding proof. Return the new accumulator and the results of the two sumchecks.
std::pair< bool, Accumulator > instance_to_accumulator(const std::shared_ptr< VerifierInstance > &instance, const Proof &proof)
Turn an instance into an accumulator by executing sumcheck.
void queue_ecc_random_op()
Mechanism for populating two rows with randomness. This "operation" doesn't return a tuple representi...
std::shared_ptr< ECCOpQueue > op_queue
ecc_op_tuple queue_ecc_eq(bool in_finalize=true)
Add point equality operation to the op queue based on the value of the internal accumulator and add c...
ecc_op_tuple queue_ecc_no_op()
Logic for a no-op operation.
void queue_ecc_hiding_op(const curve::BN254::BaseField &Px, const curve::BN254::BaseField &Py)
Add a hiding op with random (possibly non-curve) Px, Py values to the op queue and circuit.
Container for all witness polynomials used/constructed by the prover.
static constexpr size_t PROOF_LENGTH_WITHOUT_PUB_INPUTS(size_t virtual_log_n=VIRTUAL_LOG_N)
static constexpr size_t VIRTUAL_LOG_N
An object storing two EC points that represent the inputs to a pairing check.
bool check() const
Perform the pairing check.
static bool check(const Builder &circuit)
Check the witness satisifies the circuit.
static constexpr size_t CONST_TRANSLATOR_LOG_N
static constexpr size_t PROOF_LENGTH_WITHOUT_PUB_INPUTS
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.
#define vinfo(...)
Definition log.hpp:80
void info(Args... args)
Definition log.hpp:75
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.
Definition api.hpp:5
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 kernel (whi...
Definition chonk.hpp:91
void to_file_msgpack(const std::string &filename) const
Definition chonk.cpp:642
static Proof from_msgpack_buffer(uint8_t const *&buffer)
Definition chonk.cpp:623
static Proof from_file_msgpack(const std::string &filename)
Definition chonk.cpp:653
HonkProof mega_proof
Definition chonk.hpp:92
size_t size() const
Definition chonk.cpp:554
static constexpr size_t PROOF_LENGTH(size_t virtual_log_n=MegaZKFlavor::VIRTUAL_LOG_N)
The size of a Chonk proof with backend-added public inputs: HidingKernelIO.
Definition chonk.hpp:116
GoblinProof goblin_proof
Definition chonk.hpp:93
static Proof from_field_elements(const std::vector< Chonk::FF > &fields)
Definition chonk.cpp:571
std::vector< FF > to_field_elements() const
Serialize proof to field elements.
Definition chonk.cpp:559
uint8_t * to_msgpack_heap_buffer() const
Very quirky method to convert a msgpack buffer to a "heap" buffer.
Definition chonk.cpp:615
msgpack::sbuffer to_msgpack_buffer() const
Definition chonk.cpp:608
std::shared_ptr< RecursiveVKAndHash > honk_vk_and_hash
Definition chonk.hpp:245
std::shared_ptr< MegaVerificationKey > honk_vk
Definition chonk.hpp:236
std::vector< FF > proof
Definition chonk.hpp:235
HonkProof eccvm_proof
Definition types.hpp:23
HonkProof ipa_proof
Definition types.hpp:24
HonkProof merge_proof
Definition types.hpp:22
size_t size() const
Definition types.hpp:27
HonkProof translator_proof
Definition types.hpp:25
bool compare_with_verifier_claim(const MultilinearBatchingVerifierClaim< curve::BN254 > &verifier_claim)
An object storing two EC points that represent the inputs to a pairing check.
static PairingPoints aggregate_multiple(std::vector< PairingPoints > &pairing_points)
Aggregate multiple PairingPoints.
void throw_or_abort(std::string const &err)
curve::BN254::BaseField Fq