arnaucube
arnaucube/poulpyPublic Self-hosted repository
Updated arguments to get scratch space size for ops
Jean-Philippe Bossuat jeanphilippe.bossuat@gmail.com
Wed, 28 May 2025 18:46:24 +0200
commit

f9440c5407d2cf6d79c0c9ab5b079eaaf7ca46d9

parent

8209fb4e4058df2ab322df3f6f109e360221eaf1

M core/benches/external_product_glwe_fft64.rs → core/benches/external_product_glwe_fft64.rs

@@ -33,19 +33,20 @@

let rows: usize = (p.k_ct_in + p.basek - 1) / p.basek; let sigma: f64 = 3.2; - let mut ct_rgsw: GGSWCiphertext<Vec<u8>, FFT64> = GGSWCiphertext::alloc(&module, basek, k_ggsw, rows, rank); - let mut ct_rlwe_in: GLWECiphertext<Vec<u8>> = GLWECiphertext::alloc(&module, basek, k_ct_in, rank); - let mut ct_rlwe_out: GLWECiphertext<Vec<u8>> = GLWECiphertext::alloc(&module, basek, k_ct_out, rank); + let mut ct_ggsw: GGSWCiphertext<Vec<u8>, FFT64> = GGSWCiphertext::alloc(&module, basek, k_ggsw, rows, rank); + let mut ct_glwe_in: GLWECiphertext<Vec<u8>> = GLWECiphertext::alloc(&module, basek, k_ct_in, rank); + let mut ct_glwe_out: GLWECiphertext<Vec<u8>> = GLWECiphertext::alloc(&module, basek, k_ct_out, rank); let pt_rgsw: ScalarZnx<Vec<u8>> = 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 @@ sk.fill_ternary_prob(0.5, &mut source_xs);

let mut sk_dft: SecretKeyFourier<Vec<u8>, 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 @@ sigma,

scratch.borrow(), ); - ct_rlwe_in.encrypt_zero_sk( + ct_glwe_in.encrypt_zero_sk( &module, &sk_dft, &mut source_xa,

@@ -79,10 +80,10 @@ scratch.borrow(),

); 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 @@

let rows: usize = (p.k_ct + p.basek - 1) / p.basek; let sigma: f64 = 3.2; - let mut ct_rgsw: GGSWCiphertext<Vec<u8>, FFT64> = GGSWCiphertext::alloc(&module, basek, k_ggsw, rows, rank); - let mut ct_rlwe: GLWECiphertext<Vec<u8>> = GLWECiphertext::alloc(&module, basek, k_glwe, rank); + let mut ct_ggsw: GGSWCiphertext<Vec<u8>, FFT64> = GGSWCiphertext::alloc(&module, basek, k_ggsw, rows, rank); + let mut ct_glwe: GLWECiphertext<Vec<u8>> = GLWECiphertext::alloc(&module, basek, k_glwe, rank); let pt_rgsw: ScalarZnx<Vec<u8>> = 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 @@ sk.fill_ternary_prob(0.5, &mut source_xs);

let mut sk_dft: SecretKeyFourier<Vec<u8>, 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 @@ sigma,

scratch.borrow(), ); - ct_rlwe.encrypt_zero_sk( + ct_glwe.encrypt_zero_sk( &module, &sk_dft, &mut source_xa,

@@ -169,9 +170,9 @@

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), ); });
M core/benches/keyswitch_glwe_fft64.rs → core/benches/keyswitch_glwe_fft64.rs

@@ -40,13 +40,14 @@ let mut ct_in: GLWECiphertext<Vec<u8>> = GLWECiphertext::alloc(&module, basek, k_rlwe_in, rank_in);

let mut ct_out: GLWECiphertext<Vec<u8>> = 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 @@ let mut ksk: GLWESwitchingKey<Vec<u8>, FFT64> = GLWESwitchingKey::alloc(&module, basek, k_ksk, rows, rank, rank);

let mut ct: GLWECiphertext<Vec<u8>> = 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]);
M core/src/automorphism.rs → 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 AutomorphismKey<Vec<u8>, FFT64> { - pub fn generate_from_sk_scratch_space(module: &Module<FFT64>, 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<FFT64>, 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<FFT64>, 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<FFT64>, _basek: usize, _k: usize, _rank: usize) -> usize { + GGLWECiphertext::generate_from_pk_scratch_space(module, _basek, _k, _rank) } pub fn keyswitch_scratch_space( module: &Module<FFT64>, - 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<FFT64>, 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<FFT64>, + 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<FFT64>, - 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<FFT64>, 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<FFT64>, + 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<FFT64>, - 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<FFT64>, - 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 @@ assert_eq!(sk.n(), module.n());

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()) ) }
M core/src/gglwe_ciphertext.rs → core/src/gglwe_ciphertext.rs

