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