use poulpy_hal::{ api::{ ScratchOwnedAlloc, ScratchOwnedBorrow, SvpApplyDftToDftInplace, VecZnxBigAddInplace, VecZnxBigAddSmallInplace, VecZnxBigBytesOf, VecZnxBigNormalize, VecZnxDftApply, VecZnxDftBytesOf, VecZnxIdftApplyConsume, VecZnxNormalizeInplace, VecZnxNormalizeTmpBytes, VecZnxSubInplace, ScratchTakeBasic, }, layouts::{Backend, DataRef, Module, Scratch, ScratchOwned}, oep::{ScratchOwnedAllocImpl, ScratchOwnedBorrowImpl}, }; use crate::{ decryption::GLWEDecryption, layouts::{ GLWE, GLWEPlaintext, GLWEPlaintextToRef, GLWEToRef, LWEInfos, prepared::{GLWESecretPrepared, GLWESecretPreparedToRef}, }, }; impl GLWE { pub fn noise(&self, module: &M, sk_prepared: &S, pt_want: &P, scratch: &mut Scratch) -> f64 where M: GLWENoise, S: GLWESecretPreparedToRef, P: GLWEPlaintextToRef, { module.glwe_noise(self, sk_prepared, pt_want, scratch) } // pub fn noise( // &self, // module: &Module, // sk_prepared: &GLWESecretPrepared, // pt_want: &GLWEPlaintext, // scratch: &mut Scratch, // ) -> f64 // where // DataSk: DataRef, // DataPt: DataRef, // B: Backend, // Module: VecZnxDftApply // + VecZnxSubInplace // + VecZnxNormalizeInplace // + SvpApplyDftToDftInplace // + VecZnxIdftApplyConsume // + VecZnxBigAddInplace // + VecZnxBigAddSmallInplace // + VecZnxBigNormalize, // Scratch:, // { // let mut pt_have: GLWEPlaintext> = GLWEPlaintext::alloc_from_infos(module, self); // self.decrypt(module, &mut pt_have, sk_prepared, scratch); // module.vec_znx_sub_inplace(&mut pt_have.data, 0, &pt_want.data, 0); // module.vec_znx_normalize_inplace(self.base2k().into(), &mut pt_have.data, 0, scratch); // pt_have.data.std(self.base2k().into(), 0).log2() // } pub fn assert_noise( &self, module: &M, sk_prepared: &GLWESecretPrepared, pt_want: &GLWEPlaintext, max_noise: f64, ) where DataSk: DataRef, DataPt: DataRef, M: GLWENoise, BE: Backend + ScratchOwnedAllocImpl + ScratchOwnedBorrowImpl + ScratchOwnedBorrow, { module.glwe_assert_noise(self, sk_prepared, pt_want, max_noise); } // pub fn assert_noise( // &self, // module: &Module, // sk_prepared: &GLWESecretPrepared, // pt_want: &GLWEPlaintext, // max_noise: f64, // ) where // DataSk: DataRef, // DataPt: DataRef, // Module: VecZnxDftBytesOf // + VecZnxBigBytesOf // + VecZnxDftApply // + SvpApplyDftToDftInplace // + VecZnxIdftApplyConsume // + VecZnxBigAddInplace // + VecZnxBigAddSmallInplace // + VecZnxBigNormalize // + VecZnxNormalizeTmpBytes // + VecZnxSubInplace // + VecZnxNormalizeInplace, // B: Backend + ScratchOwnedAllocImpl + ScratchOwnedBorrowImpl, // { // let mut scratch: ScratchOwned = ScratchOwned::alloc(GLWE::decrypt_tmp_bytes(module, self)); // let noise_have: f64 = self.noise(module, sk_prepared, pt_want, scratch.borrow()); // assert!(noise_have <= max_noise, "{noise_have} {max_noise}"); // } } pub trait GLWENoise { fn glwe_noise(&self, res: &R, sk_prepared: &S, pt_want: &P, scratch: &mut Scratch) -> f64 where R: GLWEToRef, S: GLWESecretPreparedToRef, P: GLWEPlaintextToRef; fn glwe_assert_noise(&self, res: &R, sk_prepared: &S, pt_want: &P, max_noise: f64) where R: GLWEToRef, S: GLWESecretPreparedToRef, P: GLWEPlaintextToRef, BE: ScratchOwnedAllocImpl + ScratchOwnedBorrowImpl + ScratchOwnedBorrow; } impl GLWENoise for Module where Module: VecZnxDftBytesOf + VecZnxBigBytesOf + VecZnxDftApply + SvpApplyDftToDftInplace + VecZnxIdftApplyConsume + VecZnxBigAddInplace + VecZnxBigAddSmallInplace + VecZnxBigNormalize + VecZnxNormalizeTmpBytes + VecZnxSubInplace + VecZnxNormalizeInplace + GLWEDecryption, Scratch: ScratchTakeBasic + ScratchOwnedAllocImpl + ScratchOwnedBorrowImpl + ScratchOwnedBorrowImpl + ScratchOwnedBorrow, { fn glwe_noise(&self, res: &R, sk_prepared: &S, pt_want: &P, scratch: &mut Scratch) -> f64 where R: GLWEToRef, S: GLWESecretPreparedToRef, P: GLWEPlaintextToRef, { let res_ref: &GLWE<&[u8]> = &res.to_ref(); let pt_want: &GLWEPlaintext<&[u8]> = &pt_want.to_ref(); let mut pt_have: GLWEPlaintext> = GLWEPlaintext::alloc_from_infos(self, res_ref); self.glwe_decrypt(res, &mut pt_have, sk_prepared, scratch); self.vec_znx_sub_inplace(&mut pt_have.data, 0, &pt_want.data, 0); self.vec_znx_normalize_inplace(res_ref.base2k().into(), &mut pt_have.data, 0, scratch); pt_have.data.std(res_ref.base2k().into(), 0).log2() } fn glwe_assert_noise(&self, res: &R, sk_prepared: &S, pt_want: &P, max_noise: f64) where R: GLWEToRef, S: GLWESecretPreparedToRef, P: GLWEPlaintextToRef, BE: ScratchOwnedAllocImpl + ScratchOwnedBorrowImpl + ScratchOwnedBorrow, { let res: &GLWE<&[u8]> = &res.to_ref(); let mut scratch: ScratchOwned = ScratchOwned::alloc(self.glwe_decrypt_tmp_bytes(res)); let noise_have: f64 = self.glwe_noise(res, sk_prepared, pt_want, scratch.borrow()); assert!(noise_have <= max_noise, "{noise_have} {max_noise}"); } }