use poulpy_hal::{ api::{VmpPMatAlloc, VmpPMatAllocBytes, VmpPrepare}, layouts::{Backend, Data, DataMut, DataRef, Module, Scratch}, }; use crate::layouts::{ Base2K, Degree, Digits, GGLWELayoutInfos, GLWEInfos, LWEInfos, LWESwitchingKey, Rank, Rows, TorusPrecision, prepared::{GGLWESwitchingKeyPrepared, Prepare, PrepareAlloc}, }; #[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 GGLWELayoutInfos for LWESwitchingKeyPrepared { fn digits(&self) -> Digits { self.0.digits() } fn rank_in(&self) -> Rank { self.0.rank_in() } fn rank_out(&self) -> Rank { self.0.rank_out() } fn rows(&self) -> Rows { self.0.rows() } } impl LWESwitchingKeyPrepared, B> { pub fn alloc(module: &Module, infos: &A) -> Self where A: GGLWELayoutInfos, Module: VmpPMatAlloc, { debug_assert_eq!( infos.digits().0, 1, "digits > 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, rows: Rows) -> Self where Module: VmpPMatAlloc, { Self(GGLWESwitchingKeyPrepared::alloc_with( module, base2k, k, rows, Digits(1), Rank(1), Rank(1), )) } pub fn alloc_bytes(module: &Module, infos: &A) -> usize where A: GGLWELayoutInfos, Module: VmpPMatAllocBytes, { debug_assert_eq!( infos.digits().0, 1, "digits > 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, rows: Rows) -> usize where Module: VmpPMatAllocBytes, { GGLWESwitchingKeyPrepared::alloc_bytes_with(module, base2k, k, rows, Digits(1), Rank(1), Rank(1)) } } 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); } }