arnaucube
arnaucube/poulpyPublic Self-hosted repository
poulpy/poulpy-core/src/layouts/compressed/lwe_ksk.rs
poulpy-core/src/layouts/compressed/lwe_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, Dnum, Dsize, GGLWEInfos, GLWEInfos, LWEInfos, LWESwitchingKey, LWESwitchingKeyToMut, Rank, RingDegree,
  8    TorusPrecision,
  9    compressed::{
 10        GLWESwitchingKeyCompressed, GLWESwitchingKeyCompressedAlloc, GLWESwitchingKeyCompressedToMut,
 11        GLWESwitchingKeyCompressedToRef, GLWESwitchingKeyDecompress,
 12    },
 13};
 14use std::fmt;
 15
 16#[derive(PartialEq, Eq, Clone)]
 17pub struct LWESwitchingKeyCompressed<D: Data>(pub(crate) GLWESwitchingKeyCompressed<D>);
 18
 19impl<D: Data> LWEInfos for LWESwitchingKeyCompressed<D> {
 20    fn base2k(&self) -> Base2K {
 21        self.0.base2k()
 22    }
 23
 24    fn k(&self) -> TorusPrecision {
 25        self.0.k()
 26    }
 27
 28    fn n(&self) -> RingDegree {
 29        self.0.n()
 30    }
 31    fn size(&self) -> usize {
 32        self.0.size()
 33    }
 34}
 35impl<D: Data> GLWEInfos for LWESwitchingKeyCompressed<D> {
 36    fn rank(&self) -> Rank {
 37        self.rank_out()
 38    }
 39}
 40
 41impl<D: Data> GGLWEInfos for LWESwitchingKeyCompressed<D> {
 42    fn dsize(&self) -> Dsize {
 43        self.0.dsize()
 44    }
 45
 46    fn rank_in(&self) -> Rank {
 47        self.0.rank_in()
 48    }
 49
 50    fn rank_out(&self) -> Rank {
 51        self.0.rank_out()
 52    }
 53
 54    fn dnum(&self) -> Dnum {
 55        self.0.dnum()
 56    }
 57}
 58
 59impl<D: DataRef> fmt::Debug for LWESwitchingKeyCompressed<D> {
 60    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 61        write!(f, "{self}")
 62    }
 63}
 64
 65impl<D: DataMut> FillUniform for LWESwitchingKeyCompressed<D> {
 66    fn fill_uniform(&mut self, log_bound: usize, source: &mut Source) {
 67        self.0.fill_uniform(log_bound, source);
 68    }
 69}
 70
 71impl<D: DataRef> fmt::Display for LWESwitchingKeyCompressed<D> {
 72    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
 73        write!(f, "(LWESwitchingKeyCompressed) {}", self.0)
 74    }
 75}
 76
 77impl<D: DataMut> ReaderFrom for LWESwitchingKeyCompressed<D> {
 78    fn read_from<R: std::io::Read>(&mut self, reader: &mut R) -> std::io::Result<()> {
 79        self.0.read_from(reader)
 80    }
 81}
 82
 83impl<D: DataRef> WriterTo for LWESwitchingKeyCompressed<D> {
 84    fn write_to<W: std::io::Write>(&self, writer: &mut W) -> std::io::Result<()> {
 85        self.0.write_to(writer)
 86    }
 87}
 88
 89pub trait LWESwitchingKeyCompressedAlloc
 90where
 91    Self: GLWESwitchingKeyCompressedAlloc,
 92{
 93    fn alloc_lwe_switching_key_compressed(
 94        &self,
 95        base2k: Base2K,
 96        k: TorusPrecision,
 97        dnum: Dnum,
 98    ) -> LWESwitchingKeyCompressed<Vec<u8>> {
 99        LWESwitchingKeyCompressed(self.alloc_glwe_switching_key_compressed(base2k, k, Rank(1), Rank(1), dnum, Dsize(1)))
100    }
101
102    fn alloc_lwe_switching_key_compressed_from_infos<A>(&self, infos: &A) -> LWESwitchingKeyCompressed<Vec<u8>>
103    where
104        A: GGLWEInfos,
105    {
106        assert_eq!(
107            infos.dsize().0,
108            1,
109            "dsize > 1 is not supported for LWESwitchingKeyCompressed"
110        );
111        assert_eq!(
112            infos.rank_in().0,
113            1,
114            "rank_in > 1 is not supported for LWESwitchingKeyCompressed"
115        );
116        assert_eq!(
117            infos.rank_out().0,
118            1,
119            "rank_out > 1 is not supported for LWESwitchingKeyCompressed"
120        );
121        self.alloc_lwe_switching_key_compressed(infos.base2k(), infos.k(), infos.dnum())
122    }
123
124    fn bytes_of_lwe_switching_key_compressed(&self, base2k: Base2K, k: TorusPrecision, dnum: Dnum) -> usize {
125        self.bytes_of_glwe_switching_key_compressed(base2k, k, Rank(1), dnum, Dsize(1))
126    }
127
128    fn bytes_of_lwe_switching_key_compressed_from_infos<A>(&self, infos: &A) -> usize
129    where
130        A: GGLWEInfos,
131    {
132        assert_eq!(
133            infos.dsize().0,
134            1,
135            "dsize > 1 is not supported for LWESwitchingKeyCompressed"
136        );
137        assert_eq!(
138            infos.rank_in().0,
139            1,
140            "rank_in > 1 is not supported for LWESwitchingKeyCompressed"
141        );
142        assert_eq!(
143            infos.rank_out().0,
144            1,
145            "rank_out > 1 is not supported for LWESwitchingKeyCompressed"
146        );
147        self.bytes_of_glwe_switching_key_compressed_from_infos(infos)
148    }
149}
150
151impl<B: Backend> LWESwitchingKeyCompressedAlloc for Module<B> where Self: GLWESwitchingKeyCompressedAlloc {}
152
153impl LWESwitchingKeyCompressed<Vec<u8>> {
154    pub fn alloc_from_infos<A, M>(module: &M, infos: &A) -> Self
155    where
156        A: GGLWEInfos,
157        M: LWESwitchingKeyCompressedAlloc,
158    {
159        module.alloc_lwe_switching_key_compressed_from_infos(infos)
160    }
161
162    pub fn alloc<M>(module: &M, base2k: Base2K, k: TorusPrecision, dnum: Dnum) -> Self
163    where
164        M: LWESwitchingKeyCompressedAlloc,
165    {
166        module.alloc_lwe_switching_key_compressed(base2k, k, dnum)
167    }
168
169    pub fn bytes_of_from_infos<A, M>(module: &M, infos: &A) -> usize
170    where
171        A: GGLWEInfos,
172        M: LWESwitchingKeyCompressedAlloc,
173    {
174        module.bytes_of_lwe_switching_key_compressed_from_infos(infos)
175    }
176
177    pub fn bytes_of<M>(module: &M, base2k: Base2K, k: TorusPrecision, dnum: Dnum) -> usize
178    where
179        M: LWESwitchingKeyCompressedAlloc,
180    {
181        module.bytes_of_lwe_switching_key_compressed(base2k, k, dnum)
182    }
183}
184
185pub trait LWESwitchingKeyDecompress
186where
187    Self: GLWESwitchingKeyDecompress,
188{
189    fn decompress_lwe_switching_key<R, O>(&self, res: &mut R, other: &O)
190    where
191        R: LWESwitchingKeyToMut,
192        O: LWESwitchingKeyCompressedToRef,
193    {
194        self.decompress_glwe_switching_key(&mut res.to_mut().0, &other.to_ref().0);
195    }
196}
197
198impl<B: Backend> LWESwitchingKeyDecompress for Module<B> where Self: GLWESwitchingKeyDecompress {}
199
200impl<D: DataMut> LWESwitchingKey<D> {
201    pub fn decompress<O, M>(&mut self, module: &M, other: &O)
202    where
203        O: LWESwitchingKeyCompressedToRef,
204        M: LWESwitchingKeyDecompress,
205    {
206        module.decompress_lwe_switching_key(self, other);
207    }
208}
209
210pub trait LWESwitchingKeyCompressedToRef {
211    fn to_ref(&self) -> LWESwitchingKeyCompressed<&[u8]>;
212}
213
214impl<D: DataRef> LWESwitchingKeyCompressedToRef for LWESwitchingKeyCompressed<D>
215where
216    GLWESwitchingKeyCompressed<D>: GLWESwitchingKeyCompressedToRef,
217{
218    fn to_ref(&self) -> LWESwitchingKeyCompressed<&[u8]> {
219        LWESwitchingKeyCompressed(self.0.to_ref())
220    }
221}
222
223pub trait LWESwitchingKeyCompressedToMut {
224    fn to_mut(&mut self) -> LWESwitchingKeyCompressed<&mut [u8]>;
225}
226
227impl<D: DataMut> LWESwitchingKeyCompressedToMut for LWESwitchingKeyCompressed<D>
228where
229    GLWESwitchingKeyCompressed<D>: GLWESwitchingKeyCompressedToMut,
230{
231    fn to_mut(&mut self) -> LWESwitchingKeyCompressed<&mut [u8]> {
232        LWESwitchingKeyCompressed(self.0.to_mut())
233    }
234}