use poulpy_hal::{ layouts::{ Backend, Data, DataMut, DataRef, Module, ReaderFrom, ScalarZnx, ScalarZnxToMut, ScalarZnxToRef, WriterTo, ZnxInfos, ZnxZero, }, source::Source, }; use crate::{ dist::Distribution, layouts::{Base2K, Degree, GLWEInfos, GetDegree, GetDist, LWEInfos, Rank, TorusPrecision}, }; #[derive(PartialEq, Eq, Copy, Clone, Debug)] pub struct GLWESecretLayout { pub n: Degree, pub rank: Rank, } impl LWEInfos for GLWESecretLayout { fn base2k(&self) -> Base2K { Base2K(0) } fn k(&self) -> TorusPrecision { TorusPrecision(0) } fn n(&self) -> Degree { self.n } fn size(&self) -> usize { 1 } } impl GLWEInfos for GLWESecretLayout { fn rank(&self) -> Rank { self.rank } } #[derive(PartialEq, Eq, Clone)] pub struct GLWESecret { pub(crate) data: ScalarZnx, pub(crate) dist: Distribution, } impl LWEInfos for GLWESecret { 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 { 1 } } impl GetDist for GLWESecret { fn get_dist(&self) -> Distribution { self.dist } } impl GLWEInfos for GLWESecret { fn rank(&self) -> Rank { Rank(self.data.cols() as u32) } } pub trait GLWESecretAlloc where Self: GetDegree, { fn alloc_glwe_secret(&self, rank: Rank) -> GLWESecret> { GLWESecret { data: ScalarZnx::alloc(self.ring_degree().into(), rank.into()), dist: Distribution::NONE, } } fn alloc_glwe_secret_from_infos(&self, infos: &A) -> GLWESecret> where A: GLWEInfos, { self.alloc_glwe_secret(infos.rank()) } fn bytes_of_glwe_secret(&self, rank: Rank) -> usize { ScalarZnx::bytes_of(self.ring_degree().into(), rank.into()) } fn bytes_of_glwe_secret_from_infos(&self, infos: &A) -> usize where A: GLWEInfos, { self.bytes_of_glwe_secret(infos.rank()) } } impl GLWESecretAlloc for Module where Self: GetDegree {} impl GLWESecret> { pub fn alloc_from_infos(module: &M, infos: &A) -> Self where A: GLWEInfos, M: GLWESecretAlloc, { module.alloc_glwe_secret_from_infos(infos) } pub fn alloc(module: &M, rank: Rank) -> Self where M: GLWESecretAlloc, { module.alloc_glwe_secret(rank) } pub fn bytes_of_from_infos(module: &M, infos: &A) -> usize where A: GLWEInfos, M: GLWESecretAlloc, { module.bytes_of_glwe_secret_from_infos(infos) } pub fn bytes_of(module: &M, rank: Rank) -> usize where M: GLWESecretAlloc, { module.bytes_of_glwe_secret(rank) } } impl GLWESecret { pub fn fill_ternary_prob(&mut self, prob: f64, source: &mut Source) { (0..self.rank().into()).for_each(|i| { self.data.fill_ternary_prob(i, prob, source); }); self.dist = Distribution::TernaryProb(prob); } pub fn fill_ternary_hw(&mut self, hw: usize, source: &mut Source) { (0..self.rank().into()).for_each(|i| { self.data.fill_ternary_hw(i, hw, source); }); self.dist = Distribution::TernaryFixed(hw); } pub fn fill_binary_prob(&mut self, prob: f64, source: &mut Source) { (0..self.rank().into()).for_each(|i| { self.data.fill_binary_prob(i, prob, source); }); self.dist = Distribution::BinaryProb(prob); } pub fn fill_binary_hw(&mut self, hw: usize, source: &mut Source) { (0..self.rank().into()).for_each(|i| { self.data.fill_binary_hw(i, hw, source); }); self.dist = Distribution::BinaryFixed(hw); } pub fn fill_binary_block(&mut self, block_size: usize, source: &mut Source) { (0..self.rank().into()).for_each(|i| { self.data.fill_binary_block(i, block_size, source); }); self.dist = Distribution::BinaryBlock(block_size); } pub fn fill_zero(&mut self) { self.data.zero(); self.dist = Distribution::ZERO; } } pub trait GLWESecretToMut { fn to_mut(&mut self) -> GLWESecret<&mut [u8]>; } impl GLWESecretToMut for GLWESecret { fn to_mut(&mut self) -> GLWESecret<&mut [u8]> { GLWESecret { dist: self.dist, data: self.data.to_mut(), } } } pub trait GLWESecretToRef { fn to_ref(&self) -> GLWESecret<&[u8]>; } impl GLWESecretToRef for GLWESecret { fn to_ref(&self) -> GLWESecret<&[u8]> { GLWESecret { data: self.data.to_ref(), dist: self.dist, } } } impl ReaderFrom for GLWESecret { fn read_from(&mut self, reader: &mut R) -> std::io::Result<()> { match Distribution::read_from(reader) { Ok(dist) => self.dist = dist, Err(e) => return Err(e), } self.data.read_from(reader) } } impl WriterTo for GLWESecret { fn write_to(&self, writer: &mut W) -> std::io::Result<()> { match self.dist.write_to(writer) { Ok(()) => {} Err(e) => return Err(e), } self.data.write_to(writer) } }