arnaucube
arnaucube/poulpyPublic Self-hosted repository
poulpy/poulpy-core/src/encryption/lwe_ksk.rs
poulpy-core/src/encryption/lwe_ksk.rsRaw
  1use poulpy_hal::{
  2    api::{
  3        ModuleN, SvpApplyDftToDftInplace, SvpPPolAlloc, SvpPPolBytesOf, SvpPrepare, VecZnxAddInplace, VecZnxAddNormal, VecZnxAddScalarInplace,
  4        VecZnxAutomorphismInplace, VecZnxBigNormalize, VecZnxDftApply, VecZnxDftBytesOf, VecZnxFillUniform,
  5        VecZnxIdftApplyConsume, VecZnxNormalize, VecZnxNormalizeInplace, VecZnxNormalizeTmpBytes, VecZnxSub, VecZnxSubInplace,
  6        VecZnxSwitchRing,
  7    },
  8    layouts::{Backend, DataMut, DataRef, Module, Scratch, ZnxView, ZnxViewMut},
  9    source::Source,
 10};
 11
 12use crate::{
 13    layouts::{
 14        GLWESecretAlloc,
 15        GGLWEInfos, GLWESecret, GLWESwitchingKey, LWEInfos, LWESecret, LWESwitchingKey, Rank,
 16        prepared::{GLWESecretPrepared, GLWESecretPreparedAlloc},
 17    },
 18    ScratchTakeCore, 
 19};
 20
 21impl LWESwitchingKey<Vec<u8>> {
 22    pub fn encrypt_sk_tmp_bytes<M, A, BE: Backend>(module: &M, infos: &A) -> usize
 23    where
 24        A: GGLWEInfos,
 25        M: LWESwitchingKeyEncrypt<BE>,
 26    {
 27        module.lwe_switching_key_encrypt_sk_tmp_bytes(infos)
 28    }
 29    
 30    // pub fn encrypt_sk_tmp_bytes<B: Backend, A>(module: &Module<B>, infos: &A) -> usize
 31    // where
 32    //     A: GGLWEInfos,
 33    //     Module<B>: ModuleN + SvpPPolBytesOf + SvpPPolAlloc<B> + VecZnxNormalizeTmpBytes + VecZnxDftBytesOf + VecZnxNormalizeTmpBytes,
 34    // {
 35    //     debug_assert_eq!(
 36    //         infos.dsize().0,
 37    //         1,
 38    //         "dsize > 1 is not supported for LWESwitchingKey"
 39    //     );
 40    //     debug_assert_eq!(
 41    //         infos.rank_in().0,
 42    //         1,
 43    //         "rank_in > 1 is not supported for LWESwitchingKey"
 44    //     );
 45    //     debug_assert_eq!(
 46    //         infos.rank_out().0,
 47    //         1,
 48    //         "rank_out > 1 is not supported for LWESwitchingKey"
 49    //     );
 50    //     GLWESecret::bytes_of(module, Rank(1))
 51    //         + GLWESecretPrepared::bytes_of(module, Rank(1))
 52    //         + GLWESwitchingKey::encrypt_sk_tmp_bytes(module, infos)
 53    // }
 54}
 55
 56impl<D: DataMut> LWESwitchingKey<D> {
 57    #[allow(clippy::too_many_arguments)]
 58    pub fn encrypt_sk<DIn, DOut, B: Backend>(
 59        &mut self,
 60        module: &Module<B>,
 61        sk_lwe_in: &LWESecret<DIn>,
 62        sk_lwe_out: &LWESecret<DOut>,
 63        source_xa: &mut Source,
 64        source_xe: &mut Source,
 65        scratch: &mut Scratch<B>,
 66    ) where
 67        DIn: DataRef,
 68        DOut: DataRef,
 69        Module<B>: ModuleN
 70            + VecZnxAutomorphismInplace<B>
 71            + VecZnxAddScalarInplace
 72            + VecZnxDftBytesOf
 73            + VecZnxBigNormalize<B>
 74            + VecZnxDftApply<B>
 75            + SvpApplyDftToDftInplace<B>
 76            + VecZnxIdftApplyConsume<B>
 77            + VecZnxNormalizeTmpBytes
 78            + VecZnxFillUniform
 79            + VecZnxSubInplace
 80            + VecZnxAddInplace
 81            + VecZnxNormalizeInplace<B>
 82            + VecZnxAddNormal
 83            + VecZnxNormalize<B>
 84            + VecZnxSub
 85            + SvpPrepare<B>
 86            + VecZnxSwitchRing
 87            + SvpPPolBytesOf
 88            + SvpPPolAlloc<B>,
 89        Scratch<B>: ScratchTakeCore<B>,
 90    {
 91        #[cfg(debug_assertions)]
 92        {
 93            assert!(sk_lwe_in.n().0 <= self.n().0);
 94            assert!(sk_lwe_out.n().0 <= self.n().0);
 95            assert!(self.n().0 <= module.n() as u32);
 96        }
 97
 98        let (mut sk_in_glwe, scratch_1) = scratch.take_glwe_secret(module, Rank(1));
 99        let (mut sk_out_glwe, scratch_2) = scratch_1.take_glwe_secret(module, Rank(1));
100
101        sk_out_glwe.data.at_mut(0, 0)[..sk_lwe_out.n().into()].copy_from_slice(sk_lwe_out.data.at(0, 0));
102        sk_out_glwe.data.at_mut(0, 0)[sk_lwe_out.n().into()..].fill(0);
103        module.vec_znx_automorphism_inplace(-1, &mut sk_out_glwe.data.as_vec_znx_mut(), 0, scratch_2);
104
105        sk_in_glwe.data.at_mut(0, 0)[..sk_lwe_in.n().into()].copy_from_slice(sk_lwe_in.data.at(0, 0));
106        sk_in_glwe.data.at_mut(0, 0)[sk_lwe_in.n().into()..].fill(0);
107        module.vec_znx_automorphism_inplace(-1, &mut sk_in_glwe.data.as_vec_znx_mut(), 0, scratch_2);
108
109        self.0.encrypt_sk(
110            module,
111            &sk_in_glwe,
112            &sk_out_glwe,
113            source_xa,
114            source_xe,
115            scratch_2,
116        );
117    }
118}
119
120pub trait LWESwitchingKeyEncrypt<BE: Backend>
121where 
122    Self: Sized
123        + ModuleN
124        + SvpPPolBytesOf
125        + SvpPPolAlloc<BE>
126        + VecZnxNormalizeTmpBytes
127        + VecZnxDftBytesOf
128        + VecZnxAutomorphismInplace<BE>
129        + VecZnxAddScalarInplace
130        + VecZnxBigNormalize<BE>
131        + VecZnxDftApply<BE>
132        + SvpApplyDftToDftInplace<BE>
133        + VecZnxIdftApplyConsume<BE>
134        + VecZnxFillUniform
135        + VecZnxSubInplace
136        + VecZnxAddInplace
137        + VecZnxNormalizeInplace<BE>
138        + VecZnxAddNormal
139        + VecZnxNormalize<BE>
140        + VecZnxSub
141        + SvpPrepare<BE>
142        + VecZnxSwitchRing
143        + GLWESecretAlloc
144        + GLWESecretPreparedAlloc<BE>
145{
146    fn lwe_switching_key_encrypt_sk_tmp_bytes<A>(&self, infos: &A) -> usize
147    where
148        A: GGLWEInfos;
149}
150
151impl<BE:Backend> LWESwitchingKeyEncrypt<BE> for Module<BE> where 
152    Self: ModuleN
153        + SvpPPolBytesOf
154        + SvpPPolAlloc<BE>
155        + VecZnxNormalizeTmpBytes
156        + VecZnxDftBytesOf
157        + VecZnxAutomorphismInplace<BE>
158        + VecZnxAddScalarInplace
159        + VecZnxBigNormalize<BE>
160        + VecZnxDftApply<BE>
161        + SvpApplyDftToDftInplace<BE>
162        + VecZnxIdftApplyConsume<BE>
163        + VecZnxFillUniform
164        + VecZnxSubInplace
165        + VecZnxAddInplace
166        + VecZnxNormalizeInplace<BE>
167        + VecZnxAddNormal
168        + VecZnxNormalize<BE>
169        + VecZnxSub
170        + SvpPrepare<BE>
171        + VecZnxSwitchRing
172        + GLWESecretAlloc
173        + GLWESecretPreparedAlloc<BE>
174{
175    fn lwe_switching_key_encrypt_sk_tmp_bytes<A>(&self, infos: &A) -> usize
176    where
177        A: GGLWEInfos
178    {
179        debug_assert_eq!(
180            infos.dsize().0,
181            1,
182            "dsize > 1 is not supported for LWESwitchingKey"
183        );
184        debug_assert_eq!(
185            infos.rank_in().0,
186            1,
187            "rank_in > 1 is not supported for LWESwitchingKey"
188        );
189        debug_assert_eq!(
190            infos.rank_out().0,
191            1,
192            "rank_out > 1 is not supported for LWESwitchingKey"
193        );
194        GLWESecret::bytes_of(self, Rank(1))
195            + GLWESecretPrepared::bytes_of(self, Rank(1))
196            + GLWESwitchingKey::encrypt_sk_tmp_bytes(self, infos)
197    }
198}