1 // Copyright (c) Microsoft Corporation. All rights reserved.
2 // Licensed under the MIT license.
3 
4 #include "seal/seal.h"
5 #include "seal/util/rlwe.h"
6 #include "bench.h"
7 
8 using namespace benchmark;
9 using namespace sealbench;
10 using namespace seal;
11 using namespace std;
12 
13 /**
14 This file defines benchmarks for BFV-specific HE primitives.
15 */
16 
17 namespace sealbench
18 {
bm_bfv_encrypt_secret(State & state,shared_ptr<BMEnv> bm_env)19     void bm_bfv_encrypt_secret(State &state, shared_ptr<BMEnv> bm_env)
20     {
21         vector<Ciphertext> &ct = bm_env->ct();
22         Plaintext &pt = bm_env->pt()[0];
23         for (auto _ : state)
24         {
25             state.PauseTiming();
26             bm_env->randomize_pt_bfv(pt);
27 
28             state.ResumeTiming();
29             bm_env->encryptor()->encrypt_symmetric(pt, ct[2]);
30         }
31     }
32 
bm_bfv_encrypt_public(State & state,shared_ptr<BMEnv> bm_env)33     void bm_bfv_encrypt_public(State &state, shared_ptr<BMEnv> bm_env)
34     {
35         vector<Ciphertext> &ct = bm_env->ct();
36         Plaintext &pt = bm_env->pt()[0];
37         for (auto _ : state)
38         {
39             state.PauseTiming();
40             bm_env->randomize_pt_bfv(pt);
41 
42             state.ResumeTiming();
43             bm_env->encryptor()->encrypt(pt, ct[2]);
44         }
45     }
46 
bm_bfv_decrypt(State & state,shared_ptr<BMEnv> bm_env)47     void bm_bfv_decrypt(State &state, shared_ptr<BMEnv> bm_env)
48     {
49         vector<Ciphertext> &ct = bm_env->ct();
50         Plaintext &pt = bm_env->pt()[0];
51         for (auto _ : state)
52         {
53             state.PauseTiming();
54             bm_env->randomize_ct_bfv(ct[0]);
55 
56             state.ResumeTiming();
57             bm_env->decryptor()->decrypt(ct[0], pt);
58         }
59     }
60 
bm_bfv_encode_batch(State & state,shared_ptr<BMEnv> bm_env)61     void bm_bfv_encode_batch(State &state, shared_ptr<BMEnv> bm_env)
62     {
63         vector<uint64_t> &msg = bm_env->msg_uint64();
64         Plaintext &pt = bm_env->pt()[0];
65         for (auto _ : state)
66         {
67             state.PauseTiming();
68             bm_env->randomize_message_uint64(msg);
69 
70             state.ResumeTiming();
71             bm_env->batch_encoder()->encode(msg, pt);
72         }
73     }
74 
bm_bfv_decode_batch(State & state,shared_ptr<BMEnv> bm_env)75     void bm_bfv_decode_batch(State &state, shared_ptr<BMEnv> bm_env)
76     {
77         vector<uint64_t> &msg = bm_env->msg_uint64();
78         Plaintext &pt = bm_env->pt()[0];
79         for (auto _ : state)
80         {
81             state.PauseTiming();
82             bm_env->randomize_pt_bfv(pt);
83 
84             state.ResumeTiming();
85             bm_env->batch_encoder()->decode(pt, msg);
86         }
87     }
88 
bm_bfv_add_ct(State & state,shared_ptr<BMEnv> bm_env)89     void bm_bfv_add_ct(State &state, shared_ptr<BMEnv> bm_env)
90     {
91         vector<Ciphertext> &ct = bm_env->ct();
92         for (auto _ : state)
93         {
94             state.PauseTiming();
95             bm_env->randomize_ct_bfv(ct[0]);
96             bm_env->randomize_ct_bfv(ct[1]);
97             state.ResumeTiming();
98             Ciphertext res;
99             bm_env->evaluator()->add(ct[0], ct[1], res);
100         }
101     }
102 
bm_bfv_add_pt(State & state,shared_ptr<BMEnv> bm_env)103     void bm_bfv_add_pt(State &state, shared_ptr<BMEnv> bm_env)
104     {
105         vector<Ciphertext> &ct = bm_env->ct();
106         Plaintext &pt = bm_env->pt()[0];
107         for (auto _ : state)
108         {
109             state.PauseTiming();
110             bm_env->randomize_ct_bfv(ct[0]);
111             bm_env->randomize_pt_bfv(pt);
112 
113             state.ResumeTiming();
114             bm_env->evaluator()->add_plain(ct[0], pt, ct[2]);
115         }
116     }
117 
bm_bfv_negate(State & state,shared_ptr<BMEnv> bm_env)118     void bm_bfv_negate(State &state, shared_ptr<BMEnv> bm_env)
119     {
120         vector<Ciphertext> &ct = bm_env->ct();
121         for (auto _ : state)
122         {
123             state.PauseTiming();
124             bm_env->randomize_ct_bfv(ct[0]);
125 
126             state.ResumeTiming();
127             bm_env->evaluator()->negate(ct[0], ct[2]);
128         }
129     }
130 
bm_bfv_sub_ct(State & state,shared_ptr<BMEnv> bm_env)131     void bm_bfv_sub_ct(State &state, shared_ptr<BMEnv> bm_env)
132     {
133         vector<Ciphertext> &ct = bm_env->ct();
134         for (auto _ : state)
135         {
136             state.PauseTiming();
137             bm_env->randomize_ct_bfv(ct[0]);
138             bm_env->randomize_ct_bfv(ct[1]);
139 
140             state.ResumeTiming();
141             bm_env->evaluator()->sub(ct[0], ct[1], ct[2]);
142         }
143     }
144 
bm_bfv_sub_pt(State & state,shared_ptr<BMEnv> bm_env)145     void bm_bfv_sub_pt(State &state, shared_ptr<BMEnv> bm_env)
146     {
147         vector<Ciphertext> &ct = bm_env->ct();
148         Plaintext &pt = bm_env->pt()[0];
149         for (auto _ : state)
150         {
151             state.PauseTiming();
152             bm_env->randomize_ct_bfv(ct[0]);
153             bm_env->randomize_pt_bfv(pt);
154 
155             state.ResumeTiming();
156             bm_env->evaluator()->sub_plain(ct[0], pt, ct[2]);
157         }
158     }
159 
bm_bfv_mul_ct(State & state,shared_ptr<BMEnv> bm_env)160     void bm_bfv_mul_ct(State &state, shared_ptr<BMEnv> bm_env)
161     {
162         vector<Ciphertext> &ct = bm_env->ct();
163         for (auto _ : state)
164         {
165             state.PauseTiming();
166             bm_env->randomize_ct_bfv(ct[0]);
167             bm_env->randomize_ct_bfv(ct[1]);
168 
169             state.ResumeTiming();
170             bm_env->evaluator()->multiply(ct[0], ct[1], ct[2]);
171         }
172     }
173 
bm_bfv_mul_pt(State & state,shared_ptr<BMEnv> bm_env)174     void bm_bfv_mul_pt(State &state, shared_ptr<BMEnv> bm_env)
175     {
176         vector<Ciphertext> &ct = bm_env->ct();
177         Plaintext &pt = bm_env->pt()[0];
178         for (auto _ : state)
179         {
180             state.PauseTiming();
181             bm_env->randomize_ct_bfv(ct[0]);
182             bm_env->randomize_pt_bfv(pt);
183 
184             state.ResumeTiming();
185             bm_env->evaluator()->multiply_plain(ct[0], pt, ct[2]);
186         }
187     }
188 
bm_bfv_square(State & state,shared_ptr<BMEnv> bm_env)189     void bm_bfv_square(State &state, shared_ptr<BMEnv> bm_env)
190     {
191         vector<Ciphertext> &ct = bm_env->ct();
192         for (auto _ : state)
193         {
194             state.PauseTiming();
195             bm_env->randomize_ct_bfv(ct[0]);
196             bm_env->randomize_ct_bfv(ct[1]);
197 
198             state.ResumeTiming();
199             bm_env->evaluator()->square(ct[0], ct[2]);
200         }
201     }
202 
bm_bfv_modswitch_inplace(State & state,shared_ptr<BMEnv> bm_env)203     void bm_bfv_modswitch_inplace(State &state, shared_ptr<BMEnv> bm_env)
204     {
205         vector<Ciphertext> &ct = bm_env->ct();
206         for (auto _ : state)
207         {
208             state.PauseTiming();
209             bm_env->randomize_ct_bfv(ct[0]);
210 
211             state.ResumeTiming();
212             bm_env->evaluator()->mod_switch_to_next_inplace(ct[0]);
213         }
214     }
215 
bm_bfv_relin_inplace(State & state,shared_ptr<BMEnv> bm_env)216     void bm_bfv_relin_inplace(State &state, shared_ptr<BMEnv> bm_env)
217     {
218         Ciphertext ct;
219         for (auto _ : state)
220         {
221             state.PauseTiming();
222             ct.resize(bm_env->context(), size_t(3));
223             bm_env->randomize_ct_bfv(ct);
224 
225             state.ResumeTiming();
226             bm_env->evaluator()->relinearize_inplace(ct, bm_env->rlk());
227         }
228     }
229 
bm_bfv_rotate_rows(State & state,shared_ptr<BMEnv> bm_env)230     void bm_bfv_rotate_rows(State &state, shared_ptr<BMEnv> bm_env)
231     {
232         vector<Ciphertext> &ct = bm_env->ct();
233         for (auto _ : state)
234         {
235             state.PauseTiming();
236             bm_env->randomize_ct_bfv(ct[0]);
237 
238             state.ResumeTiming();
239             bm_env->evaluator()->rotate_rows(ct[0], 1, bm_env->glk(), ct[2]);
240         }
241     }
242 
bm_bfv_rotate_cols(State & state,shared_ptr<BMEnv> bm_env)243     void bm_bfv_rotate_cols(State &state, shared_ptr<BMEnv> bm_env)
244     {
245         vector<Ciphertext> &ct = bm_env->ct();
246         for (auto _ : state)
247         {
248             state.PauseTiming();
249             bm_env->randomize_ct_bfv(ct[0]);
250 
251             state.ResumeTiming();
252             bm_env->evaluator()->rotate_columns(ct[0], bm_env->glk(), ct[2]);
253         }
254     }
255 } // namespace sealbench
256