Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
api_chonk.cpp
Go to the documentation of this file.
1#include "api_chonk.hpp"
18#include <algorithm>
19#include <stdexcept>
20
21namespace bb {
22namespace { // anonymous namespace
23
34void write_chonk_vk(std::vector<uint8_t> bytecode, const std::filesystem::path& output_path, const API::Flags& flags)
35{
36 auto response = bbapi::ChonkComputeVk{ .circuit = { .bytecode = std::move(bytecode) } }.execute();
37
38 const bool is_stdout = output_path == "-";
39 if (is_stdout) {
40 write_bytes_to_stdout(response.bytes);
41 } else if (flags.output_format == "json") {
42 std::string json_content = build_json_output(response.fields, "vk", flags);
43 write_file(output_path / "vk.json", std::vector<uint8_t>(json_content.begin(), json_content.end()));
44 info("VK (JSON) saved to ", output_path / "vk.json");
45 } else {
46 write_file(output_path / "vk", response.bytes);
47 }
48}
49} // anonymous namespace
50
51void ChonkAPI::prove(const Flags& flags,
52 const std::filesystem::path& input_path,
53 const std::filesystem::path& output_dir)
54{
55 BB_BENCH_NAME("ChonkAPI::prove");
56 bbapi::BBApiRequest request;
59
60 bbapi::ChonkStart{ .num_circuits = raw_steps.size() }.execute(request);
61 info("Chonk: starting with ", raw_steps.size(), " circuits");
62 for (const auto& step : raw_steps) {
64 .circuit = { .name = step.function_name, .bytecode = step.bytecode, .verification_key = step.vk }
65 }.execute(request);
66
67 // NOLINTNEXTLINE(bugprone-unchecked-optional-access): we know the optional has been set here.
68 info("Chonk: accumulating " + step.function_name);
69 bbapi::ChonkAccumulate{ .witness = step.witness }.execute(request);
70 }
71
72 auto proof = bbapi::ChonkProve{}.execute(request).proof;
73
74 const bool output_to_stdout = output_dir == "-";
75
76 const auto write_proof = [&]() {
77 const auto proof_fields = proof.to_field_elements();
78 if (output_to_stdout) {
79 vinfo("writing Chonk proof to stdout");
80 write_bytes_to_stdout(to_buffer(proof_fields));
81 } else if (flags.output_format == "json") {
82 vinfo("writing Chonk proof (JSON) in directory ", output_dir);
83 std::string json_content = build_json_output(proof_fields, "proof", flags);
84 write_file(output_dir / "proof.json", std::vector<uint8_t>(json_content.begin(), json_content.end()));
85 info("Proof (JSON) saved to ", output_dir / "proof.json");
86 } else {
87 vinfo("writing Chonk proof in directory ", output_dir);
88 write_file(output_dir / "proof", to_buffer(proof_fields));
89 }
90 };
91
92 write_proof();
93
94 if (flags.write_vk) {
95 vinfo("writing Chonk vk in directory ", output_dir);
96 // write CHONK vk using the bytecode of the Hiding kernel (the last step of the execution)
97 write_chonk_vk(raw_steps[raw_steps.size() - 1].bytecode, output_dir, flags);
98 }
99}
100
101bool ChonkAPI::verify([[maybe_unused]] const Flags& flags,
102 [[maybe_unused]] const std::filesystem::path& public_inputs_path,
103 const std::filesystem::path& proof_path,
104 const std::filesystem::path& vk_path)
105{
106 BB_BENCH_NAME("ChonkAPI::verify");
107 auto proof_fields = many_from_buffer<fr>(read_file(proof_path));
108 auto proof = ChonkProof::from_field_elements(proof_fields);
109
110 auto vk_buffer = read_vk_file(vk_path);
111
112 auto response = bbapi::ChonkVerify{ .proof = std::move(proof), .vk = std::move(vk_buffer) }.execute();
113 return response.valid;
114}
115
116// WORKTODO(bbapi) remove this
117bool ChonkAPI::prove_and_verify(const std::filesystem::path& input_path)
118{
121
123 // Construct the hiding kernel as the final step of the IVC
124
125 auto proof = ivc->prove();
126 auto vk_and_hash = ivc->get_hiding_kernel_vk_and_hash();
127 ChonkNativeVerifier verifier(vk_and_hash);
128 const bool verified = verifier.verify(proof);
129 return verified;
130}
131
132void ChonkAPI::gates(const Flags& flags, const std::filesystem::path& bytecode_path)
133{
134 BB_BENCH_NAME("ChonkAPI::gates");
135 chonk_gate_count(bytecode_path, flags.include_gates_per_opcode);
136}
137
138void ChonkAPI::write_solidity_verifier([[maybe_unused]] const Flags& flags,
139 [[maybe_unused]] const std::filesystem::path& output_path,
140 [[maybe_unused]] const std::filesystem::path& vk_path)
141{
142 BB_BENCH_NAME("ChonkAPI::write_solidity_verifier");
143 throw_or_abort("API function contract not implemented");
144}
145
146bool ChonkAPI::check_precomputed_vks(const Flags& flags, const std::filesystem::path& input_path)
147{
148 BB_BENCH_NAME("ChonkAPI::check_precomputed_vks");
149 bbapi::BBApiRequest request;
151
153 bool check_failed = false;
154 for (auto& step : raw_steps) {
155 if (step.vk.empty()) {
156 info("FAIL: Expected precomputed vk for function ", step.function_name);
157 return false;
158 }
159 auto response = bbapi::ChonkCheckPrecomputedVk{
160 .circuit = { .name = step.function_name, .bytecode = step.bytecode, .verification_key = step.vk }
161 }.execute();
162
163 if (!response.valid) {
164 info("VK mismatch detected for function ", step.function_name);
165 if (vk_policy != bbapi::VkPolicy::REWRITE) {
166 info("Computed VK differs from precomputed VK in ivc-inputs.msgpack");
167 return false;
168 }
169 info("Updating VK in ivc-inputs.msgpack with computed value");
170 step.vk = response.actual_vk;
171 check_failed = true;
172 }
173 }
174 if (check_failed) {
176 return false;
177 }
178 return true;
179}
180
181void ChonkAPI::write_vk(const Flags& flags,
182 const std::filesystem::path& bytecode_path,
183 const std::filesystem::path& output_path)
184{
185 BB_BENCH_NAME("ChonkAPI::write_vk");
186 write_chonk_vk(get_bytecode(bytecode_path), output_path, flags);
187}
188
189bool ChonkAPI::check([[maybe_unused]] const Flags& flags,
190 [[maybe_unused]] const std::filesystem::path& bytecode_path,
191 [[maybe_unused]] const std::filesystem::path& witness_path)
192{
193 throw_or_abort("API function check_witness not implemented");
194 return false;
195}
196
197void chonk_gate_count(const std::string& bytecode_path, bool include_gates_per_opcode)
198{
199 BB_BENCH_NAME("chonk_gate_count");
200 // All circuit reports will be built into the std::string below
201 std::string functions_string = "{\"functions\": [\n ";
202
203 bbapi::BBApiRequest request;
204
205 auto bytecode = get_bytecode(bytecode_path);
206 auto response = bbapi::ChonkStats{ .circuit = { .name = "ivc_circuit", .bytecode = std::move(bytecode) },
207 .include_gates_per_opcode = include_gates_per_opcode }
208 .execute(request);
209
210 // Build the circuit report. It always has one function, corresponding to the ACIR constraint systems.
211 // NOTE: can be reconsidered
212 std::string gates_per_opcode_str;
213 if (include_gates_per_opcode && !response.gates_per_opcode.empty()) {
214 for (size_t j = 0; j < response.gates_per_opcode.size(); j++) {
215 gates_per_opcode_str += std::to_string(response.gates_per_opcode[j]);
216 if (j != response.gates_per_opcode.size() - 1) {
217 gates_per_opcode_str += ",";
218 }
219 }
220 }
221 auto result_string = format(
222 "{\n \"acir_opcodes\": ",
223 response.acir_opcodes,
224 ",\n \"circuit_size\": ",
225 response.circuit_size,
226 (include_gates_per_opcode ? format(",\n \"gates_per_opcode\": [", gates_per_opcode_str, "]") : ""),
227 "\n }");
228 functions_string = format(functions_string, result_string);
229 std::cout << format(functions_string, "\n]}");
230}
231
232} // namespace bb
void write_bytes_to_stdout(const std::vector< uint8_t > &data)
Writes raw bytes of the vector to stdout.
Definition log.hpp:21
std::shared_ptr< Napi::ThreadSafeFunction > bytecode
#define BB_BENCH_NAME(name)
Definition bb_bench.hpp:219
bool prove_and_verify(const std::filesystem::path &input_path)
Test/debug function: prove and verify in one call (bypasses serialization).
bool verify(const Flags &flags, const std::filesystem::path &public_inputs_path, const std::filesystem::path &proof_path, const std::filesystem::path &vk_path) override
Verify a Chonk proof against a verification key.
void write_vk(const Flags &flags, const std::filesystem::path &bytecode_path, const std::filesystem::path &output_path) override
Compute and write a MegaHonk verification key for a circuit to be accumulated in Chonk.
void prove(const Flags &flags, const std::filesystem::path &input_path, const std::filesystem::path &output_dir)
Main production entry point: generate a Chonk proof from private execution steps.
Definition api_chonk.cpp:51
bool check(const Flags &flags, const std::filesystem::path &bytecode_path, const std::filesystem::path &witness_path) override
void gates(const Flags &flags, const std::filesystem::path &bytecode_path) override
Output gate count statistics for a circuit.
bool check_precomputed_vks(const Flags &flags, const std::filesystem::path &input_path)
Validate that precomputed VKs in ivc-inputs.msgpack match computed VKs.
void write_solidity_verifier(const Flags &flags, const std::filesystem::path &output_path, const std::filesystem::path &vk_path) override
Verifier for Chonk IVC proofs (both native and recursive).
Output verify(const Proof &proof)
Verify a Chonk proof.
std::string format(Args... args)
Definition log.hpp:23
#define info(...)
Definition log.hpp:93
#define vinfo(...)
Definition log.hpp:94
std::vector< uint8_t > get_bytecode(const std::string &bytecodePath)
VkPolicy
Policy for handling verification keys during IVC accumulation.
VkPolicy parse_vk_policy(const std::string &policy)
Convert VK policy string to enum for internal use.
Entry point for Barretenberg command-line interface.
Definition api.hpp:5
std::string build_json_output(const std::vector< T > &fields, const std::string &file_kind, const API::Flags &flags, const std::string &vk_hash="")
Build JSON output string using msgpack serialization.
void chonk_gate_count(const std::string &bytecode_path, bool include_gates_per_opcode)
std::vector< uint8_t > read_vk_file(const std::filesystem::path &vk_path)
Read a verification key file with an actionable error message if not found.
Definition file_io.hpp:112
std::vector< uint8_t > read_file(const std::string &filename, size_t bytes=0)
Definition file_io.hpp:30
void write_file(const std::string &filename, std::vector< uint8_t > const &data)
Definition file_io.hpp:59
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13
std::string to_string(bb::avm2::ValueTag tag)
std::vector< uint8_t > to_buffer(T const &value)
bool include_gates_per_opcode
Definition api.hpp:22
bool write_vk
Definition api.hpp:21
std::string vk_policy
Definition api.hpp:25
std::string output_format
Definition api.hpp:29
static ChonkProof_ from_field_elements(const std::vector< FF > &fields)
Common logic to reconstruct proof from field elements.
std::vector< FF > to_field_elements() const
Serialize proof to field elements (native mode)
static void compress_and_save(std::vector< PrivateExecutionStepRaw > &&steps, const std::filesystem::path &output_path)
static std::vector< PrivateExecutionStepRaw > load_and_decompress(const std::filesystem::path &input_path)
Parsed private execution steps ready for Chonk accumulation.
std::shared_ptr< Chonk > accumulate()
Creates a Chonk instance and accumulates each circuit in the folding stack. Uses precomputed VKs when...
void parse(std::vector< PrivateExecutionStepRaw > &&steps)
Converts PrivateExecutionStepRaw entries (which contain raw bytecode/witness bytes) into structured A...
Accumulate the previously loaded circuit into the IVC proof.
std::vector< uint8_t > witness
Serialized witness data for the last loaded circuit.
Verify that a precomputed verification key matches the circuit.
CircuitInput circuit
Circuit with its precomputed verification key.
Compute MegaHonk verification key for a circuit to be accumulated in Chonk.
Load a circuit into the Chonk instance for accumulation.
CircuitInput circuit
Circuit to be loaded with its bytecode and verification key.
ChonkProof proof
Complete IVC proof for all accumulated circuits.
Generate a proof for all accumulated circuits.
Response execute(BBApiRequest &request) &&
Initialize a new Chonk instance for incremental proof accumulation.
Get gate counts for a circuit.
CircuitInputNoVK circuit
The circuit to analyze.
Verify a Chonk proof with its verification key.
ChonkProof proof
The Chonk proof to verify.
std::string name
Human-readable name for the circuit.
std::string name
Human-readable name for the circuit.
std::vector< uint8_t > bytecode
Serialized bytecode representation of the circuit.
void throw_or_abort(std::string const &err)