poulpy/core/src/lib.rs
core/src/lib.rsRaw
1pub mod blind_rotation;
2pub mod dist;
3pub mod elem;
4pub mod fourier_glwe;
5pub mod gglwe;
6pub mod ggsw;
7pub mod glwe;
8pub mod lwe;
9pub mod noise;
10
11use backend::Backend;
12use backend::FFT64;
13use backend::Module;
14pub use elem::{GetRow, Infos, SetMetaData, SetRow};
15pub use fourier_glwe::{FourierGLWECiphertext, FourierGLWESecret};
16pub use gglwe::{GGLWECiphertext, GLWEAutomorphismKey, GLWESwitchingKey, GLWETensorKey};
17pub use ggsw::GGSWCiphertext;
18pub use glwe::{GLWECiphertext, GLWEOps, GLWEPacker, GLWEPlaintext, GLWEPublicKey, GLWESecret};
19pub(crate) use glwe::{GLWECiphertextToMut, GLWECiphertextToRef};
20pub use lwe::{LWECiphertext, LWESecret};
21
22pub use backend::Scratch;
23pub use backend::ScratchOwned;
24
25use crate::dist::Distribution;
26
27pub(crate) const SIX_SIGMA: f64 = 6.0;
28
29pub trait ScratchCore<B: Backend> {
30 fn tmp_glwe_ct(&mut self, module: &Module<B>, basek: usize, k: usize, rank: usize) -> (GLWECiphertext<&mut [u8]>, &mut Self);
31 fn tmp_glwe_pt(&mut self, module: &Module<B>, basek: usize, k: usize) -> (GLWEPlaintext<&mut [u8]>, &mut Self);
32 fn tmp_gglwe(
33 &mut self,
34 module: &Module<B>,
35 basek: usize,
36 k: usize,
37 rows: usize,
38 digits: usize,
39 rank_in: usize,
40 rank_out: usize,
41 ) -> (GGLWECiphertext<&mut [u8], B>, &mut Self);
42 fn tmp_ggsw(
43 &mut self,
44 module: &Module<B>,
45 basek: usize,
46 k: usize,
47 rows: usize,
48 digits: usize,
49 rank: usize,
50 ) -> (GGSWCiphertext<&mut [u8], B>, &mut Self);
51 fn tmp_glwe_fourier(
52 &mut self,
53 module: &Module<B>,
54 basek: usize,
55 k: usize,
56 rank: usize,
57 ) -> (FourierGLWECiphertext<&mut [u8], B>, &mut Self);
58 fn tmp_sk(&mut self, module: &Module<B>, rank: usize) -> (GLWESecret<&mut [u8]>, &mut Self);
59 fn tmp_fourier_sk(&mut self, module: &Module<B>, rank: usize) -> (FourierGLWESecret<&mut [u8], B>, &mut Self);
60 fn tmp_glwe_pk(
61 &mut self,
62 module: &Module<B>,
63 basek: usize,
64 k: usize,
65 rank: usize,
66 ) -> (GLWEPublicKey<&mut [u8], B>, &mut Self);
67 fn tmp_glwe_ksk(
68 &mut self,
69 module: &Module<B>,
70 basek: usize,
71 k: usize,
72 rows: usize,
73 digits: usize,
74 rank_in: usize,
75 rank_out: usize,
76 ) -> (GLWESwitchingKey<&mut [u8], B>, &mut Self);
77 fn tmp_tsk(
78 &mut self,
79 module: &Module<B>,
80 basek: usize,
81 k: usize,
82 rows: usize,
83 digits: usize,
84 rank: usize,
85 ) -> (GLWETensorKey<&mut [u8], B>, &mut Self);
86 fn tmp_autokey(
87 &mut self,
88 module: &Module<B>,
89 basek: usize,
90 k: usize,
91 rows: usize,
92 digits: usize,
93 rank: usize,
94 ) -> (GLWEAutomorphismKey<&mut [u8], B>, &mut Self);
95}
96
97impl ScratchCore<FFT64> for Scratch {
98 fn tmp_glwe_ct(
99 &mut self,
100 module: &Module<FFT64>,
101 basek: usize,
102 k: usize,
103 rank: usize,
104 ) -> (GLWECiphertext<&mut [u8]>, &mut Self) {
105 let (data, scratch) = self.tmp_vec_znx(module, rank + 1, k.div_ceil(basek));
106 (GLWECiphertext { data, basek, k }, scratch)
107 }
108
109 fn tmp_glwe_pt(&mut self, module: &Module<FFT64>, basek: usize, k: usize) -> (GLWEPlaintext<&mut [u8]>, &mut Self) {
110 let (data, scratch) = self.tmp_vec_znx(module, 1, k.div_ceil(basek));
111 (GLWEPlaintext { data, basek, k }, scratch)
112 }
113
114 fn tmp_gglwe(
115 &mut self,
116 module: &Module<FFT64>,
117 basek: usize,
118 k: usize,
119 rows: usize,
120 digits: usize,
121 rank_in: usize,
122 rank_out: usize,
123 ) -> (GGLWECiphertext<&mut [u8], FFT64>, &mut Self) {
124 let (data, scratch) = self.tmp_mat_znx_dft(
125 module,
126 rows.div_ceil(digits),
127 rank_in,
128 rank_out + 1,
129 k.div_ceil(basek),
130 );
131 (
132 GGLWECiphertext {
133 data: data,
134 basek: basek,
135 k,
136 digits,
137 },
138 scratch,
139 )
140 }
141
142 fn tmp_ggsw(
143 &mut self,
144 module: &Module<FFT64>,
145 basek: usize,
146 k: usize,
147 rows: usize,
148 digits: usize,
149 rank: usize,
150 ) -> (GGSWCiphertext<&mut [u8], FFT64>, &mut Self) {
151 let (data, scratch) = self.tmp_mat_znx_dft(
152 module,
153 rows.div_ceil(digits),
154 rank + 1,
155 rank + 1,
156 k.div_ceil(basek),
157 );
158 (
159 GGSWCiphertext {
160 data,
161 basek,
162 k,
163 digits,
164 },
165 scratch,
166 )
167 }
168
169 fn tmp_glwe_fourier(
170 &mut self,
171 module: &Module<FFT64>,
172 basek: usize,
173 k: usize,
174 rank: usize,
175 ) -> (FourierGLWECiphertext<&mut [u8], FFT64>, &mut Self) {
176 let (data, scratch) = self.tmp_vec_znx_dft(module, rank + 1, k.div_ceil(basek));
177 (FourierGLWECiphertext { data, basek, k }, scratch)
178 }
179
180 fn tmp_glwe_pk(
181 &mut self,
182 module: &Module<FFT64>,
183 basek: usize,
184 k: usize,
185 rank: usize,
186 ) -> (GLWEPublicKey<&mut [u8], FFT64>, &mut Self) {
187 let (data, scratch) = self.tmp_glwe_fourier(module, basek, k, rank);
188 (
189 GLWEPublicKey {
190 data,
191 dist: Distribution::NONE,
192 },
193 scratch,
194 )
195 }
196
197 fn tmp_sk(&mut self, module: &Module<FFT64>, rank: usize) -> (GLWESecret<&mut [u8]>, &mut Self) {
198 let (data, scratch) = self.tmp_scalar_znx(module, rank);
199 (
200 GLWESecret {
201 data,
202 dist: Distribution::NONE,
203 },
204 scratch,
205 )
206 }
207
208 fn tmp_fourier_sk(&mut self, module: &Module<FFT64>, rank: usize) -> (FourierGLWESecret<&mut [u8], FFT64>, &mut Self) {
209 let (data, scratch) = self.tmp_scalar_znx_dft(module, rank);
210 (
211 FourierGLWESecret {
212 data,
213 dist: Distribution::NONE,
214 },
215 scratch,
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 ) -> (GLWEAutomorphismKey<&mut [u8], FFT64>, &mut Self) {
242 let (data, scratch) = self.tmp_glwe_ksk(module, basek, k, rows, digits, rank, rank);
243 (GLWEAutomorphismKey { 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 ) -> (GLWETensorKey<&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 (GLWETensorKey { keys }, scratch)
271 }
272}