poulpy/poulpy-hal/src/test_suite/svp.rs
poulpy-hal/src/test_suite/svp.rsRaw
1use rand::RngCore;
2
3use crate::{
4 api::{
5 ScratchOwnedAlloc, ScratchOwnedBorrow, SvpApplyDft, SvpApplyDftToDft, SvpApplyDftToDftAdd, SvpApplyDftToDftInplace,
6 SvpPPolAlloc, SvpPrepare, VecZnxBigNormalize, VecZnxBigNormalizeTmpBytes, VecZnxDftAlloc, VecZnxDftApply,
7 VecZnxIdftApplyConsume,
8 },
9 layouts::{Backend, DataViewMut, DigestU64, FillUniform, Module, ScalarZnx, ScratchOwned, SvpPPol, VecZnx, VecZnxDft},
10 source::Source,
11};
12
13pub fn test_svp_apply_dft<BR: Backend, BT: Backend>(base2k: usize, module_ref: &Module<BR>, module_test: &Module<BT>)
14where
15 Module<BR>: SvpPrepare<BR>
16 + SvpApplyDft<BR>
17 + SvpPPolAlloc<BR>
18 + VecZnxDftAlloc<BR>
19 + VecZnxBigNormalize<BR>
20 + VecZnxIdftApplyConsume<BR>
21 + VecZnxBigNormalizeTmpBytes,
22 Module<BT>: SvpPrepare<BT>
23 + SvpApplyDft<BT>
24 + SvpPPolAlloc<BT>
25 + VecZnxDftAlloc<BT>
26 + VecZnxBigNormalize<BT>
27 + VecZnxIdftApplyConsume<BT>
28 + VecZnxBigNormalizeTmpBytes,
29 ScratchOwned<BR>: ScratchOwnedAlloc<BR> + ScratchOwnedBorrow<BR>,
30 ScratchOwned<BT>: ScratchOwnedAlloc<BT> + ScratchOwnedBorrow<BT>,
31{
32 assert_eq!(module_ref.n(), module_test.n());
33 let n: usize = module_ref.n();
34
35 let cols: usize = 2;
36
37 let mut source: Source = Source::new([0u8; 32]);
38
39 let mut scratch_ref: ScratchOwned<BR> = ScratchOwned::alloc(module_ref.vec_znx_big_normalize_tmp_bytes());
40 let mut scratch_test: ScratchOwned<BT> = ScratchOwned::alloc(module_test.vec_znx_big_normalize_tmp_bytes());
41
42 let mut scalar: ScalarZnx<Vec<u8>> = ScalarZnx::alloc(n, cols);
43 scalar.fill_uniform(base2k, &mut source);
44
45 let scalar_digest: u64 = scalar.digest_u64();
46
47 let mut svp_ref: SvpPPol<Vec<u8>, BR> = module_ref.svp_ppol_alloc(cols);
48 let mut svp_test: SvpPPol<Vec<u8>, BT> = module_test.svp_ppol_alloc(cols);
49
50 for j in 0..cols {
51 module_ref.svp_prepare(&mut svp_ref, j, &scalar, j);
52 module_test.svp_prepare(&mut svp_test, j, &scalar, j);
53 }
54
55 assert_eq!(scalar.digest_u64(), scalar_digest);
56
57 let svp_ref_digest: u64 = svp_ref.digest_u64();
58 let svp_test_digest: u64 = svp_test.digest_u64();
59
60 for a_size in [1, 2, 3, 4] {
61 // Create a random input VecZnx
62 let mut a: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, a_size);
63 a.fill_uniform(base2k, &mut source);
64
65 let a_digest: u64 = a.digest_u64();
66
67 for res_size in [1, 2, 3, 4] {
68 // Allocate VecZnxDft from FFT64Ref and module to test
69 let mut res_dft_ref: VecZnxDft<Vec<u8>, BR> = module_ref.vec_znx_dft_alloc(cols, res_size);
70 let mut res_dft_test: VecZnxDft<Vec<u8>, BT> = module_test.vec_znx_dft_alloc(cols, res_size);
71
72 // Fill output with garbage
73 source.fill_bytes(res_dft_ref.data_mut());
74 source.fill_bytes(res_dft_test.data_mut());
75
76 for j in 0..cols {
77 module_ref.svp_apply_dft(&mut res_dft_ref, j, &svp_ref, j, &a, j);
78 module_test.svp_apply_dft(&mut res_dft_test, j, &svp_test, j, &a, j);
79 }
80
81 // Assert no change to inputs
82 assert_eq!(svp_ref.digest_u64(), svp_ref_digest);
83 assert_eq!(svp_test.digest_u64(), svp_test_digest);
84 assert_eq!(a.digest_u64(), a_digest);
85
86 let res_big_ref: crate::layouts::VecZnxBig<Vec<u8>, BR> = module_ref.vec_znx_idft_apply_consume(res_dft_ref);
87 let res_big_test: crate::layouts::VecZnxBig<Vec<u8>, BT> = module_test.vec_znx_idft_apply_consume(res_dft_test);
88
89 let mut res_ref: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, res_size);
90 let mut res_test: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, res_size);
91
92 for j in 0..cols {
93 module_ref.vec_znx_big_normalize(&mut res_ref, base2k, 0, j, &res_big_ref, base2k, j, scratch_ref.borrow());
94 module_test.vec_znx_big_normalize(&mut res_test, base2k, 0, j, &res_big_test, base2k, j, scratch_test.borrow());
95 }
96
97 assert_eq!(res_ref, res_test);
98 }
99 }
100}
101
102pub fn test_svp_apply_dft_to_dft<BR: Backend, BT: Backend>(base2k: usize, module_ref: &Module<BR>, module_test: &Module<BT>)
103where
104 Module<BR>: SvpPrepare<BR>
105 + SvpApplyDftToDft<BR>
106 + SvpPPolAlloc<BR>
107 + VecZnxDftAlloc<BR>
108 + VecZnxBigNormalize<BR>
109 + VecZnxDftApply<BR>
110 + VecZnxIdftApplyConsume<BR>
111 + VecZnxBigNormalizeTmpBytes,
112 Module<BT>: SvpPrepare<BT>
113 + SvpApplyDftToDft<BT>
114 + SvpPPolAlloc<BT>
115 + VecZnxDftAlloc<BT>
116 + VecZnxBigNormalize<BT>
117 + VecZnxDftApply<BT>
118 + VecZnxIdftApplyConsume<BT>
119 + VecZnxBigNormalizeTmpBytes,
120 ScratchOwned<BR>: ScratchOwnedAlloc<BR> + ScratchOwnedBorrow<BR>,
121 ScratchOwned<BT>: ScratchOwnedAlloc<BT> + ScratchOwnedBorrow<BT>,
122{
123 assert_eq!(module_ref.n(), module_test.n());
124 let n: usize = module_ref.n();
125
126 let cols: usize = 2;
127
128 let mut source: Source = Source::new([0u8; 32]);
129
130 let mut scratch_ref: ScratchOwned<BR> = ScratchOwned::alloc(module_ref.vec_znx_big_normalize_tmp_bytes());
131 let mut scratch_test: ScratchOwned<BT> = ScratchOwned::alloc(module_test.vec_znx_big_normalize_tmp_bytes());
132
133 let mut scalar: ScalarZnx<Vec<u8>> = ScalarZnx::alloc(n, cols);
134 scalar.fill_uniform(base2k, &mut source);
135
136 let scalar_digest: u64 = scalar.digest_u64();
137
138 let mut svp_ref: SvpPPol<Vec<u8>, BR> = module_ref.svp_ppol_alloc(cols);
139 let mut svp_test: SvpPPol<Vec<u8>, BT> = module_test.svp_ppol_alloc(cols);
140
141 for j in 0..cols {
142 module_ref.svp_prepare(&mut svp_ref, j, &scalar, j);
143 module_test.svp_prepare(&mut svp_test, j, &scalar, j);
144 }
145
146 assert_eq!(scalar.digest_u64(), scalar_digest);
147
148 let svp_ref_digest: u64 = svp_ref.digest_u64();
149 let svp_test_digest: u64 = svp_test.digest_u64();
150
151 for a_size in [3] {
152 // Create a random input VecZnx
153 let mut a: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, a_size);
154 a.fill_uniform(base2k, &mut source);
155
156 let a_digest: u64 = a.digest_u64();
157
158 let mut a_dft_ref: VecZnxDft<Vec<u8>, BR> = module_ref.vec_znx_dft_alloc(cols, a_size);
159 let mut a_dft_test: VecZnxDft<Vec<u8>, BT> = module_test.vec_znx_dft_alloc(cols, a_size);
160
161 for j in 0..cols {
162 module_ref.vec_znx_dft_apply(1, 0, &mut a_dft_ref, j, &a, j);
163 module_test.vec_znx_dft_apply(1, 0, &mut a_dft_test, j, &a, j);
164 }
165
166 assert_eq!(a.digest_u64(), a_digest);
167
168 let a_dft_ref_digest: u64 = a_dft_ref.digest_u64();
169 let a_dft_test_digest: u64 = a_dft_test.digest_u64();
170
171 for res_size in [3] {
172 // Allocate VecZnxDft from FFT64Ref and module to test
173 let mut res_dft_ref: VecZnxDft<Vec<u8>, BR> = module_ref.vec_znx_dft_alloc(cols, res_size);
174 let mut res_dft_test: VecZnxDft<Vec<u8>, BT> = module_test.vec_znx_dft_alloc(cols, res_size);
175
176 // Fill output with garbage
177 source.fill_bytes(res_dft_ref.data_mut());
178 source.fill_bytes(res_dft_test.data_mut());
179
180 for j in 0..cols {
181 module_ref.svp_apply_dft_to_dft(&mut res_dft_ref, j, &svp_ref, j, &a_dft_ref, j);
182 module_test.svp_apply_dft_to_dft(&mut res_dft_test, j, &svp_test, j, &a_dft_test, j);
183 }
184
185 // Assert no change to inputs
186 assert_eq!(a_dft_ref.digest_u64(), a_dft_ref_digest);
187 assert_eq!(a_dft_test.digest_u64(), a_dft_test_digest);
188 assert_eq!(svp_ref.digest_u64(), svp_ref_digest);
189 assert_eq!(svp_test.digest_u64(), svp_test_digest);
190 assert_eq!(a.digest_u64(), a_digest);
191
192 let res_big_ref: crate::layouts::VecZnxBig<Vec<u8>, BR> = module_ref.vec_znx_idft_apply_consume(res_dft_ref);
193 let res_big_test: crate::layouts::VecZnxBig<Vec<u8>, BT> = module_test.vec_znx_idft_apply_consume(res_dft_test);
194
195 let mut res_ref: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, res_size);
196 let mut res_test: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, res_size);
197
198 for j in 0..cols {
199 module_ref.vec_znx_big_normalize(&mut res_ref, base2k, 0, j, &res_big_ref, base2k, j, scratch_ref.borrow());
200 module_test.vec_znx_big_normalize(&mut res_test, base2k, 0, j, &res_big_test, base2k, j, scratch_test.borrow());
201 }
202
203 assert_eq!(res_ref, res_test);
204 }
205 }
206}
207
208pub fn test_svp_apply_dft_to_dft_add<BR: Backend, BT: Backend>(base2k: usize, module_ref: &Module<BR>, module_test: &Module<BT>)
209where
210 Module<BR>: SvpPrepare<BR>
211 + SvpApplyDftToDftAdd<BR>
212 + SvpPPolAlloc<BR>
213 + VecZnxDftAlloc<BR>
214 + VecZnxBigNormalize<BR>
215 + VecZnxDftApply<BR>
216 + VecZnxIdftApplyConsume<BR>
217 + VecZnxBigNormalizeTmpBytes,
218 Module<BT>: SvpPrepare<BT>
219 + SvpApplyDftToDftAdd<BT>
220 + SvpPPolAlloc<BT>
221 + VecZnxDftAlloc<BT>
222 + VecZnxBigNormalize<BT>
223 + VecZnxDftApply<BT>
224 + VecZnxIdftApplyConsume<BT>
225 + VecZnxBigNormalizeTmpBytes,
226 ScratchOwned<BR>: ScratchOwnedAlloc<BR> + ScratchOwnedBorrow<BR>,
227 ScratchOwned<BT>: ScratchOwnedAlloc<BT> + ScratchOwnedBorrow<BT>,
228{
229 assert_eq!(module_ref.n(), module_test.n());
230 let n: usize = module_ref.n();
231
232 let cols: usize = 2;
233
234 let mut source: Source = Source::new([0u8; 32]);
235
236 let mut scratch_ref: ScratchOwned<BR> = ScratchOwned::alloc(module_ref.vec_znx_big_normalize_tmp_bytes());
237 let mut scratch_test: ScratchOwned<BT> = ScratchOwned::alloc(module_test.vec_znx_big_normalize_tmp_bytes());
238
239 let mut scalar: ScalarZnx<Vec<u8>> = ScalarZnx::alloc(n, cols);
240 scalar.fill_uniform(base2k, &mut source);
241
242 let scalar_digest: u64 = scalar.digest_u64();
243
244 let mut svp_ref: SvpPPol<Vec<u8>, BR> = module_ref.svp_ppol_alloc(cols);
245 let mut svp_test: SvpPPol<Vec<u8>, BT> = module_test.svp_ppol_alloc(cols);
246
247 for j in 0..cols {
248 module_ref.svp_prepare(&mut svp_ref, j, &scalar, j);
249 module_test.svp_prepare(&mut svp_test, j, &scalar, j);
250 }
251
252 assert_eq!(scalar.digest_u64(), scalar_digest);
253
254 let svp_ref_digest: u64 = svp_ref.digest_u64();
255 let svp_test_digest: u64 = svp_test.digest_u64();
256
257 for a_size in [1, 2, 3, 4] {
258 // Create a random input VecZnx
259 let mut a: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, a_size);
260 a.fill_uniform(base2k, &mut source);
261
262 let a_digest: u64 = a.digest_u64();
263
264 let mut a_dft_ref: VecZnxDft<Vec<u8>, BR> = module_ref.vec_znx_dft_alloc(cols, a_size);
265 let mut a_dft_test: VecZnxDft<Vec<u8>, BT> = module_test.vec_znx_dft_alloc(cols, a_size);
266
267 for j in 0..cols {
268 module_ref.vec_znx_dft_apply(1, 0, &mut a_dft_ref, j, &a, j);
269 module_test.vec_znx_dft_apply(1, 0, &mut a_dft_test, j, &a, j);
270 }
271
272 let a_dft_ref_digest: u64 = a_dft_ref.digest_u64();
273 let a_dft_test_digest: u64 = a_dft_test.digest_u64();
274
275 for res_size in [1, 2, 3, 4] {
276 let mut res: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, res_size);
277 res.fill_uniform(base2k, &mut source);
278
279 let mut res_dft_ref: VecZnxDft<Vec<u8>, BR> = module_ref.vec_znx_dft_alloc(cols, res_size);
280 let mut res_dft_test: VecZnxDft<Vec<u8>, BT> = module_test.vec_znx_dft_alloc(cols, res_size);
281
282 for j in 0..cols {
283 module_ref.vec_znx_dft_apply(1, 0, &mut res_dft_ref, j, &res, j);
284 module_test.vec_znx_dft_apply(1, 0, &mut res_dft_test, j, &res, j);
285 }
286
287 // Fill output with garbage
288 source.fill_bytes(res_dft_ref.data_mut());
289 source.fill_bytes(res_dft_test.data_mut());
290
291 for j in 0..cols {
292 module_ref.svp_apply_dft_to_dft_add(&mut res_dft_ref, j, &svp_ref, j, &a_dft_ref, j);
293 module_test.svp_apply_dft_to_dft_add(&mut res_dft_test, j, &svp_test, j, &a_dft_test, j);
294 }
295
296 // Assert no change to inputs
297 assert_eq!(a_dft_ref.digest_u64(), a_dft_ref_digest);
298 assert_eq!(a_dft_test.digest_u64(), a_dft_test_digest);
299 assert_eq!(svp_ref.digest_u64(), svp_ref_digest);
300 assert_eq!(svp_test.digest_u64(), svp_test_digest);
301 assert_eq!(a.digest_u64(), a_digest);
302
303 let res_big_ref: crate::layouts::VecZnxBig<Vec<u8>, BR> = module_ref.vec_znx_idft_apply_consume(res_dft_ref);
304 let res_big_test: crate::layouts::VecZnxBig<Vec<u8>, BT> = module_test.vec_znx_idft_apply_consume(res_dft_test);
305
306 let mut res_ref: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, res_size);
307 let mut res_test: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, res_size);
308
309 for j in 0..cols {
310 module_ref.vec_znx_big_normalize(&mut res_ref, base2k, 0, j, &res_big_ref, base2k, j, scratch_ref.borrow());
311 module_test.vec_znx_big_normalize(&mut res_test, base2k, 0, j, &res_big_test, base2k, j, scratch_test.borrow());
312 }
313
314 assert_eq!(res_ref, res_test);
315 }
316 }
317}
318
319pub fn test_svp_apply_dft_to_dft_inplace<BR: Backend, BT: Backend>(
320 base2k: usize,
321 module_ref: &Module<BR>,
322 module_test: &Module<BT>,
323) where
324 Module<BR>: SvpPrepare<BR>
325 + SvpApplyDftToDftInplace<BR>
326 + SvpPPolAlloc<BR>
327 + VecZnxDftAlloc<BR>
328 + VecZnxBigNormalize<BR>
329 + VecZnxDftApply<BR>
330 + VecZnxIdftApplyConsume<BR>
331 + VecZnxBigNormalizeTmpBytes,
332 Module<BT>: SvpPrepare<BT>
333 + SvpApplyDftToDftInplace<BT>
334 + SvpPPolAlloc<BT>
335 + VecZnxDftAlloc<BT>
336 + VecZnxBigNormalize<BT>
337 + VecZnxDftApply<BT>
338 + VecZnxIdftApplyConsume<BT>
339 + VecZnxBigNormalizeTmpBytes,
340 ScratchOwned<BR>: ScratchOwnedAlloc<BR> + ScratchOwnedBorrow<BR>,
341 ScratchOwned<BT>: ScratchOwnedAlloc<BT> + ScratchOwnedBorrow<BT>,
342{
343 assert_eq!(module_ref.n(), module_test.n());
344 let n: usize = module_ref.n();
345
346 let cols: usize = 2;
347
348 let mut source: Source = Source::new([0u8; 32]);
349
350 let mut scratch_ref: ScratchOwned<BR> = ScratchOwned::alloc(module_ref.vec_znx_big_normalize_tmp_bytes());
351 let mut scratch_test: ScratchOwned<BT> = ScratchOwned::alloc(module_test.vec_znx_big_normalize_tmp_bytes());
352
353 let mut scalar: ScalarZnx<Vec<u8>> = ScalarZnx::alloc(n, cols);
354 scalar.fill_uniform(base2k, &mut source);
355
356 let scalar_digest: u64 = scalar.digest_u64();
357
358 let mut svp_ref: SvpPPol<Vec<u8>, BR> = module_ref.svp_ppol_alloc(cols);
359 let mut svp_test: SvpPPol<Vec<u8>, BT> = module_test.svp_ppol_alloc(cols);
360
361 for j in 0..cols {
362 module_ref.svp_prepare(&mut svp_ref, j, &scalar, j);
363 module_test.svp_prepare(&mut svp_test, j, &scalar, j);
364 }
365
366 assert_eq!(scalar.digest_u64(), scalar_digest);
367
368 let svp_ref_digest: u64 = svp_ref.digest_u64();
369 let svp_test_digest: u64 = svp_test.digest_u64();
370
371 for res_size in [1, 2, 3, 4] {
372 let mut res: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, res_size);
373 res.fill_uniform(base2k, &mut source);
374 let res_digest: u64 = res.digest_u64();
375
376 let mut res_dft_ref: VecZnxDft<Vec<u8>, BR> = module_ref.vec_znx_dft_alloc(cols, res_size);
377 let mut res_dft_test: VecZnxDft<Vec<u8>, BT> = module_test.vec_znx_dft_alloc(cols, res_size);
378
379 for j in 0..cols {
380 module_ref.vec_znx_dft_apply(1, 0, &mut res_dft_ref, j, &res, j);
381 module_test.vec_znx_dft_apply(1, 0, &mut res_dft_test, j, &res, j);
382 }
383
384 assert_eq!(res.digest_u64(), res_digest);
385
386 for j in 0..cols {
387 module_ref.svp_apply_dft_to_dft_inplace(&mut res_dft_ref, j, &svp_ref, j);
388 module_test.svp_apply_dft_to_dft_inplace(&mut res_dft_test, j, &svp_test, j);
389 }
390
391 // Assert no change to inputs
392 assert_eq!(svp_ref.digest_u64(), svp_ref_digest);
393 assert_eq!(svp_test.digest_u64(), svp_test_digest);
394
395 let res_big_ref: crate::layouts::VecZnxBig<Vec<u8>, BR> = module_ref.vec_znx_idft_apply_consume(res_dft_ref);
396 let res_big_test: crate::layouts::VecZnxBig<Vec<u8>, BT> = module_test.vec_znx_idft_apply_consume(res_dft_test);
397
398 let mut res_ref: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, res_size);
399 let mut res_test: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, res_size);
400
401 for j in 0..cols {
402 module_ref.vec_znx_big_normalize(&mut res_ref, base2k, 0, j, &res_big_ref, base2k, j, scratch_ref.borrow());
403 module_test.vec_znx_big_normalize(&mut res_test, base2k, 0, j, &res_big_test, base2k, j, scratch_test.borrow());
404 }
405
406 assert_eq!(res_ref, res_test);
407 }
408}