use poulpy_hal::{ api::{SvpPPolAlloc, SvpPPolBytesOf, SvpPrepare}, layouts::{Backend, Data, DataMut, DataRef, Module, SvpPPol, SvpPPolToMut, SvpPPolToRef, ZnxInfos}, }; use crate::{ GetDistribution, GetDistributionMut, dist::Distribution, layouts::{Base2K, Degree, GLWEInfos, GLWESecret, GLWESecretToRef, GetDegree, LWEInfos, Rank, TorusPrecision}, }; pub struct GLWESecretPrepared { pub(crate) data: SvpPPol, pub(crate) dist: Distribution, } impl GetDistribution for GLWESecretPrepared { fn dist(&self) -> &Distribution { &self.dist } } impl GetDistributionMut for GLWESecretPrepared { fn dist_mut(&mut self) -> &mut Distribution { &mut self.dist } } impl LWEInfos for GLWESecretPrepared { fn base2k(&self) -> Base2K { Base2K(0) } fn k(&self) -> TorusPrecision { TorusPrecision(0) } fn n(&self) -> Degree { Degree(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 GLWESecretPreparedFactory where Self: GetDegree + SvpPPolBytesOf + SvpPPolAlloc + SvpPrepare, { 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()) } fn prepare_glwe_secret(&self, res: &mut R, other: &O) where R: GLWESecretPreparedToMut + GetDistributionMut, O: GLWESecretToRef + GetDistribution, { { 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.dist_mut() = *other.dist(); } } impl GLWESecretPreparedFactory for Module where Self: GetDegree + SvpPPolBytesOf + SvpPPolAlloc + SvpPrepare { } impl GLWESecretPrepared, B> { pub fn alloc_from_infos(module: &M, infos: &A) -> Self where A: GLWEInfos, M: GLWESecretPreparedFactory, { module.alloc_glwe_secret_prepared_from_infos(infos) } pub fn alloc(module: &M, rank: Rank) -> Self where M: GLWESecretPreparedFactory, { module.alloc_glwe_secret_prepared(rank) } pub fn bytes_of_from_infos(module: &M, infos: &A) -> usize where A: GLWEInfos, M: GLWESecretPreparedFactory, { module.bytes_of_glwe_secret_prepared_from_infos(infos) } pub fn bytes_of(module: &M, rank: Rank) -> usize where M: GLWESecretPreparedFactory, { module.bytes_of_glwe_secret_prepared(rank) } } impl GLWESecretPrepared { pub fn n(&self) -> Degree { Degree(self.data.n() as u32) } pub fn rank(&self) -> Rank { Rank(self.data.cols() as u32) } } impl GLWESecretPrepared { pub fn prepare(&mut self, module: &M, other: &O) where M: GLWESecretPreparedFactory, O: GLWESecretToRef + GetDistribution, { 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 where Self: GLWESecretPreparedToRef, { 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(), } } }