arnaucube
arnaucube/poulpyPublic Self-hosted repository
poulpy/poulpy-core/src/layouts/prepared/glwe_to_lwe_ksk.rs
poulpy-core/src/layouts/prepared/glwe_to_lwe_ksk.rsRaw
  1use poulpy_hal::{
  2    api::{VmpPMatAlloc, VmpPMatAllocBytes, VmpPrepare},
  3    layouts::{Backend, Data, DataMut, DataRef, Module, Scratch},
  4};
  5
  6use crate::layouts::{
  7    Base2K, Degree, Dnum, Dsize, GGLWEInfos, GLWEInfos, GLWEToLWEKey, LWEInfos, Rank, TorusPrecision,
  8    prepared::{GGLWESwitchingKeyPrepared, Prepare, PrepareAlloc},
  9};
 10
 11#[derive(PartialEq, Eq)]
 12pub struct GLWEToLWESwitchingKeyPrepared<D: Data, B: Backend>(pub(crate) GGLWESwitchingKeyPrepared<D, B>);
 13
 14impl<D: Data, B: Backend> LWEInfos for GLWEToLWESwitchingKeyPrepared<D, B> {
 15    fn base2k(&self) -> Base2K {
 16        self.0.base2k()
 17    }
 18
 19    fn k(&self) -> TorusPrecision {
 20        self.0.k()
 21    }
 22
 23    fn n(&self) -> Degree {
 24        self.0.n()
 25    }
 26
 27    fn size(&self) -> usize {
 28        self.0.size()
 29    }
 30}
 31
 32impl<D: Data, B: Backend> GLWEInfos for GLWEToLWESwitchingKeyPrepared<D, B> {
 33    fn rank(&self) -> Rank {
 34        self.rank_out()
 35    }
 36}
 37
 38impl<D: Data, B: Backend> GGLWEInfos for GLWEToLWESwitchingKeyPrepared<D, B> {
 39    fn rank_in(&self) -> Rank {
 40        self.0.rank_in()
 41    }
 42
 43    fn dsize(&self) -> Dsize {
 44        self.0.dsize()
 45    }
 46
 47    fn rank_out(&self) -> Rank {
 48        self.0.rank_out()
 49    }
 50
 51    fn dnum(&self) -> Dnum {
 52        self.0.dnum()
 53    }
 54}
 55
 56impl<B: Backend> GLWEToLWESwitchingKeyPrepared<Vec<u8>, B> {
 57    pub fn alloc<A>(module: &Module<B>, infos: &A) -> Self
 58    where
 59        A: GGLWEInfos,
 60        Module<B>: VmpPMatAlloc<B>,
 61    {
 62        debug_assert_eq!(
 63            infos.rank_out().0,
 64            1,
 65            "rank_out > 1 is not supported for GLWEToLWESwitchingKeyPrepared"
 66        );
 67        debug_assert_eq!(
 68            infos.dsize().0,
 69            1,
 70            "dsize > 1 is not supported for GLWEToLWESwitchingKeyPrepared"
 71        );
 72        Self(GGLWESwitchingKeyPrepared::alloc(module, infos))
 73    }
 74
 75    pub fn alloc_with(module: &Module<B>, base2k: Base2K, k: TorusPrecision, rank_in: Rank, dnum: Dnum) -> Self
 76    where
 77        Module<B>: VmpPMatAlloc<B>,
 78    {
 79        Self(GGLWESwitchingKeyPrepared::alloc_with(
 80            module,
 81            base2k,
 82            k,
 83            rank_in,
 84            Rank(1),
 85            dnum,
 86            Dsize(1),
 87        ))
 88    }
 89
 90    pub fn alloc_bytes<A>(module: &Module<B>, infos: &A) -> usize
 91    where
 92        A: GGLWEInfos,
 93        Module<B>: VmpPMatAllocBytes,
 94    {
 95        debug_assert_eq!(
 96            infos.rank_out().0,
 97            1,
 98            "rank_out > 1 is not supported for GLWEToLWESwitchingKeyPrepared"
 99        );
100        debug_assert_eq!(
101            infos.dsize().0,
102            1,
103            "dsize > 1 is not supported for GLWEToLWESwitchingKeyPrepared"
104        );
105        GGLWESwitchingKeyPrepared::alloc_bytes(module, infos)
106    }
107
108    pub fn alloc_bytes_with(module: &Module<B>, base2k: Base2K, k: TorusPrecision, rank_in: Rank, dnum: Dnum) -> usize
109    where
110        Module<B>: VmpPMatAllocBytes,
111    {
112        GGLWESwitchingKeyPrepared::alloc_bytes_with(module, base2k, k, rank_in, Rank(1), dnum, Dsize(1))
113    }
114}
115
116impl<D: DataRef, B: Backend> PrepareAlloc<B, GLWEToLWESwitchingKeyPrepared<Vec<u8>, B>> for GLWEToLWEKey<D>
117where
118    Module<B>: VmpPrepare<B> + VmpPMatAlloc<B>,
119{
120    fn prepare_alloc(&self, module: &Module<B>, scratch: &mut Scratch<B>) -> GLWEToLWESwitchingKeyPrepared<Vec<u8>, B> {
121        let mut ksk_prepared: GLWEToLWESwitchingKeyPrepared<Vec<u8>, B> = GLWEToLWESwitchingKeyPrepared::alloc(module, self);
122        ksk_prepared.prepare(module, self, scratch);
123        ksk_prepared
124    }
125}
126
127impl<DM: DataMut, DR: DataRef, B: Backend> Prepare<B, GLWEToLWEKey<DR>> for GLWEToLWESwitchingKeyPrepared<DM, B>
128where
129    Module<B>: VmpPrepare<B>,
130{
131    fn prepare(&mut self, module: &Module<B>, other: &GLWEToLWEKey<DR>, scratch: &mut Scratch<B>) {
132        self.0.prepare(module, &other.0, scratch);
133    }
134}