use backend::hal::{ api::{VmpPMatAlloc, VmpPMatAllocBytes, VmpPrepare}, layouts::{Backend, Data, DataMut, DataRef, Module, Scratch, VmpPMat}, }; use crate::layouts::{ GGLWESwitchingKey, Infos, prepared::{GGLWECiphertextPrepared, Prepare, PrepareAlloc}, }; #[derive(PartialEq, Eq)] pub struct GGLWESwitchingKeyPrepared { pub(crate) key: GGLWECiphertextPrepared, pub(crate) sk_in_n: usize, // Degree of sk_in pub(crate) sk_out_n: usize, // Degree of sk_out } impl GGLWESwitchingKeyPrepared, B> { pub fn alloc( module: &Module, n: usize, basek: usize, k: usize, rows: usize, digits: usize, rank_in: usize, rank_out: usize, ) -> Self where Module: VmpPMatAlloc, { GGLWESwitchingKeyPrepared::, B> { key: GGLWECiphertextPrepared::alloc(module, n, basek, k, rows, digits, rank_in, rank_out), sk_in_n: 0, sk_out_n: 0, } } pub fn bytes_of( module: &Module, n: usize, basek: usize, k: usize, rows: usize, digits: usize, rank_in: usize, rank_out: usize, ) -> usize where Module: VmpPMatAllocBytes, { GGLWECiphertextPrepared::bytes_of(module, n, basek, k, rows, digits, rank_in, rank_out) } } impl Infos for GGLWESwitchingKeyPrepared { type Inner = VmpPMat; fn inner(&self) -> &Self::Inner { self.key.inner() } fn basek(&self) -> usize { self.key.basek() } fn k(&self) -> usize { self.key.k() } } impl GGLWESwitchingKeyPrepared { pub fn rank(&self) -> usize { self.key.data.cols_out() - 1 } pub fn rank_in(&self) -> usize { self.key.data.cols_in() } pub fn rank_out(&self) -> usize { self.key.data.cols_out() - 1 } pub fn digits(&self) -> usize { self.key.digits() } pub fn sk_degree_in(&self) -> usize { self.sk_in_n } pub fn sk_degree_out(&self) -> usize { self.sk_out_n } } impl Prepare> for GGLWESwitchingKeyPrepared where Module: VmpPrepare, { fn prepare(&mut self, module: &Module, other: &GGLWESwitchingKey, scratch: &mut Scratch) { self.key.prepare(module, &other.key, scratch); self.sk_in_n = other.sk_in_n; self.sk_out_n = other.sk_out_n; } } impl PrepareAlloc, B>> for GGLWESwitchingKey where Module: VmpPMatAlloc + VmpPrepare, { fn prepare_alloc(&self, module: &Module, scratch: &mut Scratch) -> GGLWESwitchingKeyPrepared, B> { let mut atk_prepared: GGLWESwitchingKeyPrepared, B> = GGLWESwitchingKeyPrepared::alloc( module, self.n(), self.basek(), self.k(), self.rows(), self.digits(), self.rank_in(), self.rank_out(), ); atk_prepared.prepare(module, self, scratch); atk_prepared } }