1use poulpy_hal::{
2 api::{ModuleN, VecZnxAutomorphismInplace, VecZnxAutomorphismInplaceTmpBytes},
3 layouts::{Backend, DataMut, Module, Scratch, ZnxView, ZnxViewMut},
4 source::Source,
5};
6
7use crate::{
8 GGLWEEncryptSk, ScratchTakeCore,
9 layouts::{
10 GGLWE, GGLWEInfos, GGLWEToMut, GLWESecret, GLWESecretPreparedFactory, GLWESecretPreparedToRef, LWEInfos, LWESecret,
11 LWESecretToRef, LWEToGLWEKey, Rank,
12 },
13};
14
15impl LWEToGLWEKey<Vec<u8>> {
16 pub fn encrypt_sk_tmp_bytes<M, A, BE: Backend>(module: &M, infos: &A) -> usize
17 where
18 A: GGLWEInfos,
19 M: LWEToGLWESwitchingKeyEncryptSk<BE>,
20 {
21 module.lwe_to_glwe_key_encrypt_sk_tmp_bytes(infos)
22 }
23}
24
25impl<D: DataMut> LWEToGLWEKey<D> {
26 pub fn encrypt_sk<S1, S2, M, BE: Backend>(
27 &mut self,
28 module: &M,
29 sk_lwe: &S1,
30 sk_glwe: &S2,
31 source_xa: &mut Source,
32 source_xe: &mut Source,
33 scratch: &mut Scratch<BE>,
34 ) where
35 S1: LWESecretToRef,
36 S2: GLWESecretPreparedToRef<BE>,
37 M: LWEToGLWESwitchingKeyEncryptSk<BE>,
38 Scratch<BE>: ScratchTakeCore<BE>,
39 {
40 module.lwe_to_glwe_key_encrypt_sk(self, sk_lwe, sk_glwe, source_xa, source_xe, scratch);
41 }
42}
43
44pub trait LWEToGLWESwitchingKeyEncryptSk<BE: Backend> {
45 fn lwe_to_glwe_key_encrypt_sk_tmp_bytes<A>(&self, infos: &A) -> usize
46 where
47 A: GGLWEInfos;
48
49 fn lwe_to_glwe_key_encrypt_sk<R, S1, S2>(
50 &self,
51 res: &mut R,
52 sk_lwe: &S1,
53 sk_glwe: &S2,
54 source_xa: &mut Source,
55 source_xe: &mut Source,
56 scratch: &mut Scratch<BE>,
57 ) where
58 S1: LWESecretToRef,
59 S2: GLWESecretPreparedToRef<BE>,
60 R: GGLWEToMut;
61}
62
63impl<BE: Backend> LWEToGLWESwitchingKeyEncryptSk<BE> for Module<BE>
64where
65 Self: ModuleN
66 + GGLWEEncryptSk<BE>
67 + VecZnxAutomorphismInplace<BE>
68 + GLWESecretPreparedFactory<BE>
69 + VecZnxAutomorphismInplaceTmpBytes,
70 Scratch<BE>: ScratchTakeCore<BE>,
71{
72 fn lwe_to_glwe_key_encrypt_sk_tmp_bytes<A>(&self, infos: &A) -> usize
73 where
74 A: GGLWEInfos,
75 {
76 debug_assert_eq!(
77 infos.rank_in(),
78 Rank(1),
79 "rank_in != 1 is not supported for LWEToGLWEKeyPrepared"
80 );
81 GLWESecret::bytes_of(self.n().into(), infos.rank_in())
82 + GGLWE::encrypt_sk_tmp_bytes(self, infos).max(self.vec_znx_automorphism_inplace_tmp_bytes())
83 }
84
85 fn lwe_to_glwe_key_encrypt_sk<R, S1, S2>(
86 &self,
87 res: &mut R,
88 sk_lwe: &S1,
89 sk_glwe: &S2,
90 source_xa: &mut Source,
91 source_xe: &mut Source,
92 scratch: &mut Scratch<BE>,
93 ) where
94 S1: LWESecretToRef,
95 S2: GLWESecretPreparedToRef<BE>,
96 R: GGLWEToMut,
97 {
98 let sk_lwe: &LWESecret<&[u8]> = &sk_lwe.to_ref();
99
100 assert!(sk_lwe.n().0 <= self.n() as u32);
101
102 let (mut sk_lwe_as_glwe, scratch_1) = scratch.take_glwe_secret(self.n().into(), Rank(1));
103 sk_lwe_as_glwe.dist = sk_lwe.dist;
104
105 sk_lwe_as_glwe.data.at_mut(0, 0)[..sk_lwe.n().into()].copy_from_slice(sk_lwe.data.at(0, 0));
106 sk_lwe_as_glwe.data.at_mut(0, 0)[sk_lwe.n().into()..].fill(0);
107 self.vec_znx_automorphism_inplace(-1, &mut sk_lwe_as_glwe.data.as_vec_znx_mut(), 0, scratch_1);
108
109 self.gglwe_encrypt_sk(
110 res,
111 &sk_lwe_as_glwe.data,
112 sk_glwe,
113 source_xa,
114 source_xe,
115 scratch_1,
116 );
117 }
118}