poulpy/poulpy-schemes/benches/circuit_bootstrapping.rs
poulpy-schemes/benches/circuit_bootstrapping.rsRaw
1use std::hint::black_box;
2
3use criterion::{BenchmarkId, Criterion, criterion_group, criterion_main};
4use poulpy_core::{
5 GGSWNoise, GLWEDecrypt, GLWEEncryptSk, GLWEExternalProduct, LWEEncryptSk, ScratchTakeCore,
6 layouts::{
7 Dsize, GGLWEToGGSWKeyLayout, GGSW, GGSWLayout, GGSWPreparedFactory, GLWEAutomorphismKeyLayout, GLWESecret,
8 GLWESecretPreparedFactory, LWE, LWELayout, LWESecret,
9 },
10};
11use poulpy_cpu_avx::FFT64Avx;
12use poulpy_cpu_ref::FFT64Ref;
13use poulpy_hal::{
14 api::{ModuleN, ModuleNew, ScratchOwnedAlloc, ScratchOwnedBorrow, VecZnxRotateInplace},
15 layouts::{Backend, Module, Scratch, ScratchOwned},
16 source::Source,
17};
18use poulpy_schemes::bin_fhe::{
19 blind_rotation::{
20 BlindRotationAlgo, BlindRotationKey, BlindRotationKeyFactory, BlindRotationKeyInfos, BlindRotationKeyLayout, CGGI,
21 },
22 circuit_bootstrapping::{
23 CircuitBootstrappingKey, CircuitBootstrappingKeyEncryptSk, CircuitBootstrappingKeyLayout,
24 CircuitBootstrappingKeyPrepared, CircuitBootstrappingKeyPreparedFactory, CirtuitBootstrappingExecute,
25 },
26};
27
28pub fn benc_circuit_bootstrapping<BE: Backend, BRA: BlindRotationAlgo>(c: &mut Criterion, label: &str)
29where
30 Module<BE>: ModuleNew<BE>
31 + ModuleN
32 + GLWESecretPreparedFactory<BE>
33 + GLWEExternalProduct<BE>
34 + GLWEDecrypt<BE>
35 + LWEEncryptSk<BE>
36 + CircuitBootstrappingKeyEncryptSk<BRA, BE>
37 + CircuitBootstrappingKeyPreparedFactory<BRA, BE>
38 + CirtuitBootstrappingExecute<BRA, BE>
39 + GGSWPreparedFactory<BE>
40 + GGSWNoise<BE>
41 + GLWEEncryptSk<BE>
42 + VecZnxRotateInplace<BE>,
43 BlindRotationKey<Vec<u8>, BRA>: BlindRotationKeyFactory<BRA>, // TODO find a way to remove this bound or move it to CBT KEY
44 ScratchOwned<BE>: ScratchOwnedAlloc<BE> + ScratchOwnedBorrow<BE>,
45 Scratch<BE>: ScratchTakeCore<BE>,
46{
47 let group_name: String = format!("circuit_bootstrapping::{label}");
48
49 let mut group = c.benchmark_group(group_name);
50
51 struct Params {
52 name: String,
53 extension_factor: usize,
54 k_pt: usize,
55 block_size: usize,
56 lwe_infos: LWELayout,
57 ggsw_infos: GGSWLayout,
58 cbt_infos: CircuitBootstrappingKeyLayout,
59 }
60
61 fn runner<BE: Backend, BRA: BlindRotationAlgo>(params: &Params) -> impl FnMut()
62 where
63 Module<BE>: ModuleNew<BE>
64 + ModuleN
65 + GLWESecretPreparedFactory<BE>
66 + GLWEExternalProduct<BE>
67 + GLWEDecrypt<BE>
68 + LWEEncryptSk<BE>
69 + CircuitBootstrappingKeyEncryptSk<BRA, BE>
70 + CircuitBootstrappingKeyPreparedFactory<BRA, BE>
71 + CirtuitBootstrappingExecute<BRA, BE>
72 + GGSWPreparedFactory<BE>
73 + GGSWNoise<BE>
74 + GLWEEncryptSk<BE>
75 + VecZnxRotateInplace<BE>,
76 BlindRotationKey<Vec<u8>, BRA>: BlindRotationKeyFactory<BRA>, /* TODO find a way to remove this bound or move it to CBT KEY */
77 ScratchOwned<BE>: ScratchOwnedAlloc<BE> + ScratchOwnedBorrow<BE>,
78 Scratch<BE>: ScratchTakeCore<BE>,
79 {
80 // Scratch space (4MB)
81 let mut scratch: ScratchOwned<BE> = ScratchOwned::alloc(1 << 22);
82
83 let n_glwe: poulpy_core::layouts::Degree = params.cbt_infos.layout_brk.n_glwe();
84 let n_lwe: poulpy_core::layouts::Degree = params.cbt_infos.layout_brk.n_lwe();
85 let rank: poulpy_core::layouts::Rank = params.cbt_infos.layout_brk.rank;
86
87 let module: Module<BE> = Module::<BE>::new(n_glwe.as_u32() as u64);
88
89 let mut source_xs: Source = Source::new([1u8; 32]);
90 let mut source_xa: Source = Source::new([1u8; 32]);
91 let mut source_xe: Source = Source::new([1u8; 32]);
92
93 let mut sk_lwe: LWESecret<Vec<u8>> = LWESecret::alloc(n_lwe);
94 sk_lwe.fill_binary_block(params.block_size, &mut source_xs);
95 sk_lwe.fill_zero();
96
97 let mut sk_glwe: GLWESecret<Vec<u8>> = GLWESecret::alloc(n_glwe, rank);
98 sk_glwe.fill_ternary_prob(0.5, &mut source_xs);
99
100 let ct_lwe: LWE<Vec<u8>> = LWE::alloc_from_infos(¶ms.lwe_infos);
101
102 // Circuit bootstrapping evaluation key
103 let mut cbt_key: CircuitBootstrappingKey<Vec<u8>, BRA> = CircuitBootstrappingKey::alloc_from_infos(¶ms.cbt_infos);
104 cbt_key.encrypt_sk(
105 &module,
106 &sk_lwe,
107 &sk_glwe,
108 &mut source_xa,
109 &mut source_xe,
110 scratch.borrow(),
111 );
112
113 let mut res: GGSW<Vec<u8>> = GGSW::alloc_from_infos(¶ms.ggsw_infos);
114 let mut cbt_prepared: CircuitBootstrappingKeyPrepared<Vec<u8>, BRA, BE> =
115 CircuitBootstrappingKeyPrepared::alloc_from_infos(&module, ¶ms.cbt_infos);
116 cbt_prepared.prepare(&module, &cbt_key, scratch.borrow());
117 move || {
118 cbt_prepared.execute_to_constant(
119 &module,
120 &mut res,
121 &ct_lwe,
122 params.k_pt,
123 params.extension_factor,
124 scratch.borrow(),
125 );
126 black_box(());
127 }
128 }
129
130 for params in [Params {
131 name: String::from("1-bit"),
132 extension_factor: 1,
133 k_pt: 1,
134 lwe_infos: LWELayout {
135 n: 574_u32.into(),
136 k: 13_u32.into(),
137 base2k: 13_u32.into(),
138 },
139 block_size: 7,
140 ggsw_infos: GGSWLayout {
141 n: 1024_u32.into(),
142 base2k: 13_u32.into(),
143 k: 26_u32.into(),
144 dnum: 2_u32.into(),
145 dsize: 1_u32.into(),
146 rank: 2_u32.into(),
147 },
148 cbt_infos: CircuitBootstrappingKeyLayout {
149 layout_brk: BlindRotationKeyLayout {
150 n_glwe: 1024_u32.into(),
151 n_lwe: 574_u32.into(),
152 base2k: 13_u32.into(),
153 k: 52_u32.into(),
154 dnum: 3_u32.into(),
155 rank: 2_u32.into(),
156 },
157 layout_atk: GLWEAutomorphismKeyLayout {
158 n: 1024_u32.into(),
159 base2k: 13_u32.into(),
160 k: 52_u32.into(),
161 dnum: 3_u32.into(),
162 dsize: Dsize(1),
163 rank: 2_u32.into(),
164 },
165 layout_tsk: GGLWEToGGSWKeyLayout {
166 n: 1024_u32.into(),
167 base2k: 13_u32.into(),
168 k: 52_u32.into(),
169 dnum: 3_u32.into(),
170 dsize: Dsize(1),
171 rank: 2_u32.into(),
172 },
173 },
174 }] {
175 let id: BenchmarkId = BenchmarkId::from_parameter(params.name.clone());
176 let mut runner = runner::<BE, BRA>(¶ms);
177 group.bench_with_input(id, &(), |b, _| b.iter(&mut runner));
178 }
179
180 group.finish();
181}
182
183fn bench_circuit_bootstrapping_cpu_ref_fft64(c: &mut Criterion) {
184 benc_circuit_bootstrapping::<FFT64Ref, CGGI>(c, "fft64_ref");
185}
186
187fn bench_circuit_bootstrapping_cpu_avx_fft64(c: &mut Criterion) {
188 benc_circuit_bootstrapping::<FFT64Avx, CGGI>(c, "fft64_avx");
189}
190
191criterion_group!(
192 benches,
193 bench_circuit_bootstrapping_cpu_ref_fft64,
194 bench_circuit_bootstrapping_cpu_avx_fft64,
195);
196
197criterion_main!(benches);