poulpy_core/operations/
ggsw.rs

1use poulpy_hal::layouts::{Backend, Module, Scratch};
2
3use crate::{
4    GLWERotate, ScratchTakeCore,
5    layouts::{GGSW, GGSWInfos, GGSWToMut, GGSWToRef, GLWEInfos},
6};
7
8impl<BE: Backend> GGSWRotate<BE> for Module<BE> where Module<BE>: GLWERotate<BE> {}
9
10pub trait GGSWRotate<BE: Backend>
11where
12    Self: GLWERotate<BE>,
13{
14    fn ggsw_rotate_tmp_bytes(&self) -> usize {
15        self.glwe_rotate_tmp_bytes()
16    }
17
18    fn ggsw_rotate<R, A>(&self, k: i64, res: &mut R, a: &A)
19    where
20        R: GGSWToMut,
21        A: GGSWToRef,
22    {
23        let res: &mut GGSW<&mut [u8]> = &mut res.to_mut();
24        let a: &GGSW<&[u8]> = &a.to_ref();
25
26        assert!(res.dnum() <= a.dnum());
27        assert_eq!(res.dsize(), a.dsize());
28        assert_eq!(res.rank(), a.rank());
29        let rows: usize = res.dnum().into();
30        let cols: usize = (res.rank() + 1).into();
31
32        for row in 0..rows {
33            for col in 0..cols {
34                self.glwe_rotate(k, &mut res.at_mut(row, col), &a.at(row, col));
35            }
36        }
37    }
38
39    fn ggsw_rotate_inplace<R>(&self, k: i64, res: &mut R, scratch: &mut Scratch<BE>)
40    where
41        R: GGSWToMut,
42        Scratch<BE>: ScratchTakeCore<BE>,
43    {
44        let res: &mut GGSW<&mut [u8]> = &mut res.to_mut();
45
46        let rows: usize = res.dnum().into();
47        let cols: usize = (res.rank() + 1).into();
48
49        for row in 0..rows {
50            for col in 0..cols {
51                self.glwe_rotate_inplace(k, &mut res.at_mut(row, col), scratch);
52            }
53        }
54    }
55}