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