poulpy/rlwe/examples/gadget_product.rs
rlwe/examples/gadget_product.rsRaw
1use base2k::{Encoding, FFT64, SvpPPolOps};
2use rlwe::{
3 ciphertext::Ciphertext,
4 decryptor::{Decryptor, decrypt_rlwe_thread_safe_tmp_byte},
5 encryptor::{EncryptorSk, encrypt_rlwe_sk_tmp_bytes},
6 evaluator::{gadget_product_inplace, gadget_product_tmp_bytes},
7 key_generator::{gen_switching_key_thread_safe, gen_switching_key_thread_safe_tmp_bytes},
8 keys::{SecretKey, SwitchingKey},
9 parameters::{Parameters, ParametersLiteral},
10 plaintext::Plaintext,
11};
12use sampling::source::{Source, new_seed};
13
14fn main() {
15 let params_lit: ParametersLiteral = ParametersLiteral {
16 log_n: 10,
17 log_q: 54,
18 log_p: 17,
19 log_base2k: 17,
20 log_scale: 20,
21 xe: 3.2,
22 xs: 128,
23 };
24
25 let params: Parameters = Parameters::new::<FFT64>(¶ms_lit);
26
27 let mut tmp_bytes: Vec<u8> = vec![
28 0u8;
29 params.decrypt_rlwe_thread_safe_tmp_byte(params.log_q())
30 | params.encrypt_rlwe_sk_tmp_bytes(params.log_q())
31 | gen_switching_key_thread_safe_tmp_bytes(
32 params.module(),
33 params.log_base2k(),
34 params.limbs_q(),
35 params.log_q()
36 )
37 | gadget_product_tmp_bytes(
38 params.module(),
39 params.log_base2k(),
40 params.log_q(),
41 params.log_q(),
42 params.limbs_q(),
43 params.limbs_qp()
44 )
45 ];
46
47 let mut source: Source = Source::new([0; 32]);
48
49 let mut sk0: SecretKey = SecretKey::new(params.module());
50 let mut sk1: SecretKey = SecretKey::new(params.module());
51
52 sk0.fill_ternary_hw(params.xs(), &mut source);
53 sk1.fill_ternary_hw(params.xs(), &mut source);
54
55 let mut want = vec![i64::default(); params.n()];
56
57 want.iter_mut().enumerate().for_each(|(i, x)| *x = i as i64);
58
59 let mut pt: Plaintext = params.new_plaintext(params.log_q());
60
61 let log_base2k = pt.log_base2k();
62
63 let log_k: usize = params.log_q() - 20;
64
65 pt.0.value[0].encode_vec_i64(log_base2k, log_k, &want, 32);
66 pt.0.value[0].normalize(log_base2k, &mut tmp_bytes);
67
68 println!("log_k: {}", log_k);
69 pt.0.value[0].print_limbs(pt.limbs(), 16);
70
71 let mut ct: Ciphertext = params.new_ciphertext(params.log_q());
72
73 let mut source_xe: Source = Source::new([1; 32]);
74 let mut source_xa: Source = Source::new([2; 32]);
75
76 let mut sk0_svp_ppol: base2k::SvpPPol = params.module().new_svp_ppol();
77 params.module().svp_prepare(&mut sk0_svp_ppol, &sk0.0);
78
79 let mut sk1_svp_ppol: base2k::SvpPPol = params.module().new_svp_ppol();
80 params.module().svp_prepare(&mut sk1_svp_ppol, &sk1.0);
81
82 params.encrypt_rlwe_sk_thread_safe(
83 &mut ct,
84 Some(&pt),
85 &sk0_svp_ppol,
86 &mut source_xa,
87 &mut source_xe,
88 &mut tmp_bytes,
89 );
90
91 let mut swk: SwitchingKey = SwitchingKey::new(
92 params.module(),
93 params.log_base2k(),
94 params.limbs_q(),
95 params.log_qp(),
96 );
97
98 gen_switching_key_thread_safe(
99 params.module(),
100 &mut swk,
101 &sk0,
102 &sk1_svp_ppol,
103 &mut source_xa,
104 &mut source_xe,
105 params.xe(),
106 &mut tmp_bytes,
107 );
108
109 gadget_product_inplace(params.module(), &mut ct, &swk.0, &mut tmp_bytes);
110
111 params.decrypt_rlwe_thread_safe(&mut pt, &ct, &sk1_svp_ppol, &mut tmp_bytes);
112
113 pt.0.value[0].print_limbs(pt.limbs(), 16);
114
115 let mut have = vec![i64::default(); params.n()];
116
117 println!("pt: {}", log_k);
118 pt.0.value[0].decode_vec_i64(pt.log_base2k(), log_k, &mut have);
119
120 println!("want: {:?}", &want[..16]);
121 println!("have: {:?}", &have[..16]);
122}