poulpy/poulpy-core/src/encryption/gglwe_ksk.rs
poulpy-core/src/encryption/gglwe_ksk.rsRaw
1use poulpy_hal::{
2 api::{ModuleN, ScratchAvailable, ScratchTakeBasic, SvpPrepare, VecZnxSwitchRing},
3 layouts::{Backend, DataMut, Module, ScalarZnx, Scratch},
4 source::Source,
5};
6
7use crate::{
8 ScratchTakeCore,
9 encryption::gglwe_ct::GGLWEEncryptSk,
10 layouts::{
11 GGLWEInfos, GLWEInfos, GLWESecret, GLWESecretToRef, GLWESwitchingKey, GLWESwitchingKeyToMut, LWEInfos,
12 prepared::GLWESecretPreparedAlloc,
13 },
14};
15
16impl GLWESwitchingKey<Vec<u8>> {
17 pub fn encrypt_sk_tmp_bytes<M, A, BE: Backend>(module: &M, infos: &A) -> usize
18 where
19 A: GGLWEInfos,
20 M: GLWESwitchingKeyEncryptSk<BE>,
21 {
22 module.glwe_switching_key_encrypt_sk_tmp_bytes(infos)
23 }
24
25 pub fn encrypt_pk_tmp_bytes<M, A, BE: Backend>(module: &M, infos: &A) -> usize
26 where
27 A: GGLWEInfos,
28 M: GLWESwitchingKeyEncryptPk<BE>,
29 {
30 module.glwe_switching_key_encrypt_pk_tmp_bytes(infos)
31 }
32}
33
34impl<DataSelf: DataMut> GLWESwitchingKey<DataSelf> {
35 pub fn encrypt_sk<M, S1, S2, BE: Backend>(
36 &mut self,
37 module: &M,
38 sk_in: &S1,
39 sk_out: &S2,
40 source_xa: &mut Source,
41 source_xe: &mut Source,
42 scratch: &mut Scratch<BE>,
43 ) where
44 S1: GLWESecretToRef,
45 S2: GLWESecretToRef,
46 M: GLWESwitchingKeyEncryptSk<BE>,
47 Scratch<BE>: ScratchTakeCore<BE>,
48 {
49 module.glwe_switching_key_encrypt_sk(self, sk_in, sk_out, source_xa, source_xe, scratch);
50 }
51}
52
53pub trait GLWESwitchingKeyEncryptSk<BE: Backend> {
54 fn glwe_switching_key_encrypt_sk_tmp_bytes<A>(&self, infos: &A) -> usize
55 where
56 A: GGLWEInfos;
57
58 fn glwe_switching_key_encrypt_sk<R, S1, S2>(
59 &self,
60 res: &mut R,
61 sk_in: &S1,
62 sk_out: &S2,
63 source_xa: &mut Source,
64 source_xe: &mut Source,
65 scratch: &mut Scratch<BE>,
66 ) where
67 R: GLWESwitchingKeyToMut,
68 S1: GLWESecretToRef,
69 S2: GLWESecretToRef;
70}
71
72impl<BE: Backend> GLWESwitchingKeyEncryptSk<BE> for Module<BE>
73where
74 Self: ModuleN + GGLWEEncryptSk<BE> + GLWESecretPreparedAlloc<BE> + VecZnxSwitchRing + SvpPrepare<BE>,
75 Scratch<BE>: ScratchTakeCore<BE>,
76{
77 fn glwe_switching_key_encrypt_sk_tmp_bytes<A>(&self, infos: &A) -> usize
78 where
79 A: GGLWEInfos,
80 {
81 self.gglwe_encrypt_sk_tmp_bytes(infos)
82 .max(ScalarZnx::bytes_of(self.n(), 1))
83 + ScalarZnx::bytes_of(self.n(), infos.rank_in().into())
84 + self.bytes_of_glwe_secret_prepared_from_infos(infos)
85 }
86
87 fn glwe_switching_key_encrypt_sk<R, S1, S2>(
88 &self,
89 res: &mut R,
90 sk_in: &S1,
91 sk_out: &S2,
92 source_xa: &mut Source,
93 source_xe: &mut Source,
94 scratch: &mut Scratch<BE>,
95 ) where
96 R: GLWESwitchingKeyToMut,
97 S1: GLWESecretToRef,
98 S2: GLWESecretToRef,
99 {
100 let res: &mut GLWESwitchingKey<&mut [u8]> = &mut res.to_mut();
101 let sk_in: &GLWESecret<&[u8]> = &sk_in.to_ref();
102 let sk_out: &GLWESecret<&[u8]> = &sk_out.to_ref();
103
104 assert!(sk_in.n().0 <= self.n() as u32);
105 assert!(sk_out.n().0 <= self.n() as u32);
106 assert!(
107 scratch.available() >= self.glwe_switching_key_encrypt_sk_tmp_bytes(res),
108 "scratch.available()={} < GLWESwitchingKey::encrypt_sk_tmp_bytes={}",
109 scratch.available(),
110 self.glwe_switching_key_encrypt_sk_tmp_bytes(res)
111 );
112
113 let (mut sk_in_tmp, scratch_1) = scratch.take_scalar_znx(self, sk_in.rank().into());
114 for i in 0..sk_in.rank().into() {
115 self.vec_znx_switch_ring(
116 &mut sk_in_tmp.as_vec_znx_mut(),
117 i,
118 &sk_in.data.as_vec_znx(),
119 i,
120 );
121 }
122
123 let (mut sk_out_tmp, scratch_2) = scratch_1.take_glwe_secret_prepared(self, sk_out.rank());
124 {
125 let (mut tmp, _) = scratch_2.take_scalar_znx(self, 1);
126 for i in 0..sk_out.rank().into() {
127 self.vec_znx_switch_ring(&mut tmp.as_vec_znx_mut(), 0, &sk_out.data.as_vec_znx(), i);
128 self.svp_prepare(&mut sk_out_tmp.data, i, &tmp, 0);
129 }
130 }
131
132 res.key.encrypt_sk(
133 self,
134 &sk_in_tmp,
135 &sk_out_tmp,
136 source_xa,
137 source_xe,
138 scratch_2,
139 );
140 res.sk_in_n = sk_in.n().into();
141 res.sk_out_n = sk_out.n().into();
142 }
143}
144
145pub trait GLWESwitchingKeyEncryptPk<BE: Backend> {
146 fn glwe_switching_key_encrypt_pk_tmp_bytes<A>(&self, infos: &A) -> usize
147 where
148 A: GGLWEInfos;
149}
150
151impl<BE: Backend> GLWESwitchingKeyEncryptPk<BE> for Module<BE> {
152 fn glwe_switching_key_encrypt_pk_tmp_bytes<A>(&self, _infos: &A) -> usize
153 where
154 A: GGLWEInfos,
155 {
156 unimplemented!()
157 }
158}