arnaucube
arnaucube/poulpyPublic Self-hosted repository
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}