fixed benchmarks
@@ -2,12 +2,8 @@ use base2k::{FFT64, Module, ScalarZnxAlloc, ScratchOwned};
use criterion::{BenchmarkId, Criterion, black_box, criterion_group, criterion_main}; use rlwe::{ elem::Infos, - encryption::EncryptSkScratchSpace, - external_product::{ - ExternalProduct, ExternalProductInplace, ExternalProductInplaceScratchSpace, ExternalProductScratchSpace, - }, ggsw_ciphertext::GGSWCiphertext, - glwe::GLWECiphertext, + glwe_ciphertext::GLWECiphertext, keys::{SecretKey, SecretKeyFourier}, }; use sampling::source::Source;@@ -18,36 +14,38 @@
struct Params { log_n: usize, basek: usize, - k_rlwe_in: usize, - k_rlwe_out: usize, - k_rgsw: usize, + k_ct_in: usize, + k_ct_out: usize, + k_ggsw: usize, + rank: usize, } fn runner(p: Params) -> impl FnMut() { let module: Module<FFT64> = Module::<FFT64>::new(1 << p.log_n); let basek: usize = p.basek; - let k_rlwe_in: usize = p.k_rlwe_in; - let k_rlwe_out: usize = p.k_rlwe_out; - let k_rgsw: usize = p.k_rgsw; + let k_ct_in: usize = p.k_ct_in; + let k_ct_out: usize = p.k_ct_out; + let k_ggsw: usize = p.k_ggsw; + let rank: usize = p.rank; - let rows: usize = (p.k_rlwe_in + p.basek - 1) / p.basek; + let rows: usize = (p.k_ct_in + p.basek - 1) / p.basek; let sigma: f64 = 3.2; - let bound: f64 = sigma * 6.0; - let mut ct_rgsw: GGSWCiphertext<Vec<u8>, FFT64> = GGSWCiphertext::new(&module, basek, k_rgsw, rows); - let mut ct_rlwe_in: GLWECiphertext<Vec<u8>> = GLWECiphertext::new(&module, basek, k_rlwe_in); - let mut ct_rlwe_out: GLWECiphertext<Vec<u8>> = GLWECiphertext::new(&module, basek, k_rlwe_out); + let mut ct_rgsw: GGSWCiphertext<Vec<u8>, FFT64> = GGSWCiphertext::new(&module, basek, k_ggsw, rows, rank); + let mut ct_rlwe_in: GLWECiphertext<Vec<u8>> = GLWECiphertext::new(&module, basek, k_ct_in, rank); + let mut ct_rlwe_out: GLWECiphertext<Vec<u8>> = GLWECiphertext::new(&module, basek, k_ct_out, rank); let pt_rgsw: base2k::ScalarZnx<Vec<u8>> = module.new_scalar_znx(1); let mut scratch = ScratchOwned::new( - GGSWCiphertext::encrypt_sk_scratch_space(&module, ct_rgsw.size()) + GGSWCiphertext::encrypt_sk_scratch_space(&module, rank, ct_rgsw.size()) | GLWECiphertext::encrypt_sk_scratch_space(&module, ct_rlwe_in.size()) | GLWECiphertext::external_product_scratch_space( &module, ct_rlwe_out.size(), ct_rlwe_in.size(), ct_rgsw.size(), + rank, ), );@@ -55,9 +53,9 @@ let mut source_xs = Source::new([0u8; 32]);
let mut source_xe = Source::new([0u8; 32]); let mut source_xa = Source::new([0u8; 32]); - let mut sk: SecretKey<Vec<u8>> = SecretKey::new(&module); + let mut sk: SecretKey<Vec<u8>> = SecretKey::new(&module, rank); sk.fill_ternary_prob(0.5, &mut source_xs); - let mut sk_dft: SecretKeyFourier<Vec<u8>, FFT64> = SecretKeyFourier::new(&module); + let mut sk_dft: SecretKeyFourier<Vec<u8>, FFT64> = SecretKeyFourier::new(&module, rank); sk_dft.dft(&module, &sk); ct_rgsw.encrypt_sk(@@ -67,7 +65,6 @@ &sk_dft,
&mut source_xa, &mut source_xe, sigma, - bound, scratch.borrow(), );@@ -77,7 +74,6 @@ &sk_dft,
&mut source_xa, &mut source_xe, sigma, - bound, scratch.borrow(), );@@ -94,9 +90,10 @@
let params_set: Vec<Params> = vec![Params { log_n: 10, basek: 7, - k_rlwe_in: 27, - k_rlwe_out: 27, - k_rgsw: 27, + k_ct_in: 27, + k_ct_out: 27, + k_ggsw: 27, + rank: 1, }]; for params in params_set {@@ -114,38 +111,39 @@
struct Params { log_n: usize, basek: usize, - k_rlwe: usize, - k_rgsw: usize, + k_ct: usize, + k_ggsw: usize, + rank: usize, } fn runner(p: Params) -> impl FnMut() { let module: Module<FFT64> = Module::<FFT64>::new(1 << p.log_n); let basek: usize = p.basek; - let k_rlwe: usize = p.k_rlwe; - let k_rgsw: usize = p.k_rgsw; + let k_glwe: usize = p.k_ct; + let k_ggsw: usize = p.k_ggsw; + let rank: usize = p.rank; - let rows: usize = (p.k_rlwe + p.basek - 1) / p.basek; + let rows: usize = (p.k_ct + p.basek - 1) / p.basek; let sigma: f64 = 3.2; - let bound: f64 = sigma * 6.0; - let mut ct_rgsw: GGSWCiphertext<Vec<u8>, FFT64> = GGSWCiphertext::new(&module, basek, k_rgsw, rows); - let mut ct_rlwe: GLWECiphertext<Vec<u8>> = GLWECiphertext::new(&module, basek, k_rlwe); + let mut ct_rgsw: GGSWCiphertext<Vec<u8>, FFT64> = GGSWCiphertext::new(&module, basek, k_ggsw, rows, rank); + let mut ct_rlwe: GLWECiphertext<Vec<u8>> = GLWECiphertext::new(&module, basek, k_glwe, rank); let pt_rgsw: base2k::ScalarZnx<Vec<u8>> = module.new_scalar_znx(1); let mut scratch = ScratchOwned::new( - GGSWCiphertext::encrypt_sk_scratch_space(&module, ct_rgsw.size()) + GGSWCiphertext::encrypt_sk_scratch_space(&module, rank, ct_rgsw.size()) | GLWECiphertext::encrypt_sk_scratch_space(&module, ct_rlwe.size()) - | GLWECiphertext::external_product_inplace_scratch_space(&module, ct_rlwe.size(), ct_rgsw.size()), + | GLWECiphertext::external_product_inplace_scratch_space(&module, ct_rlwe.size(), ct_rgsw.size(), rank), ); let mut source_xs = Source::new([0u8; 32]); let mut source_xe = Source::new([0u8; 32]); let mut source_xa = Source::new([0u8; 32]); - let mut sk: SecretKey<Vec<u8>> = SecretKey::new(&module); + let mut sk: SecretKey<Vec<u8>> = SecretKey::new(&module, rank); sk.fill_ternary_prob(0.5, &mut source_xs); - let mut sk_dft: SecretKeyFourier<Vec<u8>, FFT64> = SecretKeyFourier::new(&module); + let mut sk_dft: SecretKeyFourier<Vec<u8>, FFT64> = SecretKeyFourier::new(&module, rank); sk_dft.dft(&module, &sk); ct_rgsw.encrypt_sk(@@ -155,7 +153,6 @@ &sk_dft,
&mut source_xa, &mut source_xe, sigma, - bound, scratch.borrow(), );@@ -165,13 +162,12 @@ &sk_dft,
&mut source_xa, &mut source_xe, sigma, - bound, scratch.borrow(), ); move || { let scratch_borrow = scratch.borrow(); - (0..1374).for_each(|i| { + (0..687).for_each(|_| { ct_rlwe.external_product_inplace( black_box(&module), black_box(&ct_rgsw),@@ -182,10 +178,11 @@ }
} let params_set: Vec<Params> = vec![Params { - log_n: 9, + log_n: 12, basek: 18, - k_rlwe: 27, - k_rgsw: 27, + k_ct: 54, + k_ggsw: 54, + rank: 1, }]; for params in params_set {
@@ -1,12 +1,10 @@
-use base2k::{FFT64, Module, ScalarZnxAlloc, ScratchOwned}; +use base2k::{FFT64, Module, ScratchOwned}; use criterion::{BenchmarkId, Criterion, black_box, criterion_group, criterion_main}; use rlwe::{ elem::Infos, - encryption::EncryptSkScratchSpace, - glwe::GLWECiphertext, + glwe_ciphertext::GLWECiphertext, keys::{SecretKey, SecretKeyFourier}, - keyswitch::{KeySwitch, KeySwitchInplace, KeySwitchInplaceScratchSpace, KeySwitchScratchSpace}, - keyswitch_key::GLWEKeySwitchKey, + keyswitch_key::GLWESwitchingKey, }; use sampling::source::Source;@@ -16,36 +14,40 @@
struct Params { log_n: usize, basek: usize, - k_rlwe_in: usize, - k_rlwe_out: usize, - k_grlwe: usize, + k_ct_in: usize, + k_ct_out: usize, + k_ksk: usize, + rank_in: usize, + rank_out: usize, } fn runner(p: Params) -> impl FnMut() { let module: Module<FFT64> = Module::<FFT64>::new(1 << p.log_n); let basek: usize = p.basek; - let k_rlwe_in: usize = p.k_rlwe_in; - let k_rlwe_out: usize = p.k_rlwe_out; - let k_grlwe: usize = p.k_grlwe; + let k_rlwe_in: usize = p.k_ct_in; + let k_rlwe_out: usize = p.k_ct_out; + let k_grlwe: usize = p.k_ksk; + let rank_in: usize = p.rank_in; + let rank_out: usize = p.rank_out; - let rows: usize = (p.k_rlwe_in + p.basek - 1) / p.basek; + let rows: usize = (p.k_ct_in + p.basek - 1) / p.basek; let sigma: f64 = 3.2; - let bound: f64 = sigma * 6.0; - let mut ct_grlwe: GLWEKeySwitchKey<Vec<u8>, FFT64> = GLWEKeySwitchKey::new(&module, basek, k_grlwe, rows); - let mut ct_rlwe_in: GLWECiphertext<Vec<u8>> = GLWECiphertext::new(&module, basek, k_rlwe_in); - let mut ct_rlwe_out: GLWECiphertext<Vec<u8>> = GLWECiphertext::new(&module, basek, k_rlwe_out); - let pt_grlwe: base2k::ScalarZnx<Vec<u8>> = module.new_scalar_znx(1); + let mut ksk: GLWESwitchingKey<Vec<u8>, FFT64> = GLWESwitchingKey::new(&module, basek, k_grlwe, rows, rank_in, rank_out); + let mut ct_in: GLWECiphertext<Vec<u8>> = GLWECiphertext::new(&module, basek, k_rlwe_in, rank_in); + let mut ct_out: GLWECiphertext<Vec<u8>> = GLWECiphertext::new(&module, basek, k_rlwe_out, rank_out); let mut scratch = ScratchOwned::new( - GLWEKeySwitchKey::encrypt_sk_scratch_space(&module, ct_grlwe.size()) - | GLWECiphertext::encrypt_sk_scratch_space(&module, ct_rlwe_in.size()) + GLWESwitchingKey::encrypt_sk_scratch_space(&module, rank_out, ksk.size()) + | GLWECiphertext::encrypt_sk_scratch_space(&module, ct_in.size()) | GLWECiphertext::keyswitch_scratch_space( &module, - ct_rlwe_out.size(), - ct_rlwe_in.size(), - ct_grlwe.size(), + ct_out.size(), + ct_in.size(), + ksk.size(), + rank_in, + rank_out, ), );@@ -53,37 +55,40 @@ let mut source_xs = Source::new([0u8; 32]);
let mut source_xe = Source::new([0u8; 32]); let mut source_xa = Source::new([0u8; 32]); - let mut sk: SecretKey<Vec<u8>> = SecretKey::new(&module); - sk.fill_ternary_prob(0.5, &mut source_xs); - let mut sk_dft: SecretKeyFourier<Vec<u8>, FFT64> = SecretKeyFourier::new(&module); - sk_dft.dft(&module, &sk); + let mut sk_in: SecretKey<Vec<u8>> = SecretKey::new(&module, rank_in); + sk_in.fill_ternary_prob(0.5, &mut source_xs); + let mut sk_in_dft: SecretKeyFourier<Vec<u8>, FFT64> = SecretKeyFourier::new(&module, rank_in); + sk_in_dft.dft(&module, &sk_in); - ct_grlwe.encrypt_sk( + let mut sk_out: SecretKey<Vec<u8>> = SecretKey::new(&module, rank_out); + sk_out.fill_ternary_prob(0.5, &mut source_xs); + let mut sk_out_dft: SecretKeyFourier<Vec<u8>, FFT64> = SecretKeyFourier::new(&module, rank_out); + sk_out_dft.dft(&module, &sk_out); + + ksk.encrypt_sk( &module, - &pt_grlwe, - &sk_dft, + &sk_in, + &sk_out_dft, &mut source_xa, &mut source_xe, sigma, - bound, scratch.borrow(), ); - ct_rlwe_in.encrypt_zero_sk( + ct_in.encrypt_zero_sk( &module, - &sk_dft, + &sk_in_dft, &mut source_xa, &mut source_xe, sigma, - bound, scratch.borrow(), ); move || { - ct_rlwe_out.keyswitch( + ct_out.keyswitch( black_box(&module), - black_box(&ct_rlwe_in), - black_box(&ct_grlwe), + black_box(&ct_in), + black_box(&ksk), black_box(scratch.borrow()), ); }@@ -92,9 +97,11 @@
let params_set: Vec<Params> = vec![Params { log_n: 16, basek: 50, - k_rlwe_in: 1250, - k_rlwe_out: 1250, - k_grlwe: 1250 + 66, + k_ct_in: 1250, + k_ct_out: 1250, + k_ksk: 1250 + 66, + rank_in: 1, + rank_out: 1, }]; for params in params_set {@@ -112,65 +119,68 @@
struct Params { log_n: usize, basek: usize, - k_rlwe: usize, - k_grlwe: usize, + k_ct: usize, + k_ksk: usize, + rank: usize, } fn runner(p: Params) -> impl FnMut() { let module: Module<FFT64> = Module::<FFT64>::new(1 << p.log_n); let basek: usize = p.basek; - let k_rlwe: usize = p.k_rlwe; - let k_grlwe: usize = p.k_grlwe; + let k_ct: usize = p.k_ct; + let k_ksk: usize = p.k_ksk; + let rank: usize = p.rank; - let rows: usize = (p.k_rlwe + p.basek - 1) / p.basek; + let rows: usize = (p.k_ct + p.basek - 1) / p.basek; let sigma: f64 = 3.2; - let bound: f64 = sigma * 6.0; - let mut ct_grlwe: GLWEKeySwitchKey<Vec<u8>, FFT64> = GLWEKeySwitchKey::new(&module, basek, k_grlwe, rows); - let mut ct_rlwe: GLWECiphertext<Vec<u8>> = GLWECiphertext::new(&module, basek, k_rlwe); - let pt_grlwe: base2k::ScalarZnx<Vec<u8>> = module.new_scalar_znx(1); + let mut ksk: GLWESwitchingKey<Vec<u8>, FFT64> = GLWESwitchingKey::new(&module, basek, k_ksk, rows, rank, rank); + let mut ct: GLWECiphertext<Vec<u8>> = GLWECiphertext::new(&module, basek, k_ct, rank); let mut scratch = ScratchOwned::new( - GLWEKeySwitchKey::encrypt_sk_scratch_space(&module, ct_grlwe.size()) - | GLWECiphertext::encrypt_sk_scratch_space(&module, ct_rlwe.size()) - | GLWECiphertext::keyswitch_inplace_scratch_space(&module, ct_rlwe.size(), ct_grlwe.size()), + GLWESwitchingKey::encrypt_sk_scratch_space(&module, rank, ksk.size()) + | GLWECiphertext::encrypt_sk_scratch_space(&module, ct.size()) + | GLWECiphertext::keyswitch_inplace_scratch_space(&module, ct.size(), ksk.size(), rank), ); let mut source_xs: Source = Source::new([0u8; 32]); let mut source_xe: Source = Source::new([0u8; 32]); let mut source_xa: Source = Source::new([0u8; 32]); - let mut sk: SecretKey<Vec<u8>> = SecretKey::new(&module); - sk.fill_ternary_prob(0.5, &mut source_xs); - let mut sk_dft: SecretKeyFourier<Vec<u8>, FFT64> = SecretKeyFourier::new(&module); - sk_dft.dft(&module, &sk); + let mut sk_in: SecretKey<Vec<u8>> = SecretKey::new(&module, rank); + sk_in.fill_ternary_prob(0.5, &mut source_xs); + let mut sk_in_dft: SecretKeyFourier<Vec<u8>, FFT64> = SecretKeyFourier::new(&module, rank); + sk_in_dft.dft(&module, &sk_in); - ct_grlwe.encrypt_sk( + let mut sk_out: SecretKey<Vec<u8>> = SecretKey::new(&module, rank); + sk_out.fill_ternary_prob(0.5, &mut source_xs); + let mut sk_out_dft: SecretKeyFourier<Vec<u8>, FFT64> = SecretKeyFourier::new(&module, rank); + sk_out_dft.dft(&module, &sk_out); + + ksk.encrypt_sk( &module, - &pt_grlwe, - &sk_dft, + &sk_in, + &sk_out_dft, &mut source_xa, &mut source_xe, sigma, - bound, scratch.borrow(), ); - ct_rlwe.encrypt_zero_sk( + ct.encrypt_zero_sk( &module, - &sk_dft, + &sk_in_dft, &mut source_xa, &mut source_xe, sigma, - bound, scratch.borrow(), ); move || { - ct_rlwe.keyswitch_inplace( + ct.keyswitch_inplace( black_box(&module), - black_box(&ct_grlwe), + black_box(&ksk), black_box(scratch.borrow()), ); }@@ -179,8 +189,9 @@
let params_set: Vec<Params> = vec![Params { log_n: 9, basek: 18, - k_rlwe: 27, - k_grlwe: 27, + k_ct: 27, + k_ksk: 27, + rank: 1, }]; for params in params_set {
@@ -82,7 +82,7 @@ }
impl GGLWECiphertext<Vec<u8>, FFT64> { pub fn encrypt_sk_scratch_space(module: &Module<FFT64>, rank: usize, size: usize) -> usize { - GLWECiphertext::encrypt_sk_scratch_space(module, rank, size) + GLWECiphertext::encrypt_sk_scratch_space(module, size) + module.bytes_of_vec_znx(rank + 1, size) + module.bytes_of_vec_znx(1, size) + module.bytes_of_vec_znx_dft(rank + 1, size)
@@ -76,7 +76,7 @@ }
impl GGSWCiphertext<Vec<u8>, FFT64> { pub fn encrypt_sk_scratch_space(module: &Module<FFT64>, rank: usize, size: usize) -> usize { - GLWECiphertext::encrypt_sk_scratch_space(module, rank, size) + GLWECiphertext::encrypt_sk_scratch_space(module, size) + module.bytes_of_vec_znx(rank + 1, size) + module.bytes_of_vec_znx(1, size) + module.bytes_of_vec_znx_dft(rank + 1, size)
@@ -97,12 +97,12 @@ }
} impl GLWECiphertext<Vec<u8>> { - pub fn encrypt_sk_scratch_space(module: &Module<FFT64>, _rank: usize, ct_size: usize) -> usize { + pub fn encrypt_sk_scratch_space(module: &Module<FFT64>, ct_size: usize) -> usize { module.vec_znx_big_normalize_tmp_bytes() + module.bytes_of_vec_znx_dft(1, ct_size) + module.bytes_of_vec_znx_big(1, ct_size) } - pub fn encrypt_pk_scratch_space(module: &Module<FFT64>, _rank: usize, pk_size: usize) -> usize { + pub fn encrypt_pk_scratch_space(module: &Module<FFT64>, pk_size: usize) -> usize { ((module.bytes_of_vec_znx_dft(1, pk_size) + module.bytes_of_vec_znx_big(1, pk_size)) | module.bytes_of_scalar_znx(1)) + module.bytes_of_scalar_znx_dft(1) + module.vec_znx_big_normalize_tmp_bytes()
@@ -80,7 +80,7 @@ module.bytes_of_vec_znx(1, size) + (module.vec_znx_big_normalize_tmp_bytes() | module.vec_znx_idft_tmp_bytes())
} pub fn encrypt_sk_scratch_space(module: &Module<FFT64>, rank: usize, ct_size: usize) -> usize { - module.bytes_of_vec_znx(rank + 1, ct_size) + GLWECiphertext::encrypt_sk_scratch_space(module, rank, ct_size) + module.bytes_of_vec_znx(rank + 1, ct_size) + GLWECiphertext::encrypt_sk_scratch_space(module, ct_size) } pub fn decrypt_scratch_space(module: &Module<FFT64>, ct_size: usize) -> usize {
@@ -69,8 +69,7 @@ let mut source_xe: Source = Source::new([0u8; 32]);
let mut source_xa: Source = Source::new([0u8; 32]); let mut scratch: ScratchOwned = ScratchOwned::new( - GLWECiphertext::encrypt_sk_scratch_space(&module, rank, ct.size()) - | GLWECiphertext::decrypt_scratch_space(&module, ct.size()), + GLWECiphertext::encrypt_sk_scratch_space(&module, ct.size()) | GLWECiphertext::decrypt_scratch_space(&module, ct.size()), ); let mut sk: SecretKey<Vec<u8>> = SecretKey::new(&module, rank);@@ -173,9 +172,9 @@ let mut pk: GLWEPublicKey<Vec<u8>, FFT64> = GLWEPublicKey::new(&module, basek, k_pk, rank);
pk.generate(&module, &sk_dft, &mut source_xa, &mut source_xe, sigma); let mut scratch: ScratchOwned = ScratchOwned::new( - GLWECiphertext::encrypt_sk_scratch_space(&module, rank, ct.size()) + GLWECiphertext::encrypt_sk_scratch_space(&module, ct.size()) | GLWECiphertext::decrypt_scratch_space(&module, ct.size()) - | GLWECiphertext::encrypt_pk_scratch_space(&module, rank, pk.size()), + | GLWECiphertext::encrypt_pk_scratch_space(&module, pk.size()), ); let mut data_want: Vec<i64> = vec![0i64; module.n()];@@ -244,7 +243,7 @@
let mut scratch: ScratchOwned = ScratchOwned::new( GLWESwitchingKey::encrypt_sk_scratch_space(&module, rank_in, ksk.size()) | GLWECiphertext::decrypt_scratch_space(&module, ct_out.size()) - | GLWECiphertext::encrypt_sk_scratch_space(&module, rank_out, ct_in.size()) + | GLWECiphertext::encrypt_sk_scratch_space(&module, ct_in.size()) | GLWECiphertext::keyswitch_scratch_space( &module, ct_out.size(),@@ -336,7 +335,7 @@
let mut scratch: ScratchOwned = ScratchOwned::new( GLWESwitchingKey::encrypt_sk_scratch_space(&module, rank, ct_grlwe.size()) | GLWECiphertext::decrypt_scratch_space(&module, ct_rlwe.size()) - | GLWECiphertext::encrypt_sk_scratch_space(&module, rank, ct_rlwe.size()) + | GLWECiphertext::encrypt_sk_scratch_space(&module, ct_rlwe.size()) | GLWECiphertext::keyswitch_inplace_scratch_space(&module, ct_rlwe.size(), ct_grlwe.size(), rank), );@@ -438,7 +437,7 @@
let mut scratch: ScratchOwned = ScratchOwned::new( GGSWCiphertext::encrypt_sk_scratch_space(&module, rank, ct_rgsw.size()) | GLWECiphertext::decrypt_scratch_space(&module, ct_rlwe_out.size()) - | GLWECiphertext::encrypt_sk_scratch_space(&module, rank, ct_rlwe_in.size()) + | GLWECiphertext::encrypt_sk_scratch_space(&module, ct_rlwe_in.size()) | GLWECiphertext::external_product_scratch_space( &module, ct_rlwe_out.size(),@@ -549,7 +548,7 @@
let mut scratch: ScratchOwned = ScratchOwned::new( GGSWCiphertext::encrypt_sk_scratch_space(&module, rank, ct_rgsw.size()) | GLWECiphertext::decrypt_scratch_space(&module, ct_rlwe.size()) - | GLWECiphertext::encrypt_sk_scratch_space(&module, rank, ct_rlwe.size()) + | GLWECiphertext::encrypt_sk_scratch_space(&module, ct_rlwe.size()) | GLWECiphertext::external_product_inplace_scratch_space(&module, ct_rlwe.size(), ct_rgsw.size(), rank), );