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