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