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