arnaucube
arnaucube/poulpyPublic Self-hosted repository
poulpy/poulpy-core/benches/external_product_glwe_fft64.rs
poulpy-core/benches/external_product_glwe_fft64.rsRaw
  1use poulpy_core::layouts::{
  2    Base2K, Dnum, Dsize, GGSW, GGSWLayout, GLWE, GLWELayout, GLWESecret, Rank, RingDegree, TorusPrecision,
  3    prepared::{GGSWPrepared, GLWESecretPrepared},
  4};
  5use std::hint::black_box;
  6
  7use criterion::{BenchmarkId, Criterion, criterion_group, criterion_main};
  8
  9use poulpy_backend::cpu_spqlios::FFT64Spqlios;
 10use poulpy_hal::{
 11    api::{ModuleNew, ScratchOwnedAlloc, ScratchOwnedBorrow},
 12    layouts::{Module, ScalarZnx, ScratchOwned},
 13    source::Source,
 14};
 15
 16fn bench_external_product_glwe_fft64(c: &mut Criterion) {
 17    let mut group = c.benchmark_group("external_product_glwe_fft64");
 18
 19    struct Params {
 20        log_n: usize,
 21        base2k: Base2K,
 22        k_ct_in: TorusPrecision,
 23        k_ct_out: TorusPrecision,
 24        k_ggsw: TorusPrecision,
 25        rank: Rank,
 26    }
 27
 28    fn runner(p: Params) -> impl FnMut() {
 29        let module: Module<FFT64Spqlios> = Module::<FFT64Spqlios>::new(1 << p.log_n);
 30
 31        let n: RingDegree = RingDegree(module.n() as u32);
 32        let base2k: Base2K = p.base2k;
 33        let k_ct_in: TorusPrecision = p.k_ct_in;
 34        let k_ct_out: TorusPrecision = p.k_ct_out;
 35        let k_ggsw: TorusPrecision = p.k_ggsw;
 36        let rank: Rank = p.rank;
 37        let dsize: Dsize = Dsize(1);
 38
 39        let dnum: Dnum = Dnum(1); //(p.k_ct_in.div_ceil(p.base2k);
 40
 41        let ggsw_layout: GGSWLayout = GGSWLayout {
 42            n,
 43            base2k,
 44            k: k_ggsw,
 45            dnum: dnum,
 46            dsize: dsize,
 47            rank,
 48        };
 49
 50        let glwe_out_layout: GLWELayout = GLWELayout {
 51            n,
 52            base2k,
 53            k: k_ct_out,
 54            rank,
 55        };
 56
 57        let glwe_in_layout: GLWELayout = GLWELayout {
 58            n,
 59            base2k,
 60            k: k_ct_in,
 61            rank,
 62        };
 63
 64        let mut ct_ggsw: GGSW<Vec<u8>> = GGSW::alloc_from_infos(&module, &ggsw_layout);
 65        let mut ct_glwe_in: GLWE<Vec<u8>> = GLWE::alloc_from_infos(&module, &glwe_in_layout);
 66        let mut ct_glwe_out: GLWE<Vec<u8>> = GLWE::alloc_from_infos(&module, &glwe_out_layout);
 67        let pt_rgsw: ScalarZnx<Vec<u8>> = ScalarZnx::alloc(n.into(), 1);
 68
 69        let mut scratch: ScratchOwned<FFT64Spqlios> = ScratchOwned::alloc(
 70            GGSW::encrypt_sk_tmp_bytes(&module, &ggsw_layout)
 71                | GLWE::encrypt_sk_tmp_bytes(&module, &glwe_in_layout)
 72                | GLWE::external_product_tmp_bytes(&module, &glwe_out_layout, &glwe_in_layout, &ggsw_layout),
 73        );
 74
 75        let mut source_xs = Source::new([0u8; 32]);
 76        let mut source_xe = Source::new([0u8; 32]);
 77        let mut source_xa = Source::new([0u8; 32]);
 78
 79        let mut sk: GLWESecret<Vec<u8>> = GLWESecret::alloc_from_infos(&module, &glwe_in_layout);
 80        sk.fill_ternary_prob(0.5, &mut source_xs);
 81
 82        let mut sk_dft: GLWESecretPrepared<Vec<u8>, FFT64Spqlios> = GLWESecretPrepared::alloc(&module, rank);
 83        sk_dft.prepare(&module, &sk);
 84
 85        ct_ggsw.encrypt_sk(
 86            &module,
 87            &pt_rgsw,
 88            &sk_dft,
 89            &mut source_xa,
 90            &mut source_xe,
 91            scratch.borrow(),
 92        );
 93
 94        ct_glwe_in.encrypt_zero_sk(
 95            &module,
 96            &sk_dft,
 97            &mut source_xa,
 98            &mut source_xe,
 99            scratch.borrow(),
100        );
101
102        let mut ggsw_prepared: GGSWPrepared<Vec<u8>, FFT64Spqlios> = GGSWPrepared::alloc_from_infos(&module, &ct_ggsw);
103        ggsw_prepared.prepare(&module, &ct_ggsw, scratch.borrow());
104
105        move || {
106            ct_glwe_out.external_product(&module, &ct_glwe_in, &ggsw_prepared, scratch.borrow());
107            black_box(());
108        }
109    }
110
111    let params_set: Vec<Params> = vec![Params {
112        log_n: 11,
113        base2k: 22_u32.into(),
114        k_ct_in: 44_u32.into(),
115        k_ct_out: 44_u32.into(),
116        k_ggsw: 54_u32.into(),
117        rank: 1_u32.into(),
118    }];
119
120    for params in params_set {
121        let id = BenchmarkId::new("EXTERNAL_PRODUCT_GLWE_FFT64", "");
122        let mut runner = runner(params);
123        group.bench_with_input(id, &(), |b, _| b.iter(&mut runner));
124    }
125
126    group.finish();
127}
128
129fn bench_external_product_glwe_inplace_fft64(c: &mut Criterion) {
130    let mut group = c.benchmark_group("external_product_glwe_inplace_fft64");
131
132    struct Params {
133        log_n: usize,
134        base2k: Base2K,
135        k_ct: TorusPrecision,
136        k_ggsw: TorusPrecision,
137        rank: Rank,
138    }
139
140    fn runner(p: Params) -> impl FnMut() {
141        let module: Module<FFT64Spqlios> = Module::<FFT64Spqlios>::new(1 << p.log_n);
142
143        let n: RingDegree = RingDegree(module.n() as u32);
144        let base2k: Base2K = p.base2k;
145        let k_glwe: TorusPrecision = p.k_ct;
146        let k_ggsw: TorusPrecision = p.k_ggsw;
147        let rank: Rank = p.rank;
148        let dsize: Dsize = Dsize(1);
149
150        let dnum: Dnum = p.k_ct.div_ceil(p.base2k).into();
151
152        let ggsw_layout: GGSWLayout = GGSWLayout {
153            n,
154            base2k,
155            k: k_ggsw,
156            dnum: dnum,
157            dsize: dsize,
158            rank,
159        };
160
161        let glwe_layout: GLWELayout = GLWELayout {
162            n,
163            base2k,
164            k: k_glwe,
165            rank,
166        };
167
168        let mut ct_ggsw: GGSW<Vec<u8>> = GGSW::alloc_from_infos(&module, &ggsw_layout);
169        let mut ct_glwe: GLWE<Vec<u8>> = GLWE::alloc_from_infos(&module, &glwe_layout);
170        let pt_rgsw: ScalarZnx<Vec<u8>> = ScalarZnx::alloc(n.into(), 1);
171
172        let mut scratch: ScratchOwned<FFT64Spqlios> = ScratchOwned::alloc(
173            GGSW::encrypt_sk_tmp_bytes(&module, &ggsw_layout)
174                | GLWE::encrypt_sk_tmp_bytes(&module, &glwe_layout)
175                | GLWE::external_product_tmp_bytes(&module, &glwe_layout, &glwe_layout, &ggsw_layout),
176        );
177
178        let mut source_xs: Source = Source::new([0u8; 32]);
179        let mut source_xe: Source = Source::new([0u8; 32]);
180        let mut source_xa: Source = Source::new([0u8; 32]);
181
182        let mut sk: GLWESecret<Vec<u8>> = GLWESecret::alloc_from_infos(&module, &glwe_layout);
183        sk.fill_ternary_prob(0.5, &mut source_xs);
184
185        let mut sk_dft: GLWESecretPrepared<Vec<u8>, FFT64Spqlios> = GLWESecretPrepared::alloc(&module, rank);
186        sk_dft.prepare(&module, &sk);
187
188        ct_ggsw.encrypt_sk(
189            &module,
190            &pt_rgsw,
191            &sk_dft,
192            &mut source_xa,
193            &mut source_xe,
194            scratch.borrow(),
195        );
196
197        ct_glwe.encrypt_zero_sk(
198            &module,
199            &sk_dft,
200            &mut source_xa,
201            &mut source_xe,
202            scratch.borrow(),
203        );
204
205        let mut ggsw_prepared: GGSWPrepared<Vec<u8>, FFT64Spqlios> = GGSWPrepared::alloc_from_infos(&module, &ct_ggsw);
206        ggsw_prepared.prepare(&module, &ct_ggsw, scratch.borrow());
207        move || {
208            let scratch_borrow = scratch.borrow();
209            ct_glwe.external_product_inplace(&module, &ggsw_prepared, scratch_borrow);
210            black_box(());
211        }
212    }
213
214    let params_set: Vec<Params> = vec![Params {
215        log_n: 12,
216        base2k: 18_u32.into(),
217        k_ct: 54_u32.into(),
218        k_ggsw: 54_u32.into(),
219        rank: 1_u32.into(),
220    }];
221
222    for params in params_set {
223        let id = BenchmarkId::new("EXTERNAL_PRODUCT_GLWE_INPLACE_FFT64", "");
224        let mut runner = runner(params);
225        group.bench_with_input(id, &(), |b, _| b.iter(&mut runner));
226    }
227
228    group.finish();
229}
230
231criterion_group!(
232    benches,
233    bench_external_product_glwe_fft64,
234    bench_external_product_glwe_inplace_fft64
235);
236criterion_main!(benches);