arnaucube
arnaucube/poulpyPublic Self-hosted repository
poulpy/poulpy-hal/src/reference/vec_znx/split_ring.rs
poulpy-hal/src/reference/vec_znx/split_ring.rsRaw
 1use crate::{
 2    layouts::{VecZnx, VecZnxToMut, VecZnxToRef, ZnxInfos, ZnxView, ZnxViewMut},
 3    reference::znx::{ZnxRotate, ZnxSwitchRing, ZnxZero},
 4};
 5
 6pub fn vec_znx_split_ring_tmp_bytes(n: usize) -> usize {
 7    n * size_of::<i64>()
 8}
 9
10pub fn vec_znx_split_ring<R, A, ZNXARI>(res: &mut [R], res_col: usize, a: &A, a_col: usize, tmp: &mut [i64])
11where
12    R: VecZnxToMut,
13    A: VecZnxToRef,
14    ZNXARI: ZnxSwitchRing + ZnxRotate + ZnxZero,
15{
16    let a: VecZnx<&[u8]> = a.to_ref();
17    let a_size = a.size();
18
19    let (_n_in, _n_out) = (a.n(), res[0].to_mut().n());
20
21    #[cfg(debug_assertions)]
22    {
23        assert_eq!(tmp.len(), a.n());
24
25        assert!(_n_out < _n_in, "invalid a: output ring degree should be smaller");
26
27        res[1..].iter_mut().for_each(|bi| {
28            assert_eq!(
29                bi.to_mut().n(),
30                _n_out,
31                "invalid input a: all VecZnx must have the same degree"
32            )
33        });
34
35        assert!(_n_in.is_multiple_of(_n_out));
36        assert_eq!(res.len(), _n_in / _n_out);
37    }
38
39    res.iter_mut().enumerate().for_each(|(i, bi)| {
40        let mut bi: VecZnx<&mut [u8]> = bi.to_mut();
41
42        let min_size = bi.size().min(a_size);
43
44        if i == 0 {
45            for j in 0..min_size {
46                ZNXARI::znx_switch_ring(bi.at_mut(res_col, j), a.at(a_col, j));
47            }
48        } else {
49            for j in 0..min_size {
50                ZNXARI::znx_rotate(-(i as i64), tmp, a.at(a_col, j));
51                ZNXARI::znx_switch_ring(bi.at_mut(res_col, j), tmp);
52            }
53        }
54
55        for j in min_size..bi.size() {
56            ZNXARI::znx_zero(bi.at_mut(res_col, j));
57        }
58    })
59}