arnaucube
arnaucube/poulpyPublic Self-hosted repository
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}