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>(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}