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_vec_glwe_ct(
32 &mut self,
33 size: usize,
34 module: &Module<B>,
35 basek: usize,
36 k: usize,
37 rank: usize,
38 ) -> (Vec<GLWECiphertext<&mut [u8]>>, &mut Self);
39 fn tmp_glwe_pt(&mut self, module: &Module<B>, basek: usize, k: usize) -> (GLWEPlaintext<&mut [u8]>, &mut Self);
40 fn tmp_gglwe(
41 &mut self,
42 module: &Module<B>,
43 basek: usize,
44 k: usize,
45 rows: usize,
46 digits: usize,
47 rank_in: usize,
48 rank_out: usize,
49 ) -> (GGLWECiphertext<&mut [u8], B>, &mut Self);
50 fn tmp_ggsw(
51 &mut self,
52 module: &Module<B>,
53 basek: usize,
54 k: usize,
55 rows: usize,
56 digits: usize,
57 rank: usize,
58 ) -> (GGSWCiphertext<&mut [u8], B>, &mut Self);
59 fn tmp_fourier_glwe_ct(
60 &mut self,
61 module: &Module<B>,
62 basek: usize,
63 k: usize,
64 rank: usize,
65 ) -> (FourierGLWECiphertext<&mut [u8], B>, &mut Self);
66 fn tmp_slice_fourier_glwe_ct(
67 &mut self,
68 size: usize,
69 module: &Module<B>,
70 basek: usize,
71 k: usize,
72 rank: usize,
73 ) -> (Vec<FourierGLWECiphertext<&mut [u8], B>>, &mut Self);
74 fn tmp_glwe_secret(&mut self, module: &Module<B>, rank: usize) -> (GLWESecret<&mut [u8]>, &mut Self);
75 fn tmp_fourier_glwe_secret(&mut self, module: &Module<B>, rank: usize) -> (FourierGLWESecret<&mut [u8], B>, &mut Self);
76 fn tmp_glwe_pk(
77 &mut self,
78 module: &Module<B>,
79 basek: usize,
80 k: usize,
81 rank: usize,
82 ) -> (GLWEPublicKey<&mut [u8], B>, &mut Self);
83 fn tmp_glwe_ksk(
84 &mut self,
85 module: &Module<B>,
86 basek: usize,
87 k: usize,
88 rows: usize,
89 digits: usize,
90 rank_in: usize,
91 rank_out: usize,
92 ) -> (GLWESwitchingKey<&mut [u8], B>, &mut Self);
93 fn tmp_tsk(
94 &mut self,
95 module: &Module<B>,
96 basek: usize,
97 k: usize,
98 rows: usize,
99 digits: usize,
100 rank: usize,
101 ) -> (GLWETensorKey<&mut [u8], B>, &mut Self);
102 fn tmp_autokey(
103 &mut self,
104 module: &Module<B>,
105 basek: usize,
106 k: usize,
107 rows: usize,
108 digits: usize,
109 rank: usize,
110 ) -> (GLWEAutomorphismKey<&mut [u8], B>, &mut Self);
111}
112
113impl ScratchCore<FFT64> for Scratch {
114 fn tmp_glwe_ct(
115 &mut self,
116 module: &Module<FFT64>,
117 basek: usize,
118 k: usize,
119 rank: usize,
120 ) -> (GLWECiphertext<&mut [u8]>, &mut Self) {
121 let (data, scratch) = self.tmp_vec_znx(module, rank + 1, k.div_ceil(basek));
122 (GLWECiphertext { data, basek, k }, scratch)
123 }
124
125 fn tmp_vec_glwe_ct(
126 &mut self,
127 size: usize,
128 module: &Module<FFT64>,
129 basek: usize,
130 k: usize,
131 rank: usize,
132 ) -> (Vec<GLWECiphertext<&mut [u8]>>, &mut Self) {
133 let mut scratch: &mut Scratch = self;
134 let mut cts: Vec<GLWECiphertext<&mut [u8]>> = Vec::with_capacity(size);
135 for _ in 0..size {
136 let (ct, new_scratch) = scratch.tmp_glwe_ct(module, basek, k, rank);
137 scratch = new_scratch;
138 cts.push(ct);
139 }
140 (cts, scratch)
141 }
142
143 fn tmp_glwe_pt(&mut self, module: &Module<FFT64>, basek: usize, k: usize) -> (GLWEPlaintext<&mut [u8]>, &mut Self) {
144 let (data, scratch) = self.tmp_vec_znx(module, 1, k.div_ceil(basek));
145 (GLWEPlaintext { data, basek, k }, scratch)
146 }
147
148 fn tmp_gglwe(
149 &mut self,
150 module: &Module<FFT64>,
151 basek: usize,
152 k: usize,
153 rows: usize,
154 digits: usize,
155 rank_in: usize,
156 rank_out: usize,
157 ) -> (GGLWECiphertext<&mut [u8], FFT64>, &mut Self) {
158 let (data, scratch) = self.tmp_mat_znx_dft(
159 module,
160 rows.div_ceil(digits),
161 rank_in,
162 rank_out + 1,
163 k.div_ceil(basek),
164 );
165 (
166 GGLWECiphertext {
167 data: data,
168 basek: basek,
169 k,
170 digits,
171 },
172 scratch,
173 )
174 }
175
176 fn tmp_ggsw(
177 &mut self,
178 module: &Module<FFT64>,
179 basek: usize,
180 k: usize,
181 rows: usize,
182 digits: usize,
183 rank: usize,
184 ) -> (GGSWCiphertext<&mut [u8], FFT64>, &mut Self) {
185 let (data, scratch) = self.tmp_mat_znx_dft(
186 module,
187 rows.div_ceil(digits),
188 rank + 1,
189 rank + 1,
190 k.div_ceil(basek),
191 );
192 (
193 GGSWCiphertext {
194 data,
195 basek,
196 k,
197 digits,
198 },
199 scratch,
200 )
201 }
202
203 fn tmp_fourier_glwe_ct(
204 &mut self,
205 module: &Module<FFT64>,
206 basek: usize,
207 k: usize,
208 rank: usize,
209 ) -> (FourierGLWECiphertext<&mut [u8], FFT64>, &mut Self) {
210 let (data, scratch) = self.tmp_vec_znx_dft(module, rank + 1, k.div_ceil(basek));
211 (FourierGLWECiphertext { data, basek, k }, scratch)
212 }
213
214 fn tmp_slice_fourier_glwe_ct(
215 &mut self,
216 size: usize,
217 module: &Module<FFT64>,
218 basek: usize,
219 k: usize,
220 rank: usize,
221 ) -> (Vec<FourierGLWECiphertext<&mut [u8], FFT64>>, &mut Self) {
222 let mut scratch: &mut Scratch = self;
223 let mut cts: Vec<FourierGLWECiphertext<&mut [u8], FFT64>> = Vec::with_capacity(size);
224 for _ in 0..size {
225 let (ct, new_scratch) = scratch.tmp_fourier_glwe_ct(module, basek, k, rank);
226 scratch = new_scratch;
227 cts.push(ct);
228 }
229 (cts, scratch)
230 }
231
232 fn tmp_glwe_pk(
233 &mut self,
234 module: &Module<FFT64>,
235 basek: usize,
236 k: usize,
237 rank: usize,
238 ) -> (GLWEPublicKey<&mut [u8], FFT64>, &mut Self) {
239 let (data, scratch) = self.tmp_fourier_glwe_ct(module, basek, k, rank);
240 (
241 GLWEPublicKey {
242 data,
243 dist: Distribution::NONE,
244 },
245 scratch,
246 )
247 }
248
249 fn tmp_glwe_secret(&mut self, module: &Module<FFT64>, rank: usize) -> (GLWESecret<&mut [u8]>, &mut Self) {
250 let (data, scratch) = self.tmp_scalar_znx(module, rank);
251 (
252 GLWESecret {
253 data,
254 dist: Distribution::NONE,
255 },
256 scratch,
257 )
258 }
259
260 fn tmp_fourier_glwe_secret(
261 &mut self,
262 module: &Module<FFT64>,
263 rank: usize,
264 ) -> (FourierGLWESecret<&mut [u8], FFT64>, &mut Self) {
265 let (data, scratch) = self.tmp_scalar_znx_dft(module, rank);
266 (
267 FourierGLWESecret {
268 data,
269 dist: Distribution::NONE,
270 },
271 scratch,
272 )
273 }
274
275 fn tmp_glwe_ksk(
276 &mut self,
277 module: &Module<FFT64>,
278 basek: usize,
279 k: usize,
280 rows: usize,
281 digits: usize,
282 rank_in: usize,
283 rank_out: usize,
284 ) -> (GLWESwitchingKey<&mut [u8], FFT64>, &mut Self) {
285 let (data, scratch) = self.tmp_gglwe(module, basek, k, rows, digits, rank_in, rank_out);
286 (
287 GLWESwitchingKey {
288 key: data,
289 sk_in_n: 0,
290 sk_out_n: 0,
291 },
292 scratch,
293 )
294 }
295
296 fn tmp_autokey(
297 &mut self,
298 module: &Module<FFT64>,
299 basek: usize,
300 k: usize,
301 rows: usize,
302 digits: usize,
303 rank: usize,
304 ) -> (GLWEAutomorphismKey<&mut [u8], FFT64>, &mut Self) {
305 let (data, scratch) = self.tmp_glwe_ksk(module, basek, k, rows, digits, rank, rank);
306 (GLWEAutomorphismKey { key: data, p: 0 }, scratch)
307 }
308
309 fn tmp_tsk(
310 &mut self,
311 module: &Module<FFT64>,
312 basek: usize,
313 k: usize,
314 rows: usize,
315 digits: usize,
316 rank: usize,
317 ) -> (GLWETensorKey<&mut [u8], FFT64>, &mut Self) {
318 let mut keys: Vec<GLWESwitchingKey<&mut [u8], FFT64>> = Vec::new();
319 let pairs: usize = (((rank + 1) * rank) >> 1).max(1);
320
321 let mut scratch: &mut Scratch = self;
322
323 if pairs != 0 {
324 let (gglwe, s) = scratch.tmp_glwe_ksk(module, basek, k, rows, digits, 1, rank);
325 scratch = s;
326 keys.push(gglwe);
327 }
328 for _ in 1..pairs {
329 let (gglwe, s) = scratch.tmp_glwe_ksk(module, basek, k, rows, digits, 1, rank);
330 scratch = s;
331 keys.push(gglwe);
332 }
333 (GLWETensorKey { keys }, scratch)
334 }
335}