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