1 /*
2  * Bootstrapping FFT functions
3  */
4 
5 
6 #ifndef TFHE_TEST_ENVIRONMENT
7 
8 #include <iostream>
9 #include <cassert>
10 #include "tfhe.h"
11 
12 using namespace std;
13 #define INCLUDE_ALL
14 #else
15 #undef EXPORT
16 #define EXPORT
17 #endif
18 
19 
20 #if defined INCLUDE_ALL || defined INCLUDE_TFHE_INIT_LWEBOOTSTRAPPINGKEY_FFT
21 #undef INCLUDE_TFHE_INIT_LWEBOOTSTRAPPINGKEY_FFT
22 //(equivalent of the C++ constructor)
init_LweBootstrappingKeyFFT(LweBootstrappingKeyFFT * obj,const LweBootstrappingKey * bk)23 EXPORT void init_LweBootstrappingKeyFFT(LweBootstrappingKeyFFT *obj, const LweBootstrappingKey *bk) {
24 
25     const LweParams *in_out_params = bk->in_out_params;
26     const TGswParams *bk_params = bk->bk_params;
27     const TLweParams *accum_params = bk_params->tlwe_params;
28     const LweParams *extract_params = &accum_params->extracted_lweparams;
29     const int32_t n = in_out_params->n;
30     const int32_t t = bk->ks->t;
31     const int32_t basebit = bk->ks->basebit;
32     const int32_t base = bk->ks->base;
33     const int32_t N = extract_params->n;
34 
35     LweKeySwitchKey *ks = new_LweKeySwitchKey(N, t, basebit, in_out_params);
36     // Copy the KeySwitching key
37     for (int32_t i = 0; i < N; i++) {
38         for (int32_t j = 0; j < t; j++) {
39             for (int32_t p = 0; p < base; p++) {
40                 lweCopy(&ks->ks[i][j][p], &bk->ks->ks[i][j][p], in_out_params);
41             }
42         }
43     }
44 
45     // Bootstrapping Key FFT
46     TGswSampleFFT *bkFFT = new_TGswSampleFFT_array(n, bk_params);
47     for (int32_t i = 0; i < n; ++i) {
48         tGswToFFTConvert(&bkFFT[i], &bk->bk[i], bk_params);
49     }
50 
51     new(obj) LweBootstrappingKeyFFT(in_out_params, bk_params, accum_params, extract_params, bkFFT, ks);
52 }
53 #endif
54 
55 
56 
57 //destroys the LweBootstrappingKeyFFT structure
58 //(equivalent of the C++ destructor)
destroy_LweBootstrappingKeyFFT(LweBootstrappingKeyFFT * obj)59 EXPORT void destroy_LweBootstrappingKeyFFT(LweBootstrappingKeyFFT *obj) {
60     delete_LweKeySwitchKey((LweKeySwitchKey *) obj->ks);
61     delete_TGswSampleFFT_array(obj->in_out_params->n, (TGswSampleFFT *) obj->bkFFT);
62 
63     obj->~LweBootstrappingKeyFFT();
64 }
65 
66 
tfhe_MuxRotate_FFT(TLweSample * result,const TLweSample * accum,const TGswSampleFFT * bki,const int32_t barai,const TGswParams * bk_params)67 void tfhe_MuxRotate_FFT(TLweSample *result, const TLweSample *accum, const TGswSampleFFT *bki, const int32_t barai,
68                         const TGswParams *bk_params) {
69     // ACC = BKi*[(X^barai-1)*ACC]+ACC
70     // temp = (X^barai-1)*ACC
71     tLweMulByXaiMinusOne(result, barai, accum, bk_params->tlwe_params);
72     // temp *= BKi
73     tGswFFTExternMulToTLwe(result, bki, bk_params);
74     // ACC += temp
75     tLweAddTo(result, accum, bk_params->tlwe_params);
76 }
77 
78 
79 #if defined INCLUDE_ALL || defined INCLUDE_TFHE_BLIND_ROTATE_FFT
80 #undef INCLUDE_TFHE_BLIND_ROTATE_FFT
81 /**
82  * multiply the accumulator by X^sum(bara_i.s_i)
83  * @param accum the TLWE sample to multiply
84  * @param bk An array of n TGSW FFT samples where bk_i encodes s_i
85  * @param bara An array of n coefficients between 0 and 2N-1
86  * @param bk_params The parameters of bk
87  */
tfhe_blindRotate_FFT(TLweSample * accum,const TGswSampleFFT * bkFFT,const int32_t * bara,const int32_t n,const TGswParams * bk_params)88 EXPORT void tfhe_blindRotate_FFT(TLweSample *accum,
89                                  const TGswSampleFFT *bkFFT,
90                                  const int32_t *bara,
91                                  const int32_t n,
92                                  const TGswParams *bk_params) {
93 
94     //TGswSampleFFT* temp = new_TGswSampleFFT(bk_params);
95     TLweSample *temp = new_TLweSample(bk_params->tlwe_params);
96     TLweSample *temp2 = temp;
97     TLweSample *temp3 = accum;
98 
99     for (int32_t i = 0; i < n; i++) {
100         const int32_t barai = bara[i];
101         if (barai == 0) continue; //indeed, this is an easy case!
102 
103         tfhe_MuxRotate_FFT(temp2, temp3, bkFFT + i, barai, bk_params);
104         swap(temp2, temp3);
105     }
106     if (temp3 != accum) {
107         tLweCopy(accum, temp3, bk_params->tlwe_params);
108     }
109 
110     delete_TLweSample(temp);
111     //delete_TGswSampleFFT(temp);
112 }
113 #endif
114 
115 
116 #if defined INCLUDE_ALL || defined INCLUDE_TFHE_BLIND_ROTATE_AND_EXTRACT_FFT
117 #undef INCLUDE_TFHE_BLIND_ROTATE_AND_EXTRACT_FFT
118 /**
119  * result = LWE(v_p) where p=barb-sum(bara_i.s_i) mod 2N
120  * @param result the output LWE sample
121  * @param v a 2N-elt anticyclic function (represented by a TorusPolynomial)
122  * @param bk An array of n TGSW FFT samples where bk_i encodes s_i
123  * @param barb A coefficients between 0 and 2N-1
124  * @param bara An array of n coefficients between 0 and 2N-1
125  * @param bk_params The parameters of bk
126  */
tfhe_blindRotateAndExtract_FFT(LweSample * result,const TorusPolynomial * v,const TGswSampleFFT * bk,const int32_t barb,const int32_t * bara,const int32_t n,const TGswParams * bk_params)127 EXPORT void tfhe_blindRotateAndExtract_FFT(LweSample *result,
128                                            const TorusPolynomial *v,
129                                            const TGswSampleFFT *bk,
130                                            const int32_t barb,
131                                            const int32_t *bara,
132                                            const int32_t n,
133                                            const TGswParams *bk_params) {
134 
135     const TLweParams *accum_params = bk_params->tlwe_params;
136     const LweParams *extract_params = &accum_params->extracted_lweparams;
137     const int32_t N = accum_params->N;
138     const int32_t _2N = 2 * N;
139 
140     // Test polynomial
141     TorusPolynomial *testvectbis = new_TorusPolynomial(N);
142     // Accumulator
143     TLweSample *acc = new_TLweSample(accum_params);
144 
145     // testvector = X^{2N-barb}*v
146     if (barb != 0) torusPolynomialMulByXai(testvectbis, _2N - barb, v);
147     else torusPolynomialCopy(testvectbis, v);
148     tLweNoiselessTrivial(acc, testvectbis, accum_params);
149     // Blind rotation
150     tfhe_blindRotate_FFT(acc, bk, bara, n, bk_params);
151     // Extraction
152     tLweExtractLweSample(result, acc, extract_params, accum_params);
153 
154     delete_TLweSample(acc);
155     delete_TorusPolynomial(testvectbis);
156 }
157 #endif
158 
159 
160 #if defined INCLUDE_ALL || defined INCLUDE_TFHE_BOOTSTRAP_WO_KS_FFT
161 #undef INCLUDE_TFHE_BOOTSTRAP_WO_KS_FFT
162 /**
163  * result = LWE(mu) iff phase(x)>0, LWE(-mu) iff phase(x)<0
164  * @param result The resulting LweSample
165  * @param bk The bootstrapping + keyswitch key
166  * @param mu The output message (if phase(x)>0)
167  * @param x The input sample
168  */
tfhe_bootstrap_woKS_FFT(LweSample * result,const LweBootstrappingKeyFFT * bk,Torus32 mu,const LweSample * x)169 EXPORT void tfhe_bootstrap_woKS_FFT(LweSample *result,
170                                     const LweBootstrappingKeyFFT *bk,
171                                     Torus32 mu,
172                                     const LweSample *x) {
173 
174     const TGswParams *bk_params = bk->bk_params;
175     const TLweParams *accum_params = bk->accum_params;
176     const LweParams *in_params = bk->in_out_params;
177     const int32_t N = accum_params->N;
178     const int32_t Nx2 = 2 * N;
179     const int32_t n = in_params->n;
180 
181     TorusPolynomial *testvect = new_TorusPolynomial(N);
182     int32_t *bara = new int32_t[N];
183 
184 
185     // Modulus switching
186     int32_t barb = modSwitchFromTorus32(x->b, Nx2);
187     for (int32_t i = 0; i < n; i++) {
188         bara[i] = modSwitchFromTorus32(x->a[i], Nx2);
189     }
190 
191     // the initial testvec = [mu,mu,mu,...,mu]
192     for (int32_t i = 0; i < N; i++) testvect->coefsT[i] = mu;
193 
194     // Bootstrapping rotation and extraction
195     tfhe_blindRotateAndExtract_FFT(result, testvect, bk->bkFFT, barb, bara, n, bk_params);
196 
197 
198     delete[] bara;
199     delete_TorusPolynomial(testvect);
200 }
201 #endif
202 
203 
204 #if defined INCLUDE_ALL || defined INCLUDE_TFHE_BOOTSTRAP_FFT
205 #undef INCLUDE_TFHE_BOOTSTRAP_FFT
206 /**
207  * result = LWE(mu) iff phase(x)>0, LWE(-mu) iff phase(x)<0
208  * @param result The resulting LweSample
209  * @param bk The bootstrapping + keyswitch key
210  * @param mu The output message (if phase(x)>0)
211  * @param x The input sample
212  */
tfhe_bootstrap_FFT(LweSample * result,const LweBootstrappingKeyFFT * bk,Torus32 mu,const LweSample * x)213 EXPORT void tfhe_bootstrap_FFT(LweSample *result,
214                                const LweBootstrappingKeyFFT *bk,
215                                Torus32 mu,
216                                const LweSample *x) {
217 
218     LweSample *u = new_LweSample(&bk->accum_params->extracted_lweparams);
219 
220     tfhe_bootstrap_woKS_FFT(u, bk, mu, x);
221     // Key switching
222     lweKeySwitch(result, bk->ks, u);
223 
224     delete_LweSample(u);
225 }
226 #endif
227 
228 
229 
230 
231 
232 
233 
234 
235 
236 
237 
238 
239 
240 
241 
242 
243 //allocate memory space for a LweBootstrappingKeyFFT
244 
alloc_LweBootstrappingKeyFFT()245 EXPORT LweBootstrappingKeyFFT *alloc_LweBootstrappingKeyFFT() {
246     return (LweBootstrappingKeyFFT *) malloc(sizeof(LweBootstrappingKeyFFT));
247 }
alloc_LweBootstrappingKeyFFT_array(int32_t nbelts)248 EXPORT LweBootstrappingKeyFFT *alloc_LweBootstrappingKeyFFT_array(int32_t nbelts) {
249     return (LweBootstrappingKeyFFT *) malloc(nbelts * sizeof(LweBootstrappingKeyFFT));
250 }
251 
252 //free memory space for a LweKey
free_LweBootstrappingKeyFFT(LweBootstrappingKeyFFT * ptr)253 EXPORT void free_LweBootstrappingKeyFFT(LweBootstrappingKeyFFT *ptr) {
254     free(ptr);
255 }
free_LweBootstrappingKeyFFT_array(int32_t nbelts,LweBootstrappingKeyFFT * ptr)256 EXPORT void free_LweBootstrappingKeyFFT_array(int32_t nbelts, LweBootstrappingKeyFFT *ptr) {
257     free(ptr);
258 }
259 
260 //initialize the key structure
261 
init_LweBootstrappingKeyFFT_array(int32_t nbelts,LweBootstrappingKeyFFT * obj,const LweBootstrappingKey * bk)262 EXPORT void init_LweBootstrappingKeyFFT_array(int32_t nbelts, LweBootstrappingKeyFFT *obj, const LweBootstrappingKey *bk) {
263     for (int32_t i = 0; i < nbelts; i++) {
264         init_LweBootstrappingKeyFFT(obj + i, bk);
265     }
266 }
267 
268 
destroy_LweBootstrappingKeyFFT_array(int32_t nbelts,LweBootstrappingKeyFFT * obj)269 EXPORT void destroy_LweBootstrappingKeyFFT_array(int32_t nbelts, LweBootstrappingKeyFFT *obj) {
270     for (int32_t i = 0; i < nbelts; i++) {
271         destroy_LweBootstrappingKeyFFT(obj + i);
272     }
273 }
274 
275 //allocates and initialize the LweBootstrappingKeyFFT structure
276 //(equivalent of the C++ new)
new_LweBootstrappingKeyFFT(const LweBootstrappingKey * bk)277 EXPORT LweBootstrappingKeyFFT *new_LweBootstrappingKeyFFT(const LweBootstrappingKey *bk) {
278     LweBootstrappingKeyFFT *obj = alloc_LweBootstrappingKeyFFT();
279     init_LweBootstrappingKeyFFT(obj, bk);
280     return obj;
281 }
new_LweBootstrappingKeyFFT_array(int32_t nbelts,const LweBootstrappingKey * bk)282 EXPORT LweBootstrappingKeyFFT *new_LweBootstrappingKeyFFT_array(int32_t nbelts, const LweBootstrappingKey *bk) {
283     LweBootstrappingKeyFFT *obj = alloc_LweBootstrappingKeyFFT_array(nbelts);
284     init_LweBootstrappingKeyFFT_array(nbelts, obj, bk);
285     return obj;
286 }
287 
288 //destroys and frees the LweBootstrappingKeyFFT structure
289 //(equivalent of the C++ delete)
delete_LweBootstrappingKeyFFT(LweBootstrappingKeyFFT * obj)290 EXPORT void delete_LweBootstrappingKeyFFT(LweBootstrappingKeyFFT *obj) {
291     destroy_LweBootstrappingKeyFFT(obj);
292     free_LweBootstrappingKeyFFT(obj);
293 }
delete_LweBootstrappingKeyFFT_array(int32_t nbelts,LweBootstrappingKeyFFT * obj)294 EXPORT void delete_LweBootstrappingKeyFFT_array(int32_t nbelts, LweBootstrappingKeyFFT *obj) {
295     destroy_LweBootstrappingKeyFFT_array(nbelts, obj);
296     free_LweBootstrappingKeyFFT_array(nbelts, obj);
297 }
298 
299 
300 
301 
302 
303 
304