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