use poulpy_hal::{ api::{SvpPPolAlloc, SvpPPolBytesOf, SvpPrepare}, layouts::{Backend, Data, DataMut, DataRef, Module, SvpPPol, SvpPPolToMut, SvpPPolToRef, ZnxInfos}, }; use crate::{ dist::Distribution, layouts::{ Base2K, GLWEInfos, GLWESecret, GLWESecretToRef, GetDist, GetRingDegree, LWEInfos, Rank, RingDegree, TorusPrecision, prepared::SetDist, }, }; pub struct GLWESecretPrepared { pub(crate) data: SvpPPol, pub(crate) dist: Distribution, } impl SetDist for GLWESecretPrepared { fn set_dist(&mut self, dist: Distribution) { self.dist = dist } } impl LWEInfos for GLWESecretPrepared { fn base2k(&self) -> Base2K { Base2K(0) } fn k(&self) -> TorusPrecision { TorusPrecision(0) } fn n(&self) -> RingDegree { RingDegree(self.data.n() as u32) } fn size(&self) -> usize { self.data.size() } } impl GLWEInfos for GLWESecretPrepared { fn rank(&self) -> Rank { Rank(self.data.cols() as u32) } } pub trait GLWESecretPreparedAlloc where Self: GetRingDegree + SvpPPolBytesOf + SvpPPolAlloc, { fn alloc_glwe_secret_prepared(&self, rank: Rank) -> GLWESecretPrepared, B> { GLWESecretPrepared { data: self.svp_ppol_alloc(rank.into()), dist: Distribution::NONE, } } fn alloc_glwe_secret_prepared_from_infos(&self, infos: &A) -> GLWESecretPrepared, B> where A: GLWEInfos, { assert_eq!(self.ring_degree(), infos.n()); self.alloc_glwe_secret_prepared(infos.rank()) } fn bytes_of_glwe_secret_prepared(&self, rank: Rank) -> usize { self.bytes_of_svp_ppol(rank.into()) } fn bytes_of_glwe_secret_prepared_from_infos(&self, infos: &A) -> usize where A: GLWEInfos, { assert_eq!(self.ring_degree(), infos.n()); self.bytes_of_glwe_secret_prepared(infos.rank()) } } impl GLWESecretPreparedAlloc for Module where Self: GetRingDegree + SvpPPolBytesOf + SvpPPolAlloc {} impl GLWESecretPrepared, B> { pub fn alloc_from_infos(module: &M, infos: &A) -> Self where A: GLWEInfos, M: GLWESecretPreparedAlloc, { module.alloc_glwe_secret_prepared_from_infos(infos) } pub fn alloc(module: &M, rank: Rank) -> Self where M: GLWESecretPreparedAlloc, { module.alloc_glwe_secret_prepared(rank) } pub fn bytes_of_from_infos(module: &M, infos: &A) -> usize where A: GLWEInfos, M: GLWESecretPreparedAlloc, { module.bytes_of_glwe_secret_prepared_from_infos(infos) } pub fn bytes_of(module: &M, rank: Rank) -> usize where M: GLWESecretPreparedAlloc, { module.bytes_of_glwe_secret_prepared(rank) } } impl GLWESecretPrepared { pub fn n(&self) -> RingDegree { RingDegree(self.data.n() as u32) } pub fn rank(&self) -> Rank { Rank(self.data.cols() as u32) } } pub trait GLWESecretPrepare where Self: SvpPrepare, { fn prepare_glwe_secret(&self, res: &mut R, other: &O) where R: GLWESecretPreparedToMut + SetDist, O: GLWESecretToRef + GetDist, { { let mut res: GLWESecretPrepared<&mut [u8], _> = res.to_mut(); let other: GLWESecret<&[u8]> = other.to_ref(); for i in 0..res.rank().into() { self.svp_prepare(&mut res.data, i, &other.data, i); } } res.set_dist(other.get_dist()); } } impl GLWESecretPrepare for Module where Self: SvpPrepare {} impl GLWESecretPrepared { pub fn prepare(&mut self, module: &M, other: &O) where M: GLWESecretPrepare, O: GLWESecretToRef + GetDist, { module.prepare_glwe_secret(self, other); } } pub trait GLWESecretPreparedToRef { fn to_ref(&self) -> GLWESecretPrepared<&[u8], B>; } impl GLWESecretPreparedToRef for GLWESecretPrepared { fn to_ref(&self) -> GLWESecretPrepared<&[u8], B> { GLWESecretPrepared { data: self.data.to_ref(), dist: self.dist, } } } pub trait GLWESecretPreparedToMut { fn to_mut(&mut self) -> GLWESecretPrepared<&mut [u8], B>; } impl GLWESecretPreparedToMut for GLWESecretPrepared { fn to_mut(&mut self) -> GLWESecretPrepared<&mut [u8], B> { GLWESecretPrepared { dist: self.dist, data: self.data.to_mut(), } } }