arnaucube
arnaucube/poulpyPublic Self-hosted repository
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}