arnaucube
arnaucube/poulpyPublic Self-hosted repository
non-compressed finished
Rasoul Akhavan Mahdavi rasoul.akhavan.mahdavi@uwaterloo.ca
Thu, 16 Oct 2025 23:49:33 -0400
commit

1247d3e4b724c023d1fc68710cd3dbbbc09a0df2

parent

a5600593cacee6fd76ea86fd83806aec0422b1bf

M poulpy-core/src/encryption/gglwe_atk.rs → poulpy-core/src/encryption/gglwe_atk.rs

@@ -5,58 +5,36 @@ VecZnxAddScalarInplace, VecZnxAutomorphism, VecZnxBigNormalize, VecZnxDftApply, VecZnxDftBytesOf, VecZnxFillUniform,

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<Vec<u8>> { - pub fn encrypt_sk_tmp_bytes<BE: Backend, A>(module: &Module<BE>, infos: &A) -> usize + + pub fn encrypt_sk_tmp_bytes<M, A, BE: Backend>(module: &M, infos: &A) -> usize where A: GGLWEInfos, - Module<BE>: ModuleN + SvpPPolBytesOf + VecZnxNormalizeTmpBytes + VecZnxDftBytesOf + VecZnxNormalizeTmpBytes + SvpPPolAlloc<BE>, + M: GGLWEAutomorphismKeyEncryptSk<BE> { - 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<BE: Backend, A>(module: &Module<BE>, _infos: &A) -> usize + pub fn encrypt_pk_tmp_bytes<M, A, BE: Backend>(module: &M, infos: &A) -> usize where A: GGLWEInfos, + M: GGLWEAutomorphismKeyEncryptPk<BE> { - 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<BE: Backend> { - fn gglwe_automorphism_key_encrypt_sk<A, B>( - &self, - res: &mut A, - p: i64, - sk: &B, - source_xa: &mut Source, - source_xe: &mut Source, - scratch: &mut Scratch<BE>, - ) where - A: AutomorphismKeyToMut, - B: GLWESecretToRef; -} - impl<DM: DataMut> AutomorphismKey<DM> where Self: AutomorphismKeyToMut,

@@ -75,6 +53,24 @@ Module<BE>: GGLWEAutomorphismKeyEncryptSk<BE>,

{ module.gglwe_automorphism_key_encrypt_sk(self, p, sk, source_xa, source_xe, scratch); } +} + +pub trait GGLWEAutomorphismKeyEncryptSk<BE: Backend> { + fn gglwe_automorphism_key_encrypt_sk_tmp_bytes<A>(&self, infos: &A) -> usize + where + A: GGLWEInfos; + + fn gglwe_automorphism_key_encrypt_sk<A, B>( + &self, + res: &mut A, + p: i64, + sk: &B, + source_xa: &mut Source, + source_xe: &mut Source, + scratch: &mut Scratch<BE>, + ) where + A: AutomorphismKeyToMut, + B: GLWESecretToRef; } impl<BE: Backend> GGLWEAutomorphismKeyEncryptSk<BE> for Module<BE>

@@ -99,9 +95,22 @@ + VecZnxSwitchRing

+ SvpPPolBytesOf + VecZnxAutomorphism + SvpPPolAlloc<BE> - + SvpPPolBytesOf, + + GaloisElement, Scratch<BE>: ScratchAvailable + ScratchTakeCore<BE>, { + + fn gglwe_automorphism_key_encrypt_sk_tmp_bytes<A>(&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<A, B>( &self, res: &mut A,

@@ -150,5 +159,48 @@ res.key

.encrypt_sk(self, sk, &sk_out, source_xa, source_xe, scratch_1); res.p = p; + } +} + + +pub trait GGLWEAutomorphismKeyEncryptPk<BE: Backend> { + fn gglwe_automorphism_key_encrypt_pk_tmp_bytes<A>(&self, infos: &A) -> usize + where + A: GGLWEInfos; + +} + +impl<BE: Backend> GGLWEAutomorphismKeyEncryptPk<BE> for Module<BE> +where + Module<BE>: ModuleN + + VecZnxAddScalarInplace + + VecZnxDftBytesOf + + VecZnxBigNormalize<BE> + + VecZnxDftApply<BE> + + SvpApplyDftToDftInplace<BE> + + VecZnxIdftApplyConsume<BE> + + VecZnxNormalizeTmpBytes + + VecZnxFillUniform + + VecZnxSubInplace + + VecZnxAddInplace + + VecZnxNormalizeInplace<BE> + + VecZnxAddNormal + + VecZnxNormalize<BE> + + VecZnxSub + + SvpPPolBytesOf + + SvpPPolAlloc<BE>, + Scratch<BE>: ScratchAvailable + ScratchTakeCore<BE>, +{ + + fn gglwe_automorphism_key_encrypt_pk_tmp_bytes<A>(&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) } }
M poulpy-core/src/encryption/gglwe_ct.rs → poulpy-core/src/encryption/gglwe_ct.rs

@@ -64,7 +64,6 @@ + VecZnxNormalizeTmpBytes

+ VecZnxDftBytesOf + VecZnxAddScalarInplace + VecZnxNormalizeInplace<B>, - // + SvpPPolAllocBytesImpl<B>, Scratch<B>: ScratchAvailable + ScratchTakeCore<B>, { fn gglwe_encrypt_sk_tmp_bytes<A>(&self, infos: &A) -> usize
M poulpy-core/src/encryption/gglwe_ksk.rs → poulpy-core/src/encryption/gglwe_ksk.rs

@@ -12,7 +12,7 @@

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,82 +26,205 @@ {

module.glwe_switching_key_encrypt_sk_tmp_bytes(infos) } - pub fn encrypt_pk_tmp_bytes<M, A, BE: Backend>(module: &M, infos: &A) -> usize where A: GGLWEInfos, + M: GLWESwitchingKeyEncryptPk<BE>, + { + module.glwe_switching_key_encrypt_pk_tmp_bytes(infos) + } +} + +impl<DataSelf: DataMut> GLWESwitchingKey<DataSelf> { + + pub fn encrypt_sk<M, DataSkIn: DataRef, DataSkOut: DataRef, BE: Backend>( + &mut self, + module: &M, + sk_in: &GLWESecret<DataSkIn>, + sk_out: &GLWESecret<DataSkOut>, + source_xa: &mut Source, + source_xe: &mut Source, + scratch: &mut Scratch<BE>, + ) where M: GLWESwitchingKeyEncryptSk<BE>, + Scratch<BE>: ScratchAvailable + ScratchTakeCore<BE>, { - module.glwe_switching_key_encrypt_pk_tmp_bytes(infos) + module.glwe_switching_key_encrypt_sk(self, sk_in, sk_out, source_xa, source_xe, scratch); } - // pub fn encrypt_sk_tmp_bytes<B: Backend, A>(module: &Module<B>, infos: &A) -> usize - // where - // A: GGLWEInfos, - // Module<B>: ModuleN + SvpPPolBytesOf + VecZnxNormalizeTmpBytes + VecZnxDftBytesOf + VecZnxNormalizeTmpBytes + SvpPPolAlloc<B>, - // { - // (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<B: Backend, A>(module: &Module<B>, _infos: &A) -> usize - // where - // A: GGLWEInfos, + // #[allow(clippy::too_many_arguments)] + // pub fn encrypt_sk<DataSkIn: DataRef, DataSkOut: DataRef, B: Backend>( + // &mut self, + // module: &Module<B>, + // sk_in: &GLWESecret<DataSkIn>, + // sk_out: &GLWESecret<DataSkOut>, + // source_xa: &mut Source, + // source_xe: &mut Source, + // scratch: &mut Scratch<B>, + // ) where + // Module<B>: ModuleN + // + VecZnxAddScalarInplace + // + VecZnxDftBytesOf + // + VecZnxBigNormalize<B> + // + VecZnxDftApply<B> + // + SvpApplyDftToDftInplace<B> + // + VecZnxIdftApplyConsume<B> + // + VecZnxNormalizeTmpBytes + // + VecZnxFillUniform + // + VecZnxSubInplace + // + VecZnxAddInplace + // + VecZnxNormalizeInplace<B> + // + VecZnxAddNormal + // + VecZnxNormalize<B> + // + VecZnxSub + // + SvpPrepare<B> + // + VecZnxSwitchRing + // + SvpPPolBytesOf + // + SvpPPolAlloc<B>, + // Scratch<B>: ScratchAvailable + ScratchTakeBasic + ScratchTakeCore<B>, // { - // GGLWE::encrypt_pk_tmp_bytes(module, _infos) + // #[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(); // } } -impl<DataSelf: DataMut> GLWESwitchingKey<DataSelf> { - #[allow(clippy::too_many_arguments)] - pub fn encrypt_sk<DataSkIn: DataRef, DataSkOut: DataRef, B: Backend>( - &mut self, - module: &Module<B>, + +pub trait GLWESwitchingKeyEncryptSk<BE: Backend> +where + Self: Sized + + ModuleN + + SvpPPolBytesOf + + VecZnxDftBytesOf + + VecZnxNormalizeTmpBytes + + SvpPPolAlloc<BE> + + GGLWEEncryptSk<BE>, +{ + fn glwe_switching_key_encrypt_sk_tmp_bytes<A>(&self, infos: &A) -> usize + where + A: GGLWEInfos; + + fn glwe_switching_key_encrypt_sk<R, DataSkIn, DataSkOut>( + &self, + res: &mut R, sk_in: &GLWESecret<DataSkIn>, sk_out: &GLWESecret<DataSkOut>, source_xa: &mut Source, source_xe: &mut Source, - scratch: &mut Scratch<B>, - ) where - Module<B>: ModuleN - + VecZnxAddScalarInplace - + VecZnxDftBytesOf - + VecZnxBigNormalize<B> - + VecZnxDftApply<B> - + SvpApplyDftToDftInplace<B> - + VecZnxIdftApplyConsume<B> - + VecZnxNormalizeTmpBytes - + VecZnxFillUniform - + VecZnxSubInplace - + VecZnxAddInplace - + VecZnxNormalizeInplace<B> - + VecZnxAddNormal - + VecZnxNormalize<B> - + VecZnxSub - + SvpPrepare<B> - + VecZnxSwitchRing - + SvpPPolBytesOf - + SvpPPolAlloc<B>, - Scratch<B>: ScratchAvailable + ScratchTakeBasic + ScratchTakeCore<B>, + scratch: &mut Scratch<BE>, + ) + where + R: GLWESwitchingKeyToMut, + DataSkIn: DataRef, + DataSkOut: DataRef, + Scratch<BE>: ScratchAvailable + ScratchTakeCore<BE>; + +} + +impl<BE: Backend> GLWESwitchingKeyEncryptSk<BE> for Module<BE> where + Self: ModuleN + + SvpPPolBytesOf + + VecZnxDftBytesOf + + VecZnxNormalizeTmpBytes + + SvpPPolAlloc<BE> + + GGLWEEncryptSk<BE> + + VecZnxSwitchRing + + SvpPrepare<BE> + + VecZnxIdftApplyConsume<BE> + + VecZnxNormalize<BE> + + VecZnxNormalizeInplace<BE> + + VecZnxAddInplace + + VecZnxAddNormal + + VecZnxSub +{ + + fn glwe_switching_key_encrypt_sk_tmp_bytes<A>(&self, infos: &A) -> usize + where + A: GGLWEInfos, { + (GGLWE::encrypt_sk_tmp_bytes(self, infos) | ScalarZnx::bytes_of(self.n(), 1)) + + ScalarZnx::bytes_of(self.n(), infos.rank_in().into()) + + GLWESecretPrepared::bytes_of_from_infos(self, &infos.glwe_layout()) + } + + fn glwe_switching_key_encrypt_sk<R, DataSkIn, DataSkOut>( + &self, + res: &mut R, + sk_in: &GLWESecret<DataSkIn>, + sk_out: &GLWESecret<DataSkOut>, + source_xa: &mut Source, + source_xe: &mut Source, + scratch: &mut Scratch<BE>, + ) + where + R: GLWESwitchingKeyToMut, + DataSkIn: DataRef, + DataSkOut: DataRef, + Scratch<BE>: ScratchAvailable + ScratchTakeCore<BE>, + { + + 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 <= module.n() as u32); - assert!(sk_out.n().0 <= module.n() as u32); + 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(module, self), + scratch.available() >= GLWESwitchingKey::encrypt_sk_tmp_bytes(self, res), "scratch.available()={} < GLWESwitchingKey::encrypt_sk_tmp_bytes={}", scratch.available(), - GLWESwitchingKey::encrypt_sk_tmp_bytes(module, self) + GLWESwitchingKey::encrypt_sk_tmp_bytes(self, res) ) } - let n: usize = sk_in.n().max(sk_out.n()).into(); + // 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()); + let (mut sk_in_tmp, scratch_1) = scratch.take_scalar_znx(self, sk_in.rank().into()); (0..sk_in.rank().into()).for_each(|i| { - module.vec_znx_switch_ring( + self.vec_znx_switch_ring( &mut sk_in_tmp.as_vec_znx_mut(), i, &sk_in.data.as_vec_znx(),

@@ -109,30 +232,30 @@ i,

); }); - let (mut sk_out_tmp, scratch_2) = scratch_1.take_glwe_secret_prepared(module, sk_out.rank()); + 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(module, 1); + let (mut tmp, _) = scratch_2.take_scalar_znx(self, 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.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); }); } - self.key.encrypt_sk( - module, + res.key.encrypt_sk( + self, &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(); - } -} + res.sk_in_n = sk_in.n().into(); + res.sk_out_n = sk_out.n().into(); + } +} -pub trait GLWESwitchingKeyEncryptSk<BE: Backend> +pub trait GLWESwitchingKeyEncryptPk<BE: Backend> where Self: Sized + ModuleN

