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