Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
binary.hpp
Go to the documentation of this file.
1// === AUDIT STATUS ===
2// internal: { status: not started, auditors: [], date: YYYY-MM-DD }
3// external_1: { status: not started, auditors: [], date: YYYY-MM-DD }
4// external_2: { status: not started, auditors: [], date: YYYY-MM-DD }
5// =====================
6
7// Copyright (c) Facebook, Inc. and its affiliates
8// SPDX-License-Identifier: MIT OR Apache-2.0
9
10#pragma once
11
12#include <algorithm>
13#include <cassert>
14#include <variant>
15
16#include "serde.hpp"
17
18namespace serde {
19
20template <class S> class BinarySerializer {
21 protected:
22 std::vector<uint8_t> bytes_;
24
25 public:
26 BinarySerializer(size_t max_container_depth)
27 : container_depth_budget_(max_container_depth)
28 {}
29
30 void serialize_str(const std::string& value);
31
34 void serialize_char(char32_t value);
35 void serialize_f32(float value);
36 void serialize_f64(double value);
37
38 void serialize_u8(uint8_t value);
39 void serialize_u16(uint16_t value);
40 void serialize_u32(uint32_t value);
41 void serialize_u64(uint64_t value);
43
44 void serialize_i8(int8_t value);
45 void serialize_i16(int16_t value);
46 void serialize_i32(int32_t value);
47 void serialize_i64(int64_t value);
50
54
55 std::vector<uint8_t> bytes() && { return std::move(bytes_); }
56};
57
58template <class D> class BinaryDeserializer {
59 size_t pos_;
61
62 protected:
63 std::vector<uint8_t> bytes_;
64 uint8_t read_byte();
65
66 public:
67 BinaryDeserializer(std::vector<uint8_t> bytes, size_t max_container_depth)
68 : pos_(0)
69 , container_depth_budget_(max_container_depth)
70 , bytes_(std::move(bytes))
71 {}
72
73 std::string deserialize_str();
74
77 char32_t deserialize_char();
80
81 uint8_t deserialize_u8();
82 uint16_t deserialize_u16();
83 uint32_t deserialize_u32();
84 uint64_t deserialize_u64();
86
88 int16_t deserialize_i16();
89 int32_t deserialize_i32();
90 int64_t deserialize_i64();
92
94
98};
99
100template <class S> void BinarySerializer<S>::serialize_str(const std::string& value)
101{
102 static_cast<S*>(this)->serialize_len(value.size());
103 for (auto c : value) {
104 bytes_.push_back(c);
105 }
106}
107
108template <class S> void BinarySerializer<S>::serialize_unit() {}
109
110template <class S> void BinarySerializer<S>::serialize_f32(float)
111{
112 throw_or_abort("not implemented");
113}
114
115template <class S> void BinarySerializer<S>::serialize_f64(double)
116{
117 throw_or_abort("not implemented");
118}
119
120template <class S> void BinarySerializer<S>::serialize_char(char32_t)
121{
122 throw_or_abort("not implemented");
123}
124
125template <class S> void BinarySerializer<S>::serialize_bool(bool value)
126{
127 bytes_.push_back((uint8_t)value);
128}
129
130template <class S> void BinarySerializer<S>::serialize_u8(uint8_t value)
131{
132 bytes_.push_back(value);
133}
134
135template <class S> void BinarySerializer<S>::serialize_u16(uint16_t value)
136{
137 bytes_.push_back((uint8_t)value);
138 bytes_.push_back((uint8_t)(value >> 8));
139}
140
141template <class S> void BinarySerializer<S>::serialize_u32(uint32_t value)
142{
143 bytes_.push_back((uint8_t)value);
144 bytes_.push_back((uint8_t)(value >> 8));
145 bytes_.push_back((uint8_t)(value >> 16));
146 bytes_.push_back((uint8_t)(value >> 24));
147}
148
149template <class S> void BinarySerializer<S>::serialize_u64(uint64_t value)
150{
151 bytes_.push_back((uint8_t)value);
152 bytes_.push_back((uint8_t)(value >> 8));
153 bytes_.push_back((uint8_t)(value >> 16));
154 bytes_.push_back((uint8_t)(value >> 24));
155 bytes_.push_back((uint8_t)(value >> 32));
156 bytes_.push_back((uint8_t)(value >> 40));
157 bytes_.push_back((uint8_t)(value >> 48));
158 bytes_.push_back((uint8_t)(value >> 56));
159}
160
162{
163 serialize_u64(value.low);
164 serialize_u64(value.high);
165}
166
167template <class S> void BinarySerializer<S>::serialize_i8(int8_t value)
168{
169 serialize_u8((uint8_t)value);
170}
171
172template <class S> void BinarySerializer<S>::serialize_i16(int16_t value)
173{
174 serialize_u16((uint16_t)value);
175}
176
177template <class S> void BinarySerializer<S>::serialize_i32(int32_t value)
178{
179 serialize_u32((uint32_t)value);
180}
181
182template <class S> void BinarySerializer<S>::serialize_i64(int64_t value)
183{
184 serialize_u64((uint64_t)value);
185}
186
188{
189 serialize_u64(value.low);
190 serialize_i64(value.high);
191}
192
194{
195 serialize_bool(value);
196}
197
198template <class S> size_t BinarySerializer<S>::get_buffer_offset()
199{
200 return bytes_.size();
201}
202
204{
205 if (container_depth_budget_ == 0) {
206 throw_or_abort("Too many nested containers");
207 }
208 container_depth_budget_--;
209}
210
212{
213 container_depth_budget_++;
214}
215
216template <class D> uint8_t BinaryDeserializer<D>::read_byte()
217{
218 if (pos_ >= bytes_.size()) {
219 throw_or_abort("Input is not large enough");
220 }
221 return bytes_.at(pos_++);
222}
223
224inline bool is_valid_utf8(const std::string& input)
225{
226 uint8_t trailing_digits = 0;
227 for (char byte : input) {
228 if (trailing_digits == 0) {
229 // Start new codepoint.
230 if (byte >> 7 == 0) {
231 // ASCII character
232 } else if (byte >> 5 == 0b110) {
233 // Expecting a 2-byte codepoint
234 trailing_digits = 1;
235 } else if (byte >> 4 == 0b1110) {
236 // Expecting a 3-byte codepoint
237 trailing_digits = 2;
238 } else if (byte >> 3 == 0b11110) {
239 // Expecting a 4-byte codepoint
240 trailing_digits = 3;
241 } else {
242 return false;
243 }
244 } else {
245 // Process "trailing digit".
246 if (byte >> 6 != 0b10) {
247 return false;
248 }
249 trailing_digits -= 1;
250 }
251 }
252 return trailing_digits == 0;
253}
254
255template <class D> std::string BinaryDeserializer<D>::deserialize_str()
256{
257 auto len = static_cast<D*>(this)->deserialize_len();
258 std::string result;
259 result.reserve(len);
260 for (size_t i = 0; i < len; i++) {
261 result.push_back(read_byte());
262 }
263 if (!is_valid_utf8(result)) {
264 throw_or_abort("Invalid UTF8 string: " + result);
265 }
266 return result;
267}
268
270{
271 return {};
272}
273
275{
276 throw_or_abort("not implemented");
277}
278
279template <class D> double BinaryDeserializer<D>::deserialize_f64()
280{
281 throw_or_abort("not implemented");
282}
283
284template <class D> char32_t BinaryDeserializer<D>::deserialize_char()
285{
286 throw_or_abort("not implemented");
287}
288
290{
291 switch (read_byte()) {
292 case 0:
293 return false;
294 case 1:
295 return true;
296 default:
297 throw_or_abort("Invalid boolean value");
298 }
299}
300
301template <class D> uint8_t BinaryDeserializer<D>::deserialize_u8()
302{
303 return read_byte();
304}
305
306template <class D> uint16_t BinaryDeserializer<D>::deserialize_u16()
307{
308 uint16_t val = 0;
309 val |= (uint16_t)read_byte();
310 val |= (uint16_t)read_byte() << 8;
311 return val;
312}
313
314template <class D> uint32_t BinaryDeserializer<D>::deserialize_u32()
315{
316 uint32_t val = 0;
317 val |= (uint32_t)read_byte();
318 val |= (uint32_t)read_byte() << 8;
319 val |= (uint32_t)read_byte() << 16;
320 val |= (uint32_t)read_byte() << 24;
321 return val;
322}
323
324template <class D> uint64_t BinaryDeserializer<D>::deserialize_u64()
325{
326 uint64_t val = 0;
327 val |= (uint64_t)read_byte();
328 val |= (uint64_t)read_byte() << 8;
329 val |= (uint64_t)read_byte() << 16;
330 val |= (uint64_t)read_byte() << 24;
331 val |= (uint64_t)read_byte() << 32;
332 val |= (uint64_t)read_byte() << 40;
333 val |= (uint64_t)read_byte() << 48;
334 val |= (uint64_t)read_byte() << 56;
335 return val;
336}
337
339{
340 uint128_t result;
341 result.low = deserialize_u64();
342 result.high = deserialize_u64();
343 return result;
344}
345
346template <class D> int8_t BinaryDeserializer<D>::deserialize_i8()
347{
348 return (int8_t)deserialize_u8();
349}
350
351template <class D> int16_t BinaryDeserializer<D>::deserialize_i16()
352{
353 return (int16_t)deserialize_u16();
354}
355
356template <class D> int32_t BinaryDeserializer<D>::deserialize_i32()
357{
358 return (int32_t)deserialize_u32();
359}
360
361template <class D> int64_t BinaryDeserializer<D>::deserialize_i64()
362{
363 return (int64_t)deserialize_u64();
364}
365
367{
368 int128_t result;
369 result.low = deserialize_u64();
370 result.high = deserialize_i64();
371 return result;
372}
373
375{
376 return deserialize_bool();
377}
378
380{
381 return pos_;
382}
383
385{
386 if (container_depth_budget_ == 0) {
387 throw_or_abort("Too many nested containers");
388 }
389 container_depth_budget_--;
390}
391
393{
394 container_depth_budget_++;
395}
396
397} // end of namespace serde
uint128_t deserialize_u128()
Definition binary.hpp:338
std::vector< uint8_t > bytes_
Definition binary.hpp:63
std::string deserialize_str()
Definition binary.hpp:255
std::monostate deserialize_unit()
Definition binary.hpp:269
int128_t deserialize_i128()
Definition binary.hpp:366
BinaryDeserializer(std::vector< uint8_t > bytes, size_t max_container_depth)
Definition binary.hpp:67
char32_t deserialize_char()
Definition binary.hpp:284
void serialize_char(char32_t value)
Definition binary.hpp:120
void serialize_str(const std::string &value)
Definition binary.hpp:100
void serialize_i128(const int128_t &value)
Definition binary.hpp:187
void serialize_option_tag(bool value)
Definition binary.hpp:193
void serialize_i16(int16_t value)
Definition binary.hpp:172
void serialize_u64(uint64_t value)
Definition binary.hpp:149
BinarySerializer(size_t max_container_depth)
Definition binary.hpp:26
std::vector< uint8_t > bytes() &&
Definition binary.hpp:55
void serialize_i32(int32_t value)
Definition binary.hpp:177
void serialize_i8(int8_t value)
Definition binary.hpp:167
std::vector< uint8_t > bytes_
Definition binary.hpp:22
void serialize_u16(uint16_t value)
Definition binary.hpp:135
void serialize_u32(uint32_t value)
Definition binary.hpp:141
void serialize_f32(float value)
Definition binary.hpp:110
void serialize_u8(uint8_t value)
Definition binary.hpp:130
size_t container_depth_budget_
Definition binary.hpp:23
void decrease_container_depth()
Definition binary.hpp:211
void serialize_f64(double value)
Definition binary.hpp:115
void serialize_bool(bool value)
Definition binary.hpp:125
void serialize_u128(const uint128_t &value)
Definition binary.hpp:161
void serialize_i64(int64_t value)
Definition binary.hpp:182
void increase_container_depth()
Definition binary.hpp:203
bool is_valid_utf8(const std::string &input)
Definition binary.hpp:224
STL namespace.
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13
uint8_t len
uint64_t low
Definition serde.hpp:64
int64_t high
Definition serde.hpp:63
uint64_t low
Definition serde.hpp:51
uint64_t high
Definition serde.hpp:50
void throw_or_abort(std::string const &err)