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