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