poulpy/poulpy-hal/src/test_suite/vec_znx.rs
poulpy-hal/src/test_suite/vec_znx.rsRaw
1use std::f64::consts::SQRT_2;
2
3use crate::{
4 api::{
5 ModuleNew, ScratchOwnedAlloc, ScratchOwnedBorrow, VecZnxAdd, VecZnxAddInplace, VecZnxAddNormal, VecZnxAddScalar,
6 VecZnxAddScalarInplace, VecZnxAutomorphism, VecZnxAutomorphismInplace, VecZnxAutomorphismInplaceTmpBytes, VecZnxCopy,
7 VecZnxFillNormal, VecZnxFillUniform, VecZnxLsh, VecZnxLshInplace, VecZnxLshTmpBytes, VecZnxMergeRings,
8 VecZnxMergeRingsTmpBytes, VecZnxMulXpMinusOne, VecZnxMulXpMinusOneInplace, VecZnxMulXpMinusOneInplaceTmpBytes,
9 VecZnxNegate, VecZnxNegateInplace, VecZnxNormalize, VecZnxNormalizeInplace, VecZnxNormalizeTmpBytes, VecZnxRotate,
10 VecZnxRotateInplace, VecZnxRotateInplaceTmpBytes, VecZnxRsh, VecZnxRshInplace, VecZnxRshTmpBytes, VecZnxSplitRing,
11 VecZnxSplitRingTmpBytes, VecZnxSub, VecZnxSubInplace, VecZnxSubNegateInplace, VecZnxSubScalar, VecZnxSubScalarInplace,
12 VecZnxSwitchRing,
13 },
14 layouts::{Backend, DigestU64, FillUniform, Module, ScalarZnx, ScratchOwned, VecZnx, ZnxInfos, ZnxView, ZnxViewMut},
15 reference::znx::znx_copy_ref,
16 source::Source,
17};
18
19pub fn test_vec_znx_encode_vec_i64() {
20 let n: usize = 32;
21 let base2k: usize = 17;
22 let size: usize = 5;
23 for k in [1, base2k / 2, size * base2k - 5] {
24 let mut a: VecZnx<Vec<u8>> = VecZnx::alloc(n, 2, size);
25 let mut source = Source::new([0u8; 32]);
26 let raw: &mut [i64] = a.raw_mut();
27 raw.iter_mut().enumerate().for_each(|(i, x)| *x = i as i64);
28 (0..a.cols()).for_each(|col_i| {
29 let mut have: Vec<i64> = vec![i64::default(); n];
30 have.iter_mut().for_each(|x| {
31 if k < 64 {
32 *x = source.next_u64n(1 << k, (1 << k) - 1) as i64;
33 } else {
34 *x = source.next_i64();
35 }
36 });
37 a.encode_vec_i64(base2k, col_i, k, &have);
38 let mut want: Vec<i64> = vec![i64::default(); n];
39 a.decode_vec_i64(base2k, col_i, k, &mut want);
40 assert_eq!(have, want, "{:?} != {:?}", &have, &want);
41 })
42 }
43}
44
45pub fn test_vec_znx_add_scalar<BR: Backend, BT: Backend>(base2k: usize, module_ref: &Module<BR>, module_test: &Module<BT>)
46where
47 Module<BR>: VecZnxAddScalar,
48 Module<BT>: VecZnxAddScalar,
49{
50 assert_eq!(module_ref.n(), module_test.n());
51
52 let n: usize = module_ref.n();
53
54 let mut source: Source = Source::new([0u8; 32]);
55 let cols: usize = 2;
56
57 let mut a: ScalarZnx<Vec<u8>> = ScalarZnx::alloc(n, cols);
58 a.fill_uniform(base2k, &mut source);
59 let a_digest = a.digest_u64();
60
61 for a_size in [1, 2, 3, 4] {
62 let mut b: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, a_size);
63 b.fill_uniform(base2k, &mut source);
64 let b_digest: u64 = b.digest_u64();
65
66 for res_size in [1, 2, 3, 4] {
67 let mut rest_ref: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, res_size);
68 let mut res_test: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, res_size);
69
70 // Set d to garbage
71 rest_ref.fill_uniform(base2k, &mut source);
72 res_test.fill_uniform(base2k, &mut source);
73
74 // Reference
75 for i in 0..cols {
76 module_ref.vec_znx_add_scalar(&mut rest_ref, i, &a, i, &b, i, (res_size.min(a_size)) - 1);
77 module_test.vec_znx_add_scalar(&mut res_test, i, &a, i, &b, i, (res_size.min(a_size)) - 1);
78 }
79
80 assert_eq!(b.digest_u64(), b_digest);
81 assert_eq!(a.digest_u64(), a_digest);
82 assert_eq!(rest_ref, res_test);
83 }
84 }
85}
86
87pub fn test_vec_znx_add_scalar_inplace<BR: Backend, BT: Backend>(base2k: usize, module_ref: &Module<BR>, module_test: &Module<BT>)
88where
89 Module<BR>: VecZnxAddScalarInplace,
90 Module<BT>: VecZnxAddScalarInplace,
91{
92 assert_eq!(module_ref.n(), module_test.n());
93
94 let n: usize = module_ref.n();
95
96 let mut source: Source = Source::new([0u8; 32]);
97 let cols: usize = 2;
98
99 let mut b: ScalarZnx<Vec<u8>> = ScalarZnx::alloc(n, cols);
100 b.fill_uniform(base2k, &mut source);
101 let b_digest: u64 = b.digest_u64();
102
103 for res_size in [1, 2, 3, 4] {
104 let mut rest_ref: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, res_size);
105 let mut res_test: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, res_size);
106
107 rest_ref.fill_uniform(base2k, &mut source);
108 res_test.raw_mut().copy_from_slice(rest_ref.raw());
109
110 for i in 0..cols {
111 module_ref.vec_znx_add_scalar_inplace(&mut rest_ref, i, res_size - 1, &b, i);
112 module_test.vec_znx_add_scalar_inplace(&mut res_test, i, res_size - 1, &b, i);
113 }
114
115 assert_eq!(b.digest_u64(), b_digest);
116 assert_eq!(rest_ref, res_test);
117 }
118}
119pub fn test_vec_znx_add<BR: Backend, BT: Backend>(base2k: usize, module_ref: &Module<BR>, module_test: &Module<BT>)
120where
121 Module<BR>: VecZnxAdd,
122 Module<BT>: VecZnxAdd,
123{
124 assert_eq!(module_ref.n(), module_test.n());
125 let n: usize = module_ref.n();
126
127 let mut source: Source = Source::new([0u8; 32]);
128 let cols: usize = 2;
129
130 for a_size in [1, 2, 3, 4] {
131 let mut a: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, a_size);
132 a.fill_uniform(base2k, &mut source);
133
134 let a_digest: u64 = a.digest_u64();
135
136 for b_size in [1, 2, 3, 4] {
137 let mut b: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, b_size);
138 b.fill_uniform(base2k, &mut source);
139
140 let b_digest: u64 = b.digest_u64();
141
142 for res_size in [1, 2, 3, 4] {
143 let mut res_ref: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, res_size);
144 let mut res_test: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, res_size);
145
146 // Set d to garbage
147 res_ref.fill_uniform(base2k, &mut source);
148 res_test.fill_uniform(base2k, &mut source);
149
150 // Reference
151 for i in 0..cols {
152 module_test.vec_znx_add(&mut res_ref, i, &a, i, &b, i);
153 module_ref.vec_znx_add(&mut res_test, i, &a, i, &b, i);
154 }
155
156 assert_eq!(a.digest_u64(), a_digest);
157 assert_eq!(b.digest_u64(), b_digest);
158
159 assert_eq!(res_ref, res_test);
160 }
161 }
162 }
163}
164
165pub fn test_vec_znx_add_inplace<BR: Backend, BT: Backend>(base2k: usize, module_ref: &Module<BR>, module_test: &Module<BT>)
166where
167 Module<BR>: VecZnxAddInplace,
168 Module<BT>: VecZnxAddInplace,
169{
170 assert_eq!(module_ref.n(), module_test.n());
171 let n: usize = module_ref.n();
172
173 let mut source: Source = Source::new([0u8; 32]);
174 let cols: usize = 2;
175
176 for a_size in [1, 2, 3, 4] {
177 let mut a: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, a_size);
178 a.fill_uniform(base2k, &mut source);
179 let a_digest: u64 = a.digest_u64();
180
181 for res_size in [1, 2, 3, 4] {
182 let mut res_ref: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, res_size);
183 let mut res_test: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, res_size);
184
185 res_ref.fill_uniform(base2k, &mut source);
186 res_test.raw_mut().copy_from_slice(res_ref.raw());
187
188 for i in 0..cols {
189 module_ref.vec_znx_add_inplace(&mut res_ref, i, &a, i);
190 module_test.vec_znx_add_inplace(&mut res_test, i, &a, i);
191 }
192
193 assert_eq!(a.digest_u64(), a_digest);
194 assert_eq!(res_ref, res_test);
195 }
196 }
197}
198
199pub fn test_vec_znx_automorphism<BR: Backend, BT: Backend>(base2k: usize, module_ref: &Module<BR>, module_test: &Module<BT>)
200where
201 Module<BR>: VecZnxAutomorphism,
202 Module<BT>: VecZnxAutomorphism,
203{
204 assert_eq!(module_ref.n(), module_test.n());
205 let n: usize = module_ref.n();
206
207 let mut source: Source = Source::new([0u8; 32]);
208 let cols: usize = 2;
209
210 for a_size in [1, 2, 3, 4] {
211 let mut a: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, a_size);
212 a.fill_uniform(base2k, &mut source);
213 let a_digest: u64 = a.digest_u64();
214
215 for res_size in [1, 2, 3, 4] {
216 let mut res_ref: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, res_size);
217 let mut res_test: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, res_size);
218
219 let p: i64 = -5;
220
221 // Normalize on c
222 for i in 0..cols {
223 module_ref.vec_znx_automorphism(p, &mut res_ref, i, &a, i);
224 module_test.vec_znx_automorphism(p, &mut res_test, i, &a, i);
225 }
226
227 assert_eq!(a.digest_u64(), a_digest);
228 assert_eq!(res_ref, res_test);
229
230 let p: i64 = 5;
231
232 // Normalize on c
233 for i in 0..cols {
234 module_ref.vec_znx_automorphism(p, &mut res_ref, i, &a, i);
235 module_test.vec_znx_automorphism(p, &mut res_test, i, &a, i);
236 }
237
238 assert_eq!(a.digest_u64(), a_digest);
239 assert_eq!(res_ref, res_test);
240 }
241 }
242}
243
244pub fn test_vec_znx_automorphism_inplace<BR: Backend, BT: Backend>(
245 base2k: usize,
246 module_ref: &Module<BR>,
247 module_test: &Module<BT>,
248) where
249 Module<BR>: VecZnxAutomorphismInplace<BR> + VecZnxAutomorphismInplaceTmpBytes,
250 ScratchOwned<BR>: ScratchOwnedAlloc<BR> + ScratchOwnedBorrow<BR>,
251 Module<BT>: VecZnxAutomorphismInplace<BT> + VecZnxAutomorphismInplaceTmpBytes,
252 ScratchOwned<BT>: ScratchOwnedAlloc<BT> + ScratchOwnedBorrow<BT>,
253{
254 assert_eq!(module_ref.n(), module_test.n());
255 let n: usize = module_ref.n();
256
257 let mut source: Source = Source::new([0u8; 32]);
258 let cols: usize = 2;
259
260 let mut scratch_ref: ScratchOwned<BR> = ScratchOwned::alloc(module_ref.vec_znx_automorphism_inplace_tmp_bytes());
261 let mut scratch_test: ScratchOwned<BT> = ScratchOwned::alloc(module_test.vec_znx_automorphism_inplace_tmp_bytes());
262
263 for size in [1, 2, 3, 4] {
264 let mut res_ref: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, size);
265 let mut res_test: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, size);
266
267 // Fill a with random i64
268 res_ref.fill_uniform(base2k, &mut source);
269 znx_copy_ref(res_test.raw_mut(), res_ref.raw());
270
271 let p: i64 = -7;
272
273 // Normalize on c
274 for i in 0..cols {
275 module_ref.vec_znx_automorphism_inplace(p, &mut res_ref, i, scratch_ref.borrow());
276 module_test.vec_znx_automorphism_inplace(p, &mut res_test, i, scratch_test.borrow());
277 }
278
279 assert_eq!(res_ref, res_test);
280
281 let p: i64 = 7;
282
283 // Normalize on c
284 for i in 0..cols {
285 module_ref.vec_znx_automorphism_inplace(p, &mut res_ref, i, scratch_ref.borrow());
286 module_test.vec_znx_automorphism_inplace(p, &mut res_test, i, scratch_test.borrow());
287 }
288
289 assert_eq!(res_ref, res_test);
290 }
291}
292
293pub fn test_vec_znx_copy<BR: Backend, BT: Backend>(base2k: usize, module_ref: &Module<BR>, module_test: &Module<BT>)
294where
295 Module<BR>: VecZnxCopy,
296 Module<BT>: VecZnxCopy,
297{
298 assert_eq!(module_ref.n(), module_test.n());
299 let n: usize = module_ref.n();
300
301 let mut source: Source = Source::new([0u8; 32]);
302 let cols: usize = 2;
303
304 for a_size in [1, 2, 3, 4] {
305 let mut a: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, a_size);
306 a.fill_uniform(base2k, &mut source);
307 let a_digest: u64 = a.digest_u64();
308
309 for res_size in [1, 2, 3, 4] {
310 let mut res_0: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, res_size);
311 let mut res_1: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, res_size);
312
313 // Set d to garbage
314 res_0.fill_uniform(base2k, &mut source);
315 res_1.fill_uniform(base2k, &mut source);
316
317 // Reference
318 for i in 0..cols {
319 module_ref.vec_znx_copy(&mut res_0, i, &a, i);
320 module_ref.vec_znx_copy(&mut res_1, i, &a, i);
321 }
322
323 assert_eq!(a.digest_u64(), a_digest);
324 assert_eq!(res_0, res_1);
325 }
326 }
327}
328
329pub fn test_vec_znx_merge_rings<BR: Backend, BT: Backend>(base2k: usize, module_ref: &Module<BR>, module_test: &Module<BT>)
330where
331 Module<BR>: VecZnxMergeRings<BR> + ModuleNew<BR> + VecZnxMergeRingsTmpBytes,
332 Module<BT>: VecZnxMergeRings<BT> + ModuleNew<BT> + VecZnxMergeRingsTmpBytes,
333 ScratchOwned<BR>: ScratchOwnedAlloc<BR> + ScratchOwnedBorrow<BR>,
334 ScratchOwned<BT>: ScratchOwnedAlloc<BT> + ScratchOwnedBorrow<BT>,
335{
336 assert_eq!(module_ref.n(), module_test.n());
337 let n: usize = module_ref.n();
338
339 let mut source: Source = Source::new([0u8; 32]);
340 let cols: usize = 2;
341 let mut scratch_ref: ScratchOwned<BR> = ScratchOwned::alloc(module_ref.vec_znx_merge_rings_tmp_bytes());
342 let mut scratch_test: ScratchOwned<BT> = ScratchOwned::alloc(module_test.vec_znx_merge_rings_tmp_bytes());
343
344 for a_size in [1, 2, 3, 4] {
345 let mut a: [VecZnx<Vec<u8>>; 2] = [VecZnx::alloc(n >> 1, cols, a_size), VecZnx::alloc(n >> 1, cols, a_size)];
346
347 a.iter_mut().for_each(|ai| {
348 ai.fill_uniform(base2k, &mut source);
349 });
350
351 let a_digests: [u64; 2] = [a[0].digest_u64(), a[1].digest_u64()];
352
353 for res_size in [1, 2, 3, 4] {
354 let mut res_ref: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, res_size);
355 let mut res_test: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, res_size);
356
357 res_ref.fill_uniform(base2k, &mut source);
358 res_test.fill_uniform(base2k, &mut source);
359
360 for i in 0..cols {
361 module_ref.vec_znx_merge_rings(&mut res_test, i, &a, i, scratch_ref.borrow());
362 module_test.vec_znx_merge_rings(&mut res_ref, i, &a, i, scratch_test.borrow());
363 }
364
365 assert_eq!([a[0].digest_u64(), a[1].digest_u64()], a_digests);
366 assert_eq!(res_ref, res_test);
367 }
368 }
369}
370
371pub fn test_vec_znx_mul_xp_minus_one<BR: Backend, BT: Backend>(base2k: usize, module_ref: &Module<BR>, module_test: &Module<BT>)
372where
373 Module<BR>: VecZnxMulXpMinusOne,
374 Module<BT>: VecZnxMulXpMinusOne,
375{
376 assert_eq!(module_ref.n(), module_test.n());
377 let n: usize = module_ref.n();
378
379 let mut source: Source = Source::new([0u8; 32]);
380 let cols: usize = 2;
381
382 for a_size in [1, 2, 3, 4] {
383 let mut a: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, a_size);
384 a.fill_uniform(base2k, &mut source);
385
386 let a_digest: u64 = a.digest_u64();
387
388 for res_size in [1, 2, 3, 4] {
389 let mut res_ref: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, res_size);
390 let mut res_test: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, res_size);
391
392 let p: i64 = -5;
393
394 // Normalize on c
395 for i in 0..cols {
396 module_ref.vec_znx_mul_xp_minus_one(p, &mut res_ref, i, &a, i);
397 module_test.vec_znx_mul_xp_minus_one(p, &mut res_test, i, &a, i);
398 }
399
400 assert_eq!(a.digest_u64(), a_digest);
401 assert_eq!(res_test, res_ref);
402
403 let p: i64 = 5;
404
405 // Normalize on c
406 for i in 0..cols {
407 module_ref.vec_znx_mul_xp_minus_one(p, &mut res_ref, i, &a, i);
408 module_test.vec_znx_mul_xp_minus_one(p, &mut res_test, i, &a, i);
409 }
410
411 assert_eq!(a.digest_u64(), a_digest);
412 assert_eq!(res_test, res_ref);
413 }
414 }
415}
416
417pub fn test_vec_znx_mul_xp_minus_one_inplace<BR: Backend, BT: Backend>(
418 base2k: usize,
419 module_ref: &Module<BR>,
420 module_test: &Module<BT>,
421) where
422 Module<BR>: VecZnxMulXpMinusOneInplace<BR> + VecZnxMulXpMinusOneInplaceTmpBytes,
423 ScratchOwned<BR>: ScratchOwnedAlloc<BR> + ScratchOwnedBorrow<BR>,
424 Module<BT>: VecZnxMulXpMinusOneInplace<BT> + VecZnxMulXpMinusOneInplaceTmpBytes,
425 ScratchOwned<BT>: ScratchOwnedAlloc<BT> + ScratchOwnedBorrow<BT>,
426{
427 assert_eq!(module_ref.n(), module_test.n());
428 let n: usize = module_ref.n();
429
430 let mut source: Source = Source::new([0u8; 32]);
431 let cols: usize = 2;
432
433 let mut scratch_ref: ScratchOwned<BR> = ScratchOwned::alloc(module_ref.vec_znx_mul_xp_minus_one_inplace_tmp_bytes());
434 let mut scratch_test: ScratchOwned<BT> = ScratchOwned::alloc(module_test.vec_znx_mul_xp_minus_one_inplace_tmp_bytes());
435
436 for size in [1, 2, 3, 4] {
437 let mut res_ref: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, size);
438 let mut res_test: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, size);
439
440 // Fill a with random i64
441 res_ref.fill_uniform(base2k, &mut source);
442 znx_copy_ref(res_test.raw_mut(), res_ref.raw());
443
444 let p: i64 = -7;
445
446 for i in 0..cols {
447 module_ref.vec_znx_mul_xp_minus_one_inplace(p, &mut res_ref, i, scratch_ref.borrow());
448 module_test.vec_znx_mul_xp_minus_one_inplace(p, &mut res_test, i, scratch_test.borrow());
449 }
450
451 assert_eq!(res_ref, res_test);
452
453 let p: i64 = 7;
454
455 for i in 0..cols {
456 module_ref.vec_znx_mul_xp_minus_one_inplace(p, &mut res_ref, i, scratch_ref.borrow());
457 module_test.vec_znx_mul_xp_minus_one_inplace(p, &mut res_test, i, scratch_test.borrow());
458 }
459
460 assert_eq!(res_ref, res_test);
461 }
462}
463
464pub fn test_vec_znx_negate<BR: Backend, BT: Backend>(base2k: usize, module_ref: &Module<BR>, module_test: &Module<BT>)
465where
466 Module<BR>: VecZnxNegate,
467 Module<BT>: VecZnxNegate,
468{
469 assert_eq!(module_ref.n(), module_test.n());
470 let n: usize = module_ref.n();
471
472 let mut source: Source = Source::new([0u8; 32]);
473 let cols: usize = 2;
474
475 for a_size in [1, 2, 3, 4] {
476 let mut a: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, a_size);
477 a.fill_uniform(base2k, &mut source);
478 let a_digest: u64 = a.digest_u64();
479
480 for res_size in [1, 2, 3, 4] {
481 let mut res_ref: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, res_size);
482 let mut res_test: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, res_size);
483
484 res_ref.fill_uniform(base2k, &mut source);
485 res_test.raw_mut().copy_from_slice(res_ref.raw());
486
487 for i in 0..cols {
488 module_ref.vec_znx_negate(&mut res_ref, i, &a, i);
489 module_test.vec_znx_negate(&mut res_test, i, &a, i);
490 }
491
492 assert_eq!(a.digest_u64(), a_digest);
493 assert_eq!(res_ref, res_test);
494 }
495 }
496}
497
498pub fn test_vec_znx_negate_inplace<BR: Backend, BT: Backend>(base2k: usize, module_ref: &Module<BR>, module_test: &Module<BT>)
499where
500 Module<BR>: VecZnxNegateInplace,
501 Module<BT>: VecZnxNegateInplace,
502{
503 assert_eq!(module_ref.n(), module_test.n());
504 let n: usize = module_ref.n();
505
506 let mut source: Source = Source::new([0u8; 32]);
507 let cols: usize = 2;
508
509 for res_size in [1, 2, 3, 4] {
510 let mut res_ref: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, res_size);
511 let mut res_test: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, res_size);
512
513 res_ref.fill_uniform(base2k, &mut source);
514 res_test.raw_mut().copy_from_slice(res_ref.raw());
515
516 for i in 0..cols {
517 module_ref.vec_znx_negate_inplace(&mut res_ref, i);
518 module_test.vec_znx_negate_inplace(&mut res_test, i);
519 }
520
521 assert_eq!(res_ref, res_test);
522 }
523}
524
525pub fn test_vec_znx_normalize<BR: Backend, BT: Backend>(base2k: usize, module_ref: &Module<BR>, module_test: &Module<BT>)
526where
527 Module<BR>: VecZnxNormalize<BR> + VecZnxNormalizeTmpBytes,
528 ScratchOwned<BR>: ScratchOwnedAlloc<BR> + ScratchOwnedBorrow<BR>,
529 Module<BT>: VecZnxNormalize<BT> + VecZnxNormalizeTmpBytes,
530 ScratchOwned<BT>: ScratchOwnedAlloc<BT> + ScratchOwnedBorrow<BT>,
531{
532 assert_eq!(module_ref.n(), module_test.n());
533 let n: usize = module_ref.n();
534
535 let mut source: Source = Source::new([0u8; 32]);
536 let cols: usize = 2;
537
538 let mut scratch_ref: ScratchOwned<BR> = ScratchOwned::alloc(module_ref.vec_znx_normalize_tmp_bytes());
539 let mut scratch_test: ScratchOwned<BT> = ScratchOwned::alloc(module_test.vec_znx_normalize_tmp_bytes());
540
541 for a_size in [1, 2, 3, 4] {
542 let mut a: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, a_size);
543 a.fill_uniform(base2k, &mut source);
544 let a_digest: u64 = a.digest_u64();
545
546 for res_size in [1, 2, 3, 4] {
547 let mut res_ref: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, res_size);
548 let mut res_test: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, res_size);
549
550 for res_offset in -(base2k as i64)..=(base2k as i64) {
551 // Set d to garbage
552 res_ref.fill_uniform(base2k, &mut source);
553 res_test.fill_uniform(base2k, &mut source);
554
555 // Reference
556 for i in 0..cols {
557 module_ref.vec_znx_normalize(&mut res_ref, base2k, res_offset, i, &a, base2k, i, scratch_ref.borrow());
558 module_test.vec_znx_normalize(&mut res_test, base2k, res_offset, i, &a, base2k, i, scratch_test.borrow());
559 }
560
561 assert_eq!(a.digest_u64(), a_digest);
562 assert_eq!(res_ref, res_test);
563 }
564 }
565 }
566}
567
568pub fn test_vec_znx_normalize_inplace<BR: Backend, BT: Backend>(base2k: usize, module_ref: &Module<BR>, module_test: &Module<BT>)
569where
570 Module<BR>: VecZnxNormalizeInplace<BR> + VecZnxNormalizeTmpBytes,
571 ScratchOwned<BR>: ScratchOwnedAlloc<BR> + ScratchOwnedBorrow<BR>,
572 Module<BT>: VecZnxNormalizeInplace<BT> + VecZnxNormalizeTmpBytes,
573 ScratchOwned<BT>: ScratchOwnedAlloc<BT> + ScratchOwnedBorrow<BT>,
574{
575 assert_eq!(module_ref.n(), module_test.n());
576 let n: usize = module_ref.n();
577
578 let mut source: Source = Source::new([0u8; 32]);
579 let cols: usize = 2;
580
581 let mut scratch_ref: ScratchOwned<BR> = ScratchOwned::alloc(module_ref.vec_znx_normalize_tmp_bytes());
582 let mut scratch_test: ScratchOwned<BT> = ScratchOwned::alloc(module_test.vec_znx_normalize_tmp_bytes());
583
584 for res_size in [1, 2, 3, 4] {
585 let mut res_ref: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, res_size);
586 let mut res_test: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, res_size);
587
588 res_ref.fill_uniform(base2k, &mut source);
589 res_test.raw_mut().copy_from_slice(res_ref.raw());
590
591 // Reference
592 for i in 0..cols {
593 module_ref.vec_znx_normalize_inplace(base2k, &mut res_ref, i, scratch_ref.borrow());
594 module_test.vec_znx_normalize_inplace(base2k, &mut res_test, i, scratch_test.borrow());
595 }
596
597 assert_eq!(res_ref, res_test);
598 }
599}
600
601pub fn test_vec_znx_rotate<BR: Backend, BT: Backend>(base2k: usize, module_ref: &Module<BR>, module_test: &Module<BT>)
602where
603 Module<BR>: VecZnxRotate,
604 Module<BT>: VecZnxRotate,
605{
606 assert_eq!(module_ref.n(), module_test.n());
607 let n: usize = module_ref.n();
608
609 let mut source: Source = Source::new([0u8; 32]);
610 let cols: usize = 2;
611
612 for a_size in [1, 2, 3, 4] {
613 let mut a: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, a_size);
614 a.fill_uniform(base2k, &mut source);
615 let a_digest: u64 = a.digest_u64();
616
617 for res_size in [1, 2, 3, 4] {
618 let mut res_ref: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, res_size);
619 let mut res_test: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, res_size);
620
621 let p: i64 = -5;
622
623 // Normalize on c
624 for i in 0..cols {
625 module_ref.vec_znx_rotate(p, &mut res_ref, i, &a, i);
626 module_test.vec_znx_rotate(p, &mut res_test, i, &a, i);
627 }
628
629 assert_eq!(a.digest_u64(), a_digest);
630 assert_eq!(res_ref, res_test);
631
632 let p: i64 = 5;
633
634 // Normalize on c
635 for i in 0..cols {
636 module_ref.vec_znx_rotate(p, &mut res_ref, i, &a, i);
637 module_test.vec_znx_rotate(p, &mut res_test, i, &a, i);
638 }
639
640 assert_eq!(a.digest_u64(), a_digest);
641 assert_eq!(res_ref, res_test);
642 }
643 }
644}
645
646pub fn test_vec_znx_rotate_inplace<BR: Backend, BT: Backend>(base2k: usize, module_ref: &Module<BR>, module_test: &Module<BT>)
647where
648 Module<BR>: VecZnxRotateInplace<BR> + VecZnxRotateInplaceTmpBytes,
649 ScratchOwned<BR>: ScratchOwnedAlloc<BR> + ScratchOwnedBorrow<BR>,
650 Module<BT>: VecZnxRotateInplace<BT> + VecZnxRotateInplaceTmpBytes,
651 ScratchOwned<BT>: ScratchOwnedAlloc<BT> + ScratchOwnedBorrow<BT>,
652{
653 assert_eq!(module_ref.n(), module_test.n());
654 let n: usize = module_ref.n();
655
656 let mut source: Source = Source::new([0u8; 32]);
657 let cols: usize = 2;
658
659 let mut scratch_ref: ScratchOwned<BR> = ScratchOwned::alloc(module_ref.vec_znx_rotate_inplace_tmp_bytes());
660 let mut scratch_test: ScratchOwned<BT> = ScratchOwned::alloc(module_test.vec_znx_rotate_inplace_tmp_bytes());
661
662 for size in [1, 2, 3, 4] {
663 let mut res_ref: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, size);
664 let mut res_test: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, size);
665
666 // Fill a with random i64
667 res_ref.fill_uniform(base2k, &mut source);
668 znx_copy_ref(res_test.raw_mut(), res_ref.raw());
669
670 let p: i64 = -5;
671
672 // Normalize on c
673 for i in 0..cols {
674 module_ref.vec_znx_rotate_inplace(p, &mut res_ref, i, scratch_ref.borrow());
675 module_test.vec_znx_rotate_inplace(p, &mut res_test, i, scratch_test.borrow());
676 }
677
678 assert_eq!(res_ref, res_test);
679
680 let p: i64 = 5;
681
682 // Normalize on c
683 for i in 0..cols {
684 module_ref.vec_znx_rotate_inplace(p, &mut res_ref, i, scratch_ref.borrow());
685 module_test.vec_znx_rotate_inplace(p, &mut res_test, i, scratch_test.borrow());
686 }
687
688 assert_eq!(res_ref, res_test);
689 }
690}
691
692pub fn test_vec_znx_fill_uniform<B: Backend>(module: &Module<B>)
693where
694 Module<B>: VecZnxFillUniform,
695{
696 let n: usize = module.n();
697 let base2k: usize = 17;
698 let size: usize = 5;
699 let mut source: Source = Source::new([0u8; 32]);
700 let cols: usize = 2;
701 let zero: Vec<i64> = vec![0; n];
702 let one_12_sqrt: f64 = 0.28867513459481287;
703 (0..cols).for_each(|col_i| {
704 let mut a: VecZnx<_> = VecZnx::alloc(n, cols, size);
705 module.vec_znx_fill_uniform(base2k, &mut a, col_i, &mut source);
706 (0..cols).for_each(|col_j| {
707 if col_j != col_i {
708 (0..size).for_each(|limb_i| {
709 assert_eq!(a.at(col_j, limb_i), zero);
710 })
711 } else {
712 let std: f64 = a.stats(base2k, col_i).std();
713 assert!((std - one_12_sqrt).abs() < 0.01, "std={std} ~!= {one_12_sqrt}",);
714 }
715 })
716 });
717}
718
719pub fn test_vec_znx_fill_normal<B: Backend>(module: &Module<B>)
720where
721 Module<B>: VecZnxFillNormal,
722{
723 let n: usize = module.n();
724 let base2k: usize = 17;
725 let k: usize = 2 * 17;
726 let size: usize = 5;
727 let sigma: f64 = 3.2;
728 let bound: f64 = 6.0 * sigma;
729 let mut source: Source = Source::new([0u8; 32]);
730 let cols: usize = 2;
731 let zero: Vec<i64> = vec![0; n];
732 let k_f64: f64 = (1u64 << k as u64) as f64;
733 (0..cols).for_each(|col_i| {
734 let mut a: VecZnx<_> = VecZnx::alloc(n, cols, size);
735 module.vec_znx_fill_normal(base2k, &mut a, col_i, k, &mut source, sigma, bound);
736 (0..cols).for_each(|col_j| {
737 if col_j != col_i {
738 (0..size).for_each(|limb_i| {
739 assert_eq!(a.at(col_j, limb_i), zero);
740 })
741 } else {
742 let std: f64 = a.stats(base2k, col_i).std() * k_f64;
743 assert!((std - sigma).abs() < 0.1, "std={std} ~!= {sigma}");
744 }
745 })
746 });
747}
748
749pub fn test_vec_znx_add_normal<B: Backend>(module: &Module<B>)
750where
751 Module<B>: VecZnxFillNormal + VecZnxAddNormal,
752{
753 let n: usize = module.n();
754 let base2k: usize = 17;
755 let k: usize = 2 * 17;
756 let size: usize = 5;
757 let sigma: f64 = 3.2;
758 let bound: f64 = 6.0 * sigma;
759 let mut source: Source = Source::new([0u8; 32]);
760 let cols: usize = 2;
761 let zero: Vec<i64> = vec![0; n];
762 let k_f64: f64 = (1u64 << k as u64) as f64;
763 let sqrt2: f64 = SQRT_2;
764 (0..cols).for_each(|col_i| {
765 let mut a: VecZnx<_> = VecZnx::alloc(n, cols, size);
766 module.vec_znx_fill_normal(base2k, &mut a, col_i, k, &mut source, sigma, bound);
767 module.vec_znx_add_normal(base2k, &mut a, col_i, k, &mut source, sigma, bound);
768 (0..cols).for_each(|col_j| {
769 if col_j != col_i {
770 (0..size).for_each(|limb_i| {
771 assert_eq!(a.at(col_j, limb_i), zero);
772 })
773 } else {
774 let std: f64 = a.stats(base2k, col_i).std() * k_f64;
775 assert!((std - sigma * sqrt2).abs() < 0.1, "std={std} ~!= {}", sigma * sqrt2);
776 }
777 })
778 });
779}
780
781pub fn test_vec_znx_lsh<BR: Backend, BT: Backend>(base2k: usize, module_ref: &Module<BR>, module_test: &Module<BT>)
782where
783 Module<BR>: VecZnxLsh<BR> + VecZnxLshTmpBytes,
784 ScratchOwned<BR>: ScratchOwnedAlloc<BR> + ScratchOwnedBorrow<BR>,
785 Module<BT>: VecZnxLsh<BT> + VecZnxLshTmpBytes,
786 ScratchOwned<BT>: ScratchOwnedAlloc<BT> + ScratchOwnedBorrow<BT>,
787{
788 assert_eq!(module_ref.n(), module_test.n());
789 let n: usize = module_ref.n();
790
791 let mut source: Source = Source::new([0u8; 32]);
792 let cols: usize = 2;
793
794 let mut scratch_ref: ScratchOwned<BR> = ScratchOwned::alloc(module_ref.vec_znx_lsh_tmp_bytes());
795 let mut scratch_test: ScratchOwned<BT> = ScratchOwned::alloc(module_test.vec_znx_lsh_tmp_bytes());
796
797 for a_size in [1, 2, 3, 4] {
798 let mut a: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, a_size);
799 a.fill_uniform(base2k, &mut source);
800 let a_digest: u64 = a.digest_u64();
801
802 for res_size in [1, 2, 3, 4] {
803 for k in 0..res_size * base2k {
804 let mut res_ref: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, res_size);
805 let mut res_test: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, res_size);
806
807 // Set d to garbage
808 res_ref.fill_uniform(base2k, &mut source);
809 res_test.fill_uniform(base2k, &mut source);
810
811 // Reference
812 for i in 0..cols {
813 module_ref.vec_znx_lsh(base2k, k, &mut res_ref, i, &a, i, scratch_ref.borrow());
814 module_test.vec_znx_lsh(base2k, k, &mut res_test, i, &a, i, scratch_test.borrow());
815 }
816
817 assert_eq!(a.digest_u64(), a_digest);
818 assert_eq!(res_ref, res_test);
819 }
820 }
821 }
822}
823
824pub fn test_vec_znx_lsh_inplace<BR: Backend, BT: Backend>(base2k: usize, module_ref: &Module<BR>, module_test: &Module<BT>)
825where
826 Module<BR>: VecZnxLshInplace<BR> + VecZnxLshTmpBytes,
827 ScratchOwned<BR>: ScratchOwnedAlloc<BR> + ScratchOwnedBorrow<BR>,
828 Module<BT>: VecZnxLshInplace<BT> + VecZnxLshTmpBytes,
829 ScratchOwned<BT>: ScratchOwnedAlloc<BT> + ScratchOwnedBorrow<BT>,
830{
831 assert_eq!(module_ref.n(), module_test.n());
832 let n: usize = module_ref.n();
833
834 let mut source: Source = Source::new([0u8; 32]);
835 let cols: usize = 2;
836
837 let mut scratch_ref: ScratchOwned<BR> = ScratchOwned::alloc(module_ref.vec_znx_lsh_tmp_bytes());
838 let mut scratch_test: ScratchOwned<BT> = ScratchOwned::alloc(module_test.vec_znx_lsh_tmp_bytes());
839
840 for res_size in [1, 2, 3, 4] {
841 for k in 0..base2k * res_size {
842 let mut res_ref: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, res_size);
843 let mut res_test: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, res_size);
844
845 res_ref.fill_uniform(base2k, &mut source);
846 res_test.raw_mut().copy_from_slice(res_ref.raw());
847
848 for i in 0..cols {
849 module_ref.vec_znx_lsh_inplace(base2k, k, &mut res_ref, i, scratch_ref.borrow());
850 module_test.vec_znx_lsh_inplace(base2k, k, &mut res_test, i, scratch_test.borrow());
851 }
852
853 assert_eq!(res_ref, res_test);
854 }
855 }
856}
857
858pub fn test_vec_znx_rsh<BR: Backend, BT: Backend>(base2k: usize, module_ref: &Module<BR>, module_test: &Module<BT>)
859where
860 Module<BR>: VecZnxRsh<BR> + VecZnxRshTmpBytes,
861 ScratchOwned<BR>: ScratchOwnedAlloc<BR> + ScratchOwnedBorrow<BR>,
862 Module<BT>: VecZnxRsh<BT> + VecZnxRshTmpBytes,
863 ScratchOwned<BT>: ScratchOwnedAlloc<BT> + ScratchOwnedBorrow<BT>,
864{
865 assert_eq!(module_ref.n(), module_test.n());
866 let n: usize = module_ref.n();
867 let mut source: Source = Source::new([0u8; 32]);
868 let cols: usize = 2;
869
870 let mut scratch_ref: ScratchOwned<BR> = ScratchOwned::alloc(module_ref.vec_znx_rsh_tmp_bytes());
871 let mut scratch_test: ScratchOwned<BT> = ScratchOwned::alloc(module_test.vec_znx_rsh_tmp_bytes());
872
873 for a_size in [1, 2, 3, 4] {
874 let mut a: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, a_size);
875 a.fill_uniform(base2k, &mut source);
876 let a_digest: u64 = a.digest_u64();
877
878 for res_size in [1, 2, 3, 4] {
879 for k in 0..res_size * base2k {
880 let mut res_ref: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, res_size);
881 let mut res_test: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, res_size);
882
883 // Set d to garbage
884 res_ref.fill_uniform(base2k, &mut source);
885 res_test.fill_uniform(base2k, &mut source);
886
887 // Reference
888 for i in 0..cols {
889 module_ref.vec_znx_rsh(base2k, k, &mut res_ref, i, &a, i, scratch_ref.borrow());
890 module_test.vec_znx_rsh(base2k, k, &mut res_test, i, &a, i, scratch_test.borrow());
891 }
892
893 assert_eq!(a.digest_u64(), a_digest);
894 assert_eq!(res_ref, res_test);
895 }
896 }
897 }
898}
899
900pub fn test_vec_znx_rsh_inplace<BR: Backend, BT: Backend>(base2k: usize, module_ref: &Module<BR>, module_test: &Module<BT>)
901where
902 Module<BR>: VecZnxRshInplace<BR> + VecZnxRshTmpBytes,
903 ScratchOwned<BR>: ScratchOwnedAlloc<BR> + ScratchOwnedBorrow<BR>,
904 Module<BT>: VecZnxRshInplace<BT> + VecZnxRshTmpBytes,
905 ScratchOwned<BT>: ScratchOwnedAlloc<BT> + ScratchOwnedBorrow<BT>,
906{
907 assert_eq!(module_ref.n(), module_test.n());
908 let n: usize = module_ref.n();
909 let mut source: Source = Source::new([0u8; 32]);
910 let cols: usize = 2;
911
912 let mut scratch_ref: ScratchOwned<BR> = ScratchOwned::alloc(module_ref.vec_znx_rsh_tmp_bytes());
913 let mut scratch_test: ScratchOwned<BT> = ScratchOwned::alloc(module_test.vec_znx_rsh_tmp_bytes());
914
915 for res_size in [1, 2, 3, 4] {
916 for k in 0..base2k * res_size {
917 let mut res_ref: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, res_size);
918 let mut res_test: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, res_size);
919
920 res_ref.fill_uniform(base2k, &mut source);
921 res_test.raw_mut().copy_from_slice(res_ref.raw());
922
923 for i in 0..cols {
924 module_ref.vec_znx_rsh_inplace(base2k, k, &mut res_ref, i, scratch_ref.borrow());
925 module_test.vec_znx_rsh_inplace(base2k, k, &mut res_test, i, scratch_test.borrow());
926 }
927
928 assert_eq!(res_ref, res_test);
929 }
930 }
931}
932
933pub fn test_vec_znx_split_ring<BR: Backend, BT: Backend>(base2k: usize, module_ref: &Module<BR>, module_test: &Module<BT>)
934where
935 Module<BR>: VecZnxSplitRing<BR> + ModuleNew<BR> + VecZnxSplitRingTmpBytes,
936 ScratchOwned<BR>: ScratchOwnedAlloc<BR> + ScratchOwnedBorrow<BR>,
937 Module<BT>: VecZnxSplitRing<BT> + ModuleNew<BT> + VecZnxSplitRingTmpBytes,
938 ScratchOwned<BT>: ScratchOwnedAlloc<BT> + ScratchOwnedBorrow<BT>,
939{
940 assert_eq!(module_ref.n(), module_test.n());
941 let n: usize = module_ref.n();
942
943 let mut source: Source = Source::new([0u8; 32]);
944 let cols: usize = 2;
945 let mut scratch_ref: ScratchOwned<BR> = ScratchOwned::alloc(module_ref.vec_znx_split_ring_tmp_bytes());
946 let mut scratch_test: ScratchOwned<BT> = ScratchOwned::alloc(module_test.vec_znx_split_ring_tmp_bytes());
947
948 for a_size in [1, 2, 3, 4] {
949 let mut a: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, a_size);
950 a.fill_uniform(base2k, &mut source);
951 let a_digest = a.digest_u64();
952
953 for res_size in [1, 2, 3, 4] {
954 let mut res_ref: [VecZnx<Vec<u8>>; 2] =
955 [VecZnx::alloc(n >> 1, cols, res_size), VecZnx::alloc(n >> 1, cols, res_size)];
956
957 let mut res_test: [VecZnx<Vec<u8>>; 2] =
958 [VecZnx::alloc(n >> 1, cols, res_size), VecZnx::alloc(n >> 1, cols, res_size)];
959
960 res_ref.iter_mut().for_each(|ri| {
961 ri.fill_uniform(base2k, &mut source);
962 });
963
964 res_test.iter_mut().for_each(|ri| {
965 ri.fill_uniform(base2k, &mut source);
966 });
967
968 for i in 0..cols {
969 module_ref.vec_znx_split_ring(&mut res_ref, i, &a, i, scratch_ref.borrow());
970 module_test.vec_znx_split_ring(&mut res_test, i, &a, i, scratch_test.borrow());
971 }
972
973 assert_eq!(a.digest_u64(), a_digest);
974
975 for (a, b) in res_ref.iter().zip(res_test.iter()) {
976 assert_eq!(a, b);
977 }
978 }
979 }
980}
981
982pub fn test_vec_znx_sub_scalar<BR: Backend, BT: Backend>(base2k: usize, module_ref: &Module<BR>, module_test: &Module<BT>)
983where
984 Module<BR>: VecZnxSubScalar,
985 Module<BT>: VecZnxSubScalar,
986{
987 assert_eq!(module_ref.n(), module_test.n());
988 let n: usize = module_ref.n();
989
990 let mut source: Source = Source::new([0u8; 32]);
991 let cols: usize = 2;
992
993 let mut a: ScalarZnx<Vec<u8>> = ScalarZnx::alloc(n, cols);
994 a.fill_uniform(base2k, &mut source);
995 let a_digest: u64 = a.digest_u64();
996
997 for b_size in [1, 2, 3, 4] {
998 let mut b: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, b_size);
999 b.fill_uniform(base2k, &mut source);
1000 let b_digest: u64 = b.digest_u64();
1001
1002 for res_size in [1, 2, 3, 4] {
1003 let mut res_0: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, res_size);
1004 let mut res_1: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, res_size);
1005
1006 // Set d to garbage
1007 res_0.fill_uniform(base2k, &mut source);
1008 res_1.fill_uniform(base2k, &mut source);
1009
1010 // Reference
1011 for i in 0..cols {
1012 module_ref.vec_znx_sub_scalar(&mut res_0, i, &a, i, &b, i, (res_size.min(b_size)) - 1);
1013 module_test.vec_znx_sub_scalar(&mut res_1, i, &a, i, &b, i, (res_size.min(b_size)) - 1);
1014 }
1015
1016 assert_eq!(a.digest_u64(), a_digest);
1017 assert_eq!(b.digest_u64(), b_digest);
1018 assert_eq!(res_0, res_1);
1019 }
1020 }
1021}
1022
1023pub fn test_vec_znx_sub_scalar_inplace<BR: Backend, BT: Backend>(base2k: usize, module_ref: &Module<BR>, module_test: &Module<BT>)
1024where
1025 Module<BR>: VecZnxSubScalarInplace,
1026 Module<BT>: VecZnxSubScalarInplace,
1027{
1028 assert_eq!(module_ref.n(), module_test.n());
1029 let n: usize = module_ref.n();
1030
1031 let mut source: Source = Source::new([0u8; 32]);
1032 let cols: usize = 2;
1033
1034 let mut a: ScalarZnx<Vec<u8>> = ScalarZnx::alloc(n, cols);
1035 a.fill_uniform(base2k, &mut source);
1036 let a_digest: u64 = a.digest_u64();
1037
1038 for res_size in [1, 2, 3, 4] {
1039 let mut res_0: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, res_size);
1040 let mut res_1: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, res_size);
1041
1042 res_0.fill_uniform(base2k, &mut source);
1043 res_1.raw_mut().copy_from_slice(res_0.raw());
1044
1045 for i in 0..cols {
1046 module_ref.vec_znx_sub_scalar_inplace(&mut res_0, i, res_size - 1, &a, i);
1047 module_test.vec_znx_sub_scalar_inplace(&mut res_1, i, res_size - 1, &a, i);
1048 }
1049
1050 assert_eq!(a.digest_u64(), a_digest);
1051 assert_eq!(res_0, res_1);
1052 }
1053}
1054
1055pub fn test_vec_znx_sub<BR: Backend, BT: Backend>(base2k: usize, module_ref: &Module<BR>, module_test: &Module<BT>)
1056where
1057 Module<BR>: VecZnxSub,
1058 Module<BT>: VecZnxSub,
1059{
1060 assert_eq!(module_ref.n(), module_test.n());
1061 let n: usize = module_ref.n();
1062
1063 let mut source: Source = Source::new([0u8; 32]);
1064 let cols: usize = 2;
1065
1066 for a_size in [1, 2, 3, 4] {
1067 let mut a: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, a_size);
1068 a.fill_uniform(base2k, &mut source);
1069 let a_digest: u64 = a.digest_u64();
1070
1071 for b_size in [1, 2, 3, 4] {
1072 let mut b: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, b_size);
1073 b.fill_uniform(base2k, &mut source);
1074 let b_digest: u64 = b.digest_u64();
1075
1076 for res_size in [1, 2, 3, 4] {
1077 let mut res_ref: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, res_size);
1078 let mut res_test: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, res_size);
1079
1080 // Set d to garbage
1081 res_ref.fill_uniform(base2k, &mut source);
1082 res_test.fill_uniform(base2k, &mut source);
1083
1084 // Reference
1085 for i in 0..cols {
1086 module_test.vec_znx_sub(&mut res_ref, i, &a, i, &b, i);
1087 module_ref.vec_znx_sub(&mut res_test, i, &a, i, &b, i);
1088 }
1089
1090 assert_eq!(a.digest_u64(), a_digest);
1091 assert_eq!(b.digest_u64(), b_digest);
1092
1093 assert_eq!(res_ref, res_test);
1094 }
1095 }
1096 }
1097}
1098
1099pub fn test_vec_znx_sub_inplace<BR: Backend, BT: Backend>(base2k: usize, module_ref: &Module<BR>, module_test: &Module<BT>)
1100where
1101 Module<BR>: VecZnxSubInplace,
1102 Module<BT>: VecZnxSubInplace,
1103{
1104 assert_eq!(module_ref.n(), module_test.n());
1105 let n: usize = module_ref.n();
1106
1107 let mut source: Source = Source::new([0u8; 32]);
1108 let cols: usize = 2;
1109
1110 for a_size in [1, 2, 3, 4] {
1111 let mut a: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, a_size);
1112 a.fill_uniform(base2k, &mut source);
1113 let a_digest: u64 = a.digest_u64();
1114
1115 for res_size in [1, 2, 3, 4] {
1116 let mut res_ref: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, res_size);
1117 let mut res_test: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, res_size);
1118
1119 res_ref.fill_uniform(base2k, &mut source);
1120 res_test.raw_mut().copy_from_slice(res_ref.raw());
1121
1122 for i in 0..cols {
1123 module_test.vec_znx_sub_inplace(&mut res_ref, i, &a, i);
1124 module_ref.vec_znx_sub_inplace(&mut res_test, i, &a, i);
1125 }
1126
1127 assert_eq!(a.digest_u64(), a_digest);
1128 assert_eq!(res_ref, res_test);
1129 }
1130 }
1131}
1132
1133pub fn test_vec_znx_sub_negate_inplace<BR: Backend, BT: Backend>(base2k: usize, module_ref: &Module<BR>, module_test: &Module<BT>)
1134where
1135 Module<BR>: VecZnxSubNegateInplace,
1136 Module<BT>: VecZnxSubNegateInplace,
1137{
1138 assert_eq!(module_ref.n(), module_test.n());
1139 let n: usize = module_ref.n();
1140
1141 let mut source: Source = Source::new([0u8; 32]);
1142 let cols: usize = 2;
1143
1144 for a_size in [1, 2, 3, 4] {
1145 let mut a: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, a_size);
1146 a.fill_uniform(base2k, &mut source);
1147 let a_digest: u64 = a.digest_u64();
1148
1149 for res_size in [1, 2, 3, 4] {
1150 let mut res_ref: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, res_size);
1151 let mut res_test: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, res_size);
1152
1153 res_ref.fill_uniform(base2k, &mut source);
1154 res_test.raw_mut().copy_from_slice(res_ref.raw());
1155
1156 for i in 0..cols {
1157 module_test.vec_znx_sub_negate_inplace(&mut res_ref, i, &a, i);
1158 module_ref.vec_znx_sub_negate_inplace(&mut res_test, i, &a, i);
1159 }
1160
1161 assert_eq!(a.digest_u64(), a_digest);
1162 assert_eq!(res_ref, res_test);
1163 }
1164 }
1165}
1166
1167pub fn test_vec_znx_switch_ring<BR: Backend, BT: Backend>(base2k: usize, module_ref: &Module<BR>, module_test: &Module<BT>)
1168where
1169 Module<BR>: VecZnxSwitchRing,
1170 Module<BT>: VecZnxSwitchRing,
1171{
1172 assert_eq!(module_ref.n(), module_test.n());
1173 let n: usize = module_ref.n();
1174
1175 let mut source: Source = Source::new([0u8; 32]);
1176 let cols: usize = 2;
1177
1178 for a_size in [1, 2, 3, 4] {
1179 let mut a: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, a_size);
1180
1181 // Fill a with random i64
1182 a.fill_uniform(base2k, &mut source);
1183 let a_digest: u64 = a.digest_u64();
1184
1185 for res_size in [1, 2, 3, 4] {
1186 {
1187 let mut res_ref: VecZnx<Vec<u8>> = VecZnx::alloc(n << 1, cols, res_size);
1188 let mut res_test: VecZnx<Vec<u8>> = VecZnx::alloc(n << 1, cols, res_size);
1189
1190 res_ref.fill_uniform(base2k, &mut source);
1191 res_test.fill_uniform(base2k, &mut source);
1192
1193 // Normalize on c
1194 for i in 0..cols {
1195 module_ref.vec_znx_switch_ring(&mut res_ref, i, &a, i);
1196 module_test.vec_znx_switch_ring(&mut res_test, i, &a, i);
1197 }
1198
1199 assert_eq!(a.digest_u64(), a_digest);
1200 assert_eq!(res_ref, res_test);
1201 }
1202
1203 {
1204 let mut res_ref: VecZnx<Vec<u8>> = VecZnx::alloc(n >> 1, cols, res_size);
1205 let mut res_test: VecZnx<Vec<u8>> = VecZnx::alloc(n >> 1, cols, res_size);
1206
1207 res_ref.fill_uniform(base2k, &mut source);
1208 res_test.fill_uniform(base2k, &mut source);
1209
1210 // Normalize on c
1211 for i in 0..cols {
1212 module_ref.vec_znx_switch_ring(&mut res_ref, i, &a, i);
1213 module_test.vec_znx_switch_ring(&mut res_test, i, &a, i);
1214 }
1215
1216 assert_eq!(a.digest_u64(), a_digest);
1217 assert_eq!(res_ref, res_test);
1218 }
1219 }
1220 }
1221}