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