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