arnaucube
arnaucube/poulpyPublic Self-hosted repository
poulpy/poulpy-core/src/automorphism/ggsw_ct.rs
poulpy-core/src/automorphism/ggsw_ct.rsRaw
  1use poulpy_hal::{
  2    api::ScratchAvailable,
  3    layouts::{Backend, DataMut, Module, Scratch},
  4};
  5
  6use crate::{
  7    GGSWExpandRows, ScratchTakeCore,
  8    automorphism::glwe_ct::GLWEAutomorphism,
  9    layouts::{
 10        GGLWEInfos, GGSW, GGSWInfos, GGSWToMut, GGSWToRef, GLWEInfos, LWEInfos,
 11        prepared::{AutomorphismKeyPrepared, AutomorphismKeyPreparedToRef, TensorKeyPrepared, TensorKeyPreparedToRef},
 12    },
 13};
 14
 15impl GGSW<Vec<u8>> {
 16    pub fn automorphism_tmp_bytes<R, A, K, T, M, BE: Backend>(
 17        module: &M,
 18        res_infos: &R,
 19        a_infos: &A,
 20        key_infos: &K,
 21        tsk_infos: &T,
 22    ) -> usize
 23    where
 24        R: GGSWInfos,
 25        A: GGSWInfos,
 26        K: GGLWEInfos,
 27        T: GGLWEInfos,
 28        M: GGSWAutomorphism<BE>,
 29    {
 30        module.ggsw_automorphism_tmp_bytes(res_infos, a_infos, key_infos, tsk_infos)
 31    }
 32}
 33
 34impl<D: DataMut> GGSW<D> {
 35    pub fn automorphism<A, K, T, M, BE: Backend>(&mut self, module: &M, a: &A, key: &K, tsk: &T, scratch: &mut Scratch<BE>)
 36    where
 37        A: GGSWToRef,
 38        K: AutomorphismKeyPreparedToRef<BE>,
 39        T: TensorKeyPreparedToRef<BE>,
 40        Scratch<BE>: ScratchTakeCore<BE>,
 41        M: GGSWAutomorphism<BE>,
 42    {
 43        module.ggsw_automorphism(self, a, key, tsk, scratch);
 44    }
 45
 46    pub fn automorphism_inplace<K, T, M, BE: Backend>(&mut self, module: &M, key: &K, tsk: &T, scratch: &mut Scratch<BE>)
 47    where
 48        K: AutomorphismKeyPreparedToRef<BE>,
 49        T: TensorKeyPreparedToRef<BE>,
 50        Scratch<BE>: ScratchTakeCore<BE>,
 51        M: GGSWAutomorphism<BE>,
 52    {
 53        module.ggsw_automorphism_inplace(self, key, tsk, scratch);
 54    }
 55}
 56
 57impl<BE: Backend> GGSWAutomorphism<BE> for Module<BE> where Self: GLWEAutomorphism<BE> + GGSWExpandRows<BE> {}
 58
 59pub trait GGSWAutomorphism<BE: Backend>
 60where
 61    Self: GLWEAutomorphism<BE> + GGSWExpandRows<BE>,
 62{
 63    fn ggsw_automorphism_tmp_bytes<R, A, K, T>(&self, res_infos: &R, a_infos: &A, key_infos: &K, tsk_infos: &T) -> usize
 64    where
 65        R: GGSWInfos,
 66        A: GGSWInfos,
 67        K: GGLWEInfos,
 68        T: GGLWEInfos,
 69    {
 70        let out_size: usize = res_infos.size();
 71        let ci_dft: usize = self.bytes_of_vec_znx_dft((key_infos.rank_out() + 1).into(), out_size);
 72        let ks_internal: usize = self.glwe_automorphism_tmp_bytes(res_infos, a_infos, key_infos);
 73        let expand: usize = self.ggsw_expand_rows_tmp_bytes(res_infos, tsk_infos);
 74        ci_dft + (ks_internal.max(expand))
 75    }
 76
 77    fn ggsw_automorphism<R, A, K, T>(&self, res: &mut R, a: &A, key: &K, tsk: &T, scratch: &mut Scratch<BE>)
 78    where
 79        R: GGSWToMut,
 80        A: GGSWToRef,
 81        K: AutomorphismKeyPreparedToRef<BE>,
 82        T: TensorKeyPreparedToRef<BE>,
 83        Scratch<BE>: ScratchTakeCore<BE>,
 84    {
 85        let res: &mut GGSW<&mut [u8]> = &mut res.to_mut();
 86        let a: &GGSW<&[u8]> = &a.to_ref();
 87        let key: &AutomorphismKeyPrepared<&[u8], BE> = &key.to_ref();
 88        let tsk: &TensorKeyPrepared<&[u8], BE> = &tsk.to_ref();
 89
 90        assert_eq!(res.ggsw_layout(), a.ggsw_layout());
 91        assert_eq!(res.glwe_layout(), a.glwe_layout());
 92        assert_eq!(res.lwe_layout(), a.lwe_layout());
 93        assert!(scratch.available() >= self.ggsw_automorphism_tmp_bytes(res, a, key, tsk));
 94
 95        // Keyswitch the j-th row of the col 0
 96        for row in 0..res.dnum().as_usize() {
 97            // Key-switch column 0, i.e.
 98            // col 0: (-(a0s0 + a1s1 + a2s2) + M[i], a0, a1, a2) -> (-(a0pi^-1(s0) + a1pi^-1(s1) + a2pi^-1(s2)) + M[i], a0, a1, a2)
 99            self.glwe_automorphism(&mut res.at_mut(row, 0), &a.at(row, 0), key, scratch);
100        }
101
102        self.ggsw_expand_row(res, tsk, scratch);
103    }
104
105    fn ggsw_automorphism_inplace<R, K, T>(&self, res: &mut R, key: &K, tsk: &T, scratch: &mut Scratch<BE>)
106    where
107        R: GGSWToMut,
108        K: AutomorphismKeyPreparedToRef<BE>,
109        T: TensorKeyPreparedToRef<BE>,
110        Scratch<BE>: ScratchTakeCore<BE>,
111    {
112        let res: &mut GGSW<&mut [u8]> = &mut res.to_mut();
113        let key: &AutomorphismKeyPrepared<&[u8], BE> = &key.to_ref();
114        let tsk: &TensorKeyPrepared<&[u8], BE> = &tsk.to_ref();
115
116        // Keyswitch the j-th row of the col 0
117        for row in 0..res.dnum().as_usize() {
118            // Key-switch column 0, i.e.
119            // col 0: (-(a0s0 + a1s1 + a2s2) + M[i], a0, a1, a2) -> (-(a0pi^-1(s0) + a1pi^-1(s1) + a2pi^-1(s2)) + M[i], a0, a1, a2)
120            self.glwe_automorphism_inplace(&mut res.at_mut(row, 0), key, scratch);
121        }
122
123        self.ggsw_expand_row(res, tsk, scratch);
124    }
125}
126
127impl<DataSelf: DataMut> GGSW<DataSelf> {}