poulpy/poulpy-schemes/benches/bdd_prepare.rs
poulpy-schemes/benches/bdd_prepare.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 Base2K, Degree, Dnum, Dsize, GGLWEToGGSWKeyLayout, GGSWLayout, GGSWPreparedFactory, GLWEAutomorphismKeyLayout,
8 GLWELayout, GLWESecret, GLWESecretPrepared, GLWESecretPreparedFactory, GLWESwitchingKeyLayout, GLWEToLWEKeyLayout,
9 LWESecret, Rank, TorusPrecision,
10 },
11};
12
13#[cfg(all(feature = "enable-avx", target_arch = "x86_64"))]
14pub use poulpy_cpu_avx::FFT64Avx as BackendImpl;
15
16#[cfg(not(all(feature = "enable-avx", target_arch = "x86_64")))]
17pub use poulpy_cpu_ref::FFT64Ref as BackendImpl;
18
19use poulpy_hal::{
20 api::{ModuleN, ModuleNew, ScratchOwnedAlloc, ScratchOwnedBorrow, VecZnxRotateInplace},
21 layouts::{Backend, Module, Scratch, ScratchOwned},
22 source::Source,
23};
24use poulpy_schemes::bin_fhe::{
25 bdd_arithmetic::{
26 BDDKey, BDDKeyEncryptSk, BDDKeyLayout, BDDKeyPrepared, BDDKeyPreparedFactory, ExecuteBDDCircuit2WTo1W, FheUint,
27 FheUintPrepare, FheUintPrepared,
28 },
29 blind_rotation::{
30 BlindRotationAlgo, BlindRotationKey, BlindRotationKeyFactory, BlindRotationKeyInfos, BlindRotationKeyLayout, CGGI,
31 },
32 circuit_bootstrapping::{
33 CircuitBootstrappingKeyEncryptSk, CircuitBootstrappingKeyLayout, CircuitBootstrappingKeyPreparedFactory,
34 CirtuitBootstrappingExecute,
35 },
36};
37
38pub fn benc_bdd_prepare<BE: Backend, BRA: BlindRotationAlgo>(c: &mut Criterion, label: &str)
39where
40 Module<BE>: ModuleNew<BE>
41 + ModuleN
42 + GLWESecretPreparedFactory<BE>
43 + GLWEExternalProduct<BE>
44 + GLWEDecrypt<BE>
45 + LWEEncryptSk<BE>
46 + CircuitBootstrappingKeyEncryptSk<BRA, BE>
47 + CircuitBootstrappingKeyPreparedFactory<BRA, BE>
48 + CirtuitBootstrappingExecute<BRA, BE>
49 + GGSWPreparedFactory<BE>
50 + GGSWNoise<BE>
51 + GLWEEncryptSk<BE>
52 + VecZnxRotateInplace<BE>
53 + BDDKeyEncryptSk<BRA, BE>
54 + BDDKeyPreparedFactory<BRA, BE>
55 + FheUintPrepare<BRA, BE>
56 + ExecuteBDDCircuit2WTo1W<BE>,
57 BlindRotationKey<Vec<u8>, BRA>: BlindRotationKeyFactory<BRA>, // TODO find a way to remove this bound or move it to CBT KEY
58 ScratchOwned<BE>: ScratchOwnedAlloc<BE> + ScratchOwnedBorrow<BE>,
59 Scratch<BE>: ScratchTakeCore<BE>,
60{
61 let group_name: String = format!("bdd_arithmetic::{label}");
62
63 let mut group = c.benchmark_group(group_name);
64
65 struct Params {
66 name: String,
67 block_size: usize,
68 glwe_layout: GLWELayout,
69 ggsw_layout: GGSWLayout,
70 bdd_layout: BDDKeyLayout,
71 }
72
73 fn runner<BE: Backend, BRA: BlindRotationAlgo>(params: &Params) -> impl FnMut()
74 where
75 Module<BE>: ModuleNew<BE>
76 + ModuleN
77 + GLWESecretPreparedFactory<BE>
78 + GLWEExternalProduct<BE>
79 + GLWEDecrypt<BE>
80 + LWEEncryptSk<BE>
81 + CircuitBootstrappingKeyEncryptSk<BRA, BE>
82 + CircuitBootstrappingKeyPreparedFactory<BRA, BE>
83 + CirtuitBootstrappingExecute<BRA, BE>
84 + GGSWPreparedFactory<BE>
85 + GGSWNoise<BE>
86 + GLWEEncryptSk<BE>
87 + VecZnxRotateInplace<BE>
88 + BDDKeyEncryptSk<BRA, BE>
89 + BDDKeyPreparedFactory<BRA, BE>
90 + FheUintPrepare<BRA, BE>
91 + ExecuteBDDCircuit2WTo1W<BE>,
92 BlindRotationKey<Vec<u8>, BRA>: BlindRotationKeyFactory<BRA>, /* TODO find a way to remove this bound or move it to CBT KEY */
93 ScratchOwned<BE>: ScratchOwnedAlloc<BE> + ScratchOwnedBorrow<BE>,
94 Scratch<BE>: ScratchTakeCore<BE>,
95 {
96 // Scratch space (4MB)
97 let mut scratch: ScratchOwned<BE> = ScratchOwned::alloc(1 << 25);
98
99 let n_glwe: poulpy_core::layouts::Degree = params.bdd_layout.cbt_layout.brk_layout.n_glwe();
100 let n_lwe: poulpy_core::layouts::Degree = params.bdd_layout.cbt_layout.brk_layout.n_lwe();
101 let rank: poulpy_core::layouts::Rank = params.bdd_layout.cbt_layout.brk_layout.rank;
102
103 let module: Module<BE> = Module::<BE>::new(n_glwe.as_u32() as u64);
104
105 let mut source_xs: Source = Source::new([1u8; 32]);
106 let mut source_xa: Source = Source::new([1u8; 32]);
107 let mut source_xe: Source = Source::new([1u8; 32]);
108
109 let mut sk_lwe: LWESecret<Vec<u8>> = LWESecret::alloc(n_lwe);
110 sk_lwe.fill_binary_block(params.block_size, &mut source_xs);
111
112 let mut sk_glwe: GLWESecret<Vec<u8>> = GLWESecret::alloc(n_glwe, rank);
113 sk_glwe.fill_ternary_prob(0.5, &mut source_xs);
114
115 let mut sk_glwe_prepared = GLWESecretPrepared::alloc_from_infos(&module, ¶ms.glwe_layout);
116 sk_glwe_prepared.prepare(&module, &sk_glwe);
117
118 let mut bdd_key: BDDKey<Vec<u8>, BRA> = BDDKey::alloc_from_infos(¶ms.bdd_layout);
119 bdd_key.encrypt_sk(
120 &module,
121 &sk_lwe,
122 &sk_glwe,
123 &mut source_xa,
124 &mut source_xe,
125 scratch.borrow(),
126 );
127
128 let input_a = 255_u32;
129
130 let mut a_enc: FheUint<Vec<u8>, u32> = FheUint::alloc_from_infos(¶ms.glwe_layout);
131 a_enc.encrypt_sk(
132 &module,
133 input_a,
134 &sk_glwe_prepared,
135 &mut source_xa,
136 &mut source_xe,
137 scratch.borrow(),
138 );
139
140 let mut bdd_key_prepared: BDDKeyPrepared<Vec<u8>, BRA, BE> =
141 BDDKeyPrepared::alloc_from_infos(&module, ¶ms.bdd_layout);
142 bdd_key_prepared.prepare(&module, &bdd_key, scratch.borrow());
143
144 let mut a_enc_prepared: FheUintPrepared<Vec<u8>, u32, BE> =
145 FheUintPrepared::alloc_from_infos(&module, ¶ms.ggsw_layout);
146
147 move || {
148 a_enc_prepared.prepare(&module, &a_enc, &bdd_key_prepared, scratch.borrow());
149 black_box(());
150 }
151 }
152
153 const N_GLWE: u32 = 1024;
154 const N_LWE: u32 = 679;
155 const BINARY_BLOCK_SIZE: u32 = 7;
156 const BASE2K: u32 = 15;
157 const RANK: u32 = 2;
158
159 let params: Params = Params {
160 name: String::from(format!("n_glwe={N_GLWE}")),
161 block_size: BINARY_BLOCK_SIZE as usize,
162 glwe_layout: GLWELayout {
163 n: Degree(N_GLWE),
164 base2k: Base2K(BASE2K),
165 k: TorusPrecision(2 * BASE2K),
166 rank: Rank(RANK),
167 },
168 ggsw_layout: GGSWLayout {
169 n: Degree(N_GLWE),
170 base2k: Base2K(BASE2K),
171 k: TorusPrecision(3 * BASE2K),
172 rank: Rank(RANK),
173 dnum: Dnum(3),
174 dsize: Dsize(1),
175 },
176 bdd_layout: BDDKeyLayout {
177 cbt_layout: CircuitBootstrappingKeyLayout {
178 brk_layout: BlindRotationKeyLayout {
179 n_glwe: Degree(N_GLWE),
180 n_lwe: Degree(N_LWE),
181 base2k: Base2K(BASE2K),
182 k: TorusPrecision(4 * BASE2K),
183 dnum: Dnum(4),
184 rank: Rank(RANK),
185 },
186 atk_layout: GLWEAutomorphismKeyLayout {
187 n: Degree(N_GLWE),
188 base2k: Base2K(BASE2K),
189 k: TorusPrecision(4 * BASE2K),
190 dnum: Dnum(4),
191 dsize: Dsize(1),
192 rank: Rank(RANK),
193 },
194 tsk_layout: GGLWEToGGSWKeyLayout {
195 n: Degree(N_GLWE),
196 base2k: Base2K(BASE2K),
197 k: TorusPrecision(4 * BASE2K),
198 dnum: Dnum(4),
199 dsize: Dsize(1),
200 rank: Rank(RANK),
201 },
202 },
203 ks_glwe_layout: Some(GLWESwitchingKeyLayout {
204 n: Degree(N_GLWE),
205 base2k: Base2K(BASE2K),
206 k: TorusPrecision(4 * BASE2K),
207 dnum: Dnum(4),
208 dsize: Dsize(1),
209 rank_in: Rank(RANK),
210 rank_out: Rank(1),
211 }),
212 ks_lwe_layout: GLWEToLWEKeyLayout {
213 n: Degree(N_GLWE),
214 base2k: Base2K(BASE2K),
215 k: TorusPrecision(4 * BASE2K),
216 rank_in: Rank(1),
217 dnum: Dnum(4),
218 },
219 },
220 };
221
222 let id: BenchmarkId = BenchmarkId::from_parameter(params.name.clone());
223 let mut runner = runner::<BE, BRA>(¶ms);
224 group.bench_with_input(id, &(), |b, _| b.iter(&mut runner));
225
226 group.finish();
227}
228
229fn bench_bdd_prepare_fft64(c: &mut Criterion) {
230 #[cfg(all(feature = "enable-avx", target_arch = "x86_64"))]
231 let label = "fft64_avx";
232 #[cfg(not(all(feature = "enable-avx", target_arch = "x86_64")))]
233 let label = "fft64_ref";
234 benc_bdd_prepare::<BackendImpl, CGGI>(c, label);
235}
236
237criterion_group!(benches, bench_bdd_prepare_fft64);
238criterion_main!(benches);