@@ -142,16 +265,13 @@ + VecZnxNormalizeTmpBytes

+ SvpPPolAlloc<BE> + GGLWEEncryptSk<BE>, { - fn glwe_switching_key_encrypt_sk_tmp_bytes<A>(&self, infos: &A) -> usize - where - A: GGLWEInfos; fn glwe_switching_key_encrypt_pk_tmp_bytes<A>(&self, infos: &A) -> usize where A: GGLWEInfos; } -impl<BE: Backend> GLWESwitchingKeyEncryptSk<BE> for Module<BE> where +impl<BE: Backend> GLWESwitchingKeyEncryptPk<BE> for Module<BE> where Self: ModuleN + SvpPPolBytesOf + VecZnxDftBytesOf

@@ -160,20 +280,10 @@ + SvpPPolAlloc<BE>

+ GGLWEEncryptSk<BE>, { - fn glwe_switching_key_encrypt_sk_tmp_bytes<A>(&self, infos: &A) -> usize - where - A: GGLWEInfos, - { - (GGLWE::encrypt_sk_tmp_bytes(self, infos) | ScalarZnx::bytes_of(self.n(), 1)) - + ScalarZnx::bytes_of(self.n(), infos.rank_in().into()) - + GLWESecretPrepared::bytes_of_from_infos(self, &infos.glwe_layout()) - } - fn glwe_switching_key_encrypt_pk_tmp_bytes<A>(&self, infos: &A) -> usize where A: GGLWEInfos, { GGLWE::encrypt_pk_tmp_bytes(self, infos) } - }
M poulpy-core/src/encryption/gglwe_tsk.rs → 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<Vec<u8>> { - pub fn encrypt_sk_tmp_bytes<B: Backend, A>(module: &Module<B>, infos: &A) -> usize + pub fn encrypt_sk_tmp_bytes<M, A, BE: Backend>(module: &M, infos: &A) -> usize where A: GGLWEInfos, - Module<B>: ModuleN + SvpPPolBytesOf + SvpPPolAlloc<B> + VecZnxNormalizeTmpBytes + VecZnxDftBytesOf + VecZnxNormalizeTmpBytes + VecZnxBigBytesOf, + M: GGLWETensorKeyEncryptSk<BE> { - 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<B: Backend, A>(module: &Module<B>, infos: &A) -> usize + // where + // A: GGLWEInfos, + // Module<B>: ModuleN + SvpPPolBytesOf + SvpPPolAlloc<B> + 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<DataSelf: DataMut> TensorKey<DataSelf> { - pub fn encrypt_sk<DataSk: DataRef, B: Backend>( + pub fn encrypt_sk<M, DataSk: DataRef, BE: Backend>( &mut self, - module: &Module<B>, + module: &M, sk: &GLWESecret<DataSk>, source_xa: &mut Source, source_xe: &mut Source, - scratch: &mut Scratch<B>, + scratch: &mut Scratch<BE>, ) where + M: GGLWETensorKeyEncryptSk<BE>, GLWESecret<DataSk>: GetDist, - Module<B>: ModuleN - + SvpApplyDftToDft<B> - + VecZnxIdftApplyTmpA<B> - + VecZnxAddScalarInplace - + VecZnxDftBytesOf - + VecZnxBigNormalize<B> - + VecZnxDftApply<B> - + SvpApplyDftToDftInplace<B> - + VecZnxIdftApplyConsume<B> - + VecZnxNormalizeTmpBytes - + VecZnxFillUniform - + VecZnxSubInplace - + VecZnxAddInplace - + VecZnxNormalizeInplace<B> - + VecZnxAddNormal - + VecZnxNormalize<B> - + VecZnxSub - + SvpPrepare<B> - + VecZnxSwitchRing - + SvpPPolBytesOf - + VecZnxBigAllocBytesImpl<B> - + VecZnxBigBytesOf - + SvpPPolAlloc<B>, - Scratch<B>: ScratchTakeBasic + ScratchTakeCore<B>, + Scratch<BE>: ScratchAvailable + ScratchTakeCore<BE>, { - #[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<DataSk: DataRef, B: Backend>( + // &mut self, + // module: &Module<B>, + // sk: &GLWESecret<DataSk>, + // source_xa: &mut Source, + // source_xe: &mut Source, + // scratch: &mut Scratch<B>, + // ) where + // GLWESecret<DataSk>: GetDist, + // Module<B>: ModuleN + // + SvpApplyDftToDft<B> + // + VecZnxIdftApplyTmpA<B> + // + VecZnxAddScalarInplace + // + VecZnxDftBytesOf + // + VecZnxBigNormalize<B> + // + VecZnxDftApply<B> + // + SvpApplyDftToDftInplace<B> + // + VecZnxIdftApplyConsume<B> + // + VecZnxNormalizeTmpBytes + // + VecZnxFillUniform + // + VecZnxSubInplace + // + VecZnxAddInplace + // + VecZnxNormalizeInplace<B> + // + VecZnxAddNormal + // + VecZnxNormalize<B> + // + VecZnxSub + // + SvpPrepare<B> + // + VecZnxSwitchRing + // + SvpPPolBytesOf + // + VecZnxBigAllocBytesImpl<B> + // + VecZnxBigBytesOf + // + SvpPPolAlloc<B>, + // Scratch<B>: ScratchTakeBasic + ScratchTakeCore<B>, + // { + // #[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<BE: Backend> +where + Self: Sized + + ModuleN + + SvpPPolBytesOf + + SvpPPolAlloc<BE> + + VecZnxNormalizeTmpBytes + + VecZnxDftBytesOf + + VecZnxNormalizeTmpBytes + + VecZnxBigBytesOf, +{ + fn gglwe_tensor_key_encrypt_sk_tmp_bytes<A>(&self, infos: &A) -> usize + where + A: GGLWEInfos; + + fn gglwe_tensor_key_encrypt_sk<R, S>( + &self, + res: &mut R, + sk: &S, + source_xa: &mut Source, + source_xe: &mut Source, + scratch: &mut Scratch<BE>, + ) where + R: TensorKeyToMut, + S: GLWESecretToRef + GetDist; +} + +impl<BE: Backend> GGLWETensorKeyEncryptSk<BE> for Module<BE> where + Module<BE>: ModuleN + + SvpPPolBytesOf + + SvpPPolAlloc<BE> + + VecZnxNormalizeTmpBytes + + VecZnxDftBytesOf + + VecZnxNormalizeTmpBytes + + VecZnxBigBytesOf + + VecZnxAddScalarInplaceImpl<BE> + + VecZnxDftApply<BE> + + VecZnxDftApplyImpl<BE> + + SvpApplyDftToDftImpl<BE> + + GLWESwitchingKeyEncryptSk<BE> + + SvpApplyDftToDft<BE> + + VecZnxIdftApplyTmpAImpl<BE> + + VecZnxBigNormalizeImpl<BE> + + VecZnxIdftApplyTmpA<BE> + + VecZnxBigNormalize<BE> + + VecZnxAddScalarInplaceImpl<BE> + + SvpPrepare<BE>, + Scratch<BE>: ScratchTakeBasic + ScratchTakeCore<BE>, +{ + fn gglwe_tensor_key_encrypt_sk_tmp_bytes<A>(&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<R, S>( + &self, + res: &mut R, + sk: &S, + source_xa: &mut Source, + source_xe: &mut Source, + scratch: &mut Scratch<BE>, + ) 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); }); - }) + }) } -} +}
M poulpy-core/src/encryption/ggsw_ct.rs → poulpy-core/src/encryption/ggsw_ct.rs

@@ -14,20 +14,48 @@ },

}; impl GGSW<Vec<u8>> { - pub fn encrypt_sk_tmp_bytes<B: Backend, A>(module: &Module<B>, infos: &A) -> usize + pub fn encrypt_sk_tmp_bytes<M, A, BE: Backend>(module: &M, infos: &A) -> usize where A: GGSWInfos, - Module<B>: VecZnxNormalizeTmpBytes + VecZnxDftBytesOf, + M: GGSWEncryptSk<BE>, { - 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<B: Backend, A>(module: &Module<B>, infos: &A) -> usize + // where + // A: GGSWInfos, + // Module<B>: 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<DataSelf: DataMut> GGSW<DataSelf> { + #[allow(clippy::too_many_arguments)] + pub fn encrypt_sk<DataPt: DataRef, DataSk: DataRef, B: Backend>( + &mut self, + module: &Module<B>, + pt: &ScalarZnx<DataPt>, + sk: &GLWESecretPrepared<DataSk, B>, + source_xa: &mut Source, + source_xe: &mut Source, + scratch: &mut Scratch<B>, + ) where + Module<B>: GGSWEncryptSk<B>, + { + module.ggsw_encrypt_sk(self, pt, sk, source_xa, source_xe, scratch); } } pub trait GGSWEncryptSk<B: Backend> { + fn ggsw_encrypt_sk_tmp_bytes<A>(&self, infos: &A) -> usize + where + A: GGSWInfos; + fn ggsw_encrypt_sk<R, P, S>( &self, res: &mut R,

@@ -44,9 +72,26 @@ }

impl<B: Backend> GGSWEncryptSk<B> for Module<B> where - Module<B>: ModuleN + GLWEEncryptSkInternal<B> + VecZnxAddScalarInplace + VecZnxNormalizeInplace<B>, + Module<B>: ModuleN + + GLWEEncryptSkInternal<B> + + VecZnxAddScalarInplace + + VecZnxNormalizeInplace<B> + + VecZnxDftBytesOf + + VecZnxNormalizeTmpBytes, Scratch<B>: ScratchTakeCore<B>, { + + fn ggsw_encrypt_sk_tmp_bytes<A>(&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<R, P, S>( &self, res: &mut R,

@@ -104,21 +149,4 @@ );

} } } -} - -impl<DataSelf: DataMut> GGSW<DataSelf> { - #[allow(clippy::too_many_arguments)] - pub fn encrypt_sk<DataPt: DataRef, DataSk: DataRef, B: Backend>( - &mut self, - module: &Module<B>, - pt: &ScalarZnx<DataPt>, - sk: &GLWESecretPrepared<DataSk, B>, - source_xa: &mut Source, - source_xe: &mut Source, - scratch: &mut Scratch<B>, - ) where - Module<B>: GGSWEncryptSk<B>, - { - module.ggsw_encrypt_sk(self, pt, sk, source_xa, source_xe, scratch); - } -} +}
M poulpy-core/src/encryption/glwe_to_lwe_ksk.rs → poulpy-core/src/encryption/glwe_to_lwe_ksk.rs

@@ -4,82 +4,224 @@ ModuleN, ScratchAvailable, SvpApplyDftToDftInplace, SvpPPolAlloc, SvpPPolBytesOf, SvpPrepare, VecZnxAddInplace, VecZnxAddNormal,

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<Vec<u8>> { - pub fn encrypt_sk_tmp_bytes<B: Backend, A>(module: &Module<B>, infos: &A) -> usize + pub fn encrypt_sk_tmp_bytes<M, A, BE: Backend>(module: &M, infos: &A) -> usize where A: GGLWEInfos, - Module<B>: ModuleN + SvpPPolBytesOf + SvpPPolAlloc<B> + VecZnxNormalizeTmpBytes + VecZnxDftBytesOf + VecZnxNormalizeTmpBytes, + M: GLWEToLWESwitchingKeyEncrypt<BE>, { - 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<B: Backend, A>(module: &Module<B>, infos: &A) -> usize + // where + // A: GGLWEInfos, + // Module<B>: ModuleN + SvpPPolBytesOf + SvpPPolAlloc<B> + 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<D: DataMut> GLWEToLWESwitchingKey<D> { - #[allow(clippy::too_many_arguments)] - pub fn encrypt_sk<DLwe, DGlwe, B: Backend>( + pub fn encrypt_sk<M, DLwe, DGlwe, BE: Backend>( &mut self, - module: &Module<B>, + module: &M, sk_lwe: &LWESecret<DLwe>, sk_glwe: &GLWESecret<DGlwe>, source_xa: &mut Source, source_xe: &mut Source, - scratch: &mut Scratch<B>, + scratch: &mut Scratch<BE>, ) where + M: GLWEToLWESwitchingKeyEncrypt<BE>, DLwe: DataRef, DGlwe: DataRef, - Module<B>: ModuleN - + VecZnxAutomorphismInplace<B> - + VecZnxAddScalarInplace - + VecZnxDftBytesOf - + VecZnxBigNormalize<B> - + VecZnxDftApply<B> - + SvpApplyDftToDftInplace<B> - + VecZnxIdftApplyConsume<B> - + VecZnxNormalizeTmpBytes - + VecZnxFillUniform - + VecZnxSubInplace - + VecZnxAddInplace - + VecZnxNormalizeInplace<B> - + VecZnxAddNormal - + VecZnxNormalize<B> - + VecZnxSub - + SvpPrepare<B> - + VecZnxSwitchRing - + SvpPPolBytesOf - + SvpPPolAlloc<B>, - Scratch<B>: ScratchAvailable + ScratchTakeCore<B>, + Scratch<BE>: ScratchAvailable + ScratchTakeCore<BE>, { + 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<DLwe, DGlwe, B: Backend>( + // &mut self, + // module: &Module<B>, + // sk_lwe: &LWESecret<DLwe>, + // sk_glwe: &GLWESecret<DGlwe>, + // source_xa: &mut Source, + // source_xe: &mut Source, + // scratch: &mut Scratch<B>, + // ) where + // DLwe: DataRef, + // DGlwe: DataRef, + // Module<B>: ModuleN + // + VecZnxAutomorphismInplace<B> + // + VecZnxAddScalarInplace + // + VecZnxDftBytesOf + // + VecZnxBigNormalize<B> + // + VecZnxDftApply<B> + // + SvpApplyDftToDftInplace<B> + // + VecZnxIdftApplyConsume<B> + // + VecZnxNormalizeTmpBytes + // + VecZnxFillUniform + // + VecZnxSubInplace + // + VecZnxAddInplace + // + VecZnxNormalizeInplace<B> + // + VecZnxAddNormal + // + VecZnxNormalize<B> + // + VecZnxSub + // + SvpPrepare<B> + // + VecZnxSwitchRing + // + SvpPPolBytesOf + // + SvpPPolAlloc<B>, + // Scratch<B>: ScratchAvailable + ScratchTakeCore<B>, + // { + // #[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<BE: Backend> +where + Self: Sized + + ModuleN + + SvpPPolBytesOf + + SvpPPolAlloc<BE> + + VecZnxNormalizeTmpBytes + + VecZnxDftBytesOf + + VecZnxAutomorphismInplace<BE> + + VecZnxAddScalarInplace + + VecZnxBigNormalize<BE> + + VecZnxDftApply<BE> + + SvpApplyDftToDftInplace<BE> + + VecZnxIdftApplyConsume<BE> + + VecZnxNormalize<BE> + + VecZnxNormalizeInplace<BE> + + VecZnxAddNormal + + VecZnxSub + + VecZnxSubInplace + + VecZnxAddInplace + + SvpPrepare<BE> + + VecZnxSwitchRing + + ScratchAvailable + + ScratchAvailableImpl<BE> + + VecZnxFillUniform + + VecZnxFillUniformImpl<BE> +{ + fn glwe_to_lwe_switching_key_encrypt_sk_tmp_bytes<A>(&self, infos: &A) -> usize + where + A: GGLWEInfos; + + fn glwe_to_lwe_switching_key_encrypt_sk<R, DLwe: DataRef, DataGlwe: DataRef>( + &self, + res: &mut R, + sk_lwe: &LWESecret<DLwe>, + sk_glwe: &GLWESecret<DataGlwe>, + source_xa: &mut Source, + source_xe: &mut Source, + scratch: &mut Scratch<BE>, + ) where + R: GLWEToLWESwitchingKeyToMut, + Scratch<BE>: ScratchAvailable + ScratchTakeCore<BE>; +} + +impl<BE: Backend> GLWEToLWESwitchingKeyEncrypt<BE> for Module<BE> where + Module<BE>: ModuleN + + SvpPPolBytesOf + + SvpPPolAlloc<BE> + + VecZnxNormalizeTmpBytes + + VecZnxDftBytesOf + + VecZnxAutomorphismInplace<BE> + + VecZnxAddScalarInplace + + VecZnxBigNormalize<BE> + + VecZnxDftApply<BE> + + SvpApplyDftToDftInplace<BE> + + VecZnxIdftApplyConsume<BE> + + VecZnxNormalize<BE> + + VecZnxNormalizeInplace<BE> + + VecZnxAddNormal + + VecZnxSub + + VecZnxSubInplace + + VecZnxAddInplace + + SvpPrepare<BE> + + VecZnxSwitchRing + + ScratchAvailable + + ScratchAvailableImpl<BE> + + ScratchTakeBasic + + ScratchTakeCore<BE> + + VecZnxFillUniform + + VecZnxFillUniformImpl<BE> + + GLWESwitchingKeyEncryptSk<BE> +{ + fn glwe_to_lwe_switching_key_encrypt_sk_tmp_bytes<A>(&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<R, DLwe: DataRef, DataGlwe: DataRef>( + &self, + res: &mut R, + sk_lwe: &LWESecret<DLwe>, + sk_glwe: &GLWESecret<DataGlwe>, + source_xa: &mut Source, + source_xe: &mut Source, + scratch: &mut Scratch<BE>, + ) where + R: GLWEToLWESwitchingKeyToMut, + Scratch<BE>: ScratchAvailable + ScratchTakeCore<BE>, + { + + 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, - ); + ); } -} +}
M poulpy-core/src/encryption/lwe_ksk.rs → poulpy-core/src/encryption/lwe_ksk.rs

@@ -15,6 +15,7 @@ GLWESecretAlloc,

GGLWEInfos, GLWESecret, GLWESwitchingKey, LWEInfos, LWESecret, LWESwitchingKey, Rank, prepared::{GLWESecretPrepared, GLWESecretPreparedAlloc}, }, + encryption::gglwe_ksk::GLWESwitchingKeyEncryptSk, ScratchTakeCore, };

@@ -27,30 +28,6 @@ {

module.lwe_switching_key_encrypt_sk_tmp_bytes(infos) } - // pub fn encrypt_sk_tmp_bytes<B: Backend, A>(module: &Module<B>, infos: &A) -> usize - // where - // A: GGLWEInfos, - // Module<B>: ModuleN + SvpPPolBytesOf + SvpPPolAlloc<B> + 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<D: DataMut> LWESwitchingKey<D> {

@@ -171,6 +148,8 @@ + SvpPrepare<BE>

+ VecZnxSwitchRing + GLWESecretAlloc + GLWESecretPreparedAlloc<BE> + + GLWESwitchingKeyEncryptSk<BE> + , { fn lwe_switching_key_encrypt_sk_tmp_bytes<A>(&self, infos: &A) -> usize where
M poulpy-core/src/encryption/lwe_to_glwe_ksk.rs → poulpy-core/src/encryption/lwe_to_glwe_ksk.rs

@@ -4,81 +4,227 @@ ModuleN, ScratchAvailable, SvpApplyDftToDftInplace, SvpPPolAlloc, SvpPPolBytesOf, SvpPrepare, VecZnxAddInplace, VecZnxAddNormal,

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<Vec<u8>> { - pub fn encrypt_sk_tmp_bytes<B: Backend, A>(module: &Module<B>, infos: &A) -> usize + pub fn encrypt_sk_tmp_bytes<M, A, BE: Backend>(module: &M, infos: &A) -> usize where A: GGLWEInfos, - Module<B>: ModuleN + SvpPPolBytesOf + VecZnxNormalizeTmpBytes + VecZnxDftBytesOf + VecZnxNormalizeTmpBytes + SvpPPolAlloc<B>, + M: LWEToGLWESwitchingKeyEncrypt<BE>, { - 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()) + module.lwe_to_glwe_switching_key_encrypt_sk_tmp_bytes(infos) } + + // pub fn encrypt_sk_tmp_bytes<B: Backend, A>(module: &Module<B>, infos: &A) -> usize + // where + // A: GGLWEInfos, + // Module<B>: ModuleN + SvpPPolBytesOf + VecZnxNormalizeTmpBytes + VecZnxDftBytesOf + VecZnxNormalizeTmpBytes + SvpPPolAlloc<B>, + // { + // 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<D: DataMut> LWEToGLWESwitchingKey<D> { - #[allow(clippy::too_many_arguments)] - pub fn encrypt_sk<DLwe, DGlwe, B: Backend>( + pub fn encrypt_sk<M, DLwe, DGlwe, BE: Backend>( &mut self, - module: &Module<B>, + module: &M, sk_lwe: &LWESecret<DLwe>, sk_glwe: &GLWESecret<DGlwe>, source_xa: &mut Source, source_xe: &mut Source, - scratch: &mut Scratch<B>, + scratch: &mut Scratch<BE>, ) where + M: LWEToGLWESwitchingKeyEncrypt<BE>, DLwe: DataRef, DGlwe: DataRef, - Module<B>: ModuleN - + VecZnxAutomorphismInplace<B> - + VecZnxAddScalarInplace - + VecZnxDftBytesOf - + VecZnxBigNormalize<B> - + VecZnxDftApply<B> - + SvpApplyDftToDftInplace<B> - + VecZnxIdftApplyConsume<B> - + VecZnxNormalizeTmpBytes - + VecZnxFillUniform - + VecZnxSubInplace - + VecZnxAddInplace - + VecZnxNormalizeInplace<B> - + VecZnxAddNormal - + VecZnxNormalize<B> - + VecZnxSub - + SvpPrepare<B> - + VecZnxSwitchRing - + SvpPPolBytesOf - + SvpPPolAlloc<B>, - Scratch<B>: ScratchAvailable + ScratchTakeCore<B>, + Scratch<BE>: ScratchAvailable + ScratchTakeCore<BE>, { + 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<DLwe, DGlwe, B: Backend>( + // &mut self, + // module: &Module<B>, + // sk_lwe: &LWESecret<DLwe>, + // sk_glwe: &GLWESecret<DGlwe>, + // source_xa: &mut Source, + // source_xe: &mut Source, + // scratch: &mut Scratch<B>, + // ) where + // DLwe: DataRef, + // DGlwe: DataRef, + // Module<B>: ModuleN + // + VecZnxAutomorphismInplace<B> + // + VecZnxAddScalarInplace + // + VecZnxDftBytesOf + // + VecZnxBigNormalize<B> + // + VecZnxDftApply<B> + // + SvpApplyDftToDftInplace<B> + // + VecZnxIdftApplyConsume<B> + // + VecZnxNormalizeTmpBytes + // + VecZnxFillUniform + // + VecZnxSubInplace + // + VecZnxAddInplace + // + VecZnxNormalizeInplace<B> + // + VecZnxAddNormal + // + VecZnxNormalize<B> + // + VecZnxSub + // + SvpPrepare<B> + // + VecZnxSwitchRing + // + SvpPPolBytesOf + // + SvpPPolAlloc<B>, + // Scratch<B>: ScratchAvailable + ScratchTakeCore<B>, + // { + // #[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<BE: Backend> +where + Self: Sized + + ModuleN + + SvpPPolBytesOf + + SvpPPolAlloc<BE> + + VecZnxNormalizeTmpBytes + + VecZnxDftBytesOf + + VecZnxAutomorphismInplace<BE> + + VecZnxAddScalarInplace + + VecZnxBigNormalize<BE> + + VecZnxDftApply<BE> + + SvpApplyDftToDftInplace<BE> + + VecZnxIdftApplyConsume<BE> + + VecZnxNormalize<BE> + + VecZnxNormalizeInplace<BE> + + VecZnxAddNormal + + VecZnxSub + + VecZnxSubInplace + + VecZnxAddInplace + + SvpPrepare<BE> + + VecZnxSwitchRing + + ScratchAvailable + + ScratchTakeBasic + + ScratchAvailableImpl<BE> +{ + fn lwe_to_glwe_switching_key_encrypt_sk_tmp_bytes<A>(&self, infos: &A) -> usize + where + A: GGLWEInfos; + + fn lwe_to_glwe_switching_key_encrypt_sk<R, DLwe: DataRef, DataGlwe: DataRef>( + &self, + res: &mut R, + sk_lwe: &LWESecret<DLwe>, + sk_glwe: &GLWESecret<DataGlwe>, + source_xa: &mut Source, + source_xe: &mut Source, + scratch: &mut Scratch<BE>, + ) where + R: LWEToGLWESwitchingKeyToMut, + Scratch<BE>: ScratchAvailable + ScratchTakeCore<BE>; +} + +impl<BE: Backend> LWEToGLWESwitchingKeyEncrypt<BE> for Module<BE> where + Module<BE>: ModuleN + + SvpPPolBytesOf + + SvpPPolAlloc<BE> + + VecZnxNormalizeTmpBytes + + VecZnxDftBytesOf + + VecZnxAutomorphismInplace<BE> + + VecZnxAddScalarInplace + + VecZnxBigNormalize<BE> + + VecZnxDftApply<BE> + + SvpApplyDftToDftInplace<BE> + + VecZnxIdftApplyConsume<BE> + + VecZnxNormalize<BE> + + VecZnxNormalizeInplace<BE> + + VecZnxAddNormal + + VecZnxSub + + VecZnxSubInplace + + VecZnxAddInplace + + SvpPrepare<BE> + + VecZnxSwitchRing + + ScratchAvailable + + ScratchAvailableImpl<BE> + + ScratchTakeBasic + + ScratchTakeCore<BE> + + GLWESwitchingKeyEncryptSk<BE> +{ + fn lwe_to_glwe_switching_key_encrypt_sk_tmp_bytes<A>(&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(self, infos) + + GLWESecret::bytes_of(self, infos.rank_in()) + } + + fn lwe_to_glwe_switching_key_encrypt_sk<R, DLwe: DataRef, DataGlwe: DataRef>( + &self, + res: &mut R, + sk_lwe: &LWESecret<DLwe>, + sk_glwe: &GLWESecret<DataGlwe>, + source_xa: &mut Source, + source_xe: &mut Source, + scratch: &mut Scratch<BE>, + ) where + R: LWEToGLWESwitchingKeyToMut, + Scratch<BE>: ScratchAvailable + ScratchTakeCore<BE>, + { + 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 @@ source_xe,

scratch_1, ); } -} +}