arnaucube
arnaucube/poulpyPublic Self-hosted repository
poulpy/poulpy-core/src/encryption/gglwe_tsk.rs
poulpy-core/src/encryption/gglwe_tsk.rsRaw
  1use poulpy_hal::{
  2    api::{
  3        SvpApplyDftToDft, SvpApplyDftToDftInplace, SvpPPolBytesOf, SvpPrepare, VecZnxAddInplace, VecZnxAddNormal,
  4        VecZnxAddScalarInplace, VecZnxBigBytesOf, VecZnxBigNormalize, VecZnxDftApply, VecZnxDftBytesOf, VecZnxFillUniform,
  5        VecZnxIdftApplyConsume, VecZnxIdftApplyTmpA, VecZnxNormalize, VecZnxNormalizeInplace, VecZnxNormalizeTmpBytes, VecZnxSub,
  6        VecZnxSubInplace, VecZnxSwitchRing,
  7    },
  8    layouts::{Backend, DataMut, DataRef, Module, Scratch},
  9    source::Source,
 10};
 11
 12use crate::layouts::{
 13    GGLWEInfos, GLWEInfos, GLWESecret, GLWESwitchingKey, LWEInfos, Rank, RingDegree, TensorKey, prepared::GLWESecretPrepared,
 14};
 15
 16impl TensorKey<Vec<u8>> {
 17    pub fn encrypt_sk_tmp_bytes<B: Backend, A>(module: &Module<B>, infos: &A) -> usize
 18    where
 19        A: GGLWEInfos,
 20        Module<B>: SvpPPolBytesOf + VecZnxNormalizeTmpBytes + VecZnxDftBytesOf + VecZnxNormalizeTmpBytes + VecZnxBigBytesOf,
 21    {
 22        GLWESecretPrepared::bytes_of(module, infos.rank_out())
 23            + module.bytes_of_vec_znx_dft(infos.rank_out().into(), 1)
 24            + module.bytes_of_vec_znx_big(1, 1)
 25            + module.bytes_of_vec_znx_dft(1, 1)
 26            + GLWESecret::bytes_of(RingDegree(module.n() as u32), Rank(1))
 27            + GLWESwitchingKey::encrypt_sk_tmp_bytes(module, infos)
 28    }
 29}
 30
 31impl<DataSelf: DataMut> TensorKey<DataSelf> {
 32    pub fn encrypt_sk<DataSk: DataRef, B: Backend>(
 33        &mut self,
 34        module: &Module<B>,
 35        sk: &GLWESecret<DataSk>,
 36        source_xa: &mut Source,
 37        source_xe: &mut Source,
 38        scratch: &mut Scratch<B>,
 39    ) where
 40        Module<B>: SvpApplyDftToDft<B>
 41            + VecZnxIdftApplyTmpA<B>
 42            + VecZnxAddScalarInplace
 43            + VecZnxDftBytesOf
 44            + VecZnxBigNormalize<B>
 45            + VecZnxDftApply<B>
 46            + SvpApplyDftToDftInplace<B>
 47            + VecZnxIdftApplyConsume<B>
 48            + VecZnxNormalizeTmpBytes
 49            + VecZnxFillUniform
 50            + VecZnxSubInplace
 51            + VecZnxAddInplace
 52            + VecZnxNormalizeInplace<B>
 53            + VecZnxAddNormal
 54            + VecZnxNormalize<B>
 55            + VecZnxSub
 56            + SvpPrepare<B>
 57            + VecZnxSwitchRing
 58            + SvpPPolBytesOf,
 59        Scratch<B>:,
 60    {
 61        #[cfg(debug_assertions)]
 62        {
 63            assert_eq!(self.rank_out(), sk.rank());
 64            assert_eq!(self.n(), sk.n());
 65        }
 66
 67        let n: RingDegree = sk.n();
 68        let rank: Rank = self.rank_out();
 69
 70        let (mut sk_dft_prep, scratch_1) = scratch.take_glwe_secret_prepared(n, rank);
 71        sk_dft_prep.prepare(module, sk, scratch_1);
 72
 73        let (mut sk_dft, scratch_2) = scratch_1.take_vec_znx_dft(n.into(), rank.into(), 1);
 74
 75        (0..rank.into()).for_each(|i| {
 76            module.vec_znx_dft_apply(1, 0, &mut sk_dft, i, &sk.data.as_vec_znx(), i);
 77        });
 78
 79        let (mut sk_ij_big, scratch_3) = scratch_2.take_vec_znx_big(n.into(), 1, 1);
 80        let (mut sk_ij, scratch_4) = scratch_3.take_glwe_secret(n, Rank(1));
 81        let (mut sk_ij_dft, scratch_5) = scratch_4.take_vec_znx_dft(n.into(), 1, 1);
 82
 83        (0..rank.into()).for_each(|i| {
 84            (i..rank.into()).for_each(|j| {
 85                module.svp_apply_dft_to_dft(&mut sk_ij_dft, 0, &sk_dft_prep.data, j, &sk_dft, i);
 86
 87                module.vec_znx_idft_apply_tmpa(&mut sk_ij_big, 0, &mut sk_ij_dft, 0);
 88                module.vec_znx_big_normalize(
 89                    self.base2k().into(),
 90                    &mut sk_ij.data.as_vec_znx_mut(),
 91                    0,
 92                    self.base2k().into(),
 93                    &sk_ij_big,
 94                    0,
 95                    scratch_5,
 96                );
 97
 98                self.at_mut(i, j)
 99                    .encrypt_sk(module, &sk_ij, sk, source_xa, source_xe, scratch_5);
100            });
101        })
102    }
103}