poulpy/poulpy-core/benches/external_product_glwe_fft64.rs
poulpy-core/benches/external_product_glwe_fft64.rsRaw
1use poulpy_core::layouts::{
2 GGSWCiphertext, GLWECiphertext, GLWESecret, Infos,
3 prepared::{GGSWCiphertextPrepared, GLWESecretPrepared, PrepareAlloc},
4};
5use std::hint::black_box;
6
7use criterion::{BenchmarkId, Criterion, criterion_group, criterion_main};
8
9use poulpy_backend::cpu_spqlios::FFT64;
10use poulpy_hal::{
11 api::{ModuleNew, ScratchOwnedAlloc, ScratchOwnedBorrow},
12 layouts::{Module, ScalarZnx, ScratchOwned},
13 source::Source,
14};
15
16fn bench_external_product_glwe_fft64(c: &mut Criterion) {
17 let mut group = c.benchmark_group("external_product_glwe_fft64");
18
19 struct Params {
20 log_n: usize,
21 basek: usize,
22 k_ct_in: usize,
23 k_ct_out: usize,
24 k_ggsw: usize,
25 rank: usize,
26 }
27
28 fn runner(p: Params) -> impl FnMut() {
29 let module: Module<FFT64> = Module::<FFT64>::new(1 << p.log_n);
30
31 let n: usize = module.n();
32 let basek: usize = p.basek;
33 let k_ct_in: usize = p.k_ct_in;
34 let k_ct_out: usize = p.k_ct_out;
35 let k_ggsw: usize = p.k_ggsw;
36 let rank: usize = p.rank;
37 let digits: usize = 1;
38
39 let rows: usize = 1; //(p.k_ct_in.div_ceil(p.basek);
40
41 let mut ct_ggsw: GGSWCiphertext<Vec<u8>> = GGSWCiphertext::alloc(n, basek, k_ggsw, rows, digits, rank);
42 let mut ct_glwe_in: GLWECiphertext<Vec<u8>> = GLWECiphertext::alloc(n, basek, k_ct_in, rank);
43 let mut ct_glwe_out: GLWECiphertext<Vec<u8>> = GLWECiphertext::alloc(n, basek, k_ct_out, rank);
44 let pt_rgsw: ScalarZnx<Vec<u8>> = ScalarZnx::alloc(n, 1);
45
46 let mut scratch: ScratchOwned<FFT64> = ScratchOwned::alloc(
47 GGSWCiphertext::encrypt_sk_scratch_space(&module, n, basek, ct_ggsw.k(), rank)
48 | GLWECiphertext::encrypt_sk_scratch_space(&module, n, basek, ct_glwe_in.k())
49 | GLWECiphertext::external_product_scratch_space(
50 &module,
51 n,
52 basek,
53 ct_glwe_out.k(),
54 ct_glwe_in.k(),
55 ct_ggsw.k(),
56 digits,
57 rank,
58 ),
59 );
60
61 let mut source_xs = Source::new([0u8; 32]);
62 let mut source_xe = Source::new([0u8; 32]);
63 let mut source_xa = Source::new([0u8; 32]);
64
65 let mut sk: GLWESecret<Vec<u8>> = GLWESecret::alloc(n, rank);
66 sk.fill_ternary_prob(0.5, &mut source_xs);
67 let sk_dft: GLWESecretPrepared<Vec<u8>, FFT64> = sk.prepare_alloc(&module, scratch.borrow());
68
69 ct_ggsw.encrypt_sk(
70 &module,
71 &pt_rgsw,
72 &sk_dft,
73 &mut source_xa,
74 &mut source_xe,
75 scratch.borrow(),
76 );
77
78 ct_glwe_in.encrypt_zero_sk(
79 &module,
80 &sk_dft,
81 &mut source_xa,
82 &mut source_xe,
83 scratch.borrow(),
84 );
85
86 let ggsw_prepared: GGSWCiphertextPrepared<Vec<u8>, FFT64> = ct_ggsw.prepare_alloc(&module, scratch.borrow());
87
88 move || {
89 ct_glwe_out.external_product(&module, &ct_glwe_in, &ggsw_prepared, scratch.borrow());
90 black_box(());
91 }
92 }
93
94 let params_set: Vec<Params> = vec![Params {
95 log_n: 11,
96 basek: 22,
97 k_ct_in: 44,
98 k_ct_out: 44,
99 k_ggsw: 54,
100 rank: 1,
101 }];
102
103 for params in params_set {
104 let id = BenchmarkId::new("EXTERNAL_PRODUCT_GLWE_FFT64", "");
105 let mut runner = runner(params);
106 group.bench_with_input(id, &(), |b, _| b.iter(&mut runner));
107 }
108
109 group.finish();
110}
111
112fn bench_external_product_glwe_inplace_fft64(c: &mut Criterion) {
113 let mut group = c.benchmark_group("external_product_glwe_inplace_fft64");
114
115 struct Params {
116 log_n: usize,
117 basek: usize,
118 k_ct: usize,
119 k_ggsw: usize,
120 rank: usize,
121 }
122
123 fn runner(p: Params) -> impl FnMut() {
124 let module: Module<FFT64> = Module::<FFT64>::new(1 << p.log_n);
125
126 let n = module.n();
127 let basek: usize = p.basek;
128 let k_glwe: usize = p.k_ct;
129 let k_ggsw: usize = p.k_ggsw;
130 let rank: usize = p.rank;
131 let digits: usize = 1;
132
133 let rows: usize = p.k_ct.div_ceil(p.basek);
134
135 let mut ct_ggsw: GGSWCiphertext<Vec<u8>> = GGSWCiphertext::alloc(n, basek, k_ggsw, rows, digits, rank);
136 let mut ct_glwe: GLWECiphertext<Vec<u8>> = GLWECiphertext::alloc(n, basek, k_glwe, rank);
137 let pt_rgsw: ScalarZnx<Vec<u8>> = ScalarZnx::alloc(n, 1);
138
139 let mut scratch: ScratchOwned<FFT64> = ScratchOwned::alloc(
140 GGSWCiphertext::encrypt_sk_scratch_space(&module, n, basek, ct_ggsw.k(), rank)
141 | GLWECiphertext::encrypt_sk_scratch_space(&module, n, basek, ct_glwe.k())
142 | GLWECiphertext::external_product_inplace_scratch_space(
143 &module,
144 n,
145 basek,
146 ct_glwe.k(),
147 ct_ggsw.k(),
148 digits,
149 rank,
150 ),
151 );
152
153 let mut source_xs = Source::new([0u8; 32]);
154 let mut source_xe = Source::new([0u8; 32]);
155 let mut source_xa = Source::new([0u8; 32]);
156
157 let mut sk: GLWESecret<Vec<u8>> = GLWESecret::alloc(n, rank);
158 sk.fill_ternary_prob(0.5, &mut source_xs);
159 let sk_dft: GLWESecretPrepared<Vec<u8>, FFT64> = sk.prepare_alloc(&module, scratch.borrow());
160
161 ct_ggsw.encrypt_sk(
162 &module,
163 &pt_rgsw,
164 &sk_dft,
165 &mut source_xa,
166 &mut source_xe,
167 scratch.borrow(),
168 );
169
170 ct_glwe.encrypt_zero_sk(
171 &module,
172 &sk_dft,
173 &mut source_xa,
174 &mut source_xe,
175 scratch.borrow(),
176 );
177
178 let ggsw_prepared: GGSWCiphertextPrepared<Vec<u8>, FFT64> = ct_ggsw.prepare_alloc(&module, scratch.borrow());
179
180 move || {
181 let scratch_borrow = scratch.borrow();
182 ct_glwe.external_product_inplace(&module, &ggsw_prepared, scratch_borrow);
183 black_box(());
184 }
185 }
186
187 let params_set: Vec<Params> = vec![Params {
188 log_n: 12,
189 basek: 18,
190 k_ct: 54,
191 k_ggsw: 54,
192 rank: 1,
193 }];
194
195 for params in params_set {
196 let id = BenchmarkId::new("EXTERNAL_PRODUCT_GLWE_INPLACE_FFT64", "");
197 let mut runner = runner(params);
198 group.bench_with_input(id, &(), |b, _| b.iter(&mut runner));
199 }
200
201 group.finish();
202}
203
204criterion_group!(
205 benches,
206 bench_external_product_glwe_fft64,
207 bench_external_product_glwe_inplace_fft64
208);
209criterion_main!(benches);