use std::fmt; use backend::hal::{ api::{FillUniform, Reset, ZnxInfos}, layouts::{Data, DataMut, DataRef, ReaderFrom, VecZnx, VecZnxToMut, VecZnxToRef, WriterTo}, }; use sampling::source::Source; use crate::{Infos, SetMetaData}; #[derive(PartialEq, Eq, Clone)] pub struct LWECiphertext { pub(crate) data: VecZnx, pub(crate) k: usize, pub(crate) basek: usize, } impl fmt::Debug for LWECiphertext { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{}", self) } } impl fmt::Display for LWECiphertext { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!( f, "LWECiphertext: basek={} k={}: {}", self.basek(), self.k(), self.data ) } } impl Reset for LWECiphertext where VecZnx: Reset, { fn reset(&mut self) { self.data.reset(); self.basek = 0; self.k = 0; } } impl FillUniform for LWECiphertext where VecZnx: FillUniform, { fn fill_uniform(&mut self, source: &mut Source) { self.data.fill_uniform(source); } } impl LWECiphertext> { pub fn alloc(n: usize, basek: usize, k: usize) -> Self { Self { data: VecZnx::alloc(n + 1, 1, k.div_ceil(basek)), k: k, basek: basek, } } } impl Infos for LWECiphertext where VecZnx: ZnxInfos, { type Inner = VecZnx; fn n(&self) -> usize { &self.inner().n() - 1 } fn inner(&self) -> &Self::Inner { &self.data } fn basek(&self) -> usize { self.basek } fn k(&self) -> usize { self.k } } impl SetMetaData for LWECiphertext { fn set_k(&mut self, k: usize) { self.k = k } fn set_basek(&mut self, basek: usize) { self.basek = basek } } pub trait LWECiphertextToRef { fn to_ref(&self) -> LWECiphertext<&[u8]>; } impl LWECiphertextToRef for LWECiphertext { fn to_ref(&self) -> LWECiphertext<&[u8]> { LWECiphertext { data: self.data.to_ref(), basek: self.basek, k: self.k, } } } pub trait LWECiphertextToMut { #[allow(dead_code)] fn to_mut(&mut self) -> LWECiphertext<&mut [u8]>; } impl LWECiphertextToMut for LWECiphertext { fn to_mut(&mut self) -> LWECiphertext<&mut [u8]> { LWECiphertext { data: self.data.to_mut(), basek: self.basek, k: self.k, } } } use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt}; impl ReaderFrom for LWECiphertext { fn read_from(&mut self, reader: &mut R) -> std::io::Result<()> { self.k = reader.read_u64::()? as usize; self.basek = reader.read_u64::()? as usize; self.data.read_from(reader) } } impl WriterTo for LWECiphertext { fn write_to(&self, writer: &mut W) -> std::io::Result<()> { writer.write_u64::(self.k as u64)?; writer.write_u64::(self.basek as u64)?; self.data.write_to(writer) } }