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
17#include <iomanip>
18#include <optional>
19#include <sstream>
20
21namespace bb {
22
23namespace {
24
25void write_vk_outputs(const bbapi::CircuitComputeVk::Response& vk_response, const std::filesystem::path& output_dir)
26{
27 write_file(output_dir / "vk", vk_response.bytes);
28 info("VK saved to ", output_dir / "vk");
29 write_file(output_dir / "vk_hash", vk_response.hash);
30 info("VK Hash saved to ", output_dir / "vk_hash");
31}
32
33void write_proof_outputs(const bbapi::CircuitProve::Response& prove_response, const std::filesystem::path& output_dir)
34{
35 auto public_inputs_buf = to_buffer(prove_response.public_inputs);
36 auto proof_buf = to_buffer(prove_response.proof);
37
38 write_file(output_dir / "public_inputs", public_inputs_buf);
39 write_file(output_dir / "proof", proof_buf);
40 info("Public inputs saved to ", output_dir / "public_inputs");
41 info("Proof saved to ", output_dir / "proof");
42}
43
44} // anonymous namespace
45
46bool UltraHonkAPI::check([[maybe_unused]] const Flags& flags,
47 [[maybe_unused]] const std::filesystem::path& bytecode_path,
48 [[maybe_unused]] const std::filesystem::path& witness_path)
49{
50 throw_or_abort("API function check_witness not implemented");
51 return false;
52}
53
54void UltraHonkAPI::prove(const Flags& flags,
55 const std::filesystem::path& bytecode_path,
56 const std::filesystem::path& witness_path,
57 const std::filesystem::path& vk_path,
58 const std::filesystem::path& output_dir)
59{
60 BB_BENCH_NAME("UltraHonkAPI::prove");
61 // Validate output directory
62 if (output_dir == "-") {
63 throw_or_abort("Stdout output is not supported. Please specify an output directory.");
64 }
65
66 // Convert flags to ProofSystemSettings
68 .oracle_hash_type = flags.oracle_hash_type,
69 .disable_zk = flags.disable_zk };
70
71 // Read input files
72 auto bytecode = get_bytecode(bytecode_path);
73 auto witness = get_bytecode(witness_path);
74
75 // Handle VK
76 std::vector<uint8_t> vk_bytes;
77
78 if (!vk_path.empty() && !flags.write_vk) {
79 vk_bytes = read_file(vk_path);
80 }
81
82 // Prove
83 auto response = bbapi::CircuitProve{ .circuit = { .name = "circuit",
84 .bytecode = std::move(bytecode),
85 .verification_key = std::move(vk_bytes) },
86 .witness = std::move(witness),
87 .settings = std::move(settings) }
88 .execute();
89 write_proof_outputs(response, output_dir);
90 if (flags.write_vk) {
91 write_vk_outputs(response.vk, output_dir);
92 }
93}
94
95bool UltraHonkAPI::verify(const Flags& flags,
96 const std::filesystem::path& public_inputs_path,
97 const std::filesystem::path& proof_path,
98 const std::filesystem::path& vk_path)
99{
100 BB_BENCH_NAME("UltraHonkAPI::verify");
101 // Read input files
102 auto public_inputs = many_from_buffer<uint256_t>(read_file(public_inputs_path));
103 auto proof = many_from_buffer<uint256_t>(read_file(proof_path));
104 auto vk_bytes = read_vk_file(vk_path);
105
106 // Convert flags to ProofSystemSettings
108 .oracle_hash_type = flags.oracle_hash_type,
109 .disable_zk = flags.disable_zk };
110
111 // Execute verify command
112 auto response = bbapi::CircuitVerify{ .verification_key = std::move(vk_bytes),
113 .public_inputs = std::move(public_inputs),
114 .proof = std::move(proof),
115 .settings = settings }
116 .execute();
117
118 return response.verified;
119}
120
121bool UltraHonkAPI::prove_and_verify([[maybe_unused]] const Flags& flags,
122 [[maybe_unused]] const std::filesystem::path& bytecode_path,
123 [[maybe_unused]] const std::filesystem::path& witness_path)
124{
125 throw_or_abort("API function prove_and_verify not implemented");
126 return false;
127}
128
130 const std::filesystem::path& bytecode_path,
131 const std::filesystem::path& output_dir)
132{
133 BB_BENCH_NAME("UltraHonkAPI::write_vk");
134 // Validate output directory
135 if (output_dir == "-") {
136 throw_or_abort("Stdout output is not supported. Please specify an output directory.");
137 }
138
139 // Read bytecode
140 auto bytecode = get_bytecode(bytecode_path);
141
142 // Convert flags to ProofSystemSettings
144 .oracle_hash_type = flags.oracle_hash_type,
145 .disable_zk = flags.disable_zk };
146
147 auto response = bbapi::CircuitComputeVk{ .circuit = { .name = "circuit", .bytecode = std::move(bytecode) },
148 .settings = settings }
149 .execute();
150
151 write_vk_outputs(response, output_dir);
152}
153
154void UltraHonkAPI::gates([[maybe_unused]] const Flags& flags,
155 [[maybe_unused]] const std::filesystem::path& bytecode_path)
156{
157 BB_BENCH_NAME("UltraHonkAPI::gates");
158 // Get the bytecode directly
159 auto bytecode = get_bytecode(bytecode_path);
160
161 // All circuit reports will be built into the string below
162 std::string functions_string = "{\"functions\": [\n ";
163
164 // For now, treat the entire bytecode as a single circuit
165 // TODO(https://github.com/AztecProtocol/barretenberg/issues/1074): Handle multi-circuit programs properly
166 // Convert flags to ProofSystemSettings
167 bbapi::ProofSystemSettings settings{ .ipa_accumulation = flags.ipa_accumulation,
168 .oracle_hash_type = flags.oracle_hash_type,
169 .disable_zk = flags.disable_zk };
170
171 // Execute CircuitStats command
172 auto response = bbapi::CircuitStats{ .circuit = { .name = "circuit", .bytecode = bytecode, .verification_key = {} },
173 .include_gates_per_opcode = flags.include_gates_per_opcode,
174 .settings = settings }
175 .execute();
176
177 vinfo("Calculated circuit size in gate_count: ", response.num_gates);
178
179 // Build individual circuit report to match original gate_count output
180 std::string gates_per_opcode_str;
181 if (flags.include_gates_per_opcode) {
182 size_t i = 0;
183 for (size_t count : response.gates_per_opcode) {
184 if (i != 0) {
185 gates_per_opcode_str += ",";
186 }
187 gates_per_opcode_str += std::to_string(count);
188 i++;
189 }
190 }
191
192 // For now, we'll use the CircuitStats response which includes circuit statistics
193 // The num_acir_opcodes is not directly available from bytecode alone
194 auto result_string = format(
195 "{\n \"acir_opcodes\": ",
196 response.num_acir_opcodes,
197 ",\n \"circuit_size\": ",
198 response.num_gates,
199 (flags.include_gates_per_opcode ? format(",\n \"gates_per_opcode\": [", gates_per_opcode_str, "]") : ""),
200 "\n }");
201
202 functions_string = format(functions_string, result_string);
203 std::cout << format(functions_string, "\n]}");
204}
205
207 const std::filesystem::path& output_path,
208 const std::filesystem::path& vk_path)
209{
210 BB_BENCH_NAME("UltraHonkAPI::write_solidity_verifier");
211 // Read VK file
212 auto vk_bytes = read_vk_file(vk_path);
213
214 // Convert flags to ProofSystemSettings
216 .oracle_hash_type = flags.oracle_hash_type,
217 .disable_zk = flags.disable_zk,
218 .optimized_solidity_verifier = flags.optimized_solidity_verifier };
219
220 // Execute solidity verifier command
221 auto response = bbapi::CircuitWriteSolidityVerifier{ .verification_key = vk_bytes, .settings = settings }.execute();
222
223 // Write output
224 if (output_path == "-") {
225 std::cout << response.solidity_code;
226 } else {
227 write_file(output_path, { response.solidity_code.begin(), response.solidity_code.end() });
228 if (flags.disable_zk) {
229 info("Honk solidity verifier saved to ", output_path);
230 } else {
231 info("ZK Honk solidity verifier saved to ", output_path);
232 }
233 }
234}
235} // namespace bb
std::shared_ptr< Napi::ThreadSafeFunction > bytecode
#define BB_BENCH_NAME(name)
Definition bb_bench.hpp:219
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:24
#define vinfo(...)
Definition log.hpp:94
void info(Args... args)
Definition log.hpp:89
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: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 optimized_solidity_verifier
Definition api.hpp:29
bool write_vk
Definition api.hpp:23
bool disable_zk
Definition api.hpp:13
bool ipa_accumulation
Definition api.hpp:17
std::string oracle_hash_type
Definition api.hpp:19
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)