arnaucube
arnaucube/poulpyPublic Self-hosted repository
poulpy/poulpy-core/src/layouts/compressed/glwe_switching_key.rs
poulpy-core/src/layouts/compressed/glwe_switching_key.rsRaw
  1use poulpy_hal::{
  2    layouts::{Backend, Data, DataMut, DataRef, FillUniform, Module, ReaderFrom, WriterTo},
  3    source::Source,
  4};
  5
  6use crate::layouts::{
  7    Base2K, Degree, Dnum, Dsize, GGLWECompressedSeedMut, GGLWEInfos, GGLWEToMut, GLWEInfos, GLWESwitchingKey,
  8    GLWESwitchingKeyDegrees, GLWESwitchingKeyDegreesMut, LWEInfos, Rank, TorusPrecision,
  9    compressed::{GGLWECompressed, GGLWECompressedToMut, GGLWECompressedToRef, GGLWEDecompress},
 10};
 11use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
 12use std::fmt;
 13
 14#[derive(PartialEq, Eq, Clone)]
 15pub struct GLWESwitchingKeyCompressed<D: Data> {
 16    pub(crate) key: GGLWECompressed<D>,
 17    pub(crate) input_degree: Degree,  // Degree of sk_in
 18    pub(crate) output_degree: Degree, // Degree of sk_out
 19}
 20
 21impl<D: DataMut> GGLWECompressedSeedMut for GLWESwitchingKeyCompressed<D> {
 22    fn seed_mut(&mut self) -> &mut Vec<[u8; 32]> {
 23        &mut self.key.seed
 24    }
 25}
 26
 27impl<D: DataRef> GLWESwitchingKeyDegrees for GLWESwitchingKeyCompressed<D> {
 28    fn output_degree(&self) -> &Degree {
 29        &self.output_degree
 30    }
 31
 32    fn input_degree(&self) -> &Degree {
 33        &self.input_degree
 34    }
 35}
 36
 37impl<D: DataMut> GLWESwitchingKeyDegreesMut for GLWESwitchingKeyCompressed<D> {
 38    fn output_degree(&mut self) -> &mut Degree {
 39        &mut self.output_degree
 40    }
 41
 42    fn input_degree(&mut self) -> &mut Degree {
 43        &mut self.input_degree
 44    }
 45}
 46
 47impl<D: Data> LWEInfos for GLWESwitchingKeyCompressed<D> {
 48    fn n(&self) -> Degree {
 49        self.key.n()
 50    }
 51
 52    fn base2k(&self) -> Base2K {
 53        self.key.base2k()
 54    }
 55
 56    fn k(&self) -> TorusPrecision {
 57        self.key.k()
 58    }
 59
 60    fn size(&self) -> usize {
 61        self.key.size()
 62    }
 63}
 64impl<D: Data> GLWEInfos for GLWESwitchingKeyCompressed<D> {
 65    fn rank(&self) -> Rank {
 66        self.rank_out()
 67    }
 68}
 69
 70impl<D: Data> GGLWEInfos for GLWESwitchingKeyCompressed<D> {
 71    fn rank_in(&self) -> Rank {
 72        self.key.rank_in()
 73    }
 74
 75    fn rank_out(&self) -> Rank {
 76        self.key.rank_out()
 77    }
 78
 79    fn dsize(&self) -> Dsize {
 80        self.key.dsize()
 81    }
 82
 83    fn dnum(&self) -> Dnum {
 84        self.key.dnum()
 85    }
 86}
 87
 88impl<D: DataRef> fmt::Debug for GLWESwitchingKeyCompressed<D> {
 89    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 90        write!(f, "{self}")
 91    }
 92}
 93
 94impl<D: DataMut> FillUniform for GLWESwitchingKeyCompressed<D> {
 95    fn fill_uniform(&mut self, log_bound: usize, source: &mut Source) {
 96        self.key.fill_uniform(log_bound, source);
 97    }
 98}
 99