@@ -57,14 +57,15 @@ }

} impl GGLWECiphertext<Vec<u8>, FFT64> { - pub fn generate_from_sk_scratch_space(module: &Module<FFT64>, rank: usize, size: usize) -> usize { - GLWECiphertext::encrypt_sk_scratch_space(module, size) + pub fn generate_from_sk_scratch_space(module: &Module<FFT64>, 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<FFT64>, _rank: usize, _pk_size: usize) -> usize { + pub fn generate_from_pk_scratch_space(_module: &Module<FFT64>, _basek: usize, _k: usize, _rank: usize) -> usize { unimplemented!() } }

@@ -88,13 +89,14 @@ assert_eq!(self.n(), module.n());

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()) ) }
M core/src/ggsw_ciphertext.rs → core/src/ggsw_ciphertext.rs

@@ -60,8 +60,9 @@ }

} impl GGSWCiphertext<Vec<u8>, FFT64> { - pub fn encrypt_sk_scratch_space(module: &Module<FFT64>, rank: usize, size: usize) -> usize { - GLWECiphertext::encrypt_sk_scratch_space(module, size) + pub fn encrypt_sk_scratch_space(module: &Module<FFT64>, 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 @@ }

pub(crate) fn expand_row_scratch_space( module: &Module<FFT64>, - 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<FFT64>, - 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<FFT64>, - 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<FFT64>, - 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<FFT64>, - 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<FFT64>, - 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<FFT64>, - 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<FFT64>, - 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 @@ R: VecZnxToMut,

{ 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 @@ assert!(

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 @@ assert!(

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() ) )
M core/src/glwe_ciphertext.rs → core/src/glwe_ciphertext.rs

@@ -76,106 +76,117 @@ }

} impl GLWECiphertext<Vec<u8>> { - pub fn encrypt_sk_scratch_space(module: &Module<FFT64>, ct_size: usize) -> usize { - module.vec_znx_big_normalize_tmp_bytes() + module.bytes_of_vec_znx_dft(1, ct_size) + module.bytes_of_vec_znx(1, ct_size) + pub fn encrypt_sk_scratch_space(module: &Module<FFT64>, 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<FFT64>, pk_size: usize) -> usize { - ((module.bytes_of_vec_znx_dft(1, pk_size) + module.bytes_of_vec_znx_big(1, pk_size)) | module.bytes_of_scalar_znx(1)) + pub fn encrypt_pk_scratch_space(module: &Module<FFT64>, 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<FFT64>, ct_size: usize) -> usize { - (module.vec_znx_big_normalize_tmp_bytes() | module.bytes_of_vec_znx_dft(1, ct_size)) - + module.bytes_of_vec_znx_big(1, ct_size) + pub fn decrypt_scratch_space(module: &Module<FFT64>, 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<FFT64>, - 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<FFT64>, - 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<FFT64>, 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<FFT64>, + 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<FFT64>, - 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<FFT64>, - 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<FFT64>, - 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<FFT64>, - 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 @@ assert!(

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 @@ assert!(

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 @@ assert_eq!(pt.n(), module.n());

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()) ) }
M core/src/glwe_ciphertext_fourier.rs → core/src/glwe_ciphertext_fourier.rs

@@ -53,59 +53,72 @@ }

impl GLWECiphertextFourier<Vec<u8>, FFT64> { #[allow(dead_code)] - pub(crate) fn idft_scratch_space(module: &Module<FFT64>, 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<FFT64>, 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<FFT64>, 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<FFT64>, 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<FFT64>, ct_size: usize) -> usize { + pub fn decrypt_scratch_space(module: &Module<FFT64>, 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<FFT64>, - 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<FFT64>, 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<FFT64>, + 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<FFT64>, - 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<FFT64>, - 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) } }
M core/src/glwe_packing.rs → 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 @@ self.counter = 0;

} /// Number of scratch space bytes required to call [Self::add]. - pub fn scratch_space(module: &Module<FFT64>, 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<FFT64>, 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<FFT64>) -> Vec<i64> {

@@ -142,8 +142,8 @@ }

} } -fn pack_core_scratch_space(module: &Module<FFT64>, 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<FFT64>, basek: usize, ct_k: usize, atk_k: usize, rank: usize) -> usize { + combine_scratch_space(module, basek, ct_k, atk_k, rank) } fn pack_core<D: AsRef<[u8]>, DataAK: AsRef<[u8]>>(

@@ -203,10 +203,10 @@ }

} } -fn combine_scratch_space(module: &Module<FFT64>, 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<FFT64>, 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 @@ } else {

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)) + 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 { - // 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); - 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);
M core/src/keys.rs → core/src/keys.rs

@@ -180,9 +180,11 @@

// 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,
M core/src/keyswitch_key.rs → 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 GLWESwitchingKey<Vec<u8>, FFT64> { - pub fn encrypt_sk_scratch_space(module: &Module<FFT64>, rank: usize, size: usize) -> usize { - GGLWECiphertext::generate_from_sk_scratch_space(module, rank, size) + pub fn encrypt_sk_scratch_space(module: &Module<FFT64>, 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<FFT64>, rank: usize, pk_size: usize) -> usize { - GGLWECiphertext::generate_from_pk_scratch_space(module, rank, pk_size) + pub fn encrypt_pk_scratch_space(module: &Module<FFT64>, _basek: usize, _k: usize, _rank: usize) -> usize { + GGLWECiphertext::generate_from_pk_scratch_space(module, _basek, _k, _rank) } pub fn keyswitch_scratch_space( module: &Module<FFT64>, - 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<FFT64>, 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<FFT64>, + 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<FFT64>, - 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<FFT64>, - 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 } }
M core/src/tensor_key.rs → core/src/tensor_key.rs

@@ -58,8 +58,8 @@ }

} impl TensorKey<Vec<u8>, FFT64> { - pub fn generate_from_sk_scratch_space(module: &Module<FFT64>, 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<FFT64>, basek: usize, k: usize, rank: usize) -> usize { + module.bytes_of_scalar_znx_dft(1) + GLWESwitchingKey::encrypt_sk_scratch_space(module, basek, k, rank) } }
M core/src/test_fft64/automorphism_key.rs → core/src/test_fft64/automorphism_key.rs

@@ -39,15 +39,9 @@ let mut source_xe: Source = Source::new([0u8; 32]);

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<Vec<u8>> = SecretKey::alloc(&module, rank);

@@ -132,7 +126,7 @@ }

