poulpy/backend/src/hal/tests/vec_znx/generics.rs
backend/src/hal/tests/vec_znx/generics.rsRaw
1use itertools::izip;
2use sampling::source::Source;
3
4use crate::hal::{
5 api::{
6 VecZnxAddNormal, VecZnxAlloc, VecZnxDecodeVeci64, VecZnxEncodeVeci64, VecZnxFillUniform, VecZnxStd, ZnxInfos, ZnxView,
7 ZnxViewMut,
8 },
9 layouts::{Backend, Module, VecZnx},
10};
11
12pub fn test_vec_znx_fill_uniform<B: Backend>(module: &Module<B>)
13where
14 Module<B>: VecZnxFillUniform + VecZnxStd + VecZnxAlloc,
15{
16 let basek: usize = 17;
17 let size: usize = 5;
18 let mut source: Source = Source::new([0u8; 32]);
19 let cols: usize = 2;
20 let zero: Vec<i64> = vec![0; module.n()];
21 let one_12_sqrt: f64 = 0.28867513459481287;
22 (0..cols).for_each(|col_i| {
23 let mut a: VecZnx<_> = module.vec_znx_alloc(cols, size);
24 module.vec_znx_fill_uniform(basek, &mut a, col_i, size * basek, &mut source);
25 (0..cols).for_each(|col_j| {
26 if col_j != col_i {
27 (0..size).for_each(|limb_i| {
28 assert_eq!(a.at(col_j, limb_i), zero);
29 })
30 } else {
31 let std: f64 = module.vec_znx_std(basek, &a, col_i);
32 assert!(
33 (std - one_12_sqrt).abs() < 0.01,
34 "std={} ~!= {}",
35 std,
36 one_12_sqrt
37 );
38 }
39 })
40 });
41}
42
43pub fn test_vec_znx_add_normal<B: Backend>(module: &Module<B>)
44where
45 Module<B>: VecZnxAddNormal + VecZnxStd + VecZnxAlloc,
46{
47 let basek: usize = 17;
48 let k: usize = 2 * 17;
49 let size: usize = 5;
50 let sigma: f64 = 3.2;
51 let bound: f64 = 6.0 * sigma;
52 let mut source: Source = Source::new([0u8; 32]);
53 let cols: usize = 2;
54 let zero: Vec<i64> = vec![0; module.n()];
55 let k_f64: f64 = (1u64 << k as u64) as f64;
56 (0..cols).for_each(|col_i| {
57 let mut a: VecZnx<_> = module.vec_znx_alloc(cols, size);
58 module.vec_znx_add_normal(basek, &mut a, col_i, k, &mut source, sigma, bound);
59 (0..cols).for_each(|col_j| {
60 if col_j != col_i {
61 (0..size).for_each(|limb_i| {
62 assert_eq!(a.at(col_j, limb_i), zero);
63 })
64 } else {
65 let std: f64 = module.vec_znx_std(basek, &a, col_i) * k_f64;
66 assert!((std - sigma).abs() < 0.1, "std={} ~!= {}", std, sigma);
67 }
68 })
69 });
70}
71
72pub fn test_vec_znx_encode_vec_i64_lo_norm<B: Backend>(module: &Module<B>)
73where
74 Module<B>: VecZnxEncodeVeci64 + VecZnxDecodeVeci64 + VecZnxAlloc,
75{
76 let basek: usize = 17;
77 let size: usize = 5;
78 let k: usize = size * basek - 5;
79 let mut a: VecZnx<_> = module.vec_znx_alloc(2, size);
80 let mut source: Source = Source::new([0u8; 32]);
81 let raw: &mut [i64] = a.raw_mut();
82 raw.iter_mut().enumerate().for_each(|(i, x)| *x = i as i64);
83 (0..a.cols()).for_each(|col_i| {
84 let mut have: Vec<i64> = vec![i64::default(); module.n()];
85 have.iter_mut()
86 .for_each(|x| *x = (source.next_i64() << 56) >> 56);
87 module.encode_vec_i64(basek, &mut a, col_i, k, &have, 10);
88 let mut want: Vec<i64> = vec![i64::default(); module.n()];
89 module.decode_vec_i64(basek, &a, col_i, k, &mut want);
90 izip!(want, have).for_each(|(a, b)| assert_eq!(a, b, "{} != {}", a, b));
91 });
92}
93
94pub fn test_vec_znx_encode_vec_i64_hi_norm<B: Backend>(module: &Module<B>)
95where
96 Module<B>: VecZnxEncodeVeci64 + VecZnxDecodeVeci64 + VecZnxAlloc,
97{
98 let basek: usize = 17;
99 let size: usize = 5;
100 for k in [1, basek / 2, size * basek - 5] {
101 let mut a: VecZnx<_> = module.vec_znx_alloc(2, size);
102 let mut source = Source::new([0u8; 32]);
103 let raw: &mut [i64] = a.raw_mut();
104 raw.iter_mut().enumerate().for_each(|(i, x)| *x = i as i64);
105 (0..a.cols()).for_each(|col_i| {
106 let mut have: Vec<i64> = vec![i64::default(); module.n()];
107 have.iter_mut().for_each(|x| {
108 if k < 64 {
109 *x = source.next_u64n(1 << k, (1 << k) - 1) as i64;
110 } else {
111 *x = source.next_i64();
112 }
113 });
114 module.encode_vec_i64(basek, &mut a, col_i, k, &have, 63);
115 let mut want: Vec<i64> = vec![i64::default(); module.n()];
116 module.decode_vec_i64(basek, &a, col_i, k, &mut want);
117 izip!(want, have).for_each(|(a, b)| assert_eq!(a, b, "{} != {}", a, b));
118 })
119 }
120}