arnaucube
arnaucube/poulpyPublic Self-hosted repository
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>(basek: 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(basek, &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(basek, &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(
 94                    basek,
 95                    &mut res_ref,
 96                    j,
 97                    &res_big_ref,
 98                    j,
 99                    scratch_ref.borrow(),
100                );
101                module_test.vec_znx_big_normalize(
102                    basek,
103                    &mut res_test,
104                    j,
105                    &res_big_test,
106                    j,
107                    scratch_test.borrow(),
108                );
109            }
110
111            assert_eq!(res_ref, res_test);
112        }
113    }
114}
115
116pub fn test_svp_apply_dft_to_dft<BR: Backend, BT: Backend>(basek: usize, module_ref: &Module<BR>, module_test: &Module<BT>)
117where
118    Module<BR>: SvpPrepare<BR>
119        + SvpApplyDftToDft<BR>
120        + SvpPPolAlloc<BR>
121        + VecZnxDftAlloc<BR>
122        + VecZnxBigNormalize<BR>
123        + VecZnxDftApply<BR>
124        + VecZnxIdftApplyConsume<BR>
125        + VecZnxBigNormalizeTmpBytes,
126    Module<BT>: SvpPrepare<BT>
127        + SvpApplyDftToDft<BT>
128        + SvpPPolAlloc<BT>
129        + VecZnxDftAlloc<BT>
130        + VecZnxBigNormalize<BT>
131        + VecZnxDftApply<BT>
132        + VecZnxIdftApplyConsume<BT>
133        + VecZnxBigNormalizeTmpBytes,
134    ScratchOwned<BR>: ScratchOwnedAlloc<BR> + ScratchOwnedBorrow<BR>,
135    ScratchOwned<BT>: ScratchOwnedAlloc<BT> + ScratchOwnedBorrow<BT>,
136{
137    assert_eq!(module_ref.n(), module_test.n());
138    let n: usize = module_ref.n();
139
140    let cols: usize = 2;
141
142    let mut source: Source = Source::new([0u8; 32]);
143
144    let mut scratch_ref: ScratchOwned<BR> = ScratchOwned::alloc(module_ref.vec_znx_big_normalize_tmp_bytes());
145    let mut scratch_test: ScratchOwned<BT> = ScratchOwned::alloc(module_test.vec_znx_big_normalize_tmp_bytes());
146
147    let mut scalar: ScalarZnx<Vec<u8>> = ScalarZnx::alloc(n, cols);
148    scalar.fill_uniform(basek, &mut source);
149
150    let scalar_digest: u64 = scalar.digest_u64();
151
152    let mut svp_ref: SvpPPol<Vec<u8>, BR> = module_ref.svp_ppol_alloc(cols);
153    let mut svp_test: SvpPPol<Vec<u8>, BT> = module_test.svp_ppol_alloc(cols);
154
155    for j in 0..cols {
156        module_ref.svp_prepare(&mut svp_ref, j, &scalar, j);
157        module_test.svp_prepare(&mut svp_test, j, &scalar, j);
158    }
159
160    assert_eq!(scalar.digest_u64(), scalar_digest);
161
162    let svp_ref_digest: u64 = svp_ref.digest_u64();
163    let svp_test_digest: u64 = svp_test.digest_u64();
164
165    for a_size in [3] {
166        // Create a random input VecZnx
167        let mut a: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, a_size);
168        a.fill_uniform(basek, &mut source);
169
170        let a_digest: u64 = a.digest_u64();
171
172        let mut a_dft_ref: VecZnxDft<Vec<u8>, BR> = module_ref.vec_znx_dft_alloc(cols, a_size);
173        let mut a_dft_test: VecZnxDft<Vec<u8>, BT> = module_test.vec_znx_dft_alloc(cols, a_size);
174
175        for j in 0..cols {
176            module_ref.vec_znx_dft_apply(1, 0, &mut a_dft_ref, j, &a, j);
177            module_test.vec_znx_dft_apply(1, 0, &mut a_dft_test, j, &a, j);
178        }
179
180        assert_eq!(a.digest_u64(), a_digest);
181
182        let a_dft_ref_digest: u64 = a_dft_ref.digest_u64();
183        let a_dft_test_digest: u64 = a_dft_test.digest_u64();
184
185        for res_size in [3] {
186            // Allocate VecZnxDft from FFT64Ref and module to test
187            let mut res_dft_ref: VecZnxDft<Vec<u8>, BR> = module_ref.vec_znx_dft_alloc(cols, res_size);
188            let mut res_dft_test: VecZnxDft<Vec<u8>, BT> = module_test.vec_znx_dft_alloc(cols, res_size);
189
190            // Fill output with garbage
191            source.fill_bytes(res_dft_ref.data_mut());
192            source.fill_bytes(res_dft_test.data_mut());
193
194            for j in 0..cols {
195                module_ref.svp_apply_dft_to_dft(&mut res_dft_ref, j, &svp_ref, j, &a_dft_ref, j);
196                module_test.svp_apply_dft_to_dft(&mut res_dft_test, j, &svp_test, j, &a_dft_test, j);
197            }
198
199            // Assert no change to inputs
200            assert_eq!(a_dft_ref.digest_u64(), a_dft_ref_digest);
201            assert_eq!(a_dft_test.digest_u64(), a_dft_test_digest);
202            assert_eq!(svp_ref.digest_u64(), svp_ref_digest);
203            assert_eq!(svp_test.digest_u64(), svp_test_digest);
204            assert_eq!(a.digest_u64(), a_digest);
205
206            let res_big_ref: crate::layouts::VecZnxBig<Vec<u8>, BR> = module_ref.vec_znx_idft_apply_consume(res_dft_ref);
207            let res_big_test: crate::layouts::VecZnxBig<Vec<u8>, BT> = module_test.vec_znx_idft_apply_consume(res_dft_test);
208
209            println!("res_big_ref: {}", res_big_ref);
210            println!("res_big_test: {}", res_big_test);
211
212            let mut res_ref: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, res_size);
213            let mut res_test: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, res_size);
214
215            for j in 0..cols {
216                module_ref.vec_znx_big_normalize(
217                    basek,
218                    &mut res_ref,
219                    j,
220                    &res_big_ref,
221                    j,
222                    scratch_ref.borrow(),
223                );
224                module_test.vec_znx_big_normalize(
225                    basek,
226                    &mut res_test,
227                    j,
228                    &res_big_test,
229                    j,
230                    scratch_test.borrow(),
231                );
232            }
233
234            assert_eq!(res_ref, res_test);
235        }
236    }
237}
238
239pub fn test_svp_apply_dft_to_dft_add<BR: Backend, BT: Backend>(basek: usize, module_ref: &Module<BR>, module_test: &Module<BT>)
240where
241    Module<BR>: SvpPrepare<BR>
242        + SvpApplyDftToDftAdd<BR>
243        + SvpPPolAlloc<BR>
244        + VecZnxDftAlloc<BR>
245        + VecZnxBigNormalize<BR>
246        + VecZnxDftApply<BR>
247        + VecZnxIdftApplyConsume<BR>
248        + VecZnxBigNormalizeTmpBytes,
249    Module<BT>: SvpPrepare<BT>
250        + SvpApplyDftToDftAdd<BT>
251        + SvpPPolAlloc<BT>
252        + VecZnxDftAlloc<BT>
253        + VecZnxBigNormalize<BT>
254        + VecZnxDftApply<BT>
255        + VecZnxIdftApplyConsume<BT>
256        + VecZnxBigNormalizeTmpBytes,
257    ScratchOwned<BR>: ScratchOwnedAlloc<BR> + ScratchOwnedBorrow<BR>,
258    ScratchOwned<BT>: ScratchOwnedAlloc<BT> + ScratchOwnedBorrow<BT>,
259{
260    assert_eq!(module_ref.n(), module_test.n());
261    let n: usize = module_ref.n();
262
263    let cols: usize = 2;
264
265    let mut source: Source = Source::new([0u8; 32]);
266
267    let mut scratch_ref: ScratchOwned<BR> = ScratchOwned::alloc(module_ref.vec_znx_big_normalize_tmp_bytes());
268    let mut scratch_test: ScratchOwned<BT> = ScratchOwned::alloc(module_test.vec_znx_big_normalize_tmp_bytes());
269
270    let mut scalar: ScalarZnx<Vec<u8>> = ScalarZnx::alloc(n, cols);
271    scalar.fill_uniform(basek, &mut source);
272
273    let scalar_digest: u64 = scalar.digest_u64();
274
275    let mut svp_ref: SvpPPol<Vec<u8>, BR> = module_ref.svp_ppol_alloc(cols);
276    let mut svp_test: SvpPPol<Vec<u8>, BT> = module_test.svp_ppol_alloc(cols);
277
278    for j in 0..cols {
279        module_ref.svp_prepare(&mut svp_ref, j, &scalar, j);
280        module_test.svp_prepare(&mut svp_test, j, &scalar, j);
281    }
282
283    assert_eq!(scalar.digest_u64(), scalar_digest);
284
285    let svp_ref_digest: u64 = svp_ref.digest_u64();
286    let svp_test_digest: u64 = svp_test.digest_u64();
287
288    for a_size in [1, 2, 3, 4] {
289        // Create a random input VecZnx
290        let mut a: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, a_size);
291        a.fill_uniform(basek, &mut source);
292
293        let a_digest: u64 = a.digest_u64();
294
295        let mut a_dft_ref: VecZnxDft<Vec<u8>, BR> = module_ref.vec_znx_dft_alloc(cols, a_size);
296        let mut a_dft_test: VecZnxDft<Vec<u8>, BT> = module_test.vec_znx_dft_alloc(cols, a_size);
297
298        for j in 0..cols {
299            module_ref.vec_znx_dft_apply(1, 0, &mut a_dft_ref, j, &a, j);
300            module_test.vec_znx_dft_apply(1, 0, &mut a_dft_test, j, &a, j);
301        }
302
303        let a_dft_ref_digest: u64 = a_dft_ref.digest_u64();
304        let a_dft_test_digest: u64 = a_dft_test.digest_u64();
305
306        for res_size in [1, 2, 3, 4] {
307            let mut res: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, res_size);
308            res.fill_uniform(basek, &mut source);
309
310            let mut res_dft_ref: VecZnxDft<Vec<u8>, BR> = module_ref.vec_znx_dft_alloc(cols, res_size);
311            let mut res_dft_test: VecZnxDft<Vec<u8>, BT> = module_test.vec_znx_dft_alloc(cols, res_size);
312
313            for j in 0..cols {
314                module_ref.vec_znx_dft_apply(1, 0, &mut res_dft_ref, j, &res, j);
315                module_test.vec_znx_dft_apply(1, 0, &mut res_dft_test, j, &res, j);
316            }
317
318            // Fill output with garbage
319            source.fill_bytes(res_dft_ref.data_mut());
320            source.fill_bytes(res_dft_test.data_mut());
321
322            for j in 0..cols {
323                module_ref.svp_apply_dft_to_dft_add(&mut res_dft_ref, j, &svp_ref, j, &a_dft_ref, j);
324                module_test.svp_apply_dft_to_dft_add(&mut res_dft_test, j, &svp_test, j, &a_dft_test, j);
325            }
326
327            // Assert no change to inputs
328            assert_eq!(a_dft_ref.digest_u64(), a_dft_ref_digest);
329            assert_eq!(a_dft_test.digest_u64(), a_dft_test_digest);
330            assert_eq!(svp_ref.digest_u64(), svp_ref_digest);
331            assert_eq!(svp_test.digest_u64(), svp_test_digest);
332            assert_eq!(a.digest_u64(), a_digest);
333
334            let res_big_ref: crate::layouts::VecZnxBig<Vec<u8>, BR> = module_ref.vec_znx_idft_apply_consume(res_dft_ref);
335            let res_big_test: crate::layouts::VecZnxBig<Vec<u8>, BT> = module_test.vec_znx_idft_apply_consume(res_dft_test);
336
337            let mut res_ref: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, res_size);
338            let mut res_test: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, res_size);
339
340            for j in 0..cols {
341                module_ref.vec_znx_big_normalize(
342                    basek,
343                    &mut res_ref,
344                    j,
345                    &res_big_ref,
346                    j,
347                    scratch_ref.borrow(),
348                );
349                module_test.vec_znx_big_normalize(
350                    basek,
351                    &mut res_test,
352                    j,
353                    &res_big_test,
354                    j,
355                    scratch_test.borrow(),
356                );
357            }
358
359            assert_eq!(res_ref, res_test);
360        }
361    }
362}
363
364pub fn test_svp_apply_dft_to_dft_inplace<BR: Backend, BT: Backend>(
365    basek: usize,
366    module_ref: &Module<BR>,
367    module_test: &Module<BT>,
368) where
369    Module<BR>: SvpPrepare<BR>
370        + SvpApplyDftToDftInplace<BR>
371        + SvpPPolAlloc<BR>
372        + VecZnxDftAlloc<BR>
373        + VecZnxBigNormalize<BR>
374        + VecZnxDftApply<BR>
375        + VecZnxIdftApplyConsume<BR>
376        + VecZnxBigNormalizeTmpBytes,
377    Module<BT>: SvpPrepare<BT>
378        + SvpApplyDftToDftInplace<BT>
379        + SvpPPolAlloc<BT>
380        + VecZnxDftAlloc<BT>
381        + VecZnxBigNormalize<BT>
382        + VecZnxDftApply<BT>
383        + VecZnxIdftApplyConsume<BT>
384        + VecZnxBigNormalizeTmpBytes,
385    ScratchOwned<BR>: ScratchOwnedAlloc<BR> + ScratchOwnedBorrow<BR>,
386    ScratchOwned<BT>: ScratchOwnedAlloc<BT> + ScratchOwnedBorrow<BT>,
387{
388    assert_eq!(module_ref.n(), module_test.n());
389    let n: usize = module_ref.n();
390
391    let cols: usize = 2;
392
393    let mut source: Source = Source::new([0u8; 32]);
394
395    let mut scratch_ref: ScratchOwned<BR> = ScratchOwned::alloc(module_ref.vec_znx_big_normalize_tmp_bytes());
396    let mut scratch_test: ScratchOwned<BT> = ScratchOwned::alloc(module_test.vec_znx_big_normalize_tmp_bytes());
397
398    let mut scalar: ScalarZnx<Vec<u8>> = ScalarZnx::alloc(n, cols);
399    scalar.fill_uniform(basek, &mut source);
400
401    let scalar_digest: u64 = scalar.digest_u64();
402
403    let mut svp_ref: SvpPPol<Vec<u8>, BR> = module_ref.svp_ppol_alloc(cols);
404    let mut svp_test: SvpPPol<Vec<u8>, BT> = module_test.svp_ppol_alloc(cols);
405
406    for j in 0..cols {
407        module_ref.svp_prepare(&mut svp_ref, j, &scalar, j);
408        module_test.svp_prepare(&mut svp_test, j, &scalar, j);
409    }
410
411    assert_eq!(scalar.digest_u64(), scalar_digest);
412
413    let svp_ref_digest: u64 = svp_ref.digest_u64();
414    let svp_test_digest: u64 = svp_test.digest_u64();
415
416    for res_size in [1, 2, 3, 4] {
417        let mut res: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, res_size);
418        res.fill_uniform(basek, &mut source);
419        let res_digest: u64 = res.digest_u64();
420
421        let mut res_dft_ref: VecZnxDft<Vec<u8>, BR> = module_ref.vec_znx_dft_alloc(cols, res_size);
422        let mut res_dft_test: VecZnxDft<Vec<u8>, BT> = module_test.vec_znx_dft_alloc(cols, res_size);
423
424        for j in 0..cols {
425            module_ref.vec_znx_dft_apply(1, 0, &mut res_dft_ref, j, &res, j);
426            module_test.vec_znx_dft_apply(1, 0, &mut res_dft_test, j, &res, j);
427        }
428
429        assert_eq!(res.digest_u64(), res_digest);
430
431        for j in 0..cols {
432            module_ref.svp_apply_dft_to_dft_inplace(&mut res_dft_ref, j, &svp_ref, j);
433            module_test.svp_apply_dft_to_dft_inplace(&mut res_dft_test, j, &svp_test, j);
434        }
435
436        // Assert no change to inputs
437        assert_eq!(svp_ref.digest_u64(), svp_ref_digest);
438        assert_eq!(svp_test.digest_u64(), svp_test_digest);
439
440        let res_big_ref: crate::layouts::VecZnxBig<Vec<u8>, BR> = module_ref.vec_znx_idft_apply_consume(res_dft_ref);
441        let res_big_test: crate::layouts::VecZnxBig<Vec<u8>, BT> = module_test.vec_znx_idft_apply_consume(res_dft_test);
442
443        let mut res_ref: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, res_size);
444        let mut res_test: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, res_size);
445
446        for j in 0..cols {
447            module_ref.vec_znx_big_normalize(
448                basek,
449                &mut res_ref,
450                j,
451                &res_big_ref,
452                j,
453                scratch_ref.borrow(),
454            );
455            module_test.vec_znx_big_normalize(
456                basek,
457                &mut res_test,
458                j,
459                &res_big_test,
460                j,
461                scratch_test.borrow(),
462            );
463        }
464
465        println!("res_ref: {}", res_ref);
466        println!("res_test: {}", res_test);
467
468        assert_eq!(res_ref, res_test);
469    }
470}