arnaucube
arnaucube/poulpyPublic Self-hosted repository
review of encryption
Pro7ech jeanphilippe.bossuat@gmail.com
Fri, 17 Oct 2025 10:51:14 +0200
commit

e0d3ca5cea983fc4eb0d04f4f428e7eabcda8114

parent

0a7e0b0903d63f8c1349931319898c8c004326a5

M poulpy-core/src/decryption/glwe_ct.rs → poulpy-core/src/decryption/glwe_ct.rs

@@ -1,17 +1,14 @@

use poulpy_hal::{ api::{ - ModuleN, ScratchTakeBasic, - SvpApplyDftToDftInplace, VecZnxBigAddInplace, VecZnxBigAddSmallInplace, VecZnxBigNormalize, VecZnxDftApply, VecZnxBigBytesOf, - VecZnxDftBytesOf, VecZnxIdftApplyConsume, VecZnxNormalizeTmpBytes, + ModuleN, ScratchTakeBasic, SvpApplyDftToDftInplace, VecZnxBigAddInplace, VecZnxBigAddSmallInplace, VecZnxBigBytesOf, + VecZnxBigNormalize, VecZnxDftApply, VecZnxDftBytesOf, VecZnxIdftApplyConsume, VecZnxNormalizeTmpBytes, }, layouts::{Backend, DataMut, DataViewMut, Module, Scratch}, }; -use crate::{ - layouts::{ - GLWE, GLWEInfos, GLWEPlaintext, LWEInfos, GLWEToMut, GLWEPlaintextToMut, - prepared::{GLWESecretPreparedToRef, GLWESecretPrepared}, - } +use crate::layouts::{ + GLWE, GLWEInfos, GLWEPlaintext, GLWEPlaintextToMut, GLWEToMut, LWEInfos, + prepared::{GLWESecretPrepared, GLWESecretPreparedToRef}, }; impl GLWE<Vec<u8>> {

@@ -25,12 +22,12 @@ }

} impl<DataSelf: DataMut> GLWE<DataSelf> { - pub fn decrypt<P, S, M, BE: Backend>(&mut self, module: &M, pt: &mut P, sk: &S, scratch: &mut Scratch<BE>) + pub fn decrypt<P, S, M, BE: Backend>(&mut self, module: &M, pt: &mut P, sk: &S, scratch: &mut Scratch<BE>) where P: GLWEPlaintextToMut, S: GLWESecretPreparedToRef<BE>, M: GLWEDecryption<BE>, - Scratch<BE>: ScratchTakeBasic, + Scratch<BE>: ScratchTakeBasic, { module.glwe_decrypt(self, pt, sk, scratch); }

@@ -48,29 +45,23 @@ + SvpApplyDftToDftInplace<BE>

+ VecZnxIdftApplyConsume<BE> + VecZnxBigAddInplace<BE> + VecZnxBigAddSmallInplace<BE> - + VecZnxBigNormalize<BE> + + VecZnxBigNormalize<BE>, { fn glwe_decrypt_tmp_bytes<A>(&self, infos: &A) -> usize where - A: GLWEInfos + A: GLWEInfos, { let size: usize = infos.size(); (self.vec_znx_normalize_tmp_bytes() | self.bytes_of_vec_znx_dft(1, size)) + self.bytes_of_vec_znx_dft(1, size) } - fn glwe_decrypt<R, P, S>( - &self, - res: &mut R, - pt: &mut P, - sk: &S, - scratch: &mut Scratch<BE>, - ) where + fn glwe_decrypt<R, P, S>(&self, res: &mut R, pt: &mut P, sk: &S, scratch: &mut Scratch<BE>) + where R: GLWEToMut, P: GLWEPlaintextToMut, S: GLWESecretPreparedToRef<BE>, Scratch<BE>: ScratchTakeBasic, { - let res: &mut GLWE<&mut [u8]> = &mut res.to_mut(); let pt: &mut GLWEPlaintext<&mut [u8]> = &mut pt.to_ref(); let sk: &GLWESecretPrepared<&[u8], BE> = &sk.to_ref();

@@ -117,10 +108,9 @@

pt.base2k = res.base2k(); pt.k = pt.k().min(res.k()); } - } -impl <BE: Backend> GLWEDecryption<BE> for Module<BE> where +impl<BE: Backend> GLWEDecryption<BE> for Module<BE> where Self: ModuleN + VecZnxDftBytesOf + VecZnxNormalizeTmpBytes

@@ -132,4 +122,4 @@ + VecZnxBigAddInplace<BE>

+ VecZnxBigAddSmallInplace<BE> + VecZnxBigNormalize<BE> { -}+}
M poulpy-core/src/decryption/lwe_ct.rs → poulpy-core/src/decryption/lwe_ct.rs

@@ -4,10 +4,9 @@ layouts::{Backend, DataMut, DataRef, Module, ScratchOwned, ZnxView, ZnxViewMut},

