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 elem::{GetRow, Infos, SetMetaData, SetRow};
 15pub use fourier_glwe::{FourierGLWECiphertext, FourierGLWESecret};
 16pub use gglwe::{GGLWECiphertext, GLWEAutomorphismKey, GLWESwitchingKey, GLWETensorKey};
 17pub use ggsw::GGSWCiphertext;
 18pub use glwe::{GLWECiphertext, GLWEOps, GLWEPacker, GLWEPlaintext, GLWEPublicKey, GLWESecret};
 19pub(crate) use glwe::{GLWECiphertextToMut, GLWECiphertextToRef};
 20pub use lwe::{LWECiphertext, LWESecret};
 21
 22pub use backend::Scratch;
 23pub use backend::ScratchOwned;
 24
 25use crate::dist::Distribution;
 26
 27pub(crate) const SIX_SIGMA: f64 = 6.0;
 28
 29pub trait ScratchCore<B: Backend> {
 30    fn tmp_glwe_ct(&mut self, module: &Module<B>, basek: usize, k: usize, rank: usize) -> (GLWECiphertext<&mut [u8]>, &mut Self);
 31    fn tmp_glwe_pt(&mut self, module: &Module<B>, basek: usize, k: usize) -> (GLWEPlaintext<&mut [u8]>, &mut Self);
 32    fn tmp_gglwe(
 33        &mut self,
 34        module: &Module<B>,
 35        basek: usize,
 36        k: usize,
 37        rows: usize,
 38        digits: usize,
 39        rank_in: usize,
 40        rank_out: usize,
 41    ) -> (GGLWECiphertext<&mut [u8], B>, &mut Self);
 42    fn tmp_ggsw(
 43        &mut self,
 44        module: &Module<B>,
 45        basek: usize,
 46        k: usize,
 47        rows: usize,
 48        digits: usize,
 49        rank: usize,
 50    ) -> (GGSWCiphertext<&mut [u8], B>, &mut Self);
 51    fn tmp_glwe_fourier(
 52        &mut self,
 53        module: &Module<B>,
 54        basek: usize,
 55        k: usize,
 56        rank: usize,
 57    ) -> (FourierGLWECiphertext<&mut [u8], B>, &mut Self);
 58    fn tmp_sk(&mut self, module: &Module<B>, rank: usize) -> (GLWESecret<&mut [u8]>, &mut Self);
 59    fn tmp_fourier_sk(&mut self, module: &Module<B>, rank: usize) -> (FourierGLWESecret<&mut [u8], B>, &mut Self);
 60    fn tmp_glwe_pk(
 61        &mut self,
 62        module: &Module<B>,
 63        basek: usize,
 64        k: usize,
 65        rank: usize,
 66    ) -> (GLWEPublicKey<&mut [u8], B>, &mut Self);
 67    fn tmp_glwe_ksk(
 68        &mut self,
 69        module: &Module<B>,
 70        basek: usize,
 71        k: usize,
 72        rows: usize,
 73        digits: usize,
 74        rank_in: usize,
 75        rank_out: usize,
 76    ) -> (GLWESwitchingKey<&mut [u8], B>, &mut Self);
 77    fn tmp_tsk(
 78        &mut self,
 79        module: &Module<B>,
 80        basek: usize,
 81        k: usize,
 82        rows: usize,
 83        digits: usize,
 84        rank: usize,
 85    ) -> (GLWETensorKey<&mut [u8], B>, &mut Self);
 86    fn tmp_autokey(
 87        &mut self,
 88        module: &Module<B>,
 89        basek: usize,
 90        k: usize,
 91        rows: usize,
 92        digits: usize,
 93        rank: usize,
 94    ) -> (GLWEAutomorphismKey<&mut [u8], B>, &mut Self);
 95}
 96
 97impl ScratchCore<FFT64> for Scratch {
 98    fn tmp_glwe_ct(
 99        &mut self,
100        module: &Module<FFT64>,
101        basek: usize,
102        k: usize,
103        rank: usize,
104    ) -> (GLWECiphertext<&mut [u8]>, &mut Self) {
105        let (data, scratch) = self.tmp_vec_znx(module, rank + 1, k.div_ceil(basek));
106        (GLWECiphertext { data, basek, k }, scratch)
107    }
108
109    fn tmp_glwe_pt(&mut self, module: &Module<FFT64>, basek: usize, k: usize) -> (GLWEPlaintext<&mut [u8]>, &mut Self) {
110        let (data, scratch) = self.tmp_vec_znx(module, 1, k.div_ceil(basek));
111        (GLWEPlaintext { data, basek, k }, scratch)
112    }
113
114    fn tmp_gglwe(
115        &mut self,
116        module: &Module<FFT64>,
117        basek: usize,
118        k: usize,
119        rows: usize,
120        digits: usize,
121        rank_in: usize,
122        rank_out: usize,
123    ) -> (GGLWECiphertext<&mut [u8], FFT64>, &mut Self) {
124        let (data, scratch) = self.tmp_mat_znx_dft(
125            module,
126            rows.div_ceil(digits),
127            rank_in,
128            rank_out + 1,
129            k.div_ceil(basek),
130        );
131        (
132            GGLWECiphertext {
133                data: data,
134                basek: basek,
135                k,
136                digits,
137            },
138            scratch,
139        )
140    }
141
142    fn tmp_ggsw(
143        &mut self,
144        module: &Module<FFT64>,
145        basek: usize,
146        k: usize,
147        rows: usize,
148        digits: usize,
149        rank: usize,
150    ) -> (GGSWCiphertext<&mut [u8], FFT64>, &mut Self) {
151        let (data, scratch) = self.tmp_mat_znx_dft(
152            module,
153            rows.div_ceil(digits),
154            rank + 1,
155            rank + 1,
156            k.div_ceil(basek),
157        );
158        (
159            GGSWCiphertext {
160                data,
161                basek,
162                k,
163                digits,
164            },
165            scratch,
166        )
167    }
168
169    fn tmp_glwe_fourier(
170        &mut self,
171        module: &Module<FFT64>,
172        basek: usize,
173        k: usize,
174        rank: usize,
175    ) -> (FourierGLWECiphertext<&mut [u8], FFT64>, &mut Self) {
176        let (data, scratch) = self.tmp_vec_znx_dft(module, rank + 1, k.div_ceil(basek));
177        (FourierGLWECiphertext { data, basek, k }, scratch)
178    }
179
180    fn tmp_glwe_pk(
181        &mut self,
182        module: &Module<FFT64>,
183        basek: usize,
184        k: usize,
185        rank: usize,
186    ) -> (GLWEPublicKey<&mut [u8], FFT64>, &mut Self) {
187        let (data, scratch) = self.tmp_glwe_fourier(module, basek, k, rank);
188        (
189            GLWEPublicKey {
190                data,
191                dist: Distribution::NONE,
192            },
193            scratch,
194        )
195    }
196
197    fn tmp_sk(&mut self, module: &Module<FFT64>, rank: usize) -> (GLWESecret<&mut [u8]>, &mut Self) {
198        let (data, scratch) = self.tmp_scalar_znx(module, rank);
199        (
200            GLWESecret {
201                data,
202                dist: Distribution::NONE,
203            },
204            scratch,
205        )
206    }
207
208    fn tmp_fourier_sk(&mut self, module: &Module<FFT64>, rank: usize) -> (FourierGLWESecret<&mut [u8], FFT64>, &mut Self) {
209        let (data, scratch) = self.tmp_scalar_znx_dft(module, rank);
210        (
211            FourierGLWESecret {
212                data,
213                dist: Distribution::NONE,
214            },
215            scratch,
216        )
217    }
218
219    fn tmp_glwe_ksk(
220        &mut self,
221        module: &Module<FFT64>,
222        basek: usize,
223        k: usize,
224        rows: usize,
225        digits: usize,
226        rank_in: usize,
227        rank_out: usize,
228    ) -> (GLWESwitchingKey<&mut [u8], FFT64>, &mut Self) {
229        let (data, scratch) = self.tmp_gglwe(module, basek, k, rows, digits, rank_in, rank_out);
230        (GLWESwitchingKey(data), scratch)
231    }
232
233    fn tmp_autokey(
234        &mut self,
235        module: &Module<FFT64>,
236        basek: usize,
237        k: usize,
238        rows: usize,
239        digits: usize,
240        rank: usize,
241    ) -> (GLWEAutomorphismKey<&mut [u8], FFT64>, &mut Self) {
242        let (data, scratch) = self.tmp_glwe_ksk(module, basek, k, rows, digits, rank, rank);
243        (GLWEAutomorphismKey { key: data, p: 0 }, scratch)
244    }
245
246    fn tmp_tsk(
247        &mut self,
248        module: &Module<FFT64>,
249        basek: usize,
250        k: usize,
251        rows: usize,
252        digits: usize,
253        rank: usize,
254    ) -> (GLWETensorKey<&mut [u8], FFT64>, &mut Self) {
255        let mut keys: Vec<GLWESwitchingKey<&mut [u8], FFT64>> = Vec::new();
256        let pairs: usize = (((rank + 1) * rank) >> 1).max(1);
257
258        let mut scratch: &mut Scratch = self;
259
260        if pairs != 0 {
261            let (gglwe, s) = scratch.tmp_glwe_ksk(module, basek, k, rows, digits, 1, rank);
262            scratch = s;
263            keys.push(gglwe);
264        }
265        for _ in 1..pairs {
266            let (gglwe, s) = scratch.tmp_glwe_ksk(module, basek, k, rows, digits, 1, rank);
267            scratch = s;
268            keys.push(gglwe);
269        }
270        (GLWETensorKey { keys }, scratch)
271    }
272}