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