oep::{ScratchOwnedAllocImpl, ScratchOwnedBorrowImpl}, }; -use crate::layouts::{LWE, LWEInfos, LWEPlaintext, LWESecret, LWEToMut, LWEPlaintextToMut, LWESecretToRef}; +use crate::layouts::{LWE, LWEInfos, LWEPlaintext, LWEPlaintextToMut, LWESecret, LWESecretToRef, LWEToMut}; -impl<DataSelf: DataRef + DataMut> LWE<DataSelf> -{ +impl<DataSelf: DataRef + DataMut> LWE<DataSelf> { pub fn decrypt<P, S, M, B>(&mut self, module: &M, pt: &mut P, sk: S) where P: LWEPlaintextToMut,

@@ -21,16 +20,15 @@ }

pub trait LWEDecrypt<BE: Backend> where - Self: Sized + ZnNormalizeInplace<BE> + Self: Sized + ZnNormalizeInplace<BE>, { fn lwe_decrypt<R, P, S>(&self, res: &mut R, pt: &mut P, sk: S) where - R: LWEToMut, - P: LWEPlaintextToMut, - S: LWESecretToRef, - BE: Backend + ScratchOwnedAllocImpl<BE> + ScratchOwnedBorrowImpl<BE>, + R: LWEToMut, + P: LWEPlaintextToMut, + S: LWESecretToRef, + BE: Backend + ScratchOwnedAllocImpl<BE> + ScratchOwnedBorrowImpl<BE>, { - let res: &mut LWE<&mut [u8]> = &mut res.to_mut(); let pt: &mut LWEPlaintext<&mut [u8]> = &mut pt.to_mut(); let sk: LWESecret<&[u8]> = sk.to_ref();

@@ -60,8 +58,4 @@ pt.k = crate::layouts::TorusPrecision(res.k().0.min(pt.size() as u32 * res.base2k().0));

} } -impl<BE: Backend> LWEDecrypt<BE> for Module<BE> where - Self: Sized + ZnNormalizeInplace<BE> -{ - -}+impl<BE: Backend> LWEDecrypt<BE> for Module<BE> where Self: Sized + ZnNormalizeInplace<BE> {}
M poulpy-core/src/encryption/compressed/gglwe_atk.rs → poulpy-core/src/encryption/compressed/gglwe_atk.rs

@@ -1,5 +1,8 @@

use poulpy_hal::{ - api::{ModuleN, ScratchAvailable, ScratchTakeBasic, SvpPPolAlloc, SvpPPolBytesOf, VecZnxAutomorphism, VecZnxDftBytesOf, VecZnxNormalizeTmpBytes}, + api::{ + ModuleN, ScratchAvailable, ScratchTakeBasic, SvpPPolAlloc, SvpPPolBytesOf, VecZnxAutomorphism, VecZnxDftBytesOf, + VecZnxNormalizeTmpBytes, + }, layouts::{Backend, DataMut, DataRef, Module, Scratch}, source::Source, };

@@ -17,7 +20,8 @@ impl AutomorphismKeyCompressed<Vec<u8>> {

pub fn encrypt_sk_tmp_bytes<B: Backend, A>(module: &Module<B>, infos: &A) -> usize where A: GGLWEInfos, - Module<B>: ModuleN + SvpPPolAlloc<B> + VecZnxNormalizeTmpBytes + VecZnxDftBytesOf + VecZnxNormalizeTmpBytes + SvpPPolBytesOf, + Module<B>: + ModuleN + SvpPPolAlloc<B> + VecZnxNormalizeTmpBytes + VecZnxDftBytesOf + VecZnxNormalizeTmpBytes + SvpPPolBytesOf, { assert_eq!(module.n() as u32, infos.n()); GLWESwitchingKeyCompressed::encrypt_sk_tmp_bytes(module, infos) + GLWESecret::bytes_of(module, infos.rank_out())
M poulpy-core/src/encryption/compressed/gglwe_ksk.rs → poulpy-core/src/encryption/compressed/gglwe_ksk.rs

@@ -1,5 +1,8 @@

use poulpy_hal::{ - api::{ModuleN, ScratchAvailable, ScratchTakeBasic, SvpPPolAlloc, SvpPPolBytesOf, SvpPrepare, VecZnxDftBytesOf, VecZnxNormalizeTmpBytes, VecZnxSwitchRing}, + api::{ + ModuleN, ScratchAvailable, ScratchTakeBasic, SvpPPolAlloc, SvpPPolBytesOf, SvpPrepare, VecZnxDftBytesOf, + VecZnxNormalizeTmpBytes, VecZnxSwitchRing, + }, layouts::{Backend, DataMut, DataRef, Module, ScalarZnx, Scratch}, source::Source, };

@@ -18,7 +21,8 @@ impl GLWESwitchingKeyCompressed<Vec<u8>> {

pub fn encrypt_sk_tmp_bytes<B: Backend, A>(module: &Module<B>, infos: &A) -> usize where A: GGLWEInfos, - Module<B>: ModuleN + SvpPPolAlloc<B> + VecZnxNormalizeTmpBytes + VecZnxDftBytesOf + VecZnxNormalizeTmpBytes + SvpPPolBytesOf, + Module<B>: + ModuleN + SvpPPolAlloc<B> + VecZnxNormalizeTmpBytes + VecZnxDftBytesOf + VecZnxNormalizeTmpBytes + SvpPPolBytesOf, { (GGLWE::encrypt_sk_tmp_bytes(module, infos) | ScalarZnx::bytes_of(module.n(), 1)) + ScalarZnx::bytes_of(module.n(), infos.rank_in().into())
M poulpy-core/src/encryption/compressed/gglwe_tsk.rs → poulpy-core/src/encryption/compressed/gglwe_tsk.rs

@@ -1,10 +1,10 @@

use poulpy_hal::{ api::{ - ModuleN, ScratchTakeBasic, SvpApplyDftToDft, SvpPPolAlloc, SvpPPolBytesOf, SvpPrepare, VecZnxBigBytesOf, VecZnxBigNormalize, VecZnxDftApply, VecZnxDftBytesOf, - VecZnxIdftApplyTmpA, VecZnxNormalizeTmpBytes, + ModuleN, ScratchTakeBasic, SvpApplyDftToDft, SvpPPolAlloc, SvpPPolBytesOf, SvpPrepare, VecZnxBigBytesOf, + VecZnxBigNormalize, VecZnxDftApply, VecZnxDftBytesOf, VecZnxIdftApplyTmpA, VecZnxNormalizeTmpBytes, }, + layouts::{Backend, DataMut, DataRef, Module, Scratch}, oep::{SvpPPolAllocBytesImpl, VecZnxBigAllocBytesImpl, VecZnxDftAllocBytesImpl}, - layouts::{Backend, DataMut, DataRef, Module, Scratch}, source::Source, };

@@ -12,7 +12,7 @@ use crate::{

ScratchTakeCore, encryption::compressed::gglwe_ksk::GGLWEKeyCompressedEncryptSk, layouts::{ - GetDist, GGLWEInfos, GLWEInfos, GLWESecret, GLWESecretToRef, LWEInfos, Rank, TensorKey, + GGLWEInfos, GLWEInfos, GLWESecret, GLWESecretToRef, GetDist, LWEInfos, Rank, TensorKey, compressed::{TensorKeyCompressed, TensorKeyCompressedToMut}, }, };

@@ -21,7 +21,13 @@ impl TensorKeyCompressed<Vec<u8>> {

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, + Module<B>: ModuleN + + SvpPPolBytesOf + + SvpPPolAlloc<B> + + VecZnxNormalizeTmpBytes + + VecZnxDftBytesOf + + VecZnxNormalizeTmpBytes + + VecZnxBigBytesOf, { TensorKey::encrypt_sk_tmp_bytes(module, infos) }
M poulpy-core/src/encryption/gglwe_atk.rs → poulpy-core/src/encryption/gglwe_atk.rs

@@ -1,37 +1,30 @@

use poulpy_hal::{ - api::{ - ModuleN, ScratchAvailable, SvpApplyDftToDftInplace, SvpPPolAlloc, SvpPPolBytesOf, SvpPrepare, VecZnxAddInplace, VecZnxAddNormal, - VecZnxAddScalarInplace, VecZnxAutomorphism, VecZnxBigNormalize, VecZnxDftApply, VecZnxDftBytesOf, VecZnxFillUniform, - VecZnxIdftApplyConsume, VecZnxNormalize, VecZnxNormalizeInplace, VecZnxNormalizeTmpBytes, VecZnxSub, VecZnxSubInplace, - VecZnxSwitchRing, - }, + api::{ScratchAvailable, VecZnxAutomorphism}, layouts::{Backend, DataMut, GaloisElement, Module, Scratch}, source::Source, }; use crate::{ ScratchTakeCore, - layouts::{ - AutomorphismKey, AutomorphismKeyToMut, GGLWEInfos, GLWEInfos, GLWESecret, GLWESecretToRef, GLWESwitchingKey, - }, + encryption::gglwe_ksk::GLWESwitchingKeyEncryptSk, + layouts::{AutomorphismKey, AutomorphismKeyToMut, GGLWEInfos, GLWEInfos, GLWESecret, GLWESecretToRef, LWEInfos}, }; impl AutomorphismKey<Vec<u8>> { - pub fn encrypt_sk_tmp_bytes<M, A, BE: Backend>(module: &M, infos: &A) -> usize where A: GGLWEInfos, - M: GGLWEAutomorphismKeyEncryptSk<BE> + M: AutomorphismKeyEncryptSk<BE>, { - module.gglwe_automorphism_key_encrypt_sk_tmp_bytes(infos) + module.automorphism_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: GGLWEAutomorphismKeyEncryptPk<BE> + M: GGLWEAutomorphismKeyEncryptPk<BE>, { - module.gglwe_automorphism_key_encrypt_pk_tmp_bytes(infos) + module.automorphism_key_encrypt_pk_tmp_bytes(infos) } }

@@ -39,9 +32,9 @@ impl<DM: DataMut> AutomorphismKey<DM>

where Self: AutomorphismKeyToMut, { - pub fn encrypt_sk<S, BE: Backend>( + pub fn encrypt_sk<S, M, BE: Backend>( &mut self, - module: &Module<BE>, + module: &M, p: i64, sk: &S, source_xa: &mut Source,

@@ -49,57 +42,36 @@ source_xe: &mut Source,

scratch: &mut Scratch<BE>, ) where S: GLWESecretToRef, - Module<BE>: GGLWEAutomorphismKeyEncryptSk<BE>, + M: AutomorphismKeyEncryptSk<BE>, { - module.gglwe_automorphism_key_encrypt_sk(self, p, sk, source_xa, source_xe, scratch); + module.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 +pub trait AutomorphismKeyEncryptSk<BE: Backend> { + fn automorphism_key_encrypt_sk_tmp_bytes<A>(&self, infos: &A) -> usize where A: GGLWEInfos; - fn gglwe_automorphism_key_encrypt_sk<A, B>( + fn automorphism_key_encrypt_sk<R, S>( &self, - res: &mut A, + res: &mut R, p: i64, - sk: &B, + sk: &S, source_xa: &mut Source, source_xe: &mut Source, scratch: &mut Scratch<BE>, ) where - A: AutomorphismKeyToMut, - B: GLWESecretToRef; + R: AutomorphismKeyToMut, + S: GLWESecretToRef; } -impl<BE: Backend> GGLWEAutomorphismKeyEncryptSk<BE> for Module<BE> +impl<BE: Backend> AutomorphismKeyEncryptSk<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 - + SvpPrepare<BE> - + VecZnxSwitchRing - + SvpPPolBytesOf - + VecZnxAutomorphism - + SvpPPolAlloc<BE> - + GaloisElement, - Scratch<BE>: ScratchAvailable + ScratchTakeCore<BE>, + Module<BE>: GLWESwitchingKeyEncryptSk<BE> + VecZnxAutomorphism + GaloisElement, + Scratch<BE>: ScratchTakeCore<BE>, { - - fn gglwe_automorphism_key_encrypt_sk_tmp_bytes<A>(&self, infos: &A) -> usize + fn automorphism_key_encrypt_sk_tmp_bytes<A>(&self, infos: &A) -> usize where A: GGLWEInfos, {

@@ -108,38 +80,33 @@ 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()) + self.glwe_switching_key_encrypt_sk_tmp_bytes(infos) + GLWESecret::bytes_of_from_infos(self, infos) } - fn gglwe_automorphism_key_encrypt_sk<A, B>( + fn automorphism_key_encrypt_sk<R, S>( &self, - res: &mut A, + res: &mut R, p: i64, - sk: &B, + sk: &S, source_xa: &mut Source, source_xe: &mut Source, scratch: &mut Scratch<BE>, ) where - A: AutomorphismKeyToMut, - B: GLWESecretToRef, + R: AutomorphismKeyToMut, + S: GLWESecretToRef, { let res: &mut AutomorphismKey<&mut [u8]> = &mut res.to_mut(); let sk: &GLWESecret<&[u8]> = &sk.to_ref(); - #[cfg(debug_assertions)] - { - use crate::layouts::{GLWEInfos, LWEInfos}; - - assert_eq!(res.n(), sk.n()); - assert_eq!(res.rank_out(), res.rank_in()); - assert_eq!(sk.rank(), res.rank_out()); - assert!( - scratch.available() >= AutomorphismKey::encrypt_sk_tmp_bytes(self, res), - "scratch.available(): {} < AutomorphismKey::encrypt_sk_tmp_bytes: {:?}", - scratch.available(), - AutomorphismKey::encrypt_sk_tmp_bytes(self, res) - ) - } + assert_eq!(res.n(), sk.n()); + assert_eq!(res.rank_out(), res.rank_in()); + assert_eq!(sk.rank(), res.rank_out()); + assert!( + scratch.available() >= self.automorphism_key_encrypt_sk_tmp_bytes(res), + "scratch.available(): {} < AutomorphismKey::encrypt_sk_tmp_bytes: {:?}", + scratch.available(), + self.automorphism_key_encrypt_sk_tmp_bytes(res) + ); let (mut sk_out, scratch_1) = scratch.take_glwe_secret(self, sk.rank());

@@ -161,46 +128,22 @@

res.p = p; } } - pub trait GGLWEAutomorphismKeyEncryptPk<BE: Backend> { - fn gglwe_automorphism_key_encrypt_pk_tmp_bytes<A>(&self, infos: &A) -> usize + fn 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>, + Module<BE>:, + Scratch<BE>: ScratchTakeCore<BE>, { - - fn gglwe_automorphism_key_encrypt_pk_tmp_bytes<A>(&self, infos: &A) -> usize + fn 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) + unimplemented!() } -}+}
M poulpy-core/src/encryption/gglwe_ct.rs → poulpy-core/src/encryption/gglwe_ct.rs

@@ -1,20 +1,20 @@

use poulpy_hal::{ api::{ModuleN, ScratchAvailable, VecZnxAddScalarInplace, VecZnxDftBytesOf, VecZnxNormalizeInplace, VecZnxNormalizeTmpBytes}, - // oep::SvpPPolAllocBytesImpl, - layouts::{Backend, DataMut, DataRef, Module, ScalarZnx, ScalarZnxToRef, Scratch, ZnxZero}, + layouts::{Backend, DataMut, Module, ScalarZnx, ScalarZnxToRef, Scratch, ZnxInfos, ZnxZero}, source::Source, }; use crate::{ - encryption::glwe_ct::GLWEEncryptSk, layouts::GLWEInfos, ScratchTakeCore, + ScratchTakeCore, + encryption::glwe_ct::GLWEEncryptSk, + layouts::GLWEInfos, layouts::{ - GGLWE, GGLWEInfos, GGLWEToMut, GLWE, GLWEPlaintext, LWEInfos, + GGLWE, GGLWEInfos, GGLWEToMut, GLWEPlaintext, LWEInfos, prepared::{GLWESecretPrepared, GLWESecretPreparedToRef}, }, }; impl GGLWE<Vec<u8>> { - pub fn encrypt_sk_tmp_bytes<M, A, BE: Backend>(module: &M, infos: &A) -> usize where A: GGLWEInfos,

@@ -32,15 +32,30 @@ module.gglwe_encrypt_sk_tmp_bytes(infos)

} } -pub trait GGLWEEncryptSk<B: Backend> { +impl<D: DataMut> GGLWE<D> { + #[allow(clippy::too_many_arguments)] + pub fn encrypt_sk<P, S, M, BE: Backend>( + &mut self, + module: &M, + pt: &P, + sk: &S, + source_xa: &mut Source, + source_xe: &mut Source, + scratch: &mut Scratch<BE>, + ) where + P: ScalarZnxToRef, + S: GLWESecretPreparedToRef<BE>, + M: GGLWEEncryptSk<BE>, + Scratch<BE>: ScratchTakeCore<BE>, + { + module.gglwe_encrypt_sk(self, pt, sk, source_xa, source_xe, scratch); + } +} +pub trait GGLWEEncryptSk<BE: Backend> { fn gglwe_encrypt_sk_tmp_bytes<A>(&self, infos: &A) -> usize where A: GGLWEInfos; - - fn gglwe_encrypt_pk_tmp_bytes<A>(&self, infos: &A) -> usize - where - A: GGLWEInfos; fn gglwe_encrypt_sk<R, P, S>( &self,

@@ -49,40 +64,29 @@ pt: &P,

sk: &S, source_xa: &mut Source, source_xe: &mut Source, - scratch: &mut Scratch<B>, + scratch: &mut Scratch<BE>, ) where R: GGLWEToMut, P: ScalarZnxToRef, - S: GLWESecretPreparedToRef<B>; + S: GLWESecretPreparedToRef<BE>; } -impl<B: Backend> GGLWEEncryptSk<B> for Module<B> +impl<BE: Backend> GGLWEEncryptSk<BE> for Module<BE> where - Module<B>: ModuleN - + GLWEEncryptSk<B> + Module<BE>: ModuleN + + GLWEEncryptSk<BE> + VecZnxNormalizeTmpBytes + VecZnxDftBytesOf + VecZnxAddScalarInplace - + VecZnxNormalizeInplace<B>, - Scratch<B>: ScratchAvailable + ScratchTakeCore<B>, + + VecZnxNormalizeInplace<BE>, + Scratch<BE>: ScratchTakeCore<BE>, { fn gglwe_encrypt_sk_tmp_bytes<A>(&self, infos: &A) -> usize where A: GGLWEInfos, { - GLWE::encrypt_sk_tmp_bytes(self, &infos.glwe_layout()) - + (GLWEPlaintext::bytes_of_from_infos(self, &infos.glwe_layout()) | self.vec_znx_normalize_tmp_bytes()) - } - - fn gglwe_encrypt_pk_tmp_bytes<A>(&self, _infos: &A) -> usize - where - A: GGLWEInfos, - { - unimplemented!() - // TODO: Is this correct? - // GLWE::encrypt_pk_tmp_bytes(self, &infos.glwe_layout()) - // + (GLWEPlaintext::bytes_of_from_infos(self, &infos.glwe_layout()) | self.vec_znx_normalize_tmp_bytes()) - + self.glwe_encrypt_sk_tmp_bytes(infos) + + GLWEPlaintext::bytes_of_from_infos(self, infos).max(self.vec_znx_normalize_tmp_bytes()) } fn gglwe_encrypt_sk<R, P, S>(

@@ -92,54 +96,49 @@ pt: &P,

sk: &S, source_xa: &mut Source, source_xe: &mut Source, - scratch: &mut Scratch<B>, + scratch: &mut Scratch<BE>, ) where R: GGLWEToMut, P: ScalarZnxToRef, - S: GLWESecretPreparedToRef<B>, + S: GLWESecretPreparedToRef<BE>, { let res: &mut GGLWE<&mut [u8]> = &mut res.to_mut(); let pt: &ScalarZnx<&[u8]> = &pt.to_ref(); - - #[cfg(debug_assertions)] - { - use poulpy_hal::layouts::ZnxInfos; - let sk: GLWESecretPrepared<&[u8], B> = sk.to_ref(); + let sk: &GLWESecretPrepared<&[u8], BE> = &sk.to_ref(); - assert_eq!( - res.rank_in(), - pt.cols() as u32, - "res.rank_in(): {} != pt.cols(): {}", - res.rank_in(), - pt.cols() - ); - assert_eq!( - res.rank_out(), - sk.rank(), - "res.rank_out(): {} != sk.rank(): {}", - res.rank_out(), - sk.rank() - ); - assert_eq!(res.n(), sk.n()); - assert_eq!(pt.n() as u32, sk.n()); - assert!( - scratch.available() >= GGLWE::encrypt_sk_tmp_bytes(self, res), - "scratch.available: {} < GGLWECiphertext::encrypt_sk_tmp_bytes(self, res.rank()={}, res.size()={}): {}", - scratch.available(), - res.rank_out(), - res.size(), - GGLWE::encrypt_sk_tmp_bytes(self, res) - ); - assert!( - res.dnum().0 * res.dsize().0 * res.base2k().0 <= res.k().0, - "res.dnum() : {} * res.dsize() : {} * res.base2k() : {} = {} >= res.k() = {}", - res.dnum(), - res.dsize(), - res.base2k(), - res.dnum().0 * res.dsize().0 * res.base2k().0, - res.k() - ); - } + assert_eq!( + res.rank_in(), + pt.cols() as u32, + "res.rank_in(): {} != pt.cols(): {}", + res.rank_in(), + pt.cols() + ); + assert_eq!( + res.rank_out(), + sk.rank(), + "res.rank_out(): {} != sk.rank(): {}", + res.rank_out(), + sk.rank() + ); + assert_eq!(res.n(), sk.n()); + assert_eq!(pt.n() as u32, sk.n()); + assert!( + scratch.available() >= self.gglwe_encrypt_sk_tmp_bytes(res), + "scratch.available: {} < GGLWE::encrypt_sk_tmp_bytes(self, res.rank()={}, res.size()={}): {}", + scratch.available(), + res.rank_out(), + res.size(), + self.gglwe_encrypt_sk_tmp_bytes(res) + ); + assert!( + res.dnum().0 * res.dsize().0 * res.base2k().0 <= res.k().0, + "res.dnum() : {} * res.dsize() : {} * res.base2k() : {} = {} >= res.k() = {}", + res.dnum(), + res.dsize(), + res.base2k(), + res.dnum().0 * res.dsize().0 * res.base2k().0, + res.k() + ); let dnum: usize = res.dnum().into(); let dsize: usize = res.dsize().into();

@@ -147,7 +146,7 @@ let base2k: usize = res.base2k().into();

let rank_in: usize = res.rank_in().into(); let (mut tmp_pt, scrach_1) = scratch.take_glwe_pt(self, &res.glwe_layout()); - // For each input column (i.e. rank) produces a GGLWE ciphertext of rank_out+1 columns + // For each input column (i.e. rank) produces a GGLWE of rank_out+1 columns // // Example for ksk rank 2 to rank 3: //

@@ -177,20 +176,3 @@ }

} } } - -impl<DataSelf: DataMut> GGLWE<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>: GGLWEEncryptSk<B>, - { - module.gglwe_encrypt_sk(self, pt, sk, source_xa, source_xe, scratch); - } -}
M poulpy-core/src/encryption/gglwe_ksk.rs → poulpy-core/src/encryption/gglwe_ksk.rs

@@ -1,20 +1,16 @@

use poulpy_hal::{ - api::{ - ModuleN, ScratchAvailable, SvpApplyDftToDftInplace, SvpPPolAlloc, SvpPPolBytesOf, SvpPrepare, VecZnxAddInplace, VecZnxAddNormal, - VecZnxAddScalarInplace, VecZnxBigNormalize, VecZnxDftApply, VecZnxDftBytesOf, VecZnxFillUniform, VecZnxIdftApplyConsume, - VecZnxNormalize, VecZnxNormalizeInplace, VecZnxNormalizeTmpBytes, VecZnxSub, VecZnxSubInplace, VecZnxSwitchRing, - ScratchTakeBasic, - }, - layouts::{Backend, DataMut, DataRef, Module, ScalarZnx, Scratch}, + api::{ModuleN, ScratchAvailable, ScratchTakeBasic, SvpPrepare, VecZnxSwitchRing}, + layouts::{Backend, DataMut, Module, ScalarZnx, Scratch}, source::Source, }; use crate::{ ScratchTakeCore, + encryption::gglwe_ct::GGLWEEncryptSk, layouts::{ - GGLWE, GGLWEInfos, GLWEInfos, GLWESecret, GLWESecretToRef, GLWESwitchingKey, GLWESwitchingKeyToMut, LWEInfos, prepared::GLWESecretPrepared, + GGLWEInfos, GLWEInfos, GLWESecret, GLWESecretToRef, GLWESwitchingKey, GLWESwitchingKeyToMut, LWEInfos, + prepared::GLWESecretPreparedAlloc, }, - encryption::gglwe_ct::GGLWEEncryptSk, }; impl GLWESwitchingKey<Vec<u8>> {

@@ -36,209 +32,102 @@ }

} impl<DataSelf: DataMut> GLWESwitchingKey<DataSelf> { - - pub fn encrypt_sk<M, DataSkIn: DataRef, DataSkOut: DataRef, BE: Backend>( + pub fn encrypt_sk<M, S1, S2, BE: Backend>( &mut self, module: &M, - sk_in: &GLWESecret<DataSkIn>, - sk_out: &GLWESecret<DataSkOut>, + sk_in: &S1, + sk_out: &S2, source_xa: &mut Source, source_xe: &mut Source, scratch: &mut Scratch<BE>, ) where + S1: GLWESecretToRef, + S2: GLWESecretToRef, M: GLWESwitchingKeyEncryptSk<BE>, - Scratch<BE>: ScratchAvailable + ScratchTakeCore<BE>, + Scratch<BE>: ScratchTakeCore<BE>, { 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<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>, - // { - // #[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(); - // } } - -pub trait GLWESwitchingKeyEncryptSk<BE: Backend> -where - Self: Sized - + ModuleN - + SvpPPolBytesOf - + VecZnxDftBytesOf - + VecZnxNormalizeTmpBytes - + SvpPPolAlloc<BE> - + GGLWEEncryptSk<BE>, -{ +pub trait GLWESwitchingKeyEncryptSk<BE: Backend> { 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>( + fn glwe_switching_key_encrypt_sk<R, S1, S2>( &self, res: &mut R, - sk_in: &GLWESecret<DataSkIn>, - sk_out: &GLWESecret<DataSkOut>, + sk_in: &S1, + sk_out: &S2, source_xa: &mut Source, source_xe: &mut Source, scratch: &mut Scratch<BE>, - ) - where + ) where R: GLWESwitchingKeyToMut, - DataSkIn: DataRef, - DataSkOut: DataRef, - Scratch<BE>: ScratchAvailable + ScratchTakeCore<BE>; - + S1: GLWESecretToRef, + S2: GLWESecretToRef, + Scratch<BE>: 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 +impl<BE: Backend> GLWESwitchingKeyEncryptSk<BE> for Module<BE> +where + Self: ModuleN + GGLWEEncryptSk<BE> + GLWESecretPreparedAlloc<BE> + VecZnxSwitchRing + SvpPrepare<BE>, + Scratch<BE>: ScratchTakeCore<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)) + self.gglwe_encrypt_sk_tmp_bytes(infos) + .max(ScalarZnx::bytes_of(self.n(), 1)) + ScalarZnx::bytes_of(self.n(), infos.rank_in().into()) - + GLWESecretPrepared::bytes_of_from_infos(self, &infos.glwe_layout()) + + self.bytes_of_glwe_secret_prepared_from_infos(infos) } - fn glwe_switching_key_encrypt_sk<R, DataSkIn, DataSkOut>( + fn glwe_switching_key_encrypt_sk<R, S1, S2>( &self, res: &mut R, - sk_in: &GLWESecret<DataSkIn>, - sk_out: &GLWESecret<DataSkOut>, + sk_in: &S1, + sk_out: &S2, source_xa: &mut Source, source_xe: &mut Source, scratch: &mut Scratch<BE>, - ) - where + ) where R: GLWESwitchingKeyToMut, - DataSkIn: DataRef, - DataSkOut: DataRef, - Scratch<BE>: ScratchAvailable + ScratchTakeCore<BE>, + S1: GLWESecretToRef, + S2: GLWESecretToRef, { - 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(); + assert!(sk_in.n().0 <= self.n() as u32); + assert!(sk_out.n().0 <= self.n() as u32); + assert!( + scratch.available() >= self.glwe_switching_key_encrypt_sk_tmp_bytes(res), + "scratch.available()={} < GLWESwitchingKey::encrypt_sk_tmp_bytes={}", + scratch.available(), + self.glwe_switching_key_encrypt_sk_tmp_bytes(res) + ); let (mut sk_in_tmp, scratch_1) = scratch.take_scalar_znx(self, sk_in.rank().into()); - (0..sk_in.rank().into()).for_each(|i| { + for i in 0..sk_in.rank().into() { 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| { + for i in 0..sk_out.rank().into() { 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(

@@ -251,39 +140,20 @@ scratch_2,

); res.sk_in_n = sk_in.n().into(); res.sk_out_n = sk_out.n().into(); - } - + } } -pub trait GLWESwitchingKeyEncryptPk<BE: Backend> -where - Self: Sized - + ModuleN - + SvpPPolBytesOf - + VecZnxDftBytesOf - + VecZnxNormalizeTmpBytes - + SvpPPolAlloc<BE> - + GGLWEEncryptSk<BE>, -{ - +pub trait GLWESwitchingKeyEncryptPk<BE: Backend> { fn glwe_switching_key_encrypt_pk_tmp_bytes<A>(&self, infos: &A) -> usize where A: GGLWEInfos; } -impl<BE: Backend> GLWESwitchingKeyEncryptPk<BE> for Module<BE> where - Self: ModuleN - + SvpPPolBytesOf - + VecZnxDftBytesOf - + VecZnxNormalizeTmpBytes - + SvpPPolAlloc<BE> - + GGLWEEncryptSk<BE>, -{ - - fn glwe_switching_key_encrypt_pk_tmp_bytes<A>(&self, infos: &A) -> usize +impl<BE: Backend> GLWESwitchingKeyEncryptPk<BE> for Module<BE> { + fn glwe_switching_key_encrypt_pk_tmp_bytes<A>(&self, _infos: &A) -> usize where A: GGLWEInfos, { - GGLWE::encrypt_pk_tmp_bytes(self, infos) + unimplemented!() } -}+}
M poulpy-core/src/encryption/gglwe_tsk.rs → poulpy-core/src/encryption/gglwe_tsk.rs

@@ -1,156 +1,54 @@

use poulpy_hal::{ api::{ - ModuleN, ScratchAvailable, ScratchTakeBasic, SvpApplyDftToDft, SvpApplyDftToDftInplace, SvpPPolAlloc, SvpPPolBytesOf, SvpPrepare, VecZnxAddInplace, VecZnxAddNormal, - VecZnxAddScalarInplace, VecZnxBigBytesOf, VecZnxBigNormalize, VecZnxDftApply, VecZnxDftBytesOf, VecZnxFillUniform, - VecZnxIdftApplyConsume, VecZnxIdftApplyTmpA, VecZnxNormalize, VecZnxNormalizeInplace, VecZnxNormalizeTmpBytes, VecZnxSub, - VecZnxSubInplace, VecZnxSwitchRing, + ModuleN, ScratchAvailable, ScratchTakeBasic, SvpApplyDftToDft, VecZnxBigBytesOf, VecZnxBigNormalize, VecZnxDftApply, + VecZnxDftBytesOf, VecZnxIdftApplyTmpA, }, - layouts::{Backend, DataMut, DataRef, Module, Scratch}, - oep::{VecZnxAddScalarInplaceImpl, VecZnxBigAllocBytesImpl, VecZnxDftApplyImpl, SvpApplyDftToDftImpl, VecZnxIdftApplyTmpAImpl, VecZnxBigNormalizeImpl}, + layouts::{Backend, DataMut, Module, Scratch}, source::Source, }; use crate::{ ScratchTakeCore, + encryption::gglwe_ksk::GLWESwitchingKeyEncryptSk, layouts::{ - GetDist, GGLWEInfos, GLWEInfos, GLWESecret, GLWESecretToRef, GLWESwitchingKey, LWEInfos, Rank, TensorKey, TensorKeyToMut, - prepared::GLWESecretPrepared, + GGLWEInfos, GLWEInfos, GLWESecret, GLWESecretToRef, GLWESwitchingKey, GetDist, LWEInfos, Rank, TensorKey, TensorKeyToMut, + prepared::{GLWESecretPrepare, GLWESecretPrepared, GLWESecretPreparedAlloc}, }, - encryption::gglwe_ksk::GLWESwitchingKeyEncryptSk, }; impl TensorKey<Vec<u8>> { pub fn encrypt_sk_tmp_bytes<M, A, BE: Backend>(module: &M, infos: &A) -> usize where A: GGLWEInfos, - M: GGLWETensorKeyEncryptSk<BE> + M: TensorKeyEncryptSk<BE>, { - module.gglwe_tensor_key_encrypt_sk_tmp_bytes(infos) + module.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<M, DataSk: DataRef, BE: Backend>( + pub fn encrypt_sk<M, S, BE: Backend>( &mut self, module: &M, - sk: &GLWESecret<DataSk>, + sk: &S, source_xa: &mut Source, source_xe: &mut Source, scratch: &mut Scratch<BE>, ) where - M: GGLWETensorKeyEncryptSk<BE>, - GLWESecret<DataSk>: GetDist, + M: TensorKeyEncryptSk<BE>, + S: GLWESecretToRef + GetDist, Scratch<BE>: ScratchAvailable + ScratchTakeCore<BE>, { - module.gglwe_tensor_key_encrypt_sk(self, sk, source_xa, source_xe, scratch); + module.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 +pub trait TensorKeyEncryptSk<BE: Backend> { + fn tensor_key_encrypt_sk_tmp_bytes<A>(&self, infos: &A) -> usize where A: GGLWEInfos; - fn gglwe_tensor_key_encrypt_sk<R, S>( + fn tensor_key_encrypt_sk<R, S>( &self, res: &mut R, sk: &S,

@@ -162,41 +60,33 @@ R: TensorKeyToMut,

S: GLWESecretToRef + GetDist; } -impl<BE: Backend> GGLWETensorKeyEncryptSk<BE> for Module<BE> where +impl<BE: Backend> TensorKeyEncryptSk<BE> for Module<BE> +where Module<BE>: ModuleN - + SvpPPolBytesOf - + SvpPPolAlloc<BE> - + VecZnxNormalizeTmpBytes + + GLWESwitchingKeyEncryptSk<BE> + VecZnxDftBytesOf - + VecZnxNormalizeTmpBytes + VecZnxBigBytesOf - + VecZnxAddScalarInplaceImpl<BE> + + GLWESecretPreparedAlloc<BE> + + GLWESecretPrepare<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>, + + VecZnxBigNormalize<BE>, + Scratch<BE>: ScratchTakeCore<BE>, { - fn gglwe_tensor_key_encrypt_sk_tmp_bytes<A>(&self, infos: &A) -> usize + fn 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) + + 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>( + fn tensor_key_encrypt_sk<R, S>( &self, res: &mut R, sk: &S,

@@ -217,11 +107,8 @@ sk_dft_prep.prepare(self, sk);

let sk: &GLWESecret<&[u8]> = &sk.to_ref(); - #[cfg(debug_assertions)] - { - assert_eq!(res.rank_out(), sk.rank()); - assert_eq!(res.n(), sk.n()); - } + 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);

@@ -251,6 +138,6 @@

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

@@ -1,14 +1,14 @@

use poulpy_hal::{ - api::{ModuleN, VecZnxAddScalarInplace, VecZnxDftBytesOf, VecZnxNormalizeInplace, VecZnxNormalizeTmpBytes}, - layouts::{Backend, DataMut, DataRef, Module, ScalarZnx, ScalarZnxToRef, Scratch, VecZnx, ZnxZero}, + api::{ModuleN, VecZnxAddScalarInplace, VecZnxDftBytesOf, VecZnxNormalizeInplace}, + layouts::{Backend, DataMut, Module, ScalarZnx, ScalarZnxToRef, Scratch, VecZnx, ZnxInfos, ZnxZero}, source::Source, }; use crate::{ SIGMA, ScratchTakeCore, - encryption::glwe_ct::GLWEEncryptSkInternal, + encryption::glwe_ct::{GLWEEncryptSk, GLWEEncryptSkInternal}, layouts::{ - GGSW, GGSWInfos, GGSWToMut, GLWE, GLWEInfos, LWEInfos, + GGSW, GGSWInfos, GGSWToMut, GLWEInfos, LWEInfos, prepared::{GLWESecretPrepared, GLWESecretPreparedToRef}, }, };

@@ -21,31 +21,23 @@ M: GGSWEncryptSk<BE>,

{ 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> { +impl<D: DataMut> GGSW<D> { #[allow(clippy::too_many_arguments)] - pub fn encrypt_sk<DataPt: DataRef, DataSk: DataRef, B: Backend>( + pub fn encrypt_sk<P, S, M, BE: Backend>( &mut self, - module: &Module<B>, - pt: &ScalarZnx<DataPt>, - sk: &GLWESecretPrepared<DataSk, B>, + module: &M, + pt: &P, + sk: &S, source_xa: &mut Source, source_xe: &mut Source, - scratch: &mut Scratch<B>, + scratch: &mut Scratch<BE>, ) where - Module<B>: GGSWEncryptSk<B>, + P: ScalarZnxToRef, + S: GLWESecretPreparedToRef<BE>, + M: GGSWEncryptSk<BE>, + Scratch<BE>: ScratchTakeCore<BE>, { module.ggsw_encrypt_sk(self, pt, sk, source_xa, source_xe, scratch); }

@@ -55,7 +47,7 @@ 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,

@@ -74,19 +66,18 @@ impl<B: Backend> GGSWEncryptSk<B> for Module<B>

where Module<B>: ModuleN + GLWEEncryptSkInternal<B> - + VecZnxAddScalarInplace - + VecZnxNormalizeInplace<B> + + GLWEEncryptSk<B> + VecZnxDftBytesOf - + VecZnxNormalizeTmpBytes, + + VecZnxNormalizeInplace<B> + + VecZnxAddScalarInplace, 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()) + self.glwe_encrypt_sk_tmp_bytes(infos) + 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)

@@ -109,15 +100,10 @@ let res: &mut GGSW<&mut [u8]> = &mut res.to_mut();

let pt: &ScalarZnx<&[u8]> = &pt.to_ref(); let sk: &GLWESecretPrepared<&[u8], B> = &sk.to_ref(); - #[cfg(debug_assertions)] - { - use poulpy_hal::layouts::ZnxInfos; - - assert_eq!(res.rank(), sk.rank()); - assert_eq!(res.n(), self.n() as u32); - assert_eq!(pt.n(), self.n()); - assert_eq!(sk.n(), self.n() as u32); - } + assert_eq!(res.rank(), sk.rank()); + assert_eq!(res.n(), self.n() as u32); + assert_eq!(pt.n(), self.n()); + assert_eq!(sk.n(), self.n() as u32); let k: usize = res.k().into(); let base2k: usize = res.base2k().into();

@@ -149,4 +135,4 @@ );

} } } -}+}
M poulpy-core/src/encryption/glwe_ct.rs → poulpy-core/src/encryption/glwe_ct.rs

@@ -1,15 +1,16 @@

use poulpy_hal::{ api::{ - ModuleN, ScratchAvailable, SvpApplyDftToDft, SvpApplyDftToDftInplace, SvpPPolBytesOf, SvpPrepare, VecZnxAddInplace, - VecZnxAddNormal, VecZnxBigAddNormal, VecZnxBigAddSmallInplace, VecZnxBigBytesOf, VecZnxBigNormalize, VecZnxDftApply, - VecZnxDftBytesOf, VecZnxFillUniform, VecZnxIdftApplyConsume, VecZnxNormalize, VecZnxNormalizeInplace, - VecZnxNormalizeTmpBytes, VecZnxSub, VecZnxSubInplace, ScratchTakeBasic, + ModuleN, ScratchAvailable, ScratchTakeBasic, SvpApplyDftToDft, SvpApplyDftToDftInplace, SvpPPolBytesOf, SvpPrepare, + VecZnxAddInplace, VecZnxAddNormal, VecZnxBigAddNormal, VecZnxBigAddSmallInplace, VecZnxBigBytesOf, VecZnxBigNormalize, + VecZnxDftApply, VecZnxDftBytesOf, VecZnxFillUniform, VecZnxIdftApplyConsume, VecZnxNormalize, VecZnxNormalizeInplace, + VecZnxNormalizeTmpBytes, VecZnxSub, VecZnxSubInplace, }, layouts::{Backend, DataMut, Module, ScalarZnx, Scratch, VecZnx, VecZnxBig, VecZnxToMut, ZnxInfos, ZnxZero}, source::Source, }; use crate::{ + ScratchTakeCore, dist::Distribution, encryption::{SIGMA, SIGMA_BOUND}, layouts::{

@@ -19,7 +20,6 @@ },

}; impl GLWE<Vec<u8>> { - pub fn encrypt_sk_tmp_bytes<M, A, BE: Backend>(module: &M, infos: &A) -> usize where A: GLWEInfos,

@@ -31,16 +31,16 @@

pub fn encrypt_pk_tmp_bytes<M, A, BE: Backend>(module: &M, infos: &A) -> usize where A: GLWEInfos, - M: GLWEEncryptPk<BE> + M: GLWEEncryptPk<BE>, { module.glwe_encrypt_pk_tmp_bytes(infos) } } impl<D: DataMut> GLWE<D> { - pub fn encrypt_sk<R, P, S, BE: Backend>( + pub fn encrypt_sk<R, P, S, M, BE: Backend>( &mut self, - module: &Module<BE>, + module: &M, pt: &P, sk: &S, source_xa: &mut Source,

@@ -49,28 +49,30 @@ scratch: &mut Scratch<BE>,

) where P: GLWEPlaintextToRef, S: GLWESecretPreparedToRef<BE>, - Module<BE>: GLWEEncryptSk<BE>, + M: GLWEEncryptSk<BE>, + Scratch<BE>: ScratchTakeCore<BE>, { module.glwe_encrypt_sk(self, pt, sk, source_xa, source_xe, scratch); } - pub fn encrypt_zero_sk<S, BE: Backend>( + pub fn encrypt_zero_sk<S, M, BE: Backend>( &mut self, - module: &Module<BE>, + module: &M, sk: &S, source_xa: &mut Source, source_xe: &mut Source, scratch: &mut Scratch<BE>, ) where S: GLWESecretPreparedToRef<BE>, - Module<BE>: GLWEEncryptSk<BE>, + M: GLWEEncryptSk<BE>, + Scratch<BE>: ScratchTakeCore<BE>, { module.glwe_encrypt_zero_sk(self, sk, source_xa, source_xe, scratch); } - pub fn encrypt_pk<P, K, BE: Backend>( + pub fn encrypt_pk<P, K, M, BE: Backend>( &mut self, - module: &Module<BE>, + module: &M, pt: &P, pk: &K, source_xu: &mut Source,

@@ -79,31 +81,28 @@ scratch: &mut Scratch<BE>,

) where P: GLWEPlaintextToRef, K: GLWEPublicKeyPreparedToRef<BE>, - Module<BE>: GLWEEncryptPk<BE>, + M: GLWEEncryptPk<BE>, { module.glwe_encrypt_pk(self, pt, pk, source_xu, source_xe, scratch); } - pub fn encrypt_zero_pk<K, BE: Backend>( + pub fn encrypt_zero_pk<K, M, BE: Backend>( &mut self, - module: &Module<BE>, + module: &M, pk: &K, source_xu: &mut Source, source_xe: &mut Source, scratch: &mut Scratch<BE>, ) where K: GLWEPublicKeyPreparedToRef<BE>, - Module<BE>: GLWEEncryptPk<BE>, + M: GLWEEncryptPk<BE>, { module.glwe_encrypt_zero_pk(self, pk, source_xu, source_xe, scratch); } } pub trait GLWEEncryptSk<BE: Backend> { - fn glwe_encrypt_sk_tmp_bytes<A>( - &self, - infos: &A, - ) -> usize + fn glwe_encrypt_sk_tmp_bytes<A>(&self, infos: &A) -> usize where A: GLWEInfos;

@@ -129,22 +128,15 @@ source_xe: &mut Source,

scratch: &mut Scratch<BE>, ) where R: GLWEToMut, - S: GLWESecretPreparedToRef<BE>; + S: GLWESecretPreparedToRef<BE>; } impl<BE: Backend> GLWEEncryptSk<BE> for Module<BE> where - Module<BE>: Sized - + ModuleN - + VecZnxNormalizeTmpBytes - + VecZnxDftBytesOf - + GLWEEncryptSkInternal<BE>, + Module<BE>: Sized + ModuleN + VecZnxNormalizeTmpBytes + VecZnxDftBytesOf + GLWEEncryptSkInternal<BE>, Scratch<BE>: ScratchAvailable, { - fn glwe_encrypt_sk_tmp_bytes<A>( - &self, - infos: &A, - ) -> usize + fn glwe_encrypt_sk_tmp_bytes<A>(&self, infos: &A) -> usize where A: GLWEInfos, {

@@ -166,23 +158,20 @@ R: GLWEToMut,

P: GLWEPlaintextToRef, S: GLWESecretPreparedToRef<BE>, { - let mut res: GLWE<&mut [u8]> = res.to_mut(); - let pt: GLWEPlaintext<&[u8]> = pt.to_ref(); + let res: &mut GLWE<&mut [u8]> = &mut res.to_mut(); + let pt: &GLWEPlaintext<&[u8]> = &pt.to_ref(); + let sk: &GLWESecretPrepared<&[u8], BE> = &sk.to_ref(); - #[cfg(debug_assertions)] - { - let sk: GLWESecretPrepared<&[u8], BE> = sk.to_ref(); - assert_eq!(res.rank(), sk.rank()); - assert_eq!(res.n(), self.n() as u32); - assert_eq!(sk.n(), self.n() as u32); - assert_eq!(pt.n(), self.n() as u32); - assert!( - scratch.available() >= GLWE::encrypt_sk_tmp_bytes(self, &res), - "scratch.available(): {} < GLWECiphertext::encrypt_sk_tmp_bytes: {}", - scratch.available(), - GLWE::encrypt_sk_tmp_bytes(self, &res) - ) - } + assert_eq!(res.rank(), sk.rank()); + assert_eq!(res.n(), self.n() as u32); + assert_eq!(sk.n(), self.n() as u32); + assert_eq!(pt.n(), self.n() as u32); + assert!( + scratch.available() >= self.glwe_encrypt_sk_tmp_bytes(res), + "scratch.available(): {} < GLWE::encrypt_sk_tmp_bytes: {}", + scratch.available(), + self.glwe_encrypt_sk_tmp_bytes(res) + ); let cols: usize = (res.rank() + 1).into(); self.glwe_encrypt_sk_internal(

@@ -191,7 +180,7 @@ res.k().into(),

res.data_mut(), cols, false, - Some((&pt, 0)), + Some((pt, 0)), sk, source_xa, source_xe,

@@ -211,21 +200,18 @@ ) where

R: GLWEToMut, S: GLWESecretPreparedToRef<BE>, { - let mut res: GLWE<&mut [u8]> = res.to_mut(); + let res: &mut GLWE<&mut [u8]> = &mut res.to_mut(); + let sk: &GLWESecretPrepared<&[u8], BE> = &sk.to_ref(); - #[cfg(debug_assertions)] - { - let sk: GLWESecretPrepared<&[u8], BE> = sk.to_ref(); - assert_eq!(res.rank(), sk.rank()); - assert_eq!(res.n(), self.n() as u32); - assert_eq!(sk.n(), self.n() as u32); - assert!( - scratch.available() >= self.glwe_encrypt_sk_tmp_bytes(&res), - "scratch.available(): {} < GLWECiphertext::encrypt_sk_tmp_bytes: {}", - scratch.available(), - self.glwe_encrypt_sk_tmp_bytes(&res) - ) - } + assert_eq!(res.rank(), sk.rank()); + assert_eq!(res.n(), self.n() as u32); + assert_eq!(sk.n(), self.n() as u32); + assert!( + scratch.available() >= self.glwe_encrypt_sk_tmp_bytes(res), + "scratch.available(): {} < GLWE::encrypt_sk_tmp_bytes: {}", + scratch.available(), + self.glwe_encrypt_sk_tmp_bytes(res) + ); let cols: usize = (res.rank() + 1).into(); self.glwe_encrypt_sk_internal(

@@ -241,14 +227,11 @@ source_xe,

SIGMA, scratch, ); - } + } } pub trait GLWEEncryptPk<BE: Backend> { - fn glwe_encrypt_pk_tmp_bytes<A>( - &self, - infos: &A, - ) -> usize + fn glwe_encrypt_pk_tmp_bytes<A>(&self, infos: &A) -> usize where A: GLWEInfos;

@@ -274,29 +257,20 @@ source_xe: &mut Source,

scratch: &mut Scratch<BE>, ) where R: GLWEToMut, - K: GLWEPublicKeyPreparedToRef<BE>; - - + K: GLWEPublicKeyPreparedToRef<BE>; } impl<BE: Backend> GLWEEncryptPk<BE> for Module<BE> where - Module<BE>: GLWEEncryptPkInternal<BE> - + VecZnxDftBytesOf - + SvpPPolBytesOf - + VecZnxBigBytesOf - + VecZnxNormalizeTmpBytes, + Module<BE>: GLWEEncryptPkInternal<BE> + VecZnxDftBytesOf + SvpPPolBytesOf + VecZnxBigBytesOf + VecZnxNormalizeTmpBytes, { - fn glwe_encrypt_pk_tmp_bytes<A>( - &self, - infos: &A, - ) -> usize + fn glwe_encrypt_pk_tmp_bytes<A>(&self, infos: &A) -> usize where A: GLWEInfos, { let size: usize = infos.size(); assert_eq!(self.n() as u32, infos.n()); - ((self.bytes_of_vec_znx_dft(1, size) + self.bytes_of_vec_znx_big(1, size)) | ScalarZnx::bytes_of(self.n(), 1)) + ((self.bytes_of_vec_znx_dft(1, size) + self.bytes_of_vec_znx_big(1, size)).max(ScalarZnx::bytes_of(self.n(), 1))) + self.bytes_of_svp_ppol(1) + self.vec_znx_normalize_tmp_bytes() }

@@ -383,15 +357,12 @@ {

let res: &mut GLWE<&mut [u8]> = &mut res.to_mut(); let pk: &GLWEPublicKeyPrepared<&[u8], BE> = &pk.to_ref(); - #[cfg(debug_assertions)] - { - assert_eq!(res.base2k(), pk.base2k()); - assert_eq!(res.n(), pk.n()); - assert_eq!(res.rank(), pk.rank()); - if let Some((pt, _)) = pt { - assert_eq!(pt.to_ref().base2k(), pk.base2k()); - assert_eq!(pt.to_ref().n(), pk.n()); - } + assert_eq!(res.base2k(), pk.base2k()); + assert_eq!(res.n(), pk.n()); + assert_eq!(res.rank(), pk.rank()); + if let Some((pt, _)) = pt { + assert_eq!(pt.to_ref().base2k(), pk.base2k()); + assert_eq!(pt.to_ref().n(), pk.n()); } let base2k: usize = pk.base2k().into();

@@ -517,7 +488,7 @@ if compressed {

assert_eq!( ct.cols(), 1, - "invalid ciphertext: compressed tag=true but #cols={} != 1", + "invalid glwe: compressed tag=true but #cols={} != 1", ct.cols() ) }
M poulpy-core/src/encryption/glwe_pk.rs → poulpy-core/src/encryption/glwe_pk.rs

@@ -1,13 +1,14 @@

use poulpy_hal::{ - api::{ScratchOwnedAlloc, ScratchOwnedBorrow, VecZnxDftBytesOf, VecZnxNormalizeTmpBytes}, - layouts::{Backend, DataMut, DataRef, Module, ScratchOwned}, + api::{ScratchOwnedAlloc, ScratchOwnedBorrow}, + layouts::{Backend, DataMut, DataRef, Module, Scratch, ScratchOwned}, source::Source, }; use crate::{ - encryption::glwe_ct::{GLWEEncryptSk}, + Distribution, ScratchTakeCore, + encryption::glwe_ct::GLWEEncryptSk, layouts::{ - GLWE, GLWEPublicKey, GLWEPublicKeyToMut, + GLWE, GLWEPublicKey, GLWEPublicKeyToMut, LWEInfos, prepared::{GLWESecretPrepared, GLWESecretPreparedToRef}, }, };

@@ -33,37 +34,33 @@ R: GLWEPublicKeyToMut,

S: GLWESecretPreparedToRef<B>; } -impl<B: Backend> GLWEPublicKeyGenerate<B> for Module<B> +impl<BE: Backend> GLWEPublicKeyGenerate<BE> for Module<BE> where - Module<B>: GLWEEncryptSk<B> + VecZnxNormalizeTmpBytes + VecZnxDftBytesOf, - ScratchOwned<B>: ScratchOwnedAlloc<B> + ScratchOwnedBorrow<B>, + Module<BE>: GLWEEncryptSk<BE>, + ScratchOwned<BE>: ScratchOwnedAlloc<BE> + ScratchOwnedBorrow<BE>, + Scratch<BE>: ScratchTakeCore<BE>, { fn glwe_public_key_generate<R, S>(&self, res: &mut R, sk: &S, source_xa: &mut Source, source_xe: &mut Source) where R: GLWEPublicKeyToMut, - S: GLWESecretPreparedToRef<B>, + S: GLWESecretPreparedToRef<BE>, { let res: &mut GLWEPublicKey<&mut [u8]> = &mut res.to_mut(); - let sk: &GLWESecretPrepared<&[u8], B> = &sk.to_ref(); + let sk: &GLWESecretPrepared<&[u8], BE> = &sk.to_ref(); - #[cfg(debug_assertions)] - { - use crate::{Distribution, layouts::LWEInfos}; - - assert_eq!(res.n(), self.n() as u32); - assert_eq!(sk.n(), self.n() as u32); + assert_eq!(res.n(), self.n() as u32); + assert_eq!(sk.n(), self.n() as u32); - if sk.dist == Distribution::NONE { - panic!("invalid sk: SecretDistribution::NONE") - } + if sk.dist == Distribution::NONE { + panic!("invalid sk: SecretDistribution::NONE") } // Its ok to allocate scratch space here since pk is usually generated only once. - let mut scratch: ScratchOwned<B> = ScratchOwned::alloc(self.glwe_encrypt_sk_tmp_bytes(res)); + let mut scratch: ScratchOwned<BE> = ScratchOwned::alloc(self.glwe_encrypt_sk_tmp_bytes(res)); let mut tmp: GLWE<Vec<u8>> = GLWE::alloc_from_infos(self, res); tmp.encrypt_zero_sk(self, sk, source_xa, source_xe, scratch.borrow()); res.dist = sk.dist; } -}+}
M poulpy-core/src/encryption/glwe_to_lwe_ksk.rs → poulpy-core/src/encryption/glwe_to_lwe_ksk.rs

@@ -1,23 +1,17 @@

use poulpy_hal::{ - api::{ - 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}, - oep::{ScratchAvailableImpl, VecZnxFillUniformImpl}, - source::Source + api::{ModuleN, VecZnxAutomorphismInplace}, + layouts::{Backend, DataMut, Module, Scratch, ZnxView, ZnxViewMut, ZnxZero}, + source::Source, }; use crate::{ ScratchTakeCore, + encryption::gglwe_ksk::GLWESwitchingKeyEncryptSk, layouts::{ - GGLWEInfos, GLWESecret, GLWESwitchingKey, GLWEToLWESwitchingKey, LWEInfos, LWESecret, Rank, GLWEToLWESwitchingKeyToMut, - prepared::GLWESecretPrepared, + GGLWEInfos, GLWESecret, GLWESecretToRef, GLWESwitchingKey, GLWEToLWESwitchingKey, GLWEToLWESwitchingKeyToMut, LWEInfos, + LWESecret, LWESecretToRef, Rank, + prepared::{GLWESecretPrepared, GLWESecretPreparedAlloc}, }, - encryption::gglwe_ksk::GLWESwitchingKeyEncryptSk, }; impl GLWEToLWESwitchingKey<Vec<u8>> {

@@ -28,187 +22,77 @@ M: GLWEToLWESwitchingKeyEncrypt<BE>,

{ 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> { - pub fn encrypt_sk<M, DLwe, DGlwe, BE: Backend>( + pub fn encrypt_sk<M, S1, S2, BE: Backend>( &mut self, module: &M, - sk_lwe: &LWESecret<DLwe>, - sk_glwe: &GLWESecret<DGlwe>, + sk_lwe: &S1, + sk_glwe: &S2, source_xa: &mut Source, source_xe: &mut Source, scratch: &mut Scratch<BE>, ) where M: GLWEToLWESwitchingKeyEncrypt<BE>, - DLwe: DataRef, - DGlwe: DataRef, - Scratch<BE>: ScratchAvailable + ScratchTakeCore<BE>, + S1: LWESecretToRef, + S2: GLWESecretToRef, + Scratch<BE>: 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> -{ +pub trait GLWEToLWESwitchingKeyEncrypt<BE: Backend> { 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>( + fn glwe_to_lwe_switching_key_encrypt_sk<R, S1, S2>( &self, res: &mut R, - sk_lwe: &LWESecret<DLwe>, - sk_glwe: &GLWESecret<DataGlwe>, + sk_lwe: &S1, + sk_glwe: &S2, source_xa: &mut Source, source_xe: &mut Source, scratch: &mut Scratch<BE>, ) where - R: GLWEToLWESwitchingKeyToMut, - Scratch<BE>: ScratchAvailable + ScratchTakeCore<BE>; + S1: LWESecretToRef, + S2: GLWESecretToRef, + R: GLWEToLWESwitchingKeyToMut; } -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> +impl<BE: Backend> GLWEToLWESwitchingKeyEncrypt<BE> for Module<BE> +where + Module<BE>: ModuleN + GLWESwitchingKeyEncryptSk<BE> + GLWESecretPreparedAlloc<BE> + VecZnxAutomorphismInplace<BE>, + Scratch<BE>: ScratchTakeCore<BE>, { - fn glwe_to_lwe_switching_key_encrypt_sk_tmp_bytes<A>(&self, infos: &A) -> usize + fn glwe_to_lwe_switching_key_encrypt_sk_tmp_bytes<A>(&self, infos: &A) -> usize where - A: GGLWEInfos + A: GGLWEInfos, { GLWESecretPrepared::bytes_of(self, infos.rank_in()) - + (GLWESwitchingKey::encrypt_sk_tmp_bytes(self, infos) | GLWESecret::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>( + fn glwe_to_lwe_switching_key_encrypt_sk<R, S1, S2>( &self, res: &mut R, - sk_lwe: &LWESecret<DLwe>, - sk_glwe: &GLWESecret<DataGlwe>, + sk_lwe: &S1, + sk_glwe: &S2, source_xa: &mut Source, source_xe: &mut Source, scratch: &mut Scratch<BE>, ) where + S1: LWESecretToRef, + S2: GLWESecretToRef, R: GLWEToLWESwitchingKeyToMut, - Scratch<BE>: ScratchAvailable + ScratchTakeCore<BE>, { - let res: &mut GLWEToLWESwitchingKey<&mut [u8]> = &mut res.to_mut(); + let sk_lwe: &LWESecret<&[u8]> = &sk_lwe.to_ref(); + let sk_glwe: &GLWESecret<&[u8]> = &sk_glwe.to_ref(); - #[cfg(debug_assertions)] - { - assert!(sk_lwe.n().0 <= self.n() as u32); - } + assert!(sk_lwe.n().0 <= self.n() as u32); let (mut sk_lwe_as_glwe, scratch_1) = scratch.take_glwe_secret(self, Rank(1)); sk_lwe_as_glwe.data.zero();

@@ -222,6 +106,6 @@ &sk_lwe_as_glwe,

source_xa, source_xe, scratch_1, - ); + ); } -}+}
M poulpy-core/src/encryption/lwe_ct.rs → poulpy-core/src/encryption/lwe_ct.rs

@@ -7,11 +7,10 @@ };

use crate::{ encryption::{SIGMA, SIGMA_BOUND}, - layouts::{LWE, LWEInfos, LWEPlaintext, LWESecret, LWEToMut, LWEPlaintextToRef, LWESecretToRef}, + layouts::{LWE, LWEInfos, LWEPlaintext, LWEPlaintextToRef, LWESecret, LWESecretToRef, LWEToMut}, }; impl<DataSelf: DataMut> LWE<DataSelf> { - pub fn encrypt_sk<P, S, M, BE: Backend>(&mut self, module: &M, pt: &P, sk: &S, source_xa: &mut Source, source_xe: &mut Source) where P: LWEPlaintextToRef,

@@ -23,27 +22,24 @@ module.lwe_encrypt_sk(self, pt, sk, source_xa, source_xe);

} } -pub trait LWEEncryptSk<BE: Backend> -where - Self: Sized + ZnFillUniform + ZnAddNormal + ZnNormalizeInplace<BE>, -{ +pub trait LWEEncryptSk<BE: Backend> { fn lwe_encrypt_sk<R, P, S>(&self, res: &mut R, pt: &P, sk: &S, source_xa: &mut Source, source_xe: &mut Source) where R: LWEToMut, P: LWEPlaintextToRef, - S: LWESecretToRef, - BE: Backend + ScratchOwnedAllocImpl<BE> + ScratchOwnedBorrowImpl<BE>; + S: LWESecretToRef; } -impl<BE: Backend> LWEEncryptSk<BE> for Module<BE> where +impl<BE: Backend> LWEEncryptSk<BE> for Module<BE> +where Self: Sized + ZnFillUniform + ZnAddNormal + ZnNormalizeInplace<BE>, + BE: ScratchOwnedAllocImpl<BE> + ScratchOwnedBorrowImpl<BE>, { fn lwe_encrypt_sk<R, P, S>(&self, res: &mut R, pt: &P, sk: &S, source_xa: &mut Source, source_xe: &mut Source) where R: LWEToMut, P: LWEPlaintextToRef, S: LWESecretToRef, - BE: Backend + ScratchOwnedAllocImpl<BE> + ScratchOwnedBorrowImpl<BE>, { let res: &mut LWE<&mut [u8]> = &mut res.to_mut(); let pt: &LWEPlaintext<&[u8]> = &pt.to_ref();

@@ -101,6 +97,6 @@ );

(0..res.size()).for_each(|i| { res.data.at_mut(0, i)[0] = tmp_znx.at(0, i)[0]; - }); + }); } -}+}
M poulpy-core/src/encryption/lwe_ksk.rs → poulpy-core/src/encryption/lwe_ksk.rs

@@ -1,22 +1,17 @@

use poulpy_hal::{ - api::{ - ModuleN, SvpApplyDftToDftInplace, SvpPPolAlloc, SvpPPolBytesOf, SvpPrepare, VecZnxAddInplace, VecZnxAddNormal, VecZnxAddScalarInplace, - VecZnxAutomorphismInplace, VecZnxBigNormalize, VecZnxDftApply, VecZnxDftBytesOf, VecZnxFillUniform, - VecZnxIdftApplyConsume, VecZnxNormalize, VecZnxNormalizeInplace, VecZnxNormalizeTmpBytes, VecZnxSub, VecZnxSubInplace, - VecZnxSwitchRing, - }, - layouts::{Backend, DataMut, DataRef, Module, Scratch, ZnxView, ZnxViewMut}, + api::{ModuleN, VecZnxAutomorphismInplace}, + layouts::{Backend, DataMut, Module, Scratch, ZnxView, ZnxViewMut}, source::Source, }; use crate::{ + ScratchTakeCore, + encryption::gglwe_ksk::GLWESwitchingKeyEncryptSk, layouts::{ - GLWESecretAlloc, - GGLWEInfos, GLWESecret, GLWESwitchingKey, LWEInfos, LWESecret, LWESwitchingKey, Rank, + GGLWEInfos, GLWESecret, GLWESwitchingKey, LWEInfos, LWESecret, LWESecretToRef, LWESwitchingKey, LWESwitchingKeyToMut, + Rank, prepared::{GLWESecretPrepared, GLWESecretPreparedAlloc}, }, - encryption::gglwe_ksk::GLWESwitchingKeyEncryptSk, - ScratchTakeCore, }; impl LWESwitchingKey<Vec<u8>> {

@@ -27,145 +22,65 @@ M: LWESwitchingKeyEncrypt<BE>,

{ module.lwe_switching_key_encrypt_sk_tmp_bytes(infos) } - } impl<D: DataMut> LWESwitchingKey<D> { - #[allow(clippy::too_many_arguments)] - pub fn encrypt_sk<DIn, DOut, B: Backend>( + pub fn encrypt_sk<S1, S2, M, BE: Backend>( &mut self, - module: &Module<B>, - sk_lwe_in: &LWESecret<DIn>, - sk_lwe_out: &LWESecret<DOut>, + module: &M, + sk_lwe_in: &S1, + sk_lwe_out: &S2, source_xa: &mut Source, source_xe: &mut Source, - scratch: &mut Scratch<B>, + scratch: &mut Scratch<BE>, ) where - DIn: DataRef, - DOut: 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>: ScratchTakeCore<B>, + S1: LWESecretToRef, + S2: LWESecretToRef, + M: LWESwitchingKeyEncrypt<BE>, { - #[cfg(debug_assertions)] - { - assert!(sk_lwe_in.n().0 <= self.n().0); - assert!(sk_lwe_out.n().0 <= self.n().0); - assert!(self.n().0 <= module.n() as u32); - } - - let (mut sk_in_glwe, scratch_1) = scratch.take_glwe_secret(module, Rank(1)); - let (mut sk_out_glwe, scratch_2) = scratch_1.take_glwe_secret(module, Rank(1)); - - sk_out_glwe.data.at_mut(0, 0)[..sk_lwe_out.n().into()].copy_from_slice(sk_lwe_out.data.at(0, 0)); - sk_out_glwe.data.at_mut(0, 0)[sk_lwe_out.n().into()..].fill(0); - module.vec_znx_automorphism_inplace(-1, &mut sk_out_glwe.data.as_vec_znx_mut(), 0, scratch_2); - - sk_in_glwe.data.at_mut(0, 0)[..sk_lwe_in.n().into()].copy_from_slice(sk_lwe_in.data.at(0, 0)); - sk_in_glwe.data.at_mut(0, 0)[sk_lwe_in.n().into()..].fill(0); - module.vec_znx_automorphism_inplace(-1, &mut sk_in_glwe.data.as_vec_znx_mut(), 0, scratch_2); - - self.0.encrypt_sk( - module, - &sk_in_glwe, - &sk_out_glwe, - source_xa, - source_xe, - scratch_2, - ); + module.lwe_switching_key_encrypt_sk(self, sk_lwe_in, sk_lwe_out, source_xa, source_xe, scratch); } } -pub trait LWESwitchingKeyEncrypt<BE: Backend> -where - Self: Sized - + ModuleN - + SvpPPolBytesOf - + SvpPPolAlloc<BE> - + VecZnxNormalizeTmpBytes - + VecZnxDftBytesOf - + VecZnxAutomorphismInplace<BE> - + VecZnxAddScalarInplace - + VecZnxBigNormalize<BE> - + VecZnxDftApply<BE> - + SvpApplyDftToDftInplace<BE> - + VecZnxIdftApplyConsume<BE> - + VecZnxFillUniform - + VecZnxSubInplace - + VecZnxAddInplace - + VecZnxNormalizeInplace<BE> - + VecZnxAddNormal - + VecZnxNormalize<BE> - + VecZnxSub - + SvpPrepare<BE> - + VecZnxSwitchRing - + GLWESecretAlloc - + GLWESecretPreparedAlloc<BE> -{ +pub trait LWESwitchingKeyEncrypt<BE: Backend> { fn lwe_switching_key_encrypt_sk_tmp_bytes<A>(&self, infos: &A) -> usize where A: GGLWEInfos; + + fn lwe_switching_key_encrypt_sk<R, S1, S2>( + &self, + res: &mut R, + sk_lwe_in: &S1, + sk_lwe_out: &S2, + source_xa: &mut Source, + source_xe: &mut Source, + scratch: &mut Scratch<BE>, + ) where + R: LWESwitchingKeyToMut, + S1: LWESecretToRef, + S2: LWESecretToRef; } -impl<BE:Backend> LWESwitchingKeyEncrypt<BE> for Module<BE> where - Self: ModuleN - + SvpPPolBytesOf - + SvpPPolAlloc<BE> - + VecZnxNormalizeTmpBytes - + VecZnxDftBytesOf - + VecZnxAutomorphismInplace<BE> - + VecZnxAddScalarInplace - + VecZnxBigNormalize<BE> - + VecZnxDftApply<BE> - + SvpApplyDftToDftInplace<BE> - + VecZnxIdftApplyConsume<BE> - + VecZnxFillUniform - + VecZnxSubInplace - + VecZnxAddInplace - + VecZnxNormalizeInplace<BE> - + VecZnxAddNormal - + VecZnxNormalize<BE> - + VecZnxSub - + SvpPrepare<BE> - + VecZnxSwitchRing - + GLWESecretAlloc - + GLWESecretPreparedAlloc<BE> - + GLWESwitchingKeyEncryptSk<BE> - , +impl<BE: Backend> LWESwitchingKeyEncrypt<BE> for Module<BE> +where + Self: ModuleN + GLWESwitchingKeyEncryptSk<BE> + GLWESecretPreparedAlloc<BE> + VecZnxAutomorphismInplace<BE>, + Scratch<BE>: ScratchTakeCore<BE>, { fn lwe_switching_key_encrypt_sk_tmp_bytes<A>(&self, infos: &A) -> usize where - A: GGLWEInfos + A: GGLWEInfos, { - debug_assert_eq!( + assert_eq!( infos.dsize().0, 1, "dsize > 1 is not supported for LWESwitchingKey" ); - debug_assert_eq!( + assert_eq!( infos.rank_in().0, 1, "rank_in > 1 is not supported for LWESwitchingKey" ); - debug_assert_eq!( + assert_eq!( infos.rank_out().0, 1, "rank_out > 1 is not supported for LWESwitchingKey"

@@ -174,4 +89,47 @@ GLWESecret::bytes_of(self, Rank(1))

+ GLWESecretPrepared::bytes_of(self, Rank(1)) + GLWESwitchingKey::encrypt_sk_tmp_bytes(self, infos) } -}+ + #[allow(clippy::too_many_arguments)] + fn lwe_switching_key_encrypt_sk<R, S1, S2>( + &self, + res: &mut R, + sk_lwe_in: &S1, + sk_lwe_out: &S2, + source_xa: &mut Source, + source_xe: &mut Source, + scratch: &mut Scratch<BE>, + ) where + R: LWESwitchingKeyToMut, + S1: LWESecretToRef, + S2: LWESecretToRef, + { + let res: &mut LWESwitchingKey<&mut [u8]> = &mut res.to_mut(); + let sk_lwe_in: &LWESecret<&[u8]> = &sk_lwe_in.to_ref(); + let sk_lwe_out = &sk_lwe_out.to_ref(); + + assert!(sk_lwe_in.n().0 <= res.n().0); + assert!(sk_lwe_out.n().0 <= res.n().0); + assert!(res.n() <= self.n() as u32); + + let (mut sk_in_glwe, scratch_1) = scratch.take_glwe_secret(self, Rank(1)); + let (mut sk_out_glwe, scratch_2) = scratch_1.take_glwe_secret(self, Rank(1)); + + sk_out_glwe.data.at_mut(0, 0)[..sk_lwe_out.n().into()].copy_from_slice(sk_lwe_out.data.at(0, 0)); + sk_out_glwe.data.at_mut(0, 0)[sk_lwe_out.n().into()..].fill(0); + self.vec_znx_automorphism_inplace(-1, &mut sk_out_glwe.data.as_vec_znx_mut(), 0, scratch_2); + + sk_in_glwe.data.at_mut(0, 0)[..sk_lwe_in.n().into()].copy_from_slice(sk_lwe_in.data.at(0, 0)); + sk_in_glwe.data.at_mut(0, 0)[sk_lwe_in.n().into()..].fill(0); + self.vec_znx_automorphism_inplace(-1, &mut sk_in_glwe.data.as_vec_znx_mut(), 0, scratch_2); + + self.glwe_switching_key_encrypt_sk( + &mut res.0, + &sk_in_glwe, + &sk_out_glwe, + source_xa, + source_xe, + scratch_2, + ); + } +}
M poulpy-core/src/encryption/lwe_to_glwe_ksk.rs → poulpy-core/src/encryption/lwe_to_glwe_ksk.rs

@@ -1,20 +1,16 @@

use poulpy_hal::{ - api::{ - 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}, + api::{ModuleN, VecZnxAutomorphismInplace}, + layouts::{Backend, DataMut, Module, Scratch, ZnxView, ZnxViewMut}, source::Source, }; use crate::{ - layouts::{GGLWEInfos, GLWESecret, GLWESwitchingKey, LWEInfos, LWESecret, LWEToGLWESwitchingKey, LWEToGLWESwitchingKeyToMut, Rank}, ScratchTakeCore, encryption::gglwe_ksk::GLWESwitchingKeyEncryptSk, + layouts::{ + GGLWEInfos, GLWESecret, GLWESecretToRef, GLWESwitchingKey, LWEInfos, LWESecret, LWESecretToRef, LWEToGLWESwitchingKey, + LWEToGLWESwitchingKeyToMut, Rank, + }, }; impl LWEToGLWESwitchingKey<Vec<u8>> {

@@ -25,198 +21,81 @@ M: LWEToGLWESwitchingKeyEncrypt<BE>,

{ 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> { - pub fn encrypt_sk<M, DLwe, DGlwe, BE: Backend>( + pub fn encrypt_sk<S1, S2, M, BE: Backend>( &mut self, module: &M, - sk_lwe: &LWESecret<DLwe>, - sk_glwe: &GLWESecret<DGlwe>, + sk_lwe: &S1, + sk_glwe: &S2, source_xa: &mut Source, source_xe: &mut Source, scratch: &mut Scratch<BE>, ) where + S1: LWESecretToRef, + S2: GLWESecretToRef, M: LWEToGLWESwitchingKeyEncrypt<BE>, - DLwe: DataRef, - DGlwe: DataRef, - Scratch<BE>: ScratchAvailable + ScratchTakeCore<BE>, + Scratch<BE>: 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> -{ +pub trait LWEToGLWESwitchingKeyEncrypt<BE: Backend> { 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>( + fn lwe_to_glwe_switching_key_encrypt_sk<R, S1, S2>( &self, res: &mut R, - sk_lwe: &LWESecret<DLwe>, - sk_glwe: &GLWESecret<DataGlwe>, + sk_lwe: &S1, + sk_glwe: &S2, source_xa: &mut Source, source_xe: &mut Source, scratch: &mut Scratch<BE>, ) where - R: LWEToGLWESwitchingKeyToMut, - Scratch<BE>: ScratchAvailable + ScratchTakeCore<BE>; + S1: LWESecretToRef, + S2: GLWESecretToRef, + R: LWEToGLWESwitchingKeyToMut; } -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> +impl<BE: Backend> LWEToGLWESwitchingKeyEncrypt<BE> for Module<BE> +where + Self: ModuleN + GLWESwitchingKeyEncryptSk<BE> + VecZnxAutomorphismInplace<BE>, + Scratch<BE>: ScratchTakeCore<BE>, { fn lwe_to_glwe_switching_key_encrypt_sk_tmp_bytes<A>(&self, infos: &A) -> usize where - A: GGLWEInfos + 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()) + 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>( + fn lwe_to_glwe_switching_key_encrypt_sk<R, S1, S2>( &self, res: &mut R, - sk_lwe: &LWESecret<DLwe>, - sk_glwe: &GLWESecret<DataGlwe>, + sk_lwe: &S1, + sk_glwe: &S2, source_xa: &mut Source, source_xe: &mut Source, scratch: &mut Scratch<BE>, - ) where + ) where + S1: LWESecretToRef, + S2: GLWESecretToRef, R: LWEToGLWESwitchingKeyToMut, - Scratch<BE>: ScratchAvailable + ScratchTakeCore<BE>, { let res: &mut LWEToGLWESwitchingKey<&mut [u8]> = &mut res.to_mut(); - - #[cfg(debug_assertions)] - { - use crate::layouts::LWEInfos; + let sk_lwe: &LWESecret<&[u8]> = &sk_lwe.to_ref(); + let sk_glwe: &GLWESecret<&[u8]> = &sk_glwe.to_ref(); - assert!(sk_lwe.n().0 <= self.n() as u32); - } + assert!(sk_lwe.n().0 <= self.n() as u32); 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));

@@ -232,4 +111,4 @@ source_xe,

scratch_1, ); } -}+}
M poulpy-core/src/layouts/prepared/glwe_sk.rs → poulpy-core/src/layouts/prepared/glwe_sk.rs

@@ -66,7 +66,7 @@

fn bytes_of_glwe_secret(&self, rank: Rank) -> usize { self.bytes_of_svp_ppol(rank.into()) } - fn bytes_of_glwe_secret_from_infos<A>(&self, infos: &A) -> usize + fn bytes_of_glwe_secret_prepared_from_infos<A>(&self, infos: &A) -> usize where A: GLWEInfos, {

@@ -98,7 +98,7 @@ where

A: GLWEInfos, M: GLWESecretPreparedAlloc<B>, { - module.bytes_of_glwe_secret_from_infos(infos) + module.bytes_of_glwe_secret_prepared_from_infos(infos) } pub fn bytes_of<M>(module: &M, rank: Rank) -> usize