arnaucube
arnaucube/poulpyPublic Self-hosted repository
poulpy/poulpy-core/src/external_product/gglwe_ksk.rs
poulpy-core/src/external_product/gglwe_ksk.rsRaw
  1use poulpy_hal::layouts::{Backend, DataMut, Module, Scratch, ZnxZero};
  2
  3use crate::{
  4    GLWEExternalProduct, ScratchTakeCore,
  5    layouts::{
  6        GGLWE, GGLWEInfos, GGLWEToMut, GGLWEToRef, GGSWInfos, GLWEInfos, GLWESwitchingKey,
  7        prepared::{GGSWPrepared, GGSWPreparedToRef},
  8    },
  9};
 10
 11pub trait GGLWEExternalProduct<BE: Backend>
 12where
 13    Self: GLWEExternalProduct<BE>,
 14{
 15    fn gglwe_external_product_tmp_bytes<R, A, B>(&self, res_infos: &R, a_infos: &A, b_infos: &B) -> usize
 16    where
 17        R: GGLWEInfos,
 18        A: GGLWEInfos,
 19        B: GGSWInfos,
 20    {
 21        self.glwe_external_product_tmp_bytes(res_infos, a_infos, b_infos)
 22    }
 23
 24    fn gglwe_external_product<R, A, B>(&self, res: &mut R, a: &A, b: &B, scratch: &mut Scratch<BE>)
 25    where
 26        R: GGLWEToMut,
 27        A: GGLWEToRef,
 28        B: GGSWPreparedToRef<BE>,
 29        Scratch<BE>: ScratchTakeCore<BE>,
 30    {
 31        let res: &mut GGLWE<&mut [u8]> = &mut res.to_mut();
 32        let a: &GGLWE<&[u8]> = &a.to_ref();
 33        let b: &GGSWPrepared<&[u8], BE> = &b.to_ref();
 34
 35        assert_eq!(
 36            res.rank_in(),
 37            a.rank_in(),
 38            "res input rank_in: {} != a input rank_in: {}",
 39            res.rank_in(),
 40            a.rank_in()
 41        );
 42        assert_eq!(
 43            a.rank_out(),
 44            b.rank(),
 45            "a output rank_out: {} != b rank: {}",
 46            a.rank_out(),
 47            b.rank()
 48        );
 49        assert_eq!(
 50            res.rank_out(),
 51            b.rank(),
 52            "res output rank_out: {} != b rank: {}",
 53            res.rank_out(),
 54            b.rank()
 55        );
 56
 57        for row in 0..res.dnum().into() {
 58            for col in 0..res.rank_in().into() {
 59                self.glwe_external_product(&mut res.at_mut(row, col), &a.at(row, col), b, scratch);
 60            }
 61        }
 62
 63        for row in res.dnum().min(a.dnum()).into()..res.dnum().into() {
 64            for col in 0..res.rank_in().into() {
 65                res.at_mut(row, col).data_mut().zero();
 66            }
 67        }
 68    }
 69
 70    fn gglwe_external_product_inplace<R, A>(&self, res: &mut R, a: &A, scratch: &mut Scratch<BE>)
 71    where
 72        R: GGLWEToMut,
 73        A: GGSWPreparedToRef<BE>,
 74        Scratch<BE>: ScratchTakeCore<BE>,
 75    {
 76        let res: &mut GGLWE<&mut [u8]> = &mut res.to_mut();
 77        let a: &GGSWPrepared<&[u8], BE> = &a.to_ref();
 78
 79        assert_eq!(
 80            res.rank_out(),
 81            a.rank(),
 82            "res output rank: {} != a rank: {}",
 83            res.rank_out(),
 84            a.rank()
 85        );
 86
 87        for row in 0..res.dnum().into() {
 88            for col in 0..res.rank_in().into() {
 89                self.glwe_external_product_inplace(&mut res.at_mut(row, col), a, scratch);
 90            }
 91        }
 92    }
 93}
 94
 95impl<BE: Backend> GGLWEExternalProduct<BE> for Module<BE> where Self: GLWEExternalProduct<BE> {}
 96
 97impl GLWESwitchingKey<Vec<u8>> {
 98    pub fn external_product_tmp_bytes<R, A, B, M, BE: Backend>(
 99        &self,
100        module: &M,
101        res_infos: &R,
102        a_infos: &A,
103        b_infos: &B,
104    ) -> usize
105    where
106        R: GGLWEInfos,
107        A: GGLWEInfos,
108        B: GGSWInfos,
109        M: GGLWEExternalProduct<BE>,
110    {
111        module.gglwe_external_product_tmp_bytes(res_infos, a_infos, b_infos)
112    }
113}
114
115impl<DataSelf: DataMut> GLWESwitchingKey<DataSelf> {
116    pub fn external_product<A, B, M, BE: Backend>(&mut self, module: &M, a: &A, b: &B, scratch: &mut Scratch<BE>)
117    where
118        M: GGLWEExternalProduct<BE>,
119        A: GGLWEToRef,
120        B: GGSWPreparedToRef<BE>,
121        Scratch<BE>: ScratchTakeCore<BE>,
122    {
123        module.gglwe_external_product(self, a, b, scratch);
124    }
125
126    pub fn external_product_inplace<A, M, BE: Backend>(&mut self, module: &M, a: &A, scratch: &mut Scratch<BE>)
127    where
128        M: GGLWEExternalProduct<BE>,
129        A: GGSWPreparedToRef<BE>,
130        Scratch<BE>: ScratchTakeCore<BE>,
131    {
132        module.gglwe_external_product_inplace(self, a, scratch);
133    }
134}