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