forked from homenc/HElib
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathnew-api.cpp
More file actions
285 lines (232 loc) · 9.75 KB
/
new-api.cpp
File metadata and controls
285 lines (232 loc) · 9.75 KB
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
class EncodedPtxt;
// container holding either a polynomial
// encoding of either a BGV or CKKS constant
// Interface: not really needed for normal users
class PtxtArray;
// container holding either a either a BGV or CKKS constant
// Interface: see below
class View
{
// NOTE: View is really a typedef for EncryptedArray
// but I suggest we start moving away from that
public:
//========== ENCODING =========
// BGV-only
void encode(EncodedPtxt& eptxt, const std::vector<NTL::ZZX>& array) const;
void encode(EncodedPtxt& eptxt, const std::vector<long>& array) const;
// CKKS-only encoding functions
// mag: defaults to Norm(array).
// prec: defaults to r=getAlMod().getR(), which
// is usually the same as context.getDefaultPrecision().
// mag should be an upper bound on Norm(array).
// If an encoding will be encrypted, the user may wish
// to hide Norm(array) by setting mag to some data-independent
// upper bound. A warning is issued if Norm(array) > mag.
// The encoding will normally have an accuracy of 2^{-prec}, meaning that
// Norm(array - decode(encode(array))) <= 2^{-prec}.
// Note that prec may be positive, negative, or zero.
// The exact logic is a bit heuristic, and a warning is
// issued if the the accuracy exceeds 2^{-prec}.
// NOTE: Norm above is the infinity (i.e., max) norm.
void encode(EncodedPtxt& eptxt,
const std::vector<cx_double>& array,
double mag = -1,
OptLong prec = OptLong()) const;
void encode(EncodedPtxt& eptxt,
const std::vector<double>& array,
double mag = -1,
OptLong prec = OptLong()) const;
// BGV and CKKS
// The following encoding functions are provided for both
// BGV and CKKS to allow for the creation of "masks".
// For CKKS, mag and prec are set to their default values.
void encode(EncodedPtxt& eptxt, const std::vector<bool>& array) const;
void encodeUnitSelector(EncodedPtxt& eptxt, long i) const;
//========= ENCRYPTING ==========
// BGV only
void encrypt(Ctxt& ctxt, const std::vector<NTL::ZZX>& array) const;
void encrypt(Ctxt& ctxt, const std::vector<long>& array) const;
// CKKS only
// NOTE: mag must be set to non-default value
void encrypt(Ctxt& ctxt,
const std::vector<cx_double>& array,
double mag = -1,
OptLong prec = OptLong()) const;
void encrypt(Ctxt& ctxt,
const std::vector<double>& array,
double mag = -1,
OptLong prec = OptLong()) const;
//========= DECRYPTING ==========
// BGV-only
void decrypt(const Ctxt& ctxt,
const SecKey& sKey,
std::vector<NTL::ZZX>& ptxt) const;
void decrypt(const Ctxt& ctxt,
const SecKey& sKey,
std::vector<long>& ptxt) const;
// CKKS-only
void decrypt(const Ctxt& ctxt,
const SecKey& sKey,
std::vector<cx_double>& ptxt,
OptLong prec = OptLong()) const;
void decrypt(const Ctxt& ctxt,
const SecKey& sKey,
std::vector<double>& ptxt,
OptLong prec = OptLong()) const;
};
// It is recommended to use the PtxtArray class to do encoding,
// encrypting, and decrypting.
// The interface is a bit more uniform and convenient.
class PtxtArray
{
public:
// constructors
explicit PtxtArray(const View& view);
explicit PtxtArray(const Context& context); // use default view from context
// NOTE: the View object associated with a PtxtArray
// object never changes
PtxtArray(const PtxtArray& other); // copy
// templates that allow construction via convert:
// T can be any type supported by convert(PtxtArray,T)
template <class T>
PtxtArray(const View& view, const T& t);
template <class T>
PtxtArray(const Context& context, const T& t);
// assignment
PtxtArray& operator=(const PtxtArray& other); // copy
// template that allow assignment via load:
// T can be any type supported by PtxtArray::load(T)
template <class T>
PtxtArray& operator=(const T& t);
void randomReal();
// CKKS only: random number in [0,1] in each slot
void randomComplex();
// CKKS only: random number in complex unit sphere in each slot
void random();
// BGV: random ring element in each slot
// CKKS: random number in [0,1] in each slot
// access methods
const View& getView() const; // preferred name
const View& getEA() const; // legacy name
// The following encode, encrypt, and decrypt operations
// work for both BGV and CKKS
void encode(EncodedPtxt& eptxt,
double mag = -1,
OptLong prec = OptLong()) const;
// eptxt = encoding of *this
// NOTE: for BGV, mag,prec are ignored
void encrypt(Ctxt& ctxt, double mag = -1, OptLong prec = OptLong()) const;
// ctxt = encryption of *this
// NOTES: (1) for BGV, mag,prec are ignored;
// (2) for CKKS, default mag is set to 2^(ceil(log2(max(Norm(x),1)))),
// where x is the underlying vector
void decrypt(const Ctxt& ctxt, const SecKey& sKey, OptLong prec = OptLong());
// *this = decryption of ctxt under sKey
// prec is ignored for BGV
// The following are for CKKS only
void decryptReal(const Ctxt& ctxt,
const SecKey& sKey,
OptLong prec = OptLong());
void decryptComplex(const Ctxt& ctxt,
const SecKey& sKey,
OptLong prec = OptLong());
void rawDecrypt(const Ctxt& ctxt, const SecKey& sKey);
void rawDecryptReal(const Ctxt& ctxt, const SecKey& sKey);
void rawDecryptComplex(const Ctxt& ctxt, const SecKey& sKey);
//===== store =====
// conversion from PtxtArray to std::vector's
void store(std::vector<NTL::ZZX>& vec) const; // BGV only
void store(std::vector<long>& vec) const; // BGV & CKKS
void store(std::vector<double>& vec) const; // CKKS only
void store(std::vector<cx_double>& vec) const; // CKKS only
// NOTE: For CKKS, conversion to vector<cx_double> projects
// the real part, and conversion to vector<long> projects and
// rounds the real part.
//===== load =====
// conversion to PtxtArray from various types
//(this is a much more permissive set of conversions)
// vectors
void load(const std::vector<NTL::ZZX>& vec); // BGV only
void load(const std::vector<int>& vec); // BGV & CKKS
void load(const std::vector<long>& vec); // BGV & CKKS
void load(const std::vector<double>& vec); // CKKS only
void load(const std::vector<cx_double>& vec); // CKKS only
// scalars: puts the same value in each slot
void load(const NTL::ZZX& scalar); // BGV only
void load(int scalar); // BGV & CKKS
void load(long scalar); // BGV & CKKS
void load(double scalar); // CKKS only
void load(cx_double scalar); // CKKS only
// NTL vectors of NTL ring types
void load(const NTL::Vec<NTL::GF2>& vec); // BGV only
void load(const NTL::Vec<NTL::GF2X>& vec); // BGV only
void load(const NTL::Vec<NTL::zz_p>& vec); // BGV only
void load(const NTL::Vec<NTL::zz_pX>& vec); // BGV only
// NTL scalar ring types: puts the same value in each slot
void load(NTL::GF2 scalar); // BGV only
void load(const NTL::GF2X& scalar); // BGV only
void load(NTL::zz_p scalar); // BGV only
void load(const NTL::zz_pX& scalar); // BGV only
// NOTE: for conversion to PtxtArray from vectors, the input
// vector will effectively be truncated or zero-padded to
// match the number of slots in a PtxtArray
};
std::ostream& operator<<(std::ostream& s, const PtxtArray& a);
bool operator==(const PtxtArray& a, const PtxtArray& b);
bool operator!=(const PtxtArray& a, const PtxtArray& b);
// The above are exact comparisons.
// They are not very useful for CKKS.
// norm and distance functions
double Norm(const PtxtArray& a);
double Distance(const PtxtArray& a, const PtxtArray& b);
// NOTES:
// (1) for BGV, the underlying norm is the trivial norm.
// (2) for CKKS, the underlying norm is the l-infty norm.
// These functions, together with the functions defined in NumbTh.h,
// allow one to write
a ==
Approx(b)
// or
a
!=
Approx(b)
// The Approx function takes two optional parameters:
double tolerance; // default is 0.01
double floor; // default is 1.0
// The expression
a == Approx(b, tolerance, floor)
// is true iff Distance(a,b) <= tolerance*max(Norm(b),floor).
// The idea is that it checks if the relative error is
// at most tolerance, unless Norm(b) itself is too small
// (as determined by floor).
// For BGV, with the default parameters, a == Approx(b)
// is equivalent to an exact equality test.
// arithmetic:
PtxtArray&
operator+=(PtxtArray& a, const PtxtArray& b);
PtxtArray& operator-=(PtxtArray& a, const PtxtArray& b);
PtxtArray& operator*=(PtxtArray& a, const PtxtArray& b);
// also for b of of any type T supported by PtxtArray::load(T):
// NOTE: SFINAE is used to truly limit T
template <class T>
PtxtArray& operator+=(PtxtArray& a, const T& b);
template <class T>
PtxtArray& operator-=(PtxtArray& a, const T& b);
template <class T>
PtxtArray& operator*=(PtxtArray& a, const T& b);
void negate(PtxtArray& a);
void power(PtxtArray& a, long e);
// data movement
void rotate(PtxtArray& a, long k);
void shift(PtxtArray& a, long k);
voud rotate1D(PtxtArray& a, long i, long k);
voud shift1D(PtxtArray& a, long i, long k);
void applyPerm(PtxtArray& a, const NTL::Vec<long>& pi);
// For CKKS, these use complex conjugation, rather than Frobenius
void frobeniusAutomorph(PtxtArray& a, long j);
void frobeniusAutomorph(PtxtArray& a, const NTL::Vec<long>& vec);
void conjugate(PtxtArray& a); // synonym for frobeniusAutomorph(ctxt, 1);
void extractRealPart(PtxtArray& a); // CKKS only
void extractImPart(PtxtArray& a); // CKKS only
void totalSums(PtxtArray& a);
void runningSums(PtxtArray& a);