poulpy/core/src/tests/generics/automorphism/glwe_ct.rs
core/src/tests/generics/automorphism/glwe_ct.rsRaw
1use backend::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};
16use sampling::source::Source;
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
26pub fn test_glwe_automorphism<B: Backend>(
27 module: &Module<B>,
28 basek: usize,
29 p: i64,
30 k_out: usize,
31 k_in: usize,
32 k_ksk: usize,
33 digits: usize,
34 rank: usize,
35 sigma: f64,
36) where
37 Module<B>: VecZnxDftAllocBytes
38 + VecZnxBigNormalize<B>
39 + VecZnxDftFromVecZnx<B>
40 + SvpApplyInplace<B>
41 + VecZnxDftToVecZnxBigConsume<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: TakeVecZnxDftImpl<B>
67 + TakeVecZnxBigImpl<B>
68 + TakeSvpPPolImpl<B>
69 + ScratchOwnedAllocImpl<B>
70 + ScratchOwnedBorrowImpl<B>
71 + ScratchAvailableImpl<B>
72 + TakeScalarZnxImpl<B>
73 + TakeVecZnxImpl<B>,
74{
75 let n: usize = module.n();
76 let rows: usize = k_in.div_ceil(basek * digits);
77
78 let mut autokey: GGLWEAutomorphismKey<Vec<u8>> = GGLWEAutomorphismKey::alloc(n, basek, k_ksk, rows, digits, rank);
79 let mut ct_in: GLWECiphertext<Vec<u8>> = GLWECiphertext::alloc(n, basek, k_in, rank);
80 let mut ct_out: GLWECiphertext<Vec<u8>> = GLWECiphertext::alloc(n, basek, k_out, rank);
81 let mut pt_want: GLWEPlaintext<Vec<u8>> = GLWEPlaintext::alloc(n, basek, k_in);
82
83 let mut source_xs: Source = Source::new([0u8; 32]);
84 let mut source_xe: Source = Source::new([0u8; 32]);
85 let mut source_xa: Source = Source::new([0u8; 32]);
86
87 module.vec_znx_fill_uniform(basek, &mut pt_want.data, 0, k_in, &mut source_xa);
88
89 let mut scratch: ScratchOwned<B> = ScratchOwned::alloc(
90 GGLWEAutomorphismKey::encrypt_sk_scratch_space(module, n, basek, autokey.k(), rank)
91 | GLWECiphertext::decrypt_scratch_space(module, n, basek, ct_out.k())
92 | GLWECiphertext::encrypt_sk_scratch_space(module, n, basek, ct_in.k())
93 | GLWECiphertext::automorphism_scratch_space(
94 module,
95 n,
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 sigma,
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 sigma,
126 scratch.borrow(),
127 );
128
129 let mut autokey_prepared: GGLWEAutomorphismKeyPrepared<Vec<u8>, B> =
130 GGLWEAutomorphismKeyPrepared::alloc(module, n, basek, k_ksk, rows, digits, rank);
131 autokey_prepared.prepare(module, &autokey, scratch.borrow());
132
133 ct_out.automorphism(module, &ct_in, &autokey_prepared, scratch.borrow());
134
135 let max_noise: f64 = log2_std_noise_gglwe_product(
136 module.n() as f64,
137 basek * digits,
138 0.5,
139 0.5,
140 0f64,
141 sigma * sigma,
142 0f64,
143 rank as f64,
144 k_in,
145 k_ksk,
146 );
147
148 module.vec_znx_automorphism_inplace(p, &mut pt_want.data, 0);
149
150 ct_out.assert_noise(module, &sk_prepared, &pt_want, max_noise + 1.0);
151}
152
153pub fn test_glwe_automorphism_inplace<B: Backend>(
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 sigma: f64,
162) where
163 Module<B>: VecZnxDftAllocBytes
164 + VecZnxBigNormalize<B>
165 + VecZnxDftFromVecZnx<B>
166 + SvpApplyInplace<B>
167 + VecZnxDftToVecZnxBigConsume<B>
168 + VecZnxNormalizeTmpBytes
169 + VecZnxFillUniform
170 + VecZnxSubABInplace
171 + VecZnxAddInplace
172 + VecZnxNormalizeInplace<B>
173 + VecZnxAddNormal
174 + VecZnxNormalize<B>
175 + VecZnxSub
176 + SvpPrepare<B>
177 + SvpPPolAllocBytes
178 + SvpPPolAlloc<B>
179 + VecZnxBigAllocBytes
180 + VecZnxBigAddInplace<B>
181 + VecZnxBigAddSmallInplace<B>
182 + VmpApplyTmpBytes
183 + VecZnxBigNormalizeTmpBytes
184 + VmpApply<B>
185 + VmpApplyAdd<B>
186 + VecZnxAutomorphism
187 + VecZnxSwithcDegree
188 + VecZnxAddScalarInplace
189 + VecZnxAutomorphismInplace
190 + VmpPMatAlloc<B>
191 + VmpPrepare<B>,
192 B: 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, n, basek, autokey.k(), rank)
216 | GLWECiphertext::decrypt_scratch_space(module, n, basek, ct.k())
217 | GLWECiphertext::encrypt_sk_scratch_space(module, n, basek, ct.k())
218 | GLWECiphertext::automorphism_inplace_scratch_space(module, n, 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 sigma,
232 scratch.borrow(),
233 );
234
235 ct.encrypt_sk(
236 module,
237 &pt_want,
238 &sk_prepared,
239 &mut source_xa,
240 &mut source_xe,
241 sigma,
242 scratch.borrow(),
243 );
244
245 let mut autokey_prepared: GGLWEAutomorphismKeyPrepared<Vec<u8>, B> =
246 GGLWEAutomorphismKeyPrepared::alloc(module, n, basek, k_ksk, rows, digits, rank);
247 autokey_prepared.prepare(module, &autokey, scratch.borrow());
248
249 ct.automorphism_inplace(module, &autokey_prepared, scratch.borrow());
250
251 let max_noise: f64 = log2_std_noise_gglwe_product(
252 module.n() as f64,
253 basek * digits,
254 0.5,
255 0.5,
256 0f64,
257 sigma * sigma,
258 0f64,
259 rank as f64,
260 k_ct,
261 k_ksk,
262 );
263
264 module.vec_znx_automorphism_inplace(p, &mut pt_want.data, 0);
265
266 ct.assert_noise(module, &sk_prepared, &pt_want, max_noise + 1.0);
267}