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