use poulpy_hal::{ api::{VmpPMatAlloc, VmpPMatAllocBytes}, layouts::{Backend, Data, DataMut, DataRef, Module, Scratch}, }; use crate::layouts::{ Base2K, Degree, Dnum, Dsize, GGLWEInfos, GLWEInfos, LWEInfos, LWESwitchingKeyToRef, Rank, TorusPrecision, prepared::{GLWESwitchingKeyPrepare, GLWESwitchingKeyPrepared, GLWESwitchingKeyPreparedToMut, GLWESwitchingKeyPreparedToRef}, }; #[derive(PartialEq, Eq)] pub struct LWESwitchingKeyPrepared(pub(crate) GLWESwitchingKeyPrepared); impl LWEInfos for LWESwitchingKeyPrepared { fn base2k(&self) -> Base2K { self.0.base2k() } fn k(&self) -> TorusPrecision { self.0.k() } fn n(&self) -> Degree { self.0.n() } fn size(&self) -> usize { self.0.size() } } impl GLWEInfos for LWESwitchingKeyPrepared { fn rank(&self) -> Rank { self.rank_out() } } impl GGLWEInfos for LWESwitchingKeyPrepared { fn dsize(&self) -> Dsize { self.0.dsize() } fn rank_in(&self) -> Rank { self.0.rank_in() } fn rank_out(&self) -> Rank { self.0.rank_out() } fn dnum(&self) -> Dnum { self.0.dnum() } } impl LWESwitchingKeyPrepared, B> { pub fn alloc(module: &Module, infos: &A) -> Self where A: GGLWEInfos, Module: VmpPMatAlloc, { debug_assert_eq!( infos.dsize().0, 1, "dsize > 1 is not supported for LWESwitchingKey" ); debug_assert_eq!( infos.rank_in().0, 1, "rank_in > 1 is not supported for LWESwitchingKey" ); debug_assert_eq!( infos.rank_out().0, 1, "rank_out > 1 is not supported for LWESwitchingKey" ); Self(GLWESwitchingKeyPrepared::alloc_from_infos(module, infos)) } pub fn alloc_with(module: &Module, base2k: Base2K, k: TorusPrecision, dnum: Dnum) -> Self where Module: VmpPMatAlloc, { Self(GLWESwitchingKeyPrepared::alloc( module, base2k, k, Rank(1), Rank(1), dnum, Dsize(1), )) } pub fn alloc_bytes(module: &Module, infos: &A) -> usize where A: GGLWEInfos, Module: VmpPMatAllocBytes, { debug_assert_eq!( infos.dsize().0, 1, "dsize > 1 is not supported for LWESwitchingKey" ); debug_assert_eq!( infos.rank_in().0, 1, "rank_in > 1 is not supported for LWESwitchingKey" ); debug_assert_eq!( infos.rank_out().0, 1, "rank_out > 1 is not supported for LWESwitchingKey" ); GLWESwitchingKeyPrepared::alloc_bytes_from_infos(module, infos) } pub fn alloc_bytes_with(module: &Module, base2k: Base2K, k: TorusPrecision, dnum: Dnum) -> usize where Module: VmpPMatAllocBytes, { GLWESwitchingKeyPrepared::alloc_bytes(module, base2k, k, Rank(1), Rank(1), dnum, Dsize(1)) } } pub trait LWESwitchingKeyPrepareTmpBytes { fn lwe_switching_key_prepare_tmp_bytes(&self, infos: &A) where A: GGLWEInfos; } impl LWESwitchingKeyPrepareTmpBytes for Module where Module: LWESwitchingKeyPrepareTmpBytes, { fn lwe_switching_key_prepare_tmp_bytes(&self, infos: &A) where A: GGLWEInfos, { self.lwe_switching_key_prepare_tmp_bytes(infos); } } impl LWESwitchingKeyPrepared, B> { pub fn prepare_tmp_bytes(&self, module: &Module, infos: &A) where A: GLWEInfos, Module: LWESwitchingKeyPrepareTmpBytes, { module.glwe_secret_prepare_tmp_bytes(infos); } } pub trait LWESwitchingKeyPrepare { fn lwe_switching_key_prepare(&self, res: &mut R, other: &O, scratch: &Scratch) where R: LWESwitchingKeyPreparedToMut, O: LWESwitchingKeyToRef; } impl LWESwitchingKeyPrepare for Module where Module: GLWESwitchingKeyPrepare, { fn lwe_switching_key_prepare(&self, res: &mut R, other: &O, scratch: &Scratch) where R: LWESwitchingKeyPreparedToMut, O: LWESwitchingKeyToRef, { self.glwe_switching_prepare(&mut res.to_mut().0, other, scratch); } } impl LWESwitchingKeyPrepared { fn prepare(&mut self, module: &Module, other: &O, scratch: &Scratch) where O: LWESwitchingKeyToRef, Module: LWESwitchingKeyPrepare, { module.lwe_switching_key_prepare(self, other, scratch); } } pub trait LWESwitchingKeyPrepareAlloc { fn lwe_switching_key_prepare_alloc(&self, other: &O, scratch: &mut Scratch) where O: LWESwitchingKeyToRef; } impl LWESwitchingKeyPrepareAlloc for Module where Module: LWESwitchingKeyPrepare, { fn lwe_switching_key_prepare_alloc(&self, other: &O, scratch: &mut Scratch) where O: LWESwitchingKeyToRef, { let mut ct_prep: LWESwitchingKeyPrepared, B> = LWESwitchingKeyPrepared::alloc(self, &other.to_ref()); self.lwe_switching_key_prepare(&mut ct_prep, other, scratch); ct_prep } } pub trait LWESwitchingKeyPreparedToRef { fn to_ref(&self) -> LWESwitchingKeyPrepared<&[u8], B>; } impl LWESwitchingKeyPreparedToRef for LWESwitchingKeyPrepared where GLWESwitchingKeyPrepared: GLWESwitchingKeyPreparedToRef, { fn to_ref(&self) -> LWESwitchingKeyPrepared<&[u8], B> { LWESwitchingKeyPrepared(self.0.to_ref()) } } pub trait LWESwitchingKeyPreparedToMut { fn to_mut(&mut self) -> LWESwitchingKeyPrepared<&mut [u8], B>; } impl LWESwitchingKeyPreparedToMut for LWESwitchingKeyPrepared where GLWESwitchingKeyPrepared: GLWESwitchingKeyPreparedToMut, { fn to_mut(&mut self) -> LWESwitchingKeyPrepared<&mut [u8], B> { LWESwitchingKeyPrepared(self.0.to_mut()) } }