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