use poulpy_hal::{ api::{VmpPMatAlloc, VmpPMatAllocBytes, VmpPrepare}, layouts::{Backend, Data, DataMut, DataRef, Module, Scratch}, }; use crate::layouts::{ Base2K, Degree, Dnum, Dsize, GGLWEInfos, GLWEInfos, LWEInfos, LWESwitchingKey, Rank, TorusPrecision, prepared::{GGLWESwitchingKeyPrepared, Prepare, PrepareAlloc, PrepareScratchSpace}, }; #[derive(PartialEq, Eq)] pub struct LWESwitchingKeyPrepared(pub(crate) GGLWESwitchingKeyPrepared); 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(GGLWESwitchingKeyPrepared::alloc(module, infos)) } pub fn alloc_with(module: &Module, base2k: Base2K, k: TorusPrecision, dnum: Dnum) -> Self where Module: VmpPMatAlloc, { Self(GGLWESwitchingKeyPrepared::alloc_with( 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" ); GGLWESwitchingKeyPrepared::alloc_bytes(module, infos) } pub fn alloc_bytes_with(module: &Module, base2k: Base2K, k: TorusPrecision, dnum: Dnum) -> usize where Module: VmpPMatAllocBytes, { GGLWESwitchingKeyPrepared::alloc_bytes_with(module, base2k, k, Rank(1), Rank(1), dnum, Dsize(1)) } } impl PrepareScratchSpace for LWESwitchingKeyPrepared where GGLWESwitchingKeyPrepared: PrepareScratchSpace, { fn prepare_scratch_space(&self, module: &Module, infos: &A) -> usize { self.0.prepare_scratch_space(module, infos) } } impl PrepareAlloc, B>> for LWESwitchingKey where Module: VmpPrepare + VmpPMatAlloc, { fn prepare_alloc(&self, module: &Module, scratch: &mut Scratch) -> LWESwitchingKeyPrepared, B> { let mut ksk_prepared: LWESwitchingKeyPrepared, B> = LWESwitchingKeyPrepared::alloc(module, self); ksk_prepared.prepare(module, self, scratch); ksk_prepared } } impl Prepare> for LWESwitchingKeyPrepared where Module: VmpPrepare, { fn prepare(&mut self, module: &Module, other: &LWESwitchingKey, scratch: &mut Scratch) { self.0.prepare(module, &other.0, scratch); } }