use poulpy_hal::{ api::{SvpPPolAlloc, SvpPPolAllocBytes, SvpPrepare}, layouts::{Backend, Data, DataMut, DataRef, Module, SvpPPol, ZnxInfos}, }; use crate::{ dist::Distribution, layouts::{ GLWESecret, prepared::{Prepare, PrepareAlloc}, }, }; pub struct GLWESecretPrepared { pub(crate) data: SvpPPol, pub(crate) dist: Distribution, } impl GLWESecretPrepared, B> { pub fn alloc(module: &Module, rank: usize) -> Self where Module: SvpPPolAlloc, { Self { data: module.svp_ppol_alloc(rank), dist: Distribution::NONE, } } pub fn bytes_of(module: &Module, rank: usize) -> usize where Module: SvpPPolAllocBytes, { module.svp_ppol_alloc_bytes(rank) } } impl GLWESecretPrepared { pub fn n(&self) -> usize { self.data.n() } pub fn log_n(&self) -> usize { self.data.log_n() } pub fn rank(&self) -> usize { self.data.cols() } } impl PrepareAlloc, B>> for GLWESecret where Module: SvpPrepare + SvpPPolAlloc, { fn prepare_alloc(&self, module: &Module, scratch: &mut poulpy_hal::layouts::Scratch) -> GLWESecretPrepared, B> { let mut sk_dft: GLWESecretPrepared, B> = GLWESecretPrepared::alloc(module, self.rank()); sk_dft.prepare(module, self, scratch); sk_dft } } impl Prepare> for GLWESecretPrepared where Module: SvpPrepare, { fn prepare(&mut self, module: &Module, other: &GLWESecret, _scratch: &mut poulpy_hal::layouts::Scratch) { (0..self.rank()).for_each(|i| { module.svp_prepare(&mut self.data, i, &other.data, i); }); self.dist = other.dist } }