poulpy/poulpy-core/src/layouts/mod.rs
poulpy-core/src/layouts/mod.rsRaw
1mod gglwe_atk;
2mod gglwe_ct;
3mod gglwe_ksk;
4mod gglwe_tsk;
5mod ggsw_ct;
6mod glwe_ct;
7mod glwe_pk;
8mod glwe_pt;
9mod glwe_sk;
10mod glwe_to_lwe_ksk;
11mod lwe_ct;
12mod lwe_ksk;
13mod lwe_pt;
14mod lwe_sk;
15mod lwe_to_glwe_ksk;
16
17pub mod compressed;
18pub mod prepared;
19
20pub use gglwe_atk::*;
21pub use gglwe_ct::*;
22pub use gglwe_ksk::*;
23pub use gglwe_tsk::*;
24pub use ggsw_ct::*;
25pub use glwe_ct::*;
26pub use glwe_pk::*;
27pub use glwe_pt::*;
28pub use glwe_sk::*;
29pub use glwe_to_lwe_ksk::*;
30pub use lwe_ct::*;
31pub use lwe_ksk::*;
32pub use lwe_pt::*;
33pub use lwe_sk::*;
34pub use lwe_to_glwe_ksk::*;
35
36#[derive(Debug)]
37pub enum BuildError {
38 MissingData,
39 MissingBase2K,
40 MissingK,
41 MissingDigits,
42 ZeroDegree,
43 NonPowerOfTwoDegree,
44 ZeroBase2K,
45 ZeroTorusPrecision,
46 ZeroCols,
47 ZeroLimbs,
48 ZeroRank,
49 ZeroDigits,
50 VecZnxColsNotOne,
51}
52
53/// Newtype over `u32` with arithmetic and comparisons against same type and `u32`.
54/// Arithmetic is **saturating** (add/sub/mul) to avoid debug-overflow panics.
55macro_rules! newtype_u32 {
56 ($name:ident) => {
57 #[repr(transparent)]
58 #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
59 pub struct $name(pub u32);
60
61 // ----- Conversions -----
62 impl From<$name> for u32 {
63 #[inline]
64 fn from(v: $name) -> u32 {
65 v.0
66 }
67 }
68 impl From<$name> for usize {
69 #[inline]
70 fn from(v: $name) -> usize {
71 v.0 as usize
72 }
73 }
74
75 impl From<u32> for $name {
76 #[inline]
77 fn from(v: u32) -> $name {
78 $name(v)
79 }
80 }
81 impl From<usize> for $name {
82 #[inline]
83 fn from(v: usize) -> $name {
84 $name(v as u32)
85 }
86 }
87
88 // ----- Display -----
89 impl ::core::fmt::Display for $name {
90 #[inline]
91 fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
92 write!(f, "{}", self.0)
93 }
94 }
95
96 // ===== Arithmetic (same type) =====
97 impl ::core::ops::Add for $name {
98 type Output = $name;
99 #[inline]
100 fn add(self, rhs: $name) -> $name {
101 $name(self.0.saturating_add(rhs.0))
102 }
103 }
104 impl ::core::ops::Sub for $name {
105 type Output = $name;
106 #[inline]
107 fn sub(self, rhs: $name) -> $name {
108 $name(self.0.saturating_sub(rhs.0))
109 }
110 }
111 impl ::core::ops::Mul for $name {
112 type Output = $name;
113 #[inline]
114 fn mul(self, rhs: $name) -> $name {
115 $name(self.0.saturating_mul(rhs.0))
116 }
117 }
118
119 // ===== Arithmetic (with u32) =====
120 impl ::core::ops::Add<u32> for $name {
121 type Output = $name;
122 #[inline]
123 fn add(self, rhs: u32) -> $name {
124 $name(self.0.saturating_add(rhs))
125 }
126 }
127 impl ::core::ops::Sub<u32> for $name {
128 type Output = $name;
129 #[inline]
130 fn sub(self, rhs: u32) -> $name {
131 $name(self.0.saturating_sub(rhs))
132 }
133 }
134 impl ::core::ops::Mul<u32> for $name {
135 type Output = $name;
136 #[inline]
137 fn mul(self, rhs: u32) -> $name {
138 $name(self.0.saturating_mul(rhs))
139 }
140 }
141
142 impl $name {
143 #[inline]
144 pub const fn as_u32(self) -> u32 {
145 self.0
146 }
147 #[inline]
148 pub const fn as_usize(self) -> usize {
149 self.0 as usize
150 }
151
152 #[inline]
153 pub fn div_ceil<T: Into<u32>>(self, rhs: T) -> u32 {
154 self.0.div_ceil(rhs.into())
155 }
156 }
157
158 // Optional symmetric forms: u32 (+|-|*) $name -> $name
159 impl ::core::ops::Add<$name> for u32 {
160 type Output = $name;
161 #[inline]
162 fn add(self, rhs: $name) -> $name {
163 $name(self.saturating_add(rhs.0))
164 }
165 }
166 impl ::core::ops::Sub<$name> for u32 {
167 type Output = $name;
168 #[inline]
169 fn sub(self, rhs: $name) -> $name {
170 $name(self.saturating_sub(rhs.0))
171 }
172 }
173 impl ::core::ops::Mul<$name> for u32 {
174 type Output = $name;
175 #[inline]
176 fn mul(self, rhs: $name) -> $name {
177 $name(self.saturating_mul(rhs.0))
178 }
179 }
180
181 // ===== Cross-type comparisons with u32 (both directions) =====
182 impl ::core::cmp::PartialEq<u32> for $name {
183 #[inline]
184 fn eq(&self, other: &u32) -> bool {
185 self.0 == *other
186 }
187 }
188 impl ::core::cmp::PartialEq<$name> for u32 {
189 #[inline]
190 fn eq(&self, other: &$name) -> bool {
191 *self == other.0
192 }
193 }
194
195 impl ::core::cmp::PartialOrd<u32> for $name {
196 #[inline]
197 fn partial_cmp(&self, other: &u32) -> Option<::core::cmp::Ordering> {
198 self.0.partial_cmp(other)
199 }
200 }
201 impl ::core::cmp::PartialOrd<$name> for u32 {
202 #[inline]
203 fn partial_cmp(&self, other: &$name) -> Option<::core::cmp::Ordering> {
204 self.partial_cmp(&other.0)
205 }
206 }
207 };
208}
209
210newtype_u32!(Degree);
211newtype_u32!(TorusPrecision);
212newtype_u32!(Base2K);
213newtype_u32!(Dnum);
214newtype_u32!(Rank);
215newtype_u32!(Dsize);
216
217impl Degree {
218 pub fn log2(&self) -> usize {
219 let n: usize = self.0 as usize;
220 (usize::BITS - (n - 1).leading_zeros()) as _
221 }
222}