diff --git a/core/benches/external_product_glwe_fft64.rs b/core/benches/external_product_glwe_fft64.rs index 7f4800d..bb9f268 100644 --- a/core/benches/external_product_glwe_fft64.rs +++ b/core/benches/external_product_glwe_fft64.rs @@ -33,19 +33,20 @@ fn bench_external_product_glwe_fft64(c: &mut Criterion) { let rows: usize = (p.k_ct_in + p.basek - 1) / p.basek; let sigma: f64 = 3.2; - let mut ct_rgsw: GGSWCiphertext, FFT64> = GGSWCiphertext::alloc(&module, basek, k_ggsw, rows, rank); - let mut ct_rlwe_in: GLWECiphertext> = GLWECiphertext::alloc(&module, basek, k_ct_in, rank); - let mut ct_rlwe_out: GLWECiphertext> = GLWECiphertext::alloc(&module, basek, k_ct_out, rank); + let mut ct_ggsw: GGSWCiphertext, FFT64> = GGSWCiphertext::alloc(&module, basek, k_ggsw, rows, rank); + let mut ct_glwe_in: GLWECiphertext> = GLWECiphertext::alloc(&module, basek, k_ct_in, rank); + let mut ct_glwe_out: GLWECiphertext> = GLWECiphertext::alloc(&module, basek, k_ct_out, rank); let pt_rgsw: ScalarZnx> = module.new_scalar_znx(1); let mut scratch = ScratchOwned::new( - GGSWCiphertext::encrypt_sk_scratch_space(&module, rank, ct_rgsw.size()) - | GLWECiphertext::encrypt_sk_scratch_space(&module, ct_rlwe_in.size()) + GGSWCiphertext::encrypt_sk_scratch_space(&module, basek, ct_ggsw.k(), rank) + | GLWECiphertext::encrypt_sk_scratch_space(&module, basek, ct_glwe_in.k()) | GLWECiphertext::external_product_scratch_space( &module, - ct_rlwe_out.size(), - ct_rlwe_in.size(), - ct_rgsw.size(), + basek, + ct_glwe_out.k(), + ct_glwe_in.k(), + ct_ggsw.k(), rank, ), ); @@ -59,7 +60,7 @@ fn bench_external_product_glwe_fft64(c: &mut Criterion) { let mut sk_dft: SecretKeyFourier, FFT64> = SecretKeyFourier::alloc(&module, rank); sk_dft.dft(&module, &sk); - ct_rgsw.encrypt_sk( + ct_ggsw.encrypt_sk( &module, &pt_rgsw, &sk_dft, @@ -69,7 +70,7 @@ fn bench_external_product_glwe_fft64(c: &mut Criterion) { scratch.borrow(), ); - ct_rlwe_in.encrypt_zero_sk( + ct_glwe_in.encrypt_zero_sk( &module, &sk_dft, &mut source_xa, @@ -79,10 +80,10 @@ fn bench_external_product_glwe_fft64(c: &mut Criterion) { ); move || { - ct_rlwe_out.external_product( + ct_glwe_out.external_product( black_box(&module), - black_box(&ct_rlwe_in), - black_box(&ct_rgsw), + black_box(&ct_glwe_in), + black_box(&ct_ggsw), black_box(scratch.borrow()), ); } @@ -128,14 +129,14 @@ fn bench_external_product_glwe_inplace_fft64(c: &mut Criterion) { let rows: usize = (p.k_ct + p.basek - 1) / p.basek; let sigma: f64 = 3.2; - let mut ct_rgsw: GGSWCiphertext, FFT64> = GGSWCiphertext::alloc(&module, basek, k_ggsw, rows, rank); - let mut ct_rlwe: GLWECiphertext> = GLWECiphertext::alloc(&module, basek, k_glwe, rank); + let mut ct_ggsw: GGSWCiphertext, FFT64> = GGSWCiphertext::alloc(&module, basek, k_ggsw, rows, rank); + let mut ct_glwe: GLWECiphertext> = GLWECiphertext::alloc(&module, basek, k_glwe, rank); let pt_rgsw: ScalarZnx> = module.new_scalar_znx(1); let mut scratch = ScratchOwned::new( - 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(), rank), + GGSWCiphertext::encrypt_sk_scratch_space(&module, basek, ct_ggsw.k(), rank) + | GLWECiphertext::encrypt_sk_scratch_space(&module, basek, ct_glwe.k()) + | GLWECiphertext::external_product_inplace_scratch_space(&module, basek, ct_glwe.k(), ct_ggsw.k(), rank), ); let mut source_xs = Source::new([0u8; 32]); @@ -147,7 +148,7 @@ fn bench_external_product_glwe_inplace_fft64(c: &mut Criterion) { let mut sk_dft: SecretKeyFourier, FFT64> = SecretKeyFourier::alloc(&module, rank); sk_dft.dft(&module, &sk); - ct_rgsw.encrypt_sk( + ct_ggsw.encrypt_sk( &module, &pt_rgsw, &sk_dft, @@ -157,7 +158,7 @@ fn bench_external_product_glwe_inplace_fft64(c: &mut Criterion) { scratch.borrow(), ); - ct_rlwe.encrypt_zero_sk( + ct_glwe.encrypt_zero_sk( &module, &sk_dft, &mut source_xa, @@ -169,9 +170,9 @@ fn bench_external_product_glwe_inplace_fft64(c: &mut Criterion) { move || { let scratch_borrow = scratch.borrow(); (0..687).for_each(|_| { - ct_rlwe.external_product_inplace( + ct_glwe.external_product_inplace( black_box(&module), - black_box(&ct_rgsw), + black_box(&ct_ggsw), black_box(scratch_borrow), ); }); diff --git a/core/benches/keyswitch_glwe_fft64.rs b/core/benches/keyswitch_glwe_fft64.rs index 688da18..cee1bd5 100644 --- a/core/benches/keyswitch_glwe_fft64.rs +++ b/core/benches/keyswitch_glwe_fft64.rs @@ -40,13 +40,14 @@ fn bench_keyswitch_glwe_fft64(c: &mut Criterion) { let mut ct_out: GLWECiphertext> = GLWECiphertext::alloc(&module, basek, k_rlwe_out, rank_out); let mut scratch = ScratchOwned::new( - GLWESwitchingKey::encrypt_sk_scratch_space(&module, rank_out, ksk.size()) - | GLWECiphertext::encrypt_sk_scratch_space(&module, ct_in.size()) + GLWESwitchingKey::encrypt_sk_scratch_space(&module, basek, ksk.k(), rank_out) + | GLWECiphertext::encrypt_sk_scratch_space(&module, basek, ct_in.k()) | GLWECiphertext::keyswitch_scratch_space( &module, - ct_out.size(), - ct_in.size(), - ksk.size(), + basek, + ct_out.k(), + ct_in.k(), + ksk.k(), rank_in, rank_out, ), @@ -140,9 +141,9 @@ fn bench_keyswitch_glwe_inplace_fft64(c: &mut Criterion) { let mut ct: GLWECiphertext> = GLWECiphertext::alloc(&module, basek, k_ct, rank); let mut scratch = ScratchOwned::new( - 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), + GLWESwitchingKey::encrypt_sk_scratch_space(&module, basek, ksk.k(), rank) + | GLWECiphertext::encrypt_sk_scratch_space(&module, basek, ct.k()) + | GLWECiphertext::keyswitch_inplace_scratch_space(&module, basek, ct.k(), rank, ksk.k()), ); let mut source_xs: Source = Source::new([0u8; 32]); diff --git a/core/src/automorphism.rs b/core/src/automorphism.rs index 1df916e..28daa56 100644 --- a/core/src/automorphism.rs +++ b/core/src/automorphism.rs @@ -1,6 +1,6 @@ use backend::{ Backend, FFT64, MatZnxDft, MatZnxDftOps, Module, ScalarZnxDftAlloc, ScalarZnxDftOps, ScalarZnxOps, Scratch, VecZnx, - VecZnxBigAlloc, VecZnxDftAlloc, VecZnxDftOps, VecZnxOps, ZnxZero, + VecZnxDftOps, VecZnxOps, ZnxZero, }; use sampling::source::Source; @@ -86,63 +86,79 @@ impl + AsRef<[u8]>> SetRow for AutomorphismKey { } impl AutomorphismKey, FFT64> { - pub fn generate_from_sk_scratch_space(module: &Module, rank: usize, size: usize) -> usize { - GGLWECiphertext::generate_from_sk_scratch_space(module, rank, size) + module.bytes_of_scalar_znx_dft(rank) + pub fn generate_from_sk_scratch_space(module: &Module, basek: usize, k: usize, rank: usize) -> usize { + GGLWECiphertext::generate_from_sk_scratch_space(module, basek, k, rank) + module.bytes_of_scalar_znx_dft(rank) } - pub fn generate_from_pk_scratch_space(module: &Module, rank: usize, pk_size: usize) -> usize { - GGLWECiphertext::generate_from_pk_scratch_space(module, rank, pk_size) + pub fn generate_from_pk_scratch_space(module: &Module, _basek: usize, _k: usize, _rank: usize) -> usize { + GGLWECiphertext::generate_from_pk_scratch_space(module, _basek, _k, _rank) } pub fn keyswitch_scratch_space( module: &Module, - out_size: usize, - in_size: usize, - ksk_size: usize, + basek: usize, + out_k: usize, + in_k: usize, + ksk_k: usize, rank: usize, ) -> usize { - GLWESwitchingKey::keyswitch_scratch_space(module, out_size, rank, in_size, rank, ksk_size) + GLWESwitchingKey::keyswitch_scratch_space(module, basek, out_k, rank, in_k, rank, ksk_k) } - pub fn keyswitch_inplace_scratch_space(module: &Module, out_size: usize, out_rank: usize, ksk_size: usize) -> usize { - GLWESwitchingKey::keyswitch_inplace_scratch_space(module, out_size, out_rank, ksk_size) + pub fn keyswitch_inplace_scratch_space( + module: &Module, + basek: usize, + out_k: usize, + out_rank: usize, + ksk_k: usize, + ) -> usize { + GLWESwitchingKey::keyswitch_inplace_scratch_space(module, basek, out_k, out_rank, ksk_k) } pub fn automorphism_scratch_space( module: &Module, - out_size: usize, - in_size: usize, - ksk_size: usize, + basek: usize, + out_k: usize, + in_k: usize, + atk_k: usize, rank: usize, ) -> usize { - let tmp_dft: usize = module.bytes_of_vec_znx_dft(rank + 1, in_size); - let tmp_idft: usize = module.bytes_of_vec_znx_big(rank + 1, out_size); + let tmp_dft: usize = GLWECiphertextFourier::bytes_of(module, basek, in_k, rank); + let tmp_idft: usize = GLWECiphertextFourier::bytes_of(module, basek, out_k, rank); let idft: usize = module.vec_znx_idft_tmp_bytes(); - let keyswitch: usize = GLWECiphertext::keyswitch_inplace_scratch_space(module, out_size, rank, ksk_size); + let keyswitch: usize = GLWECiphertext::keyswitch_inplace_scratch_space(module, basek, out_k, rank, atk_k); tmp_dft + tmp_idft + idft + keyswitch } - pub fn automorphism_inplace_scratch_space(module: &Module, out_size: usize, ksk_size: usize, rank: usize) -> usize { - AutomorphismKey::automorphism_scratch_space(module, out_size, out_size, ksk_size, rank) + pub fn automorphism_inplace_scratch_space( + module: &Module, + basek: usize, + out_k: usize, + ksk_k: usize, + rank: usize, + ) -> usize { + AutomorphismKey::automorphism_scratch_space(module, basek, out_k, out_k, ksk_k, rank) } pub fn external_product_scratch_space( module: &Module, - out_size: usize, - in_size: usize, - ggsw_size: usize, + basek: usize, + out_k: usize, + in_k: usize, + ggsw_k: usize, rank: usize, ) -> usize { - GLWESwitchingKey::external_product_scratch_space(module, out_size, in_size, ggsw_size, rank) + GLWESwitchingKey::external_product_scratch_space(module, basek, out_k, in_k, ggsw_k, rank) } pub fn external_product_inplace_scratch_space( module: &Module, - out_size: usize, - ggsw_size: usize, + basek: usize, + out_k: usize, + ggsw_k: usize, rank: usize, ) -> usize { - GLWESwitchingKey::external_product_inplace_scratch_space(module, out_size, ggsw_size, rank) + GLWESwitchingKey::external_product_inplace_scratch_space(module, basek, out_k, ggsw_k, rank) } } @@ -164,13 +180,14 @@ impl + AsRef<[u8]>> AutomorphismKey { assert_eq!(self.rank_out(), self.rank_in()); assert_eq!(sk.rank(), self.rank()); assert!( - scratch.available() >= AutomorphismKey::generate_from_sk_scratch_space(module, self.rank(), self.size()), + scratch.available() + >= AutomorphismKey::generate_from_sk_scratch_space(module, self.basek(), self.k(), self.rank()), "scratch.available(): {} < AutomorphismKey::generate_from_sk_scratch_space(module, self.rank()={}, \ self.size()={}): {}", scratch.available(), self.rank(), self.size(), - AutomorphismKey::generate_from_sk_scratch_space(module, self.rank(), self.size()) + AutomorphismKey::generate_from_sk_scratch_space(module, self.basek(), self.k(), self.rank()) ) } diff --git a/core/src/gglwe_ciphertext.rs b/core/src/gglwe_ciphertext.rs index dd4a6ff..c18f08c 100644 --- a/core/src/gglwe_ciphertext.rs +++ b/core/src/gglwe_ciphertext.rs @@ -57,14 +57,15 @@ impl GGLWECiphertext { } impl GGLWECiphertext, FFT64> { - pub fn generate_from_sk_scratch_space(module: &Module, rank: usize, size: usize) -> usize { - GLWECiphertext::encrypt_sk_scratch_space(module, size) + pub fn generate_from_sk_scratch_space(module: &Module, basek: usize, k: usize, rank: usize) -> usize { + let size = derive_size(basek, k); + GLWECiphertext::encrypt_sk_scratch_space(module, basek, k) + module.bytes_of_vec_znx(rank + 1, size) + module.bytes_of_vec_znx(1, size) + module.bytes_of_vec_znx_dft(rank + 1, size) } - pub fn generate_from_pk_scratch_space(_module: &Module, _rank: usize, _pk_size: usize) -> usize { + pub fn generate_from_pk_scratch_space(_module: &Module, _basek: usize, _k: usize, _rank: usize) -> usize { unimplemented!() } } @@ -88,13 +89,14 @@ impl + AsRef<[u8]>> GGLWECiphertext { assert_eq!(sk_dft.n(), module.n()); assert_eq!(pt.n(), module.n()); assert!( - scratch.available() >= GGLWECiphertext::generate_from_sk_scratch_space(module, self.rank(), self.size()), + scratch.available() + >= GGLWECiphertext::generate_from_sk_scratch_space(module, self.basek(), self.k(), self.rank()), "scratch.available: {} < GGLWECiphertext::generate_from_sk_scratch_space(module, self.rank()={}, \ self.size()={}): {}", scratch.available(), self.rank(), self.size(), - GGLWECiphertext::generate_from_sk_scratch_space(module, self.rank(), self.size()) + GGLWECiphertext::generate_from_sk_scratch_space(module, self.basek(), self.k(), self.rank()) ) } diff --git a/core/src/ggsw_ciphertext.rs b/core/src/ggsw_ciphertext.rs index 43e9f34..6de21c9 100644 --- a/core/src/ggsw_ciphertext.rs +++ b/core/src/ggsw_ciphertext.rs @@ -60,8 +60,9 @@ impl GGSWCiphertext { } impl GGSWCiphertext, FFT64> { - pub fn encrypt_sk_scratch_space(module: &Module, rank: usize, size: usize) -> usize { - GLWECiphertext::encrypt_sk_scratch_space(module, size) + pub fn encrypt_sk_scratch_space(module: &Module, basek: usize, k: usize, rank: usize) -> usize { + let size = derive_size(basek, k); + GLWECiphertext::encrypt_sk_scratch_space(module, basek, k) + module.bytes_of_vec_znx(rank + 1, size) + module.bytes_of_vec_znx(1, size) + module.bytes_of_vec_znx_dft(rank + 1, size) @@ -69,112 +70,116 @@ impl GGSWCiphertext, FFT64> { pub(crate) fn expand_row_scratch_space( module: &Module, - self_size: usize, - tensor_key_size: usize, + basek: usize, + self_k: usize, + tsk_k: usize, rank: usize, ) -> usize { - let tmp_dft_i: usize = module.bytes_of_vec_znx_dft(rank + 1, tensor_key_size); + let tsk_size: usize = derive_size(basek, tsk_k); + let self_size: usize = derive_size(basek, self_k); + let tmp_dft_i: usize = module.bytes_of_vec_znx_dft(rank + 1, tsk_size); let tmp_dft_col_data: usize = module.bytes_of_vec_znx_dft(1, self_size); - let vmp: usize = - tmp_dft_col_data + module.vmp_apply_tmp_bytes(self_size, self_size, self_size, rank, rank, tensor_key_size); - let tmp_idft: usize = module.bytes_of_vec_znx_big(1, tensor_key_size); + let vmp: usize = tmp_dft_col_data + module.vmp_apply_tmp_bytes(self_size, self_size, self_size, rank, rank, tsk_size); + let tmp_idft: usize = module.bytes_of_vec_znx_big(1, tsk_size); let norm: usize = module.vec_znx_big_normalize_tmp_bytes(); tmp_dft_i + ((tmp_dft_col_data + vmp) | (tmp_idft + norm)) } pub(crate) fn keyswitch_internal_col0_scratch_space( module: &Module, - out_size: usize, - in_size: usize, - ksk_size: usize, + basek: usize, + out_k: usize, + in_k: usize, + ksk_k: usize, rank: usize, ) -> usize { - GLWECiphertext::keyswitch_from_fourier_scratch_space(module, out_size, rank, in_size, rank, ksk_size) - + module.bytes_of_vec_znx_dft(rank + 1, in_size) + GLWECiphertext::keyswitch_from_fourier_scratch_space(module, basek, out_k, rank, in_k, rank, ksk_k) + + module.bytes_of_vec_znx_dft(rank + 1, derive_size(basek, in_k)) } pub fn keyswitch_scratch_space( module: &Module, - out_size: usize, - in_size: usize, - ksk_size: usize, - tensor_key_size: usize, + basek: usize, + out_k: usize, + in_k: usize, + ksk_k: usize, + tsk_k: usize, rank: usize, ) -> usize { + let out_size: usize = derive_size(basek, out_k); + let res_znx: usize = module.bytes_of_vec_znx(rank + 1, out_size); let ci_dft: usize = module.bytes_of_vec_znx_dft(rank + 1, out_size); - let ks: usize = GGSWCiphertext::keyswitch_internal_col0_scratch_space(module, out_size, in_size, ksk_size, rank); - let expand_rows: usize = GGSWCiphertext::expand_row_scratch_space(module, out_size, tensor_key_size, rank); + let ks: usize = GGSWCiphertext::keyswitch_internal_col0_scratch_space(module, basek, out_k, in_k, ksk_k, rank); + let expand_rows: usize = GGSWCiphertext::expand_row_scratch_space(module, basek, out_k, tsk_k, rank); let res_dft: usize = module.bytes_of_vec_znx_dft(rank + 1, out_size); res_znx + ci_dft + (ks | expand_rows | res_dft) } pub fn keyswitch_inplace_scratch_space( module: &Module, - out_size: usize, - ksk_size: usize, - tensor_key_size: usize, + basek: usize, + out_k: usize, + ksk_k: usize, + tsk_k: usize, rank: usize, ) -> usize { - GGSWCiphertext::keyswitch_scratch_space(module, out_size, out_size, ksk_size, tensor_key_size, rank) + GGSWCiphertext::keyswitch_scratch_space(module, basek, out_k, out_k, ksk_k, tsk_k, rank) } pub fn automorphism_scratch_space( module: &Module, - out_size: usize, - in_size: usize, - auto_key_size: usize, - tensor_key_size: usize, + basek: usize, + out_k: usize, + in_k: usize, + atk_k: usize, + tsk_k: usize, rank: usize, ) -> usize { let cols: usize = rank + 1; + let out_size: usize = derive_size(basek, out_k); let res: usize = module.bytes_of_vec_znx(cols, out_size); let res_dft: usize = module.bytes_of_vec_znx_dft(cols, out_size); let ci_dft: usize = module.bytes_of_vec_znx_dft(cols, out_size); - let ks_internal: usize = - GGSWCiphertext::keyswitch_internal_col0_scratch_space(module, out_size, in_size, auto_key_size, rank); - let expand: usize = GGSWCiphertext::expand_row_scratch_space(module, out_size, tensor_key_size, rank); + let ks_internal: usize = GGSWCiphertext::keyswitch_internal_col0_scratch_space(module, basek, out_k, in_k, atk_k, rank); + let expand: usize = GGSWCiphertext::expand_row_scratch_space(module, basek, out_k, tsk_k, rank); res + ci_dft + (ks_internal | expand | res_dft) } pub fn automorphism_inplace_scratch_space( module: &Module, - out_size: usize, - auto_key_size: usize, - tensor_key_size: usize, + basek: usize, + out_k: usize, + atk_k: usize, + tsk_k: usize, rank: usize, ) -> usize { - GGSWCiphertext::automorphism_scratch_space( - module, - out_size, - out_size, - auto_key_size, - tensor_key_size, - rank, - ) + GGSWCiphertext::automorphism_scratch_space(module, basek, out_k, out_k, atk_k, tsk_k, rank) } pub fn external_product_scratch_space( module: &Module, - out_size: usize, - in_size: usize, - ggsw_size: usize, + basek: usize, + out_k: usize, + in_k: usize, + ggsw_k: usize, rank: usize, ) -> usize { - let tmp_in: usize = module.bytes_of_vec_znx_dft(rank + 1, in_size); - let tmp_out: usize = module.bytes_of_vec_znx_dft(rank + 1, out_size); - let ggsw: usize = GLWECiphertextFourier::external_product_scratch_space(module, out_size, in_size, ggsw_size, rank); + let tmp_in: usize = GLWECiphertextFourier::bytes_of(module, basek, in_k, rank); + let tmp_out: usize = GLWECiphertextFourier::bytes_of(module, basek, out_k, rank); + let ggsw: usize = GLWECiphertextFourier::external_product_scratch_space(module, basek, out_k, in_k, ggsw_k, rank); tmp_in + tmp_out + ggsw } pub fn external_product_inplace_scratch_space( module: &Module, - out_size: usize, - ggsw_size: usize, + basek: usize, + out_k: usize, + ggsw_k: usize, rank: usize, ) -> usize { - let tmp: usize = module.bytes_of_vec_znx_dft(rank + 1, out_size); - let ggsw: usize = GLWECiphertextFourier::external_product_inplace_scratch_space(module, out_size, ggsw_size, rank); + let tmp: usize = GLWECiphertextFourier::bytes_of(module, basek, out_k, rank); + let ggsw: usize = GLWECiphertextFourier::external_product_inplace_scratch_space(module, basek, out_k, ggsw_k, rank); tmp + ggsw } } @@ -248,7 +253,9 @@ impl + AsRef<[u8]>> GGSWCiphertext { { let cols: usize = self.rank() + 1; - assert!(scratch.available() >= GGSWCiphertext::expand_row_scratch_space(module, self.size(), tsk.size(), tsk.rank())); + assert!( + scratch.available() >= GGSWCiphertext::expand_row_scratch_space(module, self.basek(), self.k(), tsk.k(), self.rank()) + ); // Example for rank 3: // @@ -414,10 +421,11 @@ impl + AsRef<[u8]>> GGSWCiphertext { scratch.available() >= GGSWCiphertext::automorphism_scratch_space( module, - self.size(), - lhs.size(), - auto_key.size(), - tensor_key.size(), + self.basek(), + self.k(), + lhs.k(), + auto_key.k(), + tensor_key.k(), self.rank() ) ) @@ -570,9 +578,10 @@ impl> GGSWCiphertext { scratch.available() >= GGSWCiphertext::keyswitch_internal_col0_scratch_space( module, - res.size(), - self.size(), - ksk.size(), + self.basek(), + res.k(), + self.k(), + ksk.k(), ksk.rank() ) ) diff --git a/core/src/glwe_ciphertext.rs b/core/src/glwe_ciphertext.rs index a01c41c..50d988d 100644 --- a/core/src/glwe_ciphertext.rs +++ b/core/src/glwe_ciphertext.rs @@ -76,106 +76,117 @@ impl> GLWECiphertext { } impl GLWECiphertext> { - pub fn encrypt_sk_scratch_space(module: &Module, 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(1, ct_size) + pub fn encrypt_sk_scratch_space(module: &Module, basek: usize, k: usize) -> usize { + let size: usize = derive_size(basek, k); + module.vec_znx_big_normalize_tmp_bytes() + module.bytes_of_vec_znx_dft(1, size) + module.bytes_of_vec_znx(1, size) } - pub fn encrypt_pk_scratch_space(module: &Module, 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)) + pub fn encrypt_pk_scratch_space(module: &Module, basek: usize, k: usize) -> usize { + let size: usize = derive_size(basek, k); + ((module.bytes_of_vec_znx_dft(1, size) + module.bytes_of_vec_znx_big(1, size)) | module.bytes_of_scalar_znx(1)) + module.bytes_of_scalar_znx_dft(1) + module.vec_znx_big_normalize_tmp_bytes() } - pub fn decrypt_scratch_space(module: &Module, 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 decrypt_scratch_space(module: &Module, basek: usize, k: usize) -> usize { + let size: usize = derive_size(basek, k); + (module.vec_znx_big_normalize_tmp_bytes() | module.bytes_of_vec_znx_dft(1, size)) + module.bytes_of_vec_znx_big(1, size) } pub fn keyswitch_scratch_space( module: &Module, - out_size: usize, + basek: usize, + out_k: usize, out_rank: usize, - in_size: usize, + in_k: usize, in_rank: usize, - ksk_size: usize, + ksk_k: usize, ) -> usize { - let res_dft: usize = module.bytes_of_vec_znx_dft(out_rank + 1, ksk_size); + let res_dft: usize = GLWECiphertextFourier::bytes_of(module, basek, out_k, out_rank); + let in_size: usize = derive_size(basek, in_k); + let out_size: usize = derive_size(basek, out_k); + let ksk_size: usize = derive_size(basek, ksk_k); let vmp: usize = module.vmp_apply_tmp_bytes(out_size, in_size, in_size, in_rank, out_rank + 1, ksk_size) + module.bytes_of_vec_znx_dft(in_rank, in_size); let normalize: usize = module.vec_znx_big_normalize_tmp_bytes(); - return res_dft + (vmp | normalize); } pub fn keyswitch_from_fourier_scratch_space( module: &Module, - out_size: usize, + basek: usize, + out_k: usize, out_rank: usize, - in_size: usize, + in_k: usize, in_rank: usize, - ksk_size: usize, + ksk_k: usize, ) -> usize { - let res_dft = module.bytes_of_vec_znx_dft(out_rank + 1, ksk_size); - - let vmp: usize = module.vmp_apply_tmp_bytes(out_size, in_size, in_size, in_rank, out_rank + 1, ksk_size) - + module.bytes_of_vec_znx_dft(in_rank, in_size); - - let norm: usize = module.vec_znx_big_normalize_tmp_bytes(); - - res_dft + (vmp | norm) + Self::keyswitch_scratch_space(module, basek, out_k, out_rank, in_k, in_rank, ksk_k) } - pub fn keyswitch_inplace_scratch_space(module: &Module, out_size: usize, out_rank: usize, ksk_size: usize) -> usize { - GLWECiphertext::keyswitch_scratch_space(module, out_size, out_rank, out_size, out_rank, ksk_size) + pub fn keyswitch_inplace_scratch_space( + module: &Module, + basek: usize, + out_k: usize, + out_rank: usize, + ksk_k: usize, + ) -> usize { + Self::keyswitch_scratch_space(module, basek, out_k, out_rank, out_k, out_rank, ksk_k) } pub fn automorphism_scratch_space( module: &Module, - out_size: usize, - out_rank: usize, - in_size: usize, - autokey_size: usize, + basek: usize, + out_k: usize, + in_k: usize, + atk_k: usize, + rank: usize, ) -> usize { - GLWECiphertext::keyswitch_scratch_space(module, out_size, out_rank, in_size, out_rank, autokey_size) + Self::keyswitch_scratch_space(module, basek, out_k, rank, in_k, rank, atk_k) } pub fn automorphism_inplace_scratch_space( module: &Module, - out_size: usize, - out_rank: usize, - autokey_size: usize, + basek: usize, + out_k: usize, + atk_k: usize, + rank: usize, ) -> usize { - GLWECiphertext::keyswitch_scratch_space(module, out_size, out_rank, out_size, out_rank, autokey_size) + Self::keyswitch_scratch_space(module, basek, out_k, rank, out_k, rank, atk_k) } pub fn external_product_scratch_space( module: &Module, - out_size: usize, - out_rank: usize, - in_size: usize, - ggsw_size: usize, + basek: usize, + out_k: usize, + in_k: usize, + ggsw_k: usize, + rank: usize, ) -> usize { - let res_dft: usize = module.bytes_of_vec_znx_dft(out_rank + 1, ggsw_size); - let vmp: usize = module.bytes_of_vec_znx_dft(out_rank + 1, in_size) + let res_dft: usize = GLWECiphertextFourier::bytes_of(module, basek, out_k, rank); + let in_size: usize = derive_size(basek, in_k); + let out_size: usize = derive_size(basek, out_k); + let ggsw_size: usize = derive_size(basek, ggsw_k); + let vmp: usize = module.bytes_of_vec_znx_dft(rank + 1, in_size) + module.vmp_apply_tmp_bytes( out_size, in_size, - in_size, // rows - out_rank + 1, // cols in - out_rank + 1, // cols out + in_size, // rows + rank + 1, // cols in + rank + 1, // cols out ggsw_size, ); let normalize: usize = module.vec_znx_big_normalize_tmp_bytes(); - res_dft + (vmp | normalize) } pub fn external_product_inplace_scratch_space( module: &Module, - out_size: usize, - out_rank: usize, - ggsw_size: usize, + basek: usize, + out_k: usize, + ggsw_k: usize, + rank: usize, ) -> usize { - GLWECiphertext::external_product_scratch_space(module, out_size, out_rank, out_size, ggsw_size) + Self::external_product_scratch_space(module, basek, out_k, out_k, ggsw_k, rank) } } @@ -385,11 +396,12 @@ impl + AsMut<[u8]>> GLWECiphertext { scratch.available() >= GLWECiphertext::keyswitch_from_fourier_scratch_space( module, - self.size(), + self.basek(), + self.k(), self.rank(), - lhs.size(), + lhs.k(), lhs.rank(), - rhs.size(), + rhs.k(), ) ); } @@ -452,11 +464,12 @@ impl + AsMut<[u8]>> GLWECiphertext { scratch.available() >= GLWECiphertext::keyswitch_scratch_space( module, - self.size(), + self.basek(), + self.k(), self.rank(), - lhs.size(), + lhs.k(), lhs.rank(), - rhs.size(), + rhs.k(), ) ); } @@ -576,10 +589,10 @@ impl + AsMut<[u8]>> GLWECiphertext { assert!(col < self.rank() + 1); } assert!( - scratch.available() >= GLWECiphertext::encrypt_sk_scratch_space(module, self.size()), + scratch.available() >= GLWECiphertext::encrypt_sk_scratch_space(module, self.basek(), self.k()), "scratch.available(): {} < GLWECiphertext::encrypt_sk_scratch_space: {}", scratch.available(), - GLWECiphertext::encrypt_sk_scratch_space(module, self.size()) + GLWECiphertext::encrypt_sk_scratch_space(module, self.basek(), self.k()) ) } diff --git a/core/src/glwe_ciphertext_fourier.rs b/core/src/glwe_ciphertext_fourier.rs index 19f37f1..3ae7704 100644 --- a/core/src/glwe_ciphertext_fourier.rs +++ b/core/src/glwe_ciphertext_fourier.rs @@ -53,59 +53,72 @@ impl GLWECiphertextFourier { impl GLWECiphertextFourier, FFT64> { #[allow(dead_code)] - pub(crate) fn idft_scratch_space(module: &Module, size: usize) -> usize { - module.bytes_of_vec_znx(1, size) + (module.vec_znx_big_normalize_tmp_bytes() | module.vec_znx_idft_tmp_bytes()) + pub(crate) fn idft_scratch_space(module: &Module, basek: usize, k: usize) -> usize { + module.bytes_of_vec_znx(1, derive_size(basek, k)) + + (module.vec_znx_big_normalize_tmp_bytes() | module.vec_znx_idft_tmp_bytes()) } - pub fn encrypt_sk_scratch_space(module: &Module, rank: usize, ct_size: usize) -> usize { - module.bytes_of_vec_znx(rank + 1, ct_size) + GLWECiphertext::encrypt_sk_scratch_space(module, ct_size) + pub fn encrypt_sk_scratch_space(module: &Module, basek: usize, k: usize, rank: usize) -> usize { + module.bytes_of_vec_znx(rank + 1, derive_size(basek, k)) + GLWECiphertext::encrypt_sk_scratch_space(module, basek, k) } - pub fn decrypt_scratch_space(module: &Module, ct_size: usize) -> usize { + pub fn decrypt_scratch_space(module: &Module, basek: usize, k: usize) -> usize { + let size: usize = derive_size(basek, k); (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) + module.vec_znx_idft_tmp_bytes())) - + module.bytes_of_vec_znx_big(1, ct_size) + | module.bytes_of_vec_znx_dft(1, size) + | (module.bytes_of_vec_znx_big(1, size) + module.vec_znx_idft_tmp_bytes())) + + module.bytes_of_vec_znx_big(1, size) } pub fn keyswitch_scratch_space( module: &Module, - out_size: usize, + basek: usize, + out_k: usize, out_rank: usize, - in_size: usize, + in_k: usize, in_rank: usize, - ksk_size: usize, + ksk_k: usize, ) -> usize { - module.bytes_of_vec_znx(out_rank + 1, out_size) - + GLWECiphertext::keyswitch_from_fourier_scratch_space(module, out_size, out_rank, in_size, in_rank, ksk_size) + GLWECiphertext::bytes_of(module, basek, out_k, out_rank) + + GLWECiphertext::keyswitch_from_fourier_scratch_space(module, basek, out_k, out_rank, in_k, in_rank, ksk_k) } - pub fn keyswitch_inplace_scratch_space(module: &Module, out_size: usize, out_rank: usize, ksk_size: usize) -> usize { - Self::keyswitch_scratch_space(module, out_size, out_rank, out_size, out_rank, ksk_size) + pub fn keyswitch_inplace_scratch_space( + module: &Module, + basek: usize, + out_k: usize, + out_rank: usize, + ksk_k: usize, + ) -> usize { + Self::keyswitch_scratch_space(module, basek, out_k, out_rank, out_k, out_rank, ksk_k) } pub fn external_product_scratch_space( module: &Module, - out_size: usize, - in_size: usize, - ggsw_size: usize, + basek: usize, + out_k: usize, + in_k: usize, + ggsw_k: usize, rank: usize, ) -> usize { - let res_dft: usize = module.bytes_of_vec_znx_dft(rank + 1, out_size); + let res_dft: usize = GLWECiphertextFourier::bytes_of(module, basek, out_k, rank); + let out_size: usize = derive_size(basek, out_k); + let in_size: usize = derive_size(basek, in_k); + let ggsw_size: usize = derive_size(basek, ggsw_k); let vmp: usize = module.vmp_apply_tmp_bytes(out_size, in_size, in_size, rank + 1, rank + 1, ggsw_size); - let res_small: usize = module.bytes_of_vec_znx(rank + 1, out_size); + let res_small: usize = GLWECiphertext::bytes_of(module, basek, out_k, rank); let normalize: usize = module.vec_znx_big_normalize_tmp_bytes(); - res_dft + (vmp | (res_small + normalize)) } pub fn external_product_inplace_scratch_space( module: &Module, - out_size: usize, - ggsw_size: usize, + basek: usize, + out_k: usize, + ggsw_k: usize, rank: usize, ) -> usize { - Self::external_product_scratch_space(module, out_size, out_size, ggsw_size, rank) + Self::external_product_scratch_space(module, basek, out_k, out_k, ggsw_k, rank) } } diff --git a/core/src/glwe_packing.rs b/core/src/glwe_packing.rs index 54583ad..3b6cdc0 100644 --- a/core/src/glwe_packing.rs +++ b/core/src/glwe_packing.rs @@ -1,7 +1,7 @@ use crate::{ScratchCore, automorphism::AutomorphismKey, elem::Infos, glwe_ciphertext::GLWECiphertext, glwe_ops::GLWEOps}; use std::collections::HashMap; -use backend::{FFT64, Module, Scratch, VecZnxAlloc}; +use backend::{FFT64, Module, Scratch}; /// [StreamPacker] enables only the fly GLWE packing /// with constant memory of Log(N) ciphertexts. @@ -74,8 +74,8 @@ impl StreamPacker { } /// Number of scratch space bytes required to call [Self::add]. - pub fn scratch_space(module: &Module, ct_size: usize, autokey_size: usize, rank: usize) -> usize { - pack_core_scratch_space(module, ct_size, autokey_size, rank) + pub fn scratch_space(module: &Module, basek: usize, ct_k: usize, atk_k: usize, rank: usize) -> usize { + pack_core_scratch_space(module, basek, ct_k, atk_k, rank) } pub fn galois_elements(module: &Module) -> Vec { @@ -142,8 +142,8 @@ impl StreamPacker { } } -fn pack_core_scratch_space(module: &Module, ct_size: usize, autokey_size: usize, rank: usize) -> usize { - combine_scratch_space(module, ct_size, autokey_size, rank) +fn pack_core_scratch_space(module: &Module, basek: usize, ct_k: usize, atk_k: usize, rank: usize) -> usize { + combine_scratch_space(module, basek, ct_k, atk_k, rank) } fn pack_core, DataAK: AsRef<[u8]>>( @@ -203,10 +203,10 @@ fn pack_core, DataAK: AsRef<[u8]>>( } } -fn combine_scratch_space(module: &Module, ct_size: usize, autokey_size: usize, rank: usize) -> usize { - 2 * module.bytes_of_vec_znx(rank + 1, ct_size) +fn combine_scratch_space(module: &Module, basek: usize, ct_k: usize, atk_k: usize, rank: usize) -> usize { + GLWECiphertext::bytes_of(module, basek, ct_k, rank) + (GLWECiphertext::rsh_scratch_space(module) - | GLWECiphertext::automorphism_scratch_space(module, ct_size, rank, ct_size, autokey_size)) + | GLWECiphertext::automorphism_scratch_space(module, basek, ct_k, ct_k, atk_k, rank)) } /// [combine] merges two ciphertexts together. @@ -232,46 +232,52 @@ fn combine, DataAK: AsRef<[u8]>>( gal_el = module.galois_element(1 << (i - 1)) } - // Goal is to evaluate: a = a + b*X^t + phi(a - b*X^t)) X^t(a*X^-t + b - phi(a*X^-t + b)) - // Different cases for wether a and/or b are zero. - if acc.value { - // Implicite RSH without modulus switch, introduces extra I(X) * Q/2 on decryption. - // Necessary so that the scaling of the plaintext remains constant. - // It however is ok to do so here because coefficients are eventually - // either mapped to garbage or twice their value which vanishes I(X) - // since 2*(I(X) * Q/2) = I(X) * Q = 0 mod Q. - a.rsh(1, scratch); + let t: i64 = 1 << (log_n - i - 1); + // Goal is to evaluate: a = a + b*X^t + phi(a - b*X^t)) + // We also use the identity: AUTO(a * X^t, g) = -X^t * AUTO(a, g) + // where t = 2^(log_n - i - 1) and g = 5^{2^(i - 1)} + // Different cases for wether a and/or b are zero. + // + // Implicite RSH without modulus switch, introduces extra I(X) * Q/2 on decryption. + // Necessary so that the scaling of the plaintext remains constant. + // It however is ok to do so here because coefficients are eventually + // either mapped to garbage or twice their value which vanishes I(X) + // since 2*(I(X) * Q/2) = I(X) * Q = 0 mod Q. + if acc.value { if let Some(b) = b { let (mut tmp_b, scratch_1) = scratch.tmp_glwe_ct(module, basek, k, rank); - { - let (mut tmp_a, scratch_2) = scratch_1.tmp_glwe_ct(module, basek, k, rank); //TODO can we skip tmp_a by reordering X^k ? - // tmp_a = b * X^t - tmp_a.rotate(module, 1 << (log_n - i - 1), b); + // a = a * X^-t + a.rotate_inplace(module, -t); - // tmp_a >>= 1 - tmp_a.rsh(1, scratch_2); + // tmp_b = a * X^-t - b + tmp_b.sub(module, a, b); + tmp_b.rsh(1, scratch_1); - // tmp_b = a - b*X^t - tmp_b.sub(module, a, &tmp_a); - tmp_b.normalize_inplace(module, scratch_2); + // a = a * X^-t + b + a.add_inplace(module, b); + a.rsh(1, scratch_1); - // a = a + b * X^t - a.add_inplace(module, &tmp_a); - } + tmp_b.normalize_inplace(module, scratch_1); - // tmp_b = phi(a - b * X^t) + // tmp_b = phi(a * X^-t - b) if let Some(key) = auto_keys.get(&gal_el) { tmp_b.automorphism_inplace(module, key, scratch_1); } else { panic!("auto_key[{}] not found", gal_el); } - // a = a + b*X^t + phi(a - b*X^t)) - a.add_inplace(module, &tmp_b); + // a = a * X^-t + b - phi(a * X^-t - b) + a.sub_inplace_ab(module, &tmp_b); a.normalize_inplace(module, scratch_1); + + // a = a + b * X^t - phi(a * X^-t - b) * X^t + // = a + b * X^t - phi(a * X^-t - b) * - phi(X^t) + // = a + b * X^t + phi(a - b * X^t) + a.rotate_inplace(module, t); } else { + a.rsh(1, scratch); // a = a + phi(a) if let Some(key) = auto_keys.get(&gal_el) { a.automorphism_add_inplace(module, key, scratch); diff --git a/core/src/keys.rs b/core/src/keys.rs index f48e7bb..beabef9 100644 --- a/core/src/keys.rs +++ b/core/src/keys.rs @@ -180,9 +180,11 @@ impl + AsMut<[u8]>> GLWEPublicKey { // Its ok to allocate scratch space here since pk is usually generated only once. let mut scratch: ScratchOwned = ScratchOwned::new(GLWECiphertextFourier::encrypt_sk_scratch_space( module, + self.basek(), + self.k(), self.rank(), - self.size(), )); + self.data.encrypt_zero_sk( module, sk_dft, diff --git a/core/src/keyswitch_key.rs b/core/src/keyswitch_key.rs index 2503176..10a06c0 100644 --- a/core/src/keyswitch_key.rs +++ b/core/src/keyswitch_key.rs @@ -1,4 +1,4 @@ -use backend::{Backend, FFT64, MatZnxDft, MatZnxDftOps, Module, Scratch, VecZnxDftAlloc, ZnxZero}; +use backend::{Backend, FFT64, MatZnxDft, MatZnxDftOps, Module, Scratch, ZnxZero}; use sampling::source::Source; use crate::{ @@ -79,55 +79,64 @@ impl + AsRef<[u8]>> SetRow for GLWESwitchingKey } impl GLWESwitchingKey, FFT64> { - pub fn encrypt_sk_scratch_space(module: &Module, rank: usize, size: usize) -> usize { - GGLWECiphertext::generate_from_sk_scratch_space(module, rank, size) + pub fn encrypt_sk_scratch_space(module: &Module, basek: usize, k: usize, rank: usize) -> usize { + GGLWECiphertext::generate_from_sk_scratch_space(module, basek, k, rank) } - pub fn encrypt_pk_scratch_space(module: &Module, rank: usize, pk_size: usize) -> usize { - GGLWECiphertext::generate_from_pk_scratch_space(module, rank, pk_size) + pub fn encrypt_pk_scratch_space(module: &Module, _basek: usize, _k: usize, _rank: usize) -> usize { + GGLWECiphertext::generate_from_pk_scratch_space(module, _basek, _k, _rank) } pub fn keyswitch_scratch_space( module: &Module, - out_size: usize, + basek: usize, + out_k: usize, out_rank: usize, - in_size: usize, + in_k: usize, in_rank: usize, - ksk_size: usize, + ksk_k: usize, ) -> usize { - let tmp_in: usize = module.bytes_of_vec_znx_dft(in_rank + 1, in_size); - let tmp_out: usize = module.bytes_of_vec_znx_dft(out_rank + 1, out_size); - let ksk: usize = GLWECiphertextFourier::keyswitch_scratch_space(module, out_size, out_rank, in_size, in_rank, ksk_size); + let tmp_in: usize = GLWECiphertextFourier::bytes_of(module, basek, in_k, in_rank); + let tmp_out: usize = GLWECiphertextFourier::bytes_of(module, basek, out_k, out_rank); + let ksk: usize = GLWECiphertextFourier::keyswitch_scratch_space(module, basek, out_k, out_rank, in_k, in_rank, ksk_k); tmp_in + tmp_out + ksk } - pub fn keyswitch_inplace_scratch_space(module: &Module, out_size: usize, out_rank: usize, ksk_size: usize) -> usize { - let tmp: usize = module.bytes_of_vec_znx_dft(out_rank + 1, out_size); - let ksk: usize = GLWECiphertextFourier::keyswitch_inplace_scratch_space(module, out_size, out_rank, ksk_size); + pub fn keyswitch_inplace_scratch_space( + module: &Module, + basek: usize, + out_k: usize, + out_rank: usize, + ksk_k: usize, + ) -> usize { + let tmp: usize = GLWECiphertextFourier::bytes_of(module, basek, out_k, out_rank); + let ksk: usize = GLWECiphertextFourier::keyswitch_inplace_scratch_space(module, basek, out_k, out_rank, ksk_k); tmp + ksk } pub fn external_product_scratch_space( module: &Module, - out_size: usize, - in_size: usize, - ggsw_size: usize, + basek: usize, + out_k: usize, + in_k: usize, + ggsw_k: usize, rank: usize, ) -> usize { - let tmp_in: usize = module.bytes_of_vec_znx_dft(rank + 1, in_size); - let tmp_out: usize = module.bytes_of_vec_znx_dft(rank + 1, out_size); - let ggsw: usize = GLWECiphertextFourier::external_product_scratch_space(module, out_size, in_size, ggsw_size, rank); + let tmp_in: usize = GLWECiphertextFourier::bytes_of(module, basek, in_k, rank); + let tmp_out: usize = GLWECiphertextFourier::bytes_of(module, basek, out_k, rank); + let ggsw: usize = GLWECiphertextFourier::external_product_scratch_space(module, basek, out_k, in_k, ggsw_k, rank); tmp_in + tmp_out + ggsw } pub fn external_product_inplace_scratch_space( module: &Module, - out_size: usize, - ggsw_size: usize, + basek: usize, + out_k: usize, + ggsw_k: usize, rank: usize, ) -> usize { - let tmp: usize = module.bytes_of_vec_znx_dft(rank + 1, out_size); - let ggsw: usize = GLWECiphertextFourier::external_product_inplace_scratch_space(module, out_size, ggsw_size, rank); + let tmp: usize = GLWECiphertextFourier::bytes_of(module, basek, out_k, rank); + let ggsw: usize = GLWECiphertextFourier::external_product_inplace_scratch_space(module, basek, out_k, ggsw_k, rank); tmp + ggsw } } diff --git a/core/src/tensor_key.rs b/core/src/tensor_key.rs index 8267a25..47c90eb 100644 --- a/core/src/tensor_key.rs +++ b/core/src/tensor_key.rs @@ -58,8 +58,8 @@ impl TensorKey { } impl TensorKey, FFT64> { - pub fn generate_from_sk_scratch_space(module: &Module, rank: usize, size: usize) -> usize { - module.bytes_of_scalar_znx_dft(1) + GLWESwitchingKey::encrypt_sk_scratch_space(module, rank, size) + pub fn generate_from_sk_scratch_space(module: &Module, basek: usize, k: usize, rank: usize) -> usize { + module.bytes_of_scalar_znx_dft(1) + GLWESwitchingKey::encrypt_sk_scratch_space(module, basek, k, rank) } } diff --git a/core/src/test_fft64/automorphism_key.rs b/core/src/test_fft64/automorphism_key.rs index cf4e983..546e13f 100644 --- a/core/src/test_fft64/automorphism_key.rs +++ b/core/src/test_fft64/automorphism_key.rs @@ -39,15 +39,9 @@ fn test_automorphism(p0: i64, p1: i64, log_n: usize, basek: usize, k_ksk: usize, let mut source_xa: Source = Source::new([0u8; 32]); let mut scratch: ScratchOwned = ScratchOwned::new( - AutomorphismKey::generate_from_sk_scratch_space(&module, rank, auto_key_in.size()) - | GLWECiphertextFourier::decrypt_scratch_space(&module, auto_key_out.size()) - | AutomorphismKey::automorphism_scratch_space( - &module, - auto_key_out.size(), - auto_key_in.size(), - auto_key_apply.size(), - rank, - ), + AutomorphismKey::generate_from_sk_scratch_space(&module, basek, k_ksk, rank) + | GLWECiphertextFourier::decrypt_scratch_space(&module, basek, k_ksk) + | AutomorphismKey::automorphism_scratch_space(&module, basek, k_ksk, k_ksk, k_ksk, rank), ); let mut sk: SecretKey> = SecretKey::alloc(&module, rank); @@ -132,7 +126,7 @@ fn test_automorphism(p0: i64, p1: i64, log_n: usize, basek: usize, k_ksk: usize, fn test_automorphism_inplace(p0: i64, p1: i64, log_n: usize, basek: usize, k_ksk: usize, sigma: f64, rank: usize) { let module: Module = Module::::new(1 << log_n); - let rows = (k_ksk + basek - 1) / basek; + let rows: usize = (k_ksk + basek - 1) / basek; let mut auto_key: AutomorphismKey, FFT64> = AutomorphismKey::alloc(&module, basek, k_ksk, rows, rank); let mut auto_key_apply: AutomorphismKey, FFT64> = AutomorphismKey::alloc(&module, basek, k_ksk, rows, rank); @@ -142,9 +136,9 @@ fn test_automorphism_inplace(p0: i64, p1: i64, log_n: usize, basek: usize, k_ksk let mut source_xa: Source = Source::new([0u8; 32]); let mut scratch: ScratchOwned = ScratchOwned::new( - AutomorphismKey::generate_from_sk_scratch_space(&module, rank, auto_key.size()) - | GLWECiphertextFourier::decrypt_scratch_space(&module, auto_key.size()) - | AutomorphismKey::automorphism_inplace_scratch_space(&module, auto_key.size(), auto_key_apply.size(), rank), + AutomorphismKey::generate_from_sk_scratch_space(&module, basek, k_ksk, rank) + | GLWECiphertextFourier::decrypt_scratch_space(&module, basek, k_ksk) + | AutomorphismKey::automorphism_inplace_scratch_space(&module, basek, k_ksk, k_ksk, rank), ); let mut sk: SecretKey> = SecretKey::alloc(&module, rank); diff --git a/core/src/test_fft64/gglwe.rs b/core/src/test_fft64/gglwe.rs index 06be1b3..e23e2d5 100644 --- a/core/src/test_fft64/gglwe.rs +++ b/core/src/test_fft64/gglwe.rs @@ -84,8 +84,8 @@ fn test_encrypt_sk(log_n: usize, basek: usize, k_ksk: usize, sigma: f64, rank_in let mut source_xa: Source = Source::new([0u8; 32]); let mut scratch: ScratchOwned = ScratchOwned::new( - GLWESwitchingKey::encrypt_sk_scratch_space(&module, rank_out, ksk.size()) - | GLWECiphertextFourier::decrypt_scratch_space(&module, ksk.size()), + GLWESwitchingKey::encrypt_sk_scratch_space(&module, basek, k_ksk, rank_out) + | GLWECiphertextFourier::decrypt_scratch_space(&module, basek, k_ksk), ); let mut sk_in: SecretKey> = SecretKey::alloc(&module, rank_in); @@ -148,15 +148,16 @@ fn test_key_switch( let mut source_xa: Source = Source::new([0u8; 32]); let mut scratch: ScratchOwned = ScratchOwned::new( - GLWESwitchingKey::encrypt_sk_scratch_space(&module, rank_in_s0s1 | rank_out_s0s1, ct_gglwe_s0s1.size()) - | GLWECiphertextFourier::decrypt_scratch_space(&module, ct_gglwe_s0s2.size()) + GLWESwitchingKey::encrypt_sk_scratch_space(&module, basek, k_ksk, rank_in_s0s1 | rank_out_s0s1) + | GLWECiphertextFourier::decrypt_scratch_space(&module, basek, k_ksk) | GLWESwitchingKey::keyswitch_scratch_space( &module, - ct_gglwe_s0s2.size(), + basek, + ct_gglwe_s0s2.k(), ct_gglwe_s0s2.rank(), - ct_gglwe_s0s1.size(), + ct_gglwe_s0s1.k(), ct_gglwe_s0s1.rank(), - ct_gglwe_s1s2.size(), + ct_gglwe_s1s2.k(), ), ); @@ -251,13 +252,14 @@ fn test_key_switch_inplace(log_n: usize, basek: usize, k_ksk: usize, sigma: f64, let mut source_xa: Source = Source::new([0u8; 32]); let mut scratch: ScratchOwned = ScratchOwned::new( - GLWESwitchingKey::encrypt_sk_scratch_space(&module, rank_out_s0s1, ct_gglwe_s0s1.size()) - | GLWECiphertextFourier::decrypt_scratch_space(&module, ct_gglwe_s0s1.size()) + GLWESwitchingKey::encrypt_sk_scratch_space(&module, basek, k_ksk, rank_out_s0s1) + | GLWECiphertextFourier::decrypt_scratch_space(&module, basek, k_ksk) | GLWESwitchingKey::keyswitch_inplace_scratch_space( &module, - ct_gglwe_s0s1.size(), + basek, + ct_gglwe_s0s1.k(), ct_gglwe_s0s1.rank(), - ct_gglwe_s1s2.size(), + ct_gglwe_s1s2.k(), ), ); @@ -356,16 +358,17 @@ fn test_external_product(log_n: usize, basek: usize, k: usize, sigma: f64, rank_ let mut source_xa: Source = Source::new([0u8; 32]); let mut scratch: ScratchOwned = ScratchOwned::new( - GLWESwitchingKey::encrypt_sk_scratch_space(&module, rank_out, ct_gglwe_in.size()) - | GLWECiphertextFourier::decrypt_scratch_space(&module, ct_gglwe_out.size()) + GLWESwitchingKey::encrypt_sk_scratch_space(&module, basek, k, rank_out) + | GLWECiphertextFourier::decrypt_scratch_space(&module, basek, k) | GLWESwitchingKey::external_product_scratch_space( &module, - ct_gglwe_out.size(), - ct_gglwe_in.size(), - ct_rgsw.size(), + basek, + ct_gglwe_out.k(), + ct_gglwe_in.k(), + ct_rgsw.k(), rank_out, ) - | GGSWCiphertext::encrypt_sk_scratch_space(&module, rank_out, ct_rgsw.size()), + | GGSWCiphertext::encrypt_sk_scratch_space(&module, basek, k, rank_out), ); let r: usize = 1; @@ -409,16 +412,17 @@ fn test_external_product(log_n: usize, basek: usize, k: usize, sigma: f64, rank_ ct_gglwe_out.external_product(&module, &ct_gglwe_in, &ct_rgsw, scratch.borrow()); scratch = ScratchOwned::new( - GLWESwitchingKey::encrypt_sk_scratch_space(&module, rank_out, ct_gglwe_in.size()) - | GLWECiphertextFourier::decrypt_scratch_space(&module, ct_gglwe_out.size()) + GLWESwitchingKey::encrypt_sk_scratch_space(&module, basek, k, rank_out) + | GLWECiphertextFourier::decrypt_scratch_space(&module, basek, k) | GLWESwitchingKey::external_product_scratch_space( &module, - ct_gglwe_out.size(), - ct_gglwe_in.size(), - ct_rgsw.size(), + basek, + ct_gglwe_out.k(), + ct_gglwe_in.k(), + ct_rgsw.k(), rank_out, ) - | GGSWCiphertext::encrypt_sk_scratch_space(&module, rank_out, ct_rgsw.size()), + | GGSWCiphertext::encrypt_sk_scratch_space(&module, basek, k, rank_out), ); let mut ct_glwe_dft: GLWECiphertextFourier, FFT64> = GLWECiphertextFourier::alloc(&module, basek, k, rank_out); @@ -482,10 +486,10 @@ fn test_external_product_inplace(log_n: usize, basek: usize, k: usize, sigma: f6 let mut source_xa: Source = Source::new([0u8; 32]); let mut scratch: ScratchOwned = ScratchOwned::new( - GLWESwitchingKey::encrypt_sk_scratch_space(&module, rank_out, ct_gglwe.size()) - | GLWECiphertextFourier::decrypt_scratch_space(&module, ct_gglwe.size()) - | GLWESwitchingKey::external_product_inplace_scratch_space(&module, ct_gglwe.size(), ct_rgsw.size(), rank_out) - | GGSWCiphertext::encrypt_sk_scratch_space(&module, rank_out, ct_rgsw.size()), + GLWESwitchingKey::encrypt_sk_scratch_space(&module, basek, k, rank_out) + | GLWECiphertextFourier::decrypt_scratch_space(&module, basek, k) + | GLWESwitchingKey::external_product_inplace_scratch_space(&module, basek, k, k, rank_out) + | GGSWCiphertext::encrypt_sk_scratch_space(&module, basek, k, rank_out), ); let r: usize = 1; diff --git a/core/src/test_fft64/ggsw.rs b/core/src/test_fft64/ggsw.rs index 639b90f..c617a54 100644 --- a/core/src/test_fft64/ggsw.rs +++ b/core/src/test_fft64/ggsw.rs @@ -73,14 +73,14 @@ fn external_product_inplace() { }); } -fn test_encrypt_sk(log_n: usize, basek: usize, k_ggsw: usize, sigma: f64, rank: usize) { +fn test_encrypt_sk(log_n: usize, basek: usize, k: usize, sigma: f64, rank: usize) { let module: Module = Module::::new(1 << log_n); - let rows: usize = (k_ggsw + basek - 1) / basek; + let rows: usize = (k + basek - 1) / basek; - let mut ct: GGSWCiphertext, FFT64> = GGSWCiphertext::alloc(&module, basek, k_ggsw, rows, rank); - let mut pt_have: GLWEPlaintext> = GLWEPlaintext::alloc(&module, basek, k_ggsw); - let mut pt_want: GLWEPlaintext> = GLWEPlaintext::alloc(&module, basek, k_ggsw); + let mut ct: GGSWCiphertext, FFT64> = GGSWCiphertext::alloc(&module, basek, k, rows, rank); + let mut pt_have: GLWEPlaintext> = GLWEPlaintext::alloc(&module, basek, k); + let mut pt_want: GLWEPlaintext> = GLWEPlaintext::alloc(&module, basek, k); let mut pt_scalar: ScalarZnx> = module.new_scalar_znx(1); let mut source_xs: Source = Source::new([0u8; 32]); @@ -90,8 +90,8 @@ fn test_encrypt_sk(log_n: usize, basek: usize, k_ggsw: usize, sigma: f64, rank: pt_scalar.fill_ternary_hw(0, module.n(), &mut source_xs); let mut scratch: ScratchOwned = ScratchOwned::new( - GGSWCiphertext::encrypt_sk_scratch_space(&module, rank, ct.size()) - | GLWECiphertextFourier::decrypt_scratch_space(&module, ct.size()), + GGSWCiphertext::encrypt_sk_scratch_space(&module, basek, k, rank) + | GLWECiphertextFourier::decrypt_scratch_space(&module, basek, k), ); let mut sk: SecretKey> = SecretKey::alloc(&module, rank); @@ -110,7 +110,7 @@ fn test_encrypt_sk(log_n: usize, basek: usize, k_ggsw: usize, sigma: f64, rank: scratch.borrow(), ); - let mut ct_glwe_fourier: GLWECiphertextFourier, FFT64> = GLWECiphertextFourier::alloc(&module, basek, k_ggsw, rank); + let mut ct_glwe_fourier: GLWECiphertextFourier, FFT64> = GLWECiphertextFourier::alloc(&module, basek, k, rank); let mut pt_dft: VecZnxDft, FFT64> = module.new_vec_znx_dft(1, ct.size()); let mut pt_big: VecZnxBig, FFT64> = module.new_vec_znx_big(1, ct.size()); @@ -132,7 +132,7 @@ fn test_encrypt_sk(log_n: usize, basek: usize, k_ggsw: usize, sigma: f64, rank: module.vec_znx_sub_ab_inplace(&mut pt_have.data, 0, &pt_want.data, 0); - let std_pt: f64 = pt_have.data.std(0, basek) * (k_ggsw as f64).exp2(); + let std_pt: f64 = pt_have.data.std(0, basek) * (k as f64).exp2(); assert!((sigma - std_pt).abs() <= 0.2, "{} {}", sigma, std_pt); pt_want.data.zero(); @@ -157,16 +157,17 @@ fn test_keyswitch(log_n: usize, basek: usize, k: usize, rank: usize, sigma: f64) let mut source_xa: Source = Source::new([0u8; 32]); let mut scratch: ScratchOwned = ScratchOwned::new( - GGSWCiphertext::encrypt_sk_scratch_space(&module, rank, ct_in.size()) - | GLWECiphertextFourier::decrypt_scratch_space(&module, ct_out.size()) - | GLWESwitchingKey::encrypt_sk_scratch_space(&module, rank, ksk.size()) - | TensorKey::generate_from_sk_scratch_space(&module, rank, ksk.size()) + GGSWCiphertext::encrypt_sk_scratch_space(&module, basek, k, rank) + | GLWECiphertextFourier::decrypt_scratch_space(&module, basek, k) + | GLWESwitchingKey::encrypt_sk_scratch_space(&module, basek, k, rank) + | TensorKey::generate_from_sk_scratch_space(&module, basek, k, rank) | GGSWCiphertext::keyswitch_scratch_space( &module, - ct_out.size(), - ct_in.size(), - ksk.size(), - tsk.size(), + basek, + ct_out.k(), + ct_in.k(), + ksk.k(), + tsk.k(), rank, ), ); @@ -283,11 +284,11 @@ fn test_keyswitch_inplace(log_n: usize, basek: usize, k: usize, rank: usize, sig let mut source_xa: Source = Source::new([0u8; 32]); let mut scratch: ScratchOwned = ScratchOwned::new( - GGSWCiphertext::encrypt_sk_scratch_space(&module, rank, ct.size()) - | GLWECiphertextFourier::decrypt_scratch_space(&module, ct.size()) - | GLWESwitchingKey::encrypt_sk_scratch_space(&module, rank, ksk.size()) - | TensorKey::generate_from_sk_scratch_space(&module, rank, ksk.size()) - | GGSWCiphertext::keyswitch_inplace_scratch_space(&module, ct.size(), ksk.size(), tsk.size(), rank), + GGSWCiphertext::encrypt_sk_scratch_space(&module, basek, k, rank) + | GLWECiphertextFourier::decrypt_scratch_space(&module, basek, k) + | GLWESwitchingKey::encrypt_sk_scratch_space(&module, basek, k, rank) + | TensorKey::generate_from_sk_scratch_space(&module, basek, k, rank) + | GGSWCiphertext::keyswitch_inplace_scratch_space(&module, basek, ct.k(), ksk.k(), tsk.k(), rank), ); let var_xs: f64 = 0.5; @@ -452,16 +453,17 @@ fn test_automorphism(p: i64, log_n: usize, basek: usize, k: usize, rank: usize, let mut source_xa: Source = Source::new([0u8; 32]); let mut scratch: ScratchOwned = ScratchOwned::new( - GGSWCiphertext::encrypt_sk_scratch_space(&module, rank, ct_in.size()) - | GLWECiphertextFourier::decrypt_scratch_space(&module, ct_out.size()) - | AutomorphismKey::generate_from_sk_scratch_space(&module, rank, auto_key.size()) - | TensorKey::generate_from_sk_scratch_space(&module, rank, tensor_key.size()) + GGSWCiphertext::encrypt_sk_scratch_space(&module, basek, k, rank) + | GLWECiphertextFourier::decrypt_scratch_space(&module, basek, k) + | AutomorphismKey::generate_from_sk_scratch_space(&module, basek, k, rank) + | TensorKey::generate_from_sk_scratch_space(&module, basek, k, rank) | GGSWCiphertext::automorphism_scratch_space( &module, - ct_out.size(), - ct_in.size(), - auto_key.size(), - tensor_key.size(), + basek, + ct_out.k(), + ct_in.k(), + auto_key.k(), + tensor_key.k(), rank, ), ); @@ -572,11 +574,11 @@ fn test_automorphism_inplace(p: i64, log_n: usize, basek: usize, k: usize, rank: let mut source_xa: Source = Source::new([0u8; 32]); let mut scratch: ScratchOwned = ScratchOwned::new( - GGSWCiphertext::encrypt_sk_scratch_space(&module, rank, ct.size()) - | GLWECiphertextFourier::decrypt_scratch_space(&module, ct.size()) - | AutomorphismKey::generate_from_sk_scratch_space(&module, rank, auto_key.size()) - | TensorKey::generate_from_sk_scratch_space(&module, rank, tensor_key.size()) - | GGSWCiphertext::automorphism_inplace_scratch_space(&module, ct.size(), auto_key.size(), tensor_key.size(), rank), + GGSWCiphertext::encrypt_sk_scratch_space(&module, basek, k, rank) + | GLWECiphertextFourier::decrypt_scratch_space(&module, basek, k) + | AutomorphismKey::generate_from_sk_scratch_space(&module, basek, k, rank) + | TensorKey::generate_from_sk_scratch_space(&module, basek, k, rank) + | GGSWCiphertext::automorphism_inplace_scratch_space(&module, basek, ct.k(), auto_key.k(), tensor_key.k(), rank), ); let var_xs: f64 = 0.5; @@ -691,13 +693,14 @@ fn test_external_product(log_n: usize, basek: usize, k_ggsw: usize, rank: usize, pt_ggsw_rhs.to_mut().raw_mut()[k] = 1; //X^{k} let mut scratch: ScratchOwned = ScratchOwned::new( - GLWECiphertextFourier::decrypt_scratch_space(&module, ct_ggsw_lhs_out.size()) - | GGSWCiphertext::encrypt_sk_scratch_space(&module, rank, ct_ggsw_lhs_in.size()) + GLWECiphertextFourier::decrypt_scratch_space(&module, basek, k) + | GGSWCiphertext::encrypt_sk_scratch_space(&module, basek, k, rank) | GGSWCiphertext::external_product_scratch_space( &module, - ct_ggsw_lhs_out.size(), - ct_ggsw_lhs_in.size(), - ct_ggsw_rhs.size(), + basek, + ct_ggsw_lhs_out.k(), + ct_ggsw_lhs_in.k(), + ct_ggsw_rhs.k(), rank, ), ); @@ -809,10 +812,10 @@ fn test_external_product_inplace(log_n: usize, basek: usize, k_ggsw: usize, rank pt_ggsw_rhs.to_mut().raw_mut()[k] = 1; //X^{k} let mut scratch: ScratchOwned = ScratchOwned::new( - GLWESwitchingKey::encrypt_sk_scratch_space(&module, rank, ct_ggsw_rhs.size()) - | GLWECiphertextFourier::decrypt_scratch_space(&module, ct_ggsw_lhs.size()) - | GGSWCiphertext::encrypt_sk_scratch_space(&module, rank, ct_ggsw_lhs.size()) - | GGSWCiphertext::external_product_inplace_scratch_space(&module, ct_ggsw_lhs.size(), ct_ggsw_rhs.size(), rank), + GLWESwitchingKey::encrypt_sk_scratch_space(&module, basek, k, rank) + | GLWECiphertextFourier::decrypt_scratch_space(&module, basek, k) + | GGSWCiphertext::encrypt_sk_scratch_space(&module, basek, k, rank) + | GGSWCiphertext::external_product_inplace_scratch_space(&module, basek, ct_ggsw_lhs.k(), ct_ggsw_rhs.k(), rank), ); let mut sk: SecretKey> = SecretKey::alloc(&module, rank); diff --git a/core/src/test_fft64/glwe.rs b/core/src/test_fft64/glwe.rs index 753783e..921c561 100644 --- a/core/src/test_fft64/glwe.rs +++ b/core/src/test_fft64/glwe.rs @@ -43,10 +43,10 @@ fn encrypt_pk() { #[test] fn keyswitch() { - (1..4).for_each(|rank_in| { - (1..4).for_each(|rank_out| { - println!("test keyswitch rank_in: {} rank_out: {}", rank_in, rank_out); - test_keyswitch(12, 12, 60, 45, 60, rank_in, rank_out, 3.2); + (1..4).for_each(|in_rank| { + (1..4).for_each(|out_rank| { + println!("test keyswitch in_rank: {} out_rank: {}", in_rank, out_rank); + test_keyswitch(12, 12, 60, 45, 60, in_rank, out_rank, 3.2); }); }); } @@ -91,10 +91,10 @@ fn automorphism() { }); } -fn test_encrypt_sk(log_n: usize, basek: usize, k_ct: usize, k_pt: usize, sigma: f64, rank: usize) { +fn test_encrypt_sk(log_n: usize, basek: usize, ct_k: usize, k_pt: usize, sigma: f64, rank: usize) { let module: Module = Module::::new(1 << log_n); - let mut ct: GLWECiphertext> = GLWECiphertext::alloc(&module, basek, k_ct, rank); + let mut ct: GLWECiphertext> = GLWECiphertext::alloc(&module, basek, ct_k, rank); let mut pt: GLWEPlaintext> = GLWEPlaintext::alloc(&module, basek, k_pt); let mut source_xs: Source = Source::new([0u8; 32]); @@ -102,7 +102,8 @@ fn test_encrypt_sk(log_n: usize, basek: usize, k_ct: usize, k_pt: usize, sigma: let mut source_xa: Source = Source::new([0u8; 32]); let mut scratch: ScratchOwned = ScratchOwned::new( - GLWECiphertext::encrypt_sk_scratch_space(&module, ct.size()) | GLWECiphertext::decrypt_scratch_space(&module, ct.size()), + GLWECiphertext::encrypt_sk_scratch_space(&module, basek, ct.k()) + | GLWECiphertext::decrypt_scratch_space(&module, basek, ct.k()), ); let mut sk: SecretKey> = SecretKey::alloc(&module, rank); @@ -151,10 +152,10 @@ fn test_encrypt_sk(log_n: usize, basek: usize, k_ct: usize, k_pt: usize, sigma: }); } -fn test_encrypt_zero_sk(log_n: usize, basek: usize, k_ct: usize, sigma: f64, rank: usize) { +fn test_encrypt_zero_sk(log_n: usize, basek: usize, ct_k: usize, sigma: f64, rank: usize) { let module: Module = Module::::new(1 << log_n); - let mut pt: GLWEPlaintext> = GLWEPlaintext::alloc(&module, basek, k_ct); + let mut pt: GLWEPlaintext> = GLWEPlaintext::alloc(&module, basek, ct_k); let mut source_xs: Source = Source::new([0u8; 32]); let mut source_xe: Source = Source::new([1u8; 32]); @@ -165,11 +166,11 @@ fn test_encrypt_zero_sk(log_n: usize, basek: usize, k_ct: usize, sigma: f64, ran let mut sk_dft: SecretKeyFourier, FFT64> = SecretKeyFourier::alloc(&module, rank); sk_dft.dft(&module, &sk); - let mut ct_dft: GLWECiphertextFourier, FFT64> = GLWECiphertextFourier::alloc(&module, basek, k_ct, rank); + let mut ct_dft: GLWECiphertextFourier, FFT64> = GLWECiphertextFourier::alloc(&module, basek, ct_k, rank); let mut scratch: ScratchOwned = ScratchOwned::new( - GLWECiphertextFourier::decrypt_scratch_space(&module, ct_dft.size()) - | GLWECiphertextFourier::encrypt_sk_scratch_space(&module, rank, ct_dft.size()), + GLWECiphertextFourier::decrypt_scratch_space(&module, basek, ct_k) + | GLWECiphertextFourier::encrypt_sk_scratch_space(&module, basek, ct_k, rank), ); ct_dft.encrypt_zero_sk( @@ -182,14 +183,14 @@ fn test_encrypt_zero_sk(log_n: usize, basek: usize, k_ct: usize, sigma: f64, ran ); ct_dft.decrypt(&module, &mut pt, &sk_dft, scratch.borrow()); - assert!((sigma - pt.data.std(0, basek) * (k_ct as f64).exp2()) <= 0.2); + assert!((sigma - pt.data.std(0, basek) * (ct_k as f64).exp2()) <= 0.2); } -fn test_encrypt_pk(log_n: usize, basek: usize, k_ct: usize, k_pk: usize, sigma: f64, rank: usize) { +fn test_encrypt_pk(log_n: usize, basek: usize, ct_k: usize, k_pk: usize, sigma: f64, rank: usize) { let module: Module = Module::::new(1 << log_n); - let mut ct: GLWECiphertext> = GLWECiphertext::alloc(&module, basek, k_ct, rank); - let mut pt_want: GLWEPlaintext> = GLWEPlaintext::alloc(&module, basek, k_ct); + let mut ct: GLWECiphertext> = GLWECiphertext::alloc(&module, basek, ct_k, rank); + let mut pt_want: GLWEPlaintext> = GLWEPlaintext::alloc(&module, basek, ct_k); let mut source_xs: Source = Source::new([0u8; 32]); let mut source_xe: Source = Source::new([0u8; 32]); @@ -205,9 +206,9 @@ fn test_encrypt_pk(log_n: usize, basek: usize, k_ct: usize, k_pk: usize, sigma: pk.generate_from_sk(&module, &sk_dft, &mut source_xa, &mut source_xe, sigma); let mut scratch: ScratchOwned = ScratchOwned::new( - GLWECiphertext::encrypt_sk_scratch_space(&module, ct.size()) - | GLWECiphertext::decrypt_scratch_space(&module, ct.size()) - | GLWECiphertext::encrypt_pk_scratch_space(&module, pk.size()), + GLWECiphertext::encrypt_sk_scratch_space(&module, basek, ct.k()) + | GLWECiphertext::decrypt_scratch_space(&module, basek, ct.k()) + | GLWECiphertext::encrypt_pk_scratch_space(&module, basek, pk.k()), ); let mut data_want: Vec = vec![0i64; module.n()]; @@ -216,7 +217,7 @@ fn test_encrypt_pk(log_n: usize, basek: usize, k_ct: usize, k_pk: usize, sigma: .iter_mut() .for_each(|x| *x = source_xa.next_i64() & 0); - pt_want.data.encode_vec_i64(0, basek, k_ct, &data_want, 10); + pt_want.data.encode_vec_i64(0, basek, ct_k, &data_want, 10); ct.encrypt_pk( &module, @@ -228,14 +229,14 @@ fn test_encrypt_pk(log_n: usize, basek: usize, k_ct: usize, k_pk: usize, sigma: scratch.borrow(), ); - let mut pt_have: GLWEPlaintext> = GLWEPlaintext::alloc(&module, basek, k_ct); + let mut pt_have: GLWEPlaintext> = GLWEPlaintext::alloc(&module, basek, ct_k); ct.decrypt(&module, &mut pt_have, &sk_dft, scratch.borrow()); module.vec_znx_sub_ab_inplace(&mut pt_want.data, 0, &pt_have.data, 0); let noise_have: f64 = pt_want.data.std(0, basek).log2(); - let noise_want: f64 = ((((rank as f64) + 1.0) * module.n() as f64 * 0.5 * sigma * sigma).sqrt()).log2() - (k_ct as f64); + let noise_want: f64 = ((((rank as f64) + 1.0) * module.n() as f64 * 0.5 * sigma * sigma).sqrt()).log2() - (ct_k as f64); assert!( (noise_have - noise_want).abs() < 0.2, @@ -249,20 +250,20 @@ fn test_keyswitch( log_n: usize, basek: usize, k_keyswitch: usize, - k_ct_in: usize, - k_ct_out: usize, - rank_in: usize, - rank_out: usize, + ct_k_in: usize, + ct_k_out: usize, + in_rank: usize, + out_rank: usize, sigma: f64, ) { let module: Module = Module::::new(1 << log_n); - let rows: usize = (k_ct_in + basek - 1) / basek; + let rows: usize = (ct_k_in + basek - 1) / basek; - let mut ksk: GLWESwitchingKey, FFT64> = GLWESwitchingKey::alloc(&module, basek, k_keyswitch, rows, rank_in, rank_out); - let mut ct_in: GLWECiphertext> = GLWECiphertext::alloc(&module, basek, k_ct_in, rank_in); - let mut ct_out: GLWECiphertext> = GLWECiphertext::alloc(&module, basek, k_ct_out, rank_out); - let mut pt_want: GLWEPlaintext> = GLWEPlaintext::alloc(&module, basek, k_ct_in); - let mut pt_have: GLWEPlaintext> = GLWEPlaintext::alloc(&module, basek, k_ct_out); + let mut ksk: GLWESwitchingKey, FFT64> = GLWESwitchingKey::alloc(&module, basek, k_keyswitch, rows, in_rank, out_rank); + let mut ct_in: GLWECiphertext> = GLWECiphertext::alloc(&module, basek, ct_k_in, in_rank); + let mut ct_out: GLWECiphertext> = GLWECiphertext::alloc(&module, basek, ct_k_out, out_rank); + let mut pt_want: GLWEPlaintext> = GLWEPlaintext::alloc(&module, basek, ct_k_in); + let mut pt_have: GLWEPlaintext> = GLWEPlaintext::alloc(&module, basek, ct_k_out); let mut source_xs: Source = Source::new([0u8; 32]); let mut source_xe: Source = Source::new([0u8; 32]); @@ -274,29 +275,30 @@ fn test_keyswitch( .fill_uniform(basek, 0, pt_want.size(), &mut source_xa); 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, ct_in.size()) + GLWESwitchingKey::encrypt_sk_scratch_space(&module, basek, ksk.k(), out_rank) + | GLWECiphertext::decrypt_scratch_space(&module, basek, ct_out.k()) + | GLWECiphertext::encrypt_sk_scratch_space(&module, basek, ct_in.k()) | GLWECiphertext::keyswitch_scratch_space( &module, - ct_out.size(), - rank_out, - ct_in.size(), - rank_in, - ksk.size(), + basek, + ct_out.k(), + out_rank, + ct_in.k(), + in_rank, + ksk.k(), ), ); - let mut sk_in: SecretKey> = SecretKey::alloc(&module, rank_in); + let mut sk_in: SecretKey> = SecretKey::alloc(&module, in_rank); sk_in.fill_ternary_prob(0.5, &mut source_xs); - let mut sk_in_dft: SecretKeyFourier, FFT64> = SecretKeyFourier::alloc(&module, rank_in); + let mut sk_in_dft: SecretKeyFourier, FFT64> = SecretKeyFourier::alloc(&module, in_rank); sk_in_dft.dft(&module, &sk_in); - let mut sk_out: SecretKey> = SecretKey::alloc(&module, rank_out); + let mut sk_out: SecretKey> = SecretKey::alloc(&module, out_rank); sk_out.fill_ternary_prob(0.5, &mut source_xs); - let mut sk_out_dft: SecretKeyFourier, FFT64> = SecretKeyFourier::alloc(&module, rank_out); + let mut sk_out_dft: SecretKeyFourier, FFT64> = SecretKeyFourier::alloc(&module, out_rank); sk_out_dft.dft(&module, &sk_out); ksk.generate_from_sk( @@ -334,8 +336,8 @@ fn test_keyswitch( 0f64, sigma * sigma, 0f64, - rank_in as f64, - k_ct_in, + in_rank as f64, + ct_k_in, k_keyswitch, ); @@ -347,14 +349,14 @@ fn test_keyswitch( ); } -fn test_keyswitch_inplace(log_n: usize, basek: usize, k_ksk: usize, k_ct: usize, rank: usize, sigma: f64) { +fn test_keyswitch_inplace(log_n: usize, basek: usize, k_ksk: usize, ct_k: usize, rank: usize, sigma: f64) { let module: Module = Module::::new(1 << log_n); - let rows: usize = (k_ct + basek - 1) / basek; + let rows: usize = (ct_k + basek - 1) / basek; let mut ct_grlwe: GLWESwitchingKey, FFT64> = GLWESwitchingKey::alloc(&module, basek, k_ksk, rows, rank, rank); - let mut ct_rlwe: GLWECiphertext> = GLWECiphertext::alloc(&module, basek, k_ct, rank); - let mut pt_want: GLWEPlaintext> = GLWEPlaintext::alloc(&module, basek, k_ct); - let mut pt_have: GLWEPlaintext> = GLWEPlaintext::alloc(&module, basek, k_ct); + let mut ct_glwe: GLWECiphertext> = GLWECiphertext::alloc(&module, basek, ct_k, rank); + let mut pt_want: GLWEPlaintext> = GLWEPlaintext::alloc(&module, basek, ct_k); + let mut pt_have: GLWEPlaintext> = GLWEPlaintext::alloc(&module, basek, ct_k); let mut source_xs: Source = Source::new([0u8; 32]); let mut source_xe: Source = Source::new([0u8; 32]); @@ -366,10 +368,10 @@ fn test_keyswitch_inplace(log_n: usize, basek: usize, k_ksk: usize, k_ct: usize, .fill_uniform(basek, 0, pt_want.size(), &mut source_xa); 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, ct_rlwe.size()) - | GLWECiphertext::keyswitch_inplace_scratch_space(&module, ct_rlwe.size(), rank, ct_grlwe.size()), + GLWESwitchingKey::encrypt_sk_scratch_space(&module, basek, ct_grlwe.k(), rank) + | GLWECiphertext::decrypt_scratch_space(&module, basek, ct_glwe.k()) + | GLWECiphertext::encrypt_sk_scratch_space(&module, basek, ct_glwe.k()) + | GLWECiphertext::keyswitch_inplace_scratch_space(&module, basek, ct_glwe.k(), rank, ct_grlwe.k()), ); let mut sk0: SecretKey> = SecretKey::alloc(&module, rank); @@ -394,7 +396,7 @@ fn test_keyswitch_inplace(log_n: usize, basek: usize, k_ksk: usize, k_ct: usize, scratch.borrow(), ); - ct_rlwe.encrypt_sk( + ct_glwe.encrypt_sk( &module, &pt_want, &sk0_dft, @@ -404,9 +406,9 @@ fn test_keyswitch_inplace(log_n: usize, basek: usize, k_ksk: usize, k_ct: usize, scratch.borrow(), ); - ct_rlwe.keyswitch_inplace(&module, &ct_grlwe, scratch.borrow()); + ct_glwe.keyswitch_inplace(&module, &ct_grlwe, scratch.borrow()); - ct_rlwe.decrypt(&module, &mut pt_have, &sk1_dft, scratch.borrow()); + ct_glwe.decrypt(&module, &mut pt_have, &sk1_dft, scratch.borrow()); module.vec_znx_sub_ab_inplace(&mut pt_have.data, 0, &pt_want.data, 0); @@ -420,7 +422,7 @@ fn test_keyswitch_inplace(log_n: usize, basek: usize, k_ksk: usize, k_ct: usize, sigma * sigma, 0f64, rank as f64, - k_ct, + ct_k, k_ksk, ); @@ -437,19 +439,19 @@ fn test_automorphism( basek: usize, p: i64, k_autokey: usize, - k_ct_in: usize, - k_ct_out: usize, + ct_k_in: usize, + ct_k_out: usize, rank: usize, sigma: f64, ) { let module: Module = Module::::new(1 << log_n); - let rows: usize = (k_ct_in + basek - 1) / basek; + let rows: usize = (ct_k_in + basek - 1) / basek; let mut autokey: AutomorphismKey, FFT64> = AutomorphismKey::alloc(&module, basek, k_autokey, rows, rank); - let mut ct_in: GLWECiphertext> = GLWECiphertext::alloc(&module, basek, k_ct_in, rank); - let mut ct_out: GLWECiphertext> = GLWECiphertext::alloc(&module, basek, k_ct_out, rank); - let mut pt_want: GLWEPlaintext> = GLWEPlaintext::alloc(&module, basek, k_ct_in); - let mut pt_have: GLWEPlaintext> = GLWEPlaintext::alloc(&module, basek, k_ct_out); + let mut ct_in: GLWECiphertext> = GLWECiphertext::alloc(&module, basek, ct_k_in, rank); + let mut ct_out: GLWECiphertext> = GLWECiphertext::alloc(&module, basek, ct_k_out, rank); + let mut pt_want: GLWEPlaintext> = GLWEPlaintext::alloc(&module, basek, ct_k_in); + let mut pt_have: GLWEPlaintext> = GLWEPlaintext::alloc(&module, basek, ct_k_out); let mut source_xs: Source = Source::new([0u8; 32]); let mut source_xe: Source = Source::new([0u8; 32]); @@ -460,10 +462,10 @@ fn test_automorphism( .fill_uniform(basek, 0, pt_want.size(), &mut source_xa); let mut scratch: ScratchOwned = ScratchOwned::new( - GLWESwitchingKey::encrypt_sk_scratch_space(&module, rank, autokey.size()) - | GLWECiphertext::decrypt_scratch_space(&module, ct_out.size()) - | GLWECiphertext::encrypt_sk_scratch_space(&module, ct_in.size()) - | GLWECiphertext::automorphism_scratch_space(&module, ct_out.size(), rank, ct_in.size(), autokey.size()), + GLWESwitchingKey::encrypt_sk_scratch_space(&module, basek, autokey.k(), rank) + | GLWECiphertext::decrypt_scratch_space(&module, basek, ct_out.k()) + | GLWECiphertext::encrypt_sk_scratch_space(&module, basek, ct_in.k()) + | GLWECiphertext::automorphism_scratch_space(&module, basek, ct_out.k(), ct_in.k(), autokey.k(), rank), ); let mut sk: SecretKey> = SecretKey::alloc(&module, rank); @@ -511,7 +513,7 @@ fn test_automorphism( sigma * sigma, 0f64, rank as f64, - k_ct_in, + ct_k_in, k_autokey, ); @@ -523,14 +525,14 @@ fn test_automorphism( ); } -fn test_automorphism_inplace(log_n: usize, basek: usize, p: i64, k_autokey: usize, k_ct: usize, rank: usize, sigma: f64) { +fn test_automorphism_inplace(log_n: usize, basek: usize, p: i64, k_autokey: usize, ct_k: usize, rank: usize, sigma: f64) { let module: Module = Module::::new(1 << log_n); - let rows: usize = (k_ct + basek - 1) / basek; + let rows: usize = (ct_k + basek - 1) / basek; let mut autokey: AutomorphismKey, FFT64> = AutomorphismKey::alloc(&module, basek, k_autokey, rows, rank); - let mut ct: GLWECiphertext> = GLWECiphertext::alloc(&module, basek, k_ct, rank); - let mut pt_want: GLWEPlaintext> = GLWEPlaintext::alloc(&module, basek, k_ct); - let mut pt_have: GLWEPlaintext> = GLWEPlaintext::alloc(&module, basek, k_ct); + let mut ct: GLWECiphertext> = GLWECiphertext::alloc(&module, basek, ct_k, rank); + let mut pt_want: GLWEPlaintext> = GLWEPlaintext::alloc(&module, basek, ct_k); + let mut pt_have: GLWEPlaintext> = GLWEPlaintext::alloc(&module, basek, ct_k); let mut source_xs: Source = Source::new([0u8; 32]); let mut source_xe: Source = Source::new([0u8; 32]); @@ -542,10 +544,10 @@ fn test_automorphism_inplace(log_n: usize, basek: usize, p: i64, k_autokey: usiz .fill_uniform(basek, 0, pt_want.size(), &mut source_xa); let mut scratch: ScratchOwned = ScratchOwned::new( - GLWESwitchingKey::encrypt_sk_scratch_space(&module, rank, autokey.size()) - | GLWECiphertext::decrypt_scratch_space(&module, ct.size()) - | GLWECiphertext::encrypt_sk_scratch_space(&module, ct.size()) - | GLWECiphertext::automorphism_inplace_scratch_space(&module, ct.size(), rank, autokey.size()), + GLWESwitchingKey::encrypt_sk_scratch_space(&module, basek, autokey.k(), rank) + | GLWECiphertext::decrypt_scratch_space(&module, basek, ct.k()) + | GLWECiphertext::encrypt_sk_scratch_space(&module, basek, ct.k()) + | GLWECiphertext::automorphism_inplace_scratch_space(&module, basek, ct.k(), autokey.k(), rank), ); let mut sk: SecretKey> = SecretKey::alloc(&module, rank); @@ -590,7 +592,7 @@ fn test_automorphism_inplace(log_n: usize, basek: usize, p: i64, k_autokey: usiz sigma * sigma, 0f64, rank as f64, - k_ct, + ct_k, k_autokey, ); @@ -602,17 +604,17 @@ fn test_automorphism_inplace(log_n: usize, basek: usize, p: i64, k_autokey: usiz ); } -fn test_external_product(log_n: usize, basek: usize, k_ggsw: usize, k_ct_in: usize, k_ct_out: usize, rank: usize, sigma: f64) { +fn test_external_product(log_n: usize, basek: usize, k_ggsw: usize, ct_k_in: usize, ct_k_out: usize, rank: usize, sigma: f64) { let module: Module = Module::::new(1 << log_n); - let rows: usize = (k_ct_in + basek - 1) / basek; + let rows: usize = (ct_k_in + basek - 1) / basek; - let mut ct_rgsw: GGSWCiphertext, FFT64> = GGSWCiphertext::alloc(&module, basek, k_ggsw, rows, rank); - let mut ct_rlwe_in: GLWECiphertext> = GLWECiphertext::alloc(&module, basek, k_ct_in, rank); - let mut ct_rlwe_out: GLWECiphertext> = GLWECiphertext::alloc(&module, basek, k_ct_out, rank); + let mut ct_ggsw: GGSWCiphertext, FFT64> = GGSWCiphertext::alloc(&module, basek, k_ggsw, rows, rank); + let mut ct_glwe_in: GLWECiphertext> = GLWECiphertext::alloc(&module, basek, ct_k_in, rank); + let mut ct_glwe_out: GLWECiphertext> = GLWECiphertext::alloc(&module, basek, ct_k_out, rank); let mut pt_rgsw: ScalarZnx> = module.new_scalar_znx(1); - let mut pt_want: GLWEPlaintext> = GLWEPlaintext::alloc(&module, basek, k_ct_in); - let mut pt_have: GLWEPlaintext> = GLWEPlaintext::alloc(&module, basek, k_ct_out); + let mut pt_want: GLWEPlaintext> = GLWEPlaintext::alloc(&module, basek, ct_k_in); + let mut pt_have: GLWEPlaintext> = GLWEPlaintext::alloc(&module, basek, ct_k_out); let mut source_xs: Source = Source::new([0u8; 32]); let mut source_xe: Source = Source::new([0u8; 32]); @@ -630,14 +632,15 @@ fn test_external_product(log_n: usize, basek: usize, k_ggsw: usize, k_ct_in: usi pt_rgsw.raw_mut()[k] = 1; // X^{k} 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, ct_rlwe_in.size()) + GGSWCiphertext::encrypt_sk_scratch_space(&module, basek, ct_ggsw.k(), rank) + | GLWECiphertext::decrypt_scratch_space(&module, basek, ct_glwe_out.k()) + | GLWECiphertext::encrypt_sk_scratch_space(&module, basek, ct_glwe_in.k()) | GLWECiphertext::external_product_scratch_space( &module, - ct_rlwe_out.size(), - ct_rlwe_in.size(), - ct_rgsw.size(), + basek, + ct_glwe_out.k(), + ct_glwe_in.k(), + ct_ggsw.k(), rank, ), ); @@ -648,7 +651,7 @@ fn test_external_product(log_n: usize, basek: usize, k_ggsw: usize, k_ct_in: usi let mut sk_dft: SecretKeyFourier, FFT64> = SecretKeyFourier::alloc(&module, rank); sk_dft.dft(&module, &sk); - ct_rgsw.encrypt_sk( + ct_ggsw.encrypt_sk( &module, &pt_rgsw, &sk_dft, @@ -658,7 +661,7 @@ fn test_external_product(log_n: usize, basek: usize, k_ggsw: usize, k_ct_in: usi scratch.borrow(), ); - ct_rlwe_in.encrypt_sk( + ct_glwe_in.encrypt_sk( &module, &pt_want, &sk_dft, @@ -668,9 +671,9 @@ fn test_external_product(log_n: usize, basek: usize, k_ggsw: usize, k_ct_in: usi scratch.borrow(), ); - ct_rlwe_out.external_product(&module, &ct_rlwe_in, &ct_rgsw, scratch.borrow()); + ct_glwe_out.external_product(&module, &ct_glwe_in, &ct_ggsw, scratch.borrow()); - ct_rlwe_out.decrypt(&module, &mut pt_have, &sk_dft, scratch.borrow()); + ct_glwe_out.decrypt(&module, &mut pt_have, &sk_dft, scratch.borrow()); module.vec_znx_rotate_inplace(k as i64, &mut pt_want.data, 0); @@ -695,7 +698,7 @@ fn test_external_product(log_n: usize, basek: usize, k_ggsw: usize, k_ct_in: usi var_gct_err_lhs, var_gct_err_rhs, rank as f64, - k_ct_in, + ct_k_in, k_ggsw, ); @@ -707,15 +710,15 @@ fn test_external_product(log_n: usize, basek: usize, k_ggsw: usize, k_ct_in: usi ); } -fn test_external_product_inplace(log_n: usize, basek: usize, k_ggsw: usize, k_ct: usize, rank: usize, sigma: f64) { +fn test_external_product_inplace(log_n: usize, basek: usize, k_ggsw: usize, ct_k: usize, rank: usize, sigma: f64) { let module: Module = Module::::new(1 << log_n); - let rows: usize = (k_ct + basek - 1) / basek; + let rows: usize = (ct_k + basek - 1) / basek; - let mut ct_rgsw: GGSWCiphertext, FFT64> = GGSWCiphertext::alloc(&module, basek, k_ggsw, rows, rank); - let mut ct_rlwe: GLWECiphertext> = GLWECiphertext::alloc(&module, basek, k_ct, rank); + let mut ct_ggsw: GGSWCiphertext, FFT64> = GGSWCiphertext::alloc(&module, basek, k_ggsw, rows, rank); + let mut ct_glwe: GLWECiphertext> = GLWECiphertext::alloc(&module, basek, ct_k, rank); let mut pt_rgsw: ScalarZnx> = module.new_scalar_znx(1); - let mut pt_want: GLWEPlaintext> = GLWEPlaintext::alloc(&module, basek, k_ct); - let mut pt_have: GLWEPlaintext> = GLWEPlaintext::alloc(&module, basek, k_ct); + let mut pt_want: GLWEPlaintext> = GLWEPlaintext::alloc(&module, basek, ct_k); + let mut pt_have: GLWEPlaintext> = GLWEPlaintext::alloc(&module, basek, ct_k); let mut source_xs: Source = Source::new([0u8; 32]); let mut source_xe: Source = Source::new([0u8; 32]); @@ -733,10 +736,10 @@ fn test_external_product_inplace(log_n: usize, basek: usize, k_ggsw: usize, k_ct pt_rgsw.raw_mut()[k] = 1; // X^{k} 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, ct_rlwe.size()) - | GLWECiphertext::external_product_inplace_scratch_space(&module, ct_rlwe.size(), ct_rgsw.size(), rank), + GGSWCiphertext::encrypt_sk_scratch_space(&module, basek, ct_ggsw.k(), rank) + | GLWECiphertext::decrypt_scratch_space(&module, basek, ct_glwe.k()) + | GLWECiphertext::encrypt_sk_scratch_space(&module, basek, ct_glwe.k()) + | GLWECiphertext::external_product_inplace_scratch_space(&module, basek, ct_glwe.k(), ct_ggsw.k(), rank), ); let mut sk: SecretKey> = SecretKey::alloc(&module, rank); @@ -745,7 +748,7 @@ fn test_external_product_inplace(log_n: usize, basek: usize, k_ggsw: usize, k_ct let mut sk_dft: SecretKeyFourier, FFT64> = SecretKeyFourier::alloc(&module, rank); sk_dft.dft(&module, &sk); - ct_rgsw.encrypt_sk( + ct_ggsw.encrypt_sk( &module, &pt_rgsw, &sk_dft, @@ -755,7 +758,7 @@ fn test_external_product_inplace(log_n: usize, basek: usize, k_ggsw: usize, k_ct scratch.borrow(), ); - ct_rlwe.encrypt_sk( + ct_glwe.encrypt_sk( &module, &pt_want, &sk_dft, @@ -765,9 +768,9 @@ fn test_external_product_inplace(log_n: usize, basek: usize, k_ggsw: usize, k_ct scratch.borrow(), ); - ct_rlwe.external_product_inplace(&module, &ct_rgsw, scratch.borrow()); + ct_glwe.external_product_inplace(&module, &ct_ggsw, scratch.borrow()); - ct_rlwe.decrypt(&module, &mut pt_have, &sk_dft, scratch.borrow()); + ct_glwe.decrypt(&module, &mut pt_have, &sk_dft, scratch.borrow()); module.vec_znx_rotate_inplace(k as i64, &mut pt_want.data, 0); @@ -792,7 +795,7 @@ fn test_external_product_inplace(log_n: usize, basek: usize, k_ggsw: usize, k_ct var_gct_err_lhs, var_gct_err_rhs, rank as f64, - k_ct, + ct_k, k_ggsw, ); diff --git a/core/src/test_fft64/glwe_fourier.rs b/core/src/test_fft64/glwe_fourier.rs index 85ccb1a..4213545 100644 --- a/core/src/test_fft64/glwe_fourier.rs +++ b/core/src/test_fft64/glwe_fourier.rs @@ -1,4 +1,5 @@ use crate::{ + GLWEOps, elem::Infos, ggsw_ciphertext::GGSWCiphertext, glwe_ciphertext::GLWECiphertext, @@ -79,16 +80,17 @@ fn test_keyswitch( .fill_uniform(basek, 0, pt_want.size(), &mut source_xa); let mut scratch: ScratchOwned = ScratchOwned::new( - GLWESwitchingKey::encrypt_sk_scratch_space(&module, rank_out, ksk.size()) - | GLWECiphertext::decrypt_scratch_space(&module, ct_glwe_out.size()) - | GLWECiphertext::encrypt_sk_scratch_space(&module, ct_glwe_in.size()) + GLWESwitchingKey::encrypt_sk_scratch_space(&module, basek, k_ksk, rank_out) + | GLWECiphertext::decrypt_scratch_space(&module, basek, k_ct_out) + | GLWECiphertext::encrypt_sk_scratch_space(&module, basek, k_ct_in) | GLWECiphertextFourier::keyswitch_scratch_space( &module, - ct_glwe_out.size(), + basek, + ct_glwe_out.k(), rank_out, - ct_glwe_in.size(), + ct_glwe_in.k(), rank_in, - ksk.size(), + ksk.k(), ), ); @@ -174,10 +176,10 @@ fn test_keyswitch_inplace(log_n: usize, basek: usize, k_ksk: usize, k_ct: usize, .fill_uniform(basek, 0, pt_want.size(), &mut source_xa); let mut scratch: ScratchOwned = ScratchOwned::new( - GLWESwitchingKey::encrypt_sk_scratch_space(&module, rank, ksk.size()) - | GLWECiphertext::decrypt_scratch_space(&module, ct_glwe.size()) - | GLWECiphertext::encrypt_sk_scratch_space(&module, ct_glwe.size()) - | GLWECiphertextFourier::keyswitch_inplace_scratch_space(&module, ct_rlwe_dft.size(), ksk.size(), rank), + GLWESwitchingKey::encrypt_sk_scratch_space(&module, basek, ksk.k(), rank) + | GLWECiphertext::decrypt_scratch_space(&module, basek, ct_glwe.k()) + | GLWECiphertext::encrypt_sk_scratch_space(&module, basek, ct_glwe.k()) + | GLWECiphertextFourier::keyswitch_inplace_scratch_space(&module, basek, ct_rlwe_dft.k(), ksk.k(), rank), ); let mut sk_in: SecretKey> = SecretKey::alloc(&module, rank); @@ -247,7 +249,7 @@ fn test_external_product(log_n: usize, basek: usize, k_ggsw: usize, k_ct_in: usi let rows: usize = (k_ct_in + basek - 1) / basek; - let mut ct_rgsw: GGSWCiphertext, FFT64> = GGSWCiphertext::alloc(&module, basek, k_ggsw, rows, rank); + let mut ct_ggsw: GGSWCiphertext, FFT64> = GGSWCiphertext::alloc(&module, basek, k_ggsw, rows, rank); let mut ct_in: GLWECiphertext> = GLWECiphertext::alloc(&module, basek, k_ct_in, rank); let mut ct_out: GLWECiphertext> = GLWECiphertext::alloc(&module, basek, k_ct_out, rank); let mut ct_in_dft: GLWECiphertextFourier, FFT64> = GLWECiphertextFourier::alloc(&module, basek, k_ct_in, rank); @@ -267,15 +269,16 @@ fn test_external_product(log_n: usize, basek: usize, k_ggsw: usize, k_ct_in: usi pt_want.data.at_mut(0, 0)[1] = 1; - let k: usize = 1; + let k: i64 = 1; - pt_rgsw.raw_mut()[k] = 1; // X^{k} + pt_rgsw.raw_mut()[0] = 1; // X^{0} + module.vec_znx_rotate_inplace(k, &mut pt_rgsw, 0); // X^{k} let mut scratch: ScratchOwned = ScratchOwned::new( - GGSWCiphertext::encrypt_sk_scratch_space(&module, rank, ct_rgsw.size()) - | GLWECiphertext::decrypt_scratch_space(&module, ct_out.size()) - | GLWECiphertext::encrypt_sk_scratch_space(&module, ct_in.size()) - | GLWECiphertextFourier::external_product_scratch_space(&module, ct_out.size(), ct_in.size(), ct_rgsw.size(), rank), + GGSWCiphertext::encrypt_sk_scratch_space(&module, basek, ct_ggsw.k(), rank) + | GLWECiphertext::decrypt_scratch_space(&module, basek, ct_out.k()) + | GLWECiphertext::encrypt_sk_scratch_space(&module, basek, ct_in.k()) + | GLWECiphertextFourier::external_product_scratch_space(&module, basek, ct_out.k(), ct_in.k(), ct_ggsw.k(), rank), ); let mut sk: SecretKey> = SecretKey::alloc(&module, rank); @@ -284,7 +287,7 @@ fn test_external_product(log_n: usize, basek: usize, k_ggsw: usize, k_ct_in: usi let mut sk_dft: SecretKeyFourier, FFT64> = SecretKeyFourier::alloc(&module, rank); sk_dft.dft(&module, &sk); - ct_rgsw.encrypt_sk( + ct_ggsw.encrypt_sk( &module, &pt_rgsw, &sk_dft, @@ -305,14 +308,13 @@ fn test_external_product(log_n: usize, basek: usize, k_ggsw: usize, k_ct_in: usi ); ct_in.dft(&module, &mut ct_in_dft); - ct_out_dft.external_product(&module, &ct_in_dft, &ct_rgsw, scratch.borrow()); + ct_out_dft.external_product(&module, &ct_in_dft, &ct_ggsw, scratch.borrow()); ct_out_dft.idft(&module, &mut ct_out, scratch.borrow()); ct_out.decrypt(&module, &mut pt_have, &sk_dft, scratch.borrow()); - module.vec_znx_rotate_inplace(k as i64, &mut pt_want.data, 0); - - module.vec_znx_sub_ab_inplace(&mut pt_have.data, 0, &pt_want.data, 0); + pt_want.rotate_inplace(&module, k); + pt_have.sub_inplace_ab(&module, &pt_want); let noise_have: f64 = pt_have.data.std(0, basek).log2(); @@ -367,15 +369,16 @@ fn test_external_product_inplace(log_n: usize, basek: usize, k_ggsw: usize, k_ct pt_want.data.at_mut(0, 0)[1] = 1; - let k: usize = 1; + let k: i64 = 1; - pt_rgsw.raw_mut()[k] = 1; // X^{k} + pt_rgsw.raw_mut()[0] = 1; // X^{0} + module.vec_znx_rotate_inplace(k, &mut pt_rgsw, 0); // X^{k} let mut scratch: ScratchOwned = ScratchOwned::new( - GGSWCiphertext::encrypt_sk_scratch_space(&module, rank, ct_ggsw.size()) - | GLWECiphertext::decrypt_scratch_space(&module, ct.size()) - | GLWECiphertext::encrypt_sk_scratch_space(&module, ct.size()) - | GLWECiphertextFourier::external_product_inplace_scratch_space(&module, ct.size(), ct_ggsw.size(), rank), + GGSWCiphertext::encrypt_sk_scratch_space(&module, basek, ct_ggsw.k(), rank) + | GLWECiphertext::decrypt_scratch_space(&module, basek, ct.k()) + | GLWECiphertext::encrypt_sk_scratch_space(&module, basek, ct.k()) + | GLWECiphertextFourier::external_product_inplace_scratch_space(&module, basek, ct.k(), ct_ggsw.k(), rank), ); let mut sk: SecretKey> = SecretKey::alloc(&module, rank); @@ -410,9 +413,8 @@ fn test_external_product_inplace(log_n: usize, basek: usize, k_ggsw: usize, k_ct ct.decrypt(&module, &mut pt_have, &sk_dft, scratch.borrow()); - module.vec_znx_rotate_inplace(k as i64, &mut pt_want.data, 0); - - module.vec_znx_sub_ab_inplace(&mut pt_have.data, 0, &pt_want.data, 0); + pt_want.rotate_inplace(&module, k); + pt_have.sub_inplace_ab(&module, &pt_want); let noise_have: f64 = pt_have.data.std(0, basek).log2(); diff --git a/core/src/test_fft64/glwe_packing.rs b/core/src/test_fft64/glwe_packing.rs index 3a0641d..a6433c2 100644 --- a/core/src/test_fft64/glwe_packing.rs +++ b/core/src/test_fft64/glwe_packing.rs @@ -10,7 +10,6 @@ use std::collections::HashMap; use backend::{Encoding, FFT64, Module, ScratchOwned, Stats}; use sampling::source::Source; -use std::time::Instant; #[test] fn packing() { @@ -22,20 +21,18 @@ fn packing() { let mut source_xa: Source = Source::new([0u8; 32]); let basek: usize = 18; - let k_ct: usize = 36; - let k_auto_key: usize = k_ct + basek; - let k_pt: usize = 18; + let ct_k: usize = 36; + let atk_k: usize = ct_k + basek; + let pt_k: usize = 18; let rank: usize = 3; - let rows: usize = (k_ct + basek - 1) / basek; + let rows: usize = (ct_k + basek - 1) / basek; let sigma: f64 = 3.2; - let ct_size: usize = rows; - let auto_key_size: usize = (k_auto_key + basek - 1) / basek; let mut scratch: ScratchOwned = ScratchOwned::new( - GLWECiphertext::encrypt_sk_scratch_space(&module, ct_size) - | GLWECiphertext::decrypt_scratch_space(&module, ct_size) - | AutomorphismKey::generate_from_sk_scratch_space(&module, rank, auto_key_size) - | StreamPacker::scratch_space(&module, ct_size, auto_key_size, rank), + GLWECiphertext::encrypt_sk_scratch_space(&module, basek, ct_k) + | GLWECiphertext::decrypt_scratch_space(&module, basek, ct_k) + | AutomorphismKey::generate_from_sk_scratch_space(&module, basek, atk_k, rank) + | StreamPacker::scratch_space(&module, basek, ct_k, atk_k, rank), ); let mut sk: SecretKey> = SecretKey::alloc(&module, rank); @@ -44,18 +41,18 @@ fn packing() { let mut sk_dft: SecretKeyFourier, FFT64> = SecretKeyFourier::alloc(&module, rank); sk_dft.dft(&module, &sk); - let mut pt: GLWEPlaintext> = GLWEPlaintext::alloc(&module, basek, k_ct); + let mut pt: GLWEPlaintext> = GLWEPlaintext::alloc(&module, basek, ct_k); let mut data: Vec = vec![0i64; module.n()]; data.iter_mut().enumerate().for_each(|(i, x)| { *x = i as i64; }); - pt.data.encode_vec_i64(0, basek, k_pt, &data, 32); + pt.data.encode_vec_i64(0, basek, pt_k, &data, 32); let gal_els: Vec = StreamPacker::galois_elements(&module); let mut auto_keys: HashMap, FFT64>> = HashMap::new(); gal_els.iter().for_each(|gal_el| { - let mut key: AutomorphismKey, FFT64> = AutomorphismKey::alloc(&module, basek, k_auto_key, rows, rank); + let mut key: AutomorphismKey, FFT64> = AutomorphismKey::alloc(&module, basek, atk_k, rows, rank); key.generate_from_sk( &module, *gal_el, @@ -70,9 +67,9 @@ fn packing() { let log_batch: usize = 0; - let mut packer: StreamPacker = StreamPacker::new(&module, log_batch, basek, k_ct, rank); + let mut packer: StreamPacker = StreamPacker::new(&module, log_batch, basek, ct_k, rank); - let mut ct: GLWECiphertext> = GLWECiphertext::alloc(&module, basek, k_ct, rank); + let mut ct: GLWECiphertext> = GLWECiphertext::alloc(&module, basek, ct_k, rank); ct.encrypt_sk( &module, @@ -86,9 +83,7 @@ fn packing() { let mut res: Vec>> = Vec::new(); - let start = Instant::now(); (0..module.n() >> log_batch).for_each(|i| { - println!("pt {}", pt.data); ct.encrypt_sk( &module, &pt, @@ -113,15 +108,11 @@ fn packing() { ) } }); - let duration = start.elapsed(); - println!("Elapsed time: {} ms", duration.as_millis()); packer.flush(&module, &mut res, &auto_keys, scratch.borrow()); packer.reset(); - let mut pt_want: GLWEPlaintext> = GLWEPlaintext::alloc(&module, basek, k_ct); - - println!("{}", res.len()); + let mut pt_want: GLWEPlaintext> = GLWEPlaintext::alloc(&module, basek, ct_k); res.iter().enumerate().for_each(|(i, res_i)| { let mut data: Vec = vec![0i64; module.n()]; @@ -130,12 +121,10 @@ fn packing() { *x = reverse_bits_msb(i, log_n as u32) as i64; } }); - pt_want.data.encode_vec_i64(0, basek, k_pt, &data, 32); + pt_want.data.encode_vec_i64(0, basek, pt_k, &data, 32); res_i.decrypt(&module, &mut pt, &sk_dft, scratch.borrow()); - println!("{}", pt.data); - if i & 1 == 0 { pt.sub_inplace_ab(&module, &pt_want); } else { @@ -143,9 +132,9 @@ fn packing() { } let noise_have = pt.data.std(0, basek).log2(); - println!("noise_have: {}", noise_have); + // println!("noise_have: {}", noise_have); assert!( - noise_have < -((k_ct - basek) as f64), + noise_have < -((ct_k - basek) as f64), "noise: {}", noise_have ); diff --git a/core/src/test_fft64/tensor_key.rs b/core/src/test_fft64/tensor_key.rs index de4447c..66d7a34 100644 --- a/core/src/test_fft64/tensor_key.rs +++ b/core/src/test_fft64/tensor_key.rs @@ -32,8 +32,9 @@ fn test_encrypt_sk(log_n: usize, basek: usize, k: usize, sigma: f64, rank: usize let mut scratch: ScratchOwned = ScratchOwned::new(TensorKey::generate_from_sk_scratch_space( &module, + basek, + tensor_key.k(), rank, - tensor_key.size(), )); let mut sk: SecretKey> = SecretKey::alloc(&module, rank); diff --git a/core/src/test_fft64/trace.rs b/core/src/test_fft64/trace.rs index 8e72468..b4d8f4e 100644 --- a/core/src/test_fft64/trace.rs +++ b/core/src/test_fft64/trace.rs @@ -36,10 +36,10 @@ fn test_trace_inplace(log_n: usize, basek: usize, k: usize, sigma: f64, rank: us let mut source_xa: Source = Source::new([0u8; 32]); let mut scratch: ScratchOwned = ScratchOwned::new( - GLWECiphertext::encrypt_sk_scratch_space(&module, ct.size()) - | GLWECiphertext::decrypt_scratch_space(&module, ct.size()) - | AutomorphismKey::generate_from_sk_scratch_space(&module, rank, k_autokey) - | GLWECiphertext::trace_inplace_scratch_space(&module, ct.size(), k_autokey, rank), + GLWECiphertext::encrypt_sk_scratch_space(&module, basek, ct.k()) + | GLWECiphertext::decrypt_scratch_space(&module, basek, ct.k()) + | AutomorphismKey::generate_from_sk_scratch_space(&module, basek, k_autokey, rank) + | GLWECiphertext::trace_inplace_scratch_space(&module, basek, ct.k(), k_autokey, rank), ); let mut sk: SecretKey> = SecretKey::alloc(&module, rank); diff --git a/core/src/trace.rs b/core/src/trace.rs index 301453a..5e41757 100644 --- a/core/src/trace.rs +++ b/core/src/trace.rs @@ -24,16 +24,17 @@ impl GLWECiphertext> { pub fn trace_scratch_space( module: &Module, - out_size: usize, - in_size: usize, - autokey_size: usize, + basek: usize, + out_k: usize, + in_k: usize, + atk_k: usize, rank: usize, ) -> usize { - Self::automorphism_inplace_scratch_space(module, out_size.max(in_size), rank, autokey_size) + Self::automorphism_inplace_scratch_space(module, basek, out_k.min(in_k), atk_k, rank) } - pub fn trace_inplace_scratch_space(module: &Module, out_size: usize, autokey_size: usize, rank: usize) -> usize { - Self::automorphism_inplace_scratch_space(module, out_size, rank, autokey_size) + pub fn trace_inplace_scratch_space(module: &Module, basek: usize, out_k: usize, atk_k: usize, rank: usize) -> usize { + Self::automorphism_inplace_scratch_space(module, basek, out_k, atk_k, rank) } }