fn test_automorphism_inplace(p0: i64, p1: i64, log_n: usize, basek: usize, k_ksk: usize, sigma: f64, rank: usize) { let module: Module<FFT64> = Module::<FFT64>::new(1 << log_n); - let rows = (k_ksk + basek - 1) / basek; + let rows: usize = (k_ksk + basek - 1) / basek; let mut auto_key: AutomorphismKey<Vec<u8>, FFT64> = AutomorphismKey::alloc(&module, basek, k_ksk, rows, rank); let mut auto_key_apply: AutomorphismKey<Vec<u8>, FFT64> = AutomorphismKey::alloc(&module, basek, k_ksk, rows, rank);

@@ -142,9 +136,9 @@ let mut source_xe: Source = Source::new([0u8; 32]);

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<Vec<u8>> = SecretKey::alloc(&module, rank);
M core/src/test_fft64/gglwe.rs → core/src/test_fft64/gglwe.rs

@@ -84,8 +84,8 @@ let mut source_xe: Source = Source::new([0u8; 32]);

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<Vec<u8>> = SecretKey::alloc(&module, rank_in);

@@ -148,15 +148,16 @@ let mut source_xe: Source = Source::new([0u8; 32]);

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 @@ let mut source_xe: Source = Source::new([0u8; 32]);

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 @@ let mut source_xe: Source = Source::new([0u8; 32]);

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 @@ // gglwe_(m) (x) RGSW_(X^k) = gglwe_(m * X^k)

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<Vec<u8>, FFT64> = GLWECiphertextFourier::alloc(&module, basek, k, rank_out);

@@ -482,10 +486,10 @@ let mut source_xe: Source = Source::new([0u8; 32]);

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;
M core/src/test_fft64/ggsw.rs → core/src/test_fft64/ggsw.rs

@@ -73,14 +73,14 @@ test_external_product_inplace(12, 15, 60, rank, 3.2);

}); } -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<FFT64> = Module::<FFT64>::new(1 << log_n); - let rows: usize = (k_ggsw + basek - 1) / basek; + let rows: usize = (k + basek - 1) / basek; - let mut ct: GGSWCiphertext<Vec<u8>, FFT64> = GGSWCiphertext::alloc(&module, basek, k_ggsw, rows, rank); - let mut pt_have: GLWEPlaintext<Vec<u8>> = GLWEPlaintext::alloc(&module, basek, k_ggsw); - let mut pt_want: GLWEPlaintext<Vec<u8>> = GLWEPlaintext::alloc(&module, basek, k_ggsw); + let mut ct: GGSWCiphertext<Vec<u8>, FFT64> = GGSWCiphertext::alloc(&module, basek, k, rows, rank); + let mut pt_have: GLWEPlaintext<Vec<u8>> = GLWEPlaintext::alloc(&module, basek, k); + let mut pt_want: GLWEPlaintext<Vec<u8>> = GLWEPlaintext::alloc(&module, basek, k); let mut pt_scalar: ScalarZnx<Vec<u8>> = module.new_scalar_znx(1); let mut source_xs: Source = Source::new([0u8; 32]);

