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