use poulpy_hal::{ api::{VmpPMatAlloc, VmpPMatAllocBytes, VmpPrepare}, layouts::{Backend, Data, DataMut, DataRef, Module, Scratch}, }; use crate::layouts::{ Base2K, Degree, Dnum, Dsize, GGLWEAutomorphismKey, GGLWEInfos, GLWEInfos, LWEInfos, Rank, TorusPrecision, prepared::{GGLWESwitchingKeyPrepared, Prepare, PrepareAlloc, PrepareScratchSpace}, }; #[derive(PartialEq, Eq)] pub struct GGLWEAutomorphismKeyPrepared { pub(crate) key: GGLWESwitchingKeyPrepared, pub(crate) p: i64, } impl GGLWEAutomorphismKeyPrepared { pub fn p(&self) -> i64 { self.p } } impl LWEInfos for GGLWEAutomorphismKeyPrepared { fn n(&self) -> Degree { self.key.n() } fn base2k(&self) -> Base2K { self.key.base2k() } fn k(&self) -> TorusPrecision { self.key.k() } fn size(&self) -> usize { self.key.size() } } impl GLWEInfos for GGLWEAutomorphismKeyPrepared { fn rank(&self) -> Rank { self.rank_out() } } impl GGLWEInfos for GGLWEAutomorphismKeyPrepared { fn rank_in(&self) -> Rank { self.key.rank_in() } fn rank_out(&self) -> Rank { self.key.rank_out() } fn dsize(&self) -> Dsize { self.key.dsize() } fn dnum(&self) -> Dnum { self.key.dnum() } } impl GGLWEAutomorphismKeyPrepared, B> { pub fn alloc(module: &Module, infos: &A) -> Self where A: GGLWEInfos, Module: VmpPMatAlloc, { assert_eq!( infos.rank_in(), infos.rank_out(), "rank_in != rank_out is not supported for GGLWEAutomorphismKeyPrepared" ); GGLWEAutomorphismKeyPrepared::, B> { key: GGLWESwitchingKeyPrepared::alloc(module, infos), p: 0, } } pub fn alloc_with(module: &Module, base2k: Base2K, k: TorusPrecision, rank: Rank, dnum: Dnum, dsize: Dsize) -> Self where Module: VmpPMatAlloc, { GGLWEAutomorphismKeyPrepared { key: GGLWESwitchingKeyPrepared::alloc_with(module, base2k, k, rank, rank, dnum, dsize), p: 0, } } pub fn alloc_bytes(module: &Module, infos: &A) -> usize where A: GGLWEInfos, Module: VmpPMatAllocBytes, { assert_eq!( infos.rank_in(), infos.rank_out(), "rank_in != rank_out is not supported for GGLWEAutomorphismKeyPrepared" ); GGLWESwitchingKeyPrepared::alloc_bytes(module, infos) } pub fn alloc_bytes_with(module: &Module, base2k: Base2K, k: TorusPrecision, rank: Rank, dnum: Dnum, dsize: Dsize) -> usize where Module: VmpPMatAllocBytes, { GGLWESwitchingKeyPrepared::alloc_bytes_with(module, base2k, k, rank, rank, dnum, dsize) } } impl PrepareScratchSpace for GGLWEAutomorphismKeyPrepared, B> where GGLWESwitchingKeyPrepared, B>: PrepareScratchSpace, { fn prepare_scratch_space(module: &Module, infos: &A) -> usize { GGLWESwitchingKeyPrepared::prepare_scratch_space(module, infos) } } impl Prepare> for GGLWEAutomorphismKeyPrepared where Module: VmpPrepare, { fn prepare(&mut self, module: &Module, other: &GGLWEAutomorphismKey, scratch: &mut Scratch) { self.key.prepare(module, &other.key, scratch); self.p = other.p; } } impl PrepareAlloc, B>> for GGLWEAutomorphismKey where Module: VmpPMatAlloc + VmpPrepare, { fn prepare_alloc(&self, module: &Module, scratch: &mut Scratch) -> GGLWEAutomorphismKeyPrepared, B> { let mut atk_prepared: GGLWEAutomorphismKeyPrepared, B> = GGLWEAutomorphismKeyPrepared::alloc(module, self); atk_prepared.prepare(module, self, scratch); atk_prepared } }