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::{Data, DataMut, DataRef, FillUniform, ReaderFrom, WriterTo},
  5    source::Source,
  6};
  7
  8use crate::layouts::{
  9    Base2K, Degree, Dnum, Dsize, GGLWEInfos, GLWEInfos, GLWESwitchingKey, GLWESwitchingKeyToMut, GLWESwitchingKeyToRef, LWEInfos,
 10    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
104impl LWESwitchingKey<Vec<u8>> {
105    pub fn alloc<A>(infos: &A) -> Self
106    where
107        A: GGLWEInfos,
108    {
109        debug_assert_eq!(
110            infos.dsize().0,
111            1,
112            "dsize > 1 is not supported for LWESwitchingKey"
113        );
114        debug_assert_eq!(
115            infos.rank_in().0,
116            1,
117            "rank_in > 1 is not supported for LWESwitchingKey"
118        );
119        debug_assert_eq!(
120            infos.rank_out().0,
121            1,
122            "rank_out > 1 is not supported for LWESwitchingKey"
123        );
124        Self(GLWESwitchingKey::alloc(infos))
125    }
126
127    pub fn alloc_with(n: Degree, base2k: Base2K, k: TorusPrecision, dnum: Dnum) -> Self {
128        Self(GLWESwitchingKey::alloc_with(
129            n,
130            base2k,
131            k,
132            Rank(1),
133            Rank(1),
134            dnum,
135            Dsize(1),
136        ))
137    }
138
139    pub fn alloc_bytes<A>(infos: &A) -> usize
140    where
141        A: GGLWEInfos,
142    {
143        debug_assert_eq!(
144            infos.dsize().0,
145            1,
146            "dsize > 1 is not supported for LWESwitchingKey"
147        );
148        debug_assert_eq!(
149            infos.rank_in().0,
150            1,
151            "rank_in > 1 is not supported for LWESwitchingKey"
152        );
153        debug_assert_eq!(
154            infos.rank_out().0,
155            1,
156            "rank_out > 1 is not supported for LWESwitchingKey"
157        );
158        GLWESwitchingKey::alloc_bytes(infos)
159    }
160
161    pub fn alloc_bytes_with(n: Degree, base2k: Base2K, k: TorusPrecision, dnum: Dnum) -> usize {
162        GLWESwitchingKey::alloc_bytes_with(n, base2k, k, Rank(1), Rank(1), dnum, Dsize(1))
163    }
164}
165
166impl<D: DataRef> fmt::Debug for LWESwitchingKey<D> {
167    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
168        write!(f, "{self}")
169    }
170}
171
172impl<D: DataMut> FillUniform for LWESwitchingKey<D> {
173    fn fill_uniform(&mut self, log_bound: usize, source: &mut Source) {
174        self.0.fill_uniform(log_bound, source);
175    }
176}
177
178impl<D: DataRef> fmt::Display for LWESwitchingKey<D> {
179    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
180        write!(f, "(LWESwitchingKey) {}", self.0)
181    }
182}
183
184impl<D: DataMut> ReaderFrom for LWESwitchingKey<D> {
185    fn read_from<R: std::io::Read>(&mut self, reader: &mut R) -> std::io::Result<()> {
186        self.0.read_from(reader)
187    }
188}
189
190impl<D: DataRef> WriterTo for LWESwitchingKey<D> {
191    fn write_to<W: std::io::Write>(&self, writer: &mut W) -> std::io::Result<()> {
192        self.0.write_to(writer)
193    }
194}
195
196pub trait LWESwitchingKeyToRef {
197    fn to_ref(&self) -> LWESwitchingKey<&[u8]>;
198}
199
200impl<D: DataRef> LWESwitchingKeyToRef for LWESwitchingKey<D>
201where
202    GLWESwitchingKey<D>: GLWESwitchingKeyToRef,
203{
204    fn to_ref(&self) -> LWESwitchingKey<&[u8]> {
205        LWESwitchingKey(self.0.to_ref())
206    }
207}
208
209pub trait LWESwitchingKeyToMut {
210    fn to_mut(&mut self) -> LWESwitchingKey<&mut [u8]>;
211}
212
213impl<D: DataMut> LWESwitchingKeyToMut for LWESwitchingKey<D>
214where
215    GLWESwitchingKey<D>: GLWESwitchingKeyToMut,
216{
217    fn to_mut(&mut self) -> LWESwitchingKey<&mut [u8]> {
218        LWESwitchingKey(self.0.to_mut())
219    }
220}