use poulpy_hal::layouts::{Backend, Data, DataMut, DataRef, Module, Scratch}; use crate::layouts::{ Base2K, Dnum, Dsize, GGLWEInfos, GLWEInfos, LWEInfos, LWESwitchingKeyToRef, Rank, RingDegree, TorusPrecision, prepared::{ GLWESwitchingKeyPrepare, GLWESwitchingKeyPrepared, GLWESwitchingKeyPreparedAlloc, 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) -> RingDegree { 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() } } pub trait LWESwitchingKeyPreparedAlloc where Self: GLWESwitchingKeyPreparedAlloc, { fn alloc_lwe_switching_key_prepared( &self, base2k: Base2K, k: TorusPrecision, dnum: Dnum, ) -> LWESwitchingKeyPrepared, B> { LWESwitchingKeyPrepared(self.alloc_glwe_switching_key_prepared(base2k, k, Rank(1), Rank(1), dnum, Dsize(1))) } fn alloc_lwe_switching_key_prepared_from_infos(&self, infos: &A) -> LWESwitchingKeyPrepared, B> where A: GGLWEInfos, { 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.alloc_lwe_switching_key_prepared(infos.base2k(), infos.k(), infos.dnum()) } fn bytes_of_lwe_switching_key_prepared(&self, base2k: Base2K, k: TorusPrecision, dnum: Dnum) -> usize { self.bytes_of_glwe_switching_key_prepared(base2k, k, Rank(1), Rank(1), dnum, Dsize(1)) } fn bytes_of_lwe_switching_key_prepared_from_infos(&self, infos: &A) -> usize where A: GGLWEInfos, { 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.bytes_of_lwe_switching_key_prepared(infos.base2k(), infos.k(), infos.dnum()) } } impl LWESwitchingKeyPreparedAlloc for Module where Self: GLWESwitchingKeyPreparedAlloc {} impl LWESwitchingKeyPrepared, B> { pub fn alloc_from_infos(module: &M, infos: &A) -> Self where A: GGLWEInfos, M: LWESwitchingKeyPreparedAlloc, { module.alloc_lwe_switching_key_prepared_from_infos(infos) } pub fn alloc(module: &M, base2k: Base2K, k: TorusPrecision, dnum: Dnum) -> Self where M: LWESwitchingKeyPreparedAlloc, { module.alloc_lwe_switching_key_prepared(base2k, k, dnum) } pub fn bytes_of_from_infos(module: &M, infos: &A) -> usize where A: GGLWEInfos, M: LWESwitchingKeyPreparedAlloc, { module.bytes_of_lwe_switching_key_prepared_from_infos(infos) } pub fn bytes_of(module: &M, base2k: Base2K, k: TorusPrecision, dnum: Dnum) -> usize where M: LWESwitchingKeyPreparedAlloc, { module.bytes_of_lwe_switching_key_prepared(base2k, k, dnum) } } pub trait LWESwitchingKeyPrepare where Self: GLWESwitchingKeyPrepare, { fn prepare_lwe_switching_key_tmp_bytes(&self, infos: &A) where A: GGLWEInfos, { self.prepare_glwe_switching_key_tmp_bytes(infos); } fn prepare_lwe_switching_key(&self, res: &mut R, other: &O, scratch: &mut Scratch) where R: LWESwitchingKeyPreparedToMut, O: LWESwitchingKeyToRef, { self.prepare_glwe_switching(&mut res.to_mut().0, &other.to_ref().0, scratch); } } impl LWESwitchingKeyPrepare for Module where Self: GLWESwitchingKeyPrepare {} impl LWESwitchingKeyPrepared, B> { pub fn prepare_tmp_bytes(&self, module: &M, infos: &A) where A: GGLWEInfos, M: LWESwitchingKeyPrepare, { module.prepare_lwe_switching_key_tmp_bytes(infos); } } impl LWESwitchingKeyPrepared { pub fn prepare(&mut self, module: &M, other: &O, scratch: &mut Scratch) where O: LWESwitchingKeyToRef, M: LWESwitchingKeyPrepare, { module.prepare_lwe_switching_key(self, other, scratch); } } 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()) } }