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