arnaucube
arnaucube/poulpyPublic Self-hosted repository
poulpy/core/src/external_product/gglwe_ksk.rs
core/src/external_product/gglwe_ksk.rsRaw
  1use backend::hal::{
  2    api::{
  3        ScratchAvailable, TakeVecZnxDft, VecZnxBigNormalize, VecZnxDftAllocBytes, VecZnxDftFromVecZnx,
  4        VecZnxDftToVecZnxBigConsume, VecZnxNormalizeTmpBytes, VmpApply, VmpApplyAdd, VmpApplyTmpBytes, ZnxZero,
  5    },
  6    layouts::{Backend, DataMut, DataRef, Module, Scratch},
  7};
  8
  9use crate::layouts::{GGLWESwitchingKey, GLWECiphertext, Infos, prepared::GGSWCiphertextPrepared};
 10
 11impl GGLWESwitchingKey<Vec<u8>> {
 12    pub fn external_product_scratch_space<B: Backend>(
 13        module: &Module<B>,
 14        n: usize,
 15        basek: usize,
 16        k_out: usize,
 17        k_in: usize,
 18        k_ggsw: usize,
 19        digits: usize,
 20        rank: usize,
 21    ) -> usize
 22    where
 23        Module<B>: VecZnxDftAllocBytes + VmpApplyTmpBytes + VecZnxNormalizeTmpBytes,
 24    {
 25        GLWECiphertext::external_product_scratch_space(module, n, basek, k_out, k_in, k_ggsw, digits, rank)
 26    }
 27
 28    pub fn external_product_inplace_scratch_space<B: Backend>(
 29        module: &Module<B>,
 30        n: usize,
 31        basek: usize,
 32        k_out: usize,
 33        k_ggsw: usize,
 34        digits: usize,
 35        rank: usize,
 36    ) -> usize
 37    where
 38        Module<B>: VecZnxDftAllocBytes + VmpApplyTmpBytes + VecZnxNormalizeTmpBytes,
 39    {
 40        GLWECiphertext::external_product_inplace_scratch_space(module, n, basek, k_out, k_ggsw, digits, rank)
 41    }
 42}
 43
 44impl<DataSelf: DataMut> GGLWESwitchingKey<DataSelf> {
 45    pub fn external_product<DataLhs: DataRef, DataRhs: DataRef, B: Backend>(
 46        &mut self,
 47        module: &Module<B>,
 48        lhs: &GGLWESwitchingKey<DataLhs>,
 49        rhs: &GGSWCiphertextPrepared<DataRhs, B>,
 50        scratch: &mut Scratch<B>,
 51    ) where
 52        Module<B>: VecZnxDftAllocBytes
 53            + VmpApplyTmpBytes
 54            + VecZnxNormalizeTmpBytes
 55            + VecZnxDftFromVecZnx<B>
 56            + VmpApply<B>
 57            + VmpApplyAdd<B>
 58            + VecZnxDftToVecZnxBigConsume<B>
 59            + VecZnxBigNormalize<B>,
 60        Scratch<B>: TakeVecZnxDft<B> + ScratchAvailable,
 61    {
 62        #[cfg(debug_assertions)]
 63        {
 64            assert_eq!(
 65                self.rank_in(),
 66                lhs.rank_in(),
 67                "ksk_out input rank: {} != ksk_in input rank: {}",
 68                self.rank_in(),
 69                lhs.rank_in()
 70            );
 71            assert_eq!(
 72                lhs.rank_out(),
 73                rhs.rank(),
 74                "ksk_in output rank: {} != ggsw rank: {}",
 75                self.rank_out(),
 76                rhs.rank()
 77            );
 78            assert_eq!(
 79                self.rank_out(),
 80                rhs.rank(),
 81                "ksk_out output rank: {} != ggsw rank: {}",
 82                self.rank_out(),
 83                rhs.rank()
 84            );
 85        }
 86
 87        (0..self.rank_in()).for_each(|col_i| {
 88            (0..self.rows()).for_each(|row_j| {
 89                self.at_mut(row_j, col_i)
 90                    .external_product(module, &lhs.at(row_j, col_i), rhs, scratch);
 91            });
 92        });
 93
 94        (self.rows().min(lhs.rows())..self.rows()).for_each(|row_i| {
 95            (0..self.rank_in()).for_each(|col_j| {
 96                self.at_mut(row_i, col_j).data.zero();
 97            });
 98        });
 99    }
100
101    pub fn external_product_inplace<DataRhs: DataRef, B: Backend>(
102        &mut self,
103        module: &Module<B>,
104        rhs: &GGSWCiphertextPrepared<DataRhs, B>,
105        scratch: &mut Scratch<B>,
106    ) where
107        Module<B>: VecZnxDftAllocBytes
108            + VmpApplyTmpBytes
109            + VecZnxNormalizeTmpBytes
110            + VecZnxDftFromVecZnx<B>
111            + VmpApply<B>
112            + VmpApplyAdd<B>
113            + VecZnxDftToVecZnxBigConsume<B>
114            + VecZnxBigNormalize<B>,
115        Scratch<B>: TakeVecZnxDft<B> + ScratchAvailable,
116    {
117        #[cfg(debug_assertions)]
118        {
119            assert_eq!(
120                self.rank_out(),
121                rhs.rank(),
122                "ksk_out output rank: {} != ggsw rank: {}",
123                self.rank_out(),
124                rhs.rank()
125            );
126        }
127
128        (0..self.rank_in()).for_each(|col_i| {
129            (0..self.rows()).for_each(|row_j| {
130                self.at_mut(row_j, col_i)
131                    .external_product_inplace(module, rhs, scratch);
132            });
133        });
134    }
135}