arnaucube
arnaucube/fhe-studyPublic Self-hosted repository
fhe-study/arith/src/ring.rs
arith/src/ring.rsRaw
 1use rand::{distributions::Distribution, Rng};
 2use std::fmt::Debug;
 3use std::iter::Sum;
 4use std::ops::{Add, AddAssign, Mul, Sub, SubAssign};
 5
 6/// Represents a ring element. Currently implemented by ring_nq.rs#Rq and
 7/// ring_torus.rs#Tn. Is not a 'pure algebraic ring', but more a custom trait
 8/// definition which includes methods like `mod_switch`.
 9// assumed to be mod (X^N +1)
10pub trait Ring:
11    Sized
12    + Add<Output = Self>
13    + AddAssign
14    + Sum
15    + Sub<Output = Self>
16    + SubAssign
17    + Mul<Output = Self> // internal product
18    + Mul<u64, Output = Self> // scalar mul, external product
19    + Mul<Self::C, Output = Self>
20    + PartialEq
21    + Debug
22    + Clone
23    + Copy
24    + Sum<<Self as Add>::Output>
25    + Sum<<Self as Mul>::Output>
26{
27    /// C defines the coefficient type
28    type C: Debug + Clone;
29
30    const Q: u64;
31    const N: usize;
32
33    fn coeffs(&self) -> Vec<Self::C>;
34    fn zero() -> Self;
35    // note/wip/warning: dist (0,q) with f64, will output more '0=q' elements than other values
36    fn rand(rng: impl Rng, dist: impl Distribution<f64>) -> Self;
37
38    fn from_vec(coeffs: Vec<Self::C>) -> Self;
39
40    fn decompose(&self, beta: u32, l: u32) -> Vec<Self>;
41
42    fn remodule<const P: u64>(&self) -> impl Ring;
43    fn mod_switch<const P: u64>(&self) -> impl Ring;
44
45    /// returns [ [(num/den) * self].round() ] mod q
46    /// ie. performs the multiplication and division over f64, and then it
47    /// rounds the result, only applying the mod Q (if the ring is mod Q) at the
48    /// end.
49    fn mul_div_round(&self, num: u64, den: u64) -> Self;
50}