@@ -90,8 +90,8 @@

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<Vec<u8>> = SecretKey::alloc(&module, rank);

@@ -110,7 +110,7 @@ sigma,

scratch.borrow(), ); - let mut ct_glwe_fourier: GLWECiphertextFourier<Vec<u8>, FFT64> = GLWECiphertextFourier::alloc(&module, basek, k_ggsw, rank); + let mut ct_glwe_fourier: GLWECiphertextFourier<Vec<u8>, FFT64> = GLWECiphertextFourier::alloc(&module, basek, k, rank); let mut pt_dft: VecZnxDft<Vec<u8>, FFT64> = module.new_vec_znx_dft(1, ct.size()); let mut pt_big: VecZnxBig<Vec<u8>, FFT64> = module.new_vec_znx_big(1, ct.size());

@@ -132,7 +132,7 @@ ct_glwe_fourier.decrypt(&module, &mut pt_have, &sk_dft, scratch.borrow());

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 @@ let mut source_xe: Source = Source::new([0u8; 32]);

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 @@ let mut source_xe: Source = Source::new([0u8; 32]);

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 @@ let mut source_xe: Source = Source::new([0u8; 32]);

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 @@ let mut source_xe: Source = Source::new([0u8; 32]);

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 @@

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 @@

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<Vec<u8>> = SecretKey::alloc(&module, rank);
M core/src/test_fft64/glwe.rs → core/src/test_fft64/glwe.rs

@@ -43,10 +43,10 @@ }

#[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 @@ test_automorphism(12, 12, -5, 60, 45, 60, rank, 3.2);

}); } -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<FFT64> = Module::<FFT64>::new(1 << log_n); - let mut ct: GLWECiphertext<Vec<u8>> = GLWECiphertext::alloc(&module, basek, k_ct, rank); + let mut ct: GLWECiphertext<Vec<u8>> = GLWECiphertext::alloc(&module, basek, ct_k, rank); let mut pt: GLWEPlaintext<Vec<u8>> = GLWEPlaintext::alloc(&module, basek, k_pt); let mut source_xs: Source = Source::new([0u8; 32]);

@@ -102,7 +102,8 @@ let mut source_xe: Source = Source::new([0u8; 32]);

let mut source_xa: Source = Source::new([0u8; 32]); let mut scratch: ScratchOwned = ScratchOwned::new( - GLWECiphertext::encrypt_sk_scratch_space(&module, 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<Vec<u8>> = SecretKey::alloc(&module, rank);

@@ -151,10 +152,10 @@ )

}); } -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<FFT64> = Module::<FFT64>::new(1 << log_n); - let mut pt: GLWEPlaintext<Vec<u8>> = GLWEPlaintext::alloc(&module, basek, k_ct); + let mut pt: GLWEPlaintext<Vec<u8>> = 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 @@ sk.fill_ternary_prob(0.5, &mut source_xs);

