Zeth - Zerocash on Ethereum  0.8
Reference implementation of the Zeth protocol by Clearmatics
stream_utils.tcc
Go to the documentation of this file.
1 // Copyright (c) 2015-2022 Clearmatics Technologies Ltd
2 //
3 // SPDX-License-Identifier: LGPL-3.0+
4 
5 #ifndef __ZETH_SERIALIZATION_STREAM_UTILS_TCC__
6 #define __ZETH_SERIALIZATION_STREAM_UTILS_TCC__
7 
8 #include "libzeth/core/group_element_utils.hpp"
9 #include "libzeth/serialization/stream_utils.hpp"
10 
11 namespace libzeth
12 {
13 
14 template<typename T>
15 typename std::enable_if<std::is_fundamental<T>::value, T>::type read_bytes(
16  std::istream &in_s)
17 {
18  T val;
19  read_bytes(val, in_s);
20  return val;
21 }
22 
23 template<typename T>
24 typename std::enable_if<std::is_fundamental<T>::value, void>::type read_bytes(
25  T &val, std::istream &in_s)
26 {
27  in_s.read((char *)(&val), sizeof(T));
28 }
29 
30 template<typename T>
31 typename std::enable_if<std::is_fundamental<T>::value, void>::type write_bytes(
32  const T &val, std::ostream &out_s)
33 {
34  out_s.write((const char *)(&val), sizeof(T));
35 }
36 
37 /// Write the first n from a collection of values, using a specified writer
38 /// function.
39 template<
40  // typename ValueT,
41  typename CollectionT,
42  void(WriterFn)(const MemberT<CollectionT> &, std::ostream &)>
43 void collection_n_write_bytes(
44  const CollectionT &collection, const size_t n, std::ostream &out_s)
45 {
46  for (size_t i = 0; i < n; ++i) {
47  WriterFn(collection[i], out_s);
48  }
49 }
50 
51 /// Read n element using a specified reader function, appending to the given
52 /// collection.
53 template<
54  typename CollectionT,
55  void(ReaderFn)(MemberT<CollectionT> &, std::istream &)>
56 void collection_n_read_bytes(
57  CollectionT &collection, const size_t n, std::istream &in_s)
58 {
59  for (size_t i = 0; i < n; ++i) {
60  collection.emplace_back();
61  ReaderFn(collection.back(), in_s);
62  }
63 }
64 
65 /// Write a full collection of values to a stream as bytes, using
66 /// a specific writer function.
67 template<
68  typename CollectionT,
69  void(WriterT)(const MemberT<CollectionT> &, std::ostream &)>
70 void collection_write_bytes(const CollectionT &collection, std::ostream &out_s)
71 {
72  write_bytes(collection.size(), out_s);
73  collection_n_write_bytes<CollectionT, WriterT>(
74  collection, collection.size(), out_s);
75 }
76 
77 /// Read a collection of values, from a stream of bytes, using
78 /// a specific reader function.
79 template<
80  // typename ValueT,
81  typename CollectionT,
82  void(ReaderT)(MemberT<CollectionT> &, std::istream &)>
83 void collection_read_bytes(CollectionT &collection, std::istream &in_s)
84 {
85  const size_t n = read_bytes<size_t>(in_s);
86 
87  collection.clear();
88  collection.reserve(n);
89  collection_n_read_bytes<CollectionT, ReaderT>(collection, n, in_s);
90 }
91 
92 template<typename T, void(ReaderFn)(T &, std::istream &)>
93 void sparse_vector_read_bytes(
94  libsnark::sparse_vector<T> &sparse_vector, std::istream &in_s)
95 {
96  sparse_vector.domain_size_ = read_bytes<size_t>(in_s);
97  const size_t num_entries = read_bytes<size_t>(in_s);
98  sparse_vector.indices.clear();
99  sparse_vector.indices.reserve(num_entries);
100  sparse_vector.values.clear();
101  sparse_vector.values.reserve(num_entries);
102 
103  for (size_t i = 0; i < num_entries; ++i) {
104  sparse_vector.indices.push_back(read_bytes<size_t>(in_s));
105  sparse_vector.values.emplace_back();
106  ReaderFn(sparse_vector.values.back(), in_s);
107  }
108 }
109 
110 template<typename T, void(WriterFn)(const T &, std::ostream &)>
111 void sparse_vector_write_bytes(
112  const libsnark::sparse_vector<T> &sparse_vector, std::ostream &out_s)
113 {
114  const size_t num_entries = sparse_vector.indices.size();
115  assert(num_entries == sparse_vector.values.size());
116 
117  write_bytes(sparse_vector.domain_size_, out_s);
118  write_bytes(num_entries, out_s);
119  for (size_t i = 0; i < num_entries; ++i) {
120  write_bytes(sparse_vector.indices[i], out_s);
121  WriterFn(sparse_vector.values[i], out_s);
122  }
123 }
124 
125 template<typename T, void(ReaderFn)(T &, std::istream &)>
126 void accumulation_vector_read_bytes(
127  libsnark::accumulation_vector<T> &acc_vector, std::istream &in_s)
128 {
129  ReaderFn(acc_vector.first, in_s);
130  sparse_vector_read_bytes<T, ReaderFn>(acc_vector.rest, in_s);
131 }
132 
133 template<typename T, void(WriterFn)(const T &, std::ostream &)>
134 void accumulation_vector_write_bytes(
135  const libsnark::accumulation_vector<T> &acc_vector, std::ostream &out_s)
136 {
137  WriterFn(acc_vector.first, out_s);
138  sparse_vector_write_bytes<T, WriterFn>(acc_vector.rest, out_s);
139 }
140 
141 template<typename kcT>
142 void knowledge_commitment_read_bytes(
143  kcT &knowledge_commitment, std::istream &in_s)
144 {
145  group_element_read_bytes(knowledge_commitment.g, in_s);
146  group_element_read_bytes(knowledge_commitment.h, in_s);
147 }
148 
149 template<typename kcT>
150 void knowledge_commitment_write_bytes(
151  const kcT &knowledge_commitment, std::ostream &out_s)
152 {
153  group_element_write_bytes(knowledge_commitment.g, out_s);
154  group_element_write_bytes(knowledge_commitment.h, out_s);
155 }
156 
157 template<typename kcvectorT>
158 void knowledge_commitment_vector_read_bytes(
159  kcvectorT &knowledge_commitment_vector, std::istream &in_s)
160 {
161  using kcT = typename std::decay<decltype(
162  knowledge_commitment_vector.values[0])>::type;
163  sparse_vector_read_bytes<kcT, knowledge_commitment_read_bytes<kcT>>(
164  knowledge_commitment_vector, in_s);
165 }
166 
167 template<typename kcvectorT>
168 void knowledge_commitment_vector_write_bytes(
169  const kcvectorT &knowledge_commitment_vector, std::ostream &out_s)
170 {
171  using kcT = typename std::decay<decltype(
172  knowledge_commitment_vector.values[0])>::type;
173  sparse_vector_write_bytes<kcT, knowledge_commitment_write_bytes<kcT>>(
174  knowledge_commitment_vector, out_s);
175 }
176 
177 } // namespace libzeth
178 
179 #endif // __ZETH_SERIALIZATION_STREAM_UTILS_TCC__