poulpy_core/layouts/
glwe_pt.rs1use std::fmt;
2
3use poulpy_hal::layouts::{Data, DataMut, DataRef, VecZnx, VecZnxToMut, VecZnxToRef, ZnxInfos};
4
5use crate::layouts::{
6 Base2K, BuildError, Degree, GLWECiphertext, GLWECiphertextToMut, GLWECiphertextToRef, GLWEInfos, GLWELayoutSet, LWEInfos,
7 Rank, TorusPrecision,
8};
9
10#[derive(PartialEq, Eq, Copy, Clone, Debug)]
11pub struct GLWEPlaintextLayout {
12 pub n: Degree,
13 pub base2k: Base2K,
14 pub k: TorusPrecision,
15}
16
17impl LWEInfos for GLWEPlaintextLayout {
18 fn base2k(&self) -> Base2K {
19 self.base2k
20 }
21
22 fn k(&self) -> TorusPrecision {
23 self.k
24 }
25
26 fn n(&self) -> Degree {
27 self.n
28 }
29}
30
31impl GLWEInfos for GLWEPlaintextLayout {
32 fn rank(&self) -> Rank {
33 Rank(0)
34 }
35}
36
37pub struct GLWEPlaintext<D: Data> {
38 pub data: VecZnx<D>,
39 pub base2k: Base2K,
40 pub k: TorusPrecision,
41}
42
43impl<D: DataMut> GLWELayoutSet for GLWEPlaintext<D> {
44 fn set_basek(&mut self, base2k: Base2K) {
45 self.base2k = base2k
46 }
47
48 fn set_k(&mut self, k: TorusPrecision) {
49 self.k = k
50 }
51}
52
53impl<D: Data> LWEInfos for GLWEPlaintext<D> {
54 fn base2k(&self) -> Base2K {
55 self.base2k
56 }
57
58 fn k(&self) -> TorusPrecision {
59 self.k
60 }
61
62 fn size(&self) -> usize {
63 self.data.size()
64 }
65
66 fn n(&self) -> Degree {
67 Degree(self.data.n() as u32)
68 }
69}
70
71impl<D: Data> GLWEInfos for GLWEPlaintext<D> {
72 fn rank(&self) -> Rank {
73 Rank(self.data.cols() as u32 - 1)
74 }
75}
76
77pub struct GLWEPlaintextBuilder<D: Data> {
78 data: Option<VecZnx<D>>,
79 base2k: Option<Base2K>,
80 k: Option<TorusPrecision>,
81}
82
83impl<D: Data> GLWEPlaintext<D> {
84 #[inline]
85 pub fn builder() -> GLWEPlaintextBuilder<D> {
86 GLWEPlaintextBuilder {
87 data: None,
88 base2k: None,
89 k: None,
90 }
91 }
92}
93
94impl<D: Data> GLWEPlaintextBuilder<D> {
95 #[inline]
96 pub fn data(mut self, data: VecZnx<D>) -> Self {
97 self.data = Some(data);
98 self
99 }
100 #[inline]
101 pub fn base2k(mut self, base2k: Base2K) -> Self {
102 self.base2k = Some(base2k);
103 self
104 }
105 #[inline]
106 pub fn k(mut self, k: TorusPrecision) -> Self {
107 self.k = Some(k);
108 self
109 }
110
111 pub fn build(self) -> Result<GLWEPlaintext<D>, BuildError> {
112 let data: VecZnx<D> = self.data.ok_or(BuildError::MissingData)?;
113 let base2k: Base2K = self.base2k.ok_or(BuildError::MissingBase2K)?;
114 let k: TorusPrecision = self.k.ok_or(BuildError::MissingK)?;
115
116 if base2k.0 == 0 {
117 return Err(BuildError::ZeroBase2K);
118 }
119
120 if k.0 == 0 {
121 return Err(BuildError::ZeroTorusPrecision);
122 }
123
124 if data.n() == 0 {
125 return Err(BuildError::ZeroDegree);
126 }
127
128 if data.cols() != 1 {
129 return Err(BuildError::ZeroCols);
130 }
131
132 if data.size() == 0 {
133 return Err(BuildError::ZeroLimbs);
134 }
135
136 Ok(GLWEPlaintext { data, base2k, k })
137 }
138}
139
140impl<D: DataRef> fmt::Display for GLWEPlaintext<D> {
141 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
142 write!(
143 f,
144 "GLWEPlaintext: base2k={} k={}: {}",
145 self.base2k().0,
146 self.k().0,
147 self.data
148 )
149 }
150}
151
152impl GLWEPlaintext<Vec<u8>> {
153 pub fn alloc<A>(infos: &A) -> Self
154 where
155 A: GLWEInfos,
156 {
157 Self::alloc_with(infos.n(), infos.base2k(), infos.k(), Rank(0))
158 }
159
160 pub fn alloc_with(n: Degree, base2k: Base2K, k: TorusPrecision, rank: Rank) -> Self {
161 debug_assert!(rank.0 == 0);
162 Self {
163 data: VecZnx::alloc(n.into(), (rank + 1).into(), k.0.div_ceil(base2k.0) as usize),
164 base2k,
165 k,
166 }
167 }
168
169 pub fn alloc_bytes<A>(infos: &A) -> usize
170 where
171 A: GLWEInfos,
172 {
173 Self::alloc_bytes_with(infos.n(), infos.base2k(), infos.k(), Rank(0))
174 }
175
176 pub fn alloc_bytes_with(n: Degree, base2k: Base2K, k: TorusPrecision, rank: Rank) -> usize {
177 debug_assert!(rank.0 == 0);
178 VecZnx::alloc_bytes(n.into(), (rank + 1).into(), k.0.div_ceil(base2k.0) as usize)
179 }
180}
181
182impl<D: DataRef> GLWECiphertextToRef for GLWEPlaintext<D> {
183 fn to_ref(&self) -> GLWECiphertext<&[u8]> {
184 GLWECiphertext::builder()
185 .data(self.data.to_ref())
186 .k(self.k())
187 .base2k(self.base2k())
188 .build()
189 .unwrap()
190 }
191}
192
193impl<D: DataMut> GLWECiphertextToMut for GLWEPlaintext<D> {
194 fn to_mut(&mut self) -> GLWECiphertext<&mut [u8]> {
195 GLWECiphertext::builder()
196 .k(self.k())
197 .base2k(self.base2k())
198 .data(self.data.to_mut())
199 .build()
200 .unwrap()
201 }
202}