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