let mut sk_dft: SecretKeyFourier<Vec<u8>, FFT64> = SecretKeyFourier::alloc(&module, rank); sk_dft.dft(&module, &sk); - let mut ct_dft: GLWECiphertextFourier<Vec<u8>, FFT64> = GLWECiphertextFourier::alloc(&module, basek, k_ct, rank); + let mut ct_dft: GLWECiphertextFourier<Vec<u8>, 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 @@ scratch.borrow(),

); 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<FFT64> = Module::<FFT64>::new(1 << log_n); - let mut ct: GLWECiphertext<Vec<u8>> = GLWECiphertext::alloc(&module, basek, k_ct, rank); - let mut pt_want: GLWEPlaintext<Vec<u8>> = GLWEPlaintext::alloc(&module, basek, k_ct); + let mut ct: GLWECiphertext<Vec<u8>> = GLWECiphertext::alloc(&module, basek, ct_k, rank); + let mut pt_want: GLWEPlaintext<Vec<u8>> = 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 @@ let mut pk: GLWEPublicKey<Vec<u8>, FFT64> = GLWEPublicKey::alloc(&module, basek, k_pk, rank);

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<i64> = vec![0i64; module.n()];

@@ -216,7 +217,7 @@ data_want

.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 @@ sigma,

scratch.borrow(), ); - let mut pt_have: GLWEPlaintext<Vec<u8>> = GLWEPlaintext::alloc(&module, basek, k_ct); + let mut pt_have: GLWEPlaintext<Vec<u8>> = 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<FFT64> = Module::<FFT64>::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<Vec<u8>, FFT64> = GLWESwitchingKey::alloc(&module, basek, k_keyswitch, rows, rank_in, rank_out); - let mut ct_in: GLWECiphertext<Vec<u8>> = GLWECiphertext::alloc(&module, basek, k_ct_in, rank_in); - let mut ct_out: GLWECiphertext<Vec<u8>> = GLWECiphertext::alloc(&module, basek, k_ct_out, rank_out); - let mut pt_want: GLWEPlaintext<Vec<u8>> = GLWEPlaintext::alloc(&module, basek, k_ct_in); - let mut pt_have: GLWEPlaintext<Vec<u8>> = GLWEPlaintext::alloc(&module, basek, k_ct_out); + let mut ksk: GLWESwitchingKey<Vec<u8>, FFT64> = GLWESwitchingKey::alloc(&module, basek, k_keyswitch, rows, in_rank, out_rank); + let mut ct_in: GLWECiphertext<Vec<u8>> = GLWECiphertext::alloc(&module, basek, ct_k_in, in_rank); + let mut ct_out: GLWECiphertext<Vec<u8>> = GLWECiphertext::alloc(&module, basek, ct_k_out, out_rank); + let mut pt_want: GLWEPlaintext<Vec<u8>> = GLWEPlaintext::alloc(&module, basek, ct_k_in); + let mut pt_have: GLWEPlaintext<Vec<u8>> = 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 @@ .data

.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<Vec<u8>> = SecretKey::alloc(&module, rank_in); + let mut sk_in: SecretKey<Vec<u8>> = SecretKey::alloc(&module, in_rank); sk_in.fill_ternary_prob(0.5, &mut source_xs); - let mut sk_in_dft: SecretKeyFourier<Vec<u8>, FFT64> = SecretKeyFourier::alloc(&module, rank_in); + let mut sk_in_dft: SecretKeyFourier<Vec<u8>, FFT64> = SecretKeyFourier::alloc(&module, in_rank); sk_in_dft.dft(&module, &sk_in); - let mut sk_out: SecretKey<Vec<u8>> = SecretKey::alloc(&module, rank_out); + let mut sk_out: SecretKey<Vec<u8>> = SecretKey::alloc(&module, out_rank); sk_out.fill_ternary_prob(0.5, &mut source_xs); - let mut sk_out_dft: SecretKeyFourier<Vec<u8>, FFT64> = SecretKeyFourier::alloc(&module, rank_out); + let mut sk_out_dft: SecretKeyFourier<Vec<u8>, FFT64> = SecretKeyFourier::alloc(&module, out_rank); sk_out_dft.dft(&module, &sk_out); ksk.generate_from_sk(

@@ -334,8 +336,8 @@ 0.5,

0f64, sigma * sigma, 0f64, - rank_in as f64, - k_ct_in, + in_rank as f64, + ct_k_in, k_keyswitch, );

