use backend::hal::{ api::{VecZnxDftAlloc, VecZnxDftAllocBytes, VecZnxDftFromVecZnx}, layouts::{Backend, Data, DataMut, DataRef, Module, Scratch, VecZnxDft}, }; use crate::{ dist::Distribution, layouts::{ GLWEPublicKey, Infos, prepared::{Prepare, PrepareAlloc}, }, }; #[derive(PartialEq, Eq)] pub struct GLWEPublicKeyPrepared { pub(crate) data: VecZnxDft, pub(crate) basek: usize, pub(crate) k: usize, pub(crate) dist: Distribution, } impl Infos for GLWEPublicKeyPrepared { type Inner = VecZnxDft; fn inner(&self) -> &Self::Inner { &self.data } fn basek(&self) -> usize { self.basek } fn k(&self) -> usize { self.k } } impl GLWEPublicKeyPrepared { pub fn rank(&self) -> usize { self.cols() - 1 } } impl GLWEPublicKeyPrepared, B> { pub fn alloc(module: &Module, n: usize, basek: usize, k: usize, rank: usize) -> Self where Module: VecZnxDftAlloc, { Self { data: module.vec_znx_dft_alloc(n, rank + 1, k.div_ceil(basek)), basek: basek, k: k, dist: Distribution::NONE, } } pub fn bytes_of(module: &Module, n: usize, basek: usize, k: usize, rank: usize) -> usize where Module: VecZnxDftAllocBytes, { module.vec_znx_dft_alloc_bytes(n, rank + 1, k.div_ceil(basek)) } } impl PrepareAlloc, B>> for GLWEPublicKey where Module: VecZnxDftAlloc + VecZnxDftFromVecZnx, { fn prepare_alloc(&self, module: &Module, scratch: &mut Scratch) -> GLWEPublicKeyPrepared, B> { let mut pk_prepared: GLWEPublicKeyPrepared, B> = GLWEPublicKeyPrepared::alloc(module, self.n(), self.basek(), self.k(), self.rank()); pk_prepared.prepare(module, self, scratch); pk_prepared } } impl Prepare> for GLWEPublicKeyPrepared where Module: VecZnxDftFromVecZnx, { fn prepare(&mut self, module: &Module, other: &GLWEPublicKey, _scratch: &mut Scratch) { #[cfg(debug_assertions)] { assert_eq!(self.n(), other.n()); assert_eq!(self.size(), other.size()); } (0..self.cols()).for_each(|i| { module.vec_znx_dft_from_vec_znx(1, 0, &mut self.data, i, &other.data, i); }); self.k = other.k; self.basek = other.basek; self.dist = other.dist; } }