From 69d04c71bc245388af2caea3879b0d91055b12f5 Mon Sep 17 00:00:00 2001 From: Pro7ech Date: Fri, 17 Oct 2025 10:59:35 +0200 Subject: [PATCH] gglwe compressed encrypt --- .../src/encryption/compressed/gglwe_ct.rs | 141 ++++++++++-------- poulpy-core/src/encryption/ggsw_ct.rs | 41 +++-- 2 files changed, 96 insertions(+), 86 deletions(-) diff --git a/poulpy-core/src/encryption/compressed/gglwe_ct.rs b/poulpy-core/src/encryption/compressed/gglwe_ct.rs index cca081f..98cadfb 100644 --- a/poulpy-core/src/encryption/compressed/gglwe_ct.rs +++ b/poulpy-core/src/encryption/compressed/gglwe_ct.rs @@ -1,50 +1,56 @@ use poulpy_hal::{ - api::{ - ModuleN, ScratchAvailable, VecZnxAddScalarInplace, VecZnxDftBytesOf, VecZnxNormalizeInplace, VecZnxNormalizeTmpBytes, - ZnNormalizeInplace, - }, - layouts::{Backend, DataMut, DataRef, Module, ScalarZnx, ScalarZnxToRef, Scratch, ZnxZero}, + api::{ModuleN, ScratchAvailable, VecZnxAddScalarInplace, VecZnxDftBytesOf, VecZnxNormalizeInplace, VecZnxNormalizeTmpBytes}, + layouts::{Backend, DataMut, Module, ScalarZnx, ScalarZnxToRef, Scratch, ZnxInfos, ZnxZero}, source::Source, }; use crate::{ ScratchTakeCore, - encryption::{SIGMA, glwe_ct::GLWEEncryptSkInternal}, + encryption::{ + SIGMA, + glwe_ct::{GLWEEncryptSk, GLWEEncryptSkInternal}, + }, layouts::{ - GGLWE, GGLWEInfos, LWEInfos, + GGLWEInfos, GLWEPlaintextAlloc, LWEInfos, compressed::{GGLWECompressed, GGLWECompressedToMut}, - prepared::{GLWESecretPrepared, GLWESecretPreparedToRef}, + prepared::GLWESecretPreparedToRef, }, }; impl GGLWECompressed { #[allow(clippy::too_many_arguments)] - pub fn encrypt_sk( + pub fn encrypt_sk( &mut self, - module: &Module, - pt: &ScalarZnx, - sk: &GLWESecretPrepared, + module: &M, + pt: &P, + sk: &S, seed: [u8; 32], source_xe: &mut Source, - scratch: &mut Scratch, + scratch: &mut Scratch, ) where - Module: GGLWECompressedEncryptSk, + P: ScalarZnxToRef, + S: GLWESecretPreparedToRef, + M: GGLWECompressedEncryptSk, { module.gglwe_compressed_encrypt_sk(self, pt, sk, seed, source_xe, scratch); } } impl GGLWECompressed> { - pub fn encrypt_sk_tmp_bytes(module: &Module, infos: &A) -> usize + pub fn encrypt_sk_tmp_bytes(module: &M, infos: &A) -> usize where A: GGLWEInfos, - Module: VecZnxNormalizeTmpBytes + VecZnxDftBytesOf + VecZnxNormalizeTmpBytes, + M: GGLWECompressedEncryptSk, { - GGLWE::encrypt_sk_tmp_bytes(module, infos) + module.gglwe_compressed_encrypt_sk_tmp_bytes(infos) } } -pub trait GGLWECompressedEncryptSk { +pub trait GGLWECompressedEncryptSk { + fn gglwe_compressed_encrypt_sk_tmp_bytes(&self, infos: &A) -> usize + where + A: GGLWEInfos; + fn gglwe_compressed_encrypt_sk( &self, res: &mut R, @@ -52,24 +58,33 @@ pub trait GGLWECompressedEncryptSk { sk: &S, seed: [u8; 32], source_xe: &mut Source, - scratch: &mut Scratch, + scratch: &mut Scratch, ) where R: GGLWECompressedToMut, P: ScalarZnxToRef, - S: GLWESecretPreparedToRef; + S: GLWESecretPreparedToRef; } -impl GGLWECompressedEncryptSk for Module +impl GGLWECompressedEncryptSk for Module where - Module: ModuleN - + GLWEEncryptSkInternal - + VecZnxNormalizeInplace - + VecZnxNormalizeTmpBytes + Module: ModuleN + + GLWEEncryptSkInternal + + GLWEEncryptSk + VecZnxDftBytesOf + + VecZnxNormalizeInplace + VecZnxAddScalarInplace - + ZnNormalizeInplace, - Scratch: ScratchAvailable + ScratchTakeCore, + + VecZnxNormalizeTmpBytes, + Scratch: ScratchTakeCore, { + fn gglwe_compressed_encrypt_sk_tmp_bytes(&self, infos: &A) -> usize + where + A: GGLWEInfos, + { + self.glwe_encrypt_sk_tmp_bytes(infos) + .max(self.vec_znx_normalize_tmp_bytes()) + + self.bytes_of_glwe_plaintext_from_infos(infos) + } + fn gglwe_compressed_encrypt_sk( &self, res: &mut R, @@ -77,52 +92,48 @@ where sk: &S, seed: [u8; 32], source_xe: &mut Source, - scratch: &mut Scratch, + scratch: &mut Scratch, ) where R: GGLWECompressedToMut, P: ScalarZnxToRef, - S: GLWESecretPreparedToRef, + S: GLWESecretPreparedToRef, { let res: &mut GGLWECompressed<&mut [u8]> = &mut res.to_mut(); let pt: &ScalarZnx<&[u8]> = &pt.to_ref(); - #[cfg(debug_assertions)] - { - use poulpy_hal::layouts::ZnxInfos; - let sk = &sk.to_ref(); + let sk = &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() >= GGLWECompressed::encrypt_sk_tmp_bytes(self, res), - "scratch.available: {} < GGLWECiphertext::encrypt_sk_tmp_bytes: {}", - scratch.available(), - GGLWECompressed::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() >= GGLWECompressed::encrypt_sk_tmp_bytes(self, res), + "scratch.available: {} < GGLWECiphertext::encrypt_sk_tmp_bytes: {}", + scratch.available(), + GGLWECompressed::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() + ); let dnum: usize = res.dnum().into(); let dsize: usize = res.dsize().into(); diff --git a/poulpy-core/src/encryption/ggsw_ct.rs b/poulpy-core/src/encryption/ggsw_ct.rs index 72b6846..a758384 100644 --- a/poulpy-core/src/encryption/ggsw_ct.rs +++ b/poulpy-core/src/encryption/ggsw_ct.rs @@ -1,6 +1,6 @@ use poulpy_hal::{ - api::{ModuleN, VecZnxAddScalarInplace, VecZnxDftBytesOf, VecZnxNormalizeInplace}, - layouts::{Backend, DataMut, Module, ScalarZnx, ScalarZnxToRef, Scratch, VecZnx, ZnxInfos, ZnxZero}, + api::{ModuleN, VecZnxAddScalarInplace, VecZnxDftBytesOf, VecZnxNormalizeInplace, VecZnxNormalizeTmpBytes}, + layouts::{Backend, DataMut, Module, ScalarZnx, ScalarZnxToRef, Scratch, ZnxInfos, ZnxZero}, source::Source, }; @@ -8,7 +8,7 @@ use crate::{ SIGMA, ScratchTakeCore, encryption::glwe_ct::{GLWEEncryptSk, GLWEEncryptSkInternal}, layouts::{ - GGSW, GGSWInfos, GGSWToMut, GLWEInfos, LWEInfos, + GGSW, GGSWInfos, GGSWToMut, GLWEInfos, GLWEPlaintextAlloc, LWEInfos, prepared::{GLWESecretPrepared, GLWESecretPreparedToRef}, }, }; @@ -43,7 +43,7 @@ impl GGSW { } } -pub trait GGSWEncryptSk { +pub trait GGSWEncryptSk { fn ggsw_encrypt_sk_tmp_bytes(&self, infos: &A) -> usize where A: GGSWInfos; @@ -55,32 +55,31 @@ pub trait GGSWEncryptSk { sk: &S, source_xa: &mut Source, source_xe: &mut Source, - scratch: &mut Scratch, + scratch: &mut Scratch, ) where R: GGSWToMut, P: ScalarZnxToRef, - S: GLWESecretPreparedToRef; + S: GLWESecretPreparedToRef; } -impl GGSWEncryptSk for Module +impl GGSWEncryptSk for Module where - Module: ModuleN - + GLWEEncryptSkInternal - + GLWEEncryptSk + Module: ModuleN + + GLWEEncryptSkInternal + + GLWEEncryptSk + VecZnxDftBytesOf - + VecZnxNormalizeInplace - + VecZnxAddScalarInplace, - Scratch: ScratchTakeCore, + + VecZnxNormalizeInplace + + VecZnxAddScalarInplace + + VecZnxNormalizeTmpBytes, + Scratch: ScratchTakeCore, { fn ggsw_encrypt_sk_tmp_bytes(&self, infos: &A) -> usize where A: GGSWInfos, { - let size = infos.size(); 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) + .max(self.vec_znx_normalize_tmp_bytes()) + + self.bytes_of_glwe_plaintext_from_infos(infos) } fn ggsw_encrypt_sk( @@ -90,15 +89,15 @@ where sk: &S, source_xa: &mut Source, source_xe: &mut Source, - scratch: &mut Scratch, + scratch: &mut Scratch, ) where R: GGSWToMut, P: ScalarZnxToRef, - S: GLWESecretPreparedToRef, + S: GLWESecretPreparedToRef, { 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(); + let sk: &GLWESecretPrepared<&[u8], BE> = &sk.to_ref(); assert_eq!(res.rank(), sk.rank()); assert_eq!(res.n(), self.n() as u32); @@ -111,7 +110,7 @@ where let dsize: usize = res.dsize().into(); let cols: usize = (rank + 1).into(); - let (mut tmp_pt, scratch_1) = scratch.take_glwe_pt(self, &res.glwe_layout()); + let (mut tmp_pt, scratch_1) = scratch.take_glwe_pt(self, res); for row_i in 0..res.dnum().into() { tmp_pt.data.zero();