arnaucube
arnaucube/poulpyPublic Self-hosted repository
poulpy/poulpy-core/src/layouts/compressed/gglwe_ksk.rs
poulpy-core/src/layouts/compressed/gglwe_ksk.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, GGLWEInfos, GLWEInfos, GLWESwitchingKey, GLWESwitchingKeySetMetaData, GLWESwitchingKeyToMut,
  8    LWEInfos, Rank, TorusPrecision,
  9    compressed::{GGLWECompressed, GGLWECompressedAlloc, 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) sk_in_n: usize,  // Degree of sk_in
 18    pub(crate) sk_out_n: usize, // Degree of sk_out
 19}
 20
 21impl<D: Data> LWEInfos for GLWESwitchingKeyCompressed<D> {
 22    fn n(&self) -> Degree {
 23        self.key.n()
 24    }
 25
 26    fn base2k(&self) -> Base2K {
 27        self.key.base2k()
 28    }
 29
 30    fn k(&self) -> TorusPrecision {
 31        self.key.k()
 32    }
 33
 34    fn size(&self) -> usize {
 35        self.key.size()
 36    }
 37}
 38impl<D: Data> GLWEInfos for GLWESwitchingKeyCompressed<D> {
 39    fn rank(&self) -> Rank {
 40        self.rank_out()
 41    }
 42}
 43
 44impl<D: Data> GGLWEInfos for GLWESwitchingKeyCompressed<D> {
 45    fn rank_in(&self) -> Rank {
 46        self.key.rank_in()
 47    }
 48
 49    fn rank_out(&self) -> Rank {
 50        self.key.rank_out()
 51    }
 52
 53    fn dsize(&self) -> Dsize {
 54        self.key.dsize()
 55    }
 56
 57    fn dnum(&self) -> Dnum {
 58        self.key.dnum()
 59    }
 60}
 61
 62impl<D: DataRef> fmt::Debug for GLWESwitchingKeyCompressed<D> {
 63    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 64        write!(f, "{self}")
 65    }
 66}
 67
 68impl<D: DataMut> FillUniform for GLWESwitchingKeyCompressed<D> {
 69    fn fill_uniform(&mut self, log_bound: usize, source: &mut Source) {
 70        self.key.fill_uniform(log_bound, source);
 71    }
 72}
 73
 74impl<D: DataRef> fmt::Display for GLWESwitchingKeyCompressed<D> {
 75    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
 76        write!(
 77            f,
 78            "(GLWESwitchingKeyCompressed: sk_in_n={} sk_out_n={}) {}",
 79            self.sk_in_n, self.sk_out_n, self.key.data
 80        )
 81    }
 82}
 83
 84impl<BE: Backend> GLWESwitchingKeyCompressedAlloc for Module<BE> where Self: GGLWECompressedAlloc {}
 85
 86pub trait GLWESwitchingKeyCompressedAlloc
 87where
 88    Self: GGLWECompressedAlloc,
 89{
 90    fn alloc_glwe_switching_key_compressed(
 91        &self,
 92        base2k: Base2K,
 93        k: TorusPrecision,
 94        rank_in: Rank,
 95        rank_out: Rank,
 96        dnum: Dnum,
 97        dsize: Dsize,
 98    ) -> GLWESwitchingKeyCompressed<Vec<u8>> {
 99        GLWESwitchingKeyCompressed {
100            key: self.alloc_gglwe_compressed(base2k, k, rank_in, rank_out, dnum, dsize),
101            sk_in_n: 0,
102            sk_out_n: 0,
103        }
104    }
105
106    fn alloc_glwe_switching_key_compressed_from_infos<A>(&self, infos: &A) -> GLWESwitchingKeyCompressed<Vec<u8>>
107    where
108        A: GGLWEInfos,
109    {
110        self.alloc_glwe_switching_key_compressed(
111            infos.base2k(),
112            infos.k(),
113            infos.rank_in(),
114            infos.rank_out(),
115            infos.dnum(),
116            infos.dsize(),
117        )
118    }
119
120    fn bytes_of_glwe_switching_key_compressed(
121        &self,
122        base2k: Base2K,
123        k: TorusPrecision,
124        rank_in: Rank,
125        dnum: Dnum,
126        dsize: Dsize,
127    ) -> usize {
128        self.bytes_of_gglwe_compressed(base2k, k, rank_in, dnum, dsize)
129    }
130
131    fn bytes_of_glwe_switching_key_compressed_from_infos<A>(&self, infos: &A) -> usize
132    where
133        A: GGLWEInfos,
134    {
135        self.bytes_of_gglwe_compressed_from_infos(infos)
136    }
137}
138
139impl GLWESwitchingKeyCompressed<Vec<u8>> {
140    pub fn alloc_from_infos<A, M>(module: &M, infos: &A) -> Self
141    where
142        A: GGLWEInfos,
143        M: GLWESwitchingKeyCompressedAlloc,
144    {
145        module.alloc_glwe_switching_key_compressed_from_infos(infos)
146    }
147
148    pub fn alloc<M>(
149        module: &M,
150        base2k: Base2K,
151        k: TorusPrecision,
152        rank_in: Rank,
153        rank_out: Rank,
154        dnum: Dnum,
155        dsize: Dsize,
156    ) -> Self
157    where
158        M: GLWESwitchingKeyCompressedAlloc,
159    {
160        module.alloc_glwe_switching_key_compressed(base2k, k, rank_in, rank_out, dnum, dsize)
161    }
162
163    pub fn bytes_of_from_infos<A, M>(module: &M, infos: &A) -> usize
164    where
165        A: GGLWEInfos,
166        M: GLWESwitchingKeyCompressedAlloc,
167    {
168        module.bytes_of_glwe_switching_key_compressed_from_infos(infos)
169    }
170
171    pub fn bytes_of<M>(module: &M, base2k: Base2K, k: TorusPrecision, rank_in: Rank, dnum: Dnum, dsize: Dsize) -> usize
172    where
173        M: GLWESwitchingKeyCompressedAlloc,
174    {
175        module.bytes_of_glwe_switching_key_compressed(base2k, k, rank_in, dnum, dsize)
176    }
177}
178
179impl<D: DataMut> ReaderFrom for GLWESwitchingKeyCompressed<D> {
180    fn read_from<R: std::io::Read>(&mut self, reader: &mut R) -> std::io::Result<()> {
181        self.sk_in_n = reader.read_u64::<LittleEndian>()? as usize;
182        self.sk_out_n = reader.read_u64::<LittleEndian>()? as usize;
183        self.key.read_from(reader)
184    }
185}
186
187impl<D: DataRef> WriterTo for GLWESwitchingKeyCompressed<D> {
188    fn write_to<W: std::io::Write>(&self, writer: &mut W) -> std::io::Result<()> {
189        writer.write_u64::<LittleEndian>(self.sk_in_n as u64)?;
190        writer.write_u64::<LittleEndian>(self.sk_out_n as u64)?;
191        self.key.write_to(writer)
192    }
193}
194
195pub trait GLWESwitchingKeyDecompress
196where
197    Self: GGLWEDecompress,
198{
199    fn decompress_glwe_switching_key<R, O>(&self, res: &mut R, other: &O)
200    where
201        R: GLWESwitchingKeyToMut + GLWESwitchingKeySetMetaData,
202        O: GLWESwitchingKeyCompressedToRef,
203    {
204        let other: &GLWESwitchingKeyCompressed<&[u8]> = &other.to_ref();
205        self.decompress_gglwe(&mut res.to_mut().key, &other.key);
206        res.set_sk_in_n(other.sk_in_n);
207        res.set_sk_out_n(other.sk_out_n);
208    }
209}
210
211impl<B: Backend> GLWESwitchingKeyDecompress for Module<B> where Self: GGLWEDecompress {}
212
213impl<D: DataMut> GLWESwitchingKey<D> {
214    pub fn decompress<O, M>(&mut self, module: &M, other: &O)
215    where
216        O: GLWESwitchingKeyCompressedToRef,
217        M: GLWESwitchingKeyDecompress,
218    {
219        module.decompress_glwe_switching_key(self, other);
220    }
221}
222
223pub trait GLWESwitchingKeyCompressedToMut {
224    fn to_mut(&mut self) -> GLWESwitchingKeyCompressed<&mut [u8]>;
225}
226
227impl<D: DataMut> GLWESwitchingKeyCompressedToMut for GLWESwitchingKeyCompressed<D>
228where
229    GGLWECompressed<D>: GGLWECompressedToMut,
230{
231    fn to_mut(&mut self) -> GLWESwitchingKeyCompressed<&mut [u8]> {
232        GLWESwitchingKeyCompressed {
233            sk_in_n: self.sk_in_n,
234            sk_out_n: self.sk_out_n,
235            key: self.key.to_mut(),
236        }
237    }
238}
239
240pub trait GLWESwitchingKeyCompressedToRef {
241    fn to_ref(&self) -> GLWESwitchingKeyCompressed<&[u8]>;
242}
243
244impl<D: DataRef> GLWESwitchingKeyCompressedToRef for GLWESwitchingKeyCompressed<D>
245where
246    GGLWECompressed<D>: GGLWECompressedToRef,
247{
248    fn to_ref(&self) -> GLWESwitchingKeyCompressed<&[u8]> {
249        GLWESwitchingKeyCompressed {
250            sk_in_n: self.sk_in_n,
251            sk_out_n: self.sk_out_n,
252            key: self.key.to_ref(),
253        }
254    }
255}