31 request.ivc_stack_depth = 0;
35 request.loaded_circuit_name.clear();
36 request.loaded_circuit_constraints.reset();
37 request.loaded_circuit_vk.clear();
45 if (!request.ivc_in_progress) {
49 request.loaded_circuit_name = circuit.name;
51 request.loaded_circuit_vk = circuit.verification_key;
53 info(
"ChonkLoad - loaded circuit '", request.loaded_circuit_name,
"'");
61 if (!request.ivc_in_progress) {
65 if (!request.loaded_circuit_constraints.has_value()) {
75 auto loaded_vk =
std::move(request.loaded_circuit_vk);
76 auto circuit_name =
std::move(request.loaded_circuit_name);
77 request.loaded_circuit_constraints.reset();
78 request.loaded_circuit_vk.clear();
79 request.loaded_circuit_name.clear();
83 const bool is_hiding_kernel = (request.ivc_stack_depth + 1 == chonk->get_num_circuits());
86 auto circuit = acir_format::create_circuit<IVCBase::ClientCircuit>(program, metadata);
91 precomputed_vk =
nullptr;
93 if (!loaded_vk.empty()) {
94 validate_vk_size<Chonk::MegaVerificationKey>(loaded_vk);
95 precomputed_vk = from_buffer<std::shared_ptr<Chonk::MegaVerificationKey>>(loaded_vk);
106 if (*precomputed_vk != *computed_vk) {
108 "': provided VK does not match computed VK");
113 throw_or_abort(
"Invalid VK policy. Valid options: default, check, recompute");
116 info(
"ChonkAccumulate - accumulating circuit '", circuit_name,
"'");
120 request.ivc_in_progress->accumulate(circuit, precomputed_vk);
121 request.ivc_stack_depth++;
129 if (!request.ivc_in_progress) {
133 if (request.ivc_stack_depth == 0) {
134 throw_or_abort(
"No circuits accumulated. Call ChonkAccumulate first.");
137 info(
"ChonkProve - generating proof for ", request.ivc_stack_depth,
" accumulated circuits");
141 bool verification_passed =
false;
143 info(
"ChonkProve - using Chonk");
145 auto proof = chonk->prove();
146 auto vk_and_hash = chonk->get_hiding_kernel_vk_and_hash();
150 info(
"ChonkProve - verifying the generated proof as a sanity check");
152 verification_passed = verifier.
verify(proof);
154 if (!verification_passed) {
160 request.ivc_in_progress.reset();
161 request.ivc_stack_depth = 0;
171 validate_vk_size<VerificationKey>(
vk);
177 const size_t expected_proof_size =
179 if (proof.size() != expected_proof_size) {
187 const bool verified = verifier.
verify(proof);
189 return { .valid = verified };
197 validate_vk_size<VerificationKey>(
vk);
202 const size_t expected_field_count =
204 if (proof.size() != expected_field_count) {
205 throw_or_abort(
"ChonkVerifyFromFields: proof has wrong field count: expected " +
214 const bool verified = verifier.
verify(structured);
216 return { .valid = verified };
223 if (proofs.size() != vks.size()) {
227 if (proofs.empty()) {
236 ipa_claims.reserve(proofs.size());
237 ipa_transcripts.reserve(proofs.size());
239 for (
size_t i = 0; i < proofs.size(); ++i) {
240 validate_vk_size<VerificationKey>(vks[i]);
243 const size_t expected_proof_size =
245 if (proofs[i].size() != expected_proof_size) {
253 if (!result.all_checks_passed) {
254 return { .valid =
false };
256 ipa_claims.push_back(
std::move(result.ipa_claim));
264 return { .valid = verified };
281 info(
"ChonkComputeVk - deriving MegaVerificationKey for circuit '",
284 use_zk_flavor ?
" (MegaZK)" :
"");
289 auto verification_key = compute_chonk_vk_from_program(program, use_zk_flavor);
291 info(
"ChonkComputeVk - VK derived, size: ",
to_buffer(*verification_key).size(),
" bytes");
293 return { .bytes =
to_buffer(*verification_key), .fields = verification_key->to_field_elements() };
302 auto computed_vk = compute_chonk_vk_from_program(program, use_zk_flavor);
304 if (circuit.verification_key.empty()) {
305 info(
"FAIL: Expected precomputed vk for function ", circuit.name);
309 validate_vk_size<Chonk::MegaVerificationKey>(circuit.verification_key);
312 auto precomputed_vk = from_buffer<std::shared_ptr<Chonk::MegaVerificationKey>>(circuit.verification_key);
315 response.
valid =
true;
316 if (*computed_vk != *precomputed_vk) {
317 response.valid =
false;
318 response.actual_vk =
to_buffer(computed_vk);
332 const auto& ivc_constraints = constraint_system.hn_recursion_constraints;
337 .collect_gates_per_opcode = include_gates_per_opcode
341 auto builder = acir_format::create_circuit<MegaCircuitBuilder>(program, metadata);
349 if (include_gates_per_opcode) {
355 info(
"ChonkStats - circuit: ",
388 const std::string& fifo_path)
391 info(
"ChonkBatchVerifierService: already running, ignoring start()");
395 if (num_cores == 0) {
396 num_cores =
static_cast<uint32_t
>(std::thread::hardware_concurrency());
397 if (num_cores == 0) {
417 info(
"ChonkBatchVerifierService started, fifo=", fifo_path);
446 info(
"ChonkBatchVerifierService stopped");
459 int fd = open(fifo_path.c_str(), O_WRONLY);
461 info(
"ChonkBatchVerifierService: failed to open FIFO '", fifo_path,
"': ", strerror(errno));
482 msgpack::sbuffer buf;
483 msgpack::pack(buf, result);
486 info(
"ChonkBatchVerifierService: FIFO write failed, stopping writer");
498 if (request.batch_verifier_service && request.batch_verifier_service->is_running()) {
499 throw_or_abort(
"ChonkBatchVerifierStart: service already running. Call ChonkBatchVerifierStop first.");
505 parsed_vks.reserve(vks.size());
507 for (
size_t i = 0; i < vks.size(); ++i) {
508 validate_vk_size<VerificationKey>(vks[i]);
514 request.batch_verifier_service->start(
std::move(parsed_vks), num_cores, batch_size, fifo_path);
520 if (!request.batch_verifier_service || !request.batch_verifier_service->is_running()) {
521 throw_or_abort(
"ChonkBatchVerifierQueue: service not running. Call ChonkBatchVerifierStart first.");
526 .vk_index = vk_index,
535 if (!request.batch_verifier_service || !request.batch_verifier_service->is_running()) {
539 request.batch_verifier_service->stop();
540 request.batch_verifier_service.reset();
548 throw_or_abort(
"ChonkBatchVerifierStart is not supported in WASM builds");
553 throw_or_abort(
"ChonkBatchVerifierQueue is not supported in WASM builds");
558 throw_or_abort(
"ChonkBatchVerifierStop is not supported in WASM builds");
#define BB_BENCH_NAME(name)
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
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.
Base Native verification key class.
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)
~ChonkBatchVerifierService()
ChonkBatchVerifier verifier_
void writer_loop(const std::string &fifo_path)
std::queue< VerifyResult > result_queue_
std::condition_variable result_cv_
std::thread writer_thread_
void start(std::vector< std::shared_ptr< MegaZKFlavor::VKAndHash > > vks, uint32_t num_cores, uint32_t batch_size, const std::string &fifo_path)
MemoryProfile GLOBAL_MEMORY_PROFILE
bool write_frame(int fd, const void *data, size_t len)
Write a length-delimited frame to a file descriptor.
VerifierCommitmentKey< Curve > vk
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
std::string to_string(bb::avm2::ValueTag tag)
std::vector< uint8_t > to_buffer(T const &value)
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.
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)