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