arnaucube
arnaucube/poulpyPublic Self-hosted repository
poulpy/poulpy-core/src/encryption/gglwe_ksk.rs
poulpy-core/src/encryption/gglwe_ksk.rsRaw
  1use poulpy_hal::{
  2    api::{
  3        ModuleN, ScratchAvailable, SvpApplyDftToDftInplace, SvpPPolAlloc, SvpPPolBytesOf, SvpPrepare, VecZnxAddInplace, VecZnxAddNormal,
  4        VecZnxAddScalarInplace, VecZnxBigNormalize, VecZnxDftApply, VecZnxDftBytesOf, VecZnxFillUniform, VecZnxIdftApplyConsume,
  5        VecZnxNormalize, VecZnxNormalizeInplace, VecZnxNormalizeTmpBytes, VecZnxSub, VecZnxSubInplace, VecZnxSwitchRing,
  6        ScratchTakeBasic,
  7    },
  8    layouts::{Backend, DataMut, DataRef, Module, ScalarZnx, Scratch},
  9    source::Source,
 10};
 11
 12use crate::{
 13    ScratchTakeCore,
 14    layouts::{
 15        GGLWE, GGLWEInfos, GLWEInfos, GLWESecret, GLWESecretToRef, GLWESwitchingKey, GLWESwitchingKeyToMut, LWEInfos, prepared::GLWESecretPrepared,
 16    },
 17    encryption::gglwe_ct::GGLWEEncryptSk,
 18};
 19
 20impl GLWESwitchingKey<Vec<u8>> {
 21    pub fn encrypt_sk_tmp_bytes<M, A, BE: Backend>(module: &M, infos: &A) -> usize
 22    where
 23        A: GGLWEInfos,
 24        M: GLWESwitchingKeyEncryptSk<BE>,
 25    {
 26        module.glwe_switching_key_encrypt_sk_tmp_bytes(infos)
 27    }
 28
 29    pub fn encrypt_pk_tmp_bytes<M, A, BE: Backend>(module: &M, infos: &A) -> usize
 30    where
 31        A: GGLWEInfos,
 32        M: GLWESwitchingKeyEncryptPk<BE>,
 33    {
 34        module.glwe_switching_key_encrypt_pk_tmp_bytes(infos)
 35    }
 36}
 37
 38impl<DataSelf: DataMut> GLWESwitchingKey<DataSelf> {
 39
 40    pub fn encrypt_sk<M, DataSkIn: DataRef, DataSkOut: DataRef, BE: Backend>(
 41        &mut self,
 42        module: &M,
 43        sk_in: &GLWESecret<DataSkIn>,
 44        sk_out: &GLWESecret<DataSkOut>,
 45        source_xa: &mut Source,
 46        source_xe: &mut Source,
 47        scratch: &mut Scratch<BE>,
 48    ) where
 49        M: GLWESwitchingKeyEncryptSk<BE>,
 50        Scratch<BE>: ScratchAvailable + ScratchTakeCore<BE>,
 51    {
 52        module.glwe_switching_key_encrypt_sk(self, sk_in, sk_out, source_xa, source_xe, scratch);
 53    }
 54
 55
 56    // #[allow(clippy::too_many_arguments)]
 57    // pub fn encrypt_sk<DataSkIn: DataRef, DataSkOut: DataRef, B: Backend>(
 58    //     &mut self,
 59    //     module: &Module<B>,
 60    //     sk_in: &GLWESecret<DataSkIn>,
 61    //     sk_out: &GLWESecret<DataSkOut>,
 62    //     source_xa: &mut Source,
 63    //     source_xe: &mut Source,
 64    //     scratch: &mut Scratch<B>,
 65    // ) where
 66    //     Module<B>: ModuleN
 67    //         + VecZnxAddScalarInplace
 68    //         + VecZnxDftBytesOf
 69    //         + VecZnxBigNormalize<B>
 70    //         + VecZnxDftApply<B>
 71    //         + SvpApplyDftToDftInplace<B>
 72    //         + VecZnxIdftApplyConsume<B>
 73    //         + VecZnxNormalizeTmpBytes
 74    //         + VecZnxFillUniform
 75    //         + VecZnxSubInplace
 76    //         + VecZnxAddInplace
 77    //         + VecZnxNormalizeInplace<B>
 78    //         + VecZnxAddNormal
 79    //         + VecZnxNormalize<B>
 80    //         + VecZnxSub
 81    //         + SvpPrepare<B>
 82    //         + VecZnxSwitchRing
 83    //         + SvpPPolBytesOf
 84    //         + SvpPPolAlloc<B>,
 85    //     Scratch<B>: ScratchAvailable + ScratchTakeBasic + ScratchTakeCore<B>,
 86    // {
 87    //     #[cfg(debug_assertions)]
 88    //     {
 89    //         assert!(sk_in.n().0 <= module.n() as u32);
 90    //         assert!(sk_out.n().0 <= module.n() as u32);
 91    //         assert!(
 92    //             scratch.available() >= GLWESwitchingKey::encrypt_sk_tmp_bytes(module, self),
 93    //             "scratch.available()={} < GLWESwitchingKey::encrypt_sk_tmp_bytes={}",
 94    //             scratch.available(),
 95    //             GLWESwitchingKey::encrypt_sk_tmp_bytes(module, self)
 96    //         )
 97    //     }
 98
 99    //     // let n: usize = sk_in.n().max(sk_out.n()).into();
100
101    //     let (mut sk_in_tmp, scratch_1) = scratch.take_scalar_znx(module, sk_in.rank().into());
102    //     (0..sk_in.rank().into()).for_each(|i| {
103    //         module.vec_znx_switch_ring(
104    //             &mut sk_in_tmp.as_vec_znx_mut(),
105    //             i,
106    //             &sk_in.data.as_vec_znx(),
107    //             i,
108    //         );
109    //     });
110
111    //     let (mut sk_out_tmp, scratch_2) = scratch_1.take_glwe_secret_prepared(module, sk_out.rank());
112    //     {
113    //         let (mut tmp, _) = scratch_2.take_scalar_znx(module, 1);
114    //         (0..sk_out.rank().into()).for_each(|i| {
115    //             module.vec_znx_switch_ring(&mut tmp.as_vec_znx_mut(), 0, &sk_out.data.as_vec_znx(), i);
116    //             module.svp_prepare(&mut sk_out_tmp.data, i, &tmp, 0);
117    //         });
118    //     }
119
120    //     self.key.encrypt_sk(
121    //         module,
122    //         &sk_in_tmp,
123    //         &sk_out_tmp,
124    //         source_xa,
125    //         source_xe,
126    //         scratch_2,
127    //     );
128    //     self.sk_in_n = sk_in.n().into();
129    //     self.sk_out_n = sk_out.n().into();
130    // }
131}
132
133
134pub trait GLWESwitchingKeyEncryptSk<BE: Backend> 
135where
136    Self: Sized
137        + ModuleN
138        + SvpPPolBytesOf
139        + VecZnxDftBytesOf
140        + VecZnxNormalizeTmpBytes
141        + SvpPPolAlloc<BE>
142        + GGLWEEncryptSk<BE>,
143{
144    fn glwe_switching_key_encrypt_sk_tmp_bytes<A>(&self, infos: &A) -> usize
145    where
146        A: GGLWEInfos;
147
148    fn glwe_switching_key_encrypt_sk<R, DataSkIn, DataSkOut>(
149        &self,
150        res: &mut R,
151        sk_in: &GLWESecret<DataSkIn>,
152        sk_out: &GLWESecret<DataSkOut>,
153        source_xa: &mut Source,
154        source_xe: &mut Source,
155        scratch: &mut Scratch<BE>,
156    ) 
157    where 
158        R: GLWESwitchingKeyToMut,
159        DataSkIn: DataRef,
160        DataSkOut: DataRef,
161        Scratch<BE>: ScratchAvailable + ScratchTakeCore<BE>;
162
163}
164
165impl<BE: Backend> GLWESwitchingKeyEncryptSk<BE> for Module<BE> where
166    Self: ModuleN
167        + SvpPPolBytesOf
168        + VecZnxDftBytesOf
169        + VecZnxNormalizeTmpBytes
170        + SvpPPolAlloc<BE>
171        + GGLWEEncryptSk<BE>
172        + VecZnxSwitchRing
173        + SvpPrepare<BE>
174        + VecZnxIdftApplyConsume<BE>
175        + VecZnxNormalize<BE>
176        + VecZnxNormalizeInplace<BE>
177        + VecZnxAddInplace
178        + VecZnxAddNormal
179        + VecZnxSub
180{
181
182    fn glwe_switching_key_encrypt_sk_tmp_bytes<A>(&self, infos: &A) -> usize
183    where
184        A: GGLWEInfos,
185    {
186        (GGLWE::encrypt_sk_tmp_bytes(self, infos) | ScalarZnx::bytes_of(self.n(), 1))
187            + ScalarZnx::bytes_of(self.n(), infos.rank_in().into())
188            + GLWESecretPrepared::bytes_of_from_infos(self, &infos.glwe_layout())
189    }
190
191    fn glwe_switching_key_encrypt_sk<R, DataSkIn, DataSkOut>(
192        &self,
193        res: &mut R,
194        sk_in: &GLWESecret<DataSkIn>,
195        sk_out: &GLWESecret<DataSkOut>,
196        source_xa: &mut Source,
197        source_xe: &mut Source,
198        scratch: &mut Scratch<BE>,
199    ) 
200    where 
201        R: GLWESwitchingKeyToMut,
202        DataSkIn: DataRef,
203        DataSkOut: DataRef,
204        Scratch<BE>: ScratchAvailable + ScratchTakeCore<BE>,
205    {
206
207        let res: &mut GLWESwitchingKey<&mut [u8]> = &mut res.to_mut();
208        let sk_in: &GLWESecret<&[u8]> = &sk_in.to_ref();
209        let sk_out: &GLWESecret<&[u8]> = &sk_out.to_ref();
210
211        #[cfg(debug_assertions)]
212        {
213            assert!(sk_in.n().0 <= self.n() as u32);
214            assert!(sk_out.n().0 <= self.n() as u32);
215            assert!(
216                scratch.available() >= GLWESwitchingKey::encrypt_sk_tmp_bytes(self, res),
217                "scratch.available()={} < GLWESwitchingKey::encrypt_sk_tmp_bytes={}",
218                scratch.available(),
219                GLWESwitchingKey::encrypt_sk_tmp_bytes(self, res)
220            )
221        }
222
223        // let n: usize = sk_in.n().max(sk_out.n()).into();
224
225        let (mut sk_in_tmp, scratch_1) = scratch.take_scalar_znx(self, sk_in.rank().into());
226        (0..sk_in.rank().into()).for_each(|i| {
227            self.vec_znx_switch_ring(
228                &mut sk_in_tmp.as_vec_znx_mut(),
229                i,
230                &sk_in.data.as_vec_znx(),
231                i,
232            );
233        });
234
235        let (mut sk_out_tmp, scratch_2) = scratch_1.take_glwe_secret_prepared(self, sk_out.rank());
236        {
237            let (mut tmp, _) = scratch_2.take_scalar_znx(self, 1);
238            (0..sk_out.rank().into()).for_each(|i| {
239                self.vec_znx_switch_ring(&mut tmp.as_vec_znx_mut(), 0, &sk_out.data.as_vec_znx(), i);
240                self.svp_prepare(&mut sk_out_tmp.data, i, &tmp, 0);
241            });
242        }
243
244        res.key.encrypt_sk(
245            self,
246            &sk_in_tmp,
247            &sk_out_tmp,
248            source_xa,
249            source_xe,
250            scratch_2,
251        );
252        res.sk_in_n = sk_in.n().into();
253        res.sk_out_n = sk_out.n().into();
254    }    
255
256}
257
258pub trait GLWESwitchingKeyEncryptPk<BE: Backend> 
259where
260    Self: Sized
261        + ModuleN
262        + SvpPPolBytesOf
263        + VecZnxDftBytesOf
264        + VecZnxNormalizeTmpBytes
265        + SvpPPolAlloc<BE>
266        + GGLWEEncryptSk<BE>,
267{
268
269    fn glwe_switching_key_encrypt_pk_tmp_bytes<A>(&self, infos: &A) -> usize
270    where
271        A: GGLWEInfos;
272}
273
274impl<BE: Backend> GLWESwitchingKeyEncryptPk<BE> for Module<BE> where
275    Self: ModuleN
276        + SvpPPolBytesOf
277        + VecZnxDftBytesOf
278        + VecZnxNormalizeTmpBytes
279        + SvpPPolAlloc<BE>
280        + GGLWEEncryptSk<BE>,
281{
282
283    fn glwe_switching_key_encrypt_pk_tmp_bytes<A>(&self, infos: &A) -> usize
284    where
285        A: GGLWEInfos,
286    {
287        GGLWE::encrypt_pk_tmp_bytes(self, infos)
288    }
289}