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