-
Notifications
You must be signed in to change notification settings - Fork 14
/
Copy pathfileops.h
307 lines (252 loc) · 10.8 KB
/
fileops.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.
/**
@file fileops.h
@brief Functions to load and save keys and ciphertexts and other objects to files.
*/
#pragma once
#include <cassert>
#include <fstream>
#include <iostream>
#include <string>
#include "seal/seal.h"
#include "utils.h"
// -----------------------------------------------------
// ---------------- Utility functions ------------------
// -----------------------------------------------------
/**
Returns the number of bytes in a file
@param[in] file File to check
*/
inline std::size_t size_of_file(std::fstream &file)
{
file.seekg(0, std::ios::end);
std::size_t size = file.tellg();
file.seekg(0, std::ios::beg);
return size;
}
/**
Exits if a file is not open or on file failure. Optionally checks that the file is not empty.
If failure is detected, closes file and exits.
@param[in] file File to check
@param[in] msg Message to print on exit
@param[in] check_size If true, checks that the file is not empty
*/
inline void exit_on_err_file(std::fstream &file, std::string msg, bool check_size)
{
if (!file.is_open())
{
std::cerr << "Error: File is not open." << std::endl;
goto close_and_exit;
}
if (file.fail())
{
std::cerr << "Error: File failed." << std::endl;
goto close_and_exit;
}
if (check_size && !size_of_file(file))
{
std::cerr << "Error: File is empty." << std::endl;
goto close_and_exit;
}
return;
close_and_exit:
file.close();
exit_on_err(1, msg);
}
// ===============================================================
// Binary file save/load
// (SEAL-Embedded format)
// ===============================================================
/**
Saves the secret key to a binary file. Optionally also creates a code file containing the hard-coded
values of the secret key. This file may then be compiled with the SEAL-Embedded library.
Note: This stores the secret key in **compressed** form.
Note: This function may modify sk in order to write to file, but should revert all changes before
returning.
@param[in] fpath Path to file to save secret key values in binary form
@param[in] str_fpath Path to file to hard-code secret key bytes in a code file for use with
SEAL-Embedded
@param[in] context SEAL context
@param[in] use_str_fpath If true, hard codes secret key bytes to file at str_fpath
@param[in] sk Secret key instance
*/
void sk_bin_file_save(std::string fpath, std::string str_fpath, const seal::SEALContext &context,
bool use_str_fpath, seal::SecretKey &sk);
/**
Loads the secret key from a binary file generated using 'sk_bin_file_save'.
Note: This assumes the secret key was saved in **compressed** form.
@param[in] fpath Path to file to load the secret key values, stored in binary form
@param[in] context SEAL context
@param[out] sk Secret key instance
*/
void sk_bin_file_load(std::string fpath, const seal::SEALContext &context, seal::SecretKey &sk);
/**
Saves the public key to a binary file. Also creates a code file containing the hard-coded values of
the public key to compile with the SEAL-Embedded library.
@param[in] dirpath Path to directory to save public key file
@param[in] context SEAL context
@param[in] pk_wr Public key wrapper instance
@param[in] incl_sp If true, writes bytes for special prime as well
@param[in] high_byte_first Toggle for endianness
@param[in] append If true, will append values to binary file. Otherwise, will overwrite
*/
void pk_bin_file_save(std::string dirpath, const seal::SEALContext &context,
PublicKeyWrapper &pk_wr, bool incl_sp, bool high_byte_first, bool append = 0);
/**
Loads a public key from a SEAL-Embedded-formatted binary file.
@param[in] dirpath Path to directory containing public key file
@param[in] context SEAL context
@param[out] pk_wr Public key wrapper instance
@param[in] incl_sp If true, reads in bytes for special prime as well
@param[in] high_byte_first Toggle for endianness
*/
void pk_bin_file_load(std::string dirpath, const seal::SEALContext &context,
PublicKeyWrapper &pk_wr, bool incl_sp, bool high_byte_first);
// ==============================================================
// Binary file save/load
// (SEAL format)
// ==============================================================
/**
Saves a secret key to a binary file in SEAL form.
@param[in] fpath Path to binary file to save the secret key
@param[in] sk Secret key instance
@param[in] compress If true, compresses the secret key w/ zstd before saving
*/
void sk_seal_save(std::string fpath, seal::SecretKey &sk, bool compress = true);
/**
Loads a secret key from a SEAL-formatted binary file.
@param[in] fpath Path to binary file containing secret key in SEAL form
@param[in] context SEAL context
@param[out] sk Secret key instance
*/
void sk_seal_load(std::string fpath, const seal::SEALContext &context, seal::SecretKey &sk);
/**
Saves a public key to a binary file in SEAL form.
@param[in] fpath Path to binary file to save the public key
@param[in] pk Public key instance
@param[in] compress If true, compresses the public key w/ zstd before saving
*/
void pk_seal_save(std::string fpath, seal::PublicKey &pk, bool compress = true);
/**
Loads a public key from a SEAL-formatted binary file.
@param[in] fpath Path to binary file containing public key in SEAL form
@param[in] context SEAL context
@param[out] pk Public key instance
*/
void pk_seal_load(std::string fpath, const seal::SEALContext &context, seal::PublicKey &pk);
// ==============================================================
// String file save/load
// (Mainly for debugging)
// ==============================================================
/**
Load a secret key from a string file.
@param[in] fpath Path to string file containing secret key
@param[in] context SEAL context
@param[out] sk Secret key object to store loaded values
@return Position of file pointer after reading in the secret key
*/
std::streampos sk_string_file_load(std::string fpath, const seal::SEALContext &context,
seal::SecretKey &sk);
/**
Load a freshly encrypted ciphertext from a string file.
CT objects should be formatted as follows:
ct0 : { x, x, x, x, x}
ct1 : { x, x, x, x, x}
ct0 : { x, x, x, x, x} --> w.r.t. next prime
ct1 : { x, x, x, x, x} --> w.r.t. next prime
@param[in] fpath Path to string file containing values of ciphertext.
@param[in] context SEAL context
@param[in] evaluator SEAL evaluator
@param[out] ct Ciphertext object to load values into
@param[in] filepos_in Previous returned value from calling this function
@return Position of file pointer after reading in a single ciphertext
*/
std::streampos ct_string_file_load(std::string fpath, const seal::SEALContext &context,
seal::Evaluator &evaluator, seal::Ciphertext &ct,
std::streampos filepos_in = 0);
/**
Load a polynomial object from a string file.
String file objects should be formatted as follows (values in [] are optional):
<object_name> : {<value 1>, <value 2>, ...}
@param[in] fpath Path to string file containing values of ciphertext.
@param[in] ncomponents Number of components of the object (e.g. 2 for a fresh CT)
@param[out] vec Pointer to memory to store polynomial elements
@param[in] pos Position of file to start reading from
@returns End position of ftell after reading 'num_elements' type-T elements of 'invec' starting from
pos
*/
template <typename T>
std::streampos poly_string_file_load(std::string fpath, std::size_t ncomponents, T *vec,
std::streampos pos = 0)
{
std::vector<T> vec_temp;
std::fstream infile(fpath.c_str(), std::ios::in);
std::cout << std::endl << "opening file at: " << fpath << std::endl << std::endl;
assert(infile.is_open());
char ch;
std::size_t idx = 0;
// -- In case we have multiple lines in a file
if (pos) { infile.seekg(pos); }
while ((idx < ncomponents) && infile.get(ch))
{
// -- First, find the opening bracket
if (ch != '{') continue;
vec_temp.clear();
for (std::size_t i = 0; !infile.eof(); i++)
{
std::string val;
// -- Read in a single byte
infile >> val;
// -- Break when we find the closing bracket
if (val.find("}") != std::string::npos) break;
val.erase(remove(val.begin(), val.end(), ','), val.end());
T val_temp;
if (std::is_same<T, double>::value)
{ val_temp = static_cast<T>(std::stod(val.c_str(), 0)); }
else if (std::is_same<T, uint64_t>::value)
{
val_temp = static_cast<T>(std::strtoull(val.c_str(), 0, 10));
}
else if (std::is_same<T, int64_t>::value)
{
val_temp = static_cast<T>(std::strtoll(val.c_str(), 0, 10));
}
else
{
std::cout << "Error! Type not accounted for." << std::endl;
exit(0);
}
// std::cout << "idx: " << i << " value: " << val_temp << std::endl;
// -- Store found values in a vector
vec_temp.push_back(val_temp);
}
// -- Copy read elements into input vector at specific location
std::size_t N = vec_temp.size();
// print_poly("vec_temp", vec_temp, N);
for (std::size_t i = 0; i < N; i++) { vec[i + idx * N] = vec_temp[i]; }
idx++;
}
std::streampos curr_pos = infile.tellg();
assert(infile.is_open());
infile.close();
std::cout << "curr_pos: " << curr_pos << std::endl;
return curr_pos;
}
/**
Load a polynomial object from a string file.
String file objects should be formatted as follows:
<object_name> : {<value 1>, <value 2>, ...}
@param[in] fpath Path to string file containing values of ciphertext.
@param[in] ncomponents Number of components of the object (e.g. 2 for a fresh CT)
@param[out] vec Vector object to store polynomial values
@param[in] pos Position of file to start reading from
@returns End position of ftell after reading 'num_elements' type-T elements of 'invec' starting from
pos
*/
template <typename T>
std::streampos poly_string_file_load(std::string fpath, std::size_t ncomponents,
std::vector<T> &vec, std::streampos pos = 0)
{
return poly_string_file_load(fpath, ncomponents, &(vec[0]), pos);
}