arnaucube
arnaucube/poulpyPublic Self-hosted repository
glwe + ggsw keyswitch
Pro7ech jeanphilippe.bossuat@gmail.com
Mon, 20 Oct 2025 11:07:29 +0200
commit

0c894c19db60841eebfa74f103c3b82d106fe0dc

parent

8dc4946736bd2936a3b0e96d26f083d6d542fac9

M poulpy-core/src/keyswitching/gglwe_ct.rs → poulpy-core/src/keyswitching/gglwe_ct.rs

@@ -11,7 +11,7 @@ },

}; impl AutomorphismKey<Vec<u8>> { - pub fn keyswitch_inplace_tmp_bytes<R, A, K, M, BE: Backend>(module: &M, res_infos: &R, a_infos: &A, key_infos: &K) -> usize + pub fn keyswitch_tmp_bytes<R, A, K, M, BE: Backend>(module: &M, res_infos: &R, a_infos: &A, key_infos: &K) -> usize where R: GGLWEInfos, A: GGLWEInfos,

@@ -44,7 +44,7 @@ }

} impl GLWESwitchingKey<Vec<u8>> { - pub fn keyswitch_inplace_tmp_bytes<R, A, K, M, BE: Backend>(module: &M, res_infos: &R, a_infos: &A, key_infos: &K) -> usize + pub fn keyswitch_tmp_bytes<R, A, K, M, BE: Backend>(module: &M, res_infos: &R, a_infos: &A, key_infos: &K) -> usize where R: GGLWEInfos, A: GGLWEInfos,

@@ -77,7 +77,7 @@ }

} impl GGLWE<Vec<u8>> { - pub fn keyswitch_inplace_tmp_bytes<R, A, K, M, BE: Backend>(module: &M, res_infos: &R, a_infos: &A, key_infos: &K) -> usize + pub fn keyswitch_tmp_bytes<R, A, K, M, BE: Backend>(module: &M, res_infos: &R, a_infos: &A, key_infos: &K) -> usize where R: GGLWEInfos, A: GGLWEInfos,
M poulpy-core/src/keyswitching/ggsw_ct.rs → poulpy-core/src/keyswitching/ggsw_ct.rs

@@ -1,4 +1,4 @@

-use poulpy_hal::layouts::{Backend, DataMut, Scratch, VecZnx}; +use poulpy_hal::layouts::{Backend, DataMut, Module, Scratch, VecZnx}; use crate::{ GGSWExpandRows, ScratchTakeCore,

@@ -50,6 +50,8 @@ {

module.ggsw_keyswitch_inplace(self, key, tsk, scratch); } } + +impl<BE: Backend> GGSWKeyswitch<BE> for Module<BE> where Self: GLWEKeyswitch<BE> + GGSWExpandRows<BE> {} pub trait GGSWKeyswitch<BE: Backend> where
M poulpy-core/src/keyswitching/mod.rs → poulpy-core/src/keyswitching/mod.rs

@@ -4,6 +4,6 @@ mod glwe_ct;

mod lwe_ct; pub use gglwe_ct::*; -// pub use gglwe_ct::*; +pub use ggsw_ct::*; pub use glwe_ct::*; pub use lwe_ct::*;
M poulpy-core/src/tests/test_suite/keyswitch/gglwe_ct.rs → poulpy-core/src/tests/test_suite/keyswitch/gglwe_ct.rs

@@ -1,68 +1,31 @@

use poulpy_hal::{ - api::{ - ScratchOwnedAlloc, ScratchOwnedBorrow, SvpApplyDftToDftInplace, SvpPPolAlloc, SvpPPolBytesOf, SvpPrepare, - VecZnxAddInplace, VecZnxAddNormal, VecZnxAddScalarInplace, VecZnxBigAddInplace, VecZnxBigAddSmallInplace, - VecZnxBigBytesOf, VecZnxBigNormalize, VecZnxBigNormalizeTmpBytes, VecZnxDftApply, VecZnxDftBytesOf, VecZnxFillUniform, - VecZnxIdftApplyConsume, VecZnxNormalize, VecZnxNormalizeInplace, VecZnxNormalizeTmpBytes, VecZnxSub, VecZnxSubInplace, - VecZnxSubScalarInplace, VecZnxSwitchRing, VmpApplyDftToDft, VmpApplyDftToDftAdd, VmpApplyDftToDftTmpBytes, VmpPMatAlloc, - VmpPrepare, - }, - layouts::{Backend, Module, ScratchOwned}, - oep::{ - ScratchAvailableImpl, ScratchOwnedAllocImpl, ScratchOwnedBorrowImpl, TakeScalarZnxImpl, TakeSvpPPolImpl, - TakeVecZnxBigImpl, TakeVecZnxDftImpl, TakeVecZnxImpl, - }, + api::{ScratchAvailable, ScratchOwnedAlloc, ScratchOwnedBorrow}, + layouts::{Backend, Module, Scratch, ScratchOwned}, source::Source, }; use crate::{ + GGLWEKeyswitch, GGLWENoise, GLWESwitchingKeyEncryptSk, ScratchTakeCore, encryption::SIGMA, layouts::{ - GLWESecret, GLWESwitchingKey, GLWESwitchingKeyLayout, - prepared::{GLWESecretPrepared, GLWESwitchingKeyPrepared, PrepareAlloc}, + GLWESecret, GLWESecretPrepare, GLWESecretPreparedAlloc, GLWESwitchingKey, GLWESwitchingKeyLayout, + GLWESwitchingKeyPrepare, GLWESwitchingKeyPreparedAlloc, + prepared::{GLWESecretPrepared, GLWESwitchingKeyPrepared}, }, noise::log2_std_noise_gglwe_product, }; -pub fn test_gglwe_switching_key_keyswitch<B>(module: &Module<B>) +pub fn test_gglwe_switching_key_keyswitch<BE: Backend>(module: &Module<BE>) where - Module<B>: VecZnxDftBytesOf - + VecZnxBigNormalize<B> - + VecZnxDftApply<B> - + SvpApplyDftToDftInplace<B> - + VecZnxIdftApplyConsume<B> - + VecZnxFillUniform - + VecZnxSubInplace - + VecZnxAddInplace - + VecZnxNormalizeInplace<B> - + VecZnxAddNormal - + VecZnxNormalize<B> - + VecZnxSub - + SvpPrepare<B> - + SvpPPolBytesOf - + SvpPPolAlloc<B> - + VecZnxBigBytesOf - + VecZnxBigAddInplace<B> - + VecZnxBigAddSmallInplace<B> - + VecZnxNormalizeTmpBytes - + VecZnxAddScalarInplace - + VmpPMatAlloc<B> - + VmpPrepare<B> - + VmpApplyDftToDftTmpBytes - + VmpApplyDftToDft<B> - + VmpApplyDftToDftAdd<B> - + VecZnxBigNormalizeTmpBytes - + VecZnxSwitchRing - + VecZnxSubScalarInplace, - B: Backend - + TakeVecZnxDftImpl<B> - + TakeVecZnxBigImpl<B> - + TakeSvpPPolImpl<B> - + ScratchOwnedAllocImpl<B> - + ScratchOwnedBorrowImpl<B> - + ScratchAvailableImpl<B> - + TakeScalarZnxImpl<B> - + TakeVecZnxImpl<B>, + Module<BE>: GLWESwitchingKeyEncryptSk<BE> + + GGLWEKeyswitch<BE> + + GLWESecretPrepare<BE> + + GLWESwitchingKeyPreparedAlloc<BE> + + GLWESecretPreparedAlloc<BE> + + GLWESwitchingKeyPrepare<BE> + + GGLWENoise<BE>, + ScratchOwned<BE>: ScratchOwnedAlloc<BE> + ScratchOwnedBorrow<BE>, + Scratch<BE>: ScratchAvailable + ScratchTakeCore<BE>, { let base2k: usize = 12; let k_in: usize = 60;

@@ -118,12 +81,12 @@ let mut source_xs: Source = Source::new([0u8; 32]);

let mut source_xe: Source = Source::new([0u8; 32]); let mut source_xa: Source = Source::new([0u8; 32]); - let mut scratch_enc: ScratchOwned<B> = ScratchOwned::alloc( + let mut scratch_enc: ScratchOwned<BE> = ScratchOwned::alloc( GLWESwitchingKey::encrypt_sk_tmp_bytes(module, &gglwe_s0s1_infos) | GLWESwitchingKey::encrypt_sk_tmp_bytes(module, &gglwe_s1s2_infos) | GLWESwitchingKey::encrypt_sk_tmp_bytes(module, &gglwe_s0s2_infos), ); - let mut scratch_apply: ScratchOwned<B> = ScratchOwned::alloc(GLWESwitchingKey::keyswitch_tmp_bytes( + let mut scratch_apply: ScratchOwned<BE> = ScratchOwned::alloc(GLWESwitchingKey::keyswitch_tmp_bytes( module, &gglwe_s0s1_infos, &gglwe_s0s2_infos,

@@ -138,7 +101,10 @@ sk1.fill_ternary_prob(0.5, &mut source_xs);

let mut sk2: GLWESecret<Vec<u8>> = GLWESecret::alloc(n.into(), rank_out_s1s2.into()); sk2.fill_ternary_prob(0.5, &mut source_xs); - let sk2_prepared: GLWESecretPrepared<Vec<u8>, B> = sk2.prepare_alloc(module, scratch_apply.borrow()); + + let mut sk2_prepared: GLWESecretPrepared<Vec<u8>, BE> = + GLWESecretPrepared::alloc(module, rank_out_s1s2.into()); + sk2_prepared.prepare(module, &sk2); // gglwe_{s1}(s0) = s0 -> s1 gglwe_s0s1.encrypt_sk(

@@ -160,8 +126,9 @@ &mut source_xe,

scratch_enc.borrow(), ); - let gglwe_s1s2_prepared: GLWESwitchingKeyPrepared<Vec<u8>, B> = - gglwe_s1s2.prepare_alloc(module, scratch_apply.borrow()); + let mut gglwe_s1s2_prepared: GLWESwitchingKeyPrepared<Vec<u8>, BE> = + GLWESwitchingKeyPrepared::alloc_from_infos(module, &gglwe_s1s2); + gglwe_s1s2_prepared.prepare(module, &gglwe_s1s2, scratch_apply.borrow()); // gglwe_{s1}(s0) (x) gglwe_{s2}(s1) = gglwe_{s2}(s0) gglwe_s0s2.keyswitch(

@@ -194,45 +161,17 @@ }

} #[allow(clippy::too_many_arguments)] -pub fn test_gglwe_switching_key_keyswitch_inplace<B>(module: &Module<B>) +pub fn test_gglwe_switching_key_keyswitch_inplace<BE: Backend>(module: &Module<BE>) where - Module<B>: VecZnxDftBytesOf - + VecZnxBigNormalize<B> - + VecZnxDftApply<B> - + SvpApplyDftToDftInplace<B> - + VecZnxIdftApplyConsume<B> - + VecZnxFillUniform - + VecZnxSubInplace - + VecZnxAddInplace - + VecZnxNormalizeInplace<B> - + VecZnxAddNormal - + VecZnxNormalize<B> - + VecZnxSub - + SvpPrepare<B> - + SvpPPolBytesOf - + SvpPPolAlloc<B> - + VecZnxBigBytesOf - + VecZnxBigAddInplace<B> - + VecZnxBigAddSmallInplace<B> - + VecZnxNormalizeTmpBytes - + VecZnxAddScalarInplace - + VmpPMatAlloc<B> - + VmpPrepare<B> - + VmpApplyDftToDftTmpBytes - + VmpApplyDftToDft<B> - + VmpApplyDftToDftAdd<B> - + VecZnxBigNormalizeTmpBytes - + VecZnxSwitchRing - + VecZnxSubScalarInplace, - B: Backend - + TakeVecZnxDftImpl<B> - + TakeVecZnxBigImpl<B> - + TakeSvpPPolImpl<B> - + ScratchOwnedAllocImpl<B> - + ScratchOwnedBorrowImpl<B> - + ScratchAvailableImpl<B> - + TakeScalarZnxImpl<B> - + TakeVecZnxImpl<B>, + Module<BE>: GLWESwitchingKeyEncryptSk<BE> + + GGLWEKeyswitch<BE> + + GLWESecretPrepare<BE> + + GLWESecretPreparedAlloc<BE> + + GLWESwitchingKeyPrepare<BE> + + GGLWENoise<BE> + + GLWESwitchingKeyPreparedAlloc<BE>, + ScratchOwned<BE>: ScratchOwnedAlloc<BE> + ScratchOwnedBorrow<BE>, + Scratch<BE>: ScratchAvailable + ScratchTakeCore<BE>, { let base2k: usize = 12; let k_out: usize = 60;

@@ -273,12 +212,13 @@ let mut source_xs: Source = Source::new([0u8; 32]);

let mut source_xe: Source = Source::new([0u8; 32]); let mut source_xa: Source = Source::new([0u8; 32]); - let mut scratch_enc: ScratchOwned<B> = ScratchOwned::alloc( + let mut scratch_enc: ScratchOwned<BE> = ScratchOwned::alloc( GLWESwitchingKey::encrypt_sk_tmp_bytes(module, &gglwe_s0s1_infos) | GLWESwitchingKey::encrypt_sk_tmp_bytes(module, &gglwe_s1s2_infos), ); - let mut scratch_apply: ScratchOwned<B> = ScratchOwned::alloc(GLWESwitchingKey::keyswitch_inplace_tmp_bytes( + let mut scratch_apply: ScratchOwned<BE> = ScratchOwned::alloc(GLWESwitchingKey::keyswitch_tmp_bytes( module, + &gglwe_s0s1_infos, &gglwe_s0s1_infos, &gglwe_s1s2_infos, ));

@@ -293,7 +233,9 @@ sk1.fill_ternary_prob(var_xs, &mut source_xs);

let mut sk2: GLWESecret<Vec<u8>> = GLWESecret::alloc(n.into(), rank_out.into()); sk2.fill_ternary_prob(var_xs, &mut source_xs); - let sk2_prepared: GLWESecretPrepared<Vec<u8>, B> = sk2.prepare_alloc(module, scratch_apply.borrow()); + + let mut sk2_prepared: GLWESecretPrepared<Vec<u8>, BE> = GLWESecretPrepared::alloc(module, rank_out.into()); + sk2_prepared.prepare(module, &sk2); // gglwe_{s1}(s0) = s0 -> s1 gglwe_s0s1.encrypt_sk(

@@ -315,8 +257,9 @@ &mut source_xe,

scratch_enc.borrow(), ); - let gglwe_s1s2_prepared: GLWESwitchingKeyPrepared<Vec<u8>, B> = - gglwe_s1s2.prepare_alloc(module, scratch_apply.borrow()); + let mut gglwe_s1s2_prepared: GLWESwitchingKeyPrepared<Vec<u8>, BE> = + GLWESwitchingKeyPrepared::alloc_from_infos(module, &gglwe_s1s2); + gglwe_s1s2_prepared.prepare(module, &gglwe_s1s2, scratch_apply.borrow()); // gglwe_{s1}(s0) (x) gglwe_{s2}(s1) = gglwe_{s2}(s0) gglwe_s0s1.keyswitch_inplace(module, &gglwe_s1s2_prepared, scratch_apply.borrow());
M poulpy-core/src/tests/test_suite/keyswitch/ggsw_ct.rs → poulpy-core/src/tests/test_suite/keyswitch/ggsw_ct.rs

@@ -1,74 +1,34 @@

use poulpy_hal::{ - api::{ - ScratchOwnedAlloc, ScratchOwnedBorrow, SvpApplyDftToDft, SvpApplyDftToDftInplace, SvpPPolAlloc, SvpPPolBytesOf, - SvpPrepare, VecZnxAddInplace, VecZnxAddNormal, VecZnxAddScalarInplace, VecZnxBigAddInplace, VecZnxBigAddSmallInplace, - VecZnxBigAlloc, VecZnxBigBytesOf, VecZnxBigNormalize, VecZnxBigNormalizeTmpBytes, VecZnxDftAddInplace, VecZnxDftAlloc, - VecZnxDftApply, VecZnxDftBytesOf, VecZnxDftCopy, VecZnxFillUniform, VecZnxIdftApplyConsume, VecZnxIdftApplyTmpA, - VecZnxNormalize, VecZnxNormalizeInplace, VecZnxNormalizeTmpBytes, VecZnxSub, VecZnxSubInplace, VecZnxSwitchRing, - VmpApplyDftToDft, VmpApplyDftToDftAdd, VmpApplyDftToDftTmpBytes, VmpPMatAlloc, VmpPrepare, - }, - layouts::{Backend, Module, ScalarZnx, ScratchOwned}, - oep::{ - ScratchAvailableImpl, ScratchOwnedAllocImpl, ScratchOwnedBorrowImpl, TakeScalarZnxImpl, TakeSvpPPolImpl, - TakeVecZnxBigImpl, TakeVecZnxDftImpl, TakeVecZnxImpl, - }, + api::{ScratchAvailable, ScratchOwnedAlloc, ScratchOwnedBorrow}, + layouts::{Backend, Module, ScalarZnx, Scratch, ScratchOwned}, source::Source, }; use crate::{ + GGSWEncryptSk, GGSWKeyswitch, GGSWNoise, GLWESwitchingKeyEncryptSk, ScratchTakeCore, TensorKeyEncryptSk, encryption::SIGMA, layouts::{ - GGSW, GGSWCiphertextLayout, GLWESecret, GLWESwitchingKey, GLWESwitchingKeyLayout, TensorKey, TensorKeyLayout, - prepared::{GLWESecretPrepared, GLWESwitchingKeyPrepared, PrepareAlloc, TensorKeyPrepared}, + GGSW, GGSWLayout, GLWESecret, GLWESecretPrepare, GLWESecretPreparedAlloc, GLWESwitchingKey, GLWESwitchingKeyLayout, + GLWESwitchingKeyPreparedAlloc, TensorKey, TensorKeyLayout, TensorKeyPreparedAlloc, + prepared::{GLWESecretPrepared, GLWESwitchingKeyPrepared, TensorKeyPrepared}, }, noise::noise_ggsw_keyswitch, }; #[allow(clippy::too_many_arguments)] -pub fn test_ggsw_keyswitch<B>(module: &Module<B>) +pub fn test_ggsw_keyswitch<BE: Backend>(module: &Module<BE>) where - Module<B>: VecZnxDftBytesOf - + VecZnxBigNormalize<B> - + VecZnxDftApply<B> - + SvpApplyDftToDftInplace<B> - + VecZnxIdftApplyConsume<B> - + VecZnxFillUniform - + VecZnxSubInplace - + VecZnxAddInplace - + VecZnxNormalizeInplace<B> - + VecZnxAddNormal - + VecZnxNormalize<B> - + VecZnxSub - + SvpPrepare<B> - + SvpPPolBytesOf - + SvpPPolAlloc<B> - + VecZnxBigBytesOf - + VecZnxBigAddInplace<B> - + VecZnxBigAddSmallInplace<B> - + VecZnxNormalizeTmpBytes - + VecZnxAddScalarInplace - + VmpPMatAlloc<B> - + VmpPrepare<B> - + VmpApplyDftToDftTmpBytes - + VmpApplyDftToDft<B> - + VmpApplyDftToDftAdd<B> - + VecZnxBigNormalizeTmpBytes - + VecZnxSwitchRing - + SvpApplyDftToDft<B> - + VecZnxIdftApplyTmpA<B> - + VecZnxDftCopy<B> - + VecZnxDftAddInplace<B> - + VecZnxBigAlloc<B> - + VecZnxDftAlloc<B>, - B: Backend - + TakeVecZnxDftImpl<B> - + TakeVecZnxBigImpl<B> - + TakeSvpPPolImpl<B> - + ScratchOwnedAllocImpl<B> - + ScratchOwnedBorrowImpl<B> - + ScratchAvailableImpl<B> - + TakeScalarZnxImpl<B> - + TakeVecZnxImpl<B>, + Module<BE>: GGSWEncryptSk<BE> + + GLWESwitchingKeyEncryptSk<BE> + + TensorKeyEncryptSk<BE> + + GGSWKeyswitch<BE> + + GLWESecretPreparedAlloc<BE> + + GLWESecretPrepare<BE> + + TensorKeyPreparedAlloc<BE> + + GLWESwitchingKeyPreparedAlloc<BE> + + GGSWNoise<BE>, + ScratchOwned<BE>: ScratchOwnedAlloc<BE> + ScratchOwnedBorrow<BE>, + Scratch<BE>: ScratchAvailable + ScratchTakeCore<BE>, { let base2k: usize = 12; let k_in: usize = 54;

@@ -84,7 +44,7 @@ let dnum: usize = k_in.div_ceil(di * base2k);

let dsize_in: usize = 1; - let ggsw_in_infos: GGSWCiphertextLayout = GGSWCiphertextLayout { + let ggsw_in_infos: GGSWLayout = GGSWLayout { n: n.into(), base2k: base2k.into(), k: k_in.into(),

@@ -93,7 +53,7 @@ dsize: dsize_in.into(),

rank: rank.into(), }; - let ggsw_out_infos: GGSWCiphertextLayout = GGSWCiphertextLayout { + let ggsw_out_infos: GGSWLayout = GGSWLayout { n: n.into(), base2k: base2k.into(), k: k_out.into(),

@@ -131,7 +91,7 @@ let mut source_xs: Source = Source::new([0u8; 32]);

let mut source_xe: Source = Source::new([0u8; 32]); let mut source_xa: Source = Source::new([0u8; 32]); - let mut scratch: ScratchOwned<B> = ScratchOwned::alloc( + let mut scratch: ScratchOwned<BE> = ScratchOwned::alloc( GGSW::encrypt_sk_tmp_bytes(module, &ggsw_in_infos) | GLWESwitchingKey::encrypt_sk_tmp_bytes(module, &ksk_apply_infos) | TensorKey::encrypt_sk_tmp_bytes(module, &tsk_infos)

@@ -148,11 +108,15 @@ let var_xs: f64 = 0.5;

let mut sk_in: GLWESecret<Vec<u8>> = GLWESecret::alloc(n.into(), rank.into()); sk_in.fill_ternary_prob(var_xs, &mut source_xs); - let sk_in_dft: GLWESecretPrepared<Vec<u8>, B> = sk_in.prepare_alloc(module, scratch.borrow()); + + let mut sk_in_prepared: GLWESecretPrepared<Vec<u8>, BE> = GLWESecretPrepared::alloc(module, rank.into()); + sk_in_prepared.prepare(module, &sk_in); let mut sk_out: GLWESecret<Vec<u8>> = GLWESecret::alloc(n.into(), rank.into()); sk_out.fill_ternary_prob(var_xs, &mut source_xs); - let sk_out_prepared: GLWESecretPrepared<Vec<u8>, B> = sk_out.prepare_alloc(module, scratch.borrow()); + + let mut sk_out_prepared: GLWESecretPrepared<Vec<u8>, BE> = GLWESecretPrepared::alloc(module, rank.into()); + sk_out_prepared.prepare(module, &sk_out); ksk.encrypt_sk( module,

@@ -175,14 +139,14 @@

ggsw_in.encrypt_sk( module, &pt_scalar, - &sk_in_dft, + &sk_in_prepared, &mut source_xa, &mut source_xe, scratch.borrow(), ); - let ksk_prepared: GLWESwitchingKeyPrepared<Vec<u8>, B> = ksk.prepare_alloc(module, scratch.borrow()); - let tsk_prepared: TensorKeyPrepared<Vec<u8>, B> = tsk.prepare_alloc(module, scratch.borrow()); + let ksk_prepared: GLWESwitchingKeyPrepared<Vec<u8>, BE> = GLWESwitchingKeyPrepared::alloc_from_infos(module, &ksk); + let tsk_prepared: TensorKeyPrepared<Vec<u8>, BE> = TensorKeyPrepared::alloc_from_infos(module, &tsk); ggsw_out.keyswitch( module,

@@ -214,50 +178,19 @@ }

} #[allow(clippy::too_many_arguments)] -pub fn test_ggsw_keyswitch_inplace<B>(module: &Module<B>) +pub fn test_ggsw_keyswitch_inplace<BE: Backend>(module: &Module<BE>) where - Module<B>: VecZnxDftBytesOf - + VecZnxBigNormalize<B> - + VecZnxDftApply<B> - + SvpApplyDftToDftInplace<B> - + VecZnxIdftApplyConsume<B> - + VecZnxFillUniform - + VecZnxSubInplace - + VecZnxAddInplace - + VecZnxNormalizeInplace<B> - + VecZnxAddNormal - + VecZnxNormalize<B> - + VecZnxSub - + SvpPrepare<B> - + SvpPPolBytesOf - + SvpPPolAlloc<B> - + VecZnxBigBytesOf - + VecZnxBigAddInplace<B> - + VecZnxBigAddSmallInplace<B> - + VecZnxNormalizeTmpBytes - + VecZnxAddScalarInplace - + VmpPMatAlloc<B> - + VmpPrepare<B> - + VmpApplyDftToDftTmpBytes - + VmpApplyDftToDft<B> - + VmpApplyDftToDftAdd<B> - + VecZnxBigNormalizeTmpBytes - + VecZnxSwitchRing - + SvpApplyDftToDft<B> - + VecZnxIdftApplyTmpA<B> - + VecZnxDftCopy<B> - + VecZnxDftAddInplace<B> - + VecZnxBigAlloc<B> - + VecZnxDftAlloc<B>, - B: Backend - + TakeVecZnxDftImpl<B> - + TakeVecZnxBigImpl<B> - + TakeSvpPPolImpl<B> - + ScratchOwnedAllocImpl<B> - + ScratchOwnedBorrowImpl<B> - + ScratchAvailableImpl<B> - + TakeScalarZnxImpl<B> - + TakeVecZnxImpl<B>, + Module<BE>: GGSWEncryptSk<BE> + + GLWESwitchingKeyEncryptSk<BE> + + TensorKeyEncryptSk<BE> + + GGSWKeyswitch<BE> + + GLWESecretPreparedAlloc<BE> + + GLWESecretPrepare<BE> + + TensorKeyPreparedAlloc<BE> + + GLWESwitchingKeyPreparedAlloc<BE> + + GGSWNoise<BE>, + ScratchOwned<BE>: ScratchOwnedAlloc<BE> + ScratchOwnedBorrow<BE>, + Scratch<BE>: ScratchAvailable + ScratchTakeCore<BE>, { let base2k: usize = 12; let k_out: usize = 54;

@@ -272,7 +205,7 @@ let dnum: usize = k_out.div_ceil(di * base2k);

let dsize_in: usize = 1; - let ggsw_out_infos: GGSWCiphertextLayout = GGSWCiphertextLayout { + let ggsw_out_infos: GGSWLayout = GGSWLayout { n: n.into(), base2k: base2k.into(), k: k_out.into(),

@@ -309,22 +242,31 @@ let mut source_xs: Source = Source::new([0u8; 32]);

let mut source_xe: Source = Source::new([0u8; 32]); let mut source_xa: Source = Source::new([0u8; 32]); - let mut scratch: ScratchOwned<B> = ScratchOwned::alloc( + let mut scratch: ScratchOwned<BE> = ScratchOwned::alloc( GGSW::encrypt_sk_tmp_bytes(module, &ggsw_out_infos) | GLWESwitchingKey::encrypt_sk_tmp_bytes(module, &ksk_apply_infos) | TensorKey::encrypt_sk_tmp_bytes(module, &tsk_infos) - | GGSW::keyswitch_inplace_tmp_bytes(module, &ggsw_out_infos, &ksk_apply_infos, &tsk_infos), + | GGSW::keyswitch_tmp_bytes( + module, + &ggsw_out_infos, + &ggsw_out_infos, + &ksk_apply_infos, + &tsk_infos, + ), ); let var_xs: f64 = 0.5; let mut sk_in: GLWESecret<Vec<u8>> = GLWESecret::alloc(n.into(), rank.into()); sk_in.fill_ternary_prob(var_xs, &mut source_xs); - let sk_in_dft: GLWESecretPrepared<Vec<u8>, B> = sk_in.prepare_alloc(module, scratch.borrow()); + let mut sk_in_prepared: GLWESecretPrepared<Vec<u8>, BE> = GLWESecretPrepared::alloc(module, rank.into()); + sk_in_prepared.prepare(module, &sk_in); let mut sk_out: GLWESecret<Vec<u8>> = GLWESecret::alloc(n.into(), rank.into()); sk_out.fill_ternary_prob(var_xs, &mut source_xs); - let sk_out_prepared: GLWESecretPrepared<Vec<u8>, B> = sk_out.prepare_alloc(module, scratch.borrow()); + + let mut sk_out_prepared: GLWESecretPrepared<Vec<u8>, BE> = GLWESecretPrepared::alloc(module, rank.into()); + sk_out_prepared.prepare(module, &sk_out); ksk.encrypt_sk( module,

@@ -347,14 +289,14 @@

ggsw_out.encrypt_sk( module, &pt_scalar, - &sk_in_dft, + &sk_in_prepared, &mut source_xa, &mut source_xe, scratch.borrow(), ); - let ksk_prepared: GLWESwitchingKeyPrepared<Vec<u8>, B> = ksk.prepare_alloc(module, scratch.borrow()); - let tsk_prepared: TensorKeyPrepared<Vec<u8>, B> = tsk.prepare_alloc(module, scratch.borrow()); + let ksk_prepared: GLWESwitchingKeyPrepared<Vec<u8>, BE> = GLWESwitchingKeyPrepared::alloc_from_infos(module, &ksk); + let tsk_prepared: TensorKeyPrepared<Vec<u8>, BE> = TensorKeyPrepared::alloc_from_infos(module, &tsk); ggsw_out.keyswitch_inplace(module, &ksk_prepared, &tsk_prepared, scratch.borrow());
M poulpy-core/src/tests/test_suite/keyswitch/glwe_ct.rs → poulpy-core/src/tests/test_suite/keyswitch/glwe_ct.rs

@@ -1,67 +1,25 @@

use poulpy_hal::{ - api::{ - ScratchOwnedAlloc, ScratchOwnedBorrow, SvpApplyDftToDftInplace, SvpPPolAlloc, SvpPPolBytesOf, SvpPrepare, - VecZnxAddInplace, VecZnxAddNormal, VecZnxAddScalarInplace, VecZnxBigAddInplace, VecZnxBigAddSmallInplace, - VecZnxBigBytesOf, VecZnxBigNormalize, VecZnxBigNormalizeTmpBytes, VecZnxDftApply, VecZnxDftBytesOf, VecZnxFillUniform, - VecZnxIdftApplyConsume, VecZnxNormalize, VecZnxNormalizeInplace, VecZnxNormalizeTmpBytes, VecZnxSub, VecZnxSubInplace, - VecZnxSwitchRing, VmpApplyDftToDft, VmpApplyDftToDftAdd, VmpApplyDftToDftTmpBytes, VmpPMatAlloc, VmpPrepare, - }, - layouts::{Backend, Module, ScratchOwned}, - oep::{ - ScratchAvailableImpl, ScratchOwnedAllocImpl, ScratchOwnedBorrowImpl, TakeScalarZnxImpl, TakeSvpPPolImpl, - TakeVecZnxBigImpl, TakeVecZnxDftImpl, TakeVecZnxImpl, - }, + api::{ScratchAvailable, ScratchOwnedAlloc, ScratchOwnedBorrow}, + layouts::{Backend, Module, Scratch, ScratchOwned}, source::Source, }; use crate::{ + ScratchTakeCore, encryption::SIGMA, layouts::{ GLWE, GLWELayout, GLWEPlaintext, GLWESecret, GLWESwitchingKey, GLWESwitchingKeyLayout, - prepared::{GLWESecretPrepared, GLWESwitchingKeyPrepared, PrepareAlloc}, + prepared::{GLWESecretPrepared, GLWESwitchingKeyPrepared}, }, noise::log2_std_noise_gglwe_product, }; #[allow(clippy::too_many_arguments)] -pub fn test_glwe_keyswitch<B>(module: &Module<B>) +pub fn test_glwe_keyswitch<BE: Backend>(module: &Module<BE>) where - Module<B>: VecZnxDftBytesOf - + VecZnxBigNormalize<B> - + VecZnxDftApply<B> - + SvpApplyDftToDftInplace<B> - + VecZnxIdftApplyConsume<B> - + VecZnxFillUniform - + VecZnxSubInplace - + VecZnxAddInplace - + VecZnxNormalizeInplace<B> - + VecZnxAddNormal - + VecZnxNormalize<B> - + VecZnxSub - + SvpPrepare<B> - + SvpPPolBytesOf - + SvpPPolAlloc<B> - + VecZnxBigBytesOf - + VecZnxBigAddInplace<B> - + VecZnxBigAddSmallInplace<B> - + VecZnxNormalizeTmpBytes - + VecZnxAddScalarInplace - + VmpPMatAlloc<B> - + VmpPrepare<B> - + VmpApplyDftToDftTmpBytes - + VmpApplyDftToDft<B> - + VmpApplyDftToDftAdd<B> - + VecZnxBigNormalizeTmpBytes - + VecZnxSwitchRing, - B: Backend - + TakeVecZnxDftImpl<B> - + TakeVecZnxBigImpl<B> - + TakeSvpPPolImpl<B> - + ScratchOwnedAllocImpl<B> - + ScratchOwnedBorrowImpl<B> - + ScratchAvailableImpl<B> - + TakeScalarZnxImpl<B> - + TakeVecZnxImpl<B>, + Module<BE>:, + ScratchOwned<BE>: ScratchOwnedAlloc<BE> + ScratchOwnedBorrow<BE>, + Scratch<BE>: ScratchAvailable + ScratchTakeCore<BE>, { let base2k: usize = 12; let k_in: usize = 45;

@@ -111,7 +69,7 @@ let mut source_xa: Source = Source::new([0u8; 32]);

module.vec_znx_fill_uniform(base2k, &mut pt_want.data, 0, &mut source_xa); - let mut scratch: ScratchOwned<B> = ScratchOwned::alloc( + let mut scratch: ScratchOwned<BE> = ScratchOwned::alloc( GLWESwitchingKey::encrypt_sk_tmp_bytes(module, &key_apply) | GLWE::encrypt_sk_tmp_bytes(module, &glwe_in_infos) | GLWE::keyswitch_tmp_bytes(module, &glwe_out_infos, &glwe_in_infos, &key_apply),

@@ -119,11 +77,11 @@ );

let mut sk_in: GLWESecret<Vec<u8>> = GLWESecret::alloc(n.into(), rank_in.into()); sk_in.fill_ternary_prob(0.5, &mut source_xs); - let sk_in_prepared: GLWESecretPrepared<Vec<u8>, B> = sk_in.prepare_alloc(module, scratch.borrow()); + let sk_in_prepared: GLWESecretPrepared<Vec<u8>, BE> = sk_in.prepare_alloc(module, scratch.borrow()); let mut sk_out: GLWESecret<Vec<u8>> = GLWESecret::alloc(n.into(), rank_out.into()); sk_out.fill_ternary_prob(0.5, &mut source_xs); - let sk_out_prepared: GLWESecretPrepared<Vec<u8>, B> = sk_out.prepare_alloc(module, scratch.borrow()); + let sk_out_prepared: GLWESecretPrepared<Vec<u8>, BE> = sk_out.prepare_alloc(module, scratch.borrow()); ksk.encrypt_sk( module,

@@ -143,7 +101,7 @@ &mut source_xe,

scratch.borrow(), ); - let ksk_prepared: GLWESwitchingKeyPrepared<Vec<u8>, B> = ksk.prepare_alloc(module, scratch.borrow()); + let ksk_prepared: GLWESwitchingKeyPrepared<Vec<u8>, BE> = ksk.prepare_alloc(module, scratch.borrow()); glwe_out.keyswitch(module, &glwe_in, &ksk_prepared, scratch.borrow());

@@ -166,44 +124,11 @@ }

} } -pub fn test_glwe_keyswitch_inplace<B>(module: &Module<B>) +pub fn test_glwe_keyswitch_inplace<BE: Backend>(module: &Module<BE>) where - Module<B>: VecZnxDftBytesOf - + VecZnxBigNormalize<B> - + VecZnxDftApply<B> - + SvpApplyDftToDftInplace<B> - + VecZnxIdftApplyConsume<B> - + VecZnxFillUniform - + VecZnxSubInplace - + VecZnxAddInplace - + VecZnxNormalizeInplace<B> - + VecZnxAddNormal - + VecZnxNormalize<B> - + VecZnxSub - + SvpPrepare<B> - + SvpPPolBytesOf - + SvpPPolAlloc<B> - + VecZnxBigBytesOf - + VecZnxBigAddInplace<B> - + VecZnxBigAddSmallInplace<B> - + VecZnxNormalizeTmpBytes - + VecZnxAddScalarInplace - + VmpPMatAlloc<B> - + VmpPrepare<B> - + VmpApplyDftToDftTmpBytes - + VmpApplyDftToDft<B> - + VmpApplyDftToDftAdd<B> - + VecZnxBigNormalizeTmpBytes - + VecZnxSwitchRing, - B: Backend - + TakeVecZnxDftImpl<B> - + TakeVecZnxBigImpl<B> - + TakeSvpPPolImpl<B> - + ScratchOwnedAllocImpl<B> - + ScratchOwnedBorrowImpl<B> - + ScratchAvailableImpl<B> - + TakeScalarZnxImpl<B> - + TakeVecZnxImpl<B>, + Module<BE>:, + ScratchOwned<BE>: ScratchOwnedAlloc<BE> + ScratchOwnedBorrow<BE>, + Scratch<BE>: ScratchAvailable + ScratchTakeCore<BE>, { let base2k: usize = 12; let k_out: usize = 45;

@@ -243,7 +168,7 @@ let mut source_xa: Source = Source::new([0u8; 32]);

module.vec_znx_fill_uniform(base2k, &mut pt_want.data, 0, &mut source_xa); - let mut scratch: ScratchOwned<B> = ScratchOwned::alloc( + let mut scratch: ScratchOwned<BE> = ScratchOwned::alloc( GLWESwitchingKey::encrypt_sk_tmp_bytes(module, &key_apply_infos) | GLWE::encrypt_sk_tmp_bytes(module, &glwe_out_infos) | GLWE::keyswitch_inplace_tmp_bytes(module, &glwe_out_infos, &key_apply_infos),

@@ -251,11 +176,11 @@ );

let mut sk_in: GLWESecret<Vec<u8>> = GLWESecret::alloc(n.into(), rank.into()); sk_in.fill_ternary_prob(0.5, &mut source_xs); - let sk_in_prepared: GLWESecretPrepared<Vec<u8>, B> = sk_in.prepare_alloc(module, scratch.borrow()); + let sk_in_prepared: GLWESecretPrepared<Vec<u8>, BE> = sk_in.prepare_alloc(module, scratch.borrow()); let mut sk_out: GLWESecret<Vec<u8>> = GLWESecret::alloc(n.into(), rank.into()); sk_out.fill_ternary_prob(0.5, &mut source_xs); - let sk_out_prepared: GLWESecretPrepared<Vec<u8>, B> = sk_out.prepare_alloc(module, scratch.borrow()); + let sk_out_prepared: GLWESecretPrepared<Vec<u8>, BE> = sk_out.prepare_alloc(module, scratch.borrow()); key_apply.encrypt_sk( module,

@@ -275,7 +200,7 @@ &mut source_xe,

scratch.borrow(), ); - let ksk_prepared: GLWESwitchingKeyPrepared<Vec<u8>, B> = key_apply.prepare_alloc(module, scratch.borrow()); + let ksk_prepared: GLWESwitchingKeyPrepared<Vec<u8>, BE> = key_apply.prepare_alloc(module, scratch.borrow()); glwe_out.keyswitch_inplace(module, &ksk_prepared, scratch.borrow());
M poulpy-core/src/tests/test_suite/keyswitch/lwe_ct.rs → poulpy-core/src/tests/test_suite/keyswitch/lwe_ct.rs

@@ -1,68 +1,21 @@

use poulpy_hal::{ - api::{ - ScratchOwnedAlloc, ScratchOwnedBorrow, SvpApplyDftToDftInplace, SvpPPolAlloc, SvpPPolBytesOf, SvpPrepare, - VecZnxAddInplace, VecZnxAddNormal, VecZnxAddScalarInplace, VecZnxAutomorphismInplace, VecZnxBigAddInplace, - VecZnxBigAddSmallInplace, VecZnxBigBytesOf, VecZnxBigNormalize, VecZnxBigNormalizeTmpBytes, VecZnxCopy, VecZnxDftApply, - VecZnxDftBytesOf, VecZnxFillUniform, VecZnxIdftApplyConsume, VecZnxNormalize, VecZnxNormalizeInplace, - VecZnxNormalizeTmpBytes, VecZnxSub, VecZnxSubInplace, VecZnxSwitchRing, VmpApplyDftToDft, VmpApplyDftToDftAdd, - VmpApplyDftToDftTmpBytes, VmpPMatAlloc, VmpPrepare, ZnAddNormal, ZnFillUniform, ZnNormalizeInplace, - }, - layouts::{Backend, Module, ScratchOwned, ZnxView}, - oep::{ - ScratchAvailableImpl, ScratchOwnedAllocImpl, ScratchOwnedBorrowImpl, TakeScalarZnxImpl, TakeSvpPPolImpl, - TakeVecZnxBigImpl, TakeVecZnxDftImpl, TakeVecZnxImpl, - }, + api::{ScratchAvailable, ScratchOwnedAlloc, ScratchOwnedBorrow}, + layouts::{Backend, Module, Scratch, ScratchOwned, ZnxView}, source::Source, }; -use crate::layouts::{ - LWE, LWECiphertextLayout, LWEPlaintext, LWESecret, LWESwitchingKey, LWESwitchingKeyLayout, - prepared::{LWESwitchingKeyPrepared, PrepareAlloc}, +use crate::{ + ScratchTakeCore, + layouts::{ + LWE, LWELayout, LWEPlaintext, LWESecret, LWESwitchingKey, LWESwitchingKeyLayout, prepared::LWESwitchingKeyPrepared, + }, }; -pub fn test_lwe_keyswitch<B>(module: &Module<B>) +pub fn test_lwe_keyswitch<BE: Backend>(module: &Module<BE>) where - Module<B>: VecZnxDftBytesOf - + VecZnxBigNormalize<B> - + VecZnxDftApply<B> - + SvpApplyDftToDftInplace<B> - + VecZnxIdftApplyConsume<B> - + VecZnxFillUniform - + VecZnxSubInplace - + VecZnxAddInplace - + VecZnxNormalizeInplace<B> - + VecZnxAddNormal - + VecZnxNormalize<B> - + VecZnxSub - + SvpPrepare<B> - + SvpPPolBytesOf - + SvpPPolAlloc<B> - + VecZnxBigBytesOf - + VecZnxBigAddInplace<B> - + VecZnxBigAddSmallInplace<B> - + VecZnxNormalizeTmpBytes - + VecZnxAddScalarInplace - + VmpPMatAlloc<B> - + VmpPrepare<B> - + VmpApplyDftToDftTmpBytes - + VmpApplyDftToDft<B> - + VmpApplyDftToDftAdd<B> - + VecZnxBigNormalizeTmpBytes - + VecZnxSwitchRing - + VecZnxAutomorphismInplace<B> - + ZnNormalizeInplace<B> - + ZnFillUniform - + ZnAddNormal - + VecZnxCopy, - B: Backend - + TakeVecZnxDftImpl<B> - + TakeVecZnxBigImpl<B> - + TakeSvpPPolImpl<B> - + ScratchOwnedAllocImpl<B> - + ScratchOwnedBorrowImpl<B> - + ScratchAvailableImpl<B> - + TakeScalarZnxImpl<B> - + TakeVecZnxImpl<B>, + Module<BE>:, + ScratchOwned<BE>: ScratchOwnedAlloc<BE> + ScratchOwnedBorrow<BE>, + Scratch<BE>: ScratchAvailable + ScratchTakeCore<BE>, { let n: usize = module.n(); let base2k: usize = 17;

@@ -86,19 +39,19 @@ k: k_ksk.into(),

dnum: dnum.into(), }; - let lwe_in_infos: LWECiphertextLayout = LWECiphertextLayout { + let lwe_in_infos: LWELayout = LWELayout { n: n_lwe_in.into(), base2k: base2k.into(), k: k_lwe_ct.into(), }; - let lwe_out_infos: LWECiphertextLayout = LWECiphertextLayout { + let lwe_out_infos: LWELayout = LWELayout { n: n_lwe_out.into(), k: k_lwe_ct.into(), base2k: base2k.into(), }; - let mut scratch: ScratchOwned<B> = ScratchOwned::alloc( + let mut scratch: ScratchOwned<BE> = ScratchOwned::alloc( LWESwitchingKey::encrypt_sk_tmp_bytes(module, &key_apply_infos) | LWE::keyswitch_tmp_bytes(module, &lwe_out_infos, &lwe_in_infos, &key_apply_infos), );

@@ -136,7 +89,7 @@ );

let mut lwe_ct_out: LWE<Vec<u8>> = LWE::alloc_from_infos(&lwe_out_infos); - let ksk_prepared: LWESwitchingKeyPrepared<Vec<u8>, B> = ksk.prepare_alloc(module, scratch.borrow()); + let ksk_prepared: LWESwitchingKeyPrepared<Vec<u8>, BE> = ksk.prepare_alloc(module, scratch.borrow()); lwe_ct_out.keyswitch(module, &lwe_ct_in, &ksk_prepared, scratch.borrow());
M poulpy-core/src/tests/test_suite/mod.rs → poulpy-core/src/tests/test_suite/mod.rs

@@ -1,7 +1,7 @@

// pub mod automorphism; pub mod encryption; // pub mod external_product; -// pub mod keyswitch; +pub mod keyswitch; // mod conversion; // mod packing;