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 ScratchOwnedAlloc, ScratchOwnedBorrow, SvpApplyInplace, SvpPPolAlloc, SvpPPolAllocBytes, SvpPrepare, VecZnxAddInplace,
4 VecZnxAddNormal, VecZnxAddScalarInplace, VecZnxAutomorphism, VecZnxAutomorphismInplace, VecZnxBigAddInplace,
5 VecZnxBigAddSmallInplace, VecZnxBigAllocBytes, VecZnxBigNormalize, VecZnxBigNormalizeTmpBytes, VecZnxDftAllocBytes,
6 VecZnxDftFromVecZnx, VecZnxDftToVecZnxBigConsume, VecZnxFillUniform, VecZnxNormalize, VecZnxNormalizeInplace,
7 VecZnxNormalizeTmpBytes, VecZnxSub, VecZnxSubABInplace, VecZnxSwithcDegree, VmpApply, VmpApplyAdd, VmpApplyTmpBytes,
8 VmpPMatAlloc, 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 layouts::{
20 GGLWEAutomorphismKey, GLWECiphertext, GLWEPlaintext, GLWESecret, Infos,
21 prepared::{GGLWEAutomorphismKeyPrepared, GLWESecretPrepared, Prepare, PrepareAlloc},
22 },
23 noise::log2_std_noise_gglwe_product,
24};
25
26#[allow(clippy::too_many_arguments)]
27pub fn test_glwe_automorphism<B>(
28 module: &Module<B>,
29 basek: usize,
30 p: i64,
31 k_out: usize,
32 k_in: usize,
33 k_ksk: usize,
34 digits: usize,
35 rank: usize,
36 sigma: f64,
37) where
38 Module<B>: VecZnxDftAllocBytes
39 + VecZnxBigNormalize<B>
40 + VecZnxDftFromVecZnx<B>
41 + SvpApplyInplace<B>
42 + VecZnxDftToVecZnxBigConsume<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 + VmpApplyTmpBytes
58 + VecZnxBigNormalizeTmpBytes
59 + VmpApply<B>
60 + VmpApplyAdd<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, n, basek, autokey.k(), rank)
93 | GLWECiphertext::decrypt_scratch_space(module, n, basek, ct_out.k())
94 | GLWECiphertext::encrypt_sk_scratch_space(module, n, basek, ct_in.k())
95 | GLWECiphertext::automorphism_scratch_space(
96 module,
97 n,
98 basek,
99 ct_out.k(),
100 ct_in.k(),
101 autokey.k(),
102 digits,
103 rank,
104 ),
105 );
106
107 let mut sk: GLWESecret<Vec<u8>> = GLWESecret::alloc(n, rank);
108 sk.fill_ternary_prob(0.5, &mut source_xs);
109 let sk_prepared: GLWESecretPrepared<Vec<u8>, B> = sk.prepare_alloc(module, scratch.borrow());
110
111 autokey.encrypt_sk(
112 module,
113 p,
114 &sk,
115 &mut source_xa,
116 &mut source_xe,
117 sigma,
118 scratch.borrow(),
119 );
120
121 ct_in.encrypt_sk(
122 module,
123 &pt_want,
124 &sk_prepared,
125 &mut source_xa,
126 &mut source_xe,
127 sigma,
128 scratch.borrow(),
129 );
130
131 let mut autokey_prepared: GGLWEAutomorphismKeyPrepared<Vec<u8>, B> =
132 GGLWEAutomorphismKeyPrepared::alloc(module, n, basek, k_ksk, rows, digits, rank);
133 autokey_prepared.prepare(module, &autokey, scratch.borrow());
134
135 ct_out.automorphism(module, &ct_in, &autokey_prepared, scratch.borrow());
136
137 let max_noise: f64 = log2_std_noise_gglwe_product(
138 module.n() as f64,
139 basek * digits,
140 0.5,
141 0.5,
142 0f64,
143 sigma * sigma,
144 0f64,
145 rank as f64,
146 k_in,
147 k_ksk,
148 );
149
150 module.vec_znx_automorphism_inplace(p, &mut pt_want.data, 0);
151
152 ct_out.assert_noise(module, &sk_prepared, &pt_want, max_noise + 1.0);
153}
154
155#[allow(clippy::too_many_arguments)]
156pub fn test_glwe_automorphism_inplace<B>(
157 module: &Module<B>,
158 basek: usize,
159 p: i64,
160 k_ct: usize,
161 k_ksk: usize,
162 digits: usize,
163 rank: usize,
164 sigma: f64,
165) where
166 Module<B>: VecZnxDftAllocBytes
167 + VecZnxBigNormalize<B>
168 + VecZnxDftFromVecZnx<B>
169 + SvpApplyInplace<B>
170 + VecZnxDftToVecZnxBigConsume<B>
171 + VecZnxNormalizeTmpBytes
172 + VecZnxFillUniform
173 + VecZnxSubABInplace
174 + VecZnxAddInplace
175 + VecZnxNormalizeInplace<B>
176 + VecZnxAddNormal
177 + VecZnxNormalize<B>
178 + VecZnxSub
179 + SvpPrepare<B>
180 + SvpPPolAllocBytes
181 + SvpPPolAlloc<B>
182 + VecZnxBigAllocBytes
183 + VecZnxBigAddInplace<B>
184 + VecZnxBigAddSmallInplace<B>
185 + VmpApplyTmpBytes
186 + VecZnxBigNormalizeTmpBytes
187 + VmpApply<B>
188 + VmpApplyAdd<B>
189 + VecZnxAutomorphism
190 + VecZnxSwithcDegree
191 + VecZnxAddScalarInplace
192 + VecZnxAutomorphismInplace
193 + VmpPMatAlloc<B>
194 + VmpPrepare<B>,
195 B: Backend
196 + TakeVecZnxDftImpl<B>
197 + TakeVecZnxBigImpl<B>
198 + TakeSvpPPolImpl<B>
199 + ScratchOwnedAllocImpl<B>
200 + ScratchOwnedBorrowImpl<B>
201 + ScratchAvailableImpl<B>
202 + TakeScalarZnxImpl<B>
203 + TakeVecZnxImpl<B>,
204{
205 let n: usize = module.n();
206 let rows: usize = k_ct.div_ceil(basek * digits);
207
208 let mut autokey: GGLWEAutomorphismKey<Vec<u8>> = GGLWEAutomorphismKey::alloc(n, basek, k_ksk, rows, digits, rank);
209 let mut ct: GLWECiphertext<Vec<u8>> = GLWECiphertext::alloc(n, basek, k_ct, rank);
210 let mut pt_want: GLWEPlaintext<Vec<u8>> = GLWEPlaintext::alloc(n, basek, k_ct);
211
212 let mut source_xs: Source = Source::new([0u8; 32]);
213 let mut source_xe: Source = Source::new([0u8; 32]);
214 let mut source_xa: Source = Source::new([0u8; 32]);
215
216 module.vec_znx_fill_uniform(basek, &mut pt_want.data, 0, k_ct, &mut source_xa);
217
218 let mut scratch: ScratchOwned<B> = ScratchOwned::alloc(
219 GGLWEAutomorphismKey::encrypt_sk_scratch_space(module, n, basek, autokey.k(), rank)
220 | GLWECiphertext::decrypt_scratch_space(module, n, basek, ct.k())
221 | GLWECiphertext::encrypt_sk_scratch_space(module, n, basek, ct.k())
222 | GLWECiphertext::automorphism_inplace_scratch_space(module, n, basek, ct.k(), autokey.k(), digits, rank),
223 );
224
225 let mut sk: GLWESecret<Vec<u8>> = GLWESecret::alloc(n, rank);
226 sk.fill_ternary_prob(0.5, &mut source_xs);
227 let sk_prepared: GLWESecretPrepared<Vec<u8>, B> = sk.prepare_alloc(module, scratch.borrow());
228
229 autokey.encrypt_sk(
230 module,
231 p,
232 &sk,
233 &mut source_xa,
234 &mut source_xe,
235 sigma,
236 scratch.borrow(),
237 );
238
239 ct.encrypt_sk(
240 module,
241 &pt_want,
242 &sk_prepared,
243 &mut source_xa,
244 &mut source_xe,
245 sigma,
246 scratch.borrow(),
247 );
248
249 let mut autokey_prepared: GGLWEAutomorphismKeyPrepared<Vec<u8>, B> =
250 GGLWEAutomorphismKeyPrepared::alloc(module, n, basek, k_ksk, rows, digits, rank);
251 autokey_prepared.prepare(module, &autokey, scratch.borrow());
252
253 ct.automorphism_inplace(module, &autokey_prepared, scratch.borrow());
254
255 let max_noise: f64 = log2_std_noise_gglwe_product(
256 module.n() as f64,
257 basek * digits,
258 0.5,
259 0.5,
260 0f64,
261 sigma * sigma,
262 0f64,
263 rank as f64,
264 k_ct,
265 k_ksk,
266 );
267
268 module.vec_znx_automorphism_inplace(p, &mut pt_want.data, 0);
269
270 ct.assert_noise(module, &sk_prepared, &pt_want, max_noise + 1.0);
271}