diff --git a/poulpy-core/src/encryption/compressed/gglwe.rs b/poulpy-core/src/encryption/compressed/gglwe.rs index 1dfbf58..acf2eac 100644 --- a/poulpy-core/src/encryption/compressed/gglwe.rs +++ b/poulpy-core/src/encryption/compressed/gglwe.rs @@ -143,20 +143,21 @@ where let mut source_xa = Source::new(seed); let (mut tmp_pt, scrach_1) = scratch.take_glwe_plaintext(res); - for col_i in 0..rank_in { - for d_i in 0..dnum { + + for col_j in 0..rank_in { + for row_i in 0..dnum { // Adds the scalar_znx_pt to the i-th limb of the vec_znx_pt tmp_pt.data.zero(); // zeroes for next iteration - self.vec_znx_add_scalar_inplace(&mut tmp_pt.data, 0, (dsize - 1) + d_i * dsize, pt, col_i); + self.vec_znx_add_scalar_inplace(&mut tmp_pt.data, 0, (dsize - 1) + row_i * dsize, pt, col_j); self.vec_znx_normalize_inplace(base2k, &mut tmp_pt.data, 0, scrach_1); let (seed, mut source_xa_tmp) = source_xa.branch(); - seeds[col_i * dnum + d_i] = seed; + seeds[row_i * rank_in + col_j] = seed; self.glwe_encrypt_sk_internal( res.base2k().into(), res.k().into(), - &mut res.at_mut(d_i, col_i).data, + &mut res.at_mut(row_i, col_j).data, cols, true, Some((&tmp_pt, 0)), diff --git a/poulpy-core/src/layouts/compressed/gglwe.rs b/poulpy-core/src/layouts/compressed/gglwe.rs index 0fb0382..bb5fe55 100644 --- a/poulpy-core/src/layouts/compressed/gglwe.rs +++ b/poulpy-core/src/layouts/compressed/gglwe.rs @@ -263,9 +263,8 @@ where let rank_in: usize = res.rank_in().into(); let dnum: usize = res.dnum().into(); - - for row_i in 0..dnum { - for col_i in 0..rank_in { + for col_i in 0..rank_in { + for row_i in 0..dnum { self.decompress_glwe(&mut res.at_mut(row_i, col_i), &other.at(row_i, col_i)); } } diff --git a/poulpy-core/src/noise/gglwe.rs b/poulpy-core/src/noise/gglwe.rs index 1c5cb9e..12c907f 100644 --- a/poulpy-core/src/noise/gglwe.rs +++ b/poulpy-core/src/noise/gglwe.rs @@ -1,6 +1,6 @@ use poulpy_hal::{ api::VecZnxAddScalarInplace, - layouts::{Backend, DataRef, Module, ScalarZnxToRef, Scratch, Stats, ZnxInfos, ZnxZero}, + layouts::{Backend, DataRef, Module, ScalarZnxToRef, Scratch, Stats, ZnxZero}, }; use crate::{ @@ -78,7 +78,6 @@ where let dsize: usize = res.dsize().into(); let (mut pt, scratch_1) = scratch.take_glwe_plaintext(res); pt.data_mut().zero(); - println!("col: {res_col} {}", pt_want.to_ref().cols()); self.vec_znx_add_scalar_inplace( &mut pt.data, 0, diff --git a/poulpy-core/src/tests/mod.rs b/poulpy-core/src/tests/mod.rs index 16dce7c..7708c2a 100644 --- a/poulpy-core/src/tests/mod.rs +++ b/poulpy-core/src/tests/mod.rs @@ -35,6 +35,7 @@ glwe_packer => crate::tests::test_suite::test_glwe_packer, // GGLWE Encryption gglwe_switching_key_encrypt_sk => crate::tests::test_suite::encryption::test_gglwe_switching_key_encrypt_sk, gglwe_switching_key_compressed_encrypt_sk => crate::tests::test_suite::encryption::test_gglwe_switching_key_compressed_encrypt_sk, +gglwe_compressed_encrypt_sk => crate::tests::test_suite::encryption::test_gglwe_compressed_encrypt_sk, gglwe_automorphism_key_encrypt_sk => crate::tests::test_suite::encryption::test_gglwe_automorphism_key_encrypt_sk, gglwe_automorphism_key_compressed_encrypt_sk => crate::tests::test_suite::encryption::test_gglwe_automorphism_key_compressed_encrypt_sk, gglwe_tensor_key_encrypt_sk => crate::tests::test_suite::encryption::test_gglwe_tensor_key_encrypt_sk, @@ -98,6 +99,7 @@ glwe_packer => crate::tests::test_suite::test_glwe_packer, // GGLWE Encryption gglwe_switching_key_encrypt_sk => crate::tests::test_suite::encryption::test_gglwe_switching_key_encrypt_sk, gglwe_switching_key_compressed_encrypt_sk => crate::tests::test_suite::encryption::test_gglwe_switching_key_compressed_encrypt_sk, +gglwe_compressed_encrypt_sk => crate::tests::test_suite::encryption::test_gglwe_compressed_encrypt_sk, gglwe_automorphism_key_encrypt_sk => crate::tests::test_suite::encryption::test_gglwe_automorphism_key_encrypt_sk, gglwe_automorphism_key_compressed_encrypt_sk => crate::tests::test_suite::encryption::test_gglwe_automorphism_key_compressed_encrypt_sk, gglwe_tensor_key_encrypt_sk => crate::tests::test_suite::encryption::test_gglwe_tensor_key_encrypt_sk, diff --git a/poulpy-core/src/tests/test_suite/conversion.rs b/poulpy-core/src/tests/test_suite/conversion.rs index 5eaead9..9ee70e2 100644 --- a/poulpy-core/src/tests/test_suite/conversion.rs +++ b/poulpy-core/src/tests/test_suite/conversion.rs @@ -275,8 +275,6 @@ where let mut glwe_pt: GLWEPlaintext> = GLWEPlaintext::alloc_from_infos(&glwe_infos); glwe_pt.encode_vec_i64(&data, k_lwe_pt); - println!("glwe_pt: {glwe_pt}"); - let mut glwe_ct: GLWE> = GLWE::alloc_from_infos(&glwe_infos); glwe_ct.encrypt_sk( module, diff --git a/poulpy-core/src/tests/test_suite/encryption/gglwe_atk.rs b/poulpy-core/src/tests/test_suite/encryption/gglwe_atk.rs index 42d7fb0..9f917af 100644 --- a/poulpy-core/src/tests/test_suite/encryption/gglwe_atk.rs +++ b/poulpy-core/src/tests/test_suite/encryption/gglwe_atk.rs @@ -176,7 +176,6 @@ where let max_noise: f64 = SIGMA.log2() - (atk.k().as_usize() as f64) + 0.5; - println!("rank: {rank} dsize: {dsize} dnum: {dnum}"); for row in 0..atk.dnum().as_usize() { for col in 0..atk.rank().as_usize() { let noise_have = atk diff --git a/poulpy-core/src/tests/test_suite/encryption/gglwe_ct.rs b/poulpy-core/src/tests/test_suite/encryption/gglwe_ct.rs index 582413e..6122e9b 100644 --- a/poulpy-core/src/tests/test_suite/encryption/gglwe_ct.rs +++ b/poulpy-core/src/tests/test_suite/encryption/gglwe_ct.rs @@ -5,12 +5,13 @@ use poulpy_hal::{ }; use crate::{ - GGLWEEncryptSk, GGLWEKeyswitch, GLWESwitchingKeyCompressedEncryptSk, GLWESwitchingKeyEncryptSk, ScratchTakeCore, + GGLWECompressedEncryptSk, GGLWEEncryptSk, GGLWEKeyswitch, GLWESwitchingKeyCompressedEncryptSk, GLWESwitchingKeyEncryptSk, + ScratchTakeCore, decryption::GLWEDecrypt, encryption::SIGMA, layouts::{ - GGLWEInfos, GGLWELayout, GLWESecret, GLWESecretPreparedFactory, GLWESwitchingKey, GLWESwitchingKeyCompressed, - GLWESwitchingKeyDecompress, LWEInfos, + GGLWE, GGLWECompressed, GGLWEInfos, GGLWELayout, GLWESecret, GLWESecretPreparedFactory, + GLWESwitchingKey, GLWESwitchingKeyCompressed, GLWESwitchingKeyDecompress, LWEInfos, prepared::{GGLWEPreparedFactory, GLWESecretPrepared}, }, noise::GGLWENoise, @@ -121,18 +122,18 @@ where let n: usize = module.n(); let base2k: usize = 12; let k_ksk: usize = 54; - let dsize: usize = k_ksk / base2k; + let max_dsize: usize = k_ksk / base2k; for rank_in in 1_usize..3 { for rank_out in 1_usize..3 { - for di in 1_usize..dsize + 1 { - let dnum: usize = (k_ksk - di * base2k) / (di * base2k); + for dsize in 1_usize..max_dsize { + let dnum: usize = (k_ksk - dsize * base2k) / (dsize * base2k); let gglwe_infos: GGLWELayout = GGLWELayout { n: n.into(), base2k: base2k.into(), k: k_ksk.into(), dnum: dnum.into(), - dsize: di.into(), + dsize: dsize.into(), rank_in: rank_in.into(), rank_out: rank_out.into(), }; @@ -198,3 +199,95 @@ where } } } + +pub fn test_gglwe_compressed_encrypt_sk(module: &Module) +where + Module: GGLWEEncryptSk + + GGLWEPreparedFactory + + GGLWEKeyswitch + + GLWEDecrypt + + GLWESecretPreparedFactory + + GLWESwitchingKeyEncryptSk + + GGLWECompressedEncryptSk + + GLWESwitchingKeyDecompress + + GGLWENoise + + VecZnxFillUniform, + ScratchOwned: ScratchOwnedAlloc + ScratchOwnedBorrow, + Scratch: ScratchAvailable + ScratchTakeCore, +{ + let n: usize = module.n(); + let base2k: usize = 12; + let k_ksk: usize = 54; + let max_dsize: usize = k_ksk / base2k; + for rank_in in 1_usize..3 { + for rank_out in 1_usize..3 { + for dsize in 1_usize..max_dsize + 1 { + let dnum: usize = (k_ksk - dsize * base2k) / (dsize * base2k); + + let gglwe_infos: GGLWELayout = GGLWELayout { + n: n.into(), + base2k: base2k.into(), + k: k_ksk.into(), + dnum: dnum.into(), + dsize: dsize.into(), + rank_in: rank_in.into(), + rank_out: rank_out.into(), + }; + + let mut ksk_compressed: GGLWECompressed> = GGLWECompressed::alloc_from_infos(&gglwe_infos); + + let mut source_xs: Source = Source::new([0u8; 32]); + let mut source_xe: Source = Source::new([0u8; 32]); + + let mut scratch: ScratchOwned = + ScratchOwned::alloc(GGLWECompressed::encrypt_sk_tmp_bytes(module, &gglwe_infos)); + + let mut sk_in: GLWESecret> = GLWESecret::alloc(n.into(), rank_in.into()); + sk_in.fill_ternary_prob(0.5, &mut source_xs); + + let mut sk_out: GLWESecret> = GLWESecret::alloc(n.into(), rank_out.into()); + sk_out.fill_ternary_prob(0.5, &mut source_xs); + let mut sk_out_prepared: GLWESecretPrepared, BE> = GLWESecretPrepared::alloc(module, rank_out.into()); + sk_out_prepared.prepare(module, &sk_out); + + let seed_xa = [1u8; 32]; + + ksk_compressed.encrypt_sk( + module, + &sk_in.data, + &sk_out_prepared, + seed_xa, + &mut source_xe, + scratch.borrow(), + ); + + let mut ksk: GGLWE> = GGLWE::alloc_from_infos(&gglwe_infos); + ksk.decompress(module, &ksk_compressed); + + let max_noise: f64 = SIGMA.log2() - (ksk.k().as_usize() as f64) + 0.5; + + for row in 0..ksk.dnum().as_usize() { + for col in 0..ksk.rank_in().as_usize() { + let noise_have = ksk + .noise( + module, + row, + col, + &sk_in.data, + &sk_out_prepared, + scratch.borrow(), + ) + .std() + .log2(); + + assert!( + noise_have < max_noise + 0.5, + "row:{row} col:{col} noise_have:{noise_have} > max_noise:{}", + max_noise + 0.5 + ); + } + } + } + } + } +} diff --git a/poulpy-core/src/tests/test_suite/encryption/gglwe_to_ggsw_key.rs b/poulpy-core/src/tests/test_suite/encryption/gglwe_to_ggsw_key.rs index 818f073..c508bf4 100644 --- a/poulpy-core/src/tests/test_suite/encryption/gglwe_to_ggsw_key.rs +++ b/poulpy-core/src/tests/test_suite/encryption/gglwe_to_ggsw_key.rs @@ -10,8 +10,8 @@ use crate::{ encryption::SIGMA, layouts::{ Dsize, GGLWE, GGLWEDecompress, GGLWEInfos, GGLWEToGGSWKey, GGLWEToGGSWKeyCompressed, GGLWEToGGSWKeyDecompress, - GGLWEToGGSWKeyLayout, GLWESecret, GLWESecretPreparedFactory, GLWESecretTensor, GLWESecretTensorFactory, - LWEInfos, prepared::GLWESecretPrepared, + GGLWEToGGSWKeyLayout, GLWESecret, GLWESecretPreparedFactory, GLWESecretTensor, GLWESecretTensorFactory, LWEInfos, + prepared::GLWESecretPrepared, }, }; diff --git a/poulpy-core/src/tests/test_suite/encryption/glwe_tsk.rs b/poulpy-core/src/tests/test_suite/encryption/glwe_tsk.rs index 41330ab..db893c5 100644 --- a/poulpy-core/src/tests/test_suite/encryption/glwe_tsk.rs +++ b/poulpy-core/src/tests/test_suite/encryption/glwe_tsk.rs @@ -9,7 +9,7 @@ use crate::{ decryption::GLWEDecrypt, encryption::SIGMA, layouts::{ - Dsize, GGLWEDecompress, GGLWEInfos, GLWEInfos, GLWESecret, GLWESecretPreparedFactory, GLWESecretTensor, + Dsize, GGLWEDecompress, GGLWEInfos, GLWESecret, GLWESecretPreparedFactory, GLWESecretTensor, GLWESecretTensorFactory, GLWETensorKey, GLWETensorKeyCompressed, GLWETensorKeyLayout, LWEInfos, prepared::GLWESecretPrepared, }, @@ -71,7 +71,7 @@ where let max_noise: f64 = SIGMA.log2() - (tensor_key.k().as_usize() as f64) + 0.5; for row in 0..tensor_key.dnum().as_usize() { - for col in 0..tensor_key.rank().as_usize() + 1 { + for col in 0..tensor_key.rank_in().as_usize() { assert!( tensor_key .0 @@ -148,7 +148,7 @@ where let max_noise: f64 = SIGMA.log2() - (tensor_key.k().as_usize() as f64) + 0.5; for row in 0..tensor_key.dnum().as_usize() { - for col in 0..tensor_key.rank().as_usize() + 1 { + for col in 0..tensor_key.rank_in().as_usize() { assert!( tensor_key .0 diff --git a/poulpy-core/src/tests/test_suite/external_product/gglwe_ksk.rs b/poulpy-core/src/tests/test_suite/external_product/gglwe_ksk.rs index e4482b4..7161546 100644 --- a/poulpy-core/src/tests/test_suite/external_product/gglwe_ksk.rs +++ b/poulpy-core/src/tests/test_suite/external_product/gglwe_ksk.rs @@ -8,7 +8,7 @@ use crate::{ GGLWEExternalProduct, GGLWENoise, GGSWEncryptSk, GLWESwitchingKeyEncryptSk, ScratchTakeCore, encryption::SIGMA, layouts::{ - GGLWEInfos, GGSW, GGSWLayout, GGSWPreparedFactory, GLWEInfos, GLWESecret, GLWESecretPreparedFactory, GLWESwitchingKey, + GGLWEInfos, GGSW, GGSWLayout, GGSWPreparedFactory, GLWESecret, GLWESecretPreparedFactory, GLWESwitchingKey, GLWESwitchingKeyLayout, prepared::{GGSWPrepared, GLWESecretPrepared}, }, diff --git a/poulpy-schemes/src/tfhe/bdd_arithmetic/bdd_2w_to_1w.rs b/poulpy-schemes/src/tfhe/bdd_arithmetic/bdd_2w_to_1w.rs index 59a745c..45b2fb3 100644 --- a/poulpy-schemes/src/tfhe/bdd_arithmetic/bdd_2w_to_1w.rs +++ b/poulpy-schemes/src/tfhe/bdd_arithmetic/bdd_2w_to_1w.rs @@ -98,27 +98,6 @@ impl<'a, T: UnsignedInteger, BE: Backend> BitSize for FheUintHelper<'a, T, BE> { } } -pub struct JoinedBits { - pub lo: A, - pub hi: B, - pub split: usize, // 32 in your example -} - -impl GetGGSWBit for JoinedBits -where - BE: Backend, - A: GetGGSWBit, - B: GetGGSWBit, -{ - fn get_bit(&self, bit: usize) -> GGSWPrepared<&[u8], BE> { - if bit < self.split { - self.lo.get_bit(bit) - } else { - self.hi.get_bit(bit - self.split) - } - } -} - #[macro_export] macro_rules! define_bdd_2w_to_1w_trait { ($(#[$meta:meta])* $vis:vis $trait_name:ident, $method_name:ident) => {