Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
api_ultra_honk.cpp
Go to the documentation of this file.
1#include "api_ultra_honk.hpp"
2
11
12namespace bb {
13
14namespace {
15
16void write_vk_outputs(const bbapi::CircuitComputeVk::Response& vk_response,
17 const std::filesystem::path& output_dir,
18 const API::Flags& flags)
19{
20 if (flags.output_format == "json") {
21 std::string json_content =
22 VkJson::build(vk_response.fields, bytes_to_hex_string(vk_response.hash), flags.scheme);
23 write_file(output_dir / "vk.json", std::vector<uint8_t>(json_content.begin(), json_content.end()));
24 info("VK (JSON) saved to ", output_dir / "vk.json");
25 } else {
26 write_file(output_dir / "vk", vk_response.bytes);
27 info("VK saved to ", output_dir / "vk");
28 write_file(output_dir / "vk_hash", vk_response.hash);
29 info("VK Hash saved to ", output_dir / "vk_hash");
30 }
31}
32
33void write_proof_outputs(const bbapi::CircuitProve::Response& prove_response,
34 const std::filesystem::path& output_dir,
35 const API::Flags& flags)
36{
37 if (flags.output_format == "json") {
38 std::string vk_hash = bytes_to_hex_string(prove_response.vk.hash);
39 std::string proof_json = ProofJson::build(prove_response.proof, vk_hash, flags.scheme);
40 write_file(output_dir / "proof.json", std::vector<uint8_t>(proof_json.begin(), proof_json.end()));
41 info("Proof (JSON) saved to ", output_dir / "proof.json");
42
43 std::string pi_json = PublicInputsJson::build(prove_response.public_inputs, flags.scheme);
44 write_file(output_dir / "public_inputs.json", std::vector<uint8_t>(pi_json.begin(), pi_json.end()));
45 info("Public inputs (JSON) saved to ", output_dir / "public_inputs.json");
46 } else {
47 auto public_inputs_buf = to_buffer(prove_response.public_inputs);
48 auto proof_buf = to_buffer(prove_response.proof);
49
50 write_file(output_dir / "public_inputs", public_inputs_buf);
51 write_file(output_dir / "proof", proof_buf);
52 info("Public inputs saved to ", output_dir / "public_inputs");
53 info("Proof saved to ", output_dir / "proof");
54 }
55}
56
57} // anonymous namespace
58
59bool UltraHonkAPI::check([[maybe_unused]] const Flags& flags,
60 [[maybe_unused]] const std::filesystem::path& bytecode_path,
61 [[maybe_unused]] const std::filesystem::path& witness_path)
62{
63 throw_or_abort("API function check_witness not implemented");
64 return false;
65}
66
67void UltraHonkAPI::prove(const Flags& flags,
68 const std::filesystem::path& bytecode_path,
69 const std::filesystem::path& witness_path,
70 const std::filesystem::path& vk_path,
71 const std::filesystem::path& output_dir)
72{
73 BB_BENCH_NAME("UltraHonkAPI::prove");
74 // Validate output directory
75 if (output_dir == "-") {
76 throw_or_abort("Stdout output is not supported. Please specify an output directory.");
77 }
78
79 // Convert flags to ProofSystemSettings
81 .oracle_hash_type = flags.oracle_hash_type,
82 .disable_zk = flags.disable_zk };
83
84 // Read input files
85 auto bytecode = get_bytecode(bytecode_path);
86 auto witness = get_bytecode(witness_path);
87
88 // Handle VK
89 std::vector<uint8_t> vk_bytes;
90
91 if (!vk_path.empty() && !flags.write_vk) {
92 vk_bytes = read_file(vk_path);
93 }
94
95 // Prove
96 auto response = bbapi::CircuitProve{ .circuit = { .name = "circuit",
97 .bytecode = std::move(bytecode),
98 .verification_key = std::move(vk_bytes) },
99 .witness = std::move(witness),
100 .settings = std::move(settings) }
101 .execute();
102 write_proof_outputs(response, output_dir, flags);
103 if (flags.write_vk) {
104 write_vk_outputs(response.vk, output_dir, flags);
105 }
106}
107
108bool UltraHonkAPI::verify(const Flags& flags,
109 const std::filesystem::path& public_inputs_path,
110 const std::filesystem::path& proof_path,
111 const std::filesystem::path& vk_path)
112{
113 BB_BENCH_NAME("UltraHonkAPI::verify");
114
115 // Read and parse input files (auto-detect JSON vs binary format)
116 std::vector<uint256_t> public_inputs;
118 std::vector<uint8_t> vk_bytes;
119
120 auto public_inputs_content = read_file(public_inputs_path);
121 if (auto json = try_parse_json(public_inputs_content)) {
122 public_inputs = PublicInputsJson::parse(*json);
123 } else {
124 public_inputs = many_from_buffer<uint256_t>(public_inputs_content);
125 }
126
127 auto proof_content = read_file(proof_path);
128 if (auto json = try_parse_json(proof_content)) {
129 proof = ProofJson::parse(*json);
130 } else {
131 proof = many_from_buffer<uint256_t>(proof_content);
132 }
133
134 auto vk_content = read_file(vk_path);
135 if (auto json = try_parse_json(vk_content)) {
136 vk_bytes = VkJson::parse_to_bytes(*json);
137 } else {
138 vk_bytes = std::move(vk_content);
139 }
140
141 // Convert flags to ProofSystemSettings
143 .oracle_hash_type = flags.oracle_hash_type,
144 .disable_zk = flags.disable_zk };
145
146 // Execute verify command
147 auto response = bbapi::CircuitVerify{ .verification_key = std::move(vk_bytes),
148 .public_inputs = std::move(public_inputs),
149 .proof = std::move(proof),
150 .settings = settings }
151 .execute();
152
153 return response.verified;
154}
155
156bool UltraHonkAPI::prove_and_verify([[maybe_unused]] const Flags& flags,
157 [[maybe_unused]] const std::filesystem::path& bytecode_path,
158 [[maybe_unused]] const std::filesystem::path& witness_path)
159{
160 throw_or_abort("API function prove_and_verify not implemented");
161 return false;
162}
163
165 const std::filesystem::path& bytecode_path,
166 const std::filesystem::path& output_dir)
167{
168 BB_BENCH_NAME("UltraHonkAPI::write_vk");
169 // Validate output directory
170 if (output_dir == "-") {
171 throw_or_abort("Stdout output is not supported. Please specify an output directory.");
172 }
173
174 // Read bytecode
175 auto bytecode = get_bytecode(bytecode_path);
176
177 // Convert flags to ProofSystemSettings
179 .oracle_hash_type = flags.oracle_hash_type,
180 .disable_zk = flags.disable_zk };
181
182 auto response = bbapi::CircuitComputeVk{ .circuit = { .name = "circuit", .bytecode = std::move(bytecode) },
183 .settings = settings }
184 .execute();
185
186 write_vk_outputs(response, output_dir, flags);
187}
188
189void UltraHonkAPI::gates([[maybe_unused]] const Flags& flags,
190 [[maybe_unused]] const std::filesystem::path& bytecode_path)
191{
192 BB_BENCH_NAME("UltraHonkAPI::gates");
193 // Get the bytecode directly
194 auto bytecode = get_bytecode(bytecode_path);
195
196 // All circuit reports will be built into the string below
197 std::string functions_string = "{\"functions\": [\n ";
198
199 // For now, treat the entire bytecode as a single circuit
200 // Convert flags to ProofSystemSettings
201 bbapi::ProofSystemSettings settings{ .ipa_accumulation = flags.ipa_accumulation,
202 .oracle_hash_type = flags.oracle_hash_type,
203 .disable_zk = flags.disable_zk };
204
205 // Execute CircuitStats command
206 auto response = bbapi::CircuitStats{ .circuit = { .name = "circuit", .bytecode = bytecode, .verification_key = {} },
207 .include_gates_per_opcode = flags.include_gates_per_opcode,
208 .settings = settings }
209 .execute();
210
211 vinfo("Calculated circuit size in gate_count: ", response.num_gates);
212
213 // Build individual circuit report to match original gate_count output
214 std::string gates_per_opcode_str;
215 if (flags.include_gates_per_opcode) {
216 size_t i = 0;
217 for (size_t count : response.gates_per_opcode) {
218 if (i != 0) {
219 gates_per_opcode_str += ",";
220 }
221 gates_per_opcode_str += std::to_string(count);
222 i++;
223 }
224 }
225
226 // For now, we'll use the CircuitStats response which includes circuit statistics
227 // The num_acir_opcodes is not directly available from bytecode alone
228 auto result_string = format(
229 "{\n \"acir_opcodes\": ",
230 response.num_acir_opcodes,
231 ",\n \"circuit_size\": ",
232 response.num_gates,
233 (flags.include_gates_per_opcode ? format(",\n \"gates_per_opcode\": [", gates_per_opcode_str, "]") : ""),
234 "\n }");
235
236 functions_string = format(functions_string, result_string);
237 std::cout << format(functions_string, "\n]}");
238}
239
241 const std::filesystem::path& output_path,
242 const std::filesystem::path& vk_path)
243{
244 BB_BENCH_NAME("UltraHonkAPI::write_solidity_verifier");
245 // Read VK file
246 auto vk_bytes = read_vk_file(vk_path);
247
248 // Convert flags to ProofSystemSettings
250 .oracle_hash_type = flags.oracle_hash_type,
251 .disable_zk = flags.disable_zk,
252 .optimized_solidity_verifier = flags.optimized_solidity_verifier };
253
254 // Execute solidity verifier command
255 auto response = bbapi::CircuitWriteSolidityVerifier{ .verification_key = vk_bytes, .settings = settings }.execute();
256
257 // Write output
258 if (output_path == "-") {
259 std::cout << response.solidity_code;
260 } else {
261 write_file(output_path,
262 std::span<const uint8_t>(reinterpret_cast<const uint8_t*>(response.solidity_code.c_str()),
263 response.solidity_code.size()));
264 if (flags.disable_zk) {
265 info("Honk solidity verifier saved to ", output_path);
266 } else {
267 info("ZK Honk solidity verifier saved to ", output_path);
268 }
269 }
270}
271} // namespace bb
std::shared_ptr< Napi::ThreadSafeFunction > bytecode
#define BB_BENCH_NAME(name)
Definition bb_bench.hpp:225
UltraHonk-specific command definitions for the Barretenberg RPC API.
void prove(const Flags &flags, const std::filesystem::path &bytecode_path, const std::filesystem::path &witness_path, const std::filesystem::path &vk_path, const std::filesystem::path &output_dir)
void write_vk(const Flags &flags, const std::filesystem::path &bytecode_path, const std::filesystem::path &output_path) override
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
bool check(const Flags &flags, const std::filesystem::path &bytecode_path, const std::filesystem::path &witness_path) override
bool prove_and_verify(const Flags &flags, const std::filesystem::path &bytecode_path, const std::filesystem::path &witness_path)
void gates(const Flags &flags, const std::filesystem::path &bytecode_path) override
void write_solidity_verifier(const Flags &flags, const std::filesystem::path &output_path, const std::filesystem::path &vk_path) override
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)
Entry point for Barretenberg command-line interface.
Definition api.hpp:5
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:143
std::optional< nlohmann::json > try_parse_json(const std::vector< uint8_t > &content)
Try to parse file content as JSON.
std::vector< uint8_t > read_file(const std::string &filename, size_t bytes=0)
Definition file_io.hpp:29
void write_file(const std::string &filename, std::span< const uint8_t > data)
Definition file_io.hpp:99
std::string bytes_to_hex_string(const std::vector< uint8_t > &bytes)
Convert bytes to a hex string with 0x prefix.
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 optimized_solidity_verifier
Definition api.hpp:27
bool write_vk
Definition api.hpp:21
bool disable_zk
Definition api.hpp:13
bool ipa_accumulation
Definition api.hpp:17
std::string oracle_hash_type
Definition api.hpp:19
static std::vector< uint256_t > parse(const nlohmann::json &json)
static std::string build(const std::vector< T > &fields, const std::string &vk_hash, const std::string &scheme)
static std::vector< uint256_t > parse(const nlohmann::json &json)
static std::string build(const std::vector< T > &fields, const std::string &scheme)
static std::vector< uint8_t > parse_to_bytes(const nlohmann::json &json)
static std::string build(const std::vector< T > &fields, const std::string &hash, const std::string &scheme)
std::string name
Human-readable name for the circuit.
std::string name
Human-readable name for the circuit.
Represents a request to generate a proof. Currently, UltraHonk is the only proving system supported b...
Consolidated command for retrieving circuit information. Combines gate count, circuit size,...
Verify a proof against a verification key and public inputs.
std::vector< uint8_t > verification_key
Command to generate Solidity verifier contract.
bool ipa_accumulation
Optional flag to indicate if the proof should be generated with IPA accumulation (i....
void throw_or_abort(std::string const &err)