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