binio.h
1 /* Copyright (C) 2012-2020 IBM Corp.
2  * This program is Licensed under the Apache License, Version 2.0
3  * (the "License"); you may not use this file except in compliance
4  * with the License. You may obtain a copy of the License at
5  * http://www.apache.org/licenses/LICENSE-2.0
6  * Unless required by applicable law or agreed to in writing, software
7  * distributed under the License is distributed on an "AS IS" BASIS,
8  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
9  * See the License for the specific language governing permissions and
10  * limitations under the License. See accompanying LICENSE file.
11  */
12 #ifndef HELIB_BINIO_H
13 #define HELIB_BINIO_H
14 #include <iostream>
15 #include <array>
16 #include <vector>
17 #include <type_traits>
18 #include <cstdint>
19 #include <sstream>
20 #include <helib/assertions.h>
21 #include <helib/version.h>
22 
23 #include <NTL/xdouble.h>
24 #include <NTL/vec_long.h>
25 
26 namespace helib {
27 
28 struct Binio
29 {
30  static constexpr int BIT32 = 4;
31  static constexpr int BIT64 = 8;
32 
33  static constexpr std::array<char, 4> VERSION_0_0_1_0 = {0, 0, 1, 0};
34 };
35 
36 struct EyeCatcher
37 {
38  static constexpr int SIZE = 4;
39  // clang-format off
40  static constexpr std::array<char, SIZE> HEADER_BEGIN = {'|','H','E','['};
41  static constexpr std::array<char, SIZE> HEADER_END = {']','H','E','|'};
42  static constexpr std::array<char, SIZE> CONTEXT_BEGIN = {'|','C','N','['};
43  static constexpr std::array<char, SIZE> CONTEXT_END = {']','C','N','|'};
44  static constexpr std::array<char, SIZE> CTXT_BEGIN = {'|','C','X','['};
45  static constexpr std::array<char, SIZE> CTXT_END = {']','C','X','|'};
46  static constexpr std::array<char, SIZE> PK_BEGIN = {'|','P','K','['};
47  static constexpr std::array<char, SIZE> PK_END = {']','P','K','|'};
48  static constexpr std::array<char, SIZE> SK_BEGIN = {'|','S','K','['};
49  static constexpr std::array<char, SIZE> SK_END = {']','S','K','|'};
50  static constexpr std::array<char, SIZE> SKM_BEGIN = {'|','K','M','['};
51  static constexpr std::array<char, SIZE> SKM_END = {']','K','M','|'};
52  // clang-format on
53 };
54 
55 template <typename T>
56 inline constexpr char nameToStructId()
57 {
58  static_assert(true, "Type without a struct id.");
59  return 0; // Should not reach.
60 }
61 
62 class Context;
63 class PubKey;
64 class SecKey;
65 class Ctxt;
66 
67 template <>
68 inline constexpr char nameToStructId<Context>()
69 {
70  return 5;
71 }
72 template <>
73 inline constexpr char nameToStructId<PubKey>()
74 {
75  return 10;
76 }
77 template <>
78 inline constexpr char nameToStructId<SecKey>()
79 {
80  return 15;
81 }
82 template <>
83 inline constexpr char nameToStructId<Ctxt>()
84 {
85  return 20;
86 }
87 
88 // Already broken into bytes, thus should be the same written and read in bog
89 // or little endian.
90 template <typename T>
92 {
93  // Header eye catcher
94  const std::array<char, EyeCatcher::SIZE> beginCatcher =
96  // 32 bit number: 8 bits for major, minor, patch, fix
97  const std::array<char, 4> version = Binio::VERSION_0_0_1_0;
98  // The helib version that output this header.
99  const std::array<char, 4> helibVersion = {version::major,
102  0};
103  // ObjectType
104  char structId = nameToStructId<T>();
105  // Reserved for future use
106  const char reserved[7] = {0, 0, 0, 0, 0, 0, 0};
107  // End
108  const std::array<char, EyeCatcher::SIZE> endCatcher = EyeCatcher::HEADER_END;
109 
110  void writeTo(std::ostream& os)
111  {
112  os.write(reinterpret_cast<const char*>(this), sizeof(*this));
113  }
114 
115  static SerializeHeader readFrom(std::istream& is)
116  {
117  SerializeHeader<T> header;
118 
119  // Broken in bytes, should be the same written and read in bog or little
120  // endian.
121  is.read(reinterpret_cast<char*>(&header), sizeof(header));
122 
123  // Checks
124  if (header.beginCatcher != EyeCatcher::HEADER_BEGIN ||
126 
127  std::ostringstream oss;
128  oss << "Eye catchers for header mismatch '";
129  oss.write(header.beginCatcher.data(), EyeCatcher::SIZE);
130  oss << ", ";
131  oss.write(header.endCatcher.data(), EyeCatcher::SIZE);
132  oss << "' (begin, end).";
133  throw IOError(oss.str());
134  }
135 
136  return header;
137  }
138 
139  std::string versionString() const
140  {
141  // version has only 4 numbers.
142  return std::to_string(version[0]) + "." + std::to_string(version[1]) + "." +
143  std::to_string(version[2]) + "." + std::to_string(version[3]);
144  }
145 };
146 
147 /* Some utility functions for binary IO */
148 
149 bool readEyeCatcher(std::istream& str,
150  const std::array<char, EyeCatcher::SIZE>& expect);
151 void writeEyeCatcher(std::ostream& str,
152  const std::array<char, EyeCatcher::SIZE>& eye);
153 
154 void write_ntl_vec_long(std::ostream& str,
155  const NTL::vec_long& vl,
156  long intSize = Binio::BIT64);
157 void read_ntl_vec_long(std::istream& str, NTL::vec_long& vl);
158 
159 long read_raw_int(std::istream& str);
160 int read_raw_int32(std::istream& str);
161 void write_raw_int(std::ostream& str, long num);
162 void write_raw_int32(std::ostream& str, int num);
163 
164 void write_raw_double(std::ostream& str, const double d);
165 double read_raw_double(std::istream& str);
166 
167 void write_raw_xdouble(std::ostream& str, const NTL::xdouble xd);
168 NTL::xdouble read_raw_xdouble(std::istream& str);
169 
170 void write_raw_ZZ(std::ostream& str, const NTL::ZZ& zz);
171 void read_raw_ZZ(std::istream& str, NTL::ZZ& zz);
172 
173 template <typename T>
174 void write_raw_vector(std::ostream& str, const std::vector<T>& v)
175 {
176  write_raw_int(str, v.size());
177 
178  for (const T& n : v) {
179  n.writeTo(str);
180  }
181 }
182 
183 // vector<long> has a different implementation, since long.write does not work
184 template <>
185 void write_raw_vector<long>(std::ostream& str, const std::vector<long>& v);
186 
187 // vector<double> has a different implementation, since double.write does not
188 // work
189 template <>
190 void write_raw_vector<double>(std::ostream& str, const std::vector<double>& v);
191 
192 template <typename T>
193 void read_raw_vector(std::istream& str, std::vector<T>& v, T& init)
194 {
195  long sz = read_raw_int(str);
196  v.resize(sz, init); // Make space in vector
197 
198  for (auto& n : v) {
199  n.read(str);
200  }
201 }
202 
203 // FIXME: Change other method adding _inplace or this to read_return to
204 // distinguish them
205 template <typename T, typename CTy>
206 std::vector<T> read_raw_vector(std::istream& str, const CTy& ctx)
207 {
208  std::vector<T> v;
209  long sz = read_raw_int(str);
210  v.reserve(sz); // Make space in vector
211 
212  for (long i = 0; i < sz; i++) {
213  v.emplace_back(T::readFrom(str, ctx));
214  }
215 
216  return v;
217 }
218 
219 template <typename T>
220 void read_raw_vector(std::istream& str, std::vector<T>& v)
221 {
222  read_raw_vector<T>(str, v, T());
223 }
224 
225 // vector<long> has a different implementation, since long.read does not work
226 template <>
227 void read_raw_vector<long>(std::istream& str, std::vector<long>& v);
228 
229 // vector<double> has a different implementation, since double.read does not
230 // work
231 template <>
232 void read_raw_vector<double>(std::istream& str, std::vector<double>& v);
233 
234 } // namespace helib
235 #endif // ifndef HELIB_BINIO_H
Inherits from Exception and std::runtime_error.
Definition: exceptions.h:123
Definition: apiAttributes.h:21
bool readEyeCatcher(std::istream &str, const std::array< char, EyeCatcher::SIZE > &expect)
Definition: binio.cpp:19
void writeEyeCatcher(std::ostream &str, const std::array< char, EyeCatcher::SIZE > &eye)
Definition: binio.cpp:27
constexpr char nameToStructId< SecKey >()
Definition: binio.h:78
void write_raw_vector< double >(std::ostream &str, const std::vector< double > &v)
Definition: binio.cpp:242
constexpr char nameToStructId< Context >()
Definition: binio.h:68
int read_raw_int32(std::istream &str)
Definition: binio.cpp:54
void read_raw_vector< double >(std::istream &str, std::vector< double > &v)
Definition: binio.cpp:231
void write_ntl_vec_long(std::ostream &str, const NTL::vec_long &vl, long intSize)
Definition: binio.cpp:103
void read_raw_vector< long >(std::istream &str, std::vector< long > &v)
Definition: binio.cpp:210
void write_raw_vector< long >(std::ostream &str, const std::vector< long > &v)
Definition: binio.cpp:221
void write_raw_ZZ(std::ostream &str, const NTL::ZZ &zz)
Definition: binio.cpp:180
void write_raw_int32(std::ostream &str, int num)
Definition: binio.cpp:89
constexpr char nameToStructId< PubKey >()
Definition: binio.h:73
void read_raw_vector(std::istream &str, std::vector< T > &v, T &init)
Definition: binio.h:193
double read_raw_double(std::istream &str)
Definition: binio.cpp:157
void write_raw_int(std::ostream &str, long num)
Definition: binio.cpp:75
NTL::xdouble read_raw_xdouble(std::istream &str)
Definition: binio.cpp:173
void write_raw_vector(std::ostream &str, const std::vector< T > &v)
Definition: binio.h:174
void write_raw_double(std::ostream &str, const double d)
Definition: binio.cpp:148
long read_raw_int(std::istream &str)
Definition: binio.cpp:34
constexpr char nameToStructId()
Definition: binio.h:56
void read_raw_ZZ(std::istream &str, NTL::ZZ &zz)
Definition: binio.cpp:193
void write_raw_xdouble(std::ostream &str, const NTL::xdouble xd)
Definition: binio.cpp:165
void read_ntl_vec_long(std::istream &str, NTL::vec_long &vl)
Definition: binio.cpp:124
constexpr char nameToStructId< Ctxt >()
Definition: binio.h:83
Definition: binio.h:29
static constexpr std::array< char, 4 > VERSION_0_0_1_0
Definition: binio.h:33
static constexpr int BIT64
Definition: binio.h:31
static constexpr int BIT32
Definition: binio.h:30
Definition: binio.h:37
static constexpr std::array< char, SIZE > PK_END
Definition: binio.h:47
static constexpr std::array< char, SIZE > SK_END
Definition: binio.h:49
static constexpr std::array< char, SIZE > HEADER_BEGIN
Definition: binio.h:40
static constexpr std::array< char, SIZE > PK_BEGIN
Definition: binio.h:46
static constexpr std::array< char, SIZE > SK_BEGIN
Definition: binio.h:48
static constexpr std::array< char, SIZE > CTXT_END
Definition: binio.h:45
static constexpr std::array< char, SIZE > CONTEXT_BEGIN
Definition: binio.h:42
static constexpr std::array< char, SIZE > HEADER_END
Definition: binio.h:41
static constexpr std::array< char, SIZE > SKM_BEGIN
Definition: binio.h:50
static constexpr std::array< char, SIZE > SKM_END
Definition: binio.h:51
static constexpr std::array< char, SIZE > CTXT_BEGIN
Definition: binio.h:44
static constexpr std::array< char, SIZE > CONTEXT_END
Definition: binio.h:43
static constexpr int SIZE
Definition: binio.h:38
Definition: binio.h:92
char structId
Definition: binio.h:104
std::string versionString() const
Definition: binio.h:139
static SerializeHeader readFrom(std::istream &is)
Definition: binio.h:115
const char reserved[7]
Definition: binio.h:106
const std::array< char, EyeCatcher::SIZE > endCatcher
Definition: binio.h:108
const std::array< char, EyeCatcher::SIZE > beginCatcher
Definition: binio.h:94
const std::array< char, 4 > helibVersion
Definition: binio.h:99
void writeTo(std::ostream &os)
Definition: binio.h:110
The class acts as a namespace with all members static. Holds the version number for this code of HEli...
Definition: version.in.h:24
static constexpr long minor
The minor number of this version of HElib.
Definition: version.in.h:34
static constexpr long patch
The patch number of this version of HElib.
Definition: version.in.h:38
static constexpr long major
The major number of this version of HElib.
Definition: version.in.h:30