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