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