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