poulpy/poulpy-core/src/tests/generics/automorphism/glwe_ct.rs
poulpy-core/src/tests/generics/automorphism/glwe_ct.rsRaw
1use poulpy_hal::{
2 api::{
3 DFT, IDFTConsume, ScratchOwnedAlloc, ScratchOwnedBorrow, SvpApplyInplace, SvpPPolAlloc, SvpPPolAllocBytes, SvpPrepare,
4 VecZnxAddInplace, VecZnxAddNormal, VecZnxAddScalarInplace, VecZnxAutomorphism, VecZnxAutomorphismInplace,
5 VecZnxBigAddInplace, VecZnxBigAddSmallInplace, VecZnxBigAllocBytes, VecZnxBigNormalize, VecZnxBigNormalizeTmpBytes,
6 VecZnxDftAllocBytes, VecZnxFillUniform, VecZnxNormalize, VecZnxNormalizeInplace, VecZnxNormalizeTmpBytes, VecZnxSub,
7 VecZnxSubABInplace, VecZnxSwithcDegree, VmpApplyDftToDft, VmpApplyDftToDftAdd, VmpApplyDftToDftTmpBytes, VmpPMatAlloc,
8 VmpPrepare,
9 },
10 layouts::{Backend, Module, ScratchOwned},
11 oep::{
12 ScratchAvailableImpl, ScratchOwnedAllocImpl, ScratchOwnedBorrowImpl, TakeScalarZnxImpl, TakeSvpPPolImpl,
13 TakeVecZnxBigImpl, TakeVecZnxDftImpl, TakeVecZnxImpl,
14 },
15 source::Source,
16};
17
18use crate::{
19 encryption::SIGMA,
20 layouts::{
21 GGLWEAutomorphismKey, GLWECiphertext, GLWEPlaintext, GLWESecret, Infos,
22 prepared::{GGLWEAutomorphismKeyPrepared, GLWESecretPrepared, Prepare, PrepareAlloc},
23 },
24 noise::log2_std_noise_gglwe_product,
25};
26
27#[allow(clippy::too_many_arguments)]
28pub fn test_glwe_automorphism<B>(
29 module: &Module<B>,
30 basek: usize,
31 p: i64,
32 k_out: usize,
33 k_in: usize,
34 k_ksk: usize,
35 digits: usize,
36 rank: usize,
37) where
38 Module<B>: VecZnxDftAllocBytes
39 + VecZnxBigNormalize<B>
40 + DFT<B>
41 + SvpApplyInplace<B>
42 + IDFTConsume<B>
43 + VecZnxNormalizeTmpBytes
44 + VecZnxFillUniform
45 + VecZnxSubABInplace
46 + VecZnxAddInplace
47 + VecZnxNormalizeInplace<B>
48 + VecZnxAddNormal
49 + VecZnxNormalize<B>
50 + VecZnxSub
51 + SvpPrepare<B>
52 + SvpPPolAllocBytes
53 + SvpPPolAlloc<B>
54 + VecZnxBigAllocBytes
55 + VecZnxBigAddInplace<B>
56 + VecZnxBigAddSmallInplace<B>
57 + VmpApplyDftToDftTmpBytes
58 + VecZnxBigNormalizeTmpBytes
59 + VmpApplyDftToDft<B>
60 + VmpApplyDftToDftAdd<B>
61 + VecZnxAutomorphism
62 + VecZnxSwithcDegree
63 + VecZnxAddScalarInplace
64 + VecZnxAutomorphismInplace
65 + VmpPMatAlloc<B>
66 + VmpPrepare<B>,
67 B: Backend
68 + TakeVecZnxDftImpl<B>
69 + TakeVecZnxBigImpl<B>
70 + TakeSvpPPolImpl<B>
71 + ScratchOwnedAllocImpl<B>
72 + ScratchOwnedBorrowImpl<B>
73 + ScratchAvailableImpl<B>
74 + TakeScalarZnxImpl<B>
75 + TakeVecZnxImpl<B>,
76{
77 let n: usize = module.n();
78 let rows: usize = k_in.div_ceil(basek * digits);
79
80 let mut autokey: GGLWEAutomorphismKey<Vec<u8>> = GGLWEAutomorphismKey::alloc(n, basek, k_ksk, rows, digits, rank);
81 let mut ct_in: GLWECiphertext<Vec<u8>> = GLWECiphertext::alloc(n, basek, k_in, rank);
82 let mut ct_out: GLWECiphertext<Vec<u8>> = GLWECiphertext::alloc(n, basek, k_out, rank);
83 let mut pt_want: GLWEPlaintext<Vec<u8>> = GLWEPlaintext::alloc(n, basek, k_in);
84
85 let mut source_xs: Source = Source::new([0u8; 32]);
86 let mut source_xe: Source = Source::new([0u8; 32]);
87 let mut source_xa: Source = Source::new([0u8; 32]);
88
89 module.vec_znx_fill_uniform(basek, &mut pt_want.data, 0, k_in, &mut source_xa);
90
91 let mut scratch: ScratchOwned<B> = ScratchOwned::alloc(
92 GGLWEAutomorphismKey::encrypt_sk_scratch_space(module, basek, autokey.k(), rank)
93 | GLWECiphertext::decrypt_scratch_space(module, basek, ct_out.k())
94 | GLWECiphertext::encrypt_sk_scratch_space(module, basek, ct_in.k())
95 | GLWECiphertext::automorphism_scratch_space(
96 module,
97 basek,
98 ct_out.k(),
99 ct_in.k(),
100 autokey.k(),
101 digits,
102 rank,
103 ),
104 );
105
106 let mut sk: GLWESecret<Vec<u8>> = GLWESecret::alloc(n, rank);
107 sk.fill_ternary_prob(0.5, &mut source_xs);
108 let sk_prepared: GLWESecretPrepared<Vec<u8>, B> = sk.prepare_alloc(module, scratch.borrow());
109
110 autokey.encrypt_sk(
111 module,
112 p,
113 &sk,
114 &mut source_xa,
115 &mut source_xe,
116 scratch.borrow(),
117 );
118
119 ct_in.encrypt_sk(
120 module,
121 &pt_want,
122 &sk_prepared,
123 &mut source_xa,
124 &mut source_xe,
125 scratch.borrow(),
126 );
127
128 let mut autokey_prepared: GGLWEAutomorphismKeyPrepared<Vec<u8>, B> =
129 GGLWEAutomorphismKeyPrepared::alloc(module, basek, k_ksk, rows, digits, rank);
130 autokey_prepared.prepare(module, &autokey, scratch.borrow());
131
132 ct_out.automorphism(module, &ct_in, &autokey_prepared, scratch.borrow());
133
134 let max_noise: f64 = log2_std_noise_gglwe_product(
135 module.n() as f64,
136 basek * digits,
137 0.5,
138 0.5,
139 0f64,
140 SIGMA * SIGMA,
141 0f64,
142 rank as f64,
143 k_in,
144 k_ksk,
145 );
146
147 module.vec_znx_automorphism_inplace(p, &mut pt_want.data, 0);
148
149 ct_out.assert_noise(module, &sk_prepared, &pt_want, max_noise + 1.0);
150}
151
152#[allow(clippy::too_many_arguments)]
153pub fn test_glwe_automorphism_inplace<B>(
154 module: &Module<B>,
155 basek: usize,
156 p: i64,
157 k_ct: usize,
158 k_ksk: usize,
159 digits: usize,
160 rank: usize,
161) where
162 Module<B>: VecZnxDftAllocBytes
163 + VecZnxBigNormalize<B>
164 + DFT<B>
165 + SvpApplyInplace<B>
166 + IDFTConsume<B>
167 + VecZnxNormalizeTmpBytes
168 + VecZnxFillUniform
169 + VecZnxSubABInplace
170 + VecZnxAddInplace
171 + VecZnxNormalizeInplace<B>
172 + VecZnxAddNormal
173 + VecZnxNormalize<B>
174 + VecZnxSub
175 + SvpPrepare<B>
176 + SvpPPolAllocBytes
177 + SvpPPolAlloc<B>
178 + VecZnxBigAllocBytes
179 + VecZnxBigAddInplace<B>
180 + VecZnxBigAddSmallInplace<B>
181 + VmpApplyDftToDftTmpBytes
182 + VecZnxBigNormalizeTmpBytes
183 + VmpApplyDftToDft<B>
184 + VmpApplyDftToDftAdd<B>
185 + VecZnxAutomorphism
186 + VecZnxSwithcDegree
187 + VecZnxAddScalarInplace
188 + VecZnxAutomorphismInplace
189 + VmpPMatAlloc<B>
190 + VmpPrepare<B>,
191 B: Backend
192 + TakeVecZnxDftImpl<B>
193 + TakeVecZnxBigImpl<B>
194 + TakeSvpPPolImpl<B>
195 + ScratchOwnedAllocImpl<B>
196 + ScratchOwnedBorrowImpl<B>
197 + ScratchAvailableImpl<B>
198 + TakeScalarZnxImpl<B>
199 + TakeVecZnxImpl<B>,
200{
201 let n: usize = module.n();
202 let rows: usize = k_ct.div_ceil(basek * digits);
203
204 let mut autokey: GGLWEAutomorphismKey<Vec<u8>> = GGLWEAutomorphismKey::alloc(n, basek, k_ksk, rows, digits, rank);
205 let mut ct: GLWECiphertext<Vec<u8>> = GLWECiphertext::alloc(n, basek, k_ct, rank);
206 let mut pt_want: GLWEPlaintext<Vec<u8>> = GLWEPlaintext::alloc(n, basek, k_ct);
207
208 let mut source_xs: Source = Source::new([0u8; 32]);
209 let mut source_xe: Source = Source::new([0u8; 32]);
210 let mut source_xa: Source = Source::new([0u8; 32]);
211
212 module.vec_znx_fill_uniform(basek, &mut pt_want.data, 0, k_ct, &mut source_xa);
213
214 let mut scratch: ScratchOwned<B> = ScratchOwned::alloc(
215 GGLWEAutomorphismKey::encrypt_sk_scratch_space(module, basek, autokey.k(), rank)
216 | GLWECiphertext::decrypt_scratch_space(module, basek, ct.k())
217 | GLWECiphertext::encrypt_sk_scratch_space(module, basek, ct.k())
218 | GLWECiphertext::automorphism_inplace_scratch_space(module, basek, ct.k(), autokey.k(), digits, rank),
219 );
220
221 let mut sk: GLWESecret<Vec<u8>> = GLWESecret::alloc(n, rank);
222 sk.fill_ternary_prob(0.5, &mut source_xs);
223 let sk_prepared: GLWESecretPrepared<Vec<u8>, B> = sk.prepare_alloc(module, scratch.borrow());
224
225 autokey.encrypt_sk(
226 module,
227 p,
228 &sk,
229 &mut source_xa,
230 &mut source_xe,
231 scratch.borrow(),
232 );
233
234 ct.encrypt_sk(
235 module,
236 &pt_want,
237 &sk_prepared,
238 &mut source_xa,
239 &mut source_xe,
240 scratch.borrow(),
241 );
242
243 let mut autokey_prepared: GGLWEAutomorphismKeyPrepared<Vec<u8>, B> =
244 GGLWEAutomorphismKeyPrepared::alloc(module, basek, k_ksk, rows, digits, rank);
245 autokey_prepared.prepare(module, &autokey, scratch.borrow());
246
247 ct.automorphism_inplace(module, &autokey_prepared, scratch.borrow());
248
249 let max_noise: f64 = log2_std_noise_gglwe_product(
250 module.n() as f64,
251 basek * digits,
252 0.5,
253 0.5,
254 0f64,
255 SIGMA * SIGMA,
256 0f64,
257 rank as f64,
258 k_ct,
259 k_ksk,
260 );
261
262 module.vec_znx_automorphism_inplace(p, &mut pt_want.data, 0);
263
264 ct.assert_noise(module, &sk_prepared, &pt_want, max_noise + 1.0);
265}