arnaucube
arnaucube/poulpyPublic Self-hosted repository
poulpy/core/src/lib.rs
core/src/lib.rsRaw
  1pub mod blind_rotation;
  2pub mod dist;
  3pub mod elem;
  4pub mod fourier_glwe;
  5pub mod gglwe;
  6pub mod ggsw;
  7pub mod glwe;
  8pub mod lwe;
  9pub mod noise;
 10
 11use backend::Backend;
 12use backend::FFT64;
 13use backend::Module;
 14pub use blind_rotation::{BlindRotationKeyCGGI, LookUpTable, cggi_blind_rotate, cggi_blind_rotate_scratch_space};
 15pub use elem::{GetRow, Infos, SetMetaData, SetRow};
 16pub use fourier_glwe::{FourierGLWECiphertext, FourierGLWESecret};
 17pub use gglwe::{GGLWECiphertext, GLWEAutomorphismKey, GLWESwitchingKey, GLWETensorKey};
 18pub use ggsw::GGSWCiphertext;
 19pub use glwe::{GLWECiphertext, GLWEOps, GLWEPacker, GLWEPlaintext, GLWEPublicKey, GLWESecret};
 20pub use lwe::{LWECiphertext, LWESecret};
 21
 22pub(crate) use glwe::{GLWECiphertextToMut, GLWECiphertextToRef};
 23
 24pub use backend::Scratch;
 25pub use backend::ScratchOwned;
 26
 27use crate::dist::Distribution;
 28
 29pub(crate) const SIX_SIGMA: f64 = 6.0;
 30
 31pub trait ScratchCore<B: Backend> {
 32    fn tmp_glwe_ct(&mut self, module: &Module<B>, basek: usize, k: usize, rank: usize) -> (GLWECiphertext<&mut [u8]>, &mut Self);
 33    fn tmp_vec_glwe_ct(
 34        &mut self,
 35        size: usize,
 36        module: &Module<B>,
 37        basek: usize,
 38        k: usize,
 39        rank: usize,
 40    ) -> (Vec<GLWECiphertext<&mut [u8]>>, &mut Self);
 41    fn tmp_glwe_pt(&mut self, module: &Module<B>, basek: usize, k: usize) -> (GLWEPlaintext<&mut [u8]>, &mut Self);
 42    fn tmp_gglwe(
 43        &mut self,
 44        module: &Module<B>,
 45        basek: usize,
 46        k: usize,
 47        rows: usize,
 48        digits: usize,
 49        rank_in: usize,
 50        rank_out: usize,
 51    ) -> (GGLWECiphertext<&mut [u8], B>, &mut Self);
 52    fn tmp_ggsw(
 53        &mut self,
 54        module: &Module<B>,
 55        basek: usize,
 56        k: usize,
 57        rows: usize,
 58        digits: usize,
 59        rank: usize,
 60    ) -> (GGSWCiphertext<&mut [u8], B>, &mut Self);
 61    fn tmp_fourier_glwe_ct(
 62        &mut self,
 63        module: &Module<B>,
 64        basek: usize,
 65        k: usize,
 66        rank: usize,
 67    ) -> (FourierGLWECiphertext<&mut [u8], B>, &mut Self);
 68    fn tmp_slice_fourier_glwe_ct(
 69        &mut self,
 70        size: usize,
 71        module: &Module<B>,
 72        basek: usize,
 73        k: usize,
 74        rank: usize,
 75    ) -> (Vec<FourierGLWECiphertext<&mut [u8], B>>, &mut Self);
 76    fn tmp_glwe_secret(&mut self, module: &Module<B>, rank: usize) -> (GLWESecret<&mut [u8]>, &mut Self);
 77    fn tmp_fourier_glwe_secret(&mut self, module: &Module<B>, rank: usize) -> (FourierGLWESecret<&mut [u8], B>, &mut Self);
 78    fn tmp_glwe_pk(
 79        &mut self,
 80        module: &Module<B>,
 81        basek: usize,
 82        k: usize,
 83        rank: usize,
 84    ) -> (GLWEPublicKey<&mut [u8], B>, &mut Self);
 85    fn tmp_glwe_ksk(
 86        &mut self,
 87        module: &Module<B>,
 88        basek: usize,
 89        k: usize,
 90        rows: usize,
 91        digits: usize,
 92        rank_in: usize,
 93        rank_out: usize,
 94    ) -> (GLWESwitchingKey<&mut [u8], B>, &mut Self);
 95    fn tmp_tsk(
 96        &mut self,
 97        module: &Module<B>,
 98        basek: usize,
 99        k: usize,
100        rows: usize,
101        digits: usize,
102        rank: usize,
103    ) -> (GLWETensorKey<&mut [u8], B>, &mut Self);
104    fn tmp_autokey(
105        &mut self,
106        module: &Module<B>,
107        basek: usize,
108        k: usize,
109        rows: usize,
110        digits: usize,
111        rank: usize,
112    ) -> (GLWEAutomorphismKey<&mut [u8], B>, &mut Self);
113}
114
115impl ScratchCore<FFT64> for Scratch {
116    fn tmp_glwe_ct(
117        &mut self,
118        module: &Module<FFT64>,
119        basek: usize,
120        k: usize,
121        rank: usize,
122    ) -> (GLWECiphertext<&mut [u8]>, &mut Self) {
123        let (data, scratch) = self.tmp_vec_znx(module, rank + 1, k.div_ceil(basek));
124        (GLWECiphertext { data, basek, k }, scratch)
125    }
126
127    fn tmp_vec_glwe_ct(
128        &mut self,
129        size: usize,
130        module: &Module<FFT64>,
131        basek: usize,
132        k: usize,
133        rank: usize,
134    ) -> (Vec<GLWECiphertext<&mut [u8]>>, &mut Self) {
135        let mut scratch: &mut Scratch = self;
136        let mut cts: Vec<GLWECiphertext<&mut [u8]>> = Vec::with_capacity(size);
137        for _ in 0..size {
138            let (ct, new_scratch) = scratch.tmp_glwe_ct(module, basek, k, rank);
139            scratch = new_scratch;
140            cts.push(ct);
141        }
142        (cts, scratch)
143    }
144
145    fn tmp_glwe_pt(&mut self, module: &Module<FFT64>, basek: usize, k: usize) -> (GLWEPlaintext<&mut [u8]>, &mut Self) {
146        let (data, scratch) = self.tmp_vec_znx(module, 1, k.div_ceil(basek));
147        (GLWEPlaintext { data, basek, k }, scratch)
148    }
149
150    fn tmp_gglwe(
151        &mut self,
152        module: &Module<FFT64>,
153        basek: usize,
154        k: usize,
155        rows: usize,
156        digits: usize,
157        rank_in: usize,
158        rank_out: usize,
159    ) -> (GGLWECiphertext<&mut [u8], FFT64>, &mut Self) {
160        let (data, scratch) = self.tmp_mat_znx_dft(
161            module,
162            rows.div_ceil(digits),
163            rank_in,
164            rank_out + 1,
165            k.div_ceil(basek),
166        );
167        (
168            GGLWECiphertext {
169                data: data,
170                basek: basek,
171                k,
172                digits,
173            },
174            scratch,
175        )
176    }
177
178    fn tmp_ggsw(
179        &mut self,
180        module: &Module<FFT64>,
181        basek: usize,
182        k: usize,
183        rows: usize,
184        digits: usize,
185        rank: usize,
186    ) -> (GGSWCiphertext<&mut [u8], FFT64>, &mut Self) {
187        let (data, scratch) = self.tmp_mat_znx_dft(
188            module,
189            rows.div_ceil(digits),
190            rank + 1,
191            rank + 1,
192            k.div_ceil(basek),
193        );
194        (
195            GGSWCiphertext {
196                data,
197                basek,
198                k,
199                digits,
200            },
201            scratch,
202        )
203    }
204
205    fn tmp_fourier_glwe_ct(
206        &mut self,
207        module: &Module<FFT64>,
208        basek: usize,
209        k: usize,
210        rank: usize,
211    ) -> (FourierGLWECiphertext<&mut [u8], FFT64>, &mut Self) {
212        let (data, scratch) = self.tmp_vec_znx_dft(module, rank + 1, k.div_ceil(basek));
213        (FourierGLWECiphertext { data, basek, k }, scratch)
214    }
215
216    fn tmp_slice_fourier_glwe_ct(
217        &mut self,
218        size: usize,
219        module: &Module<FFT64>,
220        basek: usize,
221        k: usize,
222        rank: usize,
223    ) -> (Vec<FourierGLWECiphertext<&mut [u8], FFT64>>, &mut Self) {
224        let mut scratch: &mut Scratch = self;
225        let mut cts: Vec<FourierGLWECiphertext<&mut [u8], FFT64>> = Vec::with_capacity(size);
226        for _ in 0..size {
227            let (ct, new_scratch) = scratch.tmp_fourier_glwe_ct(module, basek, k, rank);
228            scratch = new_scratch;
229            cts.push(ct);
230        }
231        (cts, scratch)
232    }
233
234    fn tmp_glwe_pk(
235        &mut self,
236        module: &Module<FFT64>,
237        basek: usize,
238        k: usize,
239        rank: usize,
240    ) -> (GLWEPublicKey<&mut [u8], FFT64>, &mut Self) {
241        let (data, scratch) = self.tmp_fourier_glwe_ct(module, basek, k, rank);
242        (
243            GLWEPublicKey {
244                data,
245                dist: Distribution::NONE,
246            },
247            scratch,
248        )
249    }
250
251    fn tmp_glwe_secret(&mut self, module: &Module<FFT64>, rank: usize) -> (GLWESecret<&mut [u8]>, &mut Self) {
252        let (data, scratch) = self.tmp_scalar_znx(module, rank);
253        (
254            GLWESecret {
255                data,
256                dist: Distribution::NONE,
257            },
258            scratch,
259        )
260    }
261
262    fn tmp_fourier_glwe_secret(
263        &mut self,
264        module: &Module<FFT64>,
265        rank: usize,
266    ) -> (FourierGLWESecret<&mut [u8], FFT64>, &mut Self) {
267        let (data, scratch) = self.tmp_scalar_znx_dft(module, rank);
268        (
269            FourierGLWESecret {
270                data,
271                dist: Distribution::NONE,
272            },
273            scratch,
274        )
275    }
276
277    fn tmp_glwe_ksk(
278        &mut self,
279        module: &Module<FFT64>,
280        basek: usize,
281        k: usize,
282        rows: usize,
283        digits: usize,
284        rank_in: usize,
285        rank_out: usize,
286    ) -> (GLWESwitchingKey<&mut [u8], FFT64>, &mut Self) {
287        let (data, scratch) = self.tmp_gglwe(module, basek, k, rows, digits, rank_in, rank_out);
288        (
289            GLWESwitchingKey {
290                key: data,
291                sk_in_n: 0,
292                sk_out_n: 0,
293            },
294            scratch,
295        )
296    }
297
298    fn tmp_autokey(
299        &mut self,
300        module: &Module<FFT64>,
301        basek: usize,
302        k: usize,
303        rows: usize,
304        digits: usize,
305        rank: usize,
306    ) -> (GLWEAutomorphismKey<&mut [u8], FFT64>, &mut Self) {
307        let (data, scratch) = self.tmp_glwe_ksk(module, basek, k, rows, digits, rank, rank);
308        (GLWEAutomorphismKey { key: data, p: 0 }, scratch)
309    }
310
311    fn tmp_tsk(
312        &mut self,
313        module: &Module<FFT64>,
314        basek: usize,
315        k: usize,
316        rows: usize,
317        digits: usize,
318        rank: usize,
319    ) -> (GLWETensorKey<&mut [u8], FFT64>, &mut Self) {
320        let mut keys: Vec<GLWESwitchingKey<&mut [u8], FFT64>> = Vec::new();
321        let pairs: usize = (((rank + 1) * rank) >> 1).max(1);
322
323        let mut scratch: &mut Scratch = self;
324
325        if pairs != 0 {
326            let (gglwe, s) = scratch.tmp_glwe_ksk(module, basek, k, rows, digits, 1, rank);
327            scratch = s;
328            keys.push(gglwe);
329        }
330        for _ in 1..pairs {
331            let (gglwe, s) = scratch.tmp_glwe_ksk(module, basek, k, rows, digits, 1, rank);
332            scratch = s;
333            keys.push(gglwe);
334        }
335        (GLWETensorKey { keys }, scratch)
336    }
337}