1 // @file UnitTestFHEW.cpp This code runs unit tests for the FHEW methods of the
2 // PALISADE lattice encryption library.
3 // @author TPOC: contact@palisade-crypto.org
4 //
5 // @copyright Copyright (c) 2019, Duality Technologies Inc.
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 #include "binfhecontext.h"
26 #include "gtest/gtest.h"
27 
28 using namespace lbcrypto;
29 
30 // ---------------  TESTING METHODS OF FHEW ---------------
31 
32 // Checks the key switching operation
TEST(UnitTestFHEWAP,KeySwitch)33 TEST(UnitTestFHEWAP, KeySwitch) {
34   auto cc = BinFHEContext();
35 
36   cc.GenerateBinFHEContext(TOY, AP);
37 
38   NativeInteger Q = cc.GetParams()->GetLWEParams()->GetQ();
39 
40   auto sk = cc.KeyGen();
41   auto skN = cc.KeyGenN();
42 
43   auto ctQN1 = cc.Encrypt(skN, 1, FRESH);
44   auto ctQN0 = cc.Encrypt(skN, 0, FRESH);
45 
46   NativeVector newSK = sk->GetElement();
47   newSK.SwitchModulus(Q);
48   auto skQ = std::make_shared<LWEPrivateKeyImpl>(newSK);
49 
50   auto keySwitchHint = cc.KeySwitchGen(sk, skN);
51 
52   std::shared_ptr<LWECiphertextImpl> eQ1 = cc.GetLWEScheme()->KeySwitch(
53       cc.GetParams()->GetLWEParams(), keySwitchHint, ctQN1);
54   std::shared_ptr<LWECiphertextImpl> eQ0 = cc.GetLWEScheme()->KeySwitch(
55       cc.GetParams()->GetLWEParams(), keySwitchHint, ctQN0);
56 
57   LWEPlaintext resultAfterKeySwitch1;
58   cc.Decrypt(skQ, eQ1, &resultAfterKeySwitch1);
59 
60   LWEPlaintext resultAfterKeySwitch0;
61   cc.Decrypt(skQ, eQ0, &resultAfterKeySwitch0);
62 
63   EXPECT_EQ(1, resultAfterKeySwitch1) << "Failed key switching test";
64 
65   EXPECT_EQ(0, resultAfterKeySwitch0) << "Failed key switching test";
66 }
67 
68 // Checks the key switching operation
TEST(UnitTestFHEWGINX,KeySwitch)69 TEST(UnitTestFHEWGINX, KeySwitch) {
70   auto cc = BinFHEContext();
71 
72   cc.GenerateBinFHEContext(TOY, GINX);
73 
74   NativeInteger Q = cc.GetParams()->GetLWEParams()->GetQ();
75 
76   auto sk = cc.KeyGen();
77   auto skN = cc.KeyGenN();
78 
79   auto ctQN1 = cc.Encrypt(skN, 1, FRESH);
80   auto ctQN0 = cc.Encrypt(skN, 0, FRESH);
81 
82   NativeVector newSK = sk->GetElement();
83   newSK.SwitchModulus(Q);
84   auto skQ = std::make_shared<LWEPrivateKeyImpl>(newSK);
85 
86   auto keySwitchHint = cc.KeySwitchGen(sk, skN);
87 
88   std::shared_ptr<LWECiphertextImpl> eQ1 = cc.GetLWEScheme()->KeySwitch(
89       cc.GetParams()->GetLWEParams(), keySwitchHint, ctQN1);
90   std::shared_ptr<LWECiphertextImpl> eQ0 = cc.GetLWEScheme()->KeySwitch(
91       cc.GetParams()->GetLWEParams(), keySwitchHint, ctQN0);
92 
93   LWEPlaintext resultAfterKeySwitch1;
94   cc.Decrypt(skQ, eQ1, &resultAfterKeySwitch1);
95 
96   LWEPlaintext resultAfterKeySwitch0;
97   cc.Decrypt(skQ, eQ0, &resultAfterKeySwitch0);
98 
99   EXPECT_EQ(1, resultAfterKeySwitch1) << "Failed key switching test";
100 
101   EXPECT_EQ(0, resultAfterKeySwitch0) << "Failed key switching test";
102 }
103 
104 // Checks the mod switching operation
TEST(UnitTestFHEWAP,ModSwitch)105 TEST(UnitTestFHEWAP, ModSwitch) {
106   auto cc = BinFHEContext();
107 
108   cc.GenerateBinFHEContext(TOY, AP);
109 
110   NativeInteger Q = cc.GetParams()->GetLWEParams()->GetQ();
111 
112   auto sk = cc.KeyGen();
113 
114   // switch secret key to Q
115   NativeVector newSK = sk->GetElement();
116   newSK.SwitchModulus(Q);
117   auto skQ = std::make_shared<LWEPrivateKeyImpl>(newSK);
118 
119   auto ctQ1 = cc.Encrypt(skQ, 1, FRESH);
120   auto ctQ0 = cc.Encrypt(skQ, 0, FRESH);
121 
122   // switches the modulus from Q to q
123   auto ct1 = cc.GetLWEScheme()->ModSwitch(cc.GetParams()->GetLWEParams(), ctQ1);
124   auto ct0 = cc.GetLWEScheme()->ModSwitch(cc.GetParams()->GetLWEParams(), ctQ0);
125 
126   LWEPlaintext resultAfterModSwitch1;
127   cc.Decrypt(sk, ct1, &resultAfterModSwitch1);
128 
129   LWEPlaintext resultAfterModSwitch0;
130   cc.Decrypt(sk, ct0, &resultAfterModSwitch0);
131 
132   EXPECT_EQ(1, resultAfterModSwitch1) << "Failed mod switching test";
133 
134   EXPECT_EQ(0, resultAfterModSwitch0) << "Failed mod switching test";
135 }
136 
137 // Checks the mod switching operation
TEST(UnitTestFHEWGINX,ModSwitch)138 TEST(UnitTestFHEWGINX, ModSwitch) {
139   auto cc = BinFHEContext();
140 
141   cc.GenerateBinFHEContext(TOY, GINX);
142 
143   NativeInteger Q = cc.GetParams()->GetLWEParams()->GetQ();
144 
145   auto sk = cc.KeyGen();
146 
147   // switch secret key to Q
148   NativeVector newSK = sk->GetElement();
149   newSK.SwitchModulus(Q);
150   auto skQ = std::make_shared<LWEPrivateKeyImpl>(newSK);
151 
152   auto ctQ1 = cc.Encrypt(skQ, 1, FRESH);
153   auto ctQ0 = cc.Encrypt(skQ, 0, FRESH);
154 
155   // switches the modulus from Q to q
156   auto ct1 = cc.GetLWEScheme()->ModSwitch(cc.GetParams()->GetLWEParams(), ctQ1);
157   auto ct0 = cc.GetLWEScheme()->ModSwitch(cc.GetParams()->GetLWEParams(), ctQ0);
158 
159   LWEPlaintext resultAfterModSwitch1;
160   cc.Decrypt(sk, ct1, &resultAfterModSwitch1);
161 
162   LWEPlaintext resultAfterModSwitch0;
163   cc.Decrypt(sk, ct0, &resultAfterModSwitch0);
164 
165   EXPECT_EQ(1, resultAfterModSwitch1) << "Failed mod switching test";
166 
167   EXPECT_EQ(0, resultAfterModSwitch0) << "Failed mod switching test";
168 }
169 
170 // Checks the truth table for NOT
TEST(UnitTestFHEWAP,NOT)171 TEST(UnitTestFHEWAP, NOT) {
172   auto cc = BinFHEContext();
173   cc.GenerateBinFHEContext(TOY, AP);
174 
175   auto sk = cc.KeyGen();
176 
177   auto ct1 = cc.Encrypt(sk, 1, FRESH);
178   auto ct0 = cc.Encrypt(sk, 0, FRESH);
179 
180   auto ct1Not = cc.EvalNOT(ct1);
181   auto ct0Not = cc.EvalNOT(ct0);
182 
183   LWEPlaintext result1;
184   cc.Decrypt(sk, ct1Not, &result1);
185 
186   LWEPlaintext result0;
187   cc.Decrypt(sk, ct0Not, &result0);
188 
189   EXPECT_EQ(0, result1) << "NOT failed";
190 
191   EXPECT_EQ(1, result0) << "NOT failed";
192 }
193 
194 // Checks the truth table for NOT
TEST(UnitTestFHEWGINX,NOT)195 TEST(UnitTestFHEWGINX, NOT) {
196   auto cc = BinFHEContext();
197   cc.GenerateBinFHEContext(TOY, GINX);
198 
199   auto sk = cc.KeyGen();
200 
201   auto ct1 = cc.Encrypt(sk, 1, FRESH);
202   auto ct0 = cc.Encrypt(sk, 0, FRESH);
203 
204   auto ct1Not = cc.EvalNOT(ct1);
205   auto ct0Not = cc.EvalNOT(ct0);
206 
207   LWEPlaintext result1;
208   cc.Decrypt(sk, ct1Not, &result1);
209 
210   LWEPlaintext result0;
211   cc.Decrypt(sk, ct0Not, &result0);
212 
213   EXPECT_EQ(0, result1) << "NOT failed";
214 
215   EXPECT_EQ(1, result0) << "NOT failed";
216 }
217 
218 // Checks the truth table for AND
TEST(UnitTestFHEWAP,Bootstrap)219 TEST(UnitTestFHEWAP, Bootstrap) {
220   auto cc = BinFHEContext();
221   cc.GenerateBinFHEContext(TOY, AP);
222 
223   auto sk = cc.KeyGen();
224 
225   cc.BTKeyGen(sk);
226 
227   auto ct1 = cc.Encrypt(sk, 1);
228   auto ct0 = cc.Encrypt(sk, 0);
229 
230   auto ct11 = cc.Bootstrap(ct1);
231   auto ct01 = cc.Bootstrap(ct0);
232 
233   LWEPlaintext result11;
234   cc.Decrypt(sk, ct11, &result11);
235   LWEPlaintext result01;
236   cc.Decrypt(sk, ct01, &result01);
237 
238   std::string failed = "Bootstrapping failed";
239 
240   EXPECT_EQ(1, result11) << failed;
241   EXPECT_EQ(0, result01) << failed;
242 }
243 
244 // Checks the truth table for AND
TEST(UnitTestFHEWGINX,Bootstrap)245 TEST(UnitTestFHEWGINX, Bootstrap) {
246   auto cc = BinFHEContext();
247   cc.GenerateBinFHEContext(TOY, GINX);
248 
249   auto sk = cc.KeyGen();
250 
251   cc.BTKeyGen(sk);
252 
253   auto ct1 = cc.Encrypt(sk, 1);
254   auto ct0 = cc.Encrypt(sk, 0);
255 
256   auto ct11 = cc.Bootstrap(ct1);
257   auto ct01 = cc.Bootstrap(ct0);
258 
259   LWEPlaintext result11;
260   cc.Decrypt(sk, ct11, &result11);
261   LWEPlaintext result01;
262   cc.Decrypt(sk, ct01, &result01);
263 
264   std::string failed = "Bootstrapping failed";
265 
266   EXPECT_EQ(1, result11) << failed;
267   EXPECT_EQ(0, result01) << failed;
268 }
269 
270 // Checks the truth table for AND
TEST(UnitTestFHEWAP,AND)271 TEST(UnitTestFHEWAP, AND) {
272   auto cc = BinFHEContext();
273   cc.GenerateBinFHEContext(TOY, AP);
274 
275   auto sk = cc.KeyGen();
276 
277   cc.BTKeyGen(sk);
278 
279   auto ct1 = cc.Encrypt(sk, 1);
280   auto ct0 = cc.Encrypt(sk, 0);
281   auto ct1Alt = cc.Encrypt(sk, 1);
282   auto ct0Alt = cc.Encrypt(sk, 0);
283 
284   auto ct11 = cc.EvalBinGate(AND, ct1, ct1Alt);
285   auto ct01 = cc.EvalBinGate(AND, ct0, ct1);
286   auto ct10 = cc.EvalBinGate(AND, ct1, ct0);
287   auto ct00 = cc.EvalBinGate(AND, ct0, ct0Alt);
288 
289   LWEPlaintext result11;
290   cc.Decrypt(sk, ct11, &result11);
291   LWEPlaintext result01;
292   cc.Decrypt(sk, ct01, &result01);
293   LWEPlaintext result10;
294   cc.Decrypt(sk, ct10, &result10);
295   LWEPlaintext result00;
296   cc.Decrypt(sk, ct00, &result00);
297 
298   std::string failed = "AND failed";
299 
300   EXPECT_EQ(1, result11) << failed;
301   EXPECT_EQ(0, result01) << failed;
302   EXPECT_EQ(0, result10) << failed;
303   EXPECT_EQ(0, result00) << failed;
304 }
305 
306 // Checks the truth table for AND
TEST(UnitTestFHEWGINX,AND)307 TEST(UnitTestFHEWGINX, AND) {
308   auto cc = BinFHEContext();
309   cc.GenerateBinFHEContext(TOY, GINX);
310 
311   auto sk = cc.KeyGen();
312 
313   cc.BTKeyGen(sk);
314 
315   auto ct1 = cc.Encrypt(sk, 1);
316   auto ct0 = cc.Encrypt(sk, 0);
317   auto ct1Alt = cc.Encrypt(sk, 1);
318   auto ct0Alt = cc.Encrypt(sk, 0);
319 
320   auto ct11 = cc.EvalBinGate(AND, ct1, ct1Alt);
321   auto ct01 = cc.EvalBinGate(AND, ct0, ct1);
322   auto ct10 = cc.EvalBinGate(AND, ct1, ct0);
323   auto ct00 = cc.EvalBinGate(AND, ct0, ct0Alt);
324 
325   LWEPlaintext result11;
326   cc.Decrypt(sk, ct11, &result11);
327   LWEPlaintext result01;
328   cc.Decrypt(sk, ct01, &result01);
329   LWEPlaintext result10;
330   cc.Decrypt(sk, ct10, &result10);
331   LWEPlaintext result00;
332   cc.Decrypt(sk, ct00, &result00);
333 
334   std::string failed = "AND failed";
335 
336   EXPECT_EQ(1, result11) << failed;
337   EXPECT_EQ(0, result01) << failed;
338   EXPECT_EQ(0, result10) << failed;
339   EXPECT_EQ(0, result00) << failed;
340 }
341 
342 // Checks GINX for the parameter set
343 // that exercises the signed modular reduction
344 // implementation in SignedDigitDecompose
TEST(UnitTestFHEWGINX,SIGNED_MOD)345 TEST(UnitTestFHEWGINX, SIGNED_MOD) {
346   auto cc = BinFHEContext();
347   cc.GenerateBinFHEContext(SIGNED_MOD_TEST, GINX);
348 
349   auto sk = cc.KeyGen();
350 
351   cc.BTKeyGen(sk);
352 
353   auto ct1 = cc.Encrypt(sk, 1);
354   auto ct0 = cc.Encrypt(sk, 0);
355   auto ct1Alt = cc.Encrypt(sk, 1);
356   auto ct0Alt = cc.Encrypt(sk, 0);
357 
358   auto ct11 = cc.EvalBinGate(AND, ct1, ct1Alt);
359   auto ct01 = cc.EvalBinGate(AND, ct0, ct1);
360   auto ct10 = cc.EvalBinGate(AND, ct1, ct0);
361   auto ct00 = cc.EvalBinGate(AND, ct0, ct0Alt);
362 
363   LWEPlaintext result11;
364   cc.Decrypt(sk, ct11, &result11);
365   LWEPlaintext result01;
366   cc.Decrypt(sk, ct01, &result01);
367   LWEPlaintext result10;
368   cc.Decrypt(sk, ct10, &result10);
369   LWEPlaintext result00;
370   cc.Decrypt(sk, ct00, &result00);
371 
372   std::string failed = "AND failed for SIGNED_MOD_TEST";
373 
374   EXPECT_EQ(1, result11) << failed;
375   EXPECT_EQ(0, result01) << failed;
376   EXPECT_EQ(0, result10) << failed;
377   EXPECT_EQ(0, result00) << failed;
378 }
379 
380 // Checks the truth table for OR
TEST(UnitTestFHEWAP,OR)381 TEST(UnitTestFHEWAP, OR) {
382   auto cc = BinFHEContext();
383   cc.GenerateBinFHEContext(TOY, AP);
384 
385   auto sk = cc.KeyGen();
386 
387   cc.BTKeyGen(sk);
388 
389   auto ct1 = cc.Encrypt(sk, 1);
390   auto ct0 = cc.Encrypt(sk, 0);
391   auto ct1Alt = cc.Encrypt(sk, 1);
392   auto ct0Alt = cc.Encrypt(sk, 0);
393 
394   auto ct11 = cc.EvalBinGate(OR, ct1, ct1Alt);
395   auto ct01 = cc.EvalBinGate(OR, ct0, ct1);
396   auto ct10 = cc.EvalBinGate(OR, ct1, ct0);
397   auto ct00 = cc.EvalBinGate(OR, ct0, ct0Alt);
398 
399   LWEPlaintext result11;
400   cc.Decrypt(sk, ct11, &result11);
401   LWEPlaintext result01;
402   cc.Decrypt(sk, ct01, &result01);
403   LWEPlaintext result10;
404   cc.Decrypt(sk, ct10, &result10);
405   LWEPlaintext result00;
406   cc.Decrypt(sk, ct00, &result00);
407 
408   std::string failed = "OR failed";
409 
410   EXPECT_EQ(1, result11) << failed;
411   EXPECT_EQ(1, result01) << failed;
412   EXPECT_EQ(1, result10) << failed;
413   EXPECT_EQ(0, result00) << failed;
414 }
415 
416 // Checks the truth table for OR
TEST(UnitTestFHEWGINX,OR)417 TEST(UnitTestFHEWGINX, OR) {
418   auto cc = BinFHEContext();
419   cc.GenerateBinFHEContext(TOY, GINX);
420 
421   auto sk = cc.KeyGen();
422 
423   cc.BTKeyGen(sk);
424 
425   auto ct1 = cc.Encrypt(sk, 1);
426   auto ct0 = cc.Encrypt(sk, 0);
427   auto ct1Alt = cc.Encrypt(sk, 1);
428   auto ct0Alt = cc.Encrypt(sk, 0);
429 
430   auto ct11 = cc.EvalBinGate(OR, ct1, ct1Alt);
431   auto ct01 = cc.EvalBinGate(OR, ct0, ct1);
432   auto ct10 = cc.EvalBinGate(OR, ct1, ct0);
433   auto ct00 = cc.EvalBinGate(OR, ct0, ct0Alt);
434 
435   LWEPlaintext result11;
436   cc.Decrypt(sk, ct11, &result11);
437   LWEPlaintext result01;
438   cc.Decrypt(sk, ct01, &result01);
439   LWEPlaintext result10;
440   cc.Decrypt(sk, ct10, &result10);
441   LWEPlaintext result00;
442   cc.Decrypt(sk, ct00, &result00);
443 
444   std::string failed = "OR failed";
445 
446   EXPECT_EQ(1, result11) << failed;
447   EXPECT_EQ(1, result01) << failed;
448   EXPECT_EQ(1, result10) << failed;
449   EXPECT_EQ(0, result00) << failed;
450 }
451 
452 // Checks the truth table for AND
TEST(UnitTestFHEWAP,NAND)453 TEST(UnitTestFHEWAP, NAND) {
454   auto cc = BinFHEContext();
455   cc.GenerateBinFHEContext(TOY, AP);
456 
457   auto sk = cc.KeyGen();
458 
459   cc.BTKeyGen(sk);
460 
461   auto ct1 = cc.Encrypt(sk, 1);
462   auto ct0 = cc.Encrypt(sk, 0);
463   auto ct1Alt = cc.Encrypt(sk, 1);
464   auto ct0Alt = cc.Encrypt(sk, 0);
465 
466   auto ct11 = cc.EvalBinGate(NAND, ct1, ct1Alt);
467   auto ct01 = cc.EvalBinGate(NAND, ct0, ct1);
468   auto ct10 = cc.EvalBinGate(NAND, ct1, ct0);
469   auto ct00 = cc.EvalBinGate(NAND, ct0, ct0Alt);
470 
471   LWEPlaintext result11;
472   cc.Decrypt(sk, ct11, &result11);
473   LWEPlaintext result01;
474   cc.Decrypt(sk, ct01, &result01);
475   LWEPlaintext result10;
476   cc.Decrypt(sk, ct10, &result10);
477   LWEPlaintext result00;
478   cc.Decrypt(sk, ct00, &result00);
479 
480   std::string failed = "NAND failed";
481 
482   EXPECT_EQ(0, result11) << failed;
483   EXPECT_EQ(1, result01) << failed;
484   EXPECT_EQ(1, result10) << failed;
485   EXPECT_EQ(1, result00) << failed;
486 }
487 
488 // Checks the truth table for AND
TEST(UnitTestFHEWGINX,NAND)489 TEST(UnitTestFHEWGINX, NAND) {
490   auto cc = BinFHEContext();
491   cc.GenerateBinFHEContext(TOY, GINX);
492 
493   auto sk = cc.KeyGen();
494 
495   cc.BTKeyGen(sk);
496 
497   auto ct1 = cc.Encrypt(sk, 1);
498   auto ct0 = cc.Encrypt(sk, 0);
499   auto ct1Alt = cc.Encrypt(sk, 1);
500   auto ct0Alt = cc.Encrypt(sk, 0);
501 
502   auto ct11 = cc.EvalBinGate(NAND, ct1, ct1Alt);
503   auto ct01 = cc.EvalBinGate(NAND, ct0, ct1);
504   auto ct10 = cc.EvalBinGate(NAND, ct1, ct0);
505   auto ct00 = cc.EvalBinGate(NAND, ct0, ct0Alt);
506 
507   LWEPlaintext result11;
508   cc.Decrypt(sk, ct11, &result11);
509   LWEPlaintext result01;
510   cc.Decrypt(sk, ct01, &result01);
511   LWEPlaintext result10;
512   cc.Decrypt(sk, ct10, &result10);
513   LWEPlaintext result00;
514   cc.Decrypt(sk, ct00, &result00);
515 
516   std::string failed = "NAND failed";
517 
518   EXPECT_EQ(0, result11) << failed;
519   EXPECT_EQ(1, result01) << failed;
520   EXPECT_EQ(1, result10) << failed;
521   EXPECT_EQ(1, result00) << failed;
522 }
523 
524 // Checks the truth table for AND
TEST(UnitTestFHEWAP,NOR)525 TEST(UnitTestFHEWAP, NOR) {
526   auto cc = BinFHEContext();
527   cc.GenerateBinFHEContext(TOY, AP);
528 
529   auto sk = cc.KeyGen();
530 
531   cc.BTKeyGen(sk);
532 
533   auto ct1 = cc.Encrypt(sk, 1);
534   auto ct0 = cc.Encrypt(sk, 0);
535   auto ct1Alt = cc.Encrypt(sk, 1);
536   auto ct0Alt = cc.Encrypt(sk, 0);
537 
538   auto ct11 = cc.EvalBinGate(NOR, ct1, ct1Alt);
539   auto ct01 = cc.EvalBinGate(NOR, ct0, ct1);
540   auto ct10 = cc.EvalBinGate(NOR, ct1, ct0);
541   auto ct00 = cc.EvalBinGate(NOR, ct0, ct0Alt);
542 
543   LWEPlaintext result11;
544   cc.Decrypt(sk, ct11, &result11);
545   LWEPlaintext result01;
546   cc.Decrypt(sk, ct01, &result01);
547   LWEPlaintext result10;
548   cc.Decrypt(sk, ct10, &result10);
549   LWEPlaintext result00;
550   cc.Decrypt(sk, ct00, &result00);
551 
552   std::string failed = "NOR failed";
553 
554   EXPECT_EQ(0, result11) << failed;
555   EXPECT_EQ(0, result01) << failed;
556   EXPECT_EQ(0, result10) << failed;
557   EXPECT_EQ(1, result00) << failed;
558 }
559 
560 // Checks the truth table for AND
TEST(UnitTestFHEWGINX,NOR)561 TEST(UnitTestFHEWGINX, NOR) {
562   auto cc = BinFHEContext();
563   cc.GenerateBinFHEContext(TOY, GINX);
564 
565   auto sk = cc.KeyGen();
566 
567   cc.BTKeyGen(sk);
568 
569   auto ct1 = cc.Encrypt(sk, 1);
570   auto ct0 = cc.Encrypt(sk, 0);
571   auto ct1Alt = cc.Encrypt(sk, 1);
572   auto ct0Alt = cc.Encrypt(sk, 0);
573 
574   auto ct11 = cc.EvalBinGate(NOR, ct1, ct1Alt);
575   auto ct01 = cc.EvalBinGate(NOR, ct0, ct1);
576   auto ct10 = cc.EvalBinGate(NOR, ct1, ct0);
577   auto ct00 = cc.EvalBinGate(NOR, ct0, ct0Alt);
578 
579   LWEPlaintext result11;
580   cc.Decrypt(sk, ct11, &result11);
581   LWEPlaintext result01;
582   cc.Decrypt(sk, ct01, &result01);
583   LWEPlaintext result10;
584   cc.Decrypt(sk, ct10, &result10);
585   LWEPlaintext result00;
586   cc.Decrypt(sk, ct00, &result00);
587 
588   std::string failed = "NOR failed";
589 
590   EXPECT_EQ(0, result11) << failed;
591   EXPECT_EQ(0, result01) << failed;
592   EXPECT_EQ(0, result10) << failed;
593   EXPECT_EQ(1, result00) << failed;
594 }
595 
596 // Checks the truth table for XOR
TEST(UnitTestFHEWAP,XOR)597 TEST(UnitTestFHEWAP, XOR) {
598   auto cc = BinFHEContext();
599   cc.GenerateBinFHEContext(TOY, AP);
600 
601   auto sk = cc.KeyGen();
602 
603   cc.BTKeyGen(sk);
604 
605   auto ct1 = cc.Encrypt(sk, 1);
606   auto ct0 = cc.Encrypt(sk, 0);
607   auto ct1Alt = cc.Encrypt(sk, 1);
608   auto ct0Alt = cc.Encrypt(sk, 0);
609 
610   auto ct11 = cc.EvalBinGate(XOR, ct1, ct1Alt);
611   auto ct01 = cc.EvalBinGate(XOR, ct0, ct1);
612   auto ct10 = cc.EvalBinGate(XOR, ct1, ct0);
613   auto ct00 = cc.EvalBinGate(XOR, ct0, ct0Alt);
614 
615   LWEPlaintext result11;
616   cc.Decrypt(sk, ct11, &result11);
617   LWEPlaintext result01;
618   cc.Decrypt(sk, ct01, &result01);
619   LWEPlaintext result10;
620   cc.Decrypt(sk, ct10, &result10);
621   LWEPlaintext result00;
622   cc.Decrypt(sk, ct00, &result00);
623 
624   std::string failed = "XOR failed";
625 
626   EXPECT_EQ(0, result11) << failed;
627   EXPECT_EQ(1, result01) << failed;
628   EXPECT_EQ(1, result10) << failed;
629   EXPECT_EQ(0, result00) << failed;
630 }
631 
632 // Checks the truth table for XOR
TEST(UnitTestFHEWGINX,XOR)633 TEST(UnitTestFHEWGINX, XOR) {
634   auto cc = BinFHEContext();
635   cc.GenerateBinFHEContext(TOY, GINX);
636 
637   auto sk = cc.KeyGen();
638 
639   cc.BTKeyGen(sk);
640 
641   auto ct1 = cc.Encrypt(sk, 1);
642   auto ct0 = cc.Encrypt(sk, 0);
643   auto ct1Alt = cc.Encrypt(sk, 1);
644   auto ct0Alt = cc.Encrypt(sk, 0);
645 
646   auto ct11 = cc.EvalBinGate(XOR, ct1, ct1Alt);
647   auto ct01 = cc.EvalBinGate(XOR, ct0, ct1);
648   auto ct10 = cc.EvalBinGate(XOR, ct1, ct0);
649   auto ct00 = cc.EvalBinGate(XOR, ct0, ct0Alt);
650 
651   LWEPlaintext result11;
652   cc.Decrypt(sk, ct11, &result11);
653   LWEPlaintext result01;
654   cc.Decrypt(sk, ct01, &result01);
655   LWEPlaintext result10;
656   cc.Decrypt(sk, ct10, &result10);
657   LWEPlaintext result00;
658   cc.Decrypt(sk, ct00, &result00);
659 
660   std::string failed = "XOR failed";
661 
662   EXPECT_EQ(0, result11) << failed;
663   EXPECT_EQ(1, result01) << failed;
664   EXPECT_EQ(1, result10) << failed;
665   EXPECT_EQ(0, result00) << failed;
666 }
667 
668 // Checks the truth table for XOR
TEST(UnitTestFHEWAP,XNOR)669 TEST(UnitTestFHEWAP, XNOR) {
670   auto cc = BinFHEContext();
671   cc.GenerateBinFHEContext(TOY, AP);
672 
673   auto sk = cc.KeyGen();
674 
675   cc.BTKeyGen(sk);
676 
677   auto ct1 = cc.Encrypt(sk, 1);
678   auto ct0 = cc.Encrypt(sk, 0);
679   auto ct1Alt = cc.Encrypt(sk, 1);
680   auto ct0Alt = cc.Encrypt(sk, 0);
681 
682   auto ct11 = cc.EvalBinGate(XNOR, ct1, ct1Alt);
683   auto ct01 = cc.EvalBinGate(XNOR, ct0, ct1);
684   auto ct10 = cc.EvalBinGate(XNOR, ct1, ct0);
685   auto ct00 = cc.EvalBinGate(XNOR, ct0, ct0Alt);
686 
687   LWEPlaintext result11;
688   cc.Decrypt(sk, ct11, &result11);
689   LWEPlaintext result01;
690   cc.Decrypt(sk, ct01, &result01);
691   LWEPlaintext result10;
692   cc.Decrypt(sk, ct10, &result10);
693   LWEPlaintext result00;
694   cc.Decrypt(sk, ct00, &result00);
695 
696   std::string failed = "XNOR failed";
697 
698   EXPECT_EQ(1, result11) << failed;
699   EXPECT_EQ(0, result01) << failed;
700   EXPECT_EQ(0, result10) << failed;
701   EXPECT_EQ(1, result00) << failed;
702 }
703 
704 // Checks the truth table for XOR
TEST(UnitTestFHEWGINX,XNOR)705 TEST(UnitTestFHEWGINX, XNOR) {
706   auto cc = BinFHEContext();
707   cc.GenerateBinFHEContext(TOY, GINX);
708 
709   auto sk = cc.KeyGen();
710 
711   cc.BTKeyGen(sk);
712 
713   auto ct1 = cc.Encrypt(sk, 1);
714   auto ct0 = cc.Encrypt(sk, 0);
715   auto ct1Alt = cc.Encrypt(sk, 1);
716   auto ct0Alt = cc.Encrypt(sk, 0);
717 
718   auto ct11 = cc.EvalBinGate(XNOR, ct1, ct1Alt);
719   auto ct01 = cc.EvalBinGate(XNOR, ct0, ct1);
720   auto ct10 = cc.EvalBinGate(XNOR, ct1, ct0);
721   auto ct00 = cc.EvalBinGate(XNOR, ct0, ct0Alt);
722 
723   LWEPlaintext result11;
724   cc.Decrypt(sk, ct11, &result11);
725   LWEPlaintext result01;
726   cc.Decrypt(sk, ct01, &result01);
727   LWEPlaintext result10;
728   cc.Decrypt(sk, ct10, &result10);
729   LWEPlaintext result00;
730   cc.Decrypt(sk, ct00, &result00);
731 
732   std::string failed = "XNOR failed";
733 
734   EXPECT_EQ(1, result11) << failed;
735   EXPECT_EQ(0, result01) << failed;
736   EXPECT_EQ(0, result10) << failed;
737   EXPECT_EQ(1, result00) << failed;
738 }
739 
740 // Checks the truth table for XOR
TEST(UnitTestFHEWAP,XOR_FAST)741 TEST(UnitTestFHEWAP, XOR_FAST) {
742   auto cc = BinFHEContext();
743   cc.GenerateBinFHEContext(TOY, AP);
744 
745   auto sk = cc.KeyGen();
746 
747   cc.BTKeyGen(sk);
748 
749   auto ct1 = cc.Encrypt(sk, 1);
750   auto ct0 = cc.Encrypt(sk, 0);
751   auto ct1Alt = cc.Encrypt(sk, 1);
752   auto ct0Alt = cc.Encrypt(sk, 0);
753 
754   auto ct11 = cc.EvalBinGate(XOR_FAST, ct1, ct1Alt);
755   auto ct01 = cc.EvalBinGate(XOR_FAST, ct0, ct1);
756   auto ct10 = cc.EvalBinGate(XOR_FAST, ct1, ct0);
757   auto ct00 = cc.EvalBinGate(XOR_FAST, ct0, ct0Alt);
758 
759   LWEPlaintext result11;
760   cc.Decrypt(sk, ct11, &result11);
761   LWEPlaintext result01;
762   cc.Decrypt(sk, ct01, &result01);
763   LWEPlaintext result10;
764   cc.Decrypt(sk, ct10, &result10);
765   LWEPlaintext result00;
766   cc.Decrypt(sk, ct00, &result00);
767 
768   std::string failed = "XOR_FAST failed";
769 
770   EXPECT_EQ(0, result11) << failed;
771   EXPECT_EQ(1, result01) << failed;
772   EXPECT_EQ(1, result10) << failed;
773   EXPECT_EQ(0, result00) << failed;
774 }
775 
776 // Checks the truth table for XOR
TEST(UnitTestFHEWGINX,XOR_FAST)777 TEST(UnitTestFHEWGINX, XOR_FAST) {
778   auto cc = BinFHEContext();
779   cc.GenerateBinFHEContext(TOY, GINX);
780 
781   auto sk = cc.KeyGen();
782 
783   cc.BTKeyGen(sk);
784 
785   auto ct1 = cc.Encrypt(sk, 1);
786   auto ct0 = cc.Encrypt(sk, 0);
787   auto ct1Alt = cc.Encrypt(sk, 1);
788   auto ct0Alt = cc.Encrypt(sk, 0);
789 
790   auto ct11 = cc.EvalBinGate(XOR_FAST, ct1, ct1Alt);
791   auto ct01 = cc.EvalBinGate(XOR_FAST, ct0, ct1);
792   auto ct10 = cc.EvalBinGate(XOR_FAST, ct1, ct0);
793   auto ct00 = cc.EvalBinGate(XOR_FAST, ct0, ct0Alt);
794 
795   LWEPlaintext result11;
796   cc.Decrypt(sk, ct11, &result11);
797   LWEPlaintext result01;
798   cc.Decrypt(sk, ct01, &result01);
799   LWEPlaintext result10;
800   cc.Decrypt(sk, ct10, &result10);
801   LWEPlaintext result00;
802   cc.Decrypt(sk, ct00, &result00);
803 
804   std::string failed = "XOR_FAST failed";
805 
806   EXPECT_EQ(0, result11) << failed;
807   EXPECT_EQ(1, result01) << failed;
808   EXPECT_EQ(1, result10) << failed;
809   EXPECT_EQ(0, result00) << failed;
810 }
811 
812 // Checks the truth table for XOR
TEST(UnitTestFHEWAP,XNOR_FAST)813 TEST(UnitTestFHEWAP, XNOR_FAST) {
814   auto cc = BinFHEContext();
815   cc.GenerateBinFHEContext(TOY, AP);
816 
817   auto sk = cc.KeyGen();
818 
819   cc.BTKeyGen(sk);
820 
821   auto ct1 = cc.Encrypt(sk, 1);
822   auto ct0 = cc.Encrypt(sk, 0);
823   auto ct1Alt = cc.Encrypt(sk, 1);
824   auto ct0Alt = cc.Encrypt(sk, 0);
825 
826   auto ct11 = cc.EvalBinGate(XNOR_FAST, ct1, ct1Alt);
827   auto ct01 = cc.EvalBinGate(XNOR_FAST, ct0, ct1);
828   auto ct10 = cc.EvalBinGate(XNOR_FAST, ct1, ct0);
829   auto ct00 = cc.EvalBinGate(XNOR_FAST, ct0, ct0Alt);
830 
831   LWEPlaintext result11;
832   cc.Decrypt(sk, ct11, &result11);
833   LWEPlaintext result01;
834   cc.Decrypt(sk, ct01, &result01);
835   LWEPlaintext result10;
836   cc.Decrypt(sk, ct10, &result10);
837   LWEPlaintext result00;
838   cc.Decrypt(sk, ct00, &result00);
839 
840   std::string failed = "XNOR_FAST failed";
841 
842   EXPECT_EQ(1, result11) << failed;
843   EXPECT_EQ(0, result01) << failed;
844   EXPECT_EQ(0, result10) << failed;
845   EXPECT_EQ(1, result00) << failed;
846 }
847 
848 // Checks the truth table for XOR
TEST(UnitTestFHEWGINX,XNOR_FAST)849 TEST(UnitTestFHEWGINX, XNOR_FAST) {
850   auto cc = BinFHEContext();
851   cc.GenerateBinFHEContext(TOY, GINX);
852 
853   auto sk = cc.KeyGen();
854 
855   cc.BTKeyGen(sk);
856 
857   auto ct1 = cc.Encrypt(sk, 1);
858   auto ct0 = cc.Encrypt(sk, 0);
859   auto ct1Alt = cc.Encrypt(sk, 1);
860   auto ct0Alt = cc.Encrypt(sk, 0);
861 
862   auto ct11 = cc.EvalBinGate(XNOR_FAST, ct1, ct1Alt);
863   auto ct01 = cc.EvalBinGate(XNOR_FAST, ct0, ct1);
864   auto ct10 = cc.EvalBinGate(XNOR_FAST, ct1, ct0);
865   auto ct00 = cc.EvalBinGate(XNOR_FAST, ct0, ct0Alt);
866 
867   LWEPlaintext result11;
868   cc.Decrypt(sk, ct11, &result11);
869   LWEPlaintext result01;
870   cc.Decrypt(sk, ct01, &result01);
871   LWEPlaintext result10;
872   cc.Decrypt(sk, ct10, &result10);
873   LWEPlaintext result00;
874   cc.Decrypt(sk, ct00, &result00);
875 
876   std::string failed = "XNOR_FAST failed";
877 
878   EXPECT_EQ(1, result11) << failed;
879   EXPECT_EQ(0, result01) << failed;
880   EXPECT_EQ(0, result10) << failed;
881   EXPECT_EQ(1, result00) << failed;
882 }
883