1 /*
2  * @file binfhe : library benchmark routines for FHEW-AP
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  */
26 
27 /*
28  * This file benchmarks FHEW-AP gate evaluation operations
29  */
30 
31 #define PROFILE
32 #include "benchmark/benchmark.h"
33 
34 #include <fstream>
35 #include <iostream>
36 #include <iterator>
37 #include <limits>
38 #include <random>
39 
40 #include "binfhecontext.h"
41 
42 #include "utils/debug.h"
43 
44 using namespace std;
45 using namespace lbcrypto;
46 
47 /*
48  * Context setup utility methods
49  */
50 
51 BinFHEContext GenerateFHEWContext(BINFHEPARAMSET set) {
52   auto cc = BinFHEContext();
53   cc.GenerateBinFHEContext(set, AP);
54   return cc;
55 }
56 
57 /*
58  * FHEW benchmarks
59  */
60 
61 template <class ParamSet>
62 void FHEW_NOT(benchmark::State &state, ParamSet param_set) {
63   BINFHEPARAMSET param(param_set);
64   BinFHEContext cc = GenerateFHEWContext(param);
65 
66   LWEPrivateKey sk = cc.KeyGen();
67 
68   LWECiphertext ct1 = cc.Encrypt(sk, 1, FRESH);
69 
70   for (auto _ : state) {
71     LWECiphertext ct11 = cc.EvalNOT(ct1);
72   }
73 }
74 
75 BENCHMARK_CAPTURE(FHEW_NOT, MEDIUM, MEDIUM)->Unit(benchmark::kMicrosecond);
76 BENCHMARK_CAPTURE(FHEW_NOT, STD128, STD128)->Unit(benchmark::kMicrosecond);
77 BENCHMARK_CAPTURE(FHEW_NOT, STD128_AP, STD128_AP)
78     ->Unit(benchmark::kMicrosecond);
79 
80 // benchmark for binary gates, such as AND, OR, NAND, NOR
81 template <class ParamSet, class BinGate>
82 void FHEW_BINGATE(benchmark::State &state, ParamSet param_set,
83                   BinGate bin_gate) {
84   BINGATE gate(bin_gate);
85   BINFHEPARAMSET param(param_set);
86 
87   BinFHEContext cc = GenerateFHEWContext(param);
88 
89   LWEPrivateKey sk = cc.KeyGen();
90 
91   cc.BTKeyGen(sk);
92 
93   LWECiphertext ct1 = cc.Encrypt(sk, 1);
94   LWECiphertext ct2 = cc.Encrypt(sk, 1);
95 
96   for (auto _ : state) {
97     LWECiphertext ct11 = cc.EvalBinGate(gate, ct1, ct2);
98   }
99 }
100 
101 BENCHMARK_CAPTURE(FHEW_BINGATE, MEDIUM_OR, MEDIUM, OR)
102     ->Unit(benchmark::kMicrosecond)
103     ->MinTime(10.0);
104 
105 BENCHMARK_CAPTURE(FHEW_BINGATE, MEDIUM_AND, MEDIUM, AND)
106     ->Unit(benchmark::kMicrosecond);
107 
108 BENCHMARK_CAPTURE(FHEW_BINGATE, MEDIUM_NOR, MEDIUM, NOR)
109     ->Unit(benchmark::kMicrosecond);
110 
111 BENCHMARK_CAPTURE(FHEW_BINGATE, MEDIUM_NAND, MEDIUM, NAND)
112     ->Unit(benchmark::kMicrosecond);
113 
114 BENCHMARK_CAPTURE(FHEW_BINGATE, MEDIUM_XOR, MEDIUM, XOR)
115     ->Unit(benchmark::kMicrosecond);
116 
117 BENCHMARK_CAPTURE(FHEW_BINGATE, MEDIUM_XNOR, MEDIUM, XNOR)
118     ->Unit(benchmark::kMicrosecond);
119 
120 BENCHMARK_CAPTURE(FHEW_BINGATE, MEDIUM_XOR_FAST, MEDIUM, XOR_FAST)
121     ->Unit(benchmark::kMicrosecond);
122 
123 BENCHMARK_CAPTURE(FHEW_BINGATE, MEDIUM_XNOR_FAST, MEDIUM, XNOR_FAST)
124     ->Unit(benchmark::kMicrosecond);
125 
126 BENCHMARK_CAPTURE(FHEW_BINGATE, STD128_OR, STD128, OR)
127     ->Unit(benchmark::kMicrosecond)
128     ->MinTime(10.0);
129 
130 BENCHMARK_CAPTURE(FHEW_BINGATE, STD128_AND, STD128, AND)
131     ->Unit(benchmark::kMicrosecond);
132 
133 BENCHMARK_CAPTURE(FHEW_BINGATE, STD128_NOR, STD128, NOR)
134     ->Unit(benchmark::kMicrosecond);
135 
136 BENCHMARK_CAPTURE(FHEW_BINGATE, STD128_NAND, STD128, NAND)
137     ->Unit(benchmark::kMicrosecond);
138 
139 BENCHMARK_CAPTURE(FHEW_BINGATE, STD128_XOR, STD128, XOR)
140     ->Unit(benchmark::kMicrosecond);
141 
142 BENCHMARK_CAPTURE(FHEW_BINGATE, STD128_XNOR, STD128, XNOR)
143     ->Unit(benchmark::kMicrosecond);
144 
145 BENCHMARK_CAPTURE(FHEW_BINGATE, STD128_XOR_FAST, STD128, XOR_FAST)
146     ->Unit(benchmark::kMicrosecond);
147 
148 BENCHMARK_CAPTURE(FHEW_BINGATE, STD128_XNOR_FAST, STD128, XNOR_FAST)
149     ->Unit(benchmark::kMicrosecond);
150 
151 BENCHMARK_CAPTURE(FHEW_BINGATE, STD128_AP_OR, STD128_AP, OR)
152     ->Unit(benchmark::kMicrosecond)
153     ->MinTime(10.0);
154 
155 BENCHMARK_CAPTURE(FHEW_BINGATE, STD128_AP_AND, STD128_AP, AND)
156     ->Unit(benchmark::kMicrosecond);
157 
158 BENCHMARK_CAPTURE(FHEW_BINGATE, STD128_AP_NOR, STD128_AP, NOR)
159     ->Unit(benchmark::kMicrosecond);
160 
161 BENCHMARK_CAPTURE(FHEW_BINGATE, STD128_AP_NAND, STD128_AP, NAND)
162     ->Unit(benchmark::kMicrosecond);
163 
164 BENCHMARK_CAPTURE(FHEW_BINGATE, STD128_AP_XOR, STD128_AP, XOR)
165     ->Unit(benchmark::kMicrosecond);
166 
167 BENCHMARK_CAPTURE(FHEW_BINGATE, STD128_AP_XNOR, STD128_AP, XNOR)
168     ->Unit(benchmark::kMicrosecond);
169 
170 BENCHMARK_CAPTURE(FHEW_BINGATE, STD128_AP_XOR_FAST, STD128_AP, XOR_FAST)
171     ->Unit(benchmark::kMicrosecond);
172 
173 BENCHMARK_CAPTURE(FHEW_BINGATE, STD128_AP_XNOR_FAST, STD128_AP, XNOR_FAST)
174     ->Unit(benchmark::kMicrosecond);
175 
176 // benchmark for key switching
177 template <class ParamSet>
178 void FHEW_KEYSWITCH(benchmark::State &state, ParamSet param_set) {
179   BINFHEPARAMSET param(param_set);
180   BinFHEContext cc = GenerateFHEWContext(param);
181 
182   LWEPrivateKey sk = cc.KeyGen();
183   LWEPrivateKey skN = cc.KeyGenN();
184 
185   auto ctQN1 = cc.Encrypt(skN, 1, FRESH);
186   auto keySwitchHint = cc.KeySwitchGen(sk, skN);
187 
188   for (auto _ : state) {
189     std::shared_ptr<LWECiphertextImpl> eQ1 = cc.GetLWEScheme()->KeySwitch(
190         cc.GetParams()->GetLWEParams(), keySwitchHint, ctQN1);
191   }
192 }
193 
194 BENCHMARK_CAPTURE(FHEW_KEYSWITCH, MEDIUM, MEDIUM)
195     ->Unit(benchmark::kMicrosecond)
196     ->MinTime(1.0);
197 
198 BENCHMARK_CAPTURE(FHEW_KEYSWITCH, STD128, STD128)
199     ->Unit(benchmark::kMicrosecond)
200     ->MinTime(1.0);
201 
202 BENCHMARK_CAPTURE(FHEW_KEYSWITCH, STD128_AP, STD128_AP)
203     ->Unit(benchmark::kMicrosecond)
204     ->MinTime(1.0);
205 
206 BENCHMARK_MAIN();
207