Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
bbapi_chonk.cpp
Go to the documentation of this file.
19
20#ifdef BB_HAS_BATCH_VERIFIER_SERVICE
21#include <algorithm>
22#include <cerrno>
23#include <chrono>
24#include <climits>
25#include <csignal>
26#include <cstring>
27#include <fcntl.h>
28#include <limits>
29#include <sys/stat.h>
30#include <thread>
31#include <unistd.h>
32#endif
33
34namespace bb::bbapi {
35namespace {
36
37ChonkPrecomputedVkPolicy to_chonk_vk_policy(VkPolicy policy)
38{
39 switch (policy) {
42 case VkPolicy::CHECK:
47 break;
48 }
49 throw_or_abort("Invalid VK policy. Valid options: default, check, recompute");
50}
51
52} // namespace
53
54// BB_NO_EXCEPTIONS rewrites catch blocks away; handlers must not depend on catch bindings.
55#ifndef BB_NO_EXCEPTIONS
56#define BBAPI_CHONK_EXCEPTION_WHAT(exception) (exception).what()
57#else
58#define BBAPI_CHONK_EXCEPTION_WHAT(exception) "unknown exception"
59#endif
60
61template <typename VerificationKey> bool has_expected_vk_size(const std::vector<uint8_t>& vk_bytes, const char* label)
62{
63 const size_t expected_size = VerificationKey::calc_num_data_types() * sizeof(bb::fr);
64 if (vk_bytes.size() == expected_size) {
65 return true;
66 }
67 // Wasm builds cannot catch throw_or_abort from validate_vk_size.
68 info(label, ": verification key has wrong size: expected ", expected_size, ", got ", vk_bytes.size());
69 return false;
70}
71
73{
74 BB_BENCH_NAME(MSGPACK_SCHEMA_NAME);
75
76 request.ivc_in_progress = std::make_shared<ChonkStepProcessor>(std::move(kinds));
77
78 // Clear any stale loaded-circuit state from a previous session so that
79 // ChonkAccumulate cannot silently reuse a circuit loaded before this ChonkStart.
80 request.loaded_circuit_name.clear();
81 request.loaded_circuit_constraints.reset();
82 request.loaded_circuit_vk.clear();
83 request.loaded_circuit_kind = CircuitKind::App;
84
85 return Response{};
86}
87
89{
90 BB_BENCH_NAME(MSGPACK_SCHEMA_NAME);
91 if (!request.ivc_in_progress) {
92 throw_or_abort("Chonk not started. Call ChonkStart first.");
93 }
94
95 request.loaded_circuit_name = circuit.name;
96 request.loaded_circuit_constraints = acir_format::circuit_buf_to_mega_acir_format(std::move(circuit.bytecode));
97 request.loaded_circuit_vk = circuit.verification_key;
98 request.loaded_circuit_kind = kind;
99
100 info("ChonkLoad - loaded circuit '", request.loaded_circuit_name, "'");
101
102 return Response{};
103}
104
106{
107 BB_BENCH_NAME(MSGPACK_SCHEMA_NAME);
108 if (!request.ivc_in_progress) {
109 throw_or_abort("Chonk not started. Call ChonkStart first.");
110 }
111
112 if (!request.loaded_circuit_constraints.has_value()) {
113 throw_or_abort("No circuit loaded. Call ChonkLoad first.");
114 }
115
117 acir_format::AcirProgram program{ std::move(request.loaded_circuit_constraints.value()), std::move(witness_data) };
118
119 // Clear loaded state immediately after moving out of it. This ensures that if any subsequent
120 // step throws, the request won't appear to still have a valid circuit loaded (the optional
121 // would be in a moved-from state, which is technically has_value()==true but poisoned).
122 auto loaded_vk = std::move(request.loaded_circuit_vk);
123 auto circuit_name = std::move(request.loaded_circuit_name);
124 const CircuitKind loaded_kind = request.loaded_circuit_kind;
125 request.loaded_circuit_constraints.reset();
126 request.loaded_circuit_vk.clear();
127 request.loaded_circuit_name.clear();
128 request.loaded_circuit_kind = CircuitKind::App;
129
130 request.ivc_in_progress->process_step({ .name = std::move(circuit_name),
131 .program = std::move(program),
132 .precomputed_vk = std::move(loaded_vk),
133 .kind = loaded_kind },
134 to_chonk_vk_policy(request.vk_policy));
135
136 return Response{};
137}
138
140{
141 BB_BENCH_NAME(MSGPACK_SCHEMA_NAME);
142 if (!request.ivc_in_progress) {
143 throw_or_abort("Chonk not started. Call ChonkStart first.");
144 }
145
146 const size_t num_circuits_accumulated = request.ivc_in_progress->get_num_circuits_accumulated();
147 if (num_circuits_accumulated == 0) {
148 throw_or_abort("No circuits accumulated. Call ChonkAccumulate first.");
149 }
150
151 info("ChonkProve - generating proof for ", num_circuits_accumulated, " accumulated circuits");
152
153 auto proof = request.ivc_in_progress->prove();
154 auto vk_and_hash = request.ivc_in_progress->get_hiding_kernel_vk_and_hash();
155
156 // Sanity-check the freshly produced proof in-process. A separate `bb verify` call would
157 // re-load VK/proof/SRS and surface failures far from the proving site.
158 info("ChonkProve - verifying the generated proof as a sanity check");
159 ChonkNativeVerifier verifier(vk_and_hash);
160 if (!verifier.verify(proof)) {
161 throw_or_abort("Failed to verify the generated proof!");
162 }
163
164 request.ivc_in_progress.reset();
165
166 return Response{ .proof = std::move(proof) };
167}
168
170{
171 BB_BENCH_NAME(MSGPACK_SCHEMA_NAME);
172
173 try {
175 if (!has_expected_vk_size<VerificationKey>(vk, "ChonkVerify")) {
176 return { .valid = false };
177 }
178
179 // Deserialize the hiding kernel verification key directly from buffer
180 auto hiding_kernel_vk = deserialize_chonk_vk(vk);
181
182 // Validate total proof size: must match num_public_inputs + fixed overhead
183 const size_t expected_proof_size =
184 static_cast<size_t>(hiding_kernel_vk->num_public_inputs) + ChonkProof::PROOF_LENGTH_WITHOUT_PUB_INPUTS;
185 if (proof.size() != expected_proof_size) {
186 info("ChonkVerify: proof has wrong size: expected ", expected_proof_size, ", got ", proof.size());
187 return { .valid = false };
188 }
189
190 // Verify the proof using ChonkNativeVerifier
191 auto vk_and_hash = std::make_shared<ChonkNativeVerifier::VKAndHash>(hiding_kernel_vk);
192 ChonkNativeVerifier verifier(vk_and_hash);
193 const bool verified = verifier.verify(proof);
194
195 return { .valid = verified };
196 } catch (const std::exception& e) {
197 info("ChonkVerify: malformed input: ", BBAPI_CHONK_EXCEPTION_WHAT(e));
198 return { .valid = false };
199 } catch (...) {
200 info("ChonkVerify: malformed input: unknown exception");
201 return { .valid = false };
202 }
203}
204
206{
207 BB_BENCH_NAME(MSGPACK_SCHEMA_NAME);
208
209 try {
211 if (!has_expected_vk_size<VerificationKey>(vk, "ChonkVerifyFromFields")) {
212 return { .valid = false };
213 }
214
215 // The hiding kernel uses MegaZKFlavor's VK shape (distinct C++ type from MegaFlavor's VK).
216 auto hiding_kernel_vk = deserialize_chonk_vk(vk);
217
218 // Validate total field count: must match num_public_inputs + fixed overhead.
219 const size_t expected_field_count =
220 static_cast<size_t>(hiding_kernel_vk->num_public_inputs) + ChonkProof::PROOF_LENGTH_WITHOUT_PUB_INPUTS;
221 if (proof.size() != expected_field_count) {
222 info("ChonkVerifyFromFields: proof has wrong field count: expected ",
223 expected_field_count,
224 ", got ",
225 proof.size());
226 return { .valid = false };
227 }
228
229 // Split the flat field array into the structured ChonkProof. Layout knowledge stays here.
230 auto structured = ChonkProof::from_field_elements(proof);
231
232 auto vk_and_hash = std::make_shared<ChonkNativeVerifier::VKAndHash>(hiding_kernel_vk);
233 ChonkNativeVerifier verifier(vk_and_hash);
234 const bool verified = verifier.verify(structured);
235
236 return { .valid = verified };
237 } catch (const std::exception& e) {
238 info("ChonkVerifyFromFields: malformed input: ", BBAPI_CHONK_EXCEPTION_WHAT(e));
239 return { .valid = false };
240 } catch (...) {
241 info("ChonkVerifyFromFields: malformed input: unknown exception");
242 return { .valid = false };
243 }
244}
245
247{
248 BB_BENCH_NAME(MSGPACK_SCHEMA_NAME);
249
250 try {
251 if (proofs.size() != vks.size()) {
252 info("ChonkBatchVerify: proofs.size() (", proofs.size(), ") != vks.size() (", vks.size(), ")");
253 return { .valid = false };
254 }
255 if (proofs.empty()) {
256 info("ChonkBatchVerify: no proofs provided");
257 return { .valid = false };
258 }
259
261
262 // Phase 1: Run all non-IPA verification for each proof, collecting deferred TripleIPA claims and proofs.
264 reduced_results.reserve(proofs.size());
265
266 for (size_t i = 0; i < proofs.size(); ++i) {
267 if (!has_expected_vk_size<VerificationKey>(vks[i], "ChonkBatchVerify")) {
268 return { .valid = false };
269 }
270 auto hiding_kernel_vk = deserialize_chonk_vk(vks[i]);
271
272 const size_t expected_proof_size =
273 static_cast<size_t>(hiding_kernel_vk->num_public_inputs) + ChonkProof::PROOF_LENGTH_WITHOUT_PUB_INPUTS;
274 if (proofs[i].size() != expected_proof_size) {
275 info("ChonkBatchVerify: proof[",
276 i,
277 "] has wrong size: expected ",
278 expected_proof_size,
279 ", got ",
280 proofs[i].size());
281 return { .valid = false };
282 }
283
284 auto vk_and_hash = std::make_shared<ChonkNativeVerifier::VKAndHash>(hiding_kernel_vk);
285 ChonkNativeVerifier verifier(vk_and_hash);
286 auto result = verifier.reduce_to_triple_ipa_opening(std::move(proofs[i]));
287 if (!result.all_checks_passed) {
288 return { .valid = false };
289 }
290 reduced_results.push_back(std::move(result));
291 }
292
293 // Phase 2: Reduce all deferred TripleIPA claims to accumulators and discharge them with one combined SRS-MSM.
295 ipa_accumulators.reserve(reduced_results.size());
296 for (const auto& result : reduced_results) {
297 ipa_accumulators.push_back(result.triple_ipa_opening.reduce_to_accumulator());
298 }
299 const bool verified = bb::ECCVMVerifier::batch_verify_accumulators(ipa_accumulators);
300
301 return { .valid = verified };
302 } catch (const std::exception& e) {
303 info("ChonkBatchVerify: malformed input: ", BBAPI_CHONK_EXCEPTION_WHAT(e));
304 return { .valid = false };
305 } catch (...) {
306 info("ChonkBatchVerify: malformed input: unknown exception");
307 return { .valid = false };
308 }
309}
310
312{
313 BB_BENCH_NAME(MSGPACK_SCHEMA_NAME);
314 info("ChonkComputeVk - deriving Chonk verification key for circuit '",
315 circuit.name,
316 "' (kind=",
317 static_cast<int>(kind),
318 ")");
319
320 auto constraint_system = acir_format::circuit_buf_to_mega_acir_format(std::move(circuit.bytecode));
321
322 acir_format::AcirProgram program{ constraint_system, /*witness=*/{} };
323 auto verification_key = compute_chonk_vk(program, kind);
324 info("ChonkComputeVk - VK derived, size: ", verification_key.bytes.size(), " bytes");
325 return { .bytes = std::move(verification_key.bytes), .fields = std::move(verification_key.fields) };
326}
327
329{
330 BB_BENCH_NAME(MSGPACK_SCHEMA_NAME);
332 /*witness=*/{} };
333
334 if (circuit.verification_key.empty()) {
335 info("FAIL: Expected precomputed vk for function ", circuit.name);
336 throw_or_abort("Missing precomputed VK");
337 }
338
339 Response response;
340 auto check = check_precomputed_chonk_vk(program, circuit.verification_key, kind);
341 response.valid = check.valid;
342 response.actual_vk = std::move(check.actual_vk);
343 return response;
344}
345
347{
348 BB_BENCH_NAME(MSGPACK_SCHEMA_NAME);
349 Response response;
350
351 const auto constraint_system = acir_format::circuit_buf_to_mega_acir_format(std::move(circuit.bytecode));
352 acir_format::AcirProgram program{ constraint_system, {} };
353
354 // Get IVC constraints if any
355 const auto& ivc_constraints = constraint_system.hn_recursion_constraints;
356
357 // Create metadata with appropriate IVC context
359 .ivc = ivc_constraints.empty() ? nullptr : acir_format::create_mock_chonk_from_constraints(ivc_constraints),
360 .collect_gates_per_opcode = include_gates_per_opcode
361 };
362
363 // Create and finalize circuit
364 auto builder = acir_format::create_circuit<MegaCircuitBuilder>(program, metadata);
365 builder.finalize_circuit();
366
367 // Set response values
368 response.acir_opcodes = program.constraints.num_acir_opcodes;
369 response.circuit_size = static_cast<uint32_t>(builder.num_gates());
370
371 // Optionally include gates per opcode
372 if (include_gates_per_opcode) {
373 response.gates_per_opcode = std::vector<uint32_t>(program.constraints.gates_per_opcode.begin(),
374 program.constraints.gates_per_opcode.end());
375 }
376
377 // Log circuit details
378 info("ChonkStats - circuit: ",
379 circuit.name,
380 ", acir_opcodes: ",
381 response.acir_opcodes,
382 ", circuit_size: ",
383 response.circuit_size);
384
385 // Print execution trace details
386 builder.blocks.summarize();
387
388 return response;
389}
390
392{
393 BB_BENCH_NAME(MSGPACK_SCHEMA_NAME);
394 return { .compressed_proof = ProofCompressor::compress_chonk_proof(proof) };
395}
396
398{
399 BB_BENCH_NAME(MSGPACK_SCHEMA_NAME);
400 size_t mega_num_pub = ProofCompressor::compressed_mega_num_public_inputs(compressed_proof.size());
401 return { .proof = ProofCompressor::decompress_chonk_proof(compressed_proof, mega_num_pub) };
402}
403
404// ── Batch Verifier Service ──────────────────────────────────────────────────
405
406#ifdef BB_HAS_BATCH_VERIFIER_SERVICE
407
408namespace {
409
410bool write_all(int fd, const uint8_t* ptr, size_t len)
411{
412 while (len > 0) {
413 // ::write takes a size_t count on POSIX but an unsigned int on Windows (MinGW _write), so cap each
414 // call to INT_MAX and cast explicitly to keep the count in range and the return value representable.
415 const auto chunk = static_cast<unsigned int>(std::min(len, static_cast<size_t>(INT_MAX)));
416 const ssize_t written = ::write(fd, ptr, chunk);
417 if (written > 0) {
418 ptr += written;
419 len -= static_cast<size_t>(written);
420 continue;
421 }
422 if (written < 0 && errno == EINTR) {
423 continue;
424 }
425 if (written < 0 && (errno == EAGAIN || errno == EWOULDBLOCK)) {
426 std::this_thread::sleep_for(std::chrono::milliseconds(1));
427 continue;
428 }
429 return false;
430 }
431 return true;
432}
433
439bool write_frame(int fd, const void* data, size_t len)
440{
441 if (len > UINT32_MAX) {
442 return false;
443 }
444 auto len32 = static_cast<uint32_t>(len);
445 std::vector<uint8_t> header = {
446 static_cast<uint8_t>((len32 >> 24) & 0xFF),
447 static_cast<uint8_t>((len32 >> 16) & 0xFF),
448 static_cast<uint8_t>((len32 >> 8) & 0xFF),
449 static_cast<uint8_t>(len32 & 0xFF),
450 };
451
452 return write_all(fd, header.data(), header.size()) && write_all(fd, reinterpret_cast<const uint8_t*>(data), len);
453}
454
455} // namespace
456
457void ChonkBatchVerifierService::start(std::vector<std::shared_ptr<MegaZKFlavor::VKAndHash>> vks,
458 uint32_t num_cores,
459 uint32_t batch_size,
460 const std::string& fifo_path)
461{
462 bool expected = false;
463 if (!running_.compare_exchange_strong(expected, true)) {
464 throw_or_abort("ChonkBatchVerifierService: already running");
465 }
466
467 if (num_cores == 0) {
468 num_cores = static_cast<uint32_t>(std::thread::hardware_concurrency());
469 if (num_cores == 0) {
470 num_cores = 1;
471 }
472 }
473
474#ifdef SIGPIPE
475 (void)std::signal(SIGPIPE, SIG_IGN);
476#endif
477 fifo_path_ = fifo_path;
478 fifo_failed_.store(false);
479
480 try {
481 verifier_.start(
482 std::move(vks), num_cores, batch_size, [this](VerifyResult result) { write_result(std::move(result)); });
483 } catch (...) {
484 running_.store(false);
485 throw;
486 }
487
488 info("ChonkBatchVerifierService started, fifo=", fifo_path);
489}
490
491void ChonkBatchVerifierService::enqueue(VerifyRequest request)
492{
493 if (fifo_failed_.load()) {
494 throw_or_abort("ChonkBatchVerifierService: result FIFO failed");
495 }
496 verifier_.enqueue(std::move(request));
497}
498
499void ChonkBatchVerifierService::fail_request(uint64_t request_id, std::string error_message)
500{
501 write_result(VerifyResult::failed(request_id, std::move(error_message)));
502}
503
504void ChonkBatchVerifierService::stop()
505{
506 if (!running_.exchange(false)) {
507 return;
508 }
509
510 // Stop the processor first; callbacks synchronously write remaining results.
511 verifier_.stop();
512
513 {
514 std::lock_guard lock(fifo_mutex_);
515 close_fifo_locked();
516 fifo_path_.clear();
517 }
518
519 info("ChonkBatchVerifierService stopped");
520}
521
522ChonkBatchVerifierService::~ChonkBatchVerifierService()
523{
524 if (running_.load()) {
525 stop();
526 }
527}
528
529bool ChonkBatchVerifierService::ensure_fifo_open()
530{
531 if (fifo_fd_ >= 0) {
532 return true;
533 }
534 if (fifo_path_.empty()) {
535 return false;
536 }
537
538#ifndef _WIN32
539 struct stat statbuf;
540 if (lstat(fifo_path_.c_str(), &statbuf) != 0) {
541 info("ChonkBatchVerifierService: failed to stat FIFO '", fifo_path_, "': ", std::strerror(errno));
542 return false;
543 }
544 if (!S_ISFIFO(statbuf.st_mode)) {
545 info("ChonkBatchVerifierService: result path is not a FIFO: ", fifo_path_);
546 return false;
547 }
548#endif
549
550 for (size_t attempt = 0; attempt < 100; ++attempt) {
551#ifndef _WIN32
552 fifo_fd_ = open(fifo_path_.c_str(), O_WRONLY | O_NONBLOCK | O_CLOEXEC | O_NOFOLLOW);
553#else
554 fifo_fd_ = open(fifo_path_.c_str(), O_WRONLY);
555#endif
556 if (fifo_fd_ >= 0) {
557#ifndef _WIN32
558 struct stat opened_statbuf;
559 if (fstat(fifo_fd_, &opened_statbuf) != 0 || !S_ISFIFO(opened_statbuf.st_mode)) {
560 info("ChonkBatchVerifierService: opened result path is not a FIFO: ", fifo_path_);
561 close(fifo_fd_);
562 fifo_fd_ = -1;
563 return false;
564 }
565#endif
566 return true;
567 }
568 if (errno != ENXIO && errno != EINTR) {
569 info("ChonkBatchVerifierService: failed to open FIFO '", fifo_path_, "': ", std::strerror(errno));
570 return false;
571 }
572 std::this_thread::sleep_for(std::chrono::milliseconds(1));
573 }
574 info("ChonkBatchVerifierService: no FIFO reader connected for '", fifo_path_, "'");
575 return false;
576}
577
578void ChonkBatchVerifierService::close_fifo_locked()
579{
580 if (fifo_fd_ >= 0) {
581 close(fifo_fd_);
582 fifo_fd_ = -1;
583 }
584}
585
586bool ChonkBatchVerifierService::fail_fifo_locked(const std::string& message)
587{
588 if (!fifo_failed_.exchange(true)) {
589 // A fatal result path cannot report per-request failure; close it so readers fail the batch.
590 info("ChonkBatchVerifierService: ", message);
591 }
592 close_fifo_locked();
593 fifo_path_.clear();
594 return false;
595}
596
597bool ChonkBatchVerifierService::write_result(VerifyResult result)
598{
599 msgpack::sbuffer buf;
600 msgpack::pack(buf, result);
601
602 std::lock_guard lock(fifo_mutex_);
603 if (fifo_failed_.load()) {
604 return false;
605 }
606 if (!ensure_fifo_open()) {
607 return fail_fifo_locked("result FIFO unavailable");
608 }
609
610 if (!write_frame(fifo_fd_, buf.data(), buf.size())) {
611 return fail_fifo_locked(std::string("FIFO write failed: ") + std::strerror(errno));
612 }
613 return true;
614}
615
616ChonkBatchVerifierStart::Response ChonkBatchVerifierStart::execute(BBApiRequest& request) &&
617{
618 if (request.batch_verifier_service && request.batch_verifier_service->is_running()) {
619 throw_or_abort("ChonkBatchVerifierStart: service already running. Call ChonkBatchVerifierStop first.");
620 }
621
623 parsed_vks.reserve(vks.size());
624
625 for (size_t i = 0; i < vks.size(); ++i) {
626 parsed_vks.push_back(deserialize_chonk_vk_and_hash(vks[i]));
627 }
628
629 request.batch_verifier_service = std::make_shared<ChonkBatchVerifierService>();
630 request.batch_verifier_service->start(std::move(parsed_vks), num_cores, batch_size, fifo_path);
631 return {};
632}
633
634// Queue commands report per-request failures through the result FIFO; throwing loses the request id.
635ChonkBatchVerifierQueue::Response ChonkBatchVerifierQueue::execute(BBApiRequest& request) &&
636{
637 if (!request.batch_verifier_service || !request.batch_verifier_service->is_running()) {
638 throw_or_abort("ChonkBatchVerifierQueue: service not running. Call ChonkBatchVerifierStart first.");
639 }
640
641 ChonkProof proof;
642 try {
643 proof = ChonkProof::from_field_elements(proof_fields);
644 } catch (const std::exception& e) {
645 request.batch_verifier_service->fail_request(request_id, std::string("malformed proof fields: ") + e.what());
646 return {};
647 } catch (...) {
648 request.batch_verifier_service->fail_request(request_id, "malformed proof fields: unknown exception");
649 return {};
650 }
651
652 try {
653 request.batch_verifier_service->enqueue(VerifyRequest{
654 .request_id = request_id,
655 .vk_index = vk_index,
656 .proof = std::move(proof),
657 });
658 } catch (const std::exception& e) {
659 request.batch_verifier_service->fail_request(request_id, e.what());
660 } catch (...) {
661 request.batch_verifier_service->fail_request(request_id, "failed to enqueue proof: unknown exception");
662 }
663
664 return {};
665}
666
667ChonkBatchVerifierStop::Response ChonkBatchVerifierStop::execute(BBApiRequest& request) &&
668{
669 if (!request.batch_verifier_service || !request.batch_verifier_service->is_running()) {
670 throw_or_abort("ChonkBatchVerifierStop: service not running.");
671 }
672
673 request.batch_verifier_service->stop();
674 request.batch_verifier_service.reset();
675 return {};
676}
677
678#else // BB_HAS_BATCH_VERIFIER_SERVICE
679
681{
682 throw_or_abort("ChonkBatchVerifierStart is not supported on this platform (wasm/Windows)");
683}
684
686{
687 throw_or_abort("ChonkBatchVerifierQueue is not supported on this platform (wasm/Windows)");
688}
689
691{
692 throw_or_abort("ChonkBatchVerifierStop is not supported on this platform (wasm/Windows)");
693}
694
695#endif // BB_HAS_BATCH_VERIFIER_SERVICE
696
697#undef BBAPI_CHONK_EXCEPTION_WHAT
698
699} // namespace bb::bbapi
#define BB_BENCH_NAME(name)
Definition bb_bench.hpp:264
#define BBAPI_CHONK_EXCEPTION_WHAT(exception)
Chonk-specific command definitions for the Barretenberg RPC API.
MegaZKFlavor::VerificationKey MegaZKVerificationKey
Definition chonk.hpp:53
Verifier for Chonk IVC proofs (both native and recursive).
TripleIpaReductionResult reduce_to_triple_ipa_opening(const Proof &proof)
Run Chonk verification up to but not including TripleIPA verification.
Output verify(const Proof &proof)
Verify a Chonk proof.
static bool batch_verify_accumulators(std::span< const TripleIpaAccumulator > accumulators)
Base Native verification key class.
Definition flavor.hpp:138
static constexpr size_t calc_num_data_types()
Calculate the number of field elements needed for serialization.
Definition flavor.hpp:202
static std::vector< uint8_t > compress_chonk_proof(const ChonkProof &proof)
static ChonkProof decompress_chonk_proof(const std::vector< uint8_t > &compressed, size_t mega_num_public_inputs)
static size_t compressed_mega_num_public_inputs(size_t compressed_bytes)
Derive mega_num_public_inputs from compressed proof size.
#define info(...)
Definition log.hpp:93
AluTraceBuilder builder
Definition alu.test.cpp:124
std::string label
WitnessVector witness_buf_to_witness_vector(std::vector< uint8_t > &&buf)
Convert a buffer representing a witness vector into Barretenberg's internal WitnessVector format.
std::shared_ptr< Chonk > create_mock_chonk_from_constraints(const std::vector< RecursionConstraint > &constraints)
Create a Chonk instance with mocked state corresponding to a set of IVC recursion constraints.
AcirFormat circuit_buf_to_mega_acir_format(std::vector< uint8_t > &&buf)
Specialization for Mega constructor.
std::vector< bb::fr > WitnessVector
bool has_expected_vk_size(const std::vector< uint8_t > &vk_bytes, const char *label)
VkPolicy
Policy for handling verification keys during IVC accumulation.
field< Bn254FrParams > fr
Definition fr.hpp:155
void write(B &buf, field2< base_field, Params > const &value)
std::shared_ptr< MegaZKFlavor::VKAndHash > deserialize_chonk_vk_and_hash(const std::vector< uint8_t > &vk)
ChonkVkCheckResult check_precomputed_chonk_vk(acir_format::AcirProgram &program, const std::vector< uint8_t > &precomputed_vk, CircuitKind kind)
std::shared_ptr< Chonk::MegaZKVerificationKey > deserialize_chonk_vk(const std::vector< uint8_t > &vk)
ChonkVkData compute_chonk_vk(acir_format::AcirProgram &program, CircuitKind kind)
VerifierCommitmentKey< Curve > vk
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13
uint8_t len
std::byte * data
Struct containing both the constraints to be added to the circuit and the witness vector.
Metadata required to create a circuit.
std::shared_ptr< bb::Chonk > ivc
static constexpr size_t PROOF_LENGTH_WITHOUT_PUB_INPUTS
static ChonkProof_ from_field_elements(const std::vector< FF > &fields)
Reconstruct proof from field elements.
A request to verify a single Chonk proof.
Result of verifying a single proof within a batch.
static VerifyResult failed(uint64_t id, std::string msg)
Empty response indicating successful circuit accumulation.
Response execute(BBApiRequest &request) &&
Response execute(BBApiRequest &request) &&
Response execute(BBApiRequest &request) &&
Response execute(BBApiRequest &request) &&
Response execute(const BBApiRequest &request={}) &&
Contains the validation result.
std::vector< uint8_t > actual_vk
The actual VK it should be.
bool valid
True if the precomputed VK matches the circuit.
Response execute(const BBApiRequest &request={}) &&
Response execute(const BBApiRequest &request={}) &&
Contains the computed verification key in multiple formats.
Response execute(const BBApiRequest &request={}) &&
Response execute(const BBApiRequest &request={}) &&
Empty response indicating successful circuit loading.
Response execute(BBApiRequest &request) &&
Contains the generated IVC proof.
ChonkProof proof
Complete IVC proof for all accumulated circuits.
Response execute(BBApiRequest &request) &&
Empty response indicating successful initialization.
Response execute(BBApiRequest &request) &&
Contains gate count information.
uint32_t circuit_size
Circuit size (total number of gates)
uint32_t acir_opcodes
Number of ACIR opcodes.
std::vector< uint32_t > gates_per_opcode
Optional: gate counts per opcode.
Response execute(BBApiRequest &request) &&
Contains the verification result.
Response execute(const BBApiRequest &request={}) &&
Response execute(const BBApiRequest &request={}) &&
void throw_or_abort(std::string const &err)
VectorField result