arnaucube
arnaucube/poulpyPublic Self-hosted repository
poulpy/core/src/layouts/compressed/gglwe_ksk.rs
core/src/layouts/compressed/gglwe_ksk.rsRaw
  1use backend::hal::{
  2    api::{FillUniform, Reset, VecZnxCopy, VecZnxFillUniform},
  3    layouts::{Backend, Data, DataMut, DataRef, MatZnx, Module, ReaderFrom, WriterTo},
  4};
  5
  6use crate::layouts::{
  7    GGLWESwitchingKey, Infos,
  8    compressed::{Decompress, GGLWECiphertextCompressed},
  9};
 10use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
 11use std::fmt;
 12
 13#[derive(PartialEq, Eq, Clone)]
 14pub struct GGLWESwitchingKeyCompressed<D: Data> {
 15    pub(crate) key: GGLWECiphertextCompressed<D>,
 16    pub(crate) sk_in_n: usize,  // Degree of sk_in
 17    pub(crate) sk_out_n: usize, // Degree of sk_out
 18}
 19
 20impl<D: DataRef> fmt::Debug for GGLWESwitchingKeyCompressed<D> {
 21    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 22        write!(f, "{}", self)
 23    }
 24}
 25
 26impl<D: DataMut> FillUniform for GGLWESwitchingKeyCompressed<D> {
 27    fn fill_uniform(&mut self, source: &mut sampling::source::Source) {
 28        self.key.fill_uniform(source);
 29    }
 30}
 31
 32impl<D: DataMut> Reset for GGLWESwitchingKeyCompressed<D>
 33where
 34    MatZnx<D>: Reset,
 35{
 36    fn reset(&mut self) {
 37        self.key.reset();
 38        self.sk_in_n = 0;
 39        self.sk_out_n = 0;
 40    }
 41}
 42
 43impl<D: DataRef> fmt::Display for GGLWESwitchingKeyCompressed<D> {
 44    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
 45        write!(
 46            f,
 47            "(GLWESwitchingKeyCompressed: sk_in_n={} sk_out_n={}) {}",
 48            self.sk_in_n, self.sk_out_n, self.key.data
 49        )
 50    }
 51}
 52
 53impl<D: Data> Infos for GGLWESwitchingKeyCompressed<D> {
 54    type Inner = MatZnx<D>;
 55
 56    fn inner(&self) -> &Self::Inner {
 57        &self.key.inner()
 58    }
 59
 60    fn basek(&self) -> usize {
 61        self.key.basek()
 62    }
 63
 64    fn k(&self) -> usize {
 65        self.key.k()
 66    }
 67}
 68
 69impl<D: Data> GGLWESwitchingKeyCompressed<D> {
 70    pub fn rank(&self) -> usize {
 71        self.key.rank()
 72    }
 73
 74    pub fn digits(&self) -> usize {
 75        self.key.digits()
 76    }
 77
 78    pub fn rank_in(&self) -> usize {
 79        self.key.rank_in()
 80    }
 81
 82    pub fn rank_out(&self) -> usize {
 83        self.key.rank_out()
 84    }
 85}
 86
 87impl GGLWESwitchingKeyCompressed<Vec<u8>> {
 88    pub fn alloc(n: usize, basek: usize, k: usize, rows: usize, digits: usize, rank_in: usize, rank_out: usize) -> Self {
 89        GGLWESwitchingKeyCompressed {
 90            key: GGLWECiphertextCompressed::alloc(n, basek, k, rows, digits, rank_in, rank_out),
 91            sk_in_n: 0,
 92            sk_out_n: 0,
 93        }
 94    }
 95
 96    pub fn bytes_of(n: usize, basek: usize, k: usize, rows: usize, digits: usize, rank_in: usize) -> usize {
 97        GGLWECiphertextCompressed::bytes_of(n, basek, k, rows, digits, rank_in)
 98    }
 99}
100
101impl<D: DataMut> ReaderFrom for GGLWESwitchingKeyCompressed<D> {
102    fn read_from<R: std::io::Read>(&mut self, reader: &mut R) -> std::io::Result<()> {
103        self.sk_in_n = reader.read_u64::<LittleEndian>()? as usize;
104        self.sk_out_n = reader.read_u64::<LittleEndian>()? as usize;
105        self.key.read_from(reader)
106    }
107}
108
109impl<D: DataRef> WriterTo for GGLWESwitchingKeyCompressed<D> {
110    fn write_to<W: std::io::Write>(&self, writer: &mut W) -> std::io::Result<()> {
111        writer.write_u64::<LittleEndian>(self.sk_in_n as u64)?;
112        writer.write_u64::<LittleEndian>(self.sk_out_n as u64)?;
113        self.key.write_to(writer)
114    }
115}
116
117impl<D: DataMut, DR: DataRef, B: Backend> Decompress<B, GGLWESwitchingKeyCompressed<DR>> for GGLWESwitchingKey<D> {
118    fn decompress(&mut self, module: &Module<B>, other: &GGLWESwitchingKeyCompressed<DR>)
119    where
120        Module<B>: VecZnxFillUniform + VecZnxCopy,
121    {
122        self.key.decompress(module, &other.key);
123        self.sk_in_n = other.sk_in_n;
124        self.sk_out_n = other.sk_out_n;
125    }
126}