diff --git a/poulpy-core/src/encryption/gglwe_atk.rs b/poulpy-core/src/encryption/gglwe_atk.rs index 41ecd61..dfd1e97 100644 --- a/poulpy-core/src/encryption/gglwe_atk.rs +++ b/poulpy-core/src/encryption/gglwe_atk.rs @@ -5,58 +5,36 @@ use poulpy_hal::{ VecZnxIdftApplyConsume, VecZnxNormalize, VecZnxNormalizeInplace, VecZnxNormalizeTmpBytes, VecZnxSub, VecZnxSubInplace, VecZnxSwitchRing, }, - layouts::{Backend, DataMut, Module, Scratch}, + layouts::{Backend, DataMut, GaloisElement, Module, Scratch}, source::Source, }; use crate::{ ScratchTakeCore, layouts::{ - AutomorphismKey, AutomorphismKeyToMut, GGLWEInfos, GLWEInfos, GLWESecret, GLWESecretToRef, GLWESwitchingKey, LWEInfos, + AutomorphismKey, AutomorphismKeyToMut, GGLWEInfos, GLWEInfos, GLWESecret, GLWESecretToRef, GLWESwitchingKey, }, }; impl AutomorphismKey> { - pub fn encrypt_sk_tmp_bytes(module: &Module, infos: &A) -> usize + + pub fn encrypt_sk_tmp_bytes(module: &M, infos: &A) -> usize where A: GGLWEInfos, - Module: ModuleN + SvpPPolBytesOf + VecZnxNormalizeTmpBytes + VecZnxDftBytesOf + VecZnxNormalizeTmpBytes + SvpPPolAlloc, + M: GGLWEAutomorphismKeyEncryptSk { - assert_eq!( - infos.rank_in(), - infos.rank_out(), - "rank_in != rank_out is not supported for GGLWEAutomorphismKey" - ); - GLWESwitchingKey::encrypt_sk_tmp_bytes(module, infos) + GLWESecret::bytes_of_from_infos(module, &infos.glwe_layout()) + module.gglwe_automorphism_key_encrypt_sk_tmp_bytes(infos) } - pub fn encrypt_pk_tmp_bytes(module: &Module, _infos: &A) -> usize + pub fn encrypt_pk_tmp_bytes(module: &M, infos: &A) -> usize where A: GGLWEInfos, + M: GGLWEAutomorphismKeyEncryptPk { - assert_eq!( - _infos.rank_in(), - _infos.rank_out(), - "rank_in != rank_out is not supported for GGLWEAutomorphismKey" - ); - GLWESwitchingKey::encrypt_pk_tmp_bytes(module, _infos) + module.gglwe_automorphism_key_encrypt_pk_tmp_bytes(infos) } } -pub trait GGLWEAutomorphismKeyEncryptSk { - fn gglwe_automorphism_key_encrypt_sk( - &self, - res: &mut A, - p: i64, - sk: &B, - source_xa: &mut Source, - source_xe: &mut Source, - scratch: &mut Scratch, - ) where - A: AutomorphismKeyToMut, - B: GLWESecretToRef; -} - impl AutomorphismKey where Self: AutomorphismKeyToMut, @@ -77,6 +55,24 @@ where } } +pub trait GGLWEAutomorphismKeyEncryptSk { + fn gglwe_automorphism_key_encrypt_sk_tmp_bytes(&self, infos: &A) -> usize + where + A: GGLWEInfos; + + fn gglwe_automorphism_key_encrypt_sk( + &self, + res: &mut A, + p: i64, + sk: &B, + source_xa: &mut Source, + source_xe: &mut Source, + scratch: &mut Scratch, + ) where + A: AutomorphismKeyToMut, + B: GLWESecretToRef; +} + impl GGLWEAutomorphismKeyEncryptSk for Module where Module: ModuleN @@ -99,9 +95,22 @@ where + SvpPPolBytesOf + VecZnxAutomorphism + SvpPPolAlloc - + SvpPPolBytesOf, + + GaloisElement, Scratch: ScratchAvailable + ScratchTakeCore, { + + fn gglwe_automorphism_key_encrypt_sk_tmp_bytes(&self, infos: &A) -> usize + where + A: GGLWEInfos, + { + assert_eq!( + infos.rank_in(), + infos.rank_out(), + "rank_in != rank_out is not supported for GGLWEAutomorphismKey" + ); + GLWESwitchingKey::encrypt_sk_tmp_bytes(self, infos) + GLWESecret::bytes_of_from_infos(self, &infos.glwe_layout()) + } + fn gglwe_automorphism_key_encrypt_sk( &self, res: &mut A, @@ -151,4 +160,47 @@ where res.p = p; } +} + + +pub trait GGLWEAutomorphismKeyEncryptPk { + fn gglwe_automorphism_key_encrypt_pk_tmp_bytes(&self, infos: &A) -> usize + where + A: GGLWEInfos; + +} + +impl GGLWEAutomorphismKeyEncryptPk for Module +where + Module: ModuleN + + VecZnxAddScalarInplace + + VecZnxDftBytesOf + + VecZnxBigNormalize + + VecZnxDftApply + + SvpApplyDftToDftInplace + + VecZnxIdftApplyConsume + + VecZnxNormalizeTmpBytes + + VecZnxFillUniform + + VecZnxSubInplace + + VecZnxAddInplace + + VecZnxNormalizeInplace + + VecZnxAddNormal + + VecZnxNormalize + + VecZnxSub + + SvpPPolBytesOf + + SvpPPolAlloc, + Scratch: ScratchAvailable + ScratchTakeCore, +{ + + fn gglwe_automorphism_key_encrypt_pk_tmp_bytes(&self, infos: &A) -> usize + where + A: GGLWEInfos, + { + assert_eq!( + infos.rank_in(), + infos.rank_out(), + "rank_in != rank_out is not supported for GGLWEAutomorphismKey" + ); + GLWESwitchingKey::encrypt_pk_tmp_bytes(self, infos) + } } \ No newline at end of file diff --git a/poulpy-core/src/encryption/gglwe_ct.rs b/poulpy-core/src/encryption/gglwe_ct.rs index 1f7deec..e8ae4f8 100644 --- a/poulpy-core/src/encryption/gglwe_ct.rs +++ b/poulpy-core/src/encryption/gglwe_ct.rs @@ -64,7 +64,6 @@ where + VecZnxDftBytesOf + VecZnxAddScalarInplace + VecZnxNormalizeInplace, - // + SvpPPolAllocBytesImpl, Scratch: ScratchAvailable + ScratchTakeCore, { fn gglwe_encrypt_sk_tmp_bytes(&self, infos: &A) -> usize diff --git a/poulpy-core/src/encryption/gglwe_ksk.rs b/poulpy-core/src/encryption/gglwe_ksk.rs index 0ba6047..bd13c2b 100644 --- a/poulpy-core/src/encryption/gglwe_ksk.rs +++ b/poulpy-core/src/encryption/gglwe_ksk.rs @@ -12,7 +12,7 @@ use poulpy_hal::{ use crate::{ ScratchTakeCore, layouts::{ - GGLWE, GGLWEInfos, GLWEInfos, GLWESecret, GLWESwitchingKey, LWEInfos, RingDegree, prepared::GLWESecretPrepared, + GGLWE, GGLWEInfos, GLWEInfos, GLWESecret, GLWESecretToRef, GLWESwitchingKey, GLWESwitchingKeyToMut, LWEInfos, prepared::GLWESecretPrepared, }, encryption::gglwe_ct::GGLWEEncryptSk, }; @@ -26,109 +26,108 @@ impl GLWESwitchingKey> { module.glwe_switching_key_encrypt_sk_tmp_bytes(infos) } - pub fn encrypt_pk_tmp_bytes(module: &M, infos: &A) -> usize where A: GGLWEInfos, - M: GLWESwitchingKeyEncryptSk, + M: GLWESwitchingKeyEncryptPk, { module.glwe_switching_key_encrypt_pk_tmp_bytes(infos) } - - // pub fn encrypt_sk_tmp_bytes(module: &Module, infos: &A) -> usize - // where - // A: GGLWEInfos, - // Module: ModuleN + SvpPPolBytesOf + VecZnxNormalizeTmpBytes + VecZnxDftBytesOf + VecZnxNormalizeTmpBytes + SvpPPolAlloc, - // { - // (GGLWE::encrypt_sk_tmp_bytes(module, infos) | ScalarZnx::bytes_of(module.n(), 1)) - // + ScalarZnx::bytes_of(module.n(), infos.rank_in().into()) - // + GLWESecretPrepared::bytes_of_from_infos(module, &infos.glwe_layout()) - // } - - // pub fn encrypt_pk_tmp_bytes(module: &Module, _infos: &A) -> usize - // where - // A: GGLWEInfos, - // { - // GGLWE::encrypt_pk_tmp_bytes(module, _infos) - // } } impl GLWESwitchingKey { - #[allow(clippy::too_many_arguments)] - pub fn encrypt_sk( + + pub fn encrypt_sk( &mut self, - module: &Module, + module: &M, sk_in: &GLWESecret, sk_out: &GLWESecret, source_xa: &mut Source, source_xe: &mut Source, - scratch: &mut Scratch, + scratch: &mut Scratch, ) where - Module: ModuleN - + VecZnxAddScalarInplace - + VecZnxDftBytesOf - + VecZnxBigNormalize - + VecZnxDftApply - + SvpApplyDftToDftInplace - + VecZnxIdftApplyConsume - + VecZnxNormalizeTmpBytes - + VecZnxFillUniform - + VecZnxSubInplace - + VecZnxAddInplace - + VecZnxNormalizeInplace - + VecZnxAddNormal - + VecZnxNormalize - + VecZnxSub - + SvpPrepare - + VecZnxSwitchRing - + SvpPPolBytesOf - + SvpPPolAlloc, - Scratch: ScratchAvailable + ScratchTakeBasic + ScratchTakeCore, + M: GLWESwitchingKeyEncryptSk, + Scratch: ScratchAvailable + ScratchTakeCore, { - #[cfg(debug_assertions)] - { - assert!(sk_in.n().0 <= module.n() as u32); - assert!(sk_out.n().0 <= module.n() as u32); - assert!( - scratch.available() >= GLWESwitchingKey::encrypt_sk_tmp_bytes(module, self), - "scratch.available()={} < GLWESwitchingKey::encrypt_sk_tmp_bytes={}", - scratch.available(), - GLWESwitchingKey::encrypt_sk_tmp_bytes(module, self) - ) - } - - let n: usize = sk_in.n().max(sk_out.n()).into(); - - let (mut sk_in_tmp, scratch_1) = scratch.take_scalar_znx(module, sk_in.rank().into()); - (0..sk_in.rank().into()).for_each(|i| { - module.vec_znx_switch_ring( - &mut sk_in_tmp.as_vec_znx_mut(), - i, - &sk_in.data.as_vec_znx(), - i, - ); - }); - - let (mut sk_out_tmp, scratch_2) = scratch_1.take_glwe_secret_prepared(module, sk_out.rank()); - { - let (mut tmp, _) = scratch_2.take_scalar_znx(module, 1); - (0..sk_out.rank().into()).for_each(|i| { - module.vec_znx_switch_ring(&mut tmp.as_vec_znx_mut(), 0, &sk_out.data.as_vec_znx(), i); - module.svp_prepare(&mut sk_out_tmp.data, i, &tmp, 0); - }); - } - - self.key.encrypt_sk( - module, - &sk_in_tmp, - &sk_out_tmp, - source_xa, - source_xe, - scratch_2, - ); - self.sk_in_n = sk_in.n().into(); - self.sk_out_n = sk_out.n().into(); + module.glwe_switching_key_encrypt_sk(self, sk_in, sk_out, source_xa, source_xe, scratch); } + + + // #[allow(clippy::too_many_arguments)] + // pub fn encrypt_sk( + // &mut self, + // module: &Module, + // sk_in: &GLWESecret, + // sk_out: &GLWESecret, + // source_xa: &mut Source, + // source_xe: &mut Source, + // scratch: &mut Scratch, + // ) where + // Module: ModuleN + // + VecZnxAddScalarInplace + // + VecZnxDftBytesOf + // + VecZnxBigNormalize + // + VecZnxDftApply + // + SvpApplyDftToDftInplace + // + VecZnxIdftApplyConsume + // + VecZnxNormalizeTmpBytes + // + VecZnxFillUniform + // + VecZnxSubInplace + // + VecZnxAddInplace + // + VecZnxNormalizeInplace + // + VecZnxAddNormal + // + VecZnxNormalize + // + VecZnxSub + // + SvpPrepare + // + VecZnxSwitchRing + // + SvpPPolBytesOf + // + SvpPPolAlloc, + // Scratch: ScratchAvailable + ScratchTakeBasic + ScratchTakeCore, + // { + // #[cfg(debug_assertions)] + // { + // assert!(sk_in.n().0 <= module.n() as u32); + // assert!(sk_out.n().0 <= module.n() as u32); + // assert!( + // scratch.available() >= GLWESwitchingKey::encrypt_sk_tmp_bytes(module, self), + // "scratch.available()={} < GLWESwitchingKey::encrypt_sk_tmp_bytes={}", + // scratch.available(), + // GLWESwitchingKey::encrypt_sk_tmp_bytes(module, self) + // ) + // } + + // // let n: usize = sk_in.n().max(sk_out.n()).into(); + + // let (mut sk_in_tmp, scratch_1) = scratch.take_scalar_znx(module, sk_in.rank().into()); + // (0..sk_in.rank().into()).for_each(|i| { + // module.vec_znx_switch_ring( + // &mut sk_in_tmp.as_vec_znx_mut(), + // i, + // &sk_in.data.as_vec_znx(), + // i, + // ); + // }); + + // let (mut sk_out_tmp, scratch_2) = scratch_1.take_glwe_secret_prepared(module, sk_out.rank()); + // { + // let (mut tmp, _) = scratch_2.take_scalar_znx(module, 1); + // (0..sk_out.rank().into()).for_each(|i| { + // module.vec_znx_switch_ring(&mut tmp.as_vec_znx_mut(), 0, &sk_out.data.as_vec_znx(), i); + // module.svp_prepare(&mut sk_out_tmp.data, i, &tmp, 0); + // }); + // } + + // self.key.encrypt_sk( + // module, + // &sk_in_tmp, + // &sk_out_tmp, + // source_xa, + // source_xe, + // scratch_2, + // ); + // self.sk_in_n = sk_in.n().into(); + // self.sk_out_n = sk_out.n().into(); + // } } @@ -146,9 +145,21 @@ where where A: GGLWEInfos; - fn glwe_switching_key_encrypt_pk_tmp_bytes(&self, infos: &A) -> usize - where - A: GGLWEInfos; + fn glwe_switching_key_encrypt_sk( + &self, + res: &mut R, + sk_in: &GLWESecret, + sk_out: &GLWESecret, + source_xa: &mut Source, + source_xe: &mut Source, + scratch: &mut Scratch, + ) + where + R: GLWESwitchingKeyToMut, + DataSkIn: DataRef, + DataSkOut: DataRef, + Scratch: ScratchAvailable + ScratchTakeCore; + } impl GLWESwitchingKeyEncryptSk for Module where @@ -157,7 +168,15 @@ impl GLWESwitchingKeyEncryptSk for Module where + VecZnxDftBytesOf + VecZnxNormalizeTmpBytes + SvpPPolAlloc - + GGLWEEncryptSk, + + GGLWEEncryptSk + + VecZnxSwitchRing + + SvpPrepare + + VecZnxIdftApplyConsume + + VecZnxNormalize + + VecZnxNormalizeInplace + + VecZnxAddInplace + + VecZnxAddNormal + + VecZnxSub { fn glwe_switching_key_encrypt_sk_tmp_bytes(&self, infos: &A) -> usize @@ -169,11 +188,102 @@ impl GLWESwitchingKeyEncryptSk for Module where + GLWESecretPrepared::bytes_of_from_infos(self, &infos.glwe_layout()) } + fn glwe_switching_key_encrypt_sk( + &self, + res: &mut R, + sk_in: &GLWESecret, + sk_out: &GLWESecret, + source_xa: &mut Source, + source_xe: &mut Source, + scratch: &mut Scratch, + ) + where + R: GLWESwitchingKeyToMut, + DataSkIn: DataRef, + DataSkOut: DataRef, + Scratch: ScratchAvailable + ScratchTakeCore, + { + + let res: &mut GLWESwitchingKey<&mut [u8]> = &mut res.to_mut(); + let sk_in: &GLWESecret<&[u8]> = &sk_in.to_ref(); + let sk_out: &GLWESecret<&[u8]> = &sk_out.to_ref(); + + #[cfg(debug_assertions)] + { + assert!(sk_in.n().0 <= self.n() as u32); + assert!(sk_out.n().0 <= self.n() as u32); + assert!( + scratch.available() >= GLWESwitchingKey::encrypt_sk_tmp_bytes(self, res), + "scratch.available()={} < GLWESwitchingKey::encrypt_sk_tmp_bytes={}", + scratch.available(), + GLWESwitchingKey::encrypt_sk_tmp_bytes(self, res) + ) + } + + // let n: usize = sk_in.n().max(sk_out.n()).into(); + + let (mut sk_in_tmp, scratch_1) = scratch.take_scalar_znx(self, sk_in.rank().into()); + (0..sk_in.rank().into()).for_each(|i| { + self.vec_znx_switch_ring( + &mut sk_in_tmp.as_vec_znx_mut(), + i, + &sk_in.data.as_vec_znx(), + i, + ); + }); + + let (mut sk_out_tmp, scratch_2) = scratch_1.take_glwe_secret_prepared(self, sk_out.rank()); + { + let (mut tmp, _) = scratch_2.take_scalar_znx(self, 1); + (0..sk_out.rank().into()).for_each(|i| { + self.vec_znx_switch_ring(&mut tmp.as_vec_znx_mut(), 0, &sk_out.data.as_vec_znx(), i); + self.svp_prepare(&mut sk_out_tmp.data, i, &tmp, 0); + }); + } + + res.key.encrypt_sk( + self, + &sk_in_tmp, + &sk_out_tmp, + source_xa, + source_xe, + scratch_2, + ); + res.sk_in_n = sk_in.n().into(); + res.sk_out_n = sk_out.n().into(); + } + +} + +pub trait GLWESwitchingKeyEncryptPk +where + Self: Sized + + ModuleN + + SvpPPolBytesOf + + VecZnxDftBytesOf + + VecZnxNormalizeTmpBytes + + SvpPPolAlloc + + GGLWEEncryptSk, +{ + + fn glwe_switching_key_encrypt_pk_tmp_bytes(&self, infos: &A) -> usize + where + A: GGLWEInfos; +} + +impl GLWESwitchingKeyEncryptPk for Module where + Self: ModuleN + + SvpPPolBytesOf + + VecZnxDftBytesOf + + VecZnxNormalizeTmpBytes + + SvpPPolAlloc + + GGLWEEncryptSk, +{ + fn glwe_switching_key_encrypt_pk_tmp_bytes(&self, infos: &A) -> usize where A: GGLWEInfos, { GGLWE::encrypt_pk_tmp_bytes(self, infos) } - } \ No newline at end of file diff --git a/poulpy-core/src/encryption/gglwe_tsk.rs b/poulpy-core/src/encryption/gglwe_tsk.rs index 918eb8a..3f4a31b 100644 --- a/poulpy-core/src/encryption/gglwe_tsk.rs +++ b/poulpy-core/src/encryption/gglwe_tsk.rs @@ -1,112 +1,256 @@ use poulpy_hal::{ api::{ - ModuleN, ScratchTakeBasic, SvpApplyDftToDft, SvpApplyDftToDftInplace, SvpPPolAlloc, SvpPPolBytesOf, SvpPrepare, VecZnxAddInplace, VecZnxAddNormal, + ModuleN, ScratchAvailable, ScratchTakeBasic, SvpApplyDftToDft, SvpApplyDftToDftInplace, SvpPPolAlloc, SvpPPolBytesOf, SvpPrepare, VecZnxAddInplace, VecZnxAddNormal, VecZnxAddScalarInplace, VecZnxBigBytesOf, VecZnxBigNormalize, VecZnxDftApply, VecZnxDftBytesOf, VecZnxFillUniform, VecZnxIdftApplyConsume, VecZnxIdftApplyTmpA, VecZnxNormalize, VecZnxNormalizeInplace, VecZnxNormalizeTmpBytes, VecZnxSub, VecZnxSubInplace, VecZnxSwitchRing, }, layouts::{Backend, DataMut, DataRef, Module, Scratch}, - oep::VecZnxBigAllocBytesImpl, + oep::{VecZnxAddScalarInplaceImpl, VecZnxBigAllocBytesImpl, VecZnxDftApplyImpl, SvpApplyDftToDftImpl, VecZnxIdftApplyTmpAImpl, VecZnxBigNormalizeImpl}, source::Source, }; use crate::{ ScratchTakeCore, layouts::{ - GetDist, GGLWEInfos, GLWEInfos, GLWESecret, GLWESwitchingKey, LWEInfos, Rank, TensorKey, prepared::GLWESecretPrepared, + GetDist, GGLWEInfos, GLWEInfos, GLWESecret, GLWESecretToRef, GLWESwitchingKey, LWEInfos, Rank, TensorKey, TensorKeyToMut, + prepared::GLWESecretPrepared, }, + encryption::gglwe_ksk::GLWESwitchingKeyEncryptSk, }; impl TensorKey> { - pub fn encrypt_sk_tmp_bytes(module: &Module, infos: &A) -> usize + pub fn encrypt_sk_tmp_bytes(module: &M, infos: &A) -> usize where A: GGLWEInfos, - Module: ModuleN + SvpPPolBytesOf + SvpPPolAlloc + VecZnxNormalizeTmpBytes + VecZnxDftBytesOf + VecZnxNormalizeTmpBytes + VecZnxBigBytesOf, + M: GGLWETensorKeyEncryptSk { - GLWESecretPrepared::bytes_of(module, infos.rank_out()) - + module.bytes_of_vec_znx_dft(infos.rank_out().into(), 1) - + module.bytes_of_vec_znx_big(1, 1) - + module.bytes_of_vec_znx_dft(1, 1) - + GLWESecret::bytes_of(module, Rank(1)) - + GLWESwitchingKey::encrypt_sk_tmp_bytes(module, infos) + module.gglwe_tensor_key_encrypt_sk_tmp_bytes(infos) } + // pub fn encrypt_sk_tmp_bytes(module: &Module, infos: &A) -> usize + // where + // A: GGLWEInfos, + // Module: ModuleN + SvpPPolBytesOf + SvpPPolAlloc + VecZnxNormalizeTmpBytes + VecZnxDftBytesOf + VecZnxNormalizeTmpBytes + VecZnxBigBytesOf, + // { + // GLWESecretPrepared::bytes_of(module, infos.rank_out()) + // + module.bytes_of_vec_znx_dft(infos.rank_out().into(), 1) + // + module.bytes_of_vec_znx_big(1, 1) + // + module.bytes_of_vec_znx_dft(1, 1) + // + GLWESecret::bytes_of(module, Rank(1)) + // + GLWESwitchingKey::encrypt_sk_tmp_bytes(module, infos) + // } } impl TensorKey { - pub fn encrypt_sk( + pub fn encrypt_sk( &mut self, - module: &Module, + module: &M, sk: &GLWESecret, source_xa: &mut Source, source_xe: &mut Source, - scratch: &mut Scratch, + scratch: &mut Scratch, ) where + M: GGLWETensorKeyEncryptSk, GLWESecret: GetDist, - Module: ModuleN - + SvpApplyDftToDft - + VecZnxIdftApplyTmpA - + VecZnxAddScalarInplace - + VecZnxDftBytesOf - + VecZnxBigNormalize - + VecZnxDftApply - + SvpApplyDftToDftInplace - + VecZnxIdftApplyConsume - + VecZnxNormalizeTmpBytes - + VecZnxFillUniform - + VecZnxSubInplace - + VecZnxAddInplace - + VecZnxNormalizeInplace - + VecZnxAddNormal - + VecZnxNormalize - + VecZnxSub - + SvpPrepare - + VecZnxSwitchRing - + SvpPPolBytesOf - + VecZnxBigAllocBytesImpl - + VecZnxBigBytesOf - + SvpPPolAlloc, - Scratch: ScratchTakeBasic + ScratchTakeCore, + Scratch: ScratchAvailable + ScratchTakeCore, { - #[cfg(debug_assertions)] - { - assert_eq!(self.rank_out(), sk.rank()); - assert_eq!(self.n(), sk.n()); - } + module.gglwe_tensor_key_encrypt_sk(self, sk, source_xa, source_xe, scratch); + } + + // pub fn encrypt_sk( + // &mut self, + // module: &Module, + // sk: &GLWESecret, + // source_xa: &mut Source, + // source_xe: &mut Source, + // scratch: &mut Scratch, + // ) where + // GLWESecret: GetDist, + // Module: ModuleN + // + SvpApplyDftToDft + // + VecZnxIdftApplyTmpA + // + VecZnxAddScalarInplace + // + VecZnxDftBytesOf + // + VecZnxBigNormalize + // + VecZnxDftApply + // + SvpApplyDftToDftInplace + // + VecZnxIdftApplyConsume + // + VecZnxNormalizeTmpBytes + // + VecZnxFillUniform + // + VecZnxSubInplace + // + VecZnxAddInplace + // + VecZnxNormalizeInplace + // + VecZnxAddNormal + // + VecZnxNormalize + // + VecZnxSub + // + SvpPrepare + // + VecZnxSwitchRing + // + SvpPPolBytesOf + // + VecZnxBigAllocBytesImpl + // + VecZnxBigBytesOf + // + SvpPPolAlloc, + // Scratch: ScratchTakeBasic + ScratchTakeCore, + // { + // #[cfg(debug_assertions)] + // { + // assert_eq!(self.rank_out(), sk.rank()); + // assert_eq!(self.n(), sk.n()); + // } + + // // let n: RingDegree = sk.n(); + // let rank: Rank = self.rank_out(); + + // let (mut sk_dft_prep, scratch_1) = scratch.take_glwe_secret_prepared(module, rank); + // sk_dft_prep.prepare(module, sk); + + // let (mut sk_dft, scratch_2) = scratch_1.take_vec_znx_dft(module, rank.into(), 1); + + // (0..rank.into()).for_each(|i| { + // module.vec_znx_dft_apply(1, 0, &mut sk_dft, i, &sk.data.as_vec_znx(), i); + // }); + + // let (mut sk_ij_big, scratch_3) = scratch_2.take_vec_znx_big(module, 1, 1); + // let (mut sk_ij, scratch_4) = scratch_3.take_glwe_secret(module, Rank(1)); + // let (mut sk_ij_dft, scratch_5) = scratch_4.take_vec_znx_dft(module, 1, 1); + + // (0..rank.into()).for_each(|i| { + // (i..rank.into()).for_each(|j| { + // module.svp_apply_dft_to_dft(&mut sk_ij_dft, 0, &sk_dft_prep.data, j, &sk_dft, i); + + // module.vec_znx_idft_apply_tmpa(&mut sk_ij_big, 0, &mut sk_ij_dft, 0); + // module.vec_znx_big_normalize( + // self.base2k().into(), + // &mut sk_ij.data.as_vec_znx_mut(), + // 0, + // self.base2k().into(), + // &sk_ij_big, + // 0, + // scratch_5, + // ); + + // self.at_mut(i, j) + // .encrypt_sk(module, &sk_ij, sk, source_xa, source_xe, scratch_5); + // }); + // }) + // } +} + +pub trait GGLWETensorKeyEncryptSk +where + Self: Sized + + ModuleN + + SvpPPolBytesOf + + SvpPPolAlloc + + VecZnxNormalizeTmpBytes + + VecZnxDftBytesOf + + VecZnxNormalizeTmpBytes + + VecZnxBigBytesOf, +{ + fn gglwe_tensor_key_encrypt_sk_tmp_bytes(&self, infos: &A) -> usize + where + A: GGLWEInfos; + + fn gglwe_tensor_key_encrypt_sk( + &self, + res: &mut R, + sk: &S, + source_xa: &mut Source, + source_xe: &mut Source, + scratch: &mut Scratch, + ) where + R: TensorKeyToMut, + S: GLWESecretToRef + GetDist; +} + +impl GGLWETensorKeyEncryptSk for Module where + Module: ModuleN + + SvpPPolBytesOf + + SvpPPolAlloc + + VecZnxNormalizeTmpBytes + + VecZnxDftBytesOf + + VecZnxNormalizeTmpBytes + + VecZnxBigBytesOf + + VecZnxAddScalarInplaceImpl + + VecZnxDftApply + + VecZnxDftApplyImpl + + SvpApplyDftToDftImpl + + GLWESwitchingKeyEncryptSk + + SvpApplyDftToDft + + VecZnxIdftApplyTmpAImpl + + VecZnxBigNormalizeImpl + + VecZnxIdftApplyTmpA + + VecZnxBigNormalize + + VecZnxAddScalarInplaceImpl + + SvpPrepare, + Scratch: ScratchTakeBasic + ScratchTakeCore, +{ + fn gglwe_tensor_key_encrypt_sk_tmp_bytes(&self, infos: &A) -> usize + where + A: GGLWEInfos, + { + GLWESecretPrepared::bytes_of(self, infos.rank_out()) + + self.bytes_of_vec_znx_dft(infos.rank_out().into(), 1) + + self.bytes_of_vec_znx_big(1, 1) + + self.bytes_of_vec_znx_dft(1, 1) + + GLWESecret::bytes_of(self, Rank(1)) + + GLWESwitchingKey::encrypt_sk_tmp_bytes(self, infos) + } + + fn gglwe_tensor_key_encrypt_sk( + &self, + res: &mut R, + sk: &S, + source_xa: &mut Source, + source_xe: &mut Source, + scratch: &mut Scratch, + ) where + R: TensorKeyToMut, + S: GLWESecretToRef + GetDist, + { + let res: &mut TensorKey<&mut [u8]> = &mut res.to_mut(); // let n: RingDegree = sk.n(); - let rank: Rank = self.rank_out(); + let rank: Rank = res.rank_out(); - let (mut sk_dft_prep, scratch_1) = scratch.take_glwe_secret_prepared(module, rank); - sk_dft_prep.prepare(module, sk); + let (mut sk_dft_prep, scratch_1) = scratch.take_glwe_secret_prepared(self, rank); + sk_dft_prep.prepare(self, sk); - let (mut sk_dft, scratch_2) = scratch_1.take_vec_znx_dft(module, rank.into(), 1); + let sk: &GLWESecret<&[u8]> = &sk.to_ref(); + + #[cfg(debug_assertions)] + { + assert_eq!(res.rank_out(), sk.rank()); + assert_eq!(res.n(), sk.n()); + } + + let (mut sk_dft, scratch_2) = scratch_1.take_vec_znx_dft(self, rank.into(), 1); (0..rank.into()).for_each(|i| { - module.vec_znx_dft_apply(1, 0, &mut sk_dft, i, &sk.data.as_vec_znx(), i); + self.vec_znx_dft_apply(1, 0, &mut sk_dft, i, &sk.data.as_vec_znx(), i); }); - let (mut sk_ij_big, scratch_3) = scratch_2.take_vec_znx_big(module, 1, 1); - let (mut sk_ij, scratch_4) = scratch_3.take_glwe_secret(module, Rank(1)); - let (mut sk_ij_dft, scratch_5) = scratch_4.take_vec_znx_dft(module, 1, 1); + let (mut sk_ij_big, scratch_3) = scratch_2.take_vec_znx_big(self, 1, 1); + let (mut sk_ij, scratch_4) = scratch_3.take_glwe_secret(self, Rank(1)); + let (mut sk_ij_dft, scratch_5) = scratch_4.take_vec_znx_dft(self, 1, 1); (0..rank.into()).for_each(|i| { (i..rank.into()).for_each(|j| { - module.svp_apply_dft_to_dft(&mut sk_ij_dft, 0, &sk_dft_prep.data, j, &sk_dft, i); + self.svp_apply_dft_to_dft(&mut sk_ij_dft, 0, &sk_dft_prep.data, j, &sk_dft, i); - module.vec_znx_idft_apply_tmpa(&mut sk_ij_big, 0, &mut sk_ij_dft, 0); - module.vec_znx_big_normalize( - self.base2k().into(), + self.vec_znx_idft_apply_tmpa(&mut sk_ij_big, 0, &mut sk_ij_dft, 0); + self.vec_znx_big_normalize( + res.base2k().into(), &mut sk_ij.data.as_vec_znx_mut(), 0, - self.base2k().into(), + res.base2k().into(), &sk_ij_big, 0, scratch_5, ); - self.at_mut(i, j) - .encrypt_sk(module, &sk_ij, sk, source_xa, source_xe, scratch_5); + res.at_mut(i, j) + .encrypt_sk(self, &sk_ij, sk, source_xa, source_xe, scratch_5); }); - }) + }) } -} +} \ No newline at end of file diff --git a/poulpy-core/src/encryption/ggsw_ct.rs b/poulpy-core/src/encryption/ggsw_ct.rs index 3357380..90bac6b 100644 --- a/poulpy-core/src/encryption/ggsw_ct.rs +++ b/poulpy-core/src/encryption/ggsw_ct.rs @@ -14,20 +14,48 @@ use crate::{ }; impl GGSW> { - pub fn encrypt_sk_tmp_bytes(module: &Module, infos: &A) -> usize + pub fn encrypt_sk_tmp_bytes(module: &M, infos: &A) -> usize where A: GGSWInfos, - Module: VecZnxNormalizeTmpBytes + VecZnxDftBytesOf, + M: GGSWEncryptSk, { - let size = infos.size(); - GLWE::encrypt_sk_tmp_bytes(module, &infos.glwe_layout()) - + VecZnx::bytes_of(module.n(), (infos.rank() + 1).into(), size) - + VecZnx::bytes_of(module.n(), 1, size) - + module.bytes_of_vec_znx_dft((infos.rank() + 1).into(), size) + module.ggsw_encrypt_sk_tmp_bytes(infos) + } + // pub fn encrypt_sk_tmp_bytes(module: &Module, infos: &A) -> usize + // where + // A: GGSWInfos, + // Module: VecZnxNormalizeTmpBytes + VecZnxDftBytesOf, + // { + // let size = infos.size(); + // GLWE::encrypt_sk_tmp_bytes(module, &infos.glwe_layout()) + // + VecZnx::bytes_of(module.n(), (infos.rank() + 1).into(), size) + // + VecZnx::bytes_of(module.n(), 1, size) + // + module.bytes_of_vec_znx_dft((infos.rank() + 1).into(), size) + // } +} + +impl GGSW { + #[allow(clippy::too_many_arguments)] + pub fn encrypt_sk( + &mut self, + module: &Module, + pt: &ScalarZnx, + sk: &GLWESecretPrepared, + source_xa: &mut Source, + source_xe: &mut Source, + scratch: &mut Scratch, + ) where + Module: GGSWEncryptSk, + { + module.ggsw_encrypt_sk(self, pt, sk, source_xa, source_xe, scratch); } } pub trait GGSWEncryptSk { + fn ggsw_encrypt_sk_tmp_bytes(&self, infos: &A) -> usize + where + A: GGSWInfos; + fn ggsw_encrypt_sk( &self, res: &mut R, @@ -44,9 +72,26 @@ pub trait GGSWEncryptSk { impl GGSWEncryptSk for Module where - Module: ModuleN + GLWEEncryptSkInternal + VecZnxAddScalarInplace + VecZnxNormalizeInplace, + Module: ModuleN + + GLWEEncryptSkInternal + + VecZnxAddScalarInplace + + VecZnxNormalizeInplace + + VecZnxDftBytesOf + + VecZnxNormalizeTmpBytes, Scratch: ScratchTakeCore, { + + fn ggsw_encrypt_sk_tmp_bytes(&self, infos: &A) -> usize + where + A: GGSWInfos, + { + let size = infos.size(); + GLWE::encrypt_sk_tmp_bytes(self, &infos.glwe_layout()) + + VecZnx::bytes_of(self.n(), (infos.rank() + 1).into(), size) + + VecZnx::bytes_of(self.n(), 1, size) + + self.bytes_of_vec_znx_dft((infos.rank() + 1).into(), size) + } + fn ggsw_encrypt_sk( &self, res: &mut R, @@ -104,21 +149,4 @@ where } } } -} - -impl GGSW { - #[allow(clippy::too_many_arguments)] - pub fn encrypt_sk( - &mut self, - module: &Module, - pt: &ScalarZnx, - sk: &GLWESecretPrepared, - source_xa: &mut Source, - source_xe: &mut Source, - scratch: &mut Scratch, - ) where - Module: GGSWEncryptSk, - { - module.ggsw_encrypt_sk(self, pt, sk, source_xa, source_xe, scratch); - } -} +} \ No newline at end of file diff --git a/poulpy-core/src/encryption/glwe_to_lwe_ksk.rs b/poulpy-core/src/encryption/glwe_to_lwe_ksk.rs index cd3ffec..4ade4d9 100644 --- a/poulpy-core/src/encryption/glwe_to_lwe_ksk.rs +++ b/poulpy-core/src/encryption/glwe_to_lwe_ksk.rs @@ -4,82 +4,224 @@ use poulpy_hal::{ VecZnxAddScalarInplace, VecZnxAutomorphismInplace, VecZnxBigNormalize, VecZnxDftApply, VecZnxDftBytesOf, VecZnxFillUniform, VecZnxIdftApplyConsume, VecZnxNormalize, VecZnxNormalizeInplace, VecZnxNormalizeTmpBytes, VecZnxSub, VecZnxSubInplace, VecZnxSwitchRing, - }, + ScratchTakeBasic + }, layouts::{Backend, DataMut, DataRef, Module, Scratch, ZnxView, ZnxViewMut, ZnxZero}, - source::Source, + oep::{ScratchAvailableImpl, VecZnxFillUniformImpl}, + source::Source }; use crate::{ ScratchTakeCore, layouts::{ - GGLWEInfos, GLWESecret, GLWESwitchingKey, GLWEToLWESwitchingKey, LWEInfos, LWESecret, Rank, + GGLWEInfos, GLWESecret, GLWESwitchingKey, GLWEToLWESwitchingKey, LWEInfos, LWESecret, Rank, GLWEToLWESwitchingKeyToMut, prepared::GLWESecretPrepared, }, + encryption::gglwe_ksk::GLWESwitchingKeyEncryptSk, }; impl GLWEToLWESwitchingKey> { - pub fn encrypt_sk_tmp_bytes(module: &Module, infos: &A) -> usize + pub fn encrypt_sk_tmp_bytes(module: &M, infos: &A) -> usize where A: GGLWEInfos, - Module: ModuleN + SvpPPolBytesOf + SvpPPolAlloc + VecZnxNormalizeTmpBytes + VecZnxDftBytesOf + VecZnxNormalizeTmpBytes, + M: GLWEToLWESwitchingKeyEncrypt, { - GLWESecretPrepared::bytes_of(module, infos.rank_in()) - + (GLWESwitchingKey::encrypt_sk_tmp_bytes(module, infos) | GLWESecret::bytes_of(module, infos.rank_in())) + module.glwe_to_lwe_switching_key_encrypt_sk_tmp_bytes(infos) } + // pub fn encrypt_sk_tmp_bytes(module: &Module, infos: &A) -> usize + // where + // A: GGLWEInfos, + // Module: ModuleN + SvpPPolBytesOf + SvpPPolAlloc + VecZnxNormalizeTmpBytes + VecZnxDftBytesOf + VecZnxNormalizeTmpBytes, + // { + // GLWESecretPrepared::bytes_of(module, infos.rank_in()) + // + (GLWESwitchingKey::encrypt_sk_tmp_bytes(module, infos) | GLWESecret::bytes_of(module, infos.rank_in())) + // } } impl GLWEToLWESwitchingKey { - #[allow(clippy::too_many_arguments)] - pub fn encrypt_sk( + pub fn encrypt_sk( &mut self, - module: &Module, + module: &M, sk_lwe: &LWESecret, sk_glwe: &GLWESecret, source_xa: &mut Source, source_xe: &mut Source, - scratch: &mut Scratch, + scratch: &mut Scratch, ) where + M: GLWEToLWESwitchingKeyEncrypt, DLwe: DataRef, DGlwe: DataRef, - Module: ModuleN - + VecZnxAutomorphismInplace - + VecZnxAddScalarInplace - + VecZnxDftBytesOf - + VecZnxBigNormalize - + VecZnxDftApply - + SvpApplyDftToDftInplace - + VecZnxIdftApplyConsume - + VecZnxNormalizeTmpBytes - + VecZnxFillUniform - + VecZnxSubInplace - + VecZnxAddInplace - + VecZnxNormalizeInplace - + VecZnxAddNormal - + VecZnxNormalize - + VecZnxSub - + SvpPrepare - + VecZnxSwitchRing - + SvpPPolBytesOf - + SvpPPolAlloc, - Scratch: ScratchAvailable + ScratchTakeCore, + Scratch: ScratchAvailable + ScratchTakeCore, { + module.glwe_to_lwe_switching_key_encrypt_sk(self, sk_lwe, sk_glwe, source_xa, source_xe, scratch); + } + // #[allow(clippy::too_many_arguments)] + // pub fn encrypt_sk( + // &mut self, + // module: &Module, + // sk_lwe: &LWESecret, + // sk_glwe: &GLWESecret, + // source_xa: &mut Source, + // source_xe: &mut Source, + // scratch: &mut Scratch, + // ) where + // DLwe: DataRef, + // DGlwe: DataRef, + // Module: ModuleN + // + VecZnxAutomorphismInplace + // + VecZnxAddScalarInplace + // + VecZnxDftBytesOf + // + VecZnxBigNormalize + // + VecZnxDftApply + // + SvpApplyDftToDftInplace + // + VecZnxIdftApplyConsume + // + VecZnxNormalizeTmpBytes + // + VecZnxFillUniform + // + VecZnxSubInplace + // + VecZnxAddInplace + // + VecZnxNormalizeInplace + // + VecZnxAddNormal + // + VecZnxNormalize + // + VecZnxSub + // + SvpPrepare + // + VecZnxSwitchRing + // + SvpPPolBytesOf + // + SvpPPolAlloc, + // Scratch: ScratchAvailable + ScratchTakeCore, + // { + // #[cfg(debug_assertions)] + // { + // assert!(sk_lwe.n().0 <= module.n() as u32); + // } + + // let (mut sk_lwe_as_glwe, scratch_1) = scratch.take_glwe_secret(module, Rank(1)); + // sk_lwe_as_glwe.data.zero(); + // sk_lwe_as_glwe.data.at_mut(0, 0)[..sk_lwe.n().into()].copy_from_slice(sk_lwe.data.at(0, 0)); + // module.vec_znx_automorphism_inplace(-1, &mut sk_lwe_as_glwe.data.as_vec_znx_mut(), 0, scratch_1); + + // self.0.encrypt_sk( + // module, + // sk_glwe, + // &sk_lwe_as_glwe, + // source_xa, + // source_xe, + // scratch_1, + // ); + // } +} + +pub trait GLWEToLWESwitchingKeyEncrypt +where + Self: Sized + + ModuleN + + SvpPPolBytesOf + + SvpPPolAlloc + + VecZnxNormalizeTmpBytes + + VecZnxDftBytesOf + + VecZnxAutomorphismInplace + + VecZnxAddScalarInplace + + VecZnxBigNormalize + + VecZnxDftApply + + SvpApplyDftToDftInplace + + VecZnxIdftApplyConsume + + VecZnxNormalize + + VecZnxNormalizeInplace + + VecZnxAddNormal + + VecZnxSub + + VecZnxSubInplace + + VecZnxAddInplace + + SvpPrepare + + VecZnxSwitchRing + + ScratchAvailable + + ScratchAvailableImpl + + VecZnxFillUniform + + VecZnxFillUniformImpl +{ + fn glwe_to_lwe_switching_key_encrypt_sk_tmp_bytes(&self, infos: &A) -> usize + where + A: GGLWEInfos; + + fn glwe_to_lwe_switching_key_encrypt_sk( + &self, + res: &mut R, + sk_lwe: &LWESecret, + sk_glwe: &GLWESecret, + source_xa: &mut Source, + source_xe: &mut Source, + scratch: &mut Scratch, + ) where + R: GLWEToLWESwitchingKeyToMut, + Scratch: ScratchAvailable + ScratchTakeCore; +} + +impl GLWEToLWESwitchingKeyEncrypt for Module where + Module: ModuleN + + SvpPPolBytesOf + + SvpPPolAlloc + + VecZnxNormalizeTmpBytes + + VecZnxDftBytesOf + + VecZnxAutomorphismInplace + + VecZnxAddScalarInplace + + VecZnxBigNormalize + + VecZnxDftApply + + SvpApplyDftToDftInplace + + VecZnxIdftApplyConsume + + VecZnxNormalize + + VecZnxNormalizeInplace + + VecZnxAddNormal + + VecZnxSub + + VecZnxSubInplace + + VecZnxAddInplace + + SvpPrepare + + VecZnxSwitchRing + + ScratchAvailable + + ScratchAvailableImpl + + ScratchTakeBasic + + ScratchTakeCore + + VecZnxFillUniform + + VecZnxFillUniformImpl + + GLWESwitchingKeyEncryptSk +{ + fn glwe_to_lwe_switching_key_encrypt_sk_tmp_bytes(&self, infos: &A) -> usize + where + A: GGLWEInfos + { + GLWESecretPrepared::bytes_of(self, infos.rank_in()) + + (GLWESwitchingKey::encrypt_sk_tmp_bytes(self, infos) | GLWESecret::bytes_of(self, infos.rank_in())) + } + + fn glwe_to_lwe_switching_key_encrypt_sk( + &self, + res: &mut R, + sk_lwe: &LWESecret, + sk_glwe: &GLWESecret, + source_xa: &mut Source, + source_xe: &mut Source, + scratch: &mut Scratch, + ) where + R: GLWEToLWESwitchingKeyToMut, + Scratch: ScratchAvailable + ScratchTakeCore, + { + + let res: &mut GLWEToLWESwitchingKey<&mut [u8]> = &mut res.to_mut(); + #[cfg(debug_assertions)] { - assert!(sk_lwe.n().0 <= module.n() as u32); + assert!(sk_lwe.n().0 <= self.n() as u32); } - let (mut sk_lwe_as_glwe, scratch_1) = scratch.take_glwe_secret(module, Rank(1)); + let (mut sk_lwe_as_glwe, scratch_1) = scratch.take_glwe_secret(self, Rank(1)); sk_lwe_as_glwe.data.zero(); sk_lwe_as_glwe.data.at_mut(0, 0)[..sk_lwe.n().into()].copy_from_slice(sk_lwe.data.at(0, 0)); - module.vec_znx_automorphism_inplace(-1, &mut sk_lwe_as_glwe.data.as_vec_znx_mut(), 0, scratch_1); + self.vec_znx_automorphism_inplace(-1, &mut sk_lwe_as_glwe.data.as_vec_znx_mut(), 0, scratch_1); - self.0.encrypt_sk( - module, + res.0.encrypt_sk( + self, sk_glwe, &sk_lwe_as_glwe, source_xa, source_xe, scratch_1, - ); + ); } -} +} \ No newline at end of file diff --git a/poulpy-core/src/encryption/lwe_ksk.rs b/poulpy-core/src/encryption/lwe_ksk.rs index 063240e..19c5fc2 100644 --- a/poulpy-core/src/encryption/lwe_ksk.rs +++ b/poulpy-core/src/encryption/lwe_ksk.rs @@ -15,6 +15,7 @@ use crate::{ GGLWEInfos, GLWESecret, GLWESwitchingKey, LWEInfos, LWESecret, LWESwitchingKey, Rank, prepared::{GLWESecretPrepared, GLWESecretPreparedAlloc}, }, + encryption::gglwe_ksk::GLWESwitchingKeyEncryptSk, ScratchTakeCore, }; @@ -27,30 +28,6 @@ impl LWESwitchingKey> { module.lwe_switching_key_encrypt_sk_tmp_bytes(infos) } - // pub fn encrypt_sk_tmp_bytes(module: &Module, infos: &A) -> usize - // where - // A: GGLWEInfos, - // Module: ModuleN + SvpPPolBytesOf + SvpPPolAlloc + VecZnxNormalizeTmpBytes + VecZnxDftBytesOf + VecZnxNormalizeTmpBytes, - // { - // debug_assert_eq!( - // infos.dsize().0, - // 1, - // "dsize > 1 is not supported for LWESwitchingKey" - // ); - // debug_assert_eq!( - // infos.rank_in().0, - // 1, - // "rank_in > 1 is not supported for LWESwitchingKey" - // ); - // debug_assert_eq!( - // infos.rank_out().0, - // 1, - // "rank_out > 1 is not supported for LWESwitchingKey" - // ); - // GLWESecret::bytes_of(module, Rank(1)) - // + GLWESecretPrepared::bytes_of(module, Rank(1)) - // + GLWESwitchingKey::encrypt_sk_tmp_bytes(module, infos) - // } } impl LWESwitchingKey { @@ -171,6 +148,8 @@ impl LWESwitchingKeyEncrypt for Module where + VecZnxSwitchRing + GLWESecretAlloc + GLWESecretPreparedAlloc + + GLWESwitchingKeyEncryptSk + , { fn lwe_switching_key_encrypt_sk_tmp_bytes(&self, infos: &A) -> usize where diff --git a/poulpy-core/src/encryption/lwe_to_glwe_ksk.rs b/poulpy-core/src/encryption/lwe_to_glwe_ksk.rs index 32c75fc..a554e24 100644 --- a/poulpy-core/src/encryption/lwe_to_glwe_ksk.rs +++ b/poulpy-core/src/encryption/lwe_to_glwe_ksk.rs @@ -4,81 +4,227 @@ use poulpy_hal::{ VecZnxAddScalarInplace, VecZnxAutomorphismInplace, VecZnxBigNormalize, VecZnxDftApply, VecZnxDftBytesOf, VecZnxFillUniform, VecZnxIdftApplyConsume, VecZnxNormalize, VecZnxNormalizeInplace, VecZnxNormalizeTmpBytes, VecZnxSub, VecZnxSubInplace, VecZnxSwitchRing, + ScratchTakeBasic, }, layouts::{Backend, DataMut, DataRef, Module, Scratch, ZnxView, ZnxViewMut}, + oep::{ScratchAvailableImpl}, source::Source, }; use crate::{ + layouts::{GGLWEInfos, GLWESecret, GLWESwitchingKey, LWEInfos, LWESecret, LWEToGLWESwitchingKey, LWEToGLWESwitchingKeyToMut, Rank}, ScratchTakeCore, - layouts::{GGLWEInfos, GLWESecret, GLWESwitchingKey, LWEInfos, LWESecret, LWEToGLWESwitchingKey, Rank}, + encryption::gglwe_ksk::GLWESwitchingKeyEncryptSk, }; impl LWEToGLWESwitchingKey> { - pub fn encrypt_sk_tmp_bytes(module: &Module, infos: &A) -> usize + pub fn encrypt_sk_tmp_bytes(module: &M, infos: &A) -> usize where A: GGLWEInfos, - Module: ModuleN + SvpPPolBytesOf + VecZnxNormalizeTmpBytes + VecZnxDftBytesOf + VecZnxNormalizeTmpBytes + SvpPPolAlloc, + M: LWEToGLWESwitchingKeyEncrypt, + { + module.lwe_to_glwe_switching_key_encrypt_sk_tmp_bytes(infos) + } + + // pub fn encrypt_sk_tmp_bytes(module: &Module, infos: &A) -> usize + // where + // A: GGLWEInfos, + // Module: ModuleN + SvpPPolBytesOf + VecZnxNormalizeTmpBytes + VecZnxDftBytesOf + VecZnxNormalizeTmpBytes + SvpPPolAlloc, + // { + // debug_assert_eq!( + // infos.rank_in(), + // Rank(1), + // "rank_in != 1 is not supported for LWEToGLWESwitchingKey" + // ); + // GLWESwitchingKey::encrypt_sk_tmp_bytes(module, infos) + // + GLWESecret::bytes_of(module, infos.rank_in()) + // } +} + +impl LWEToGLWESwitchingKey { + pub fn encrypt_sk( + &mut self, + module: &M, + sk_lwe: &LWESecret, + sk_glwe: &GLWESecret, + source_xa: &mut Source, + source_xe: &mut Source, + scratch: &mut Scratch, + ) where + M: LWEToGLWESwitchingKeyEncrypt, + DLwe: DataRef, + DGlwe: DataRef, + Scratch: ScratchAvailable + ScratchTakeCore, + { + module.lwe_to_glwe_switching_key_encrypt_sk(self, sk_lwe, sk_glwe, source_xa, source_xe, scratch); + } + // #[allow(clippy::too_many_arguments)] + // pub fn encrypt_sk( + // &mut self, + // module: &Module, + // sk_lwe: &LWESecret, + // sk_glwe: &GLWESecret, + // source_xa: &mut Source, + // source_xe: &mut Source, + // scratch: &mut Scratch, + // ) where + // DLwe: DataRef, + // DGlwe: DataRef, + // Module: ModuleN + // + VecZnxAutomorphismInplace + // + VecZnxAddScalarInplace + // + VecZnxDftBytesOf + // + VecZnxBigNormalize + // + VecZnxDftApply + // + SvpApplyDftToDftInplace + // + VecZnxIdftApplyConsume + // + VecZnxNormalizeTmpBytes + // + VecZnxFillUniform + // + VecZnxSubInplace + // + VecZnxAddInplace + // + VecZnxNormalizeInplace + // + VecZnxAddNormal + // + VecZnxNormalize + // + VecZnxSub + // + SvpPrepare + // + VecZnxSwitchRing + // + SvpPPolBytesOf + // + SvpPPolAlloc, + // Scratch: ScratchAvailable + ScratchTakeCore, + // { + // #[cfg(debug_assertions)] + // { + // use crate::layouts::LWEInfos; + + // assert!(sk_lwe.n().0 <= module.n() as u32); + // } + + // let (mut sk_lwe_as_glwe, scratch_1) = scratch.take_glwe_secret(module, Rank(1)); + // sk_lwe_as_glwe.data.at_mut(0, 0)[..sk_lwe.n().into()].copy_from_slice(sk_lwe.data.at(0, 0)); + // sk_lwe_as_glwe.data.at_mut(0, 0)[sk_lwe.n().into()..].fill(0); + // module.vec_znx_automorphism_inplace(-1, &mut sk_lwe_as_glwe.data.as_vec_znx_mut(), 0, scratch_1); + + // self.0.encrypt_sk( + // module, + // &sk_lwe_as_glwe, + // sk_glwe, + // source_xa, + // source_xe, + // scratch_1, + // ); + // } +} + +pub trait LWEToGLWESwitchingKeyEncrypt +where + Self: Sized + + ModuleN + + SvpPPolBytesOf + + SvpPPolAlloc + + VecZnxNormalizeTmpBytes + + VecZnxDftBytesOf + + VecZnxAutomorphismInplace + + VecZnxAddScalarInplace + + VecZnxBigNormalize + + VecZnxDftApply + + SvpApplyDftToDftInplace + + VecZnxIdftApplyConsume + + VecZnxNormalize + + VecZnxNormalizeInplace + + VecZnxAddNormal + + VecZnxSub + + VecZnxSubInplace + + VecZnxAddInplace + + SvpPrepare + + VecZnxSwitchRing + + ScratchAvailable + + ScratchTakeBasic + + ScratchAvailableImpl +{ + fn lwe_to_glwe_switching_key_encrypt_sk_tmp_bytes(&self, infos: &A) -> usize + where + A: GGLWEInfos; + + fn lwe_to_glwe_switching_key_encrypt_sk( + &self, + res: &mut R, + sk_lwe: &LWESecret, + sk_glwe: &GLWESecret, + source_xa: &mut Source, + source_xe: &mut Source, + scratch: &mut Scratch, + ) where + R: LWEToGLWESwitchingKeyToMut, + Scratch: ScratchAvailable + ScratchTakeCore; +} + +impl LWEToGLWESwitchingKeyEncrypt for Module where + Module: ModuleN + + SvpPPolBytesOf + + SvpPPolAlloc + + VecZnxNormalizeTmpBytes + + VecZnxDftBytesOf + + VecZnxAutomorphismInplace + + VecZnxAddScalarInplace + + VecZnxBigNormalize + + VecZnxDftApply + + SvpApplyDftToDftInplace + + VecZnxIdftApplyConsume + + VecZnxNormalize + + VecZnxNormalizeInplace + + VecZnxAddNormal + + VecZnxSub + + VecZnxSubInplace + + VecZnxAddInplace + + SvpPrepare + + VecZnxSwitchRing + + ScratchAvailable + + ScratchAvailableImpl + + ScratchTakeBasic + + ScratchTakeCore + + GLWESwitchingKeyEncryptSk +{ + fn lwe_to_glwe_switching_key_encrypt_sk_tmp_bytes(&self, infos: &A) -> usize + where + A: GGLWEInfos { debug_assert_eq!( infos.rank_in(), Rank(1), "rank_in != 1 is not supported for LWEToGLWESwitchingKey" ); - GLWESwitchingKey::encrypt_sk_tmp_bytes(module, infos) - + GLWESecret::bytes_of(module, infos.rank_in()) + GLWESwitchingKey::encrypt_sk_tmp_bytes(self, infos) + + GLWESecret::bytes_of(self, infos.rank_in()) } -} -impl LWEToGLWESwitchingKey { - #[allow(clippy::too_many_arguments)] - pub fn encrypt_sk( - &mut self, - module: &Module, + fn lwe_to_glwe_switching_key_encrypt_sk( + &self, + res: &mut R, sk_lwe: &LWESecret, - sk_glwe: &GLWESecret, + sk_glwe: &GLWESecret, source_xa: &mut Source, source_xe: &mut Source, - scratch: &mut Scratch, - ) where - DLwe: DataRef, - DGlwe: DataRef, - Module: ModuleN - + VecZnxAutomorphismInplace - + VecZnxAddScalarInplace - + VecZnxDftBytesOf - + VecZnxBigNormalize - + VecZnxDftApply - + SvpApplyDftToDftInplace - + VecZnxIdftApplyConsume - + VecZnxNormalizeTmpBytes - + VecZnxFillUniform - + VecZnxSubInplace - + VecZnxAddInplace - + VecZnxNormalizeInplace - + VecZnxAddNormal - + VecZnxNormalize - + VecZnxSub - + SvpPrepare - + VecZnxSwitchRing - + SvpPPolBytesOf - + SvpPPolAlloc, - Scratch: ScratchAvailable + ScratchTakeCore, + scratch: &mut Scratch, + ) where + R: LWEToGLWESwitchingKeyToMut, + Scratch: ScratchAvailable + ScratchTakeCore, { + let res: &mut LWEToGLWESwitchingKey<&mut [u8]> = &mut res.to_mut(); + #[cfg(debug_assertions)] { use crate::layouts::LWEInfos; - assert!(sk_lwe.n().0 <= module.n() as u32); + assert!(sk_lwe.n().0 <= self.n() as u32); } - let (mut sk_lwe_as_glwe, scratch_1) = scratch.take_glwe_secret(module, Rank(1)); + let (mut sk_lwe_as_glwe, scratch_1) = scratch.take_glwe_secret(self, Rank(1)); sk_lwe_as_glwe.data.at_mut(0, 0)[..sk_lwe.n().into()].copy_from_slice(sk_lwe.data.at(0, 0)); sk_lwe_as_glwe.data.at_mut(0, 0)[sk_lwe.n().into()..].fill(0); - module.vec_znx_automorphism_inplace(-1, &mut sk_lwe_as_glwe.data.as_vec_znx_mut(), 0, scratch_1); + self.vec_znx_automorphism_inplace(-1, &mut sk_lwe_as_glwe.data.as_vec_znx_mut(), 0, scratch_1); - self.0.encrypt_sk( - module, + res.0.encrypt_sk( + self, &sk_lwe_as_glwe, sk_glwe, source_xa, @@ -86,4 +232,4 @@ impl LWEToGLWESwitchingKey { scratch_1, ); } -} +} \ No newline at end of file