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