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