Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
json_output.hpp
Go to the documentation of this file.
1#pragma once
2
9#include <iomanip>
10#include <optional>
11#include <sstream>
12#include <string>
13#include <vector>
14
15// nlohmann/json has sign-conversion warnings that fail with -Werror in WASM builds
16#ifdef __clang__
17#pragma clang diagnostic push
18#pragma clang diagnostic ignored "-Wsign-conversion"
19#endif
20#include <nlohmann/json.hpp>
21#ifdef __clang__
22#pragma clang diagnostic pop
23#endif
24
25namespace bb {
26
30inline std::string bytes_to_hex_string(const std::vector<uint8_t>& bytes)
31{
32 std::stringstream ss;
33 ss << "0x" << std::hex << std::setfill('0');
34 for (const auto& byte : bytes) {
35 ss << std::setw(2) << static_cast<int>(byte);
36 }
37 return ss.str();
38}
39
46inline std::optional<nlohmann::json> try_parse_json(const std::vector<uint8_t>& content)
47{
48 // Quick check: JSON objects must start with '{' (after whitespace)
49 for (const auto& byte : content) {
50 if (std::isspace(static_cast<unsigned char>(byte)) != 0) {
51 continue;
52 }
53 if (byte != '{') {
54 return std::nullopt;
55 }
56 break;
57 }
58
59 // Try to parse as JSON
60 try {
61 std::string str(content.begin(), content.end());
62 return nlohmann::json::parse(str);
63 } catch (...) {
64 return std::nullopt;
65 }
66}
67
71inline uint256_t hex_string_to_uint256(const std::string& hex_str)
72{
73 std::string str = hex_str;
74 // Remove 0x prefix if present
75 if (str.size() >= 2 && str[0] == '0' && (str[1] == 'x' || str[1] == 'X')) {
76 str = str.substr(2);
77 }
78 // Pad to 64 characters (32 bytes) if needed
79 if (str.size() < 64) {
80 str.insert(0, 64 - str.size(), '0');
81 }
82 return uint256_t(str);
83}
84
88struct VkJson {
89 std::vector<std::string> vk;
90 std::string hash;
91 std::string bb_version;
92 std::string scheme;
93
95
96 template <typename T>
97 static std::string build(const std::vector<T>& fields, const std::string& hash, const std::string& scheme)
98 {
99 std::vector<std::string> hex_fields;
100 hex_fields.reserve(fields.size());
101 for (const auto& field : fields) {
102 std::stringstream ss;
103 ss << field;
104 hex_fields.push_back(ss.str());
105 }
106
107 VkJson output{ .vk = std::move(hex_fields), .hash = hash, .bb_version = BB_VERSION, .scheme = scheme };
108
109 msgpack::sbuffer buffer;
110 msgpack::pack(buffer, output);
111 msgpack::object_handle oh = msgpack::unpack(buffer.data(), buffer.size());
112
113 std::stringstream ss;
114 ss << oh.get();
115 return ss.str();
116 }
117
118 static std::vector<uint8_t> parse_to_bytes(const nlohmann::json& json)
119 {
120 if (!json.contains("vk") || !json["vk"].is_array()) {
121 throw_or_abort("JSON missing 'vk' array");
122 }
123 std::vector<uint8_t> result;
124 result.reserve(json["vk"].size() * 32);
125 for (const auto& field : json["vk"]) {
126 auto value = hex_string_to_uint256(field.get<std::string>());
127 for (int i = 3; i >= 0; --i) {
128 uint64_t limb = value.data[i];
129 for (int j = 7; j >= 0; --j) {
130 result.push_back(static_cast<uint8_t>((limb >> (j * 8)) & 0xFF));
131 }
132 }
133 }
134 return result;
135 }
136};
137
141struct ProofJson {
142 std::vector<std::string> proof;
143 std::string vk_hash;
144 std::string bb_version;
145 std::string scheme;
146
148
149 template <typename T>
150 static std::string build(const std::vector<T>& fields, const std::string& vk_hash, const std::string& scheme)
151 {
152 std::vector<std::string> hex_fields;
153 hex_fields.reserve(fields.size());
154 for (const auto& field : fields) {
155 std::stringstream ss;
156 ss << field;
157 hex_fields.push_back(ss.str());
158 }
159
160 ProofJson output{
161 .proof = std::move(hex_fields), .vk_hash = vk_hash, .bb_version = BB_VERSION, .scheme = scheme
162 };
163
164 msgpack::sbuffer buffer;
165 msgpack::pack(buffer, output);
166 msgpack::object_handle oh = msgpack::unpack(buffer.data(), buffer.size());
167
168 std::stringstream ss;
169 ss << oh.get();
170 return ss.str();
171 }
172
173 static std::vector<uint256_t> parse(const nlohmann::json& json)
174 {
175 if (!json.contains("proof") || !json["proof"].is_array()) {
176 throw_or_abort("JSON missing 'proof' array");
177 }
179 result.reserve(json["proof"].size());
180 for (const auto& field : json["proof"]) {
181 result.push_back(hex_string_to_uint256(field.get<std::string>()));
182 }
183 return result;
184 }
185};
186
191 std::vector<std::string> public_inputs;
192 std::string bb_version;
193 std::string scheme;
194
196
197 template <typename T> static std::string build(const std::vector<T>& fields, const std::string& scheme)
198 {
199 std::vector<std::string> hex_fields;
200 hex_fields.reserve(fields.size());
201 for (const auto& field : fields) {
202 std::stringstream ss;
203 ss << field;
204 hex_fields.push_back(ss.str());
205 }
206
207 PublicInputsJson output{ .public_inputs = std::move(hex_fields), .bb_version = BB_VERSION, .scheme = scheme };
208
209 msgpack::sbuffer buffer;
210 msgpack::pack(buffer, output);
211 msgpack::object_handle oh = msgpack::unpack(buffer.data(), buffer.size());
212
213 std::stringstream ss;
214 ss << oh.get();
215 return ss.str();
216 }
217
218 static std::vector<uint256_t> parse(const nlohmann::json& json)
219 {
220 if (!json.contains("public_inputs") || !json["public_inputs"].is_array()) {
221 throw_or_abort("JSON missing 'public_inputs' array");
222 }
224 result.reserve(json["public_inputs"].size());
225 for (const auto& field : json["public_inputs"]) {
226 result.push_back(hex_string_to_uint256(field.get<std::string>()));
227 }
228 return result;
229 }
230};
231
232} // namespace bb
std::unique_ptr< uint8_t[]> buffer
Definition engine.cpp:50
Entry point for Barretenberg command-line interface.
Definition api.hpp:5
const char * BB_VERSION
Definition version.hpp:14
std::optional< nlohmann::json > try_parse_json(const std::vector< uint8_t > &content)
Try to parse file content as JSON.
uint256_t hex_string_to_uint256(const std::string &hex_str)
Parse a hex string (with or without 0x prefix) to uint256_t.
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
Serializable structure for proof JSON output (msgpack-compatible)
std::vector< std::string > proof
static std::vector< uint256_t > parse(const nlohmann::json &json)
std::string scheme
std::string bb_version
static std::string build(const std::vector< T > &fields, const std::string &vk_hash, const std::string &scheme)
MSGPACK_FIELDS(proof, vk_hash, bb_version, scheme)
std::string vk_hash
Serializable structure for public inputs JSON output (msgpack-compatible)
static std::vector< uint256_t > parse(const nlohmann::json &json)
static std::string build(const std::vector< T > &fields, const std::string &scheme)
std::vector< std::string > public_inputs
MSGPACK_FIELDS(public_inputs, bb_version, scheme)
Serializable structure for VK JSON output (msgpack-compatible)
std::string bb_version
MSGPACK_FIELDS(vk, hash, bb_version, scheme)
std::string hash
std::string scheme
std::vector< std::string > vk
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)
General class for prime fields see Prime field documentation["field documentation"] for general imple...
void throw_or_abort(std::string const &err)