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