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