100impl<D: DataRef> fmt::Display for GLWESwitchingKeyCompressed<D> {
101    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
102        write!(
103            f,
104            "(GLWESwitchingKeyCompressed: sk_in_n={} sk_out_n={}) {}",
105            self.input_degree, self.output_degree, self.key.data
106        )
107    }
108}
109
110impl GLWESwitchingKeyCompressed<Vec<u8>> {
111    pub fn alloc_from_infos<A>(infos: &A) -> Self
112    where
113        A: GGLWEInfos,
114    {
115        Self::alloc(
116            infos.n(),
117            infos.base2k(),
118            infos.k(),
119            infos.rank_in(),
120            infos.rank_out(),
121            infos.dnum(),
122            infos.dsize(),
123        )
124    }
125
126    pub fn alloc(n: Degree, base2k: Base2K, k: TorusPrecision, rank_in: Rank, rank_out: Rank, dnum: Dnum, dsize: Dsize) -> Self {
127        GLWESwitchingKeyCompressed {
128            key: GGLWECompressed::alloc(n, base2k, k, rank_in, rank_out, dnum, dsize),
129            input_degree: Degree(0),
130            output_degree: Degree(0),
131        }
132    }
133
134    pub fn bytes_of_from_infos<A>(infos: &A) -> usize
135    where
136        A: GGLWEInfos,
137    {
138        GGLWECompressed::bytes_of_from_infos(infos)
139    }
140
141    pub fn bytes_of(n: Degree, base2k: Base2K, k: TorusPrecision, rank_in: Rank, dnum: Dnum, dsize: Dsize) -> usize
142where {
143        GGLWECompressed::bytes_of(n, base2k, k, rank_in, dnum, dsize)
144    }
145}
146
147impl<D: DataMut> ReaderFrom for GLWESwitchingKeyCompressed<D> {
148    fn read_from<R: std::io::Read>(&mut self, reader: &mut R) -> std::io::Result<()> {
149        self.input_degree = Degree(reader.read_u32::<LittleEndian>()?);
150        self.output_degree = Degree(reader.read_u32::<LittleEndian>()?);
151        self.key.read_from(reader)
152    }
153}
154
155impl<D: DataRef> WriterTo for GLWESwitchingKeyCompressed<D> {
156    fn write_to<W: std::io::Write>(&self, writer: &mut W) -> std::io::Result<()> {
157        writer.write_u32::<LittleEndian>(self.input_degree.into())?;
158        writer.write_u32::<LittleEndian>(self.output_degree.into())?;
159        self.key.write_to(writer)
160    }
161}
162
163pub trait GLWESwitchingKeyDecompress
164where
165    Self: GGLWEDecompress,
166{
167    fn decompress_glwe_switching_key<R, O>(&self, res: &mut R, other: &O)
168    where
169        R: GGLWEToMut + GLWESwitchingKeyDegreesMut,
170        O: GGLWECompressedToRef + GLWESwitchingKeyDegrees,
171    {
172        self.decompress_gglwe(res, other);
173
174        *res.input_degree() = *other.input_degree();
175        *res.output_degree() = *other.output_degree();
176    }
177}
178
179impl<B: Backend> GLWESwitchingKeyDecompress for Module<B> where Self: GGLWEDecompress {}
180
181impl<D: DataMut> GLWESwitchingKey<D> {
182    pub fn decompress<O, M>(&mut self, module: &M, other: &O)
183    where
184        O: GGLWECompressedToRef + GLWESwitchingKeyDegrees,
185        M: GLWESwitchingKeyDecompress,
186    {
187        module.decompress_glwe_switching_key(self, other);
188    }
189}
190
191impl<D: DataMut> GGLWECompressedToMut for GLWESwitchingKeyCompressed<D> {
192    fn to_mut(&mut self) -> GGLWECompressed<&mut [u8]> {
193        self.key.to_mut()
194    }
195}
196
197impl<D: DataRef> GGLWECompressedToRef for GLWESwitchingKeyCompressed<D> {
198    fn to_ref(&self) -> GGLWECompressed<&[u8]> {
199        self.key.to_ref()
200    }
201}