arnaucube
arnaucube/poulpyPublic Self-hosted repository
poulpy/rlwe/examples/gadget_product.rs
rlwe/examples/gadget_product.rsRaw
  1use base2k::{FFT64, Infos, Sampling, Scalar, SvpPPolOps, VecZnx, VecZnxBig, VecZnxDft, VecZnxOps};
  2use rlwe::{
  3    ciphertext::{Ciphertext, GadgetCiphertext},
  4    decryptor::{Decryptor, decrypt_rlwe_thread_safe, decrypt_rlwe_thread_safe_tmp_byte},
  5    elem::Elem,
  6    encryptor::{
  7        EncryptorSk, encrypt_grlwe_sk_thread_safe, encrypt_grlwe_sk_tmp_bytes,
  8        encrypt_rlwe_sk_tmp_bytes,
  9    },
 10    evaluator::{gadget_product_thread_safe, gadget_product_tmp_bytes},
 11    key_generator::{gen_switching_key_thread_safe, gen_switching_key_thread_safe_tmp_bytes},
 12    keys::{SecretKey, SwitchingKey},
 13    parameters::{Parameters, ParametersLiteral},
 14    plaintext::Plaintext,
 15};
 16use sampling::source::{Source, new_seed};
 17
 18fn main() {
 19    let params_lit: ParametersLiteral = ParametersLiteral {
 20        log_n: 10,
 21        log_q: 68,
 22        log_p: 17,
 23        log_base2k: 17,
 24        log_scale: 20,
 25        xe: 3.2,
 26        xs: 128,
 27    };
 28
 29    let params: Parameters = Parameters::new::<FFT64>(&params_lit);
 30
 31    let mut tmp_bytes: Vec<u8> = vec![
 32        0u8;
 33        params.decrypt_rlwe_thread_safe_tmp_byte(params.log_q())
 34            | params.encrypt_rlwe_sk_tmp_bytes(params.log_q())
 35            | gen_switching_key_thread_safe_tmp_bytes(
 36                params.module(),
 37                params.log_base2k(),
 38                params.limbs_q(),
 39                params.log_q()
 40            )
 41            | gadget_product_tmp_bytes(
 42                params.module(),
 43                params.log_base2k(),
 44                params.log_q(),
 45                params.log_q(),
 46                params.limbs_q(),
 47                params.log_qp()
 48            )
 49            | encrypt_grlwe_sk_tmp_bytes(
 50                params.module(),
 51                params.log_base2k(),
 52                params.limbs_qp(),
 53                params.log_qp()
 54            )
 55    ];
 56
 57    let mut source: Source = Source::new([3; 32]);
 58
 59    let mut sk: SecretKey = SecretKey::new(params.module());
 60
 61    sk.fill_ternary_hw(params.xs(), &mut source);
 62
 63    let mut want = vec![i64::default(); params.n()];
 64
 65    want.iter_mut().enumerate().for_each(|(i, x)| *x = i as i64);
 66
 67    let log_base2k = params.log_base2k();
 68
 69    let log_k: usize = params.log_q() - 2 * log_base2k;
 70
 71    let mut source_xe: Source = Source::new([4; 32]);
 72    let mut source_xa: Source = Source::new([5; 32]);
 73
 74    let mut sk_svp_ppol: base2k::SvpPPol = params.module().new_svp_ppol();
 75    params.module().svp_prepare(&mut sk_svp_ppol, &sk.0);
 76
 77    let mut gadget_ct: GadgetCiphertext = GadgetCiphertext::new(
 78        params.module(),
 79        log_base2k,
 80        params.limbs_q(),
 81        params.log_qp(),
 82    );
 83
 84    let mut m: Scalar = Scalar::new(params.n());
 85    m.fill_ternary_prob(0.5, &mut source_xa);
 86
 87    encrypt_grlwe_sk_thread_safe(
 88        params.module(),
 89        &mut gadget_ct,
 90        &m,
 91        &sk_svp_ppol,
 92        &mut source_xa,
 93        &mut source_xe,
 94        params.xe(),
 95        &mut tmp_bytes,
 96    );
 97
 98    let mut res: Elem = Elem::new(params.module(), log_base2k, params.log_q(), 1, 0);
 99    let mut a: VecZnx = VecZnx::new(params.module().n(), params.limbs_q());
100    a.fill_uniform(params.log_base2k(), a.limbs(), &mut source_xa);
101    gadget_product_thread_safe(params.module(), &mut res, &a, &gadget_ct, &mut tmp_bytes);
102
103    println!("a.limbs()={}", a.limbs());
104    println!("gadget_ct.rows()={}", gadget_ct.rows());
105    println!("gadget_ct.cols()={}", gadget_ct.cols());
106    println!("res.limbs()={}", res.limbs());
107    println!();
108
109    println!("a:");
110    a.print_limbs(a.limbs(), 16);
111    println!();
112
113    println!("m:");
114    println!("{:?}", &m.0[..16]);
115    println!();
116
117    let mut a_res: Elem = Elem::new(params.module(), params.log_base2k(), params.log_q(), 0, 0);
118
119    decrypt_rlwe_thread_safe(
120        params.module(),
121        &mut a_res,
122        &res,
123        &sk_svp_ppol,
124        &mut tmp_bytes,
125    );
126
127    let mut m_svp_ppol = params.module().new_svp_ppol();
128    params.module().svp_prepare(&mut m_svp_ppol, &m);
129
130    let mut a_dft: VecZnxDft = params.module().new_vec_znx_dft(a.limbs());
131    let mut a_big: VecZnxBig = a_dft.as_vec_znx_big();
132
133    params
134        .module()
135        .svp_apply_dft(&mut a_dft, &m_svp_ppol, &a, a.limbs());
136    params
137        .module()
138        .vec_znx_idft_tmp_a(&mut a_big, &mut a_dft, a.limbs());
139    params
140        .module()
141        .vec_znx_big_normalize(params.log_base2k(), &mut a, &a_big, &mut tmp_bytes);
142
143    params.module().vec_znx_sub_inplace(&mut a, &a_res.value[0]);
144
145    println!("a*m - dec(a * GRLWE(m))");
146    a.print_limbs(a.limbs(), 16);
147}