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        ModuleN, ScratchTakeBasic, SvpApplyDftToDft, VecZnxBigBytesOf, VecZnxBigNormalize, VecZnxDftApply, VecZnxDftBytesOf,
  4        VecZnxIdftApplyTmpA,
  5    },
  6    layouts::{Backend, DataMut, Module, Scratch},
  7    source::Source,
  8};
  9
 10use crate::{
 11    ScratchTakeCore,
 12    encryption::gglwe_ksk::GLWESwitchingKeyEncryptSk,
 13    layouts::{
 14        GGLWEInfos, GLWEInfos, GLWESecret, GLWESecretToRef, GLWESwitchingKey, GetDist, LWEInfos, Rank, TensorKey, TensorKeyToMut,
 15        prepared::{GLWESecretPrepare, GLWESecretPrepared, GLWESecretPreparedAlloc},
 16    },
 17};
 18
 19impl TensorKey<Vec<u8>> {
 20    pub fn encrypt_sk_tmp_bytes<M, A, BE: Backend>(module: &M, infos: &A) -> usize
 21    where
 22        A: GGLWEInfos,
 23        M: TensorKeyEncryptSk<BE>,
 24    {
 25        module.tensor_key_encrypt_sk_tmp_bytes(infos)
 26    }
 27}
 28
 29impl<DataSelf: DataMut> TensorKey<DataSelf> {
 30    pub fn encrypt_sk<M, S, BE: Backend>(
 31        &mut self,
 32        module: &M,
 33        sk: &S,
 34        source_xa: &mut Source,
 35        source_xe: &mut Source,
 36        scratch: &mut Scratch<BE>,
 37    ) where
 38        M: TensorKeyEncryptSk<BE>,
 39        S: GLWESecretToRef + GetDist,
 40        Scratch<BE>: ScratchTakeCore<BE>,
 41    {
 42        module.tensor_key_encrypt_sk(self, sk, source_xa, source_xe, scratch);
 43    }
 44}
 45
 46pub trait TensorKeyEncryptSk<BE: Backend> {
 47    fn tensor_key_encrypt_sk_tmp_bytes<A>(&self, infos: &A) -> usize
 48    where
 49        A: GGLWEInfos;
 50
 51    fn tensor_key_encrypt_sk<R, S>(
 52        &self,
 53        res: &mut R,
 54        sk: &S,
 55        source_xa: &mut Source,
 56        source_xe: &mut Source,
 57        scratch: &mut Scratch<BE>,
 58    ) where
 59        R: TensorKeyToMut,
 60        S: GLWESecretToRef + GetDist;
 61}
 62
 63impl<BE: Backend> TensorKeyEncryptSk<BE> for Module<BE>
 64where
 65    Self: ModuleN
 66        + GLWESwitchingKeyEncryptSk<BE>
 67        + VecZnxDftBytesOf
 68        + VecZnxBigBytesOf
 69        + GLWESecretPreparedAlloc<BE>
 70        + GLWESecretPrepare<BE>
 71        + VecZnxDftApply<BE>
 72        + SvpApplyDftToDft<BE>
 73        + VecZnxIdftApplyTmpA<BE>
 74        + VecZnxBigNormalize<BE>,
 75    Scratch<BE>: ScratchTakeCore<BE>,
 76{
 77    fn tensor_key_encrypt_sk_tmp_bytes<A>(&self, infos: &A) -> usize
 78    where
 79        A: GGLWEInfos,
 80    {
 81        GLWESecretPrepared::bytes_of(self, infos.rank_out())
 82            + self.bytes_of_vec_znx_dft(infos.rank_out().into(), 1)
 83            + self.bytes_of_vec_znx_big(1, 1)
 84            + self.bytes_of_vec_znx_dft(1, 1)
 85            + GLWESecret::bytes_of(self, Rank(1))
 86            + GLWESwitchingKey::encrypt_sk_tmp_bytes(self, infos)
 87    }
 88
 89    fn tensor_key_encrypt_sk<R, S>(
 90        &self,
 91        res: &mut R,
 92        sk: &S,
 93        source_xa: &mut Source,
 94        source_xe: &mut Source,
 95        scratch: &mut Scratch<BE>,
 96    ) where
 97        R: TensorKeyToMut,
 98        S: GLWESecretToRef + GetDist,
 99    {
100        let res: &mut TensorKey<&mut [u8]> = &mut res.to_mut();
101
102        // let n: RingDegree = sk.n();
103        let rank: Rank = res.rank_out();
104
105        let (mut sk_dft_prep, scratch_1) = scratch.take_glwe_secret_prepared(self, rank);
106        sk_dft_prep.prepare(self, sk);
107
108        let sk: &GLWESecret<&[u8]> = &sk.to_ref();
109
110        assert_eq!(res.rank_out(), sk.rank());
111        assert_eq!(res.n(), sk.n());
112
113        let (mut sk_dft, scratch_2) = scratch_1.take_vec_znx_dft(self, rank.into(), 1);
114
115        (0..rank.into()).for_each(|i| {
116            self.vec_znx_dft_apply(1, 0, &mut sk_dft, i, &sk.data.as_vec_znx(), i);
117        });
118
119        let (mut sk_ij_big, scratch_3) = scratch_2.take_vec_znx_big(self, 1, 1);
120        let (mut sk_ij, scratch_4) = scratch_3.take_glwe_secret(self, Rank(1));
121        let (mut sk_ij_dft, scratch_5) = scratch_4.take_vec_znx_dft(self, 1, 1);
122
123        (0..rank.into()).for_each(|i| {
124            (i..rank.into()).for_each(|j| {
125                self.svp_apply_dft_to_dft(&mut sk_ij_dft, 0, &sk_dft_prep.data, j, &sk_dft, i);
126
127                self.vec_znx_idft_apply_tmpa(&mut sk_ij_big, 0, &mut sk_ij_dft, 0);
128                self.vec_znx_big_normalize(
129                    res.base2k().into(),
130                    &mut sk_ij.data.as_vec_znx_mut(),
131                    0,
132                    res.base2k().into(),
133                    &sk_ij_big,
134                    0,
135                    scratch_5,
136                );
137
138                res.at_mut(i, j)
139                    .encrypt_sk(self, &sk_ij, sk, source_xa, source_xe, scratch_5);
140            });
141        })
142    }
143}