arnaucube
arnaucube/poulpyPublic Self-hosted repository
poulpy/poulpy-core/src/conversion/glwe_to_lwe.rs
poulpy-core/src/conversion/glwe_to_lwe.rsRaw
  1use poulpy_hal::{
  2    api::ModuleN,
  3    layouts::{Backend, DataMut, Module, Scratch, ZnxView, ZnxViewMut, ZnxZero},
  4};
  5
  6use crate::{
  7    GLWEKeyswitch, GLWERotate, ScratchTakeCore,
  8    layouts::{GGLWEInfos, GGLWEPreparedToRef, GLWE, GLWEInfos, GLWELayout, GLWEToRef, LWE, LWEInfos, LWEToMut, Rank},
  9};
 10
 11pub trait LWESampleExtract
 12where
 13    Self: ModuleN,
 14{
 15    fn lwe_sample_extract<R, A>(&self, res: &mut R, a: &A)
 16    where
 17        R: LWEToMut,
 18        A: GLWEToRef,
 19    {
 20        let res: &mut LWE<&mut [u8]> = &mut res.to_mut();
 21        let a: &GLWE<&[u8]> = &a.to_ref();
 22
 23        assert!(res.n() <= a.n());
 24        assert_eq!(a.n(), self.n() as u32);
 25        assert!(res.base2k() == a.base2k());
 26
 27        let min_size: usize = res.size().min(a.size());
 28        let n: usize = res.n().into();
 29
 30        res.data.zero();
 31        (0..min_size).for_each(|i| {
 32            let data_lwe: &mut [i64] = res.data.at_mut(0, i);
 33            data_lwe[0] = a.data.at(0, i)[0];
 34            data_lwe[1..].copy_from_slice(&a.data.at(1, i)[..n]);
 35        });
 36    }
 37}
 38
 39impl<BE: Backend> LWESampleExtract for Module<BE> where Self: ModuleN {}
 40impl<BE: Backend> LWEFromGLWE<BE> for Module<BE> where Self: GLWEKeyswitch<BE> + LWESampleExtract + GLWERotate<BE> {}
 41
 42pub trait LWEFromGLWE<BE: Backend>
 43where
 44    Self: GLWEKeyswitch<BE> + LWESampleExtract + GLWERotate<BE>,
 45{
 46    fn lwe_from_glwe_tmp_bytes<R, A, K>(&self, lwe_infos: &R, glwe_infos: &A, key_infos: &K) -> usize
 47    where
 48        R: LWEInfos,
 49        A: GLWEInfos,
 50        K: GGLWEInfos,
 51    {
 52        let res_infos: GLWELayout = GLWELayout {
 53            n: self.n().into(),
 54            base2k: lwe_infos.base2k(),
 55            k: lwe_infos.k(),
 56            rank: Rank(1),
 57        };
 58
 59        GLWE::bytes_of(
 60            self.n().into(),
 61            lwe_infos.base2k(),
 62            lwe_infos.k(),
 63            1u32.into(),
 64        ) + GLWE::bytes_of_from_infos(glwe_infos)
 65            + self.glwe_keyswitch_tmp_bytes(&res_infos, glwe_infos, key_infos)
 66    }
 67
 68    fn lwe_from_glwe<R, A, K>(&self, res: &mut R, a: &A, a_idx: usize, key: &K, scratch: &mut Scratch<BE>)
 69    where
 70        R: LWEToMut,
 71        A: GLWEToRef,
 72        K: GGLWEPreparedToRef<BE> + GGLWEInfos,
 73        Scratch<BE>: ScratchTakeCore<BE>,
 74    {
 75        let res: &mut LWE<&mut [u8]> = &mut res.to_mut();
 76        let a: &GLWE<&[u8]> = &a.to_ref();
 77
 78        assert_eq!(a.n(), self.n() as u32);
 79        assert_eq!(key.n(), self.n() as u32);
 80        assert!(res.n() <= self.n() as u32);
 81
 82        let glwe_layout: GLWELayout = GLWELayout {
 83            n: self.n().into(),
 84            base2k: res.base2k(),
 85            k: res.k(),
 86            rank: Rank(1),
 87        };
 88
 89        let (mut tmp_glwe_rank_1, scratch_1) = scratch.take_glwe(&glwe_layout);
 90
 91        match a_idx {
 92            0 => {
 93                self.glwe_keyswitch(&mut tmp_glwe_rank_1, a, key, scratch_1);
 94            }
 95            _ => {
 96                let (mut tmp_glwe_in, scratch_2) = scratch_1.take_glwe(a);
 97                self.glwe_rotate(-(a_idx as i64), &mut tmp_glwe_in, a);
 98                self.glwe_keyswitch(&mut tmp_glwe_rank_1, &tmp_glwe_in, key, scratch_2);
 99            }
100        }
101
102        self.lwe_sample_extract(res, &tmp_glwe_rank_1);
103    }
104}
105
106impl LWE<Vec<u8>> {
107    pub fn from_glwe_tmp_bytes<R, A, K, M, BE: Backend>(module: &M, lwe_infos: &R, glwe_infos: &A, key_infos: &K) -> usize
108    where
109        R: LWEInfos,
110        A: GLWEInfos,
111        K: GGLWEInfos,
112        M: LWEFromGLWE<BE>,
113    {
114        module.lwe_from_glwe_tmp_bytes(lwe_infos, glwe_infos, key_infos)
115    }
116}
117
118impl<D: DataMut> LWE<D> {
119    pub fn sample_extract<A, M>(&mut self, module: &M, a: &A)
120    where
121        A: GLWEToRef,
122        M: LWESampleExtract,
123    {
124        module.lwe_sample_extract(self, a);
125    }
126
127    pub fn from_glwe<A, K, M, BE: Backend>(&mut self, module: &M, a: &A, a_idx: usize, key: &K, scratch: &mut Scratch<BE>)
128    where
129        A: GLWEToRef,
130        K: GGLWEPreparedToRef<BE> + GGLWEInfos,
131        M: LWEFromGLWE<BE>,
132        Scratch<BE>: ScratchTakeCore<BE>,
133    {
134        module.lwe_from_glwe(self, a, a_idx, key, scratch);
135    }
136}