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