arnaucube
arnaucube/poulpyPublic Self-hosted repository
poulpy/core/benches/external_product_glwe_fft64.rs
core/benches/external_product_glwe_fft64.rsRaw
  1use backend::{FFT64, Module, ScalarZnx, ScalarZnxAlloc, ScratchOwned};
  2use core::{
  3    elem::Infos,
  4    ggsw_ciphertext::GGSWCiphertext,
  5    glwe_ciphertext::GLWECiphertext,
  6    keys::{SecretKey, SecretKeyFourier},
  7};
  8use criterion::{BenchmarkId, Criterion, criterion_group, criterion_main};
  9use sampling::source::Source;
 10use std::hint::black_box;
 11
 12fn bench_external_product_glwe_fft64(c: &mut Criterion) {
 13    let mut group = c.benchmark_group("external_product_glwe_fft64");
 14
 15    struct Params {
 16        log_n: usize,
 17        basek: usize,
 18        k_ct_in: usize,
 19        k_ct_out: usize,
 20        k_ggsw: usize,
 21        rank: usize,
 22    }
 23
 24    fn runner(p: Params) -> impl FnMut() {
 25        let module: Module<FFT64> = Module::<FFT64>::new(1 << p.log_n);
 26
 27        let basek: usize = p.basek;
 28        let k_ct_in: usize = p.k_ct_in;
 29        let k_ct_out: usize = p.k_ct_out;
 30        let k_ggsw: usize = p.k_ggsw;
 31        let rank: usize = p.rank;
 32
 33        let rows: usize = (p.k_ct_in + p.basek - 1) / p.basek;
 34        let sigma: f64 = 3.2;
 35
 36        let mut ct_rgsw: GGSWCiphertext<Vec<u8>, FFT64> = GGSWCiphertext::alloc(&module, basek, k_ggsw, rows, rank);
 37        let mut ct_rlwe_in: GLWECiphertext<Vec<u8>> = GLWECiphertext::alloc(&module, basek, k_ct_in, rank);
 38        let mut ct_rlwe_out: GLWECiphertext<Vec<u8>> = GLWECiphertext::alloc(&module, basek, k_ct_out, rank);
 39        let pt_rgsw: ScalarZnx<Vec<u8>> = module.new_scalar_znx(1);
 40
 41        let mut scratch = ScratchOwned::new(
 42            GGSWCiphertext::encrypt_sk_scratch_space(&module, rank, ct_rgsw.size())
 43                | GLWECiphertext::encrypt_sk_scratch_space(&module, ct_rlwe_in.size())
 44                | GLWECiphertext::external_product_scratch_space(
 45                    &module,
 46                    ct_rlwe_out.size(),
 47                    ct_rlwe_in.size(),
 48                    ct_rgsw.size(),
 49                    rank,
 50                ),
 51        );
 52
 53        let mut source_xs = Source::new([0u8; 32]);
 54        let mut source_xe = Source::new([0u8; 32]);
 55        let mut source_xa = Source::new([0u8; 32]);
 56
 57        let mut sk: SecretKey<Vec<u8>> = SecretKey::alloc(&module, rank);
 58        sk.fill_ternary_prob(0.5, &mut source_xs);
 59        let mut sk_dft: SecretKeyFourier<Vec<u8>, FFT64> = SecretKeyFourier::alloc(&module, rank);
 60        sk_dft.dft(&module, &sk);
 61
 62        ct_rgsw.encrypt_sk(
 63            &module,
 64            &pt_rgsw,
 65            &sk_dft,
 66            &mut source_xa,
 67            &mut source_xe,
 68            sigma,
 69            scratch.borrow(),
 70        );
 71
 72        ct_rlwe_in.encrypt_zero_sk(
 73            &module,
 74            &sk_dft,
 75            &mut source_xa,
 76            &mut source_xe,
 77            sigma,
 78            scratch.borrow(),
 79        );
 80
 81        move || {
 82            ct_rlwe_out.external_product(
 83                black_box(&module),
 84                black_box(&ct_rlwe_in),
 85                black_box(&ct_rgsw),
 86                black_box(scratch.borrow()),
 87            );
 88        }
 89    }
 90
 91    let params_set: Vec<Params> = vec![Params {
 92        log_n: 10,
 93        basek: 7,
 94        k_ct_in: 27,
 95        k_ct_out: 27,
 96        k_ggsw: 27,
 97        rank: 1,
 98    }];
 99
100    for params in params_set {
101        let id = BenchmarkId::new("EXTERNAL_PRODUCT_GLWE_FFT64", "");
102        let mut runner = runner(params);
103        group.bench_with_input(id, &(), |b, _| b.iter(&mut runner));
104    }
105
106    group.finish();
107}
108
109fn bench_external_product_glwe_inplace_fft64(c: &mut Criterion) {
110    let mut group = c.benchmark_group("external_product_glwe_inplace_fft64");
111
112    struct Params {
113        log_n: usize,
114        basek: usize,
115        k_ct: usize,
116        k_ggsw: usize,
117        rank: usize,
118    }
119
120    fn runner(p: Params) -> impl FnMut() {
121        let module: Module<FFT64> = Module::<FFT64>::new(1 << p.log_n);
122
123        let basek: usize = p.basek;
124        let k_glwe: usize = p.k_ct;
125        let k_ggsw: usize = p.k_ggsw;
126        let rank: usize = p.rank;
127
128        let rows: usize = (p.k_ct + p.basek - 1) / p.basek;
129        let sigma: f64 = 3.2;
130
131        let mut ct_rgsw: GGSWCiphertext<Vec<u8>, FFT64> = GGSWCiphertext::alloc(&module, basek, k_ggsw, rows, rank);
132        let mut ct_rlwe: GLWECiphertext<Vec<u8>> = GLWECiphertext::alloc(&module, basek, k_glwe, rank);
133        let pt_rgsw: ScalarZnx<Vec<u8>> = module.new_scalar_znx(1);
134
135        let mut scratch = ScratchOwned::new(
136            GGSWCiphertext::encrypt_sk_scratch_space(&module, rank, ct_rgsw.size())
137                | GLWECiphertext::encrypt_sk_scratch_space(&module, ct_rlwe.size())
138                | GLWECiphertext::external_product_inplace_scratch_space(&module, ct_rlwe.size(), ct_rgsw.size(), rank),
139        );
140
141        let mut source_xs = Source::new([0u8; 32]);
142        let mut source_xe = Source::new([0u8; 32]);
143        let mut source_xa = Source::new([0u8; 32]);
144
145        let mut sk: SecretKey<Vec<u8>> = SecretKey::alloc(&module, rank);
146        sk.fill_ternary_prob(0.5, &mut source_xs);
147        let mut sk_dft: SecretKeyFourier<Vec<u8>, FFT64> = SecretKeyFourier::alloc(&module, rank);
148        sk_dft.dft(&module, &sk);
149
150        ct_rgsw.encrypt_sk(
151            &module,
152            &pt_rgsw,
153            &sk_dft,
154            &mut source_xa,
155            &mut source_xe,
156            sigma,
157            scratch.borrow(),
158        );
159
160        ct_rlwe.encrypt_zero_sk(
161            &module,
162            &sk_dft,
163            &mut source_xa,
164            &mut source_xe,
165            sigma,
166            scratch.borrow(),
167        );
168
169        move || {
170            let scratch_borrow = scratch.borrow();
171            (0..687).for_each(|_| {
172                ct_rlwe.external_product_inplace(
173                    black_box(&module),
174                    black_box(&ct_rgsw),
175                    black_box(scratch_borrow),
176                );
177            });
178        }
179    }
180
181    let params_set: Vec<Params> = vec![Params {
182        log_n: 12,
183        basek: 18,
184        k_ct: 54,
185        k_ggsw: 54,
186        rank: 1,
187    }];
188
189    for params in params_set {
190        let id = BenchmarkId::new("EXTERNAL_PRODUCT_GLWE_INPLACE_FFT64", "");
191        let mut runner = runner(params);
192        group.bench_with_input(id, &(), |b, _| b.iter(&mut runner));
193    }
194
195    group.finish();
196}
197
198criterion_group!(
199    benches,
200    bench_external_product_glwe_fft64,
201    bench_external_product_glwe_inplace_fft64
202);
203criterion_main!(benches);