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