Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
bbapi_chonk.cpp
Go to the documentation of this file.
18
19#ifndef __wasm__
20#include <algorithm>
21#include <cerrno>
22#include <chrono>
23#include <csignal>
24#include <cstring>
25#include <fcntl.h>
26#include <limits>
27#include <sys/stat.h>
28#include <thread>
29#include <unistd.h>
30#endif
31
32namespace bb::bbapi {
33
34// BB_NO_EXCEPTIONS rewrites catch blocks away; handlers must not depend on catch bindings.
35#ifndef BB_NO_EXCEPTIONS
36#define BBAPI_CHONK_EXCEPTION_WHAT(exception) (exception).what()
37#else
38#define BBAPI_CHONK_EXCEPTION_WHAT(exception) "unknown exception"
39#endif
40
41template <typename VerificationKey> bool has_expected_vk_size(const std::vector<uint8_t>& vk_bytes, const char* label)
42{
43 const size_t expected_size = VerificationKey::calc_num_data_types() * sizeof(bb::fr);
44 if (vk_bytes.size() == expected_size) {
45 return true;
46 }
47 // Wasm builds cannot catch throw_or_abort from validate_vk_size.
48 info(label, ": verification key has wrong size: expected ", expected_size, ", got ", vk_bytes.size());
49 return false;
50}
51
53{
54 BB_BENCH_NAME(MSGPACK_SCHEMA_NAME);
55
56 request.ivc_in_progress = std::make_shared<Chonk>(num_circuits);
57 request.ivc_stack_depth = 0;
58
59 // Clear any stale loaded-circuit state from a previous session so that
60 // ChonkAccumulate cannot silently reuse a circuit loaded before this ChonkStart.
61 request.loaded_circuit_name.clear();
62 request.loaded_circuit_constraints.reset();
63 request.loaded_circuit_vk.clear();
64
65 return Response{};
66}
67
69{
70 BB_BENCH_NAME(MSGPACK_SCHEMA_NAME);
71 if (!request.ivc_in_progress) {
72 throw_or_abort("Chonk not started. Call ChonkStart first.");
73 }
74
75 request.loaded_circuit_name = circuit.name;
76 request.loaded_circuit_constraints = acir_format::circuit_buf_to_acir_format(std::move(circuit.bytecode));
77 request.loaded_circuit_vk = circuit.verification_key;
78
79 info("ChonkLoad - loaded circuit '", request.loaded_circuit_name, "'");
80
81 return Response{};
82}
83
85{
86 BB_BENCH_NAME(MSGPACK_SCHEMA_NAME);
87 if (!request.ivc_in_progress) {
88 throw_or_abort("Chonk not started. Call ChonkStart first.");
89 }
90
91 if (!request.loaded_circuit_constraints.has_value()) {
92 throw_or_abort("No circuit loaded. Call ChonkLoad first.");
93 }
94
96 acir_format::AcirProgram program{ std::move(request.loaded_circuit_constraints.value()), std::move(witness_data) };
97
98 // Clear loaded state immediately after moving out of it. This ensures that if any subsequent
99 // step throws, the request won't appear to still have a valid circuit loaded (the optional
100 // would be in a moved-from state, which is technically has_value()==true but poisoned).
101 auto loaded_vk = std::move(request.loaded_circuit_vk);
102 auto circuit_name = std::move(request.loaded_circuit_name);
103 request.loaded_circuit_constraints.reset();
104 request.loaded_circuit_vk.clear();
105 request.loaded_circuit_name.clear();
106
107 // The hiding kernel (MegaZK) is definitionally the last circuit in the IVC stack; derive flag accordingly.
108 auto chonk = std::dynamic_pointer_cast<Chonk>(request.ivc_in_progress);
109 const bool is_hiding_kernel = (request.ivc_stack_depth + 1 == chonk->get_num_circuits());
110
111 const acir_format::ProgramMetadata metadata{ .ivc = request.ivc_in_progress };
112 auto circuit = acir_format::create_circuit<IVCBase::ClientCircuit>(program, metadata);
113
115
116 if (request.vk_policy == VkPolicy::RECOMPUTE) {
117 precomputed_vk = nullptr;
118 } else if (request.vk_policy == VkPolicy::DEFAULT || request.vk_policy == VkPolicy::CHECK) {
119 if (!loaded_vk.empty()) {
120 validate_vk_size<Chonk::MegaVerificationKey>(loaded_vk);
121 precomputed_vk = from_buffer<std::shared_ptr<Chonk::MegaVerificationKey>>(loaded_vk);
122
123 if (request.vk_policy == VkPolicy::CHECK) {
124 // Note that MegaZKVerificationKey = MegaVerificationKey as C++ classes but their content differs
125 // between ZK and non-ZK flavors.
126 auto computed_vk = is_hiding_kernel ? std::make_shared<Chonk::MegaVerificationKey>(
127 Chonk::HidingKernelProverInstance(circuit).get_precomputed())
129 Chonk::ProverInstance(circuit).get_precomputed());
130
131 // Dereference to compare VK contents
132 if (*precomputed_vk != *computed_vk) {
133 throw_or_abort("VK check failed for circuit '" + circuit_name +
134 "': provided VK does not match computed VK");
135 }
136 }
137 }
138 } else {
139 throw_or_abort("Invalid VK policy. Valid options: default, check, recompute");
140 }
141
142 info("ChonkAccumulate - accumulating circuit '", circuit_name, "'");
145 }
146 request.ivc_in_progress->accumulate(circuit, precomputed_vk);
147 request.ivc_stack_depth++;
148
149 return Response{};
150}
151
153{
154 BB_BENCH_NAME(MSGPACK_SCHEMA_NAME);
155 if (!request.ivc_in_progress) {
156 throw_or_abort("Chonk not started. Call ChonkStart first.");
157 }
158
159 if (request.ivc_stack_depth == 0) {
160 throw_or_abort("No circuits accumulated. Call ChonkAccumulate first.");
161 }
162
163 info("ChonkProve - generating proof for ", request.ivc_stack_depth, " accumulated circuits");
164
165 // Call prove and verify using the appropriate IVC type
166 Response response;
167 bool verification_passed = false;
168
169 info("ChonkProve - using Chonk");
170 auto chonk = std::dynamic_pointer_cast<Chonk>(request.ivc_in_progress);
171 auto proof = chonk->prove();
172 auto vk_and_hash = chonk->get_hiding_kernel_vk_and_hash();
173
174 // We verify this proof. Another bb call to verify has some overhead of loading VK/proof/SRS,
175 // and it is mysterious if this transaction fails later in the lifecycle.
176 info("ChonkProve - verifying the generated proof as a sanity check");
177 ChonkNativeVerifier verifier(vk_and_hash);
178 verification_passed = verifier.verify(proof);
179
180 if (!verification_passed) {
181 throw_or_abort("Failed to verify the generated proof!");
182 }
183
184 response.proof = std::move(proof);
185
186 request.ivc_in_progress.reset();
187 request.ivc_stack_depth = 0;
188
189 return response;
190}
191
193{
194 BB_BENCH_NAME(MSGPACK_SCHEMA_NAME);
195
196 try {
198 if (!has_expected_vk_size<VerificationKey>(vk, "ChonkVerify")) {
199 return { .valid = false };
200 }
201
202 // Deserialize the hiding kernel verification key directly from buffer
203 auto hiding_kernel_vk = std::make_shared<VerificationKey>(from_buffer<VerificationKey>(vk));
204
205 // Validate total proof size: must match num_public_inputs + fixed overhead
206 const size_t expected_proof_size =
207 static_cast<size_t>(hiding_kernel_vk->num_public_inputs) + ChonkProof::PROOF_LENGTH_WITHOUT_PUB_INPUTS;
208 if (proof.size() != expected_proof_size) {
209 info("ChonkVerify: proof has wrong size: expected ", expected_proof_size, ", got ", proof.size());
210 return { .valid = false };
211 }
212
213 // Verify the proof using ChonkNativeVerifier
214 auto vk_and_hash = std::make_shared<ChonkNativeVerifier::VKAndHash>(hiding_kernel_vk);
215 ChonkNativeVerifier verifier(vk_and_hash);
216 const bool verified = verifier.verify(proof);
217
218 return { .valid = verified };
219 } catch (const std::exception& e) {
220 info("ChonkVerify: malformed input: ", BBAPI_CHONK_EXCEPTION_WHAT(e));
221 return { .valid = false };
222 } catch (...) {
223 info("ChonkVerify: malformed input: unknown exception");
224 return { .valid = false };
225 }
226}
227
229{
230 BB_BENCH_NAME(MSGPACK_SCHEMA_NAME);
231
232 try {
234 if (!has_expected_vk_size<VerificationKey>(vk, "ChonkVerifyFromFields")) {
235 return { .valid = false };
236 }
237
238 auto hiding_kernel_vk = std::make_shared<VerificationKey>(from_buffer<VerificationKey>(vk));
239
240 // Validate total field count: must match num_public_inputs + fixed overhead.
241 const size_t expected_field_count =
242 static_cast<size_t>(hiding_kernel_vk->num_public_inputs) + ChonkProof::PROOF_LENGTH_WITHOUT_PUB_INPUTS;
243 if (proof.size() != expected_field_count) {
244 info("ChonkVerifyFromFields: proof has wrong field count: expected ",
245 expected_field_count,
246 ", got ",
247 proof.size());
248 return { .valid = false };
249 }
250
251 // Split the flat field array into the structured ChonkProof. Layout knowledge stays here.
252 auto structured = ChonkProof::from_field_elements(proof);
253
254 auto vk_and_hash = std::make_shared<ChonkNativeVerifier::VKAndHash>(hiding_kernel_vk);
255 ChonkNativeVerifier verifier(vk_and_hash);
256 const bool verified = verifier.verify(structured);
257
258 return { .valid = verified };
259 } catch (const std::exception& e) {
260 info("ChonkVerifyFromFields: malformed input: ", BBAPI_CHONK_EXCEPTION_WHAT(e));
261 return { .valid = false };
262 } catch (...) {
263 info("ChonkVerifyFromFields: malformed input: unknown exception");
264 return { .valid = false };
265 }
266}
267
269{
270 BB_BENCH_NAME(MSGPACK_SCHEMA_NAME);
271
272 try {
273 if (proofs.size() != vks.size()) {
274 info("ChonkBatchVerify: proofs.size() (", proofs.size(), ") != vks.size() (", vks.size(), ")");
275 return { .valid = false };
276 }
277 if (proofs.empty()) {
278 info("ChonkBatchVerify: no proofs provided");
279 return { .valid = false };
280 }
281
283
284 // Phase 1: Run all non-IPA verification for each proof, collecting IPA claims
287 ipa_claims.reserve(proofs.size());
288 ipa_transcripts.reserve(proofs.size());
289
290 for (size_t i = 0; i < proofs.size(); ++i) {
291 if (!has_expected_vk_size<VerificationKey>(vks[i], "ChonkBatchVerify")) {
292 return { .valid = false };
293 }
294 auto hiding_kernel_vk = std::make_shared<VerificationKey>(from_buffer<VerificationKey>(vks[i]));
295
296 const size_t expected_proof_size =
297 static_cast<size_t>(hiding_kernel_vk->num_public_inputs) + ChonkProof::PROOF_LENGTH_WITHOUT_PUB_INPUTS;
298 if (proofs[i].size() != expected_proof_size) {
299 info("ChonkBatchVerify: proof[",
300 i,
301 "] has wrong size: expected ",
302 expected_proof_size,
303 ", got ",
304 proofs[i].size());
305 return { .valid = false };
306 }
307
308 auto vk_and_hash = std::make_shared<ChonkNativeVerifier::VKAndHash>(hiding_kernel_vk);
309 ChonkNativeVerifier verifier(vk_and_hash);
310 auto result = verifier.reduce_to_ipa_claim(std::move(proofs[i]));
311 if (!result.all_checks_passed) {
312 return { .valid = false };
313 }
314 ipa_claims.push_back(std::move(result.ipa_claim));
315 ipa_transcripts.push_back(std::make_shared<NativeTranscript>(std::move(result.ipa_proof)));
316 }
317
318 // Phase 2: Batch IPA verification
320 const bool verified = IPA<curve::Grumpkin>::batch_reduce_verify(ipa_vk, ipa_claims, ipa_transcripts);
321
322 return { .valid = verified };
323 } catch (const std::exception& e) {
324 info("ChonkBatchVerify: malformed input: ", BBAPI_CHONK_EXCEPTION_WHAT(e));
325 return { .valid = false };
326 } catch (...) {
327 info("ChonkBatchVerify: malformed input: unknown exception");
328 return { .valid = false };
329 }
330}
331
332static std::shared_ptr<Chonk::MegaVerificationKey> compute_chonk_vk_from_program(acir_format::AcirProgram& program,
333 bool use_zk_flavor)
334{
335 Chonk::ClientCircuit builder = acir_format::create_circuit<Chonk::ClientCircuit>(program);
336 if (use_zk_flavor) {
338 Chonk::HidingKernelProverInstance(builder).get_precomputed());
339 }
341}
342
344{
345 BB_BENCH_NAME(MSGPACK_SCHEMA_NAME);
346 info("ChonkComputeVk - deriving MegaVerificationKey for circuit '",
347 circuit.name,
348 "'",
349 use_zk_flavor ? " (MegaZK)" : "");
350
351 auto constraint_system = acir_format::circuit_buf_to_acir_format(std::move(circuit.bytecode));
352
353 acir_format::AcirProgram program{ constraint_system, /*witness=*/{} };
354 auto verification_key = compute_chonk_vk_from_program(program, use_zk_flavor);
355
356 info("ChonkComputeVk - VK derived, size: ", to_buffer(*verification_key).size(), " bytes");
357
358 return { .bytes = to_buffer(*verification_key), .fields = verification_key->to_field_elements() };
359}
360
362{
363 BB_BENCH_NAME(MSGPACK_SCHEMA_NAME);
365 /*witness=*/{} };
366
367 auto computed_vk = compute_chonk_vk_from_program(program, use_zk_flavor);
368
369 if (circuit.verification_key.empty()) {
370 info("FAIL: Expected precomputed vk for function ", circuit.name);
371 throw_or_abort("Missing precomputed VK");
372 }
373
374 validate_vk_size<Chonk::MegaVerificationKey>(circuit.verification_key);
375
376 // Deserialize directly from buffer
377 auto precomputed_vk = from_buffer<std::shared_ptr<Chonk::MegaVerificationKey>>(circuit.verification_key);
378
379 Response response;
380 response.valid = true;
381 if (*computed_vk != *precomputed_vk) {
382 response.valid = false;
383 response.actual_vk = to_buffer(computed_vk);
384 }
385 return response;
386}
387
389{
390 BB_BENCH_NAME(MSGPACK_SCHEMA_NAME);
391 Response response;
392
393 const auto constraint_system = acir_format::circuit_buf_to_acir_format(std::move(circuit.bytecode));
394 acir_format::AcirProgram program{ constraint_system, {} };
395
396 // Get IVC constraints if any
397 const auto& ivc_constraints = constraint_system.hn_recursion_constraints;
398
399 // Create metadata with appropriate IVC context
401 .ivc = ivc_constraints.empty() ? nullptr : acir_format::create_mock_chonk_from_constraints(ivc_constraints),
402 .collect_gates_per_opcode = include_gates_per_opcode
403 };
404
405 // Create and finalize circuit
406 auto builder = acir_format::create_circuit<MegaCircuitBuilder>(program, metadata);
407 builder.finalize_circuit();
408
409 // Set response values
410 response.acir_opcodes = program.constraints.num_acir_opcodes;
411 response.circuit_size = static_cast<uint32_t>(builder.num_gates());
412
413 // Optionally include gates per opcode
414 if (include_gates_per_opcode) {
415 response.gates_per_opcode = std::vector<uint32_t>(program.constraints.gates_per_opcode.begin(),
416 program.constraints.gates_per_opcode.end());
417 }
418
419 // Log circuit details
420 info("ChonkStats - circuit: ",
421 circuit.name,
422 ", acir_opcodes: ",
423 response.acir_opcodes,
424 ", circuit_size: ",
425 response.circuit_size);
426
427 // Print execution trace details
428 builder.blocks.summarize();
429
430 return response;
431}
432
434{
435 BB_BENCH_NAME(MSGPACK_SCHEMA_NAME);
436 return { .compressed_proof = ProofCompressor::compress_chonk_proof(proof) };
437}
438
440{
441 BB_BENCH_NAME(MSGPACK_SCHEMA_NAME);
442 size_t mega_num_pub = ProofCompressor::compressed_mega_num_public_inputs(compressed_proof.size());
443 return { .proof = ProofCompressor::decompress_chonk_proof(compressed_proof, mega_num_pub) };
444}
445
446// ── Batch Verifier Service ──────────────────────────────────────────────────
447
448#ifndef __wasm__
449
450namespace {
451
452bool write_all(int fd, const uint8_t* ptr, size_t len)
453{
454 while (len > 0) {
455 const auto chunk_len =
456 static_cast<unsigned int>(std::min<size_t>(len, std::numeric_limits<unsigned int>::max()));
457 const ssize_t written = ::write(fd, ptr, chunk_len);
458 if (written > 0) {
459 ptr += written;
460 len -= static_cast<size_t>(written);
461 continue;
462 }
463 if (written < 0 && errno == EINTR) {
464 continue;
465 }
466 if (written < 0 && (errno == EAGAIN || errno == EWOULDBLOCK)) {
467 std::this_thread::sleep_for(std::chrono::milliseconds(1));
468 continue;
469 }
470 return false;
471 }
472 return true;
473}
474
480bool write_frame(int fd, const void* data, size_t len)
481{
482 if (len > UINT32_MAX) {
483 return false;
484 }
485 auto len32 = static_cast<uint32_t>(len);
486 std::vector<uint8_t> header = {
487 static_cast<uint8_t>((len32 >> 24) & 0xFF),
488 static_cast<uint8_t>((len32 >> 16) & 0xFF),
489 static_cast<uint8_t>((len32 >> 8) & 0xFF),
490 static_cast<uint8_t>(len32 & 0xFF),
491 };
492
493 return write_all(fd, header.data(), header.size()) && write_all(fd, reinterpret_cast<const uint8_t*>(data), len);
494}
495
496} // namespace
497
499 uint32_t num_cores,
500 uint32_t batch_size,
501 const std::string& fifo_path)
502{
503 bool expected = false;
504 if (!running_.compare_exchange_strong(expected, true)) {
505 throw_or_abort("ChonkBatchVerifierService: already running");
506 }
507
508 if (num_cores == 0) {
509 num_cores = static_cast<uint32_t>(std::thread::hardware_concurrency());
510 if (num_cores == 0) {
511 num_cores = 1;
512 }
513 }
514
515#ifdef SIGPIPE
516 (void)std::signal(SIGPIPE, SIG_IGN);
517#endif
518 fifo_path_ = fifo_path;
519 fifo_failed_.store(false);
520
521 try {
523 std::move(vks), num_cores, batch_size, [this](VerifyResult result) { write_result(std::move(result)); });
524 } catch (...) {
525 running_.store(false);
526 throw;
527 }
528
529 info("ChonkBatchVerifierService started, fifo=", fifo_path);
530}
531
533{
534 if (fifo_failed_.load()) {
535 throw_or_abort("ChonkBatchVerifierService: result FIFO failed");
536 }
537 verifier_.enqueue(std::move(request));
538}
539
540void ChonkBatchVerifierService::fail_request(uint64_t request_id, std::string error_message)
541{
542 write_result(VerifyResult::failed(request_id, std::move(error_message)));
543}
544
546{
547 if (!running_.exchange(false)) {
548 return;
549 }
550
551 // Stop the processor first; callbacks synchronously write remaining results.
552 verifier_.stop();
553
554 {
555 std::lock_guard lock(fifo_mutex_);
557 fifo_path_.clear();
558 }
559
560 info("ChonkBatchVerifierService stopped");
561}
562
564{
565 if (running_.load()) {
566 stop();
567 }
568}
569
571{
572 if (fifo_fd_ >= 0) {
573 return true;
574 }
575 if (fifo_path_.empty()) {
576 return false;
577 }
578
579#ifndef _WIN32
580 struct stat statbuf;
581 if (lstat(fifo_path_.c_str(), &statbuf) != 0) {
582 info("ChonkBatchVerifierService: failed to stat FIFO '", fifo_path_, "': ", std::strerror(errno));
583 return false;
584 }
585 if (!S_ISFIFO(statbuf.st_mode)) {
586 info("ChonkBatchVerifierService: result path is not a FIFO: ", fifo_path_);
587 return false;
588 }
589#endif
590
591 for (size_t attempt = 0; attempt < 100; ++attempt) {
592#ifndef _WIN32
593 fifo_fd_ = open(fifo_path_.c_str(), O_WRONLY | O_NONBLOCK | O_CLOEXEC | O_NOFOLLOW);
594#else
595 fifo_fd_ = open(fifo_path_.c_str(), O_WRONLY);
596#endif
597 if (fifo_fd_ >= 0) {
598#ifndef _WIN32
599 struct stat opened_statbuf;
600 if (fstat(fifo_fd_, &opened_statbuf) != 0 || !S_ISFIFO(opened_statbuf.st_mode)) {
601 info("ChonkBatchVerifierService: opened result path is not a FIFO: ", fifo_path_);
602 close(fifo_fd_);
603 fifo_fd_ = -1;
604 return false;
605 }
606#endif
607 return true;
608 }
609 if (errno != ENXIO && errno != EINTR) {
610 info("ChonkBatchVerifierService: failed to open FIFO '", fifo_path_, "': ", std::strerror(errno));
611 return false;
612 }
613 std::this_thread::sleep_for(std::chrono::milliseconds(1));
614 }
615 info("ChonkBatchVerifierService: no FIFO reader connected for '", fifo_path_, "'");
616 return false;
617}
618
620{
621 if (fifo_fd_ >= 0) {
622 close(fifo_fd_);
623 fifo_fd_ = -1;
624 }
625}
626
627bool ChonkBatchVerifierService::fail_fifo_locked(const std::string& message)
628{
629 if (!fifo_failed_.exchange(true)) {
630 // A fatal result path cannot report per-request failure; close it so readers fail the batch.
631 info("ChonkBatchVerifierService: ", message);
632 }
634 fifo_path_.clear();
635 return false;
636}
637
639{
640 msgpack::sbuffer buf;
641 msgpack::pack(buf, result);
642
643 std::lock_guard lock(fifo_mutex_);
644 if (fifo_failed_.load()) {
645 return false;
646 }
647 if (!ensure_fifo_open()) {
648 return fail_fifo_locked("result FIFO unavailable");
649 }
650
651 if (!write_frame(fifo_fd_, buf.data(), buf.size())) {
652 return fail_fifo_locked(std::string("FIFO write failed: ") + std::strerror(errno));
653 }
654 return true;
655}
656
658{
659 if (request.batch_verifier_service && request.batch_verifier_service->is_running()) {
660 throw_or_abort("ChonkBatchVerifierStart: service already running. Call ChonkBatchVerifierStop first.");
661 }
662
664
666 parsed_vks.reserve(vks.size());
667
668 for (size_t i = 0; i < vks.size(); ++i) {
669 validate_vk_size<VerificationKey>(vks[i]);
670 auto vk = std::make_shared<VerificationKey>(from_buffer<VerificationKey>(vks[i]));
671 parsed_vks.push_back(std::make_shared<MegaZKFlavor::VKAndHash>(vk));
672 }
673
674 request.batch_verifier_service = std::make_shared<ChonkBatchVerifierService>();
675 request.batch_verifier_service->start(std::move(parsed_vks), num_cores, batch_size, fifo_path);
676 return {};
677}
678
679// Queue commands report per-request failures through the result FIFO; throwing loses the request id.
681{
682 if (!request.batch_verifier_service || !request.batch_verifier_service->is_running()) {
683 throw_or_abort("ChonkBatchVerifierQueue: service not running. Call ChonkBatchVerifierStart first.");
684 }
685
686 ChonkProof proof;
687 try {
688 proof = ChonkProof::from_field_elements(proof_fields);
689 } catch (const std::exception& e) {
690 request.batch_verifier_service->fail_request(request_id, std::string("malformed proof fields: ") + e.what());
691 return {};
692 } catch (...) {
693 request.batch_verifier_service->fail_request(request_id, "malformed proof fields: unknown exception");
694 return {};
695 }
696
697 try {
698 request.batch_verifier_service->enqueue(VerifyRequest{
699 .request_id = request_id,
700 .vk_index = vk_index,
701 .proof = std::move(proof),
702 });
703 } catch (const std::exception& e) {
704 request.batch_verifier_service->fail_request(request_id, e.what());
705 } catch (...) {
706 request.batch_verifier_service->fail_request(request_id, "failed to enqueue proof: unknown exception");
707 }
708
709 return {};
710}
711
713{
714 if (!request.batch_verifier_service || !request.batch_verifier_service->is_running()) {
715 throw_or_abort("ChonkBatchVerifierStop: service not running.");
716 }
717
718 request.batch_verifier_service->stop();
719 request.batch_verifier_service.reset();
720 return {};
721}
722
723#else // __wasm__
724
726{
727 throw_or_abort("ChonkBatchVerifierStart is not supported in WASM builds");
728}
729
730ChonkBatchVerifierQueue::Response ChonkBatchVerifierQueue::execute(BBApiRequest& /*request*/) &&
731{
732 throw_or_abort("ChonkBatchVerifierQueue is not supported in WASM builds");
733}
734
735ChonkBatchVerifierStop::Response ChonkBatchVerifierStop::execute(BBApiRequest& /*request*/) &&
736{
737 throw_or_abort("ChonkBatchVerifierStop is not supported in WASM builds");
738}
739
740#endif // __wasm__
741
742#undef BBAPI_CHONK_EXCEPTION_WHAT
743
744} // 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.
void enqueue(VerifyRequest request)
Enqueue a proof for verification.
void stop()
Stop the processor, flushing remaining proofs.
void start(std::vector< std::shared_ptr< MegaZKFlavor::VKAndHash > > vks, uint32_t num_cores, uint32_t batch_size, ResultCallback on_result)
Start the coordinator thread.
Flavor::VerificationKey MegaVerificationKey
Definition chonk.hpp:44
Verifier for Chonk IVC proofs (both native and recursive).
IPAReductionResult reduce_to_ipa_claim(const Proof &proof)
Run Chonk verification up to but not including IPA, returning the IPA claim for deferred verification...
Output verify(const Proof &proof)
Verify a Chonk proof.
static constexpr size_t ECCVM_FIXED_SIZE
IPA (inner product argument) commitment scheme class.
Definition ipa.hpp:86
Base Native verification key class.
Definition flavor.hpp:137
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.
Contains all the information required by a Honk prover to create a proof, constructed from a finalize...
Representation of the Grumpkin Verifier Commitment Key inside a bn254 circuit.
void enqueue(VerifyRequest request)
void fail_request(uint64_t request_id, std::string error_message)
bool write_result(VerifyResult result)
void start(std::vector< std::shared_ptr< MegaZKFlavor::VKAndHash > > vks, uint32_t num_cores, uint32_t batch_size, const std::string &fifo_path)
bool fail_fifo_locked(const std::string &message)
#define info(...)
Definition log.hpp:93
AluTraceBuilder builder
Definition alu.test.cpp:124
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.
std::vector< bb::fr > WitnessVector
AcirFormat circuit_buf_to_acir_format(std::vector< uint8_t > &&buf)
Convert a buffer representing a circuit into Barretenberg's internal AcirFormat representation.
bool has_expected_vk_size(const std::vector< uint8_t > &vk_bytes, const char *label)
bool use_memory_profile
MemoryProfile GLOBAL_MEMORY_PROFILE
field< Bn254FrParams > fr
Definition fr.hpp:155
void write(B &buf, field2< base_field, Params > const &value)
VerifierCommitmentKey< Curve > vk
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13
uint8_t len
std::byte * data
std::vector< uint8_t > to_buffer(T const &value)
std::vector< size_t > gates_per_opcode
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::IVCBase > 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.
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 set_circuit_name(const std::string &name)
void throw_or_abort(std::string const &err)