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