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, Neg, 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 + Neg<Output = Self>
21 + PartialEq
22 + Debug
23 + Clone
24 // + Copy
25 + Sum<<Self as Add>::Output>
26 + Sum<<Self as Mul>::Output>
27{
28 /// C defines the coefficient type
29 type C: Debug + Clone;
30 type Params: Debug+Clone+Copy;
31
32 // const Q: u64;
33 // const N: usize;
34
35 fn coeffs(&self) -> Vec<Self::C>;
36 fn zero(params: Self::Params) -> Self;
37 // note/wip/warning: dist (0,q) with f64, will output more '0=q' elements than other values
38 fn rand(rng: impl Rng, dist: impl Distribution<f64>, params: Self::Params) -> Self;
39
40 fn from_vec(params: Self::Params, coeffs: Vec<Self::C>) -> Self;
41
42 fn decompose(&self, beta: u32, l: u32) -> Vec<Self>;
43
44 fn remodule(&self, p:u64) -> impl Ring;
45 fn mod_switch(&self, p:u64) -> impl Ring;
46
47 /// returns [ [(num/den) * self].round() ] mod q
48 /// ie. performs the multiplication and division over f64, and then it
49 /// rounds the result, only applying the mod Q (if the ring is mod Q) at the
50 /// end.
51 fn mul_div_round(&self, num: u64, den: u64) -> Self;
52}