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