arnaucube
arnaucube/poulpyPublic Self-hosted repository
poulpy/core/src/test_fft64/mod.rs
core/src/test_fft64/mod.rsRaw
  1mod automorphism_key;
  2mod gglwe;
  3mod ggsw;
  4mod glwe_fourier;
  5mod tensor_key;
  6
  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 + basek - 1) / 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
 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
 65pub(crate) fn noise_ggsw_product(
 66    n: f64,
 67    basek: usize,
 68    var_xs: f64,
 69    var_msg: f64,
 70    var_a0_err: f64,
 71    var_a1_err: f64,
 72    var_gct_err_lhs: f64,
 73    var_gct_err_rhs: f64,
 74    rank: f64,
 75    k_in: usize,
 76    k_ggsw: usize,
 77) -> f64 {
 78    let a_logq: usize = k_in.min(k_ggsw);
 79    let a_cols: usize = (a_logq + basek - 1) / basek;
 80
 81    let b_scale: f64 = (k_ggsw as f64).exp2();
 82    let a_scale: f64 = ((k_ggsw - a_logq) as f64).exp2();
 83
 84    let base: f64 = (basek as f64).exp2();
 85    let var_base: f64 = base * base / 12f64;
 86
 87    // lhs = a_cols * n * (var_base * var_gct_err_lhs + var_e_a * var_msg * p^2)
 88    // rhs = a_cols * n * var_base * var_gct_err_rhs * var_xs
 89    let mut noise: f64 = (rank + 1.0) * (a_cols as f64) * n * var_base * (var_gct_err_lhs + var_xs * var_gct_err_rhs);
 90    noise += var_msg * var_a0_err * a_scale * a_scale * n;
 91    noise += var_msg * var_a1_err * a_scale * a_scale * n * var_xs * rank;
 92    noise = noise.sqrt();
 93    noise /= b_scale;
 94    noise.log2().min(-1.0) // max noise is [-2^{-1}, 2^{-1}]
 95}
 96
 97pub(crate) fn noise_ggsw_keyswitch(
 98    n: f64,
 99    basek: usize,
100    col: usize,
101    var_xs: f64,
102    var_a_err: f64,
103    var_gct_err_lhs: f64,
104    var_gct_err_rhs: f64,
105    rank: f64,
106    k_ct: usize,
107    k_ksk: usize,
108    k_tsk: usize,
109) -> f64 {
110    let var_si_x_sj: f64 = n * var_xs * var_xs;
111
112    // Initial KS for col = 0
113    let mut noise: f64 = var_noise_gglwe_product(
114        n,
115        basek,
116        var_xs,
117        var_xs,
118        var_a_err,
119        var_gct_err_lhs,
120        var_gct_err_rhs,
121        rank,
122        k_ct,
123        k_ksk,
124    );
125
126    // Other GGSW reconstruction for col > 0
127    if col > 0 {
128        noise += var_noise_gglwe_product(
129            n,
130            basek,
131            var_xs,
132            var_si_x_sj,
133            var_a_err + 1f64 / 12.0,
134            var_gct_err_lhs,
135            var_gct_err_rhs,
136            rank,
137            k_ct,
138            k_tsk,
139        );
140        noise += n * noise * var_xs * 0.5;
141    }
142
143    noise = noise.sqrt();
144    noise.log2().min(-1.0) // max noise is [-2^{-1}, 2^{-1}]
145}