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