arnaucube
arnaucube/poulpyPublic Self-hosted repository
poulpy/poulpy-core/src/noise/mod.rs
poulpy-core/src/noise/mod.rsRaw
  1mod gglwe;
  2mod ggsw;
  3mod glwe;
  4
  5pub use gglwe::*;
  6pub use ggsw::*;
  7pub use glwe::*;
  8
  9#[allow(clippy::too_many_arguments)]
 10#[allow(dead_code)]
 11pub(crate) fn var_noise_gglwe_product(
 12    n: f64,
 13    base2k: usize,
 14    var_xs: f64,
 15    var_msg: f64,
 16    var_a_err: f64,
 17    var_gct_err_lhs: f64,
 18    var_gct_err_rhs: f64,
 19    rank_in: f64,
 20    a_logq: usize,
 21    b_logq: usize,
 22) -> f64 {
 23    let a_logq: usize = a_logq.min(b_logq);
 24    let a_cols: usize = a_logq.div_ceil(base2k);
 25
 26    let b_scale: f64 = (b_logq as f64).exp2();
 27    let a_scale: f64 = ((b_logq - a_logq) as f64).exp2();
 28
 29    let base: f64 = (base2k as f64).exp2();
 30    let var_base: f64 = base * base / 12f64;
 31
 32    // lhs = a_cols * n * (var_base * var_gct_err_lhs + var_e_a * var_msg * p^2)
 33    // rhs = a_cols * n * var_base * var_gct_err_rhs * var_xs
 34    let mut noise: f64 = (a_cols as f64) * n * var_base * (var_gct_err_lhs + var_xs * var_gct_err_rhs);
 35    noise += var_msg * var_a_err * a_scale * a_scale * n;
 36    noise *= rank_in;
 37    noise /= b_scale * b_scale;
 38    noise
 39}
 40
 41#[allow(clippy::too_many_arguments)]
 42#[allow(dead_code)]
 43pub(crate) fn log2_std_noise_gglwe_product(
 44    n: f64,
 45    base2k: usize,
 46    var_xs: f64,
 47    var_msg: f64,
 48    var_a_err: f64,
 49    var_gct_err_lhs: f64,
 50    var_gct_err_rhs: f64,
 51    rank_in: f64,
 52    a_logq: usize,
 53    b_logq: usize,
 54) -> f64 {
 55    let mut noise: f64 = var_noise_gglwe_product(
 56        n,
 57        base2k,
 58        var_xs,
 59        var_msg,
 60        var_a_err,
 61        var_gct_err_lhs,
 62        var_gct_err_rhs,
 63        rank_in,
 64        a_logq,
 65        b_logq,
 66    );
 67    noise = noise.sqrt();
 68    noise.log2().min(-1.0).max(-(a_logq as f64)) // max noise is [-2^{-1}, 2^{-1}]
 69}
 70
 71#[allow(clippy::too_many_arguments)]
 72#[allow(dead_code)]
 73pub(crate) fn noise_ggsw_product(
 74    n: f64,
 75    base2k: usize,
 76    var_xs: f64,
 77    var_msg: f64,
 78    var_a0_err: f64,
 79    var_a1_err: f64,
 80    var_gct_err_lhs: f64,
 81    var_gct_err_rhs: f64,
 82    rank: f64,
 83    k_in: usize,
 84    k_ggsw: usize,
 85) -> f64 {
 86    let a_logq: usize = k_in.min(k_ggsw);
 87    let a_cols: usize = a_logq.div_ceil(base2k);
 88
 89    let b_scale: f64 = (k_ggsw as f64).exp2();
 90    let a_scale: f64 = ((k_ggsw - a_logq) as f64).exp2();
 91
 92    let base: f64 = (base2k as f64).exp2();
 93    let var_base: f64 = base * base / 12f64;
 94
 95    // lhs = a_cols * n * (var_base * var_gct_err_lhs + var_e_a * var_msg * p^2)
 96    // rhs = a_cols * n * var_base * var_gct_err_rhs * var_xs
 97    let mut noise: f64 = (rank + 1.0) * (a_cols as f64) * n * var_base * (var_gct_err_lhs + var_xs * var_gct_err_rhs);
 98    noise += var_msg * var_a0_err * a_scale * a_scale * n;
 99    noise += var_msg * var_a1_err * a_scale * a_scale * n * var_xs * rank;
100    noise = noise.sqrt();
101    noise /= b_scale;
102    noise.log2().min(-1.0) // max noise is [-2^{-1}, 2^{-1}]
103}
104
105#[allow(clippy::too_many_arguments)]
106#[allow(dead_code)]
107pub(crate) fn noise_ggsw_keyswitch(
108    n: f64,
109    base2k: usize,
110    col: usize,
111    var_xs: f64,
112    var_a_err: f64,
113    var_gct_err_lhs: f64,
114    var_gct_err_rhs: f64,
115    rank: f64,
116    k_ct: usize,
117    k_ksk: usize,
118    k_tsk: usize,
119) -> f64 {
120    let var_si_x_sj: f64 = n * var_xs * var_xs;
121
122    // Initial KS for col = 0
123    let mut noise: f64 = var_noise_gglwe_product(
124        n,
125        base2k,
126        var_xs,
127        var_xs,
128        var_a_err,
129        var_gct_err_lhs,
130        var_gct_err_rhs,
131        rank,
132        k_ct,
133        k_ksk,
134    );
135
136    // Other GGSW reconstruction for col > 0
137    if col > 0 {
138        noise += var_noise_gglwe_product(
139            n,
140            base2k,
141            var_xs,
142            var_si_x_sj,
143            var_a_err + 1f64 / 12.0,
144            var_gct_err_lhs,
145            var_gct_err_rhs,
146            rank,
147            k_ct,
148            k_tsk,
149        );
150        noise += n * noise * var_xs * 0.5;
151    }
152
153    noise = noise.sqrt();
154    noise.log2().min(-1.0) // max noise is [-2^{-1}, 2^{-1}]
155}