1 /*
2  * @file lib-hexl-benchmark : library benchmark routines for comparison by build
3  * @author TPOC: contact@palisade-crypto.org
4  *
5  * @copyright Copyright (c) 2019, New Jersey Institute of Technology (NJIT)
6  * All rights reserved.
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions are met:
9  * 1. Redistributions of source code must retain the above copyright notice,
10  * this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright notice,
12  * this list of conditions and the following disclaimer in the documentation
13  * and/or other materials provided with the distribution. THIS SOFTWARE IS
14  * PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
15  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
16  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
17  * EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
18  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
20  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
21  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
23  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  *
25  */
26 
27 /*
28  * This file benchmarks a small number of operations in order to exercise large
29  * pieces of the library using varying parameters. To view or edit the
30  * parameter sets, see lib-hexl-util.h
31  */
32 
33 #define PROFILE
34 #define _USE_MATH_DEFINES
35 #include "benchmark/benchmark.h"
36 
37 #include <fstream>
38 #include <iostream>
39 #include <iterator>
40 #include <limits>
41 #include <random>
42 
43 #include "palisade.h"
44 
45 #include "cryptocontextgen.h"
46 #include "cryptocontexthelper.h"
47 
48 #include "utils/debug.h"
49 
50 #include "lib-hexl-util.h"
51 
52 using namespace std;
53 using namespace lbcrypto;
54 
NTTTransform(benchmark::State & state)55 void NTTTransform(benchmark::State &state) {
56   usint phim = state.range(0);
57   usint m = phim * 2;
58 
59   NativeInteger modulusQ("137438822401");
60   NativeInteger rootOfUnity = RootOfUnity(m, modulusQ);
61 
62   DiscreteUniformGeneratorImpl<NativeVector> dug;
63   dug.SetModulus(modulusQ);
64   NativeVector x = dug.GenerateVector(phim);
65   NativeVector X(phim);
66 
67   ChineseRemainderTransformFTT<NativeVector>::PreCompute(rootOfUnity, m,
68                                                          modulusQ);
69 
70   while (state.KeepRunning()) {
71     ChineseRemainderTransformFTT<NativeVector>::ForwardTransformToBitReverse(
72         x, rootOfUnity, m, &X);
73   }
74 }
75 
76 HEXL_NTT_BENCHMARK(NTTTransform);
77 
INTTTransform(benchmark::State & state)78 void INTTTransform(benchmark::State &state) {
79   usint phim = state.range(0);
80   usint m = phim * 2;
81 
82   NativeInteger modulusQ("137438822401");
83   NativeInteger rootOfUnity = RootOfUnity(m, modulusQ);
84 
85   DiscreteUniformGeneratorImpl<NativeVector> dug;
86   dug.SetModulus(modulusQ);
87   NativeVector x = dug.GenerateVector(phim);
88   NativeVector X(phim);
89 
90   ChineseRemainderTransformFTT<NativeVector>::PreCompute(rootOfUnity, m,
91                                                          modulusQ);
92 
93   while (state.KeepRunning()) {
94     ChineseRemainderTransformFTT<NativeVector>::InverseTransformFromBitReverse(
95         x, rootOfUnity, m, &X);
96   }
97 }
98 
99 HEXL_NTT_BENCHMARK(INTTTransform);
100 
NTTTransformInPlace(benchmark::State & state)101 void NTTTransformInPlace(benchmark::State &state) {
102   usint phim = state.range(0);
103   usint m = phim * 2;
104 
105   NativeInteger modulusQ("137438822401");
106   NativeInteger rootOfUnity = RootOfUnity(m, modulusQ);
107 
108   DiscreteUniformGeneratorImpl<NativeVector> dug;
109   dug.SetModulus(modulusQ);
110   NativeVector x = dug.GenerateVector(phim);
111 
112   ChineseRemainderTransformFTT<NativeVector>::PreCompute(rootOfUnity, m,
113                                                          modulusQ);
114 
115   while (state.KeepRunning()) {
116     ChineseRemainderTransformFTT<
117         NativeVector>::ForwardTransformToBitReverseInPlace(rootOfUnity, m, &x);
118   }
119 }
120 
121 HEXL_NTT_BENCHMARK(NTTTransformInPlace);
122 
INTTTransformInPlace(benchmark::State & state)123 void INTTTransformInPlace(benchmark::State &state) {
124   usint phim = state.range(0);
125   usint m = phim * 2;
126 
127   NativeInteger modulusQ("137438822401");
128   NativeInteger rootOfUnity = RootOfUnity(m, modulusQ);
129 
130   DiscreteUniformGeneratorImpl<NativeVector> dug;
131   dug.SetModulus(modulusQ);
132   NativeVector x = dug.GenerateVector(phim);
133   NativeVector X(phim);
134 
135   ChineseRemainderTransformFTT<NativeVector>::PreCompute(rootOfUnity, m,
136                                                          modulusQ);
137 
138   while (state.KeepRunning()) {
139     ChineseRemainderTransformFTT<
140         NativeVector>::InverseTransformFromBitReverseInPlace(rootOfUnity, m,
141                                                              &x);
142   }
143 }
144 
145 HEXL_NTT_BENCHMARK(INTTTransformInPlace);
146 
147 /*
148  * BFVrns benchmarks
149  */
150 
BFVrns_KeyGen(benchmark::State & state)151 void BFVrns_KeyGen(benchmark::State &state) {
152   CryptoContext<DCRTPoly> cc =
153       GenerateBFVrnsContext(state.range(0), state.range(1));
154 
155   LPKeyPair<DCRTPoly> keyPair;
156 
157   while (state.KeepRunning()) {
158     keyPair = cc->KeyGen();
159   }
160 }
161 
162 HEXL_BENCHMARK(BFVrns_KeyGen);
163 
BFVrns_MultKeyGen(benchmark::State & state)164 void BFVrns_MultKeyGen(benchmark::State &state) {
165   CryptoContext<DCRTPoly> cc =
166       GenerateBFVrnsContext(state.range(0), state.range(1));
167 
168   LPKeyPair<DCRTPoly> keyPair;
169   keyPair = cc->KeyGen();
170 
171   while (state.KeepRunning()) {
172     cc->EvalMultKeyGen(keyPair.secretKey);
173   }
174 }
175 
176 HEXL_BENCHMARK(BFVrns_MultKeyGen);
177 
BFVrns_EvalAtIndexKeyGen(benchmark::State & state)178 void BFVrns_EvalAtIndexKeyGen(benchmark::State &state) {
179   CryptoContext<DCRTPoly> cc =
180       GenerateBFVrnsContext(state.range(0), state.range(1));
181 
182   LPKeyPair<DCRTPoly> keyPair;
183   keyPair = cc->KeyGen();
184 
185   std::vector<int32_t> indexList(1);
186   for (usint i = 0; i < 1; i++) {
187     indexList[i] = 1;
188   }
189 
190   while (state.KeepRunning()) {
191     cc->EvalAtIndexKeyGen(keyPair.secretKey, indexList);
192   }
193 }
194 
195 HEXL_BENCHMARK(BFVrns_EvalAtIndexKeyGen);
196 
BFVrns_Encryption(benchmark::State & state)197 void BFVrns_Encryption(benchmark::State &state) {
198   CryptoContext<DCRTPoly> cc =
199       GenerateBFVrnsContext(state.range(0), state.range(1));
200 
201   LPKeyPair<DCRTPoly> keyPair = cc->KeyGen();
202 
203   std::vector<int64_t> vectorOfInts1 = {1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0};
204   Plaintext plaintext1 = cc->MakePackedPlaintext(vectorOfInts1);
205 
206   while (state.KeepRunning()) {
207     auto ciphertext1 = cc->Encrypt(keyPair.publicKey, plaintext1);
208   }
209 }
210 
211 HEXL_BENCHMARK(BFVrns_Encryption);
212 
BFVrns_Decryption(benchmark::State & state)213 void BFVrns_Decryption(benchmark::State &state) {
214   CryptoContext<DCRTPoly> cc =
215       GenerateBFVrnsContext(state.range(0), state.range(1));
216 
217   LPKeyPair<DCRTPoly> keyPair = cc->KeyGen();
218 
219   std::vector<int64_t> vectorOfInts1 = {1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0};
220   Plaintext plaintext1 = cc->MakePackedPlaintext(vectorOfInts1);
221 
222   auto ciphertext1 = cc->Encrypt(keyPair.publicKey, plaintext1);
223   Plaintext plaintextDec1;
224 
225   while (state.KeepRunning()) {
226     cc->Decrypt(keyPair.secretKey, ciphertext1, &plaintextDec1);
227   }
228 }
229 
230 HEXL_BENCHMARK(BFVrns_Decryption);
231 
BFVrns_Add(benchmark::State & state)232 void BFVrns_Add(benchmark::State &state) {
233   CryptoContext<DCRTPoly> cc =
234       GenerateBFVrnsContext(state.range(0), state.range(1));
235 
236   LPKeyPair<DCRTPoly> keyPair = cc->KeyGen();
237 
238   std::vector<int64_t> vectorOfInts1 = {1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0};
239   std::vector<int64_t> vectorOfInts2 = {0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1};
240 
241   auto plaintext1 = cc->MakePackedPlaintext(vectorOfInts1);
242   auto plaintext2 = cc->MakePackedPlaintext(vectorOfInts2);
243 
244   auto ciphertext1 = cc->Encrypt(keyPair.publicKey, plaintext1);
245   auto ciphertext2 = cc->Encrypt(keyPair.publicKey, plaintext2);
246 
247   while (state.KeepRunning()) {
248     auto ciphertextAdd = cc->EvalAdd(ciphertext1, ciphertext2);
249   }
250 }
251 
252 HEXL_BENCHMARK(BFVrns_Add);
253 
BFVrns_AddInPlace(benchmark::State & state)254 void BFVrns_AddInPlace(benchmark::State &state) {
255   CryptoContext<DCRTPoly> cc =
256       GenerateBFVrnsContext(state.range(0), state.range(1));
257 
258   LPKeyPair<DCRTPoly> keyPair = cc->KeyGen();
259 
260   std::vector<int64_t> vectorOfInts1 = {1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0};
261   std::vector<int64_t> vectorOfInts2 = {0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1};
262 
263   auto plaintext1 = cc->MakePackedPlaintext(vectorOfInts1);
264   auto plaintext2 = cc->MakePackedPlaintext(vectorOfInts2);
265 
266   auto ciphertext1 = cc->Encrypt(keyPair.publicKey, plaintext1);
267   auto ciphertext2 = cc->Encrypt(keyPair.publicKey, plaintext2);
268 
269   while (state.KeepRunning()) {
270     cc->EvalAddInPlace(ciphertext1, ciphertext2);
271   }
272 }
273 
274 HEXL_BENCHMARK(BFVrns_AddInPlace);
275 
BFVrns_AddPlain(benchmark::State & state)276 void BFVrns_AddPlain(benchmark::State &state) {
277   CryptoContext<DCRTPoly> cc =
278       GenerateBFVrnsContext(state.range(0), state.range(1));
279 
280   LPKeyPair<DCRTPoly> keyPair = cc->KeyGen();
281 
282   std::vector<int64_t> vectorOfInts1 = {1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0};
283   Plaintext plaintext1 = cc->MakeCoefPackedPlaintext(vectorOfInts1);
284 
285   std::vector<int64_t> vectorOfInts2 = {1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0};
286   Plaintext plaintext2 = cc->MakeCoefPackedPlaintext(vectorOfInts2);
287 
288   auto ciphertext1 = cc->Encrypt(keyPair.publicKey, plaintext1);
289 
290   while (state.KeepRunning()) {
291     auto ciphertextAdd = cc->EvalAdd(ciphertext1, plaintext2);
292   }
293 }
294 
295 HEXL_BENCHMARK(BFVrns_AddPlain);
296 
BFVrns_Negate(benchmark::State & state)297 void BFVrns_Negate(benchmark::State &state) {
298   CryptoContext<DCRTPoly> cc =
299       GenerateBFVrnsContext(state.range(0), state.range(1));
300 
301   LPKeyPair<DCRTPoly> keyPair = cc->KeyGen();
302 
303   std::vector<int64_t> vectorOfInts1 = {1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0};
304   Plaintext plaintext1 = cc->MakeCoefPackedPlaintext(vectorOfInts1);
305 
306   auto ciphertext1 = cc->Encrypt(keyPair.publicKey, plaintext1);
307 
308   while (state.KeepRunning()) {
309     auto ciphertextNeg = cc->EvalNegate(ciphertext1);
310   }
311 }
312 
313 HEXL_BENCHMARK(BFVrns_Negate);
314 
BFVrns_Sub(benchmark::State & state)315 void BFVrns_Sub(benchmark::State &state) {
316   CryptoContext<DCRTPoly> cc =
317       GenerateBFVrnsContext(state.range(0), state.range(1));
318 
319   LPKeyPair<DCRTPoly> keyPair = cc->KeyGen();
320 
321   std::vector<int64_t> vectorOfInts1 = {1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0};
322   std::vector<int64_t> vectorOfInts2 = {0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1};
323 
324   auto plaintext1 = cc->MakeCoefPackedPlaintext(vectorOfInts1);
325   auto plaintext2 = cc->MakeCoefPackedPlaintext(vectorOfInts2);
326 
327   auto ciphertext1 = cc->Encrypt(keyPair.publicKey, plaintext1);
328   auto ciphertext2 = cc->Encrypt(keyPair.publicKey, plaintext2);
329 
330   while (state.KeepRunning()) {
331     auto ciphertextSub = cc->EvalSub(ciphertext1, ciphertext2);
332   }
333 }
334 
335 HEXL_BENCHMARK(BFVrns_Sub);
336 
BFVrns_SubPlain(benchmark::State & state)337 void BFVrns_SubPlain(benchmark::State &state) {
338   CryptoContext<DCRTPoly> cc =
339       GenerateBFVrnsContext(state.range(0), state.range(1));
340 
341   LPKeyPair<DCRTPoly> keyPair = cc->KeyGen();
342 
343   std::vector<int64_t> vectorOfInts1 = {1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0};
344   Plaintext plaintext1 = cc->MakeCoefPackedPlaintext(vectorOfInts1);
345 
346   std::vector<int64_t> vectorOfInts2 = {1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0};
347   Plaintext plaintext2 = cc->MakeCoefPackedPlaintext(vectorOfInts2);
348 
349   auto ciphertext1 = cc->Encrypt(keyPair.publicKey, plaintext1);
350 
351   while (state.KeepRunning()) {
352     auto ciphertextSub = cc->EvalSub(ciphertext1, plaintext2);
353   }
354 }
355 
356 HEXL_BENCHMARK(BFVrns_SubPlain);
357 
BFVrns_MultNoRelin(benchmark::State & state)358 void BFVrns_MultNoRelin(benchmark::State &state) {
359   CryptoContext<DCRTPoly> cc =
360       GenerateBFVrnsContext(state.range(0), state.range(1));
361 
362   LPKeyPair<DCRTPoly> keyPair = cc->KeyGen();
363 
364   std::vector<int64_t> vectorOfInts1 = {1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0};
365   Plaintext plaintext1 = cc->MakePackedPlaintext(vectorOfInts1);
366 
367   std::vector<int64_t> vectorOfInts2 = {1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0};
368   Plaintext plaintext2 = cc->MakePackedPlaintext(vectorOfInts2);
369 
370   auto ciphertext1 = cc->Encrypt(keyPair.publicKey, plaintext1);
371   auto ciphertext2 = cc->Encrypt(keyPair.publicKey, plaintext2);
372 
373   while (state.KeepRunning()) {
374     auto ciphertextMul = cc->EvalMultNoRelin(ciphertext1, ciphertext2);
375   }
376 }
377 
378 HEXL_BENCHMARK(BFVrns_MultNoRelin);
379 
BFVrns_MultRelin(benchmark::State & state)380 void BFVrns_MultRelin(benchmark::State &state) {
381   CryptoContext<DCRTPoly> cc =
382       GenerateBFVrnsContext(state.range(0), state.range(1));
383 
384   LPKeyPair<DCRTPoly> keyPair = cc->KeyGen();
385   cc->EvalMultKeyGen(keyPair.secretKey);
386 
387   std::vector<int64_t> vectorOfInts1 = {1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0};
388   Plaintext plaintext1 = cc->MakePackedPlaintext(vectorOfInts1);
389 
390   std::vector<int64_t> vectorOfInts2 = {1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0};
391   Plaintext plaintext2 = cc->MakePackedPlaintext(vectorOfInts2);
392 
393   auto ciphertext1 = cc->Encrypt(keyPair.publicKey, plaintext1);
394   auto ciphertext2 = cc->Encrypt(keyPair.publicKey, plaintext2);
395 
396   while (state.KeepRunning()) {
397     auto ciphertextMul = cc->EvalMult(ciphertext1, ciphertext2);
398   }
399 }
400 
401 HEXL_BENCHMARK(BFVrns_MultRelin);
402 
BFVrns_MultPlain(benchmark::State & state)403 void BFVrns_MultPlain(benchmark::State &state) {
404   CryptoContext<DCRTPoly> cc =
405       GenerateBFVrnsContext(state.range(0), state.range(1));
406 
407   LPKeyPair<DCRTPoly> keyPair = cc->KeyGen();
408   cc->EvalMultKeyGen(keyPair.secretKey);
409 
410   std::vector<int64_t> vectorOfInts1 = {1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0};
411   Plaintext plaintext1 = cc->MakeCoefPackedPlaintext(vectorOfInts1);
412 
413   std::vector<int64_t> vectorOfInts2 = {1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0};
414   Plaintext plaintext2 = cc->MakeCoefPackedPlaintext(vectorOfInts2);
415 
416   auto ciphertext1 = cc->Encrypt(keyPair.publicKey, plaintext1);
417 
418   while (state.KeepRunning()) {
419     auto ciphertextMul = cc->EvalMult(ciphertext1, plaintext2);
420   }
421 }
422 
423 HEXL_BENCHMARK(BFVrns_MultPlain);
424 
BFVrns_EvalAtIndex(benchmark::State & state)425 void BFVrns_EvalAtIndex(benchmark::State &state) {
426   CryptoContext<DCRTPoly> cc =
427       GenerateBFVrnsContext(state.range(0), state.range(1));
428 
429   LPKeyPair<DCRTPoly> keyPair = cc->KeyGen();
430   cc->EvalMultKeyGen(keyPair.secretKey);
431 
432   std::vector<int32_t> indexList(1);
433   for (usint i = 0; i < 1; i++) {
434     indexList[i] = 1;
435   }
436 
437   cc->EvalAtIndexKeyGen(keyPair.secretKey, indexList);
438 
439   std::vector<int64_t> vectorOfInts1 = {1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0};
440   std::vector<int64_t> vectorOfInts2 = {0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1};
441 
442   auto plaintext1 = cc->MakePackedPlaintext(vectorOfInts1);
443   auto plaintext2 = cc->MakePackedPlaintext(vectorOfInts2);
444 
445   auto ciphertext1 = cc->Encrypt(keyPair.publicKey, plaintext1);
446   auto ciphertext2 = cc->Encrypt(keyPair.publicKey, plaintext2);
447 
448   auto ciphertextMul = cc->EvalMult(ciphertext1, ciphertext2);
449 
450   while (state.KeepRunning()) {
451     auto ciphertext3 = cc->EvalAtIndex(ciphertextMul, 1);
452   }
453 }
454 
455 HEXL_BENCHMARK(BFVrns_EvalAtIndex);
456 
457 /*
458  * CKKS benchmarks
459  * */
460 
CKKS_KeyGen(benchmark::State & state)461 void CKKS_KeyGen(benchmark::State &state) {
462   CryptoContext<DCRTPoly> cc =
463       GenerateCKKSContext(state.range(0), state.range(1));
464 
465   LPKeyPair<DCRTPoly> keyPair;
466 
467   while (state.KeepRunning()) {
468     keyPair = cc->KeyGen();
469   }
470 }
471 
472 HEXL_BENCHMARK(CKKS_KeyGen);
473 
CKKS_MultKeyGen(benchmark::State & state)474 void CKKS_MultKeyGen(benchmark::State &state) {
475   CryptoContext<DCRTPoly> cc =
476       GenerateCKKSContext(state.range(0), state.range(1));
477 
478   LPKeyPair<DCRTPoly> keyPair;
479   keyPair = cc->KeyGen();
480 
481   while (state.KeepRunning()) {
482     cc->EvalMultKeyGen(keyPair.secretKey);
483   }
484 }
485 
486 HEXL_BENCHMARK(CKKS_MultKeyGen);
487 
CKKS_EvalAtIndexKeyGen(benchmark::State & state)488 void CKKS_EvalAtIndexKeyGen(benchmark::State &state) {
489   CryptoContext<DCRTPoly> cc =
490       GenerateCKKSContext(state.range(0), state.range(1));
491 
492   LPKeyPair<DCRTPoly> keyPair;
493   keyPair = cc->KeyGen();
494 
495   std::vector<int32_t> indexList(1);
496   for (usint i = 0; i < 1; i++) {
497     indexList[i] = 1;
498   }
499 
500   while (state.KeepRunning()) {
501     cc->EvalAtIndexKeyGen(keyPair.secretKey, indexList);
502   }
503 }
504 
505 HEXL_BENCHMARK(CKKS_EvalAtIndexKeyGen);
506 
CKKS_Encryption(benchmark::State & state)507 void CKKS_Encryption(benchmark::State &state) {
508   CryptoContext<DCRTPoly> cc =
509       GenerateCKKSContext(state.range(0), state.range(1));
510 
511   LPKeyPair<DCRTPoly> keyPair = cc->KeyGen();
512 
513   usint slots = cc->GetEncodingParams()->GetBatchSize();
514   std::vector<std::complex<double>> vectorOfInts(slots);
515   for (usint i = 0; i < slots; i++) {
516     vectorOfInts[i] = 1.001 * i;
517   }
518 
519   auto plaintext = cc->MakeCKKSPackedPlaintext(vectorOfInts);
520 
521   while (state.KeepRunning()) {
522     auto ciphertext = cc->Encrypt(keyPair.publicKey, plaintext);
523   }
524 }
525 
526 HEXL_BENCHMARK(CKKS_Encryption);
527 
CKKS_Decryption(benchmark::State & state)528 void CKKS_Decryption(benchmark::State &state) {
529   CryptoContext<DCRTPoly> cc =
530       GenerateCKKSContext(state.range(0), state.range(1));
531 
532   LPKeyPair<DCRTPoly> keyPair = cc->KeyGen();
533 
534   usint slots = cc->GetEncodingParams()->GetBatchSize();
535   std::vector<std::complex<double>> vectorOfInts1(slots);
536   for (usint i = 0; i < slots; i++) {
537     vectorOfInts1[i] = 1.001 * i;
538   }
539 
540   auto plaintext1 = cc->MakeCKKSPackedPlaintext(vectorOfInts1);
541   auto ciphertext1 = cc->Encrypt(keyPair.publicKey, plaintext1);
542   ciphertext1 = cc->LevelReduce(ciphertext1, nullptr, 1);
543 
544   Plaintext plaintextDec1;
545 
546   while (state.KeepRunning()) {
547     cc->Decrypt(keyPair.secretKey, ciphertext1, &plaintextDec1);
548   }
549 }
550 
551 HEXL_BENCHMARK(CKKS_Decryption);
552 
CKKS_Add(benchmark::State & state)553 void CKKS_Add(benchmark::State &state) {
554   CryptoContext<DCRTPoly> cc =
555       GenerateCKKSContext(state.range(0), state.range(1));
556 
557   LPKeyPair<DCRTPoly> keyPair = cc->KeyGen();
558 
559   usint slots = cc->GetEncodingParams()->GetBatchSize();
560   std::vector<std::complex<double>> vectorOfInts1(slots);
561   for (usint i = 0; i < slots; i++) {
562     vectorOfInts1[i] = 1.001 * i;
563   }
564   std::vector<std::complex<double>> vectorOfInts2(slots);
565   for (usint i = 0; i < slots; i++) {
566     vectorOfInts2[i] = 1.001 * i;
567   }
568 
569   auto plaintext1 = cc->MakeCKKSPackedPlaintext(vectorOfInts1);
570   auto plaintext2 = cc->MakeCKKSPackedPlaintext(vectorOfInts2);
571 
572   auto ciphertext1 = cc->Encrypt(keyPair.publicKey, plaintext1);
573   auto ciphertext2 = cc->Encrypt(keyPair.publicKey, plaintext2);
574 
575   while (state.KeepRunning()) {
576     auto ciphertextAdd = cc->EvalAdd(ciphertext1, ciphertext2);
577   }
578 }
579 
580 HEXL_BENCHMARK(CKKS_Add);
581 
CKKS_AddInPlace(benchmark::State & state)582 void CKKS_AddInPlace(benchmark::State &state) {
583   CryptoContext<DCRTPoly> cc =
584       GenerateCKKSContext(state.range(0), state.range(1));
585 
586   LPKeyPair<DCRTPoly> keyPair = cc->KeyGen();
587 
588   usint slots = cc->GetEncodingParams()->GetBatchSize();
589   std::vector<std::complex<double>> vectorOfInts1(slots);
590   for (usint i = 0; i < slots; i++) {
591     vectorOfInts1[i] = 1.001 * i;
592   }
593   std::vector<std::complex<double>> vectorOfInts2(slots);
594   for (usint i = 0; i < slots; i++) {
595     vectorOfInts2[i] = 1.001 * i;
596   }
597 
598   auto plaintext1 = cc->MakeCKKSPackedPlaintext(vectorOfInts1);
599   auto plaintext2 = cc->MakeCKKSPackedPlaintext(vectorOfInts2);
600 
601   auto ciphertext1 = cc->Encrypt(keyPair.publicKey, plaintext1);
602   auto ciphertext2 = cc->Encrypt(keyPair.publicKey, plaintext2);
603 
604   while (state.KeepRunning()) {
605     cc->EvalAddInPlace(ciphertext1, ciphertext2);
606   }
607 }
608 
609 HEXL_BENCHMARK(CKKS_AddInPlace);
610 
CKKS_AddPlain(benchmark::State & state)611 void CKKS_AddPlain(benchmark::State &state) {
612   CryptoContext<DCRTPoly> cc =
613       GenerateCKKSContext(state.range(0), state.range(1));
614 
615   LPKeyPair<DCRTPoly> keyPair = cc->KeyGen();
616 
617   usint slots = cc->GetEncodingParams()->GetBatchSize();
618   std::vector<std::complex<double>> vectorOfInts1(slots);
619   for (usint i = 0; i < slots; i++) {
620     vectorOfInts1[i] = 1.001 * i;
621   }
622   std::vector<std::complex<double>> vectorOfInts2(slots);
623   for (usint i = 0; i < slots; i++) {
624     vectorOfInts2[i] = 1.001 * i;
625   }
626 
627   auto plaintext1 = cc->MakeCKKSPackedPlaintext(vectorOfInts1);
628   auto plaintext2 = cc->MakeCKKSPackedPlaintext(vectorOfInts2);
629 
630   auto ciphertext1 = cc->Encrypt(keyPair.publicKey, plaintext1);
631 
632   while (state.KeepRunning()) {
633     auto ciphertextAdd = cc->EvalAdd(ciphertext1, plaintext2);
634   }
635 }
636 
637 HEXL_BENCHMARK(CKKS_AddPlain);
638 
CKKS_Negate(benchmark::State & state)639 void CKKS_Negate(benchmark::State &state) {
640   CryptoContext<DCRTPoly> cc =
641       GenerateCKKSContext(state.range(0), state.range(1));
642 
643   LPKeyPair<DCRTPoly> keyPair = cc->KeyGen();
644 
645   usint slots = cc->GetEncodingParams()->GetBatchSize();
646   std::vector<std::complex<double>> vectorOfInts1(slots);
647   for (usint i = 0; i < slots; i++) {
648     vectorOfInts1[i] = 1.001 * i;
649   }
650 
651   auto plaintext1 = cc->MakeCKKSPackedPlaintext(vectorOfInts1);
652   auto ciphertext1 = cc->Encrypt(keyPair.publicKey, plaintext1);
653 
654   while (state.KeepRunning()) {
655     auto ciphertextNeg = cc->EvalNegate(ciphertext1);
656   }
657 }
658 
659 HEXL_BENCHMARK(CKKS_Negate);
660 
CKKS_Sub(benchmark::State & state)661 void CKKS_Sub(benchmark::State &state) {
662   CryptoContext<DCRTPoly> cc =
663       GenerateCKKSContext(state.range(0), state.range(1));
664 
665   LPKeyPair<DCRTPoly> keyPair = cc->KeyGen();
666 
667   usint slots = cc->GetEncodingParams()->GetBatchSize();
668   std::vector<std::complex<double>> vectorOfInts1(slots);
669   for (usint i = 0; i < slots; i++) {
670     vectorOfInts1[i] = 1.001 * i;
671   }
672   std::vector<std::complex<double>> vectorOfInts2(slots);
673   for (usint i = 0; i < slots; i++) {
674     vectorOfInts2[i] = 1.001 * i;
675   }
676 
677   auto plaintext1 = cc->MakeCKKSPackedPlaintext(vectorOfInts1);
678   auto plaintext2 = cc->MakeCKKSPackedPlaintext(vectorOfInts2);
679 
680   auto ciphertext1 = cc->Encrypt(keyPair.publicKey, plaintext1);
681   auto ciphertext2 = cc->Encrypt(keyPair.publicKey, plaintext2);
682 
683   while (state.KeepRunning()) {
684     auto ciphertextSub = cc->EvalSub(ciphertext1, ciphertext2);
685   }
686 }
687 
688 HEXL_BENCHMARK(CKKS_Sub);
689 
CKKS_SubPlain(benchmark::State & state)690 void CKKS_SubPlain(benchmark::State &state) {
691   CryptoContext<DCRTPoly> cc =
692       GenerateCKKSContext(state.range(0), state.range(1));
693 
694   LPKeyPair<DCRTPoly> keyPair = cc->KeyGen();
695 
696   usint slots = cc->GetEncodingParams()->GetBatchSize();
697   std::vector<std::complex<double>> vectorOfInts1(slots);
698   for (usint i = 0; i < slots; i++) {
699     vectorOfInts1[i] = 1.001 * i;
700   }
701   std::vector<std::complex<double>> vectorOfInts2(slots);
702   for (usint i = 0; i < slots; i++) {
703     vectorOfInts2[i] = 1.001 * i;
704   }
705 
706   auto plaintext1 = cc->MakeCKKSPackedPlaintext(vectorOfInts1);
707   auto plaintext2 = cc->MakeCKKSPackedPlaintext(vectorOfInts2);
708 
709   auto ciphertext1 = cc->Encrypt(keyPair.publicKey, plaintext1);
710 
711   while (state.KeepRunning()) {
712     auto ciphertextSub = cc->EvalSub(ciphertext1, plaintext2);
713   }
714 }
715 
716 HEXL_BENCHMARK(CKKS_SubPlain);
717 
CKKS_MultNoRelin(benchmark::State & state)718 void CKKS_MultNoRelin(benchmark::State &state) {
719   CryptoContext<DCRTPoly> cc =
720       GenerateCKKSContext(state.range(0), state.range(1));
721 
722   LPKeyPair<DCRTPoly> keyPair = cc->KeyGen();
723 
724   usint slots = cc->GetEncodingParams()->GetBatchSize();
725   std::vector<std::complex<double>> vectorOfInts1(slots);
726   for (usint i = 0; i < slots; i++) {
727     vectorOfInts1[i] = 1.001 * i;
728   }
729   std::vector<std::complex<double>> vectorOfInts2(slots);
730   for (usint i = 0; i < slots; i++) {
731     vectorOfInts2[i] = 1.001 * i;
732   }
733 
734   auto plaintext1 = cc->MakeCKKSPackedPlaintext(vectorOfInts1);
735   auto plaintext2 = cc->MakeCKKSPackedPlaintext(vectorOfInts2);
736 
737   auto ciphertext1 = cc->Encrypt(keyPair.publicKey, plaintext1);
738   auto ciphertext2 = cc->Encrypt(keyPair.publicKey, plaintext2);
739 
740   while (state.KeepRunning()) {
741     auto ciphertextMul = cc->EvalMultNoRelin(ciphertext1, ciphertext2);
742   }
743 }
744 
745 HEXL_BENCHMARK(CKKS_MultNoRelin);
746 
CKKS_MultRelin(benchmark::State & state)747 void CKKS_MultRelin(benchmark::State &state) {
748   CryptoContext<DCRTPoly> cc =
749       GenerateCKKSContext(state.range(0), state.range(1));
750 
751   LPKeyPair<DCRTPoly> keyPair = cc->KeyGen();
752   cc->EvalMultKeyGen(keyPair.secretKey);
753 
754   usint slots = cc->GetEncodingParams()->GetBatchSize();
755   std::vector<std::complex<double>> vectorOfInts1(slots);
756   for (usint i = 0; i < slots; i++) {
757     vectorOfInts1[i] = 1.001 * i;
758   }
759   std::vector<std::complex<double>> vectorOfInts2(slots);
760   for (usint i = 0; i < slots; i++) {
761     vectorOfInts2[i] = 1.001 * i;
762   }
763 
764   auto plaintext1 = cc->MakeCKKSPackedPlaintext(vectorOfInts1);
765   auto plaintext2 = cc->MakeCKKSPackedPlaintext(vectorOfInts2);
766 
767   auto ciphertext1 = cc->Encrypt(keyPair.publicKey, plaintext1);
768   auto ciphertext2 = cc->Encrypt(keyPair.publicKey, plaintext2);
769 
770   while (state.KeepRunning()) {
771     auto ciphertextMul = cc->EvalMult(ciphertext1, ciphertext2);
772   }
773 }
774 
775 HEXL_BENCHMARK(CKKS_MultRelin);
776 
CKKS_MultPlain(benchmark::State & state)777 void CKKS_MultPlain(benchmark::State &state) {
778   CryptoContext<DCRTPoly> cc =
779       GenerateCKKSContext(state.range(0), state.range(1));
780 
781   LPKeyPair<DCRTPoly> keyPair = cc->KeyGen();
782   cc->EvalMultKeyGen(keyPair.secretKey);
783 
784   usint slots = cc->GetEncodingParams()->GetBatchSize();
785   std::vector<std::complex<double>> vectorOfInts1(slots);
786   for (usint i = 0; i < slots; i++) {
787     vectorOfInts1[i] = 1.001 * i;
788   }
789   std::vector<std::complex<double>> vectorOfInts2(slots);
790   for (usint i = 0; i < slots; i++) {
791     vectorOfInts2[i] = 1.001 * i;
792   }
793 
794   auto plaintext1 = cc->MakeCKKSPackedPlaintext(vectorOfInts1);
795   auto plaintext2 = cc->MakeCKKSPackedPlaintext(vectorOfInts2);
796 
797   auto ciphertext1 = cc->Encrypt(keyPair.publicKey, plaintext1);
798 
799   while (state.KeepRunning()) {
800     auto ciphertextMul = cc->EvalMult(ciphertext1, plaintext2);
801   }
802 }
803 
804 HEXL_BENCHMARK(CKKS_MultPlain);
805 
CKKS_Relin(benchmark::State & state)806 void CKKS_Relin(benchmark::State &state) {
807   CryptoContext<DCRTPoly> cc =
808       GenerateCKKSContext(state.range(0), state.range(1));
809 
810   LPKeyPair<DCRTPoly> keyPair = cc->KeyGen();
811   cc->EvalMultKeyGen(keyPair.secretKey);
812 
813   usint slots = cc->GetEncodingParams()->GetBatchSize();
814   std::vector<std::complex<double>> vectorOfInts1(slots);
815   for (usint i = 0; i < slots; i++) {
816     vectorOfInts1[i] = 1.001 * i;
817   }
818   std::vector<std::complex<double>> vectorOfInts2(slots);
819   for (usint i = 0; i < slots; i++) {
820     vectorOfInts2[i] = 1.001 * i;
821   }
822 
823   auto plaintext1 = cc->MakeCKKSPackedPlaintext(vectorOfInts1);
824   auto plaintext2 = cc->MakeCKKSPackedPlaintext(vectorOfInts2);
825 
826   auto ciphertext1 = cc->Encrypt(keyPair.publicKey, plaintext1);
827   auto ciphertext2 = cc->Encrypt(keyPair.publicKey, plaintext2);
828 
829   auto ciphertextMul = cc->EvalMultNoRelin(ciphertext1, ciphertext2);
830 
831   while (state.KeepRunning()) {
832     auto ciphertext3 = cc->Relinearize(ciphertextMul);
833   }
834 }
835 
836 HEXL_BENCHMARK(CKKS_Relin);
837 
CKKS_Rescale(benchmark::State & state)838 void CKKS_Rescale(benchmark::State &state) {
839   CryptoContext<DCRTPoly> cc =
840       GenerateCKKSContext(state.range(0), state.range(1));
841 
842   LPKeyPair<DCRTPoly> keyPair = cc->KeyGen();
843   cc->EvalMultKeyGen(keyPair.secretKey);
844 
845   usint slots = cc->GetEncodingParams()->GetBatchSize();
846   std::vector<std::complex<double>> vectorOfInts1(slots);
847   for (usint i = 0; i < slots; i++) {
848     vectorOfInts1[i] = 1.001 * i;
849   }
850   std::vector<std::complex<double>> vectorOfInts2(slots);
851   for (usint i = 0; i < slots; i++) {
852     vectorOfInts2[i] = 1.001 * i;
853   }
854 
855   auto plaintext1 = cc->MakeCKKSPackedPlaintext(vectorOfInts1);
856   auto plaintext2 = cc->MakeCKKSPackedPlaintext(vectorOfInts2);
857 
858   auto ciphertext1 = cc->Encrypt(keyPair.publicKey, plaintext1);
859   auto ciphertext2 = cc->Encrypt(keyPair.publicKey, plaintext2);
860 
861   auto ciphertextMul = cc->EvalMult(ciphertext1, ciphertext2);
862 
863   while (state.KeepRunning()) {
864     auto ciphertext3 = cc->ModReduce(ciphertextMul);
865   }
866 }
867 
868 HEXL_BENCHMARK(CKKS_Rescale);
869 
CKKS_RescaleInPlace(benchmark::State & state)870 void CKKS_RescaleInPlace(benchmark::State &state) {
871   CryptoContext<DCRTPoly> cc =
872       GenerateCKKSContext(state.range(0), state.range(1));
873 
874   LPKeyPair<DCRTPoly> keyPair = cc->KeyGen();
875   cc->EvalMultKeyGen(keyPair.secretKey);
876 
877   usint slots = cc->GetEncodingParams()->GetBatchSize();
878   std::vector<std::complex<double>> vectorOfInts(slots);
879   for (usint i = 0; i < slots; i++) {
880     vectorOfInts[i] = 1.001 * i;
881   }
882 
883   auto plaintext = cc->MakeCKKSPackedPlaintext(vectorOfInts);
884   auto ciphertext = cc->Encrypt(keyPair.publicKey, plaintext);
885   auto ciphertextMul = cc->EvalMult(ciphertext, ciphertext);
886   auto ciphertextMulClone = ciphertextMul->Clone();
887 
888   while (state.KeepRunning()) {
889     cc->ModReduceInPlace(ciphertextMul);
890     state.PauseTiming();
891     ciphertextMul = ciphertextMulClone->Clone();
892     state.ResumeTiming();
893   }
894 }
895 
896 HEXL_BENCHMARK(CKKS_RescaleInPlace);
897 
CKKS_EvalAtIndex(benchmark::State & state)898 void CKKS_EvalAtIndex(benchmark::State &state) {
899   CryptoContext<DCRTPoly> cc =
900       GenerateCKKSContext(state.range(0), state.range(1));
901 
902   LPKeyPair<DCRTPoly> keyPair = cc->KeyGen();
903   cc->EvalMultKeyGen(keyPair.secretKey);
904 
905   std::vector<int32_t> indexList(1);
906   for (usint i = 0; i < 1; i++) {
907     indexList[i] = 1;
908   }
909 
910   cc->EvalAtIndexKeyGen(keyPair.secretKey, indexList);
911 
912   usint slots = cc->GetEncodingParams()->GetBatchSize();
913   std::vector<std::complex<double>> vectorOfInts1(slots);
914   for (usint i = 0; i < slots; i++) {
915     vectorOfInts1[i] = 1.001 * i;
916   }
917   std::vector<std::complex<double>> vectorOfInts2(slots);
918   for (usint i = 0; i < slots; i++) {
919     vectorOfInts2[i] = 1.001 * i;
920   }
921 
922   auto plaintext1 = cc->MakeCKKSPackedPlaintext(vectorOfInts1);
923   auto plaintext2 = cc->MakeCKKSPackedPlaintext(vectorOfInts2);
924 
925   auto ciphertext1 = cc->Encrypt(keyPair.publicKey, plaintext1);
926   auto ciphertext2 = cc->Encrypt(keyPair.publicKey, plaintext2);
927 
928   auto ciphertextMul = cc->EvalMult(ciphertext1, ciphertext2);
929 
930   while (state.KeepRunning()) {
931     auto ciphertext3 = cc->EvalAtIndex(ciphertextMul, 1);
932   }
933 }
934 
935 HEXL_BENCHMARK(CKKS_EvalAtIndex);
936 
937 /*
938  * BGVrns benchmarks
939  * */
940 
BGVrns_KeyGen(benchmark::State & state)941 void BGVrns_KeyGen(benchmark::State &state) {
942   CryptoContext<DCRTPoly> cc =
943       GenerateBGVrnsContext(state.range(0), state.range(1));
944 
945   LPKeyPair<DCRTPoly> keyPair;
946 
947   while (state.KeepRunning()) {
948     keyPair = cc->KeyGen();
949   }
950 }
951 
952 HEXL_BENCHMARK(BGVrns_KeyGen);
953 
BGVrns_MultKeyGen(benchmark::State & state)954 void BGVrns_MultKeyGen(benchmark::State &state) {
955   CryptoContext<DCRTPoly> cc =
956       GenerateBGVrnsContext(state.range(0), state.range(1));
957 
958   LPKeyPair<DCRTPoly> keyPair;
959   keyPair = cc->KeyGen();
960 
961   while (state.KeepRunning()) {
962     cc->EvalMultKeyGen(keyPair.secretKey);
963   }
964 }
965 
966 HEXL_BENCHMARK(BGVrns_MultKeyGen);
967 
BGVrns_EvalAtIndexKeyGen(benchmark::State & state)968 void BGVrns_EvalAtIndexKeyGen(benchmark::State &state) {
969   CryptoContext<DCRTPoly> cc =
970       GenerateBGVrnsContext(state.range(0), state.range(1));
971 
972   LPKeyPair<DCRTPoly> keyPair;
973   keyPair = cc->KeyGen();
974 
975   std::vector<int32_t> indexList(1);
976   for (usint i = 0; i < 1; i++) {
977     indexList[i] = 1;
978   }
979 
980   while (state.KeepRunning()) {
981     cc->EvalAtIndexKeyGen(keyPair.secretKey, indexList);
982   }
983 }
984 
985 HEXL_BENCHMARK(BGVrns_EvalAtIndexKeyGen);
986 
BGVrns_Encryption(benchmark::State & state)987 void BGVrns_Encryption(benchmark::State &state) {
988   CryptoContext<DCRTPoly> cc =
989       GenerateBGVrnsContext(state.range(0), state.range(1));
990 
991   LPKeyPair<DCRTPoly> keyPair = cc->KeyGen();
992 
993   std::vector<int64_t> vectorOfInts = {1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0};
994   Plaintext plaintext = cc->MakePackedPlaintext(vectorOfInts);
995 
996   while (state.KeepRunning()) {
997     auto ciphertext = cc->Encrypt(keyPair.publicKey, plaintext);
998   }
999 }
1000 
1001 HEXL_BENCHMARK(BGVrns_Encryption);
1002 
BGVrns_Decryption(benchmark::State & state)1003 void BGVrns_Decryption(benchmark::State &state) {
1004   CryptoContext<DCRTPoly> cc =
1005       GenerateBGVrnsContext(state.range(0), state.range(1));
1006 
1007   LPKeyPair<DCRTPoly> keyPair = cc->KeyGen();
1008 
1009   std::vector<int64_t> vectorOfInts = {1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0};
1010   Plaintext plaintext = cc->MakePackedPlaintext(vectorOfInts);
1011 
1012   auto ciphertext = cc->Encrypt(keyPair.publicKey, plaintext);
1013   ciphertext = cc->ModReduce(ciphertext);  // TODO LevelReduce
1014 
1015   Plaintext plaintextDec;
1016 
1017   while (state.KeepRunning()) {
1018     cc->Decrypt(keyPair.secretKey, ciphertext, &plaintextDec);
1019   }
1020 }
1021 
1022 HEXL_BENCHMARK(BGVrns_Decryption);
1023 
BGVrns_Add(benchmark::State & state)1024 void BGVrns_Add(benchmark::State &state) {
1025   CryptoContext<DCRTPoly> cc =
1026       GenerateBGVrnsContext(state.range(0), state.range(1));
1027 
1028   LPKeyPair<DCRTPoly> keyPair = cc->KeyGen();
1029 
1030   std::vector<int64_t> vectorOfInts1 = {1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0};
1031   std::vector<int64_t> vectorOfInts2 = {0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1};
1032 
1033   auto plaintext1 = cc->MakePackedPlaintext(vectorOfInts1);
1034   auto plaintext2 = cc->MakePackedPlaintext(vectorOfInts2);
1035 
1036   auto ciphertext1 = cc->Encrypt(keyPair.publicKey, plaintext1);
1037   auto ciphertext2 = cc->Encrypt(keyPair.publicKey, plaintext2);
1038 
1039   while (state.KeepRunning()) {
1040     auto ciphertextAdd = cc->EvalAdd(ciphertext1, ciphertext2);
1041   }
1042 }
1043 
1044 HEXL_BENCHMARK(BGVrns_Add);
1045 
BGVrns_AddInPlace(benchmark::State & state)1046 void BGVrns_AddInPlace(benchmark::State &state) {
1047   CryptoContext<DCRTPoly> cc =
1048       GenerateBGVrnsContext(state.range(0), state.range(1));
1049 
1050   LPKeyPair<DCRTPoly> keyPair = cc->KeyGen();
1051 
1052   std::vector<int64_t> vectorOfInts1 = {1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0};
1053   std::vector<int64_t> vectorOfInts2 = {0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1};
1054 
1055   auto plaintext1 = cc->MakePackedPlaintext(vectorOfInts1);
1056   auto plaintext2 = cc->MakePackedPlaintext(vectorOfInts2);
1057 
1058   auto ciphertext1 = cc->Encrypt(keyPair.publicKey, plaintext1);
1059   auto ciphertext2 = cc->Encrypt(keyPair.publicKey, plaintext2);
1060 
1061   while (state.KeepRunning()) {
1062     cc->EvalAddInPlace(ciphertext1, ciphertext2);
1063   }
1064 }
1065 
1066 HEXL_BENCHMARK(BGVrns_AddInPlace);
1067 
BGVrns_AddPlain(benchmark::State & state)1068 void BGVrns_AddPlain(benchmark::State &state) {
1069   CryptoContext<DCRTPoly> cc =
1070       GenerateBGVrnsContext(state.range(0), state.range(1));
1071 
1072   LPKeyPair<DCRTPoly> keyPair = cc->KeyGen();
1073 
1074   std::vector<int64_t> vectorOfInts1 = {1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0};
1075   std::vector<int64_t> vectorOfInts2 = {0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1};
1076 
1077   auto plaintext1 = cc->MakeCoefPackedPlaintext(vectorOfInts1);
1078   auto plaintext2 = cc->MakeCoefPackedPlaintext(vectorOfInts2);
1079 
1080   auto ciphertext1 = cc->Encrypt(keyPair.publicKey, plaintext1);
1081 
1082   while (state.KeepRunning()) {
1083     auto ciphertextAdd = cc->EvalAdd(ciphertext1, plaintext2);
1084   }
1085 }
1086 
1087 HEXL_BENCHMARK(BGVrns_AddPlain);
1088 
BGVrns_Negate(benchmark::State & state)1089 void BGVrns_Negate(benchmark::State &state) {
1090   CryptoContext<DCRTPoly> cc =
1091       GenerateBGVrnsContext(state.range(0), state.range(1));
1092 
1093   LPKeyPair<DCRTPoly> keyPair = cc->KeyGen();
1094 
1095   std::vector<int64_t> vectorOfInts1 = {1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0};
1096 
1097   auto plaintext1 = cc->MakeCoefPackedPlaintext(vectorOfInts1);
1098 
1099   auto ciphertext1 = cc->Encrypt(keyPair.publicKey, plaintext1);
1100 
1101   while (state.KeepRunning()) {
1102     auto ciphertextNeg = cc->EvalNegate(ciphertext1);
1103   }
1104 }
1105 
1106 HEXL_BENCHMARK(BGVrns_Negate);
1107 
BGVrns_Sub(benchmark::State & state)1108 void BGVrns_Sub(benchmark::State &state) {
1109   CryptoContext<DCRTPoly> cc =
1110       GenerateBGVrnsContext(state.range(0), state.range(1));
1111 
1112   LPKeyPair<DCRTPoly> keyPair = cc->KeyGen();
1113 
1114   std::vector<int64_t> vectorOfInts1 = {1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0};
1115   std::vector<int64_t> vectorOfInts2 = {0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1};
1116 
1117   auto plaintext1 = cc->MakeCoefPackedPlaintext(vectorOfInts1);
1118   auto plaintext2 = cc->MakeCoefPackedPlaintext(vectorOfInts2);
1119 
1120   auto ciphertext1 = cc->Encrypt(keyPair.publicKey, plaintext1);
1121   auto ciphertext2 = cc->Encrypt(keyPair.publicKey, plaintext2);
1122 
1123   while (state.KeepRunning()) {
1124     auto ciphertextSub = cc->EvalSub(ciphertext1, ciphertext2);
1125   }
1126 }
1127 
1128 HEXL_BENCHMARK(BGVrns_Sub);
1129 
BGVrns_SubPlain(benchmark::State & state)1130 void BGVrns_SubPlain(benchmark::State &state) {
1131   CryptoContext<DCRTPoly> cc =
1132       GenerateBGVrnsContext(state.range(0), state.range(1));
1133 
1134   LPKeyPair<DCRTPoly> keyPair = cc->KeyGen();
1135 
1136   std::vector<int64_t> vectorOfInts1 = {1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0};
1137   std::vector<int64_t> vectorOfInts2 = {0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1};
1138 
1139   auto plaintext1 = cc->MakeCoefPackedPlaintext(vectorOfInts1);
1140   auto plaintext2 = cc->MakeCoefPackedPlaintext(vectorOfInts2);
1141 
1142   auto ciphertext1 = cc->Encrypt(keyPair.publicKey, plaintext1);
1143 
1144   while (state.KeepRunning()) {
1145     auto ciphertextSub = cc->EvalSub(ciphertext1, plaintext2);
1146   }
1147 }
1148 
1149 HEXL_BENCHMARK(BGVrns_SubPlain);
1150 
BGVrns_MultNoRelin(benchmark::State & state)1151 void BGVrns_MultNoRelin(benchmark::State &state) {
1152   CryptoContext<DCRTPoly> cc =
1153       GenerateBGVrnsContext(state.range(0), state.range(1));
1154 
1155   LPKeyPair<DCRTPoly> keyPair = cc->KeyGen();
1156 
1157   std::vector<int64_t> vectorOfInts1 = {1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0};
1158   std::vector<int64_t> vectorOfInts2 = {0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1};
1159 
1160   auto plaintext1 = cc->MakePackedPlaintext(vectorOfInts1);
1161   auto plaintext2 = cc->MakePackedPlaintext(vectorOfInts2);
1162 
1163   auto ciphertext1 = cc->Encrypt(keyPair.publicKey, plaintext1);
1164   auto ciphertext2 = cc->Encrypt(keyPair.publicKey, plaintext2);
1165 
1166   while (state.KeepRunning()) {
1167     auto ciphertextMul = cc->EvalMultNoRelin(ciphertext1, ciphertext2);
1168   }
1169 }
1170 
1171 HEXL_BENCHMARK(BGVrns_MultNoRelin);
1172 
BGVrns_MultRelin(benchmark::State & state)1173 void BGVrns_MultRelin(benchmark::State &state) {
1174   CryptoContext<DCRTPoly> cc =
1175       GenerateBGVrnsContext(state.range(0), state.range(1));
1176 
1177   LPKeyPair<DCRTPoly> keyPair = cc->KeyGen();
1178   cc->EvalMultKeyGen(keyPair.secretKey);
1179 
1180   std::vector<int64_t> vectorOfInts1 = {1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0};
1181   std::vector<int64_t> vectorOfInts2 = {0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1};
1182 
1183   auto plaintext1 = cc->MakePackedPlaintext(vectorOfInts1);
1184   auto plaintext2 = cc->MakePackedPlaintext(vectorOfInts2);
1185 
1186   auto ciphertext1 = cc->Encrypt(keyPair.publicKey, plaintext1);
1187   auto ciphertext2 = cc->Encrypt(keyPair.publicKey, plaintext2);
1188 
1189   while (state.KeepRunning()) {
1190     auto ciphertextMul = cc->EvalMult(ciphertext1, ciphertext2);
1191   }
1192 }
1193 
1194 HEXL_BENCHMARK(BGVrns_MultRelin);
1195 
BGVrns_MultPlain(benchmark::State & state)1196 void BGVrns_MultPlain(benchmark::State &state) {
1197   CryptoContext<DCRTPoly> cc =
1198       GenerateBGVrnsContext(state.range(0), state.range(1));
1199 
1200   LPKeyPair<DCRTPoly> keyPair = cc->KeyGen();
1201 
1202   std::vector<int64_t> vectorOfInts1 = {1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0};
1203   std::vector<int64_t> vectorOfInts2 = {0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1};
1204 
1205   auto plaintext1 = cc->MakeCoefPackedPlaintext(vectorOfInts1);
1206   auto plaintext2 = cc->MakeCoefPackedPlaintext(vectorOfInts2);
1207 
1208   auto ciphertext1 = cc->Encrypt(keyPair.publicKey, plaintext1);
1209 
1210   while (state.KeepRunning()) {
1211     auto ciphertextMul = cc->EvalMult(ciphertext1, plaintext2);
1212   }
1213 }
1214 
1215 HEXL_BENCHMARK(BGVrns_MultPlain);
1216 
BGVrns_Relin(benchmark::State & state)1217 void BGVrns_Relin(benchmark::State &state) {
1218   CryptoContext<DCRTPoly> cc =
1219       GenerateBGVrnsContext(state.range(0), state.range(1));
1220 
1221   LPKeyPair<DCRTPoly> keyPair = cc->KeyGen();
1222   cc->EvalMultKeyGen(keyPair.secretKey);
1223 
1224   std::vector<int64_t> vectorOfInts1 = {1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0};
1225   std::vector<int64_t> vectorOfInts2 = {0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1};
1226 
1227   auto plaintext1 = cc->MakePackedPlaintext(vectorOfInts1);
1228   auto plaintext2 = cc->MakePackedPlaintext(vectorOfInts2);
1229 
1230   auto ciphertext1 = cc->Encrypt(keyPair.publicKey, plaintext1);
1231   auto ciphertext2 = cc->Encrypt(keyPair.publicKey, plaintext2);
1232 
1233   auto ciphertextMul = cc->EvalMultNoRelin(ciphertext1, ciphertext2);
1234 
1235   while (state.KeepRunning()) {
1236     auto ciphertext3 = cc->Relinearize(ciphertextMul);
1237   }
1238 }
1239 
1240 HEXL_BENCHMARK(BGVrns_Relin);
1241 
BGVrns_ModSwitch(benchmark::State & state)1242 void BGVrns_ModSwitch(benchmark::State &state) {
1243   CryptoContext<DCRTPoly> cc =
1244       GenerateBGVrnsContext(state.range(0), state.range(1));
1245 
1246   LPKeyPair<DCRTPoly> keyPair = cc->KeyGen();
1247   cc->EvalMultKeyGen(keyPair.secretKey);
1248 
1249   std::vector<int64_t> vectorOfInts1 = {1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0};
1250   std::vector<int64_t> vectorOfInts2 = {0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1};
1251 
1252   auto plaintext1 = cc->MakePackedPlaintext(vectorOfInts1);
1253   auto plaintext2 = cc->MakePackedPlaintext(vectorOfInts2);
1254 
1255   auto ciphertext1 = cc->Encrypt(keyPair.publicKey, plaintext1);
1256   auto ciphertext2 = cc->Encrypt(keyPair.publicKey, plaintext2);
1257 
1258   auto ciphertextMul = cc->EvalMult(ciphertext1, ciphertext2);
1259 
1260   while (state.KeepRunning()) {
1261     auto ciphertext3 = cc->ModReduce(ciphertextMul);
1262   }
1263 }
1264 
1265 HEXL_BENCHMARK(BGVrns_ModSwitch);
1266 
BGVrns_ModSwitchInPlace(benchmark::State & state)1267 void BGVrns_ModSwitchInPlace(benchmark::State &state) {
1268   CryptoContext<DCRTPoly> cc =
1269       GenerateBGVrnsContext(state.range(0), state.range(1));
1270 
1271   LPKeyPair<DCRTPoly> keyPair = cc->KeyGen();
1272   cc->EvalMultKeyGen(keyPair.secretKey);
1273 
1274   std::vector<int64_t> vectorOfInts = {1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0};
1275 
1276   auto plaintext = cc->MakePackedPlaintext(vectorOfInts);
1277   auto ciphertext = cc->Encrypt(keyPair.publicKey, plaintext);
1278   auto ciphertextMul = cc->EvalMult(ciphertext, ciphertext);
1279   auto ciphertextMulClone = ciphertextMul->Clone();
1280 
1281   while (state.KeepRunning()) {
1282     cc->ModReduceInPlace(ciphertextMul);
1283     state.PauseTiming();
1284     ciphertextMul = ciphertextMulClone->Clone();
1285     state.ResumeTiming();
1286   }
1287 }
1288 
1289 HEXL_BENCHMARK(BGVrns_ModSwitchInPlace);
1290 
BGVrns_EvalAtIndex(benchmark::State & state)1291 void BGVrns_EvalAtIndex(benchmark::State &state) {
1292   CryptoContext<DCRTPoly> cc =
1293       GenerateBGVrnsContext(state.range(0), state.range(1));
1294 
1295   LPKeyPair<DCRTPoly> keyPair = cc->KeyGen();
1296   cc->EvalMultKeyGen(keyPair.secretKey);
1297 
1298   std::vector<int32_t> indexList(1);
1299   for (usint i = 0; i < 1; i++) {
1300     indexList[i] = 1;
1301   }
1302 
1303   cc->EvalAtIndexKeyGen(keyPair.secretKey, indexList);
1304 
1305   std::vector<int64_t> vectorOfInts1 = {1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0};
1306   std::vector<int64_t> vectorOfInts2 = {0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1};
1307 
1308   auto plaintext1 = cc->MakeCoefPackedPlaintext(vectorOfInts1);
1309   auto plaintext2 = cc->MakeCoefPackedPlaintext(vectorOfInts2);
1310 
1311   auto ciphertext1 = cc->Encrypt(keyPair.publicKey, plaintext1);
1312   auto ciphertext2 = cc->Encrypt(keyPair.publicKey, plaintext2);
1313 
1314   auto ciphertextMul = cc->EvalMult(ciphertext1, ciphertext2);
1315 
1316   while (state.KeepRunning()) {
1317     auto ciphertext3 = cc->EvalAtIndex(ciphertextMul, 1);
1318   }
1319 }
1320 
1321 HEXL_BENCHMARK(BGVrns_EvalAtIndex);
1322 
1323 BENCHMARK_MAIN();
1324