@@ -347,14 +349,14 @@ noise_want

); } -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<FFT64> = Module::<FFT64>::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<Vec<u8>, FFT64> = GLWESwitchingKey::alloc(&module, basek, k_ksk, rows, rank, rank); - let mut ct_rlwe: GLWECiphertext<Vec<u8>> = GLWECiphertext::alloc(&module, basek, k_ct, rank); - let mut pt_want: GLWEPlaintext<Vec<u8>> = GLWEPlaintext::alloc(&module, basek, k_ct); - let mut pt_have: GLWEPlaintext<Vec<u8>> = GLWEPlaintext::alloc(&module, basek, k_ct); + let mut ct_glwe: GLWECiphertext<Vec<u8>> = GLWECiphertext::alloc(&module, basek, ct_k, rank); + let mut pt_want: GLWEPlaintext<Vec<u8>> = GLWEPlaintext::alloc(&module, basek, ct_k); + let mut pt_have: GLWEPlaintext<Vec<u8>> = 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 @@ .data

.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<Vec<u8>> = SecretKey::alloc(&module, rank);

@@ -394,7 +396,7 @@ sigma,

scratch.borrow(), ); - ct_rlwe.encrypt_sk( + ct_glwe.encrypt_sk( &module, &pt_want, &sk0_dft,

@@ -404,9 +406,9 @@ sigma,

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 @@ 0f64,

sigma * sigma, 0f64, rank as f64, - k_ct, + ct_k, k_ksk, );

@@ -437,19 +439,19 @@ log_n: usize,

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<FFT64> = Module::<FFT64>::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<Vec<u8>, FFT64> = AutomorphismKey::alloc(&module, basek, k_autokey, rows, rank); - let mut ct_in: GLWECiphertext<Vec<u8>> = GLWECiphertext::alloc(&module, basek, k_ct_in, rank); - let mut ct_out: GLWECiphertext<Vec<u8>> = GLWECiphertext::alloc(&module, basek, k_ct_out, rank); - let mut pt_want: GLWEPlaintext<Vec<u8>> = GLWEPlaintext::alloc(&module, basek, k_ct_in); - let mut pt_have: GLWEPlaintext<Vec<u8>> = GLWEPlaintext::alloc(&module, basek, k_ct_out); + let mut ct_in: GLWECiphertext<Vec<u8>> = GLWECiphertext::alloc(&module, basek, ct_k_in, rank); + let mut ct_out: GLWECiphertext<Vec<u8>> = GLWECiphertext::alloc(&module, basek, ct_k_out, rank); + let mut pt_want: GLWEPlaintext<Vec<u8>> = GLWEPlaintext::alloc(&module, basek, ct_k_in); + let mut pt_have: GLWEPlaintext<Vec<u8>> = 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 @@ .data

.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<Vec<u8>> = SecretKey::alloc(&module, rank);

@@ -511,7 +513,7 @@ 0f64,

sigma * sigma, 0f64, rank as f64, - k_ct_in, + ct_k_in, k_autokey, );

@@ -523,14 +525,14 @@ noise_want

); } -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<FFT64> = Module::<FFT64>::new(1 << log_n); - let rows: usize = (k_ct + basek - 1) / basek; + let rows: usize = (ct_k + basek - 1) / basek; let mut autokey: AutomorphismKey<Vec<u8>, FFT64> = AutomorphismKey::alloc(&module, basek, k_autokey, rows, rank); - let mut ct: GLWECiphertext<Vec<u8>> = GLWECiphertext::alloc(&module, basek, k_ct, rank); - let mut pt_want: GLWEPlaintext<Vec<u8>> = GLWEPlaintext::alloc(&module, basek, k_ct); - let mut pt_have: GLWEPlaintext<Vec<u8>> = GLWEPlaintext::alloc(&module, basek, k_ct); + let mut ct: GLWECiphertext<Vec<u8>> = GLWECiphertext::alloc(&module, basek, ct_k, rank); + let mut pt_want: GLWEPlaintext<Vec<u8>> = GLWEPlaintext::alloc(&module, basek, ct_k); + let mut pt_have: GLWEPlaintext<Vec<u8>> = 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 @@ .data

.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<Vec<u8>> = SecretKey::alloc(&module, rank);

@@ -590,7 +592,7 @@ 0f64,

sigma * sigma, 0f64, rank as f64, - k_ct, + ct_k, k_autokey, );

