arnaucube
arnaucube/poulpyPublic Self-hosted repository
poulpy/core/src/layouts/lwe_ct.rs
core/src/layouts/lwe_ct.rsRaw
  1use std::fmt;
  2
  3use backend::hal::{
  4    api::{FillUniform, Reset, ZnxInfos},
  5    layouts::{Data, DataMut, DataRef, ReaderFrom, VecZnx, VecZnxToMut, VecZnxToRef, WriterTo},
  6};
  7use sampling::source::Source;
  8
  9#[derive(PartialEq, Eq, Clone)]
 10pub struct LWECiphertext<D: Data> {
 11    pub(crate) data: VecZnx<D>,
 12    pub(crate) k: usize,
 13    pub(crate) basek: usize,
 14}
 15
 16impl<D: DataRef> fmt::Debug for LWECiphertext<D> {
 17    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 18        write!(f, "{}", self)
 19    }
 20}
 21
 22impl<D: DataRef> fmt::Display for LWECiphertext<D> {
 23    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
 24        write!(
 25            f,
 26            "LWECiphertext: basek={} k={}: {}",
 27            self.basek(),
 28            self.k(),
 29            self.data
 30        )
 31    }
 32}
 33
 34impl<D: DataMut> Reset for LWECiphertext<D>
 35where
 36    VecZnx<D>: Reset,
 37{
 38    fn reset(&mut self) {
 39        self.data.reset();
 40        self.basek = 0;
 41        self.k = 0;
 42    }
 43}
 44
 45impl<D: DataMut> FillUniform for LWECiphertext<D>
 46where
 47    VecZnx<D>: FillUniform,
 48{
 49    fn fill_uniform(&mut self, source: &mut Source) {
 50        self.data.fill_uniform(source);
 51    }
 52}
 53
 54impl LWECiphertext<Vec<u8>> {
 55    pub fn alloc(n: usize, basek: usize, k: usize) -> Self {
 56        Self {
 57            data: VecZnx::alloc(n + 1, 1, k.div_ceil(basek)),
 58            k: k,
 59            basek: basek,
 60        }
 61    }
 62}
 63
 64impl<D: Data> Infos for LWECiphertext<D>
 65where
 66    VecZnx<D>: ZnxInfos,
 67{
 68    type Inner = VecZnx<D>;
 69
 70    fn n(&self) -> usize {
 71        &self.inner().n() - 1
 72    }
 73
 74    fn inner(&self) -> &Self::Inner {
 75        &self.data
 76    }
 77
 78    fn basek(&self) -> usize {
 79        self.basek
 80    }
 81
 82    fn k(&self) -> usize {
 83        self.k
 84    }
 85}
 86
 87impl<DataSelf: DataMut> SetMetaData for LWECiphertext<DataSelf> {
 88    fn set_k(&mut self, k: usize) {
 89        self.k = k
 90    }
 91
 92    fn set_basek(&mut self, basek: usize) {
 93        self.basek = basek
 94    }
 95}
 96
 97pub trait LWECiphertextToRef {
 98    fn to_ref(&self) -> LWECiphertext<&[u8]>;
 99}
100
101impl<D: DataRef> LWECiphertextToRef for LWECiphertext<D> {
102    fn to_ref(&self) -> LWECiphertext<&[u8]> {
103        LWECiphertext {
104            data: self.data.to_ref(),
105            basek: self.basek,
106            k: self.k,
107        }
108    }
109}
110
111pub trait LWECiphertextToMut {
112    #[allow(dead_code)]
113    fn to_mut(&mut self) -> LWECiphertext<&mut [u8]>;
114}
115
116impl<D: DataMut> LWECiphertextToMut for LWECiphertext<D> {
117    fn to_mut(&mut self) -> LWECiphertext<&mut [u8]> {
118        LWECiphertext {
119            data: self.data.to_mut(),
120            basek: self.basek,
121            k: self.k,
122        }
123    }
124}
125
126use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
127
128use crate::layouts::{Infos, SetMetaData};
129
130impl<D: DataMut> ReaderFrom for LWECiphertext<D> {
131    fn read_from<R: std::io::Read>(&mut self, reader: &mut R) -> std::io::Result<()> {
132        self.k = reader.read_u64::<LittleEndian>()? as usize;
133        self.basek = reader.read_u64::<LittleEndian>()? as usize;
134        self.data.read_from(reader)
135    }
136}
137
138impl<D: DataRef> WriterTo for LWECiphertext<D> {
139    fn write_to<W: std::io::Write>(&self, writer: &mut W) -> std::io::Result<()> {
140        writer.write_u64::<LittleEndian>(self.k as u64)?;
141        writer.write_u64::<LittleEndian>(self.basek as u64)?;
142        self.data.write_to(writer)
143    }
144}