arnaucube
arnaucube/poulpyPublic Self-hosted repository
poulpy/poulpy-core/src/external_product/ggsw_ct.rs
poulpy-core/src/external_product/ggsw_ct.rsRaw
  1use poulpy_hal::{
  2    api::{
  3        ScratchAvailable, TakeVecZnx, TakeVecZnxDft, VecZnxBigNormalize, VecZnxDftAllocBytes, VecZnxDftApply,
  4        VecZnxIdftApplyConsume, VecZnxNormalize, VecZnxNormalizeTmpBytes, VmpApplyDftToDft, VmpApplyDftToDftAdd,
  5        VmpApplyDftToDftTmpBytes,
  6    },
  7    layouts::{Backend, DataMut, DataRef, Module, Scratch, ZnxZero},
  8};
  9
 10use crate::layouts::{GGSWCiphertext, GGSWInfos, GLWECiphertext, GLWEInfos, prepared::GGSWCiphertextPrepared};
 11
 12impl GGSWCiphertext<Vec<u8>> {
 13    #[allow(clippy::too_many_arguments)]
 14    pub fn external_product_scratch_space<B: Backend, OUT, IN, GGSW>(
 15        module: &Module<B>,
 16        out_infos: &OUT,
 17        in_infos: &IN,
 18        apply_infos: &GGSW,
 19    ) -> usize
 20    where
 21        OUT: GGSWInfos,
 22        IN: GGSWInfos,
 23        GGSW: GGSWInfos,
 24        Module<B>: VecZnxDftAllocBytes + VmpApplyDftToDftTmpBytes + VecZnxNormalizeTmpBytes,
 25    {
 26        GLWECiphertext::external_product_scratch_space(
 27            module,
 28            &out_infos.glwe_layout(),
 29            &in_infos.glwe_layout(),
 30            apply_infos,
 31        )
 32    }
 33
 34    pub fn external_product_inplace_scratch_space<B: Backend, OUT, GGSW>(
 35        module: &Module<B>,
 36        out_infos: &OUT,
 37        apply_infos: &GGSW,
 38    ) -> usize
 39    where
 40        OUT: GGSWInfos,
 41        GGSW: GGSWInfos,
 42        Module<B>: VecZnxDftAllocBytes + VmpApplyDftToDftTmpBytes + VecZnxNormalizeTmpBytes,
 43    {
 44        GLWECiphertext::external_product_inplace_scratch_space(module, &out_infos.glwe_layout(), apply_infos)
 45    }
 46}
 47
 48impl<DataSelf: DataMut> GGSWCiphertext<DataSelf> {
 49    pub fn external_product<DataLhs: DataRef, DataRhs: DataRef, B: Backend>(
 50        &mut self,
 51        module: &Module<B>,
 52        lhs: &GGSWCiphertext<DataLhs>,
 53        rhs: &GGSWCiphertextPrepared<DataRhs, B>,
 54        scratch: &mut Scratch<B>,
 55    ) where
 56        Module<B>: VecZnxDftAllocBytes
 57            + VmpApplyDftToDftTmpBytes
 58            + VecZnxNormalizeTmpBytes
 59            + VecZnxDftApply<B>
 60            + VmpApplyDftToDft<B>
 61            + VmpApplyDftToDftAdd<B>
 62            + VecZnxIdftApplyConsume<B>
 63            + VecZnxBigNormalize<B>
 64            + VecZnxNormalize<B>,
 65        Scratch<B>: TakeVecZnxDft<B> + ScratchAvailable + TakeVecZnx,
 66    {
 67        #[cfg(debug_assertions)]
 68        {
 69            use crate::layouts::LWEInfos;
 70
 71            assert_eq!(lhs.n(), self.n());
 72            assert_eq!(rhs.n(), self.n());
 73
 74            assert_eq!(
 75                self.rank(),
 76                lhs.rank(),
 77                "ggsw_out rank: {} != ggsw_in rank: {}",
 78                self.rank(),
 79                lhs.rank()
 80            );
 81            assert_eq!(
 82                self.rank(),
 83                rhs.rank(),
 84                "ggsw_in rank: {} != ggsw_apply rank: {}",
 85                self.rank(),
 86                rhs.rank()
 87            );
 88
 89            assert!(scratch.available() >= GGSWCiphertext::external_product_scratch_space(module, self, lhs, rhs))
 90        }
 91
 92        let min_rows: usize = self.rows().min(lhs.rows()).into();
 93
 94        (0..(self.rank() + 1).into()).for_each(|col_i| {
 95            (0..min_rows).for_each(|row_j| {
 96                self.at_mut(row_j, col_i)
 97                    .external_product(module, &lhs.at(row_j, col_i), rhs, scratch);
 98            });
 99            (min_rows..self.rows().into()).for_each(|row_i| {
100                self.at_mut(row_i, col_i).data.zero();
101            });
102        });
103    }
104
105    pub fn external_product_inplace<DataRhs: DataRef, B: Backend>(
106        &mut self,
107        module: &Module<B>,
108        rhs: &GGSWCiphertextPrepared<DataRhs, B>,
109        scratch: &mut Scratch<B>,
110    ) where
111        Module<B>: VecZnxDftAllocBytes
112            + VmpApplyDftToDftTmpBytes
113            + VecZnxNormalizeTmpBytes
114            + VecZnxDftApply<B>
115            + VmpApplyDftToDft<B>
116            + VmpApplyDftToDftAdd<B>
117            + VecZnxIdftApplyConsume<B>
118            + VecZnxBigNormalize<B>
119            + VecZnxNormalize<B>,
120        Scratch<B>: TakeVecZnxDft<B> + ScratchAvailable + TakeVecZnx,
121    {
122        #[cfg(debug_assertions)]
123        {
124            use crate::layouts::LWEInfos;
125
126            assert_eq!(rhs.n(), self.n());
127            assert_eq!(
128                self.rank(),
129                rhs.rank(),
130                "ggsw_out rank: {} != ggsw_apply: {}",
131                self.rank(),
132                rhs.rank()
133            );
134        }
135
136        (0..(self.rank() + 1).into()).for_each(|col_i| {
137            (0..self.rows().into()).for_each(|row_j| {
138                self.at_mut(row_j, col_i)
139                    .external_product_inplace(module, rhs, scratch);
140            });
141        });
142    }
143}