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