poulpy/poulpy-core/src/automorphism/glwe_ct.rs
poulpy-core/src/automorphism/glwe_ct.rsRaw
1use poulpy_hal::{
2 api::{
3 ScratchTakeBasic, VecZnxAutomorphismInplace, VecZnxBigAutomorphismInplace, VecZnxBigSubSmallInplace,
4 VecZnxBigSubSmallNegateInplace,
5 },
6 layouts::{Backend, DataMut, Module, Scratch, VecZnxBig},
7};
8
9use crate::{
10 GLWEKeyswitch, ScratchTakeCore, keyswitch_internal,
11 layouts::{
12 GGLWEInfos, GGLWEPreparedToRef, GLWE, GLWEInfos, GLWEToMut, GLWEToRef, LWEInfos, prepared::GetAutomorphismGaloisElement,
13 },
14};
15
16impl GLWE<Vec<u8>> {
17 pub fn automorphism_tmp_bytes<M, R, A, K, BE: Backend>(module: &M, res_infos: &R, a_infos: &A, key_infos: &K) -> usize
18 where
19 R: GLWEInfos,
20 A: GLWEInfos,
21 K: GGLWEInfos,
22 M: GLWEAutomorphism<BE>,
23 {
24 module.glwe_automorphism_tmp_bytes(res_infos, a_infos, key_infos)
25 }
26}
27
28impl<DataSelf: DataMut> GLWE<DataSelf> {
29 pub fn automorphism<M, A, K, BE: Backend>(&mut self, module: &M, a: &A, key: &K, scratch: &mut Scratch<BE>)
30 where
31 M: GLWEAutomorphism<BE>,
32 A: GLWEToRef,
33 K: GetAutomorphismGaloisElement + GGLWEPreparedToRef<BE> + GGLWEInfos,
34 Scratch<BE>: ScratchTakeCore<BE>,
35 {
36 module.glwe_automorphism(self, a, key, scratch);
37 }
38
39 pub fn automorphism_add<M, A, K, BE: Backend>(&mut self, module: &M, a: &A, key: &K, scratch: &mut Scratch<BE>)
40 where
41 M: GLWEAutomorphism<BE>,
42 A: GLWEToRef,
43 K: GetAutomorphismGaloisElement + GGLWEPreparedToRef<BE> + GGLWEInfos,
44 Scratch<BE>: ScratchTakeCore<BE>,
45 {
46 module.glwe_automorphism_add(self, a, key, scratch);
47 }
48
49 pub fn automorphism_sub<M, A, K, BE: Backend>(&mut self, module: &M, a: &A, key: &K, scratch: &mut Scratch<BE>)
50 where
51 M: GLWEAutomorphism<BE>,
52 A: GLWEToRef,
53 K: GetAutomorphismGaloisElement + GGLWEPreparedToRef<BE> + GGLWEInfos,
54 Scratch<BE>: ScratchTakeCore<BE>,
55 {
56 module.glwe_automorphism_sub(self, a, key, scratch);
57 }
58
59 pub fn glwe_automorphism_sub_negate<M, A, K, BE: Backend>(&mut self, module: &M, a: &A, key: &K, scratch: &mut Scratch<BE>)
60 where
61 M: GLWEAutomorphism<BE>,
62 A: GLWEToRef,
63 K: GetAutomorphismGaloisElement + GGLWEPreparedToRef<BE> + GGLWEInfos,
64 Scratch<BE>: ScratchTakeCore<BE>,
65 {
66 module.glwe_automorphism_sub_negate(self, a, key, scratch);
67 }
68
69 pub fn automorphism_inplace<M, K, BE: Backend>(&mut self, module: &M, key: &K, scratch: &mut Scratch<BE>)
70 where
71 M: GLWEAutomorphism<BE>,
72 K: GetAutomorphismGaloisElement + GGLWEPreparedToRef<BE> + GGLWEInfos,
73 Scratch<BE>: ScratchTakeCore<BE>,
74 {
75 module.glwe_automorphism_inplace(self, key, scratch);
76 }
77
78 pub fn automorphism_add_inplace<M, K, BE: Backend>(&mut self, module: &M, key: &K, scratch: &mut Scratch<BE>)
79 where
80 M: GLWEAutomorphism<BE>,
81 K: GetAutomorphismGaloisElement + GGLWEPreparedToRef<BE> + GGLWEInfos,
82 Scratch<BE>: ScratchTakeCore<BE>,
83 {
84 module.glwe_automorphism_add_inplace(self, key, scratch);
85 }
86
87 pub fn automorphism_sub_inplace<M, K, BE: Backend>(&mut self, module: &M, key: &K, scratch: &mut Scratch<BE>)
88 where
89 M: GLWEAutomorphism<BE>,
90 K: GetAutomorphismGaloisElement + GGLWEPreparedToRef<BE> + GGLWEInfos,
91 Scratch<BE>: ScratchTakeCore<BE>,
92 {
93 module.glwe_automorphism_sub_inplace(self, key, scratch);
94 }
95
96 pub fn automorphism_sub_negate_inplace<M, K, BE: Backend>(&mut self, module: &M, key: &K, scratch: &mut Scratch<BE>)
97 where
98 M: GLWEAutomorphism<BE>,
99 K: GetAutomorphismGaloisElement + GGLWEPreparedToRef<BE> + GGLWEInfos,
100 Scratch<BE>: ScratchTakeCore<BE>,
101 {
102 module.glwe_automorphism_sub_negate_inplace(self, key, scratch);
103 }
104}
105
106pub trait GLWEAutomorphism<BE: Backend>
107where
108 Self: GLWEKeyswitch<BE>
109 + VecZnxAutomorphismInplace<BE>
110 + VecZnxBigAutomorphismInplace<BE>
111 + VecZnxBigSubSmallInplace<BE>
112 + VecZnxBigSubSmallNegateInplace<BE>,
113{
114 fn glwe_automorphism_tmp_bytes<R, A, K>(&self, res_infos: &R, a_infos: &A, key_infos: &K) -> usize
115 where
116 R: GLWEInfos,
117 A: GLWEInfos,
118 K: GGLWEInfos,
119 {
120 self.glwe_keyswitch_tmp_bytes(res_infos, a_infos, key_infos)
121 }
122
123 fn glwe_automorphism<R, A, K>(&self, res: &mut R, a: &A, key: &K, scratch: &mut Scratch<BE>)
124 where
125 R: GLWEToMut,
126 A: GLWEToRef,
127 K: GetAutomorphismGaloisElement + GGLWEPreparedToRef<BE> + GGLWEInfos,
128 Scratch<BE>: ScratchTakeCore<BE>,
129 {
130 self.glwe_keyswitch(res, a, key, scratch);
131
132 let res: &mut GLWE<&mut [u8]> = &mut res.to_mut();
133
134 for i in 0..res.rank().as_usize() + 1 {
135 self.vec_znx_automorphism_inplace(key.p(), res.data_mut(), i, scratch);
136 }
137 }
138
139 fn glwe_automorphism_inplace<R, K>(&self, res: &mut R, key: &K, scratch: &mut Scratch<BE>)
140 where
141 R: GLWEToMut,
142 K: GetAutomorphismGaloisElement + GGLWEPreparedToRef<BE> + GGLWEInfos,
143 Scratch<BE>: ScratchTakeCore<BE>,
144 {
145 self.glwe_keyswitch_inplace(res, key, scratch);
146
147 let res: &mut GLWE<&mut [u8]> = &mut res.to_mut();
148
149 for i in 0..res.rank().as_usize() + 1 {
150 self.vec_znx_automorphism_inplace(key.p(), res.data_mut(), i, scratch);
151 }
152 }
153
154 fn glwe_automorphism_add<R, A, K>(&self, res: &mut R, a: &A, key: &K, scratch: &mut Scratch<BE>)
155 where
156 R: GLWEToMut,
157 A: GLWEToRef,
158 K: GetAutomorphismGaloisElement + GGLWEPreparedToRef<BE> + GGLWEInfos,
159 Scratch<BE>: ScratchTakeCore<BE>,
160 {
161 let res: &mut GLWE<&mut [u8]> = &mut res.to_mut();
162 let a: &GLWE<&[u8]> = &a.to_ref();
163
164 let (res_dft, scratch_1) = scratch.take_vec_znx_dft(self, (res.rank() + 1).into(), key.size()); // TODO: optimise size
165 let mut res_big: VecZnxBig<_, BE> = keyswitch_internal(self, res_dft, a, key, scratch_1);
166
167 for i in 0..res.rank().as_usize() + 1 {
168 self.vec_znx_big_automorphism_inplace(key.p(), &mut res_big, i, scratch_1);
169 self.vec_znx_big_add_small_inplace(&mut res_big, i, a.data(), i);
170 self.vec_znx_big_normalize(
171 res.base2k().into(),
172 res.data_mut(),
173 i,
174 key.base2k().into(),
175 &res_big,
176 i,
177 scratch_1,
178 );
179 }
180 }
181
182 fn glwe_automorphism_add_inplace<R, K>(&self, res: &mut R, key: &K, scratch: &mut Scratch<BE>)
183 where
184 R: GLWEToMut,
185 K: GetAutomorphismGaloisElement + GGLWEPreparedToRef<BE> + GGLWEInfos,
186 Scratch<BE>: ScratchTakeCore<BE>,
187 {
188 let res: &mut GLWE<&mut [u8]> = &mut res.to_mut();
189
190 let (res_dft, scratch_1) = scratch.take_vec_znx_dft(self, (res.rank() + 1).into(), key.size()); // TODO: optimise size
191 let mut res_big: VecZnxBig<_, BE> = keyswitch_internal(self, res_dft, res, key, scratch_1);
192
193 for i in 0..res.rank().as_usize() + 1 {
194 self.vec_znx_big_automorphism_inplace(key.p(), &mut res_big, i, scratch_1);
195 self.vec_znx_big_add_small_inplace(&mut res_big, i, res.data(), i);
196 self.vec_znx_big_normalize(
197 res.base2k().into(),
198 res.data_mut(),
199 i,
200 key.base2k().into(),
201 &res_big,
202 i,
203 scratch_1,
204 );
205 }
206 }
207
208 fn glwe_automorphism_sub<R, A, K>(&self, res: &mut R, a: &A, key: &K, scratch: &mut Scratch<BE>)
209 where
210 R: GLWEToMut,
211 A: GLWEToRef,
212 K: GetAutomorphismGaloisElement + GGLWEPreparedToRef<BE> + GGLWEInfos,
213 Scratch<BE>: ScratchTakeCore<BE>,
214 {
215 let res: &mut GLWE<&mut [u8]> = &mut res.to_mut();
216 let a: &GLWE<&[u8]> = &a.to_ref();
217
218 let (res_dft, scratch_1) = scratch.take_vec_znx_dft(self, (res.rank() + 1).into(), key.size()); // TODO: optimise size
219 let mut res_big: VecZnxBig<_, BE> = keyswitch_internal(self, res_dft, a, key, scratch_1);
220
221 for i in 0..res.rank().as_usize() + 1 {
222 self.vec_znx_big_automorphism_inplace(key.p(), &mut res_big, i, scratch_1);
223 self.vec_znx_big_sub_small_inplace(&mut res_big, i, a.data(), i);
224 self.vec_znx_big_normalize(
225 res.base2k().into(),
226 res.data_mut(),
227 i,
228 key.base2k().into(),
229 &res_big,
230 i,
231 scratch_1,
232 );
233 }
234 }
235
236 fn glwe_automorphism_sub_negate<R, A, K>(&self, res: &mut R, a: &A, key: &K, scratch: &mut Scratch<BE>)
237 where
238 R: GLWEToMut,
239 A: GLWEToRef,
240 K: GetAutomorphismGaloisElement + GGLWEPreparedToRef<BE> + GGLWEInfos,
241 Scratch<BE>: ScratchTakeCore<BE>,
242 {
243 let res: &mut GLWE<&mut [u8]> = &mut res.to_mut();
244 let a: &GLWE<&[u8]> = &a.to_ref();
245
246 let (res_dft, scratch_1) = scratch.take_vec_znx_dft(self, (res.rank() + 1).into(), key.size()); // TODO: optimise size
247 let mut res_big: VecZnxBig<_, BE> = keyswitch_internal(self, res_dft, a, key, scratch_1);
248
249 for i in 0..res.rank().as_usize() + 1 {
250 self.vec_znx_big_automorphism_inplace(key.p(), &mut res_big, i, scratch_1);
251 self.vec_znx_big_sub_small_negate_inplace(&mut res_big, i, a.data(), i);
252 self.vec_znx_big_normalize(
253 res.base2k().into(),
254 res.data_mut(),
255 i,
256 key.base2k().into(),
257 &res_big,
258 i,
259 scratch_1,
260 );
261 }
262 }
263
264 fn glwe_automorphism_sub_inplace<R, K>(&self, res: &mut R, key: &K, scratch: &mut Scratch<BE>)
265 where
266 R: GLWEToMut,
267 K: GetAutomorphismGaloisElement + GGLWEPreparedToRef<BE> + GGLWEInfos,
268 Scratch<BE>: ScratchTakeCore<BE>,
269 {
270 let res: &mut GLWE<&mut [u8]> = &mut res.to_mut();
271
272 let (res_dft, scratch_1) = scratch.take_vec_znx_dft(self, (res.rank() + 1).into(), key.size()); // TODO: optimise size
273 let mut res_big: VecZnxBig<_, BE> = keyswitch_internal(self, res_dft, res, key, scratch_1);
274
275 for i in 0..res.rank().as_usize() + 1 {
276 self.vec_znx_big_automorphism_inplace(key.p(), &mut res_big, i, scratch_1);
277 self.vec_znx_big_sub_small_inplace(&mut res_big, i, res.data(), i);
278 self.vec_znx_big_normalize(
279 res.base2k().into(),
280 res.data_mut(),
281 i,
282 key.base2k().into(),
283 &res_big,
284 i,
285 scratch_1,
286 );
287 }
288 }
289
290 fn glwe_automorphism_sub_negate_inplace<R, K>(&self, res: &mut R, key: &K, scratch: &mut Scratch<BE>)
291 where
292 R: GLWEToMut,
293 K: GetAutomorphismGaloisElement + GGLWEPreparedToRef<BE> + GGLWEInfos,
294 Scratch<BE>: ScratchTakeCore<BE>,
295 {
296 let res: &mut GLWE<&mut [u8]> = &mut res.to_mut();
297
298 let (res_dft, scratch_1) = scratch.take_vec_znx_dft(self, (res.rank() + 1).into(), key.size()); // TODO: optimise size
299 let mut res_big: VecZnxBig<_, BE> = keyswitch_internal(self, res_dft, res, key, scratch_1);
300
301 for i in 0..res.rank().as_usize() + 1 {
302 self.vec_znx_big_automorphism_inplace(key.p(), &mut res_big, i, scratch_1);
303 self.vec_znx_big_sub_small_negate_inplace(&mut res_big, i, res.data(), i);
304 self.vec_znx_big_normalize(
305 res.base2k().into(),
306 res.data_mut(),
307 i,
308 key.base2k().into(),
309 &res_big,
310 i,
311 scratch_1,
312 );
313 }
314 }
315}
316
317impl<BE: Backend> GLWEAutomorphism<BE> for Module<BE> where
318 Self: GLWEKeyswitch<BE>
319 + VecZnxAutomorphismInplace<BE>
320 + VecZnxBigAutomorphismInplace<BE>
321 + VecZnxBigSubSmallInplace<BE>
322 + VecZnxBigSubSmallNegateInplace<BE>
323{
324}