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}