@@ -602,17 +604,17 @@ noise_want

); } -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<FFT64> = Module::<FFT64>::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<Vec<u8>, FFT64> = GGSWCiphertext::alloc(&module, basek, k_ggsw, rows, rank); - let mut ct_rlwe_in: GLWECiphertext<Vec<u8>> = GLWECiphertext::alloc(&module, basek, k_ct_in, rank); - let mut ct_rlwe_out: GLWECiphertext<Vec<u8>> = GLWECiphertext::alloc(&module, basek, k_ct_out, rank); + let mut ct_ggsw: GGSWCiphertext<Vec<u8>, FFT64> = GGSWCiphertext::alloc(&module, basek, k_ggsw, rows, rank); + let mut ct_glwe_in: GLWECiphertext<Vec<u8>> = GLWECiphertext::alloc(&module, basek, ct_k_in, rank); + let mut ct_glwe_out: GLWECiphertext<Vec<u8>> = GLWECiphertext::alloc(&module, basek, ct_k_out, rank); let mut pt_rgsw: ScalarZnx<Vec<u8>> = module.new_scalar_znx(1); - let mut pt_want: GLWEPlaintext<Vec<u8>> = GLWEPlaintext::alloc(&module, basek, k_ct_in); - let mut pt_have: GLWEPlaintext<Vec<u8>> = GLWEPlaintext::alloc(&module, basek, k_ct_out); + let mut pt_want: GLWEPlaintext<Vec<u8>> = GLWEPlaintext::alloc(&module, basek, ct_k_in); + let mut pt_have: GLWEPlaintext<Vec<u8>> = 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 @@

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 @@

let mut sk_dft: SecretKeyFourier<Vec<u8>, 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 @@ sigma,

scratch.borrow(), ); - ct_rlwe_in.encrypt_sk( + ct_glwe_in.encrypt_sk( &module, &pt_want, &sk_dft,

@@ -668,9 +671,9 @@ sigma,

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 @@ var_a1_err,

var_gct_err_lhs, var_gct_err_rhs, rank as f64, - k_ct_in, + ct_k_in, k_ggsw, );

@@ -707,15 +710,15 @@ noise_want

); } -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<FFT64> = Module::<FFT64>::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<Vec<u8>, FFT64> = GGSWCiphertext::alloc(&module, basek, k_ggsw, rows, rank); - let mut ct_rlwe: GLWECiphertext<Vec<u8>> = GLWECiphertext::alloc(&module, basek, k_ct, rank); + let mut ct_ggsw: GGSWCiphertext<Vec<u8>, FFT64> = GGSWCiphertext::alloc(&module, basek, k_ggsw, rows, rank); + let mut ct_glwe: GLWECiphertext<Vec<u8>> = GLWECiphertext::alloc(&module, basek, ct_k, rank); let mut pt_rgsw: ScalarZnx<Vec<u8>> = module.new_scalar_znx(1); - let mut pt_want: GLWEPlaintext<Vec<u8>> = GLWEPlaintext::alloc(&module, basek, k_ct); - let mut pt_have: GLWEPlaintext<Vec<u8>> = GLWEPlaintext::alloc(&module, basek, k_ct); + let mut pt_want: GLWEPlaintext<Vec<u8>> = GLWEPlaintext::alloc(&module, basek, ct_k); + let mut pt_have: GLWEPlaintext<Vec<u8>> = 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 @@

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<Vec<u8>> = SecretKey::alloc(&module, rank);

@@ -745,7 +748,7 @@

let mut sk_dft: SecretKeyFourier<Vec<u8>, 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 @@ sigma,

scratch.borrow(), ); - ct_rlwe.encrypt_sk( + ct_glwe.encrypt_sk( &module, &pt_want, &sk_dft,

@@ -765,9 +768,9 @@ sigma,

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 @@ var_a1_err,

var_gct_err_lhs, var_gct_err_rhs, rank as f64, - k_ct, + ct_k, k_ggsw, );
M core/src/test_fft64/glwe_fourier.rs → 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 @@ .data

.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 @@ .data

.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<Vec<u8>> = SecretKey::alloc(&module, rank);

@@ -247,7 +249,7 @@ let module: Module<FFT64> = Module::<FFT64>::new(1 << log_n);

let rows: usize = (k_ct_in + basek - 1) / basek; - let mut ct_rgsw: GGSWCiphertext<Vec<u8>, FFT64> = GGSWCiphertext::alloc(&module, basek, k_ggsw, rows, rank); + let mut ct_ggsw: GGSWCiphertext<Vec<u8>, FFT64> = GGSWCiphertext::alloc(&module, basek, k_ggsw, rows, rank); let mut ct_in: GLWECiphertext<Vec<u8>> = GLWECiphertext::alloc(&module, basek, k_ct_in, rank); let mut ct_out: GLWECiphertext<Vec<u8>> = GLWECiphertext::alloc(&module, basek, k_ct_out, rank); let mut ct_in_dft: GLWECiphertextFourier<Vec<u8>, FFT64> = GLWECiphertextFourier::alloc(&module, basek, k_ct_in, rank);

@@ -267,15 +269,16 @@ .fill_uniform(basek, 0, pt_want.size(), &mut source_xa);

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<Vec<u8>> = SecretKey::alloc(&module, rank);

@@ -284,7 +287,7 @@

let mut sk_dft: SecretKeyFourier<Vec<u8>, 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 @@ scratch.borrow(),

); 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 @@ .fill_uniform(basek, 0, pt_want.size(), &mut source_xa);

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<Vec<u8>> = SecretKey::alloc(&module, rank);

