arnaucube
arnaucube/poulpyPublic Self-hosted repository
poulpy/poulpy-schemes/benches/blind_rotate.rs
poulpy-schemes/benches/blind_rotate.rsRaw
  1use std::hint::black_box;
  2
  3use criterion::{BenchmarkId, Criterion, criterion_group, criterion_main};
  4use poulpy_core::{
  5    GLWEDecrypt, LWEEncryptSk, ScratchTakeCore,
  6    layouts::{
  7        Base2K, Dnum, GLWE, GLWELayout, GLWESecret, GLWESecretPrepared, GLWESecretPreparedFactory, LWE, LWEInfos, LWELayout,
  8        LWESecret, TorusPrecision,
  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},
 20    layouts::{Backend, FillUniform, Module, Scratch, ScratchOwned},
 21    source::Source,
 22};
 23use poulpy_schemes::bin_fhe::blind_rotation::{
 24    BlindRotationAlgo, BlindRotationExecute, BlindRotationKey, BlindRotationKeyEncryptSk, BlindRotationKeyFactory,
 25    BlindRotationKeyLayout, BlindRotationKeyPrepared, BlindRotationKeyPreparedFactory, CGGI, LookUpTableLayout, LookupTable,
 26    LookupTableFactory,
 27};
 28
 29pub fn benc_blind_rotate<BE: Backend, BRA: BlindRotationAlgo>(c: &mut Criterion, label: &str)
 30where
 31    Module<BE>: ModuleN
 32        + ModuleNew<BE>
 33        + BlindRotationKeyEncryptSk<BRA, BE>
 34        + BlindRotationKeyPreparedFactory<BRA, BE>
 35        + BlindRotationExecute<BRA, BE>
 36        + LookupTableFactory
 37        + GLWESecretPreparedFactory<BE>
 38        + GLWEDecrypt<BE>
 39        + LWEEncryptSk<BE>,
 40    BlindRotationKey<Vec<u8>, BRA>: BlindRotationKeyFactory<BRA>,
 41    ScratchOwned<BE>: ScratchOwnedAlloc<BE> + ScratchOwnedBorrow<BE>,
 42    Scratch<BE>: ScratchTakeCore<BE>,
 43{
 44    let group_name: String = format!("blind_rotate::{label}");
 45
 46    let mut group = c.benchmark_group(group_name);
 47
 48    let n_glwe: usize = 512;
 49    let n_lwe: usize = 687;
 50    let rank: usize = 3;
 51    let block_size: usize = 3;
 52    let extension_factor: usize = 1;
 53
 54    let log_message_modulus: usize = 2;
 55    let message_modulus: usize = 1 << log_message_modulus;
 56
 57    let mut scratch: ScratchOwned<BE> = ScratchOwned::alloc(1 << 24);
 58
 59    let module: Module<BE> = Module::<BE>::new(n_glwe as u64);
 60
 61    let mut source_xs: Source = Source::new([2u8; 32]);
 62    let mut source_xe: Source = Source::new([2u8; 32]);
 63    let mut source_xa: Source = Source::new([1u8; 32]);
 64
 65    let brk_infos: BlindRotationKeyLayout = BlindRotationKeyLayout {
 66        n_glwe: n_glwe.into(),
 67        n_lwe: n_lwe.into(),
 68        base2k: Base2K(18),
 69        k: TorusPrecision(36),
 70        dnum: Dnum(1),
 71        rank: rank.into(),
 72    };
 73
 74    let glwe_infos: GLWELayout = GLWELayout {
 75        n: n_glwe.into(),
 76        base2k: Base2K(18),
 77        k: TorusPrecision(18),
 78        rank: rank.into(),
 79    };
 80
 81    let lwe_infos: LWELayout = LWELayout {
 82        n: n_lwe.into(),
 83        k: TorusPrecision(18),
 84        base2k: Base2K(18),
 85    };
 86
 87    let mut sk_glwe: GLWESecret<Vec<u8>> = GLWESecret::alloc_from_infos(&glwe_infos);
 88    sk_glwe.fill_ternary_prob(0.5, &mut source_xs);
 89    let mut sk_glwe_dft: GLWESecretPrepared<Vec<u8>, BE> = GLWESecretPrepared::alloc_from_infos(&module, &glwe_infos);
 90    sk_glwe_dft.prepare(&module, &sk_glwe);
 91
 92    let mut sk_lwe: LWESecret<Vec<u8>> = LWESecret::alloc(n_lwe.into());
 93    sk_lwe.fill_binary_block(block_size, &mut source_xs);
 94
 95    let mut brk: BlindRotationKey<Vec<u8>, BRA> = BlindRotationKey::<Vec<u8>, BRA>::alloc(&brk_infos);
 96
 97    brk.encrypt_sk(
 98        &module,
 99        &sk_glwe_dft,
100        &sk_lwe,
101        &mut source_xa,
102        &mut source_xe,
103        scratch.borrow(),
104    );
105
106    let mut brk_prepared: BlindRotationKeyPrepared<Vec<u8>, BRA, BE> = BlindRotationKeyPrepared::alloc(&module, &brk);
107    brk_prepared.prepare(&module, &brk, scratch.borrow());
108
109    let mut res: GLWE<Vec<u8>> = GLWE::alloc_from_infos(&glwe_infos);
110    res.data_mut().fill_uniform(glwe_infos.base2k().as_usize(), &mut source_xa);
111    let mut lwe: LWE<Vec<u8>> = LWE::alloc_from_infos(&lwe_infos);
112    lwe.data_mut().fill_uniform(lwe_infos.base2k().as_usize(), &mut source_xa);
113
114    let f = |x: i64| -> i64 { 2 * x + 1 };
115
116    let mut f_vec: Vec<i64> = vec![0i64; message_modulus];
117    f_vec.iter_mut().enumerate().for_each(|(i, x)| *x = f(i as i64));
118
119    let lut_infos = LookUpTableLayout {
120        n: module.n().into(),
121        extension_factor,
122        k: TorusPrecision(2),
123        base2k: Base2K(17),
124    };
125
126    let mut lut: LookupTable = LookupTable::alloc(&lut_infos);
127    lut.set(&module, &f_vec, log_message_modulus + 1);
128
129    let id: BenchmarkId = BenchmarkId::from_parameter(format!("{} - {}", n_glwe, n_lwe));
130
131    group.bench_with_input(id, &(), |b, _| {
132        b.iter(|| {
133            brk_prepared.execute(&module, &mut res, &lwe, &lut, scratch.borrow());
134            black_box(())
135        })
136    });
137    group.finish();
138}
139
140fn bench_blind_rotate_fft64(c: &mut Criterion) {
141    #[cfg(all(feature = "enable-avx", target_arch = "x86_64"))]
142    let label = "fft64_avx";
143    #[cfg(not(all(feature = "enable-avx", target_arch = "x86_64")))]
144    let label = "fft64_ref";
145    benc_blind_rotate::<BackendImpl, CGGI>(c, label);
146}
147
148criterion_group!(benches, bench_blind_rotate_fft64);
149criterion_main!(benches);