arnaucube
arnaucube/poulpyPublic Self-hosted repository
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, &params.glwe_layout);
116        sk_glwe_prepared.prepare(&module, &sk_glwe);
117
118        let mut bdd_key: BDDKey<Vec<u8>, BRA> = BDDKey::alloc_from_infos(&params.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(&params.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, &params.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, &params.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>(&params);
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);