@@ -410,9 +413,8 @@ ct_rlwe_dft.idft(&module, &mut ct, scratch.borrow());

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();
M core/src/test_fft64/glwe_packing.rs → 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 @@ let mut source_xe: Source = Source::new([0u8; 32]);

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<Vec<u8>> = SecretKey::alloc(&module, rank);

@@ -44,18 +41,18 @@

let mut sk_dft: SecretKeyFourier<Vec<u8>, FFT64> = SecretKeyFourier::alloc(&module, rank); sk_dft.dft(&module, &sk); - let mut pt: GLWEPlaintext<Vec<u8>> = GLWEPlaintext::alloc(&module, basek, k_ct); + let mut pt: GLWEPlaintext<Vec<u8>> = GLWEPlaintext::alloc(&module, basek, ct_k); let mut data: Vec<i64> = 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<i64> = StreamPacker::galois_elements(&module); let mut auto_keys: HashMap<i64, AutomorphismKey<Vec<u8>, FFT64>> = HashMap::new(); gal_els.iter().for_each(|gal_el| { - let mut key: AutomorphismKey<Vec<u8>, FFT64> = AutomorphismKey::alloc(&module, basek, k_auto_key, rows, rank); + let mut key: AutomorphismKey<Vec<u8>, FFT64> = AutomorphismKey::alloc(&module, basek, atk_k, rows, rank); key.generate_from_sk( &module, *gal_el,

@@ -70,9 +67,9 @@ });

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<Vec<u8>> = GLWECiphertext::alloc(&module, basek, k_ct, rank); + let mut ct: GLWECiphertext<Vec<u8>> = GLWECiphertext::alloc(&module, basek, ct_k, rank); ct.encrypt_sk( &module,

@@ -86,9 +83,7 @@ );

let mut res: Vec<GLWECiphertext<Vec<u8>>> = 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 @@ scratch.borrow(),

) } }); - 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<Vec<u8>> = GLWEPlaintext::alloc(&module, basek, k_ct); - - println!("{}", res.len()); + let mut pt_want: GLWEPlaintext<Vec<u8>> = GLWEPlaintext::alloc(&module, basek, ct_k); res.iter().enumerate().for_each(|(i, res_i)| { let mut data: Vec<i64> = vec![0i64; module.n()];

@@ -130,12 +121,10 @@ if i % 5 == 0 {

*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 @@ pt.add_inplace(&module, &pt_want);

} 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 );
M core/src/test_fft64/tensor_key.rs → core/src/test_fft64/tensor_key.rs

@@ -32,8 +32,9 @@ let mut source_xa: Source = Source::new([0u8; 32]);

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<Vec<u8>> = SecretKey::alloc(&module, rank);
M core/src/test_fft64/trace.rs → core/src/test_fft64/trace.rs

@@ -36,10 +36,10 @@ let mut source_xe: Source = Source::new([0u8; 32]);

let mut source_xa: Source = Source::new([0u8; 32]); let mut scratch: ScratchOwned = ScratchOwned::new( - GLWECiphertext::encrypt_sk_scratch_space(&module, 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<Vec<u8>> = SecretKey::alloc(&module, rank);
M core/src/trace.rs → core/src/trace.rs

@@ -24,16 +24,17 @@ }

pub fn trace_scratch_space( module: &Module<FFT64>, - 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<FFT64>, 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<FFT64>, basek: usize, out_k: usize, atk_k: usize, rank: usize) -> usize { + Self::automorphism_inplace_scratch_space(module, basek, out_k, atk_k, rank) } }