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