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