Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
bbapi_chonk.cpp
Go to the documentation of this file.
12
13namespace bb::bbapi {
14
16{
17 BB_BENCH_NAME(MSGPACK_SCHEMA_NAME);
18
19 request.ivc_in_progress = std::make_shared<Chonk>(num_circuits);
20
21 request.ivc_stack_depth = 0;
22 return Response{};
23}
24
26{
27 BB_BENCH_NAME(MSGPACK_SCHEMA_NAME);
28 if (!request.ivc_in_progress) {
29 throw_or_abort("Chonk not started. Call ChonkStart first.");
30 }
31
32 request.loaded_circuit_name = circuit.name;
33 request.loaded_circuit_constraints = acir_format::circuit_buf_to_acir_format(std::move(circuit.bytecode));
34 request.loaded_circuit_vk = circuit.verification_key;
35
36 info("ChonkLoad - loaded circuit '", request.loaded_circuit_name, "'");
37
38 return Response{};
39}
40
42{
43 BB_BENCH_NAME(MSGPACK_SCHEMA_NAME);
44 if (!request.ivc_in_progress) {
45 throw_or_abort("Chonk not started. Call ChonkStart first.");
46 }
47
48 if (!request.loaded_circuit_constraints.has_value()) {
49 throw_or_abort("No circuit loaded. Call ChonkLoad first.");
50 }
51
53 acir_format::AcirProgram program{ std::move(request.loaded_circuit_constraints.value()), std::move(witness_data) };
54
55 const acir_format::ProgramMetadata metadata{ .ivc = request.ivc_in_progress };
56 auto circuit = acir_format::create_circuit<IVCBase::ClientCircuit>(program, metadata);
57
59
60 if (request.vk_policy == VkPolicy::RECOMPUTE) {
61 precomputed_vk = nullptr;
62 } else if (request.vk_policy == VkPolicy::DEFAULT || request.vk_policy == VkPolicy::CHECK) {
63 if (!request.loaded_circuit_vk.empty()) {
64 precomputed_vk = from_buffer<std::shared_ptr<Chonk::MegaVerificationKey>>(request.loaded_circuit_vk);
65
66 if (request.vk_policy == VkPolicy::CHECK) {
67 auto prover_instance = std::make_shared<Chonk::ProverInstance>(circuit);
68 auto computed_vk = std::make_shared<Chonk::MegaVerificationKey>(prover_instance->get_precomputed());
69
70 // Dereference to compare VK contents
71 if (*precomputed_vk != *computed_vk) {
72 throw_or_abort("VK check failed for circuit '" + request.loaded_circuit_name +
73 "': provided VK does not match computed VK");
74 }
75 }
76 }
77 } else {
78 throw_or_abort("Invalid VK policy. Valid options: default, check, recompute");
79 }
80
81 info("ChonkAccumulate - accumulating circuit '", request.loaded_circuit_name, "'");
82 request.ivc_in_progress->accumulate(circuit, precomputed_vk);
83 request.ivc_stack_depth++;
84
85 request.loaded_circuit_constraints.reset();
86 request.loaded_circuit_vk.clear();
87
88 return Response{};
89}
90
92{
93 BB_BENCH_NAME(MSGPACK_SCHEMA_NAME);
94 if (!request.ivc_in_progress) {
95 throw_or_abort("Chonk not started. Call ChonkStart first.");
96 }
97
98 if (request.ivc_stack_depth == 0) {
99 throw_or_abort("No circuits accumulated. Call ChonkAccumulate first.");
100 }
101
102 info("ChonkProve - generating proof for ", request.ivc_stack_depth, " accumulated circuits");
103
104 // Call prove and verify using the appropriate IVC type
105 Response response;
106 bool verification_passed = false;
107
108 info("ChonkProve - using Chonk");
109 auto sumcheck_ivc = std::dynamic_pointer_cast<Chonk>(request.ivc_in_progress);
110 auto proof = sumcheck_ivc->prove();
111 auto vk = sumcheck_ivc->get_vk();
112
113 // We verify this proof. Another bb call to verify has some overhead of loading VK/proof/SRS,
114 // and it is mysterious if this transaction fails later in the lifecycle.
115 info("ChonkProve - verifying the generated proof as a sanity check");
116 verification_passed = Chonk::verify(proof, vk);
117
118 if (!verification_passed) {
119 throw_or_abort("Failed to verify the generated proof!");
120 }
121
122 response.proof =
123 Chonk::Proof{ .mega_proof = std::move(proof.mega_proof), .goblin_proof = std::move(proof.goblin_proof) };
124
125 request.ivc_in_progress.reset();
126 request.ivc_stack_depth = 0;
127
128 return response;
129}
130
132{
133 BB_BENCH_NAME(MSGPACK_SCHEMA_NAME);
134 // Deserialize the verification key directly from buffer
135 Chonk::VerificationKey verification_key = from_buffer<Chonk::VerificationKey>(vk);
136
137 // Verify the proof using Chonk's static verify method
138 const bool verified = Chonk::verify(proof, verification_key);
139
140 return { .valid = verified };
141}
142
143static std::shared_ptr<Chonk::ProverInstance> get_acir_program_prover_instance(acir_format::AcirProgram& program)
144{
145 Chonk::ClientCircuit builder = acir_format::create_circuit<Chonk::ClientCircuit>(program);
146
147 // Construct the verification key via the prover-constructed proving key with the proper trace settings
149}
150
152{
153 BB_BENCH_NAME(MSGPACK_SCHEMA_NAME);
154 info("ChonkComputeStandaloneVk - deriving VK for circuit '", circuit.name, "'");
155
156 auto constraint_system = acir_format::circuit_buf_to_acir_format(std::move(circuit.bytecode));
157
158 acir_format::AcirProgram program{ constraint_system, /*witness=*/{} };
159 std::shared_ptr<Chonk::ProverInstance> prover_instance = get_acir_program_prover_instance(program);
160 auto verification_key = std::make_shared<Chonk::MegaVerificationKey>(prover_instance->get_precomputed());
161
162 return { .bytes = to_buffer(*verification_key), .fields = verification_key->to_field_elements() };
163}
164
166{
167 BB_BENCH_NAME(MSGPACK_SCHEMA_NAME);
168 info("ChonkComputeIvcVk - deriving IVC VK for circuit '", circuit.name, "'");
169
170 auto standalone_vk_response = bbapi::ChonkComputeStandaloneVk{
171 .circuit{ .name = "standalone_circuit", .bytecode = std::move(circuit.bytecode) }
172 }.execute();
173
174 auto mega_vk = from_buffer<Chonk::MegaVerificationKey>(standalone_vk_response.bytes);
178 Response response;
179 response.bytes = to_buffer(chonk_vk);
180
181 info("ChonkComputeIvcVk - IVC VK derived, size: ", response.bytes.size(), " bytes");
182
183 return response;
184}
185
187{
188 BB_BENCH_NAME(MSGPACK_SCHEMA_NAME);
190 /*witness=*/{} };
191
192 std::shared_ptr<Chonk::ProverInstance> prover_instance = get_acir_program_prover_instance(program);
193 auto computed_vk = std::make_shared<Chonk::MegaVerificationKey>(prover_instance->get_precomputed());
194
195 if (circuit.verification_key.empty()) {
196 info("FAIL: Expected precomputed vk for function ", circuit.name);
197 throw_or_abort("Missing precomputed VK");
198 }
199
200 // Deserialize directly from buffer
201 auto precomputed_vk = from_buffer<std::shared_ptr<Chonk::MegaVerificationKey>>(circuit.verification_key);
202
203 Response response;
204 response.valid = true;
205 if (*computed_vk != *precomputed_vk) {
206 response.valid = false;
207 response.actual_vk = to_buffer(computed_vk);
208 }
209 return response;
210}
211
213{
214 BB_BENCH_NAME(MSGPACK_SCHEMA_NAME);
215 Response response;
216
217 const auto constraint_system = acir_format::circuit_buf_to_acir_format(std::move(circuit.bytecode));
218 acir_format::AcirProgram program{ constraint_system };
219
220 // Get IVC constraints if any
221 const auto& ivc_constraints = constraint_system.hn_recursion_constraints;
222
223 // Create metadata with appropriate IVC context
225 .ivc = ivc_constraints.empty() ? nullptr : acir_format::create_mock_chonk_from_constraints(ivc_constraints),
226 .collect_gates_per_opcode = include_gates_per_opcode
227 };
228
229 // Create and finalize circuit
230 auto builder = acir_format::create_circuit<MegaCircuitBuilder>(program, metadata);
231 builder.finalize_circuit(/*ensure_nonzero=*/true);
232
233 // Set response values
234 response.acir_opcodes = program.constraints.num_acir_opcodes;
235 response.circuit_size = static_cast<uint32_t>(builder.num_gates());
236
237 // Optionally include gates per opcode
238 if (include_gates_per_opcode) {
239 response.gates_per_opcode = std::vector<uint32_t>(program.constraints.gates_per_opcode.begin(),
240 program.constraints.gates_per_opcode.end());
241 }
242
243 // Log circuit details
244 info("ChonkStats - circuit: ",
245 circuit.name,
246 ", acir_opcodes: ",
247 response.acir_opcodes,
248 ", circuit_size: ",
249 response.circuit_size);
250
251 // Print execution trace details
252 builder.blocks.summarize();
253
254 return response;
255}
256
257} // namespace bb::bbapi
#define BB_BENCH_NAME(name)
Definition bb_bench.hpp:219
Chonk-specific command definitions for the Barretenberg RPC API.
static bool verify(const Proof &proof, const VerificationKey &vk)
Definition chonk.cpp:528
void info(Args... args)
Definition log.hpp:75
#define BB_UNUSED
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 an IVC object 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.
VerifierCommitmentKey< Curve > vk
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13
std::vector< uint8_t > to_buffer(T const &value)
std::shared_ptr< bb::IVCBase > ivc
A full proof for the IVC scheme containing a Mega proof showing correctness of the Hiding kernel (whi...
Definition chonk.hpp:91
HonkProof mega_proof
Definition chonk.hpp:92
std::shared_ptr< MegaVerificationKey > mega
Definition chonk.hpp:165
Empty response indicating successful circuit accumulation.
Response execute(BBApiRequest &request) &&
Contains the validation result.
bool valid
True if the precomputed VK matches the circuit.
Response execute(const BBApiRequest &request={}) &&
Contains the computed IVC verification key.
std::vector< uint8_t > bytes
Serialized IVC verification key in binary format.
Response execute(const BBApiRequest &request={}) &&
Contains the computed verification key in multiple formats.
Compute standalone verification key for a circuit.
Response execute(const BBApiRequest &request={}) &&
Empty response indicating successful circuit loading.
Response execute(BBApiRequest &request) &&
Contains the generated IVC proof.
Chonk::Proof 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={}) &&
std::string name
Human-readable name for the circuit.
void throw_or_abort(std::string const &err)