poulpy/poulpy-core/src/encryption/gglwe_atk.rs
poulpy-core/src/encryption/gglwe_atk.rsRaw
1use poulpy_hal::{
2 api::{
3 ScratchAvailable, SvpApplyDftToDftInplace, SvpPPolAllocBytes, SvpPrepare, TakeScalarZnx, TakeVecZnx, TakeVecZnxDft,
4 VecZnxAddInplace, VecZnxAddNormal, VecZnxAddScalarInplace, VecZnxAutomorphism, VecZnxBigNormalize, VecZnxDftAllocBytes,
5 VecZnxDftApply, VecZnxFillUniform, VecZnxIdftApplyConsume, VecZnxNormalize, VecZnxNormalizeInplace,
6 VecZnxNormalizeTmpBytes, VecZnxSub, VecZnxSubInplace, VecZnxSwitchRing,
7 },
8 layouts::{Backend, DataMut, Module, Scratch},
9 source::Source,
10};
11
12use crate::{
13 TakeGLWESecret, TakeGLWESecretPrepared,
14 layouts::{
15 GGLWEAutomorphismKey, GGLWEAutomorphismKeyToMut, GGLWEInfos, GGLWESwitchingKey, GLWEInfos, GLWESecret, GLWESecretToRef,
16 LWEInfos,
17 },
18};
19
20impl GGLWEAutomorphismKey<Vec<u8>> {
21 pub fn encrypt_sk_scratch_space<BE: Backend, A>(module: &Module<BE>, infos: &A) -> usize
22 where
23 A: GGLWEInfos,
24 Module<BE>: SvpPPolAllocBytes + VecZnxNormalizeTmpBytes + VecZnxDftAllocBytes + VecZnxNormalizeTmpBytes,
25 {
26 assert_eq!(
27 infos.rank_in(),
28 infos.rank_out(),
29 "rank_in != rank_out is not supported for GGLWEAutomorphismKey"
30 );
31 GGLWESwitchingKey::encrypt_sk_scratch_space(module, infos) + GLWESecret::alloc_bytes(&infos.glwe_layout())
32 }
33
34 pub fn encrypt_pk_scratch_space<BE: Backend, A>(module: &Module<BE>, _infos: &A) -> usize
35 where
36 A: GGLWEInfos,
37 {
38 assert_eq!(
39 _infos.rank_in(),
40 _infos.rank_out(),
41 "rank_in != rank_out is not supported for GGLWEAutomorphismKey"
42 );
43 GGLWESwitchingKey::encrypt_pk_scratch_space(module, _infos)
44 }
45}
46
47pub trait GGLWEAutomorphismKeyEncryptSk<BE: Backend> {
48 fn gglwe_automorphism_key_encrypt_sk<A, B>(
49 &self,
50 res: &mut A,
51 p: i64,
52 sk: &B,
53 source_xa: &mut Source,
54 source_xe: &mut Source,
55 scratch: &mut Scratch<BE>,
56 ) where
57 A: GGLWEAutomorphismKeyToMut,
58 B: GLWESecretToRef;
59}
60
61impl<DM: DataMut> GGLWEAutomorphismKey<DM>
62where
63 Self: GGLWEAutomorphismKeyToMut,
64{
65 pub fn encrypt_sk<S, BE: Backend>(
66 &mut self,
67 module: &Module<BE>,
68 p: i64,
69 sk: &S,
70 source_xa: &mut Source,
71 source_xe: &mut Source,
72 scratch: &mut Scratch<BE>,
73 ) where
74 S: GLWESecretToRef,
75 Module<BE>: GGLWEAutomorphismKeyEncryptSk<BE>,
76 {
77 module.gglwe_automorphism_key_encrypt_sk(self, p, sk, source_xa, source_xe, scratch);
78 }
79}
80
81impl<BE: Backend> GGLWEAutomorphismKeyEncryptSk<BE> for Module<BE>
82where
83 Module<BE>: VecZnxAddScalarInplace
84 + VecZnxDftAllocBytes
85 + VecZnxBigNormalize<BE>
86 + VecZnxDftApply<BE>
87 + SvpApplyDftToDftInplace<BE>
88 + VecZnxIdftApplyConsume<BE>
89 + VecZnxNormalizeTmpBytes
90 + VecZnxFillUniform
91 + VecZnxSubInplace
92 + VecZnxAddInplace
93 + VecZnxNormalizeInplace<BE>
94 + VecZnxAddNormal
95 + VecZnxNormalize<BE>
96 + VecZnxSub
97 + SvpPrepare<BE>
98 + VecZnxSwitchRing
99 + SvpPPolAllocBytes
100 + VecZnxAutomorphism,
101 Scratch<BE>: TakeVecZnxDft<BE> + ScratchAvailable + TakeVecZnx + TakeScalarZnx + TakeGLWESecretPrepared<BE>,
102{
103 fn gglwe_automorphism_key_encrypt_sk<A, B>(
104 &self,
105 res: &mut A,
106 p: i64,
107 sk: &B,
108 source_xa: &mut Source,
109 source_xe: &mut Source,
110 scratch: &mut Scratch<BE>,
111 ) where
112 A: GGLWEAutomorphismKeyToMut,
113 B: GLWESecretToRef,
114 {
115 let res: &mut GGLWEAutomorphismKey<&mut [u8]> = &mut res.to_mut();
116 let sk: &GLWESecret<&[u8]> = &sk.to_ref();
117
118 #[cfg(debug_assertions)]
119 {
120 use crate::layouts::{GLWEInfos, LWEInfos};
121
122 assert_eq!(res.n(), sk.n());
123 assert_eq!(res.rank_out(), res.rank_in());
124 assert_eq!(sk.rank(), res.rank_out());
125 assert!(
126 scratch.available() >= GGLWEAutomorphismKey::encrypt_sk_scratch_space(self, res),
127 "scratch.available(): {} < AutomorphismKey::encrypt_sk_scratch_space: {:?}",
128 scratch.available(),
129 GGLWEAutomorphismKey::encrypt_sk_scratch_space(self, res)
130 )
131 }
132
133 let (mut sk_out, scratch_1) = scratch.take_glwe_secret(sk.n(), sk.rank());
134
135 {
136 (0..res.rank_out().into()).for_each(|i| {
137 self.vec_znx_automorphism(
138 self.galois_element_inv(p),
139 &mut sk_out.data.as_vec_znx_mut(),
140 i,
141 &sk.data.as_vec_znx(),
142 i,
143 );
144 });
145 }
146
147 res.key
148 .encrypt_sk(self, sk, &sk_out, source_xa, source_xe, scratch_1);
149
150 res.p = p;
151 }
152}