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::derive_size;
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 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 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 rank_in: usize,
82 rank_out: usize,
83 ) -> (GLWESwitchingKey<&mut [u8], B>, &mut Self);
84 fn tmp_tsk(
85 &mut self,
86 module: &Module<B>,
87 basek: usize,
88 k: usize,
89 rows: 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 rank: usize,
99 ) -> (AutomorphismKey<&mut [u8], B>, &mut Self);
100}
101
102impl ScratchCore<FFT64> for Scratch {
103 fn tmp_glwe_ct(
104 &mut self,
105 module: &Module<FFT64>,
106 basek: usize,
107 k: usize,
108 rank: usize,
109 ) -> (GLWECiphertext<&mut [u8]>, &mut Self) {
110 let (data, scratch) = self.tmp_vec_znx(module, rank + 1, derive_size(basek, k));
111 (GLWECiphertext { data, basek, k }, scratch)
112 }
113
114 fn tmp_glwe_pt(&mut self, module: &Module<FFT64>, basek: usize, k: usize) -> (GLWEPlaintext<&mut [u8]>, &mut Self) {
115 let (data, scratch) = self.tmp_vec_znx(module, 1, derive_size(basek, k));
116 (GLWEPlaintext { data, basek, k }, scratch)
117 }
118
119 fn tmp_gglwe(
120 &mut self,
121 module: &Module<FFT64>,
122 basek: usize,
123 k: usize,
124 rows: usize,
125 rank_in: usize,
126 rank_out: usize,
127 ) -> (GGLWECiphertext<&mut [u8], FFT64>, &mut Self) {
128 let (data, scratch) = self.tmp_mat_znx_dft(module, rows, rank_in, rank_out + 1, derive_size(basek, k));
129 (
130 GGLWECiphertext {
131 data: data,
132 basek: basek,
133 k,
134 },
135 scratch,
136 )
137 }
138
139 fn tmp_ggsw(
140 &mut self,
141 module: &Module<FFT64>,
142 basek: usize,
143 k: usize,
144 rows: usize,
145 rank: usize,
146 ) -> (GGSWCiphertext<&mut [u8], FFT64>, &mut Self) {
147 let (data, scratch) = self.tmp_mat_znx_dft(module, rows, rank + 1, rank + 1, derive_size(basek, k));
148 (
149 GGSWCiphertext {
150 data: data,
151 basek: basek,
152 k,
153 },
154 scratch,
155 )
156 }
157
158 fn tmp_glwe_fourier(
159 &mut self,
160 module: &Module<FFT64>,
161 basek: usize,
162 k: usize,
163 rank: usize,
164 ) -> (GLWECiphertextFourier<&mut [u8], FFT64>, &mut Self) {
165 let (data, scratch) = self.tmp_vec_znx_dft(module, rank + 1, derive_size(basek, k));
166 (GLWECiphertextFourier { data, basek, k }, scratch)
167 }
168
169 fn tmp_glwe_pk(
170 &mut self,
171 module: &Module<FFT64>,
172 basek: usize,
173 k: usize,
174 rank: usize,
175 ) -> (GLWEPublicKey<&mut [u8], FFT64>, &mut Self) {
176 let (data, scratch) = self.tmp_glwe_fourier(module, basek, k, rank);
177 (
178 GLWEPublicKey {
179 data,
180 dist: SecretDistribution::NONE,
181 },
182 scratch,
183 )
184 }
185
186 fn tmp_sk(&mut self, module: &Module<FFT64>, rank: usize) -> (GLWESecret<&mut [u8], FFT64>, &mut Self) {
187 let (data, scratch) = self.tmp_scalar_znx(module, rank);
188 let (data_fourier, scratch1) = scratch.tmp_scalar_znx_dft(module, rank);
189 (
190 GLWESecret {
191 data,
192 data_fourier,
193 dist: SecretDistribution::NONE,
194 },
195 scratch1,
196 )
197 }
198
199 fn tmp_glwe_ksk(
200 &mut self,
201 module: &Module<FFT64>,
202 basek: usize,
203 k: usize,
204 rows: usize,
205 rank_in: usize,
206 rank_out: usize,
207 ) -> (GLWESwitchingKey<&mut [u8], FFT64>, &mut Self) {
208 let (data, scratch) = self.tmp_gglwe(module, basek, k, rows, rank_in, rank_out);
209 (GLWESwitchingKey(data), scratch)
210 }
211
212 fn tmp_autokey(
213 &mut self,
214 module: &Module<FFT64>,
215 basek: usize,
216 k: usize,
217 rows: usize,
218 rank: usize,
219 ) -> (AutomorphismKey<&mut [u8], FFT64>, &mut Self) {
220 let (data, scratch) = self.tmp_glwe_ksk(module, basek, k, rows, rank, rank);
221 (AutomorphismKey { key: data, p: 0 }, scratch)
222 }
223
224 fn tmp_tsk(
225 &mut self,
226 module: &Module<FFT64>,
227 basek: usize,
228 k: usize,
229 rows: usize,
230 rank: usize,
231 ) -> (TensorKey<&mut [u8], FFT64>, &mut Self) {
232 let mut keys: Vec<GLWESwitchingKey<&mut [u8], FFT64>> = Vec::new();
233 let pairs: usize = (((rank + 1) * rank) >> 1).max(1);
234
235 let mut scratch: &mut Scratch = self;
236
237 if pairs != 0 {
238 let (gglwe, s) = scratch.tmp_glwe_ksk(module, basek, k, rows, 1, rank);
239 scratch = s;
240 keys.push(gglwe);
241 }
242 for _ in 1..pairs {
243 let (gglwe, s) = scratch.tmp_glwe_ksk(module, basek, k, rows, 1, rank);
244 scratch = s;
245 keys.push(gglwe);
246 }
247 (TensorKey { keys }, scratch)
248 }
249}