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