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}