poulpy/core/benches/keyswitch_glwe_fft64.rs
core/benches/keyswitch_glwe_fft64.rsRaw
1use backend::{FFT64, Module, ScratchOwned};
2use core::{
3 elem::Infos,
4 glwe_ciphertext::GLWECiphertext,
5 keys::{SecretKey, SecretKeyFourier},
6 keyswitch_key::GLWESwitchingKey,
7};
8use criterion::{BenchmarkId, Criterion, criterion_group, criterion_main};
9use sampling::source::Source;
10use std::hint::black_box;
11
12fn bench_keyswitch_glwe_fft64(c: &mut Criterion) {
13 let mut group = c.benchmark_group("keyswitch_glwe_fft64");
14
15 struct Params {
16 log_n: usize,
17 basek: usize,
18 k_ct_in: usize,
19 k_ct_out: usize,
20 k_ksk: usize,
21 rank_in: usize,
22 rank_out: usize,
23 }
24
25 fn runner(p: Params) -> impl FnMut() {
26 let module: Module<FFT64> = Module::<FFT64>::new(1 << p.log_n);
27
28 let basek: usize = p.basek;
29 let k_rlwe_in: usize = p.k_ct_in;
30 let k_rlwe_out: usize = p.k_ct_out;
31 let k_grlwe: usize = p.k_ksk;
32 let rank_in: usize = p.rank_in;
33 let rank_out: usize = p.rank_out;
34
35 let rows: usize = (p.k_ct_in + p.basek - 1) / p.basek;
36 let sigma: f64 = 3.2;
37
38 let mut ksk: GLWESwitchingKey<Vec<u8>, FFT64> = GLWESwitchingKey::alloc(&module, basek, k_grlwe, rows, rank_in, rank_out);
39 let mut ct_in: GLWECiphertext<Vec<u8>> = GLWECiphertext::alloc(&module, basek, k_rlwe_in, rank_in);
40 let mut ct_out: GLWECiphertext<Vec<u8>> = GLWECiphertext::alloc(&module, basek, k_rlwe_out, rank_out);
41
42 let mut scratch = ScratchOwned::new(
43 GLWESwitchingKey::encrypt_sk_scratch_space(&module, basek, ksk.k(), rank_out)
44 | GLWECiphertext::encrypt_sk_scratch_space(&module, basek, ct_in.k())
45 | GLWECiphertext::keyswitch_scratch_space(
46 &module,
47 basek,
48 ct_out.k(),
49 ct_in.k(),
50 ksk.k(),
51 rank_in,
52 rank_out,
53 ),
54 );
55
56 let mut source_xs = Source::new([0u8; 32]);
57 let mut source_xe = Source::new([0u8; 32]);
58 let mut source_xa = Source::new([0u8; 32]);
59
60 let mut sk_in: SecretKey<Vec<u8>> = SecretKey::alloc(&module, rank_in);
61 sk_in.fill_ternary_prob(0.5, &mut source_xs);
62 let mut sk_in_dft: SecretKeyFourier<Vec<u8>, FFT64> = SecretKeyFourier::alloc(&module, rank_in);
63 sk_in_dft.dft(&module, &sk_in);
64
65 let mut sk_out: SecretKey<Vec<u8>> = SecretKey::alloc(&module, rank_out);
66 sk_out.fill_ternary_prob(0.5, &mut source_xs);
67 let mut sk_out_dft: SecretKeyFourier<Vec<u8>, FFT64> = SecretKeyFourier::alloc(&module, rank_out);
68 sk_out_dft.dft(&module, &sk_out);
69
70 ksk.generate_from_sk(
71 &module,
72 &sk_in,
73 &sk_out_dft,
74 &mut source_xa,
75 &mut source_xe,
76 sigma,
77 scratch.borrow(),
78 );
79
80 ct_in.encrypt_zero_sk(
81 &module,
82 &sk_in_dft,
83 &mut source_xa,
84 &mut source_xe,
85 sigma,
86 scratch.borrow(),
87 );
88
89 move || {
90 ct_out.keyswitch(
91 black_box(&module),
92 black_box(&ct_in),
93 black_box(&ksk),
94 black_box(scratch.borrow()),
95 );
96 }
97 }
98
99 let params_set: Vec<Params> = vec![Params {
100 log_n: 16,
101 basek: 50,
102 k_ct_in: 1250,
103 k_ct_out: 1250,
104 k_ksk: 1250 + 66,
105 rank_in: 1,
106 rank_out: 1,
107 }];
108
109 for params in params_set {
110 let id = BenchmarkId::new("KEYSWITCH_GLWE_FFT64", "");
111 let mut runner = runner(params);
112 group.bench_with_input(id, &(), |b, _| b.iter(&mut runner));
113 }
114
115 group.finish();
116}
117
118fn bench_keyswitch_glwe_inplace_fft64(c: &mut Criterion) {
119 let mut group = c.benchmark_group("keyswitch_glwe_inplace_fft64");
120
121 struct Params {
122 log_n: usize,
123 basek: usize,
124 k_ct: usize,
125 k_ksk: usize,
126 rank: usize,
127 }
128
129 fn runner(p: Params) -> impl FnMut() {
130 let module: Module<FFT64> = Module::<FFT64>::new(1 << p.log_n);
131
132 let basek: usize = p.basek;
133 let k_ct: usize = p.k_ct;
134 let k_ksk: usize = p.k_ksk;
135 let rank: usize = p.rank;
136
137 let rows: usize = (p.k_ct + p.basek - 1) / p.basek;
138 let sigma: f64 = 3.2;
139
140 let mut ksk: GLWESwitchingKey<Vec<u8>, FFT64> = GLWESwitchingKey::alloc(&module, basek, k_ksk, rows, rank, rank);
141 let mut ct: GLWECiphertext<Vec<u8>> = GLWECiphertext::alloc(&module, basek, k_ct, rank);
142
143 let mut scratch = ScratchOwned::new(
144 GLWESwitchingKey::encrypt_sk_scratch_space(&module, basek, ksk.k(), rank)
145 | GLWECiphertext::encrypt_sk_scratch_space(&module, basek, ct.k())
146 | GLWECiphertext::keyswitch_inplace_scratch_space(&module, basek, ct.k(), rank, ksk.k()),
147 );
148
149 let mut source_xs: Source = Source::new([0u8; 32]);
150 let mut source_xe: Source = Source::new([0u8; 32]);
151 let mut source_xa: Source = Source::new([0u8; 32]);
152
153 let mut sk_in: SecretKey<Vec<u8>> = SecretKey::alloc(&module, rank);
154 sk_in.fill_ternary_prob(0.5, &mut source_xs);
155 let mut sk_in_dft: SecretKeyFourier<Vec<u8>, FFT64> = SecretKeyFourier::alloc(&module, rank);
156 sk_in_dft.dft(&module, &sk_in);
157
158 let mut sk_out: SecretKey<Vec<u8>> = SecretKey::alloc(&module, rank);
159 sk_out.fill_ternary_prob(0.5, &mut source_xs);
160 let mut sk_out_dft: SecretKeyFourier<Vec<u8>, FFT64> = SecretKeyFourier::alloc(&module, rank);
161 sk_out_dft.dft(&module, &sk_out);
162
163 ksk.generate_from_sk(
164 &module,
165 &sk_in,
166 &sk_out_dft,
167 &mut source_xa,
168 &mut source_xe,
169 sigma,
170 scratch.borrow(),
171 );
172
173 ct.encrypt_zero_sk(
174 &module,
175 &sk_in_dft,
176 &mut source_xa,
177 &mut source_xe,
178 sigma,
179 scratch.borrow(),
180 );
181
182 move || {
183 ct.keyswitch_inplace(
184 black_box(&module),
185 black_box(&ksk),
186 black_box(scratch.borrow()),
187 );
188 }
189 }
190
191 let params_set: Vec<Params> = vec![Params {
192 log_n: 9,
193 basek: 18,
194 k_ct: 27,
195 k_ksk: 27,
196 rank: 1,
197 }];
198
199 for params in params_set {
200 let id = BenchmarkId::new("KEYSWITCH_GLWE_INPLACE_FFT64", "");
201 let mut runner = runner(params);
202 group.bench_with_input(id, &(), |b, _| b.iter(&mut runner));
203 }
204
205 group.finish();
206}
207
208criterion_group!(
209 benches,
210 bench_keyswitch_glwe_fft64,
211 bench_keyswitch_glwe_inplace_fft64
212);
213criterion_main!(benches);