diff --git a/poulpy-core/src/automorphism/gglwe_atk.rs b/poulpy-core/src/automorphism/gglwe_atk.rs index a291f96..ffc35cd 100644 --- a/poulpy-core/src/automorphism/gglwe_atk.rs +++ b/poulpy-core/src/automorphism/gglwe_atk.rs @@ -116,7 +116,7 @@ where } } - res.set_p((p * key.p()) % (self.cyclotomic_order() as i64)); + res.set_p((p * key.p()) % self.cyclotomic_order()); } fn glwe_automorphism_key_automorphism_inplace(&self, res: &mut R, key: &K, scratch: &mut Scratch) @@ -160,6 +160,6 @@ where } } - res.set_p((res.p() * key.p()) % (self.cyclotomic_order() as i64)); + res.set_p((res.p() * key.p()) % self.cyclotomic_order()); } } diff --git a/poulpy-core/src/encryption/ggsw.rs b/poulpy-core/src/encryption/ggsw.rs index 85b8be5..86b810c 100644 --- a/poulpy-core/src/encryption/ggsw.rs +++ b/poulpy-core/src/encryption/ggsw.rs @@ -107,7 +107,7 @@ where let base2k: usize = res.base2k().into(); let rank: usize = res.rank().into(); let dsize: usize = res.dsize().into(); - let cols: usize = (rank + 1).into(); + let cols: usize = rank + 1; let (mut tmp_pt, scratch_1) = scratch.take_glwe_plaintext(res); diff --git a/poulpy-core/src/encryption/glwe.rs b/poulpy-core/src/encryption/glwe.rs index b032b38..c81833e 100644 --- a/poulpy-core/src/encryption/glwe.rs +++ b/poulpy-core/src/encryption/glwe.rs @@ -427,6 +427,7 @@ where } pub(crate) trait GLWEEncryptSkInternal { + #[allow(clippy::too_many_arguments)] fn glwe_encrypt_sk_internal( &self, base2k: usize, diff --git a/poulpy-core/src/layouts/compressed/glwe.rs b/poulpy-core/src/layouts/compressed/glwe.rs index fa61b81..eda1e8f 100644 --- a/poulpy-core/src/layouts/compressed/glwe.rs +++ b/poulpy-core/src/layouts/compressed/glwe.rs @@ -192,7 +192,7 @@ pub trait GLWECompressedToRef { impl GLWECompressedToRef for GLWECompressed { fn to_ref(&self) -> GLWECompressed<&[u8]> { GLWECompressed { - seed: self.seed.clone(), + seed: self.seed, base2k: self.base2k, k: self.k, rank: self.rank, @@ -208,7 +208,7 @@ pub trait GLWECompressedToMut { impl GLWECompressedToMut for GLWECompressed { fn to_mut(&mut self) -> GLWECompressed<&mut [u8]> { GLWECompressed { - seed: self.seed.clone(), + seed: self.seed, base2k: self.base2k, k: self.k, rank: self.rank, diff --git a/poulpy-core/src/layouts/compressed/glwe_switching_key.rs b/poulpy-core/src/layouts/compressed/glwe_switching_key.rs index 82fb797..6da1d32 100644 --- a/poulpy-core/src/layouts/compressed/glwe_switching_key.rs +++ b/poulpy-core/src/layouts/compressed/glwe_switching_key.rs @@ -146,8 +146,8 @@ where { impl ReaderFrom for GLWESwitchingKeyCompressed { fn read_from(&mut self, reader: &mut R) -> std::io::Result<()> { - self.input_degree = Degree(reader.read_u32::()? as u32); - self.output_degree = Degree(reader.read_u32::()? as u32); + self.input_degree = Degree(reader.read_u32::()?); + self.output_degree = Degree(reader.read_u32::()?); self.key.read_from(reader) } } diff --git a/poulpy-core/src/layouts/glwe_switching_key.rs b/poulpy-core/src/layouts/glwe_switching_key.rs index 1e67222..3f94c06 100644 --- a/poulpy-core/src/layouts/glwe_switching_key.rs +++ b/poulpy-core/src/layouts/glwe_switching_key.rs @@ -240,8 +240,8 @@ impl GLWESwitchingKey { impl ReaderFrom for GLWESwitchingKey { fn read_from(&mut self, reader: &mut R) -> std::io::Result<()> { - self.input_degree = Degree(reader.read_u32::()? as u32); - self.output_degree = Degree(reader.read_u32::()? as u32); + self.input_degree = Degree(reader.read_u32::()?); + self.output_degree = Degree(reader.read_u32::()?); self.key.read_from(reader) } } diff --git a/poulpy-core/src/layouts/mod.rs b/poulpy-core/src/layouts/mod.rs index 6447fc5..1168ac8 100644 --- a/poulpy-core/src/layouts/mod.rs +++ b/poulpy-core/src/layouts/mod.rs @@ -43,7 +43,7 @@ pub trait GetDegree { impl GetDegree for Module { fn ring_degree(&self) -> Degree { - Self::n(&self).into() + Self::n(self).into() } } diff --git a/poulpy-core/src/layouts/prepared/glwe_automorphism_key.rs b/poulpy-core/src/layouts/prepared/glwe_automorphism_key.rs index 0296e0f..adf54eb 100644 --- a/poulpy-core/src/layouts/prepared/glwe_automorphism_key.rs +++ b/poulpy-core/src/layouts/prepared/glwe_automorphism_key.rs @@ -69,7 +69,7 @@ pub trait GLWEAutomorphismKeyPreparedFactory where Self: GGLWEPreparedFactory, { - fn alloc_automorphism_key_prepared( + fn alloc_glwe_automorphism_key_prepared( &self, base2k: Base2K, k: TorusPrecision, @@ -83,7 +83,7 @@ where } } - fn alloc_automorphism_key_prepared_from_infos(&self, infos: &A) -> GLWEAutomorphismKeyPrepared, B> + fn alloc_glwe_automorphism_key_prepared_from_infos(&self, infos: &A) -> GLWEAutomorphismKeyPrepared, B> where A: GGLWEInfos, { @@ -92,7 +92,7 @@ where infos.rank_out(), "rank_in != rank_out is not supported for AutomorphismKeyPrepared" ); - self.alloc_automorphism_key_prepared( + self.alloc_glwe_automorphism_key_prepared( infos.base2k(), infos.k(), infos.rank(), @@ -101,7 +101,7 @@ where ) } - fn bytes_of_automorphism_key_prepared( + fn bytes_of_glwe_automorphism_key_prepared( &self, base2k: Base2K, k: TorusPrecision, @@ -112,7 +112,7 @@ where self.bytes_of_gglwe_prepared(base2k, k, rank, rank, dnum, dsize) } - fn bytes_of_automorphism_key_prepared_from_infos(&self, infos: &A) -> usize + fn bytes_of_glwe_automorphism_key_prepared_from_infos(&self, infos: &A) -> usize where A: GGLWEInfos, { @@ -121,7 +121,7 @@ where infos.rank_out(), "rank_in != rank_out is not supported for AutomorphismKeyPrepared" ); - self.bytes_of_automorphism_key_prepared( + self.bytes_of_glwe_automorphism_key_prepared( infos.base2k(), infos.k(), infos.rank(), @@ -130,14 +130,14 @@ where ) } - fn prepare_automorphism_key_tmp_bytes(&self, infos: &A) -> usize + fn prepare_glwe_automorphism_key_tmp_bytes(&self, infos: &A) -> usize where A: GGLWEInfos, { self.prepare_gglwe_tmp_bytes(infos) } - fn prepare_automorphism_key(&self, res: &mut R, other: &O, scratch: &mut Scratch) + fn prepare_glwe_automorphism_key(&self, res: &mut R, other: &O, scratch: &mut Scratch) where R: GGLWEPreparedToMut + SetGaloisElement, O: GGLWEToRef + GetGaloisElement, @@ -155,14 +155,14 @@ impl GLWEAutomorphismKeyPrepared, B> { A: GGLWEInfos, M: GLWEAutomorphismKeyPreparedFactory, { - module.alloc_automorphism_key_prepared_from_infos(infos) + module.alloc_glwe_automorphism_key_prepared_from_infos(infos) } pub fn alloc(module: &M, base2k: Base2K, k: TorusPrecision, rank: Rank, dnum: Dnum, dsize: Dsize) -> Self where M: GLWEAutomorphismKeyPreparedFactory, { - module.alloc_automorphism_key_prepared(base2k, k, rank, dnum, dsize) + module.alloc_glwe_automorphism_key_prepared(base2k, k, rank, dnum, dsize) } pub fn bytes_of_from_infos(module: &M, infos: &A) -> usize @@ -170,14 +170,14 @@ impl GLWEAutomorphismKeyPrepared, B> { A: GGLWEInfos, M: GLWEAutomorphismKeyPreparedFactory, { - module.bytes_of_automorphism_key_prepared_from_infos(infos) + module.bytes_of_glwe_automorphism_key_prepared_from_infos(infos) } pub fn bytes_of(module: &M, base2k: Base2K, k: TorusPrecision, rank: Rank, dnum: Dnum, dsize: Dsize) -> usize where M: GLWEAutomorphismKeyPreparedFactory, { - module.bytes_of_automorphism_key_prepared(base2k, k, rank, dnum, dsize) + module.bytes_of_glwe_automorphism_key_prepared(base2k, k, rank, dnum, dsize) } } @@ -186,7 +186,7 @@ impl GLWEAutomorphismKeyPrepared, B> { where M: GLWEAutomorphismKeyPreparedFactory, { - module.prepare_automorphism_key_tmp_bytes(self) + module.prepare_glwe_automorphism_key_tmp_bytes(self) } } @@ -196,7 +196,7 @@ impl GLWEAutomorphismKeyPrepared { O: GGLWEToRef + GetGaloisElement, M: GLWEAutomorphismKeyPreparedFactory, { - module.prepare_automorphism_key(self, other, scratch); + module.prepare_glwe_automorphism_key(self, other, scratch); } } diff --git a/poulpy-core/src/layouts/prepared/glwe_secret.rs b/poulpy-core/src/layouts/prepared/glwe_secret.rs index 0e38221..8f4917d 100644 --- a/poulpy-core/src/layouts/prepared/glwe_secret.rs +++ b/poulpy-core/src/layouts/prepared/glwe_secret.rs @@ -166,7 +166,10 @@ impl GLWESecretPreparedToRef for GLWESecretPrepared { +pub trait GLWESecretPreparedToMut +where + Self: GLWESecretPreparedToRef, +{ fn to_mut(&mut self) -> GLWESecretPrepared<&mut [u8], B>; } diff --git a/poulpy-core/src/layouts/prepared/glwe_to_lwe_switching_key.rs b/poulpy-core/src/layouts/prepared/glwe_to_lwe_switching_key.rs index 865e9cd..6edac5e 100644 --- a/poulpy-core/src/layouts/prepared/glwe_to_lwe_switching_key.rs +++ b/poulpy-core/src/layouts/prepared/glwe_to_lwe_switching_key.rs @@ -102,11 +102,11 @@ where self.bytes_of_glwe_to_lwe_switching_key_prepared(infos.base2k(), infos.k(), infos.rank_in(), infos.dnum()) } - fn prepare_glwe_to_lwe_switching_key_tmp_bytes(&self, infos: &A) + fn prepare_glwe_to_lwe_switching_key_tmp_bytes(&self, infos: &A) -> usize where A: GGLWEInfos, { - self.prepare_glwe_switching_key_tmp_bytes(infos); + self.prepare_glwe_switching_key_tmp_bytes(infos) } fn prepare_glwe_to_lwe_switching_key(&self, res: &mut R, other: &O, scratch: &mut Scratch) diff --git a/poulpy-core/src/tests/test_suite/encryption/gglwe_atk.rs b/poulpy-core/src/tests/test_suite/encryption/gglwe_atk.rs index ad456c9..9363539 100644 --- a/poulpy-core/src/tests/test_suite/encryption/gglwe_atk.rs +++ b/poulpy-core/src/tests/test_suite/encryption/gglwe_atk.rs @@ -81,7 +81,7 @@ where i, ); }); - let mut sk_out_prepared: GLWESecretPrepared, BE> = GLWESecretPrepared::alloc(module, sk_out.rank().into()); + let mut sk_out_prepared: GLWESecretPrepared, BE> = GLWESecretPrepared::alloc(module, sk_out.rank()); sk_out_prepared.prepare(module, &sk_out); atk.key @@ -150,7 +150,7 @@ where i, ); }); - let mut sk_out_prepared: GLWESecretPrepared, BE> = GLWESecretPrepared::alloc(module, sk_out.rank().into()); + let mut sk_out_prepared: GLWESecretPrepared, BE> = GLWESecretPrepared::alloc(module, sk_out.rank()); sk_out_prepared.prepare(module, &sk_out); let mut atk: GLWEAutomorphismKey> = GLWEAutomorphismKey::alloc_from_infos(&atk_infos); diff --git a/poulpy-schemes/src/tfhe/bdd_arithmetic/bdd_2w_to_1w.rs b/poulpy-schemes/src/tfhe/bdd_arithmetic/bdd_2w_to_1w.rs index ba0d38f..db4a1de 100644 --- a/poulpy-schemes/src/tfhe/bdd_arithmetic/bdd_2w_to_1w.rs +++ b/poulpy-schemes/src/tfhe/bdd_arithmetic/bdd_2w_to_1w.rs @@ -3,72 +3,44 @@ use poulpy_core::layouts::prepared::GGSWPreparedToRef; use poulpy_hal::layouts::{Backend, DataMut, DataRef, Module, Scratch}; use crate::tfhe::bdd_arithmetic::{ - BitCircuitInfo, Circuit, CircuitExecute, FheUintBlocks, FheUintBlocksPrep, UnsignedInteger, circuits, + ExecuteBDDCircuit, FheUintBlocks, FheUintBlocksPrepared, GetBitCircuitInfo, UnsignedInteger, circuits, }; -/// Operations Z x Z -> Z -pub(crate) struct Circuits2WTo1W(pub &'static Circuit); +impl ExecuteBDDCircuit2WTo1W for Module where Self: Sized + ExecuteBDDCircuit {} -pub trait EvalBDD2WTo1W { - fn eval_bdd_2w_to_1w( - &self, - module: &Module, - out: &mut FheUintBlocks, - a: &FheUintBlocksPrep, - b: &FheUintBlocksPrep, - scratch: &mut Scratch, - ) where - R: DataMut, - A: DataRef, - B: DataRef; -} - -impl EvalBDD2WTo1W - for Circuits2WTo1W +pub trait ExecuteBDDCircuit2WTo1W where - Circuit: CircuitExecute, + Self: Sized + ExecuteBDDCircuit, { - fn eval_bdd_2w_to_1w( + /// Operations Z x Z -> Z + fn execute_bdd_circuit_2w_to_1w( &self, - module: &Module, out: &mut FheUintBlocks, - a: &FheUintBlocksPrep, - b: &FheUintBlocksPrep, + circuit: &C, + a: &FheUintBlocksPrepared, + b: &FheUintBlocksPrepared, scratch: &mut Scratch, ) where + C: GetBitCircuitInfo, R: DataMut, A: DataRef, B: DataRef, - { - eval_bdd_2w_to_1w(module, self.0, out, a, b, scratch); - } -} - -pub fn eval_bdd_2w_to_1w, BE: Backend>( - module: &Module, - circuit: &C, - out: &mut FheUintBlocks, - a: &FheUintBlocksPrep, - b: &FheUintBlocksPrep, - scratch: &mut Scratch, -) { - #[cfg(debug_assertions)] { assert_eq!(out.blocks.len(), T::WORD_SIZE); assert_eq!(b.blocks.len(), T::WORD_SIZE); assert_eq!(b.blocks.len(), T::WORD_SIZE); + + // Collects inputs into a single array + let inputs: Vec<&dyn GGSWPreparedToRef> = a + .blocks + .iter() + .map(|x| x as &dyn GGSWPreparedToRef) + .chain(b.blocks.iter().map(|x| x as &dyn GGSWPreparedToRef)) + .collect_vec(); + + // Evaluates out[i] = circuit[i](a, b) + self.execute_bdd_circuit(&mut out.blocks, &inputs, circuit, scratch); } - - // Collects inputs into a single array - let inputs: Vec<&dyn GGSWPreparedToRef> = a - .blocks - .iter() - .map(|x| x as &dyn GGSWPreparedToRef) - .chain(b.blocks.iter().map(|x| x as &dyn GGSWPreparedToRef)) - .collect_vec(); - - // Evaluates out[i] = circuit[i](a, b) - circuit.execute(module, &mut out.blocks, &inputs, scratch); } #[macro_export] @@ -76,13 +48,14 @@ macro_rules! define_bdd_2w_to_1w_trait { ($(#[$meta:meta])* $vis:vis $trait_name:ident, $method_name:ident) => { $(#[$meta])* $vis trait $trait_name { - fn $method_name( + fn $method_name( &mut self, - module: &Module, - a: &FheUintBlocksPrep, - b: &FheUintBlocksPrep, + module: &M, + a: &FheUintBlocksPrepared, + b: &FheUintBlocksPrepared, scratch: &mut Scratch, ) where + M: ExecuteBDDCircuit2WTo1W, A: DataRef, B: DataRef; } @@ -92,23 +65,19 @@ macro_rules! define_bdd_2w_to_1w_trait { #[macro_export] macro_rules! impl_bdd_2w_to_1w_trait { ($trait_name:ident, $method_name:ident, $ty:ty, $n:literal, $circuit_ty:ty, $output_circuits:path) => { - impl $trait_name<$ty, BE> for FheUintBlocks - where - Circuits2WTo1W<$circuit_ty, $n>: EvalBDD2WTo1W, - { - fn $method_name( + impl $trait_name<$ty, BE> for FheUintBlocks { + fn $method_name( &mut self, - module: &Module, - a: &FheUintBlocksPrep, - b: &FheUintBlocksPrep, + module: &M, + a: &FheUintBlocksPrepared, + b: &FheUintBlocksPrepared, scratch: &mut Scratch, ) where + M: ExecuteBDDCircuit2WTo1W<$ty, BE>, A: DataRef, B: DataRef, { - const OP: Circuits2WTo1W<$circuit_ty, $n> = Circuits2WTo1W::<$circuit_ty, $n>(&$output_circuits); - - OP.eval_bdd_2w_to_1w(module, self, a, b, scratch); + module.execute_bdd_circuit_2w_to_1w(self, &$output_circuits, a, b, scratch) } } }; diff --git a/poulpy-schemes/src/tfhe/bdd_arithmetic/ciphertexts/block.rs b/poulpy-schemes/src/tfhe/bdd_arithmetic/ciphertexts/block.rs index 00fe458..82d985e 100644 --- a/poulpy-schemes/src/tfhe/bdd_arithmetic/ciphertexts/block.rs +++ b/poulpy-schemes/src/tfhe/bdd_arithmetic/ciphertexts/block.rs @@ -1,26 +1,17 @@ use std::marker::PhantomData; -use poulpy_core::layouts::{Base2K, GLWE, GLWEInfos, GLWEPlaintextLayout, LWEInfos, Rank, TorusPrecision}; +use poulpy_core::{ + GLWEDecrypt, GLWENoise, + layouts::{Base2K, GLWE, GLWEInfos, GLWEPlaintextLayout, GLWESecretPreparedToRef, LWEInfos, Rank, TorusPrecision}, +}; #[cfg(test)] +use poulpy_core::GLWEEncryptSk; use poulpy_core::ScratchTakeCore; -use poulpy_core::{layouts::prepared::GLWESecretPrepared}; -use poulpy_hal::api::VecZnxBigBytesOf; +use poulpy_hal::layouts::{Backend, Data, DataMut, DataRef, Module, Scratch}; #[cfg(test)] -use poulpy_hal::api::{ - VecZnxAddInplace, VecZnxAddNormal, VecZnxFillUniform, VecZnxNormalize, VecZnxSub, -}; #[cfg(test)] use poulpy_hal::source::Source; -use poulpy_hal::{ - api::{ - VecZnxBigAddInplace, VecZnxBigAddSmallInplace, VecZnxBigNormalize, VecZnxDftApply, - VecZnxDftBytesOf, VecZnxIdftApplyConsume, VecZnxNormalizeTmpBytes, - }, - layouts::{Backend, Data, DataMut, DataRef, Module, Scratch}, -}; - -use poulpy_hal::api::{SvpApplyDftToDftInplace, VecZnxNormalizeInplace, VecZnxSubInplace}; use crate::tfhe::bdd_arithmetic::{FromBits, ToBits, UnsignedInteger}; @@ -79,25 +70,13 @@ impl FheUintBlocks { &mut self, module: &Module, value: T, - sk: &GLWESecretPrepared, + sk: &S, source_xa: &mut Source, source_xe: &mut Source, scratch: &mut Scratch, ) where - S: DataRef, - Module: VecZnxDftBytesOf - + VecZnxBigNormalize - + VecZnxDftApply - + SvpApplyDftToDftInplace - + VecZnxIdftApplyConsume - + VecZnxNormalizeTmpBytes - + VecZnxFillUniform - + VecZnxSubInplace - + VecZnxAddInplace - + VecZnxNormalizeInplace - + VecZnxAddNormal - + VecZnxNormalize - + VecZnxSub, + S: GLWESecretPreparedToRef + GLWEInfos, + Module: GLWEEncryptSk, Scratch: ScratchTakeCore, { use poulpy_core::layouts::GLWEPlaintextLayout; @@ -115,29 +94,20 @@ impl FheUintBlocks { k: 1_usize.into(), }; - let (mut pt, scratch_1) = scratch.take_glwe_pt(&pt_infos); + let (mut pt, scratch_1) = scratch.take_glwe_plaintext(&pt_infos); for i in 0..T::WORD_SIZE { pt.encode_coeff_i64(value.bit(i) as i64, TorusPrecision(2), 0); - self.blocks[i].encrypt_sk(&module, &pt, sk, source_xa, source_xe, scratch_1); + self.blocks[i].encrypt_sk(module, &pt, sk, source_xa, source_xe, scratch_1); } } } impl FheUintBlocks { - pub fn decrypt( - &self, - module: &Module, - sk: &GLWESecretPrepared, - scratch: &mut Scratch, - ) -> T + pub fn decrypt(&self, module: &Module, sk: &S, scratch: &mut Scratch) -> T where - Module: VecZnxDftApply - + SvpApplyDftToDftInplace - + VecZnxIdftApplyConsume - + VecZnxBigAddInplace - + VecZnxBigAddSmallInplace - + VecZnxBigNormalize, + Module: GLWEDecrypt, + S: GLWESecretPreparedToRef + GLWEInfos, Scratch: ScratchTakeCore, { #[cfg(debug_assertions)] @@ -153,7 +123,7 @@ impl FheUintBlocks { k: self.k(), }; - let (mut pt, scratch_1) = scratch.take_glwe_pt(&pt_infos); + let (mut pt, scratch_1) = scratch.take_glwe_plaintext(&pt_infos); let mut bits: Vec = vec![0u8; T::WORD_SIZE]; @@ -169,25 +139,10 @@ impl FheUintBlocks { T::from_bits(&bits) } - pub fn noise( - &self, - module: &Module, - sk: &GLWESecretPrepared, - want: T, - scratch: &mut Scratch, - ) -> Vec + pub fn noise(&self, module: &Module, sk: &S, want: T, scratch: &mut Scratch) -> Vec where - Module: VecZnxDftBytesOf - + VecZnxBigBytesOf - + VecZnxDftApply - + SvpApplyDftToDftInplace - + VecZnxIdftApplyConsume - + VecZnxBigAddInplace - + VecZnxBigAddSmallInplace - + VecZnxBigNormalize - + VecZnxNormalizeTmpBytes - + VecZnxSubInplace - + VecZnxNormalizeInplace, + Module: GLWENoise, + S: GLWESecretPreparedToRef + GLWEInfos, Scratch: ScratchTakeCore, { #[cfg(debug_assertions)] @@ -203,7 +158,7 @@ impl FheUintBlocks { k: 1_usize.into(), }; - let (mut pt_want, scratch_1) = scratch.take_glwe_pt(&pt_infos); + let (mut pt_want, scratch_1) = scratch.take_glwe_plaintext(&pt_infos); let mut noise: Vec = vec![0f64; T::WORD_SIZE]; diff --git a/poulpy-schemes/src/tfhe/bdd_arithmetic/ciphertexts/block_debug.rs b/poulpy-schemes/src/tfhe/bdd_arithmetic/ciphertexts/block_debug.rs new file mode 100644 index 0000000..f291c62 --- /dev/null +++ b/poulpy-schemes/src/tfhe/bdd_arithmetic/ciphertexts/block_debug.rs @@ -0,0 +1,147 @@ +use std::marker::PhantomData; + +use crate::tfhe::bdd_arithmetic::{BDDKeyPrepared, FheUintBlockDebugPrepare, ToBits}; +use crate::tfhe::{ + bdd_arithmetic::{FheUintBlocks, UnsignedInteger}, + blind_rotation::BlindRotationAlgo, + circuit_bootstrapping::CirtuitBootstrappingExecute, +}; +use poulpy_core::GGSWNoise; +#[cfg(test)] +use poulpy_core::layouts::{Base2K, Dnum, Dsize, Rank, TorusPrecision}; +use poulpy_core::layouts::{GGSW, GLWESecretPreparedToRef}; +use poulpy_core::{ + LWEFromGLWE, ScratchTakeCore, + layouts::{GGSWInfos, GGSWPreparedFactory, GLWEInfos, LWE, LWEInfos}, +}; +#[cfg(test)] +use poulpy_hal::api::ModuleN; +use poulpy_hal::layouts::{Backend, Data, DataMut, DataRef, Module, Scratch}; + +pub(crate) struct FheUintBlocksPreparedDebug { + pub(crate) blocks: Vec>, + pub(crate) _base: u8, + pub(crate) _phantom: PhantomData, +} + +#[cfg(test)] +impl FheUintBlocksPreparedDebug, T> { + #[allow(dead_code)] + pub(crate) fn alloc(module: &M, infos: &A) -> Self + where + M: ModuleN, + A: GGSWInfos, + { + Self::alloc_with( + module, + infos.base2k(), + infos.k(), + infos.dnum(), + infos.dsize(), + infos.rank(), + ) + } + + #[allow(dead_code)] + pub(crate) fn alloc_with(module: &M, base2k: Base2K, k: TorusPrecision, dnum: Dnum, dsize: Dsize, rank: Rank) -> Self + where + M: ModuleN, + { + Self { + blocks: (0..T::WORD_SIZE) + .map(|_| GGSW::alloc(module.n().into(), base2k, k, rank, dnum, dsize)) + .collect(), + _base: 1, + _phantom: PhantomData, + } + } +} + +impl LWEInfos for FheUintBlocksPreparedDebug { + fn base2k(&self) -> poulpy_core::layouts::Base2K { + self.blocks[0].base2k() + } + + fn k(&self) -> poulpy_core::layouts::TorusPrecision { + self.blocks[0].k() + } + + fn n(&self) -> poulpy_core::layouts::Degree { + self.blocks[0].n() + } +} + +impl GLWEInfos for FheUintBlocksPreparedDebug { + fn rank(&self) -> poulpy_core::layouts::Rank { + self.blocks[0].rank() + } +} + +impl GGSWInfos for FheUintBlocksPreparedDebug { + fn dsize(&self) -> poulpy_core::layouts::Dsize { + self.blocks[0].dsize() + } + + fn dnum(&self) -> poulpy_core::layouts::Dnum { + self.blocks[0].dnum() + } +} + +impl FheUintBlocksPreparedDebug { + pub(crate) fn noise(&self, module: &M, sk: &S, want: T) + where + S: GLWESecretPreparedToRef, + M: GGSWNoise, + { + for (i, ggsw) in self.blocks.iter().enumerate() { + use poulpy_hal::layouts::{ScalarZnx, ZnxViewMut}; + let mut pt_want = ScalarZnx::alloc(self.n().into(), 1); + pt_want.at_mut(0, 0)[0] = want.bit(i) as i64; + ggsw.print_noise(module, sk, &pt_want); + } + } +} + +impl FheUintBlockDebugPrepare for Module +where + Self: LWEFromGLWE + CirtuitBootstrappingExecute + GGSWPreparedFactory, + Scratch: ScratchTakeCore, +{ + fn fhe_uint_block_debug_prepare( + &self, + res: &mut FheUintBlocksPreparedDebug, + bits: &FheUintBlocks, + key: &BDDKeyPrepared, + scratch: &mut Scratch, + ) where + DM: DataMut, + DR0: DataRef, + DR1: DataRef, + { + assert_eq!(res.blocks.len(), bits.blocks.len()); + + let mut lwe: LWE> = LWE::alloc_from_infos(&bits.blocks[0]); //TODO: add TakeLWE + for (dst, src) in res.blocks.iter_mut().zip(bits.blocks.iter()) { + lwe.from_glwe(self, src, &key.ks, scratch); + key.cbt.execute_to_constant(self, dst, &lwe, 1, 1, scratch); + } + } +} + +impl FheUintBlocksPreparedDebug { + pub fn prepare( + &mut self, + module: &M, + other: &FheUintBlocks, + key: &BDDKeyPrepared, + scratch: &mut Scratch, + ) where + BRA: BlindRotationAlgo, + O: DataRef, + K: DataRef, + M: FheUintBlockDebugPrepare, + Scratch: ScratchTakeCore, + { + module.fhe_uint_block_debug_prepare(self, other, key, scratch); + } +} diff --git a/poulpy-schemes/src/tfhe/bdd_arithmetic/ciphertexts/block_prepared.rs b/poulpy-schemes/src/tfhe/bdd_arithmetic/ciphertexts/block_prepared.rs index 1ed7229..3753f99 100644 --- a/poulpy-schemes/src/tfhe/bdd_arithmetic/ciphertexts/block_prepared.rs +++ b/poulpy-schemes/src/tfhe/bdd_arithmetic/ciphertexts/block_prepared.rs @@ -1,89 +1,60 @@ use std::marker::PhantomData; -use poulpy_core::layouts::{Base2K, Dnum, Dsize, GGSWInfos, GLWEInfos, LWEInfos, Rank, TorusPrecision, prepared::GGSWPrepared}; -#[cfg(test)] -use poulpy_core::{ - layouts::{prepared::GLWESecretPrepared, GGSW}, ScratchTakeCore, -}; -use poulpy_hal::{ - api::VmpPMatAlloc, - layouts::{Backend, Data, DataMut, DataRef, Module, Scratch}, +use poulpy_core::layouts::{ + Base2K, Dnum, Dsize, GGSWInfos, GGSWPreparedFactory, GLWEInfos, LWEInfos, Rank, TorusPrecision, prepared::GGSWPrepared, }; #[cfg(test)] +use poulpy_core::{GGSWEncryptSk, ScratchTakeCore, layouts::GLWESecretPreparedToRef}; +use poulpy_hal::layouts::{Backend, Data, DataRef, Module}; +#[cfg(test)] use poulpy_hal::{ - api::{ - SvpApplyDftToDftInplace, VecZnxAddInplace, VecZnxAddNormal, - VecZnxAddScalarInplace, VecZnxBigAddInplace, VecZnxBigAddSmallInplace, VecZnxBigAlloc, VecZnxBigBytesOf, - VecZnxBigNormalize, VecZnxBigNormalizeTmpBytes, VecZnxDftAlloc, VecZnxDftApply, VecZnxDftBytesOf, VecZnxFillUniform, - VecZnxIdftApplyConsume, VecZnxIdftApplyTmpA, VecZnxNormalize, VecZnxNormalizeInplace, VecZnxNormalizeTmpBytes, VecZnxSub, - VecZnxSubInplace, VmpPrepare, - }, + api::ModuleN, + layouts::{DataMut, Scratch}, source::Source, }; -use crate::tfhe::bdd_arithmetic::{FheUintBlocks, FheUintPrepare, ToBits, UnsignedInteger}; - #[cfg(test)] -pub(crate) struct FheUintBlocksPrepDebug { - pub(crate) blocks: Vec>, - pub(crate) _base: u8, - pub(crate) _phantom: PhantomData, -} - -#[cfg(test)] -impl FheUintBlocksPrepDebug, T> { - #[allow(dead_code)] - pub(crate) fn alloc(module: &Module, infos: &A) -> Self - where - A: GGSWInfos, - { - Self::alloc_with( - module, - infos.base2k(), - infos.k(), - infos.dnum(), - infos.dsize(), - infos.rank(), - ) - } - - #[allow(dead_code)] - pub(crate) fn alloc_with( - module: &Module, - base2k: Base2K, - k: TorusPrecision, - dnum: Dnum, - dsize: Dsize, - rank: Rank, - ) -> Self { - Self { - blocks: (0..T::WORD_SIZE) - .map(|_| GGSW::alloc(module.n().into(), base2k, k, rank, dnum, dsize)) - .collect(), - _base: 1, - _phantom: PhantomData, - } - } -} +use crate::tfhe::bdd_arithmetic::ToBits; +use crate::tfhe::bdd_arithmetic::UnsignedInteger; /// A prepared FHE ciphertext encrypting the bits of an [UnsignedInteger]. -pub struct FheUintBlocksPrep { +pub struct FheUintBlocksPrepared { pub(crate) blocks: Vec>, pub(crate) _base: u8, pub(crate) _phantom: PhantomData, } -impl FheUintBlocksPrep, BE, T> -where - Module: VmpPMatAlloc, +impl FheUintBlocksPreparedFactory for Module where + Self: Sized + GGSWPreparedFactory { - #[allow(dead_code)] - pub(crate) fn alloc(module: &Module, infos: &A) -> Self +} + +pub trait FheUintBlocksPreparedFactory +where + Self: Sized + GGSWPreparedFactory, +{ + fn alloc_fhe_uint_blocks_prepared( + &self, + base2k: Base2K, + k: TorusPrecision, + dnum: Dnum, + dsize: Dsize, + rank: Rank, + ) -> FheUintBlocksPrepared, T, BE> { + FheUintBlocksPrepared { + blocks: (0..T::WORD_SIZE) + .map(|_| GGSWPrepared::alloc(self, base2k, k, dnum, dsize, rank)) + .collect(), + _base: 1, + _phantom: PhantomData, + } + } + + fn alloc_fhe_uint_blocks_prepared_from_infos(&self, infos: &A) -> FheUintBlocksPrepared, T, BE> where A: GGSWInfos, { - Self::alloc_with( - module, + self.alloc_fhe_uint_blocks_prepared( infos.base2k(), infos.k(), infos.dnum(), @@ -91,129 +62,90 @@ where infos.rank(), ) } +} + +impl FheUintBlocksPrepared, T, BE> { + #[allow(dead_code)] + pub(crate) fn alloc(module: &M, infos: &A) -> Self + where + A: GGSWInfos, + M: FheUintBlocksPreparedFactory, + { + module.alloc_fhe_uint_blocks_prepared_from_infos(infos) + } #[allow(dead_code)] - pub(crate) fn alloc_with(module: &Module, base2k: Base2K, k: TorusPrecision, dnum: Dnum, dsize: Dsize, rank: Rank) -> Self + pub(crate) fn alloc_with(module: &M, base2k: Base2K, k: TorusPrecision, dnum: Dnum, dsize: Dsize, rank: Rank) -> Self where - Module: VmpPMatAlloc, + M: FheUintBlocksPreparedFactory, { - Self { - blocks: (0..T::WORD_SIZE) - .map(|_| GGSWPrepared::alloc(module, base2k, k, dnum, dsize, rank)) - .collect(), - _base: 1, - _phantom: PhantomData, - } + module.alloc_fhe_uint_blocks_prepared(base2k, k, dnum, dsize, rank) } } -impl FheUintBlocksPrep { - #[allow(dead_code)] - #[cfg(test)] - pub(crate) fn encrypt_sk( - &mut self, - module: &Module, +#[cfg(test)] +impl FheUintBlocksPreparedEncryptSk for Module where + Self: Sized + ModuleN + GGSWEncryptSk + GGSWPreparedFactory +{ +} + +#[cfg(test)] +pub trait FheUintBlocksPreparedEncryptSk +where + Self: Sized + ModuleN + GGSWEncryptSk + GGSWPreparedFactory, +{ + fn fhe_uint_blocks_prepared_encrypt_sk( + &self, + res: &mut FheUintBlocksPrepared, value: T, - sk: &GLWESecretPrepared, + sk: &S, source_xa: &mut Source, source_xe: &mut Source, scratch: &mut Scratch, ) where - S: DataRef, - Module: VecZnxAddScalarInplace - + VecZnxDftBytesOf - + VecZnxBigNormalize - + VecZnxDftApply - + SvpApplyDftToDftInplace - + VecZnxIdftApplyConsume - + VecZnxNormalizeTmpBytes - + VecZnxFillUniform - + VecZnxSubInplace - + VecZnxAddInplace - + VecZnxNormalizeInplace - + VecZnxAddNormal - + VecZnxNormalize - + VecZnxSub - + VmpPrepare, + DM: DataMut, + S: GLWESecretPreparedToRef + GLWEInfos, Scratch: ScratchTakeCore, { - #[cfg(debug_assertions)] - { - assert!(module.n().is_multiple_of(T::WORD_SIZE)); - assert_eq!(self.n(), module.n() as u32); - assert_eq!(sk.n(), module.n() as u32); - } + use poulpy_hal::api::ScratchTakeBasic; - let (mut tmp_ggsw, scratch_1) = scratch.take_ggsw(self); - let (mut pt, scratch_2) = scratch_1.take_scalar_znx(module.n(), 1); + assert!(self.n().is_multiple_of(T::WORD_SIZE)); + assert_eq!(res.n(), self.n() as u32); + assert_eq!(sk.n(), self.n() as u32); + + let (mut tmp_ggsw, scratch_1) = scratch.take_ggsw(res); + let (mut pt, scratch_2) = scratch_1.take_scalar_znx(self.n(), 1); for i in 0..T::WORD_SIZE { - use poulpy_hal::layouts::ZnxViewMut; pt.at_mut(0, 0)[0] = value.bit(i) as i64; - tmp_ggsw.encrypt_sk(&module, &pt, sk, source_xa, source_xe, scratch_2); - self.blocks[i].prepare(module, &tmp_ggsw, scratch_2); + tmp_ggsw.encrypt_sk(self, &pt, sk, source_xa, source_xe, scratch_2); + res.blocks[i].prepare(self, &tmp_ggsw, scratch_2); } } - - /// Prepares [FheUintBits] to [FheUintBitsPrep]. - pub fn prepare(&mut self, module: &Module, bits: &FheUintBlocks, key: &KEY, scratch: &mut Scratch) - where - BIT: DataRef, - KEY: FheUintPrepare, FheUintBlocks>, - { - key.prepare(module, self, bits, scratch); - } } #[cfg(test)] -impl FheUintBlocksPrepDebug { - pub(crate) fn prepare( +impl FheUintBlocksPrepared { + pub(crate) fn encrypt_sk( &mut self, - module: &Module, - bits: &FheUintBlocks, - key: &KEY, + module: &M, + value: T, + sk: &S, + source_xa: &mut Source, + source_xe: &mut Source, scratch: &mut Scratch, ) where - BIT: DataRef, - KEY: FheUintPrepare, FheUintBlocks>, + S: GLWESecretPreparedToRef + GLWEInfos, + M: FheUintBlocksPreparedEncryptSk, + Scratch: ScratchTakeCore, { - key.prepare(module, self, bits, scratch); + module.fhe_uint_blocks_prepared_encrypt_sk(self, value, sk, source_xa, source_xe, scratch); } } -#[cfg(test)] -impl FheUintBlocksPrepDebug { - #[allow(dead_code)] - pub(crate) fn noise(&self, module: &Module, sk: &GLWESecretPrepared, want: T) - where - Module: VecZnxDftBytesOf - + VecZnxBigBytesOf - + VecZnxDftApply - + SvpApplyDftToDftInplace - + VecZnxIdftApplyConsume - + VecZnxBigAddInplace - + VecZnxBigAddSmallInplace - + VecZnxBigNormalize - + VecZnxNormalizeTmpBytes - + VecZnxBigAlloc - + VecZnxDftAlloc - + VecZnxBigNormalizeTmpBytes - + VecZnxIdftApplyTmpA - + VecZnxAddScalarInplace - + VecZnxSubInplace, - { - for (i, ggsw) in self.blocks.iter().enumerate() { - use poulpy_hal::layouts::{ScalarZnx, ZnxViewMut}; - let mut pt_want = ScalarZnx::alloc(self.n().into(), 1); - pt_want.at_mut(0, 0)[0] = want.bit(i) as i64; - ggsw.print_noise(module, sk, &pt_want); - } - } -} - -impl LWEInfos for FheUintBlocksPrep { +impl LWEInfos for FheUintBlocksPrepared { fn base2k(&self) -> poulpy_core::layouts::Base2K { self.blocks[0].base2k() } @@ -227,46 +159,13 @@ impl LWEInfos for FheUintBlocksPrep< } } -impl GLWEInfos for FheUintBlocksPrep { +impl GLWEInfos for FheUintBlocksPrepared { fn rank(&self) -> poulpy_core::layouts::Rank { self.blocks[0].rank() } } -impl GGSWInfos for FheUintBlocksPrep { - fn dsize(&self) -> poulpy_core::layouts::Dsize { - self.blocks[0].dsize() - } - - fn dnum(&self) -> poulpy_core::layouts::Dnum { - self.blocks[0].dnum() - } -} - -#[cfg(test)] -impl LWEInfos for FheUintBlocksPrepDebug { - fn base2k(&self) -> poulpy_core::layouts::Base2K { - self.blocks[0].base2k() - } - - fn k(&self) -> poulpy_core::layouts::TorusPrecision { - self.blocks[0].k() - } - - fn n(&self) -> poulpy_core::layouts::Degree { - self.blocks[0].n() - } -} - -#[cfg(test)] -impl GLWEInfos for FheUintBlocksPrepDebug { - fn rank(&self) -> poulpy_core::layouts::Rank { - self.blocks[0].rank() - } -} - -#[cfg(test)] -impl GGSWInfos for FheUintBlocksPrepDebug { +impl GGSWInfos for FheUintBlocksPrepared { fn dsize(&self) -> poulpy_core::layouts::Dsize { self.blocks[0].dsize() } diff --git a/poulpy-schemes/src/tfhe/bdd_arithmetic/ciphertexts/mod.rs b/poulpy-schemes/src/tfhe/bdd_arithmetic/ciphertexts/mod.rs index 8b51045..b8054d7 100644 --- a/poulpy-schemes/src/tfhe/bdd_arithmetic/ciphertexts/mod.rs +++ b/poulpy-schemes/src/tfhe/bdd_arithmetic/ciphertexts/mod.rs @@ -2,6 +2,11 @@ mod block; mod block_prepared; mod word; +#[cfg(test)] +mod block_debug; +#[cfg(test)] +pub(crate) use block_debug::*; + pub use block::*; pub use block_prepared::*; pub use word::*; diff --git a/poulpy-schemes/src/tfhe/bdd_arithmetic/ciphertexts/word.rs b/poulpy-schemes/src/tfhe/bdd_arithmetic/ciphertexts/word.rs index 9025b2e..1d3e218 100644 --- a/poulpy-schemes/src/tfhe/bdd_arithmetic/ciphertexts/word.rs +++ b/poulpy-schemes/src/tfhe/bdd_arithmetic/ciphertexts/word.rs @@ -1,20 +1,14 @@ use itertools::Itertools; use poulpy_core::{ + GLWECopy, GLWEDecrypt, GLWEEncryptSk, GLWEPacking, ScratchTakeCore, layouts::{ - prepared::{GLWEAutomorphismKeyPrepared, GLWESecretPrepared}, GLWEInfos, GLWEPlaintextLayout, LWEInfos, TorusPrecision, GLWE - }, ScratchTakeCore, + GLWE, GLWEInfos, GLWEPlaintextLayout, GLWESecretPreparedToRef, LWEInfos, TorusPrecision, + prepared::GLWEAutomorphismKeyPrepared, + }, }; use poulpy_hal::{ - api::{ - ScratchAvailable, SvpApplyDftToDftInplace, VecZnxAddInplace, VecZnxAddNormal, - VecZnxAddScalarInplace, VecZnxAutomorphismInplace, VecZnxBigAddInplace, VecZnxBigAddSmallInplace, - VecZnxBigAutomorphismInplace, VecZnxBigNormalize, VecZnxBigNormalizeTmpBytes, VecZnxBigSubSmallNegateInplace, VecZnxCopy, - VecZnxDftApply, VecZnxDftBytesOf, VecZnxDftCopy, VecZnxFillUniform, VecZnxIdftApplyConsume, VecZnxIdftApplyTmpA, - VecZnxNegateInplace, VecZnxNormalize, VecZnxNormalizeInplace, VecZnxNormalizeTmpBytes, VecZnxRotate, VecZnxRotateInplace, - VecZnxRshInplace, VecZnxSub, VecZnxSubInplace, VecZnxSwitchRing, VmpApplyDftToDft, VmpApplyDftToDftAdd, - VmpApplyDftToDftTmpBytes, - }, - layouts::{Backend, Data, DataMut, DataRef, Module, Scratch}, + api::ModuleN, + layouts::{Backend, Data, DataMut, DataRef, Scratch}, source::Source, }; use std::{collections::HashMap, marker::PhantomData}; @@ -26,40 +20,15 @@ pub struct FheUintWord(pub(crate) GLWE, pub(crat impl FheUintWord { #[allow(dead_code)] - fn post_process( + fn post_process( &mut self, - module: &Module, + module: &M, mut tmp_res: Vec>, auto_keys: &HashMap>, scratch: &mut Scratch, ) where ATK: DataRef, - Module: VecZnxSub - + VecZnxCopy - + VecZnxNegateInplace - + VecZnxDftBytesOf - + VecZnxAddInplace - + VmpApplyDftToDftTmpBytes - + VecZnxNormalizeTmpBytes - + VecZnxDftApply - + VmpApplyDftToDft - + VmpApplyDftToDftAdd - + VecZnxIdftApplyConsume - + VecZnxBigNormalize - + VecZnxNormalize - + VecZnxRotateInplace - + VecZnxNormalizeInplace - + VecZnxSwitchRing - + VecZnxBigAutomorphismInplace - + VecZnxRshInplace - + VecZnxDftCopy - + VecZnxIdftApplyTmpA - + VecZnxSubInplace - + VecZnxBigNormalizeTmpBytes - + VecZnxBigAddSmallInplace - + VecZnxAutomorphismInplace - + VecZnxBigSubSmallNegateInplace - + VecZnxRotate, + M: GLWEPacking + GLWECopy, Scratch: ScratchTakeCore, { // Repacks the GLWE ciphertexts bits @@ -69,10 +38,11 @@ impl FheUintWord { for (i, ct) in tmp_res.iter_mut().enumerate().take(T::WORD_SIZE) { cts.insert(i * gap, ct); } - glwe_packing(module, &mut cts, log_gap, auto_keys, scratch); + + module.glwe_pack(&mut cts, log_gap, auto_keys, scratch); // And copies the repacked ciphertext on the receiver. - self.0.copy(module, cts.remove(&0).unwrap()) + module.glwe_copy(&mut self.0, cts.remove(&0).unwrap()); } } @@ -97,29 +67,17 @@ impl GLWEInfos for FheUintWord { } impl FheUintWord { - pub fn encrypt_sk( + pub fn encrypt_sk( &mut self, - module: &Module, + module: &M, data: T, - sk: &GLWESecretPrepared, + sk: &S, source_xa: &mut Source, source_xe: &mut Source, scratch: &mut Scratch, ) where - Module: VecZnxAddScalarInplace - + VecZnxDftBytesOf - + VecZnxBigNormalize - + VecZnxDftApply - + SvpApplyDftToDftInplace - + VecZnxIdftApplyConsume - + VecZnxNormalizeTmpBytes - + VecZnxFillUniform - + VecZnxSubInplace - + VecZnxAddInplace - + VecZnxNormalizeInplace - + VecZnxAddNormal - + VecZnxNormalize - + VecZnxSub, + S: GLWESecretPreparedToRef + GLWEInfos, + M: ModuleN + GLWEEncryptSk, Scratch: ScratchTakeCore, { #[cfg(debug_assertions)] @@ -143,7 +101,7 @@ impl FheUintWord { k: 1_usize.into(), }; - let (mut pt, scratch_1) = scratch.take_glwe_pt(&pt_infos); + let (mut pt, scratch_1) = scratch.take_glwe_plaintext(&pt_infos); pt.encode_vec_i64(&data_bits, TorusPrecision(1)); self.0 @@ -152,19 +110,10 @@ impl FheUintWord { } impl FheUintWord { - pub fn decrypt( - &self, - module: &Module, - sk: &GLWESecretPrepared, - scratch: &mut Scratch, - ) -> T + pub fn decrypt(&self, module: &M, sk: &S, scratch: &mut Scratch) -> T where - Module: VecZnxDftApply - + SvpApplyDftToDftInplace - + VecZnxIdftApplyConsume - + VecZnxBigAddInplace - + VecZnxBigAddSmallInplace - + VecZnxBigNormalize, + S: GLWESecretPreparedToRef + GLWEInfos, + M: GLWEDecrypt, Scratch: ScratchTakeCore, { #[cfg(debug_assertions)] @@ -182,7 +131,7 @@ impl FheUintWord { k: 1_usize.into(), }; - let (mut pt, scratch_1) = scratch.take_glwe_pt(&pt_infos); + let (mut pt, scratch_1) = scratch.take_glwe_plaintext(&pt_infos); self.0.decrypt(module, &mut pt, sk, scratch_1); diff --git a/poulpy-schemes/src/tfhe/bdd_arithmetic/eval.rs b/poulpy-schemes/src/tfhe/bdd_arithmetic/eval.rs index 953ee7a..2d5d086 100644 --- a/poulpy-schemes/src/tfhe/bdd_arithmetic/eval.rs +++ b/poulpy-schemes/src/tfhe/bdd_arithmetic/eval.rs @@ -1,13 +1,12 @@ use itertools::Itertools; use poulpy_core::{ + GLWEAdd, GLWECopy, GLWEExternalProduct, GLWESub, ScratchTakeCore, layouts::{ - prepared::{GGSWPrepared, GGSWPreparedToRef}, GLWEToMut, LWEInfos, GLWE - }, GLWEExternalProduct, ScratchTakeCore -}; -use poulpy_hal::{ - api::{VecZnxAddInplace, VecZnxCopy, VecZnxNegateInplace, VecZnxSub}, - layouts::{Backend, DataMut, DataRef, Module, Scratch, ZnxZero}, + GLWE, LWEInfos, + prepared::{GGSWPrepared, GGSWPreparedToRef}, + }, }; +use poulpy_hal::layouts::{Backend, DataMut, DataRef, Module, Scratch, ZnxZero}; use crate::tfhe::bdd_arithmetic::UnsignedInteger; @@ -29,45 +28,43 @@ pub(crate) struct BitCircuit { pub struct Circuit(pub [C; N]); -pub trait CircuitExecute -where - Self: GetBitCircuitInfo, -{ - fn execute( +pub trait ExecuteBDDCircuit { + fn execute_bdd_circuit( &self, - module: &Module, out: &mut [GLWE], inputs: &[&dyn GGSWPreparedToRef], + circuit: &C, scratch: &mut Scratch, ) where + C: GetBitCircuitInfo, O: DataMut; } -impl CircuitExecute for Circuit +impl ExecuteBDDCircuit for Module where - Self: GetBitCircuitInfo, - Module: Cmux + VecZnxCopy, + Self: Cmux + GLWECopy, Scratch: ScratchTakeCore, { - fn execute( + fn execute_bdd_circuit( &self, - module: &Module, out: &mut [GLWE], inputs: &[&dyn GGSWPreparedToRef], + circuit: &C, scratch: &mut Scratch, ) where + C: GetBitCircuitInfo, O: DataMut, { #[cfg(debug_assertions)] { - assert_eq!(inputs.len(), self.input_size()); - assert!(out.len() >= self.output_size()); + assert_eq!(inputs.len(), circuit.input_size()); + assert!(out.len() >= circuit.output_size()); } - for (i, out_i) in out.iter_mut().enumerate().take(self.output_size()) { - let (nodes, levels, max_inter_state) = self.get_circuit(i); + for (i, out_i) in out.iter_mut().enumerate().take(circuit.output_size()) { + let (nodes, levels, max_inter_state) = circuit.get_circuit(i); - let (mut level, scratch_1) = scratch.take_glwe_ct_slice(max_inter_state * 2, out_i); + let (mut level, scratch_1) = scratch.take_glwe_slice(max_inter_state * 2, out_i); level.iter_mut().for_each(|ct| ct.data_mut().zero()); @@ -87,9 +84,9 @@ where for (j, node) in nodes_lvl.iter().enumerate() { if node.low_index == node.high_index { - next_level[j].copy(module, prev_level[node.low_index]); + self.glwe_copy(next_level[j], prev_level[node.low_index]); } else { - module.cmux( + self.cmux( next_level[j], prev_level[node.high_index], prev_level[node.low_index], @@ -105,7 +102,7 @@ where // handle last output // there's always only 1 node at last level let node: &Node = nodes.last().unwrap(); - module.cmux( + self.cmux( out_i, prev_level[node.high_index], prev_level[node.low_index], @@ -114,7 +111,7 @@ where ); } - for out_i in out.iter_mut().skip(self.output_size()) { + for out_i in out.iter_mut().skip(circuit.output_size()) { out_i.data_mut().zero(); } } @@ -167,7 +164,8 @@ pub trait Cmux { impl Cmux for Module where - Module: GLWEExternalProduct + VecZnxSub + VecZnxCopy + VecZnxNegateInplace + VecZnxAddInplace, + Module: GLWEExternalProduct + GLWESub + GLWEAdd, + Scratch: ScratchTakeCore, { fn cmux(&self, out: &mut GLWE, t: &GLWE, f: &GLWE, s: &GGSWPrepared, scratch: &mut Scratch) where @@ -177,8 +175,8 @@ where S: DataRef, { // let mut out: GLWECiphertext<&mut [u8]> = out.to_mut(); - out.sub(self, t, f); - out.external_product_inplace(self, s, scratch); - out.to_mut().add_inplace(self, f); + self.glwe_sub(out, t, f); + self.glwe_external_product_inplace(out, s, scratch); + self.glwe_add_inplace(out, f); } } diff --git a/poulpy-schemes/src/tfhe/bdd_arithmetic/key.rs b/poulpy-schemes/src/tfhe/bdd_arithmetic/key.rs index e2b8453..d1c20c6 100644 --- a/poulpy-schemes/src/tfhe/bdd_arithmetic/key.rs +++ b/poulpy-schemes/src/tfhe/bdd_arithmetic/key.rs @@ -1,26 +1,21 @@ #[cfg(test)] -use crate::tfhe::bdd_arithmetic::FheUintBlocksPrepDebug; +use crate::tfhe::bdd_arithmetic::FheUintBlocksPreparedDebug; use crate::tfhe::{ - bdd_arithmetic::{FheUintBlocks, FheUintBlocksPrep, UnsignedInteger}, - blind_rotation::{BlindRotationAlgo, BlindRotationKey, BlindRotationKeyAlloc, BlindRotationKeyEncryptSk}, + bdd_arithmetic::{FheUintBlocks, FheUintBlocksPrepared, UnsignedInteger}, + blind_rotation::{BlindRotationAlgo, BlindRotationKey, BlindRotationKeyFactory}, circuit_bootstrapping::{ CircuitBootstrappingKey, CircuitBootstrappingKeyEncryptSk, CircuitBootstrappingKeyLayout, - CircuitBootstrappingKeyPrepared, CirtuitBootstrappingExecute, + CircuitBootstrappingKeyPrepared, CircuitBootstrappingKeyPreparedFactory, CirtuitBootstrappingExecute, }, }; use poulpy_core::{ + GLWEToLWESwitchingKeyEncryptSk, GetDistribution, LWEFromGLWE, ScratchTakeCore, layouts::{ - prepared::GLWEToLWESwitchingKeyPrepared, GLWESecret, GLWEToLWEKeyLayout, GLWEToLWESwitchingKey, LWESecret - }, ScratchTakeCore, + GGSWInfos, GGSWPreparedFactory, GLWEInfos, GLWESecretToRef, GLWEToLWEKeyLayout, GLWEToLWESwitchingKey, + GLWEToLWESwitchingKeyPreparedFactory, LWE, LWEInfos, LWESecretToRef, prepared::GLWEToLWESwitchingKeyPrepared, + }, }; use poulpy_hal::{ - api::{ - ScratchAvailable, SvpApplyDftToDft, SvpApplyDftToDftInplace, SvpPPolAlloc, SvpPPolBytesOf, SvpPrepare, VecZnxAddInplace, VecZnxAddNormal, VecZnxAddScalarInplace, - VecZnxAutomorphism, VecZnxAutomorphismInplace, VecZnxBigAddSmallInplace, VecZnxBigNormalize, VecZnxBigNormalizeTmpBytes, - VecZnxDftApply, VecZnxDftBytesOf, VecZnxFillUniform, VecZnxIdftApplyConsume, VecZnxIdftApplyTmpA, VecZnxNormalize, - VecZnxNormalizeInplace, VecZnxNormalizeTmpBytes, VecZnxRotate, VecZnxSub, VecZnxSubInplace, VecZnxSwitchRing, - VmpApplyDftToDft, VmpApplyDftToDftAdd, VmpApplyDftToDftTmpBytes, VmpPrepare, - }, layouts::{Backend, Data, DataMut, DataRef, Module, Scratch}, source::Source, }; @@ -46,193 +41,256 @@ impl BDDKeyInfos for BDDKeyLayout { } } -pub struct BDDKey +pub struct BDDKey where - CBT: Data, - LWE: Data, + D: Data, BRA: BlindRotationAlgo, { - cbt: CircuitBootstrappingKey, - ks: GLWEToLWESwitchingKey, + cbt: CircuitBootstrappingKey, + ks: GLWEToLWESwitchingKey, } -impl BDDKey, Vec, BRA> { - pub fn encrypt_sk( - module: &Module, - sk_lwe: &LWESecret, - sk_glwe: &GLWESecret, - infos: &A, +impl BDDKey, BRA> +where + BlindRotationKey, BRA>: BlindRotationKeyFactory, +{ + pub fn alloc_from_infos(infos: &A) -> Self + where + A: BDDKeyInfos, + { + Self { + cbt: CircuitBootstrappingKey::alloc_from_infos(&infos.cbt_infos()), + ks: GLWEToLWESwitchingKey::alloc_from_infos(&infos.ks_infos()), + } + } +} + +pub trait BDDKeyEncryptSk { + fn bdd_key_encrypt_sk( + &self, + res: &mut BDDKey, + sk_lwe: &S0, + sk_glwe: &S1, source_xa: &mut Source, source_xe: &mut Source, scratch: &mut Scratch, - ) -> Self - where - A: BDDKeyInfos, - DLwe: DataRef, - DGlwe: DataRef, - BlindRotationKey, BRA>: BlindRotationKeyAlloc + BlindRotationKeyEncryptSk, - Module: SvpApplyDftToDft - + VecZnxIdftApplyTmpA - + VecZnxAddScalarInplace - + VecZnxDftBytesOf - + VecZnxBigNormalize - + VecZnxDftApply - + SvpApplyDftToDftInplace - + VecZnxIdftApplyConsume - + VecZnxNormalizeTmpBytes - + VecZnxFillUniform - + VecZnxSubInplace - + VecZnxAddInplace - + VecZnxNormalizeInplace - + VecZnxAddNormal - + VecZnxNormalize - + VecZnxSub - + SvpPrepare - + VecZnxSwitchRing - + SvpPPolBytesOf - + SvpPPolAlloc - + VecZnxAutomorphism - + VecZnxAutomorphismInplace, + ) where + D: DataMut, + S0: LWESecretToRef + GetDistribution + LWEInfos, + S1: GLWESecretToRef + GetDistribution + GLWEInfos; +} + +impl BDDKeyEncryptSk for Module +where + Self: CircuitBootstrappingKeyEncryptSk + GLWEToLWESwitchingKeyEncryptSk, + Scratch: ScratchTakeCore, +{ + fn bdd_key_encrypt_sk( + &self, + res: &mut BDDKey, + sk_lwe: &S0, + sk_glwe: &S1, + source_xa: &mut Source, + source_xe: &mut Source, + scratch: &mut Scratch, + ) where + D: DataMut, + S0: LWESecretToRef + GetDistribution + LWEInfos, + S1: GLWESecretToRef + GetDistribution + GLWEInfos, + { + res.ks + .encrypt_sk(self, sk_lwe, sk_glwe, source_xa, source_xe, scratch); + res.cbt + .encrypt_sk(self, sk_lwe, sk_glwe, source_xa, source_xe, scratch); + } +} + +impl BDDKey { + pub fn encrypt_sk( + &mut self, + module: &M, + sk_lwe: &S0, + sk_glwe: &S1, + source_xa: &mut Source, + source_xe: &mut Source, + scratch: &mut Scratch, + ) where + S0: LWESecretToRef + GetDistribution + LWEInfos, + S1: GLWESecretToRef + GetDistribution + GLWEInfos, + M: BDDKeyEncryptSk, Scratch: ScratchTakeCore, { - let mut ks: GLWEToLWESwitchingKey> = GLWEToLWESwitchingKey::alloc(&infos.ks_infos()); - ks.encrypt_sk(module, sk_lwe, sk_glwe, source_xa, source_xe, scratch); - - Self { - cbt: CircuitBootstrappingKey::encrypt_sk( - module, - sk_lwe, - sk_glwe, - &infos.cbt_infos(), - source_xa, - source_xe, - scratch, - ), - ks, - } + module.bdd_key_encrypt_sk(self, sk_lwe, sk_glwe, source_xa, source_xe, scratch); } } -pub struct BDDKeyPrepared +pub struct BDDKeyPrepared where - CBT: Data, - LWE: Data, + D: Data, BRA: BlindRotationAlgo, BE: Backend, { - cbt: CircuitBootstrappingKeyPrepared, - ks: GLWEToLWESwitchingKeyPrepared, + pub(crate) cbt: CircuitBootstrappingKeyPrepared, + pub(crate) ks: GLWEToLWESwitchingKeyPrepared, } -impl PrepareAlloc> - for BDDKey +pub trait BDDKeyPreparedFactory where - CircuitBootstrappingKey: PrepareAlloc>, - GLWEToLWESwitchingKey: PrepareAlloc>, + Self: Sized + CircuitBootstrappingKeyPreparedFactory + GLWEToLWESwitchingKeyPreparedFactory, { - fn prepare_alloc(&self, module: &Module, scratch: &mut Scratch) -> BDDKeyPrepared { + fn alloc_bdd_key_from_infos(&self, infos: &A) -> BDDKeyPrepared, BRA, BE> + where + A: BDDKeyInfos, + { BDDKeyPrepared { - cbt: self.cbt.prepare_alloc(module, scratch), - ks: self.ks.prepare_alloc(module, scratch), + cbt: CircuitBootstrappingKeyPrepared::alloc_from_infos(self, &infos.cbt_infos()), + ks: GLWEToLWESwitchingKeyPrepared::alloc_from_infos(self, &infos.ks_infos()), + } + } + + fn prepare_bdd_key_tmp_bytes(&self, infos: &A) -> usize + where + A: BDDKeyInfos, + { + self.circuit_bootstrapping_key_prepare_tmp_bytes(&infos.cbt_infos()) + .max(self.prepare_glwe_to_lwe_switching_key_tmp_bytes(&infos.ks_infos())) + } + + fn prepare_bdd_key(&self, res: &mut BDDKeyPrepared, other: &BDDKey, scratch: &mut Scratch) + where + DM: DataMut, + DR: DataRef, + Scratch: ScratchTakeCore, + { + res.cbt.prepare(self, &other.cbt, scratch); + res.ks.prepare(self, &other.ks, scratch); + } +} +impl BDDKeyPreparedFactory for Module where + Self: Sized + CircuitBootstrappingKeyPreparedFactory + GLWEToLWESwitchingKeyPreparedFactory +{ +} + +impl BDDKeyPrepared, BRA, BE> { + pub fn alloc_from_infos(module: &M, infos: &A) -> Self + where + M: BDDKeyPreparedFactory, + A: BDDKeyInfos, + { + module.alloc_bdd_key_from_infos(infos) + } +} + +impl BDDKeyPrepared { + pub fn prepare(&mut self, module: &M, other: &BDDKey, scratch: &mut Scratch) + where + DR: DataRef, + M: BDDKeyPreparedFactory, + Scratch: ScratchTakeCore, + { + module.prepare_bdd_key(self, other, scratch); + } +} + +pub trait FheUintBlocksPrepare { + fn fhe_uint_blocks_prepare_tmp_bytes( + &self, + block_size: usize, + extension_factor: usize, + res_infos: &R, + infos: &A, + ) -> usize + where + R: GGSWInfos, + A: BDDKeyInfos; + fn fhe_uint_blocks_prepare( + &self, + res: &mut FheUintBlocksPrepared, + bits: &FheUintBlocks, + key: &BDDKeyPrepared, + scratch: &mut Scratch, + ) where + DM: DataMut, + DR0: DataRef, + DR1: DataRef; +} + +impl FheUintBlocksPrepare for Module +where + Self: LWEFromGLWE + CirtuitBootstrappingExecute + GGSWPreparedFactory, + Scratch: ScratchTakeCore, +{ + fn fhe_uint_blocks_prepare_tmp_bytes( + &self, + block_size: usize, + extension_factor: usize, + res_infos: &R, + bdd_infos: &A, + ) -> usize + where + R: GGSWInfos, + A: BDDKeyInfos, + { + self.circuit_bootstrapping_execute_tmp_bytes( + block_size, + extension_factor, + res_infos, + &bdd_infos.cbt_infos(), + ) + } + + fn fhe_uint_blocks_prepare( + &self, + res: &mut FheUintBlocksPrepared, + bits: &FheUintBlocks, + key: &BDDKeyPrepared, + scratch: &mut Scratch, + ) where + DM: DataMut, + DR0: DataRef, + DR1: DataRef, + { + assert_eq!(res.blocks.len(), bits.blocks.len()); + + let mut lwe: LWE> = LWE::alloc_from_infos(&bits.blocks[0]); //TODO: add TakeLWE + let (mut tmp_ggsw, scratch_1) = scratch.take_ggsw(res); + for (dst, src) in res.blocks.iter_mut().zip(bits.blocks.iter()) { + lwe.from_glwe(self, src, &key.ks, scratch_1); + key.cbt + .execute_to_constant(self, &mut tmp_ggsw, &lwe, 1, 1, scratch_1); + dst.prepare(self, &tmp_ggsw, scratch_1); } } } -pub trait FheUintPrepare { - fn prepare(&self, module: &Module, out: &mut OUT, bits: &IN, scratch: &mut Scratch); -} - -impl FheUintPrepare, FheUintBlocks> - for BDDKeyPrepared -where - T: UnsignedInteger, - CBT: DataRef, - OUT: DataMut, - IN: DataRef, - LWE: DataRef, - BRA: BlindRotationAlgo, - BE: Backend, - Module: VmpPrepare - + VecZnxRotate - + VecZnxDftBytesOf - + VmpApplyDftToDftTmpBytes - + VecZnxBigNormalizeTmpBytes - + VmpApplyDftToDft - + VmpApplyDftToDftAdd - + VecZnxDftApply - + VecZnxIdftApplyConsume - + VecZnxBigAddSmallInplace - + VecZnxBigNormalize - + VecZnxNormalize - + VecZnxNormalizeTmpBytes, - Scratch: ScratchAvailable + TakeVecZnxDft + TakeGLWE + TakeVecZnx + TakeGGSW, - CircuitBootstrappingKeyPrepared: CirtuitBootstrappingExecute, -{ - fn prepare( - &self, - module: &Module, - out: &mut FheUintBlocksPrep, - bits: &FheUintBlocks, +impl FheUintBlocksPrepared { + pub fn prepare( + &mut self, + module: &M, + other: &FheUintBlocks, + key: &BDDKeyPrepared, scratch: &mut Scratch, - ) { - #[cfg(debug_assertions)] - { - assert_eq!(out.blocks.len(), bits.blocks.len()); - } - let mut lwe: LWE> = LWE::alloc(&bits.blocks[0]); //TODO: add TakeLWE - let (mut tmp_ggsw, scratch_1) = scratch.take_ggsw(out); - for (dst, src) in out.blocks.iter_mut().zip(bits.blocks.iter()) { - lwe.from_glwe(module, src, &self.ks, scratch_1); - self.cbt - .execute_to_constant(module, &mut tmp_ggsw, &lwe, 1, 1, scratch_1); - dst.prepare(module, &tmp_ggsw, scratch_1); - } + ) where + BRA: BlindRotationAlgo, + O: DataRef, + K: DataRef, + M: FheUintBlocksPrepare, + Scratch: ScratchTakeCore, + { + module.fhe_uint_blocks_prepare(self, other, key, scratch); } } #[cfg(test)] -impl FheUintPrepare, FheUintBlocks> - for BDDKeyPrepared -where - T: UnsignedInteger, - CBT: DataRef, - OUT: DataMut, - IN: DataRef, - LWE: DataRef, - BRA: BlindRotationAlgo, - BE: Backend, - Module: VmpPrepare - + VecZnxRotate - + VecZnxDftBytesOf - + VmpApplyDftToDftTmpBytes - + VecZnxBigNormalizeTmpBytes - + VmpApplyDftToDft - + VmpApplyDftToDftAdd - + VecZnxDftApply - + VecZnxIdftApplyConsume - + VecZnxBigAddSmallInplace - + VecZnxBigNormalize - + VecZnxNormalize - + VecZnxNormalizeTmpBytes, - Scratch: ScratchTakeCore, - CircuitBootstrappingKeyPrepared: CirtuitBootstrappingExecute, -{ - fn prepare( +pub(crate) trait FheUintBlockDebugPrepare { + fn fhe_uint_block_debug_prepare( &self, - module: &Module, - out: &mut FheUintBlocksPrepDebug, - bits: &FheUintBlocks, + res: &mut FheUintBlocksPreparedDebug, + bits: &FheUintBlocks, + key: &BDDKeyPrepared, scratch: &mut Scratch, - ) { - #[cfg(debug_assertions)] - { - assert_eq!(out.blocks.len(), bits.blocks.len()); - } - let mut lwe: LWE> = LWE::alloc(&bits.blocks[0]); //TODO: add TakeLWE - for (dst, src) in out.blocks.iter_mut().zip(bits.blocks.iter()) { - lwe.from_glwe(module, src, &self.ks, scratch); - self.cbt - .execute_to_constant(module, dst, &lwe, 1, 1, scratch); - } - } + ) where + DM: DataMut, + DR0: DataRef, + DR1: DataRef; } diff --git a/poulpy-schemes/src/tfhe/bdd_arithmetic/parameters.rs b/poulpy-schemes/src/tfhe/bdd_arithmetic/parameters.rs index 90175fb..f807414 100644 --- a/poulpy-schemes/src/tfhe/bdd_arithmetic/parameters.rs +++ b/poulpy-schemes/src/tfhe/bdd_arithmetic/parameters.rs @@ -1,7 +1,7 @@ #[cfg(test)] use poulpy_core::layouts::{ - AutomorphismKeyLayout, Base2K, Degree, Dnum, Dsize, GGSWLayout, GLWELayout, GLWEToLWEKeyLayout, Rank, TensorKeyLayout, - TorusPrecision, + Base2K, Degree, Dnum, Dsize, GGSWLayout, GLWEAutomorphismKeyLayout, GLWELayout, GLWETensorKeyLayout, GLWEToLWEKeyLayout, + Rank, TorusPrecision, }; #[cfg(test)] @@ -53,7 +53,7 @@ pub(crate) static TEST_BDD_KEY_LAYOUT: BDDKeyLayout = BDDKeyLayout { dnum: Dnum(3), rank: Rank(TEST_RANK), }, - layout_atk: AutomorphismKeyLayout { + layout_atk: GLWEAutomorphismKeyLayout { n: Degree(TEST_N_GLWE), base2k: Base2K(TEST_BASE2K), k: TorusPrecision(52), @@ -61,7 +61,7 @@ pub(crate) static TEST_BDD_KEY_LAYOUT: BDDKeyLayout = BDDKeyLayout { dnum: Dnum(3), dsize: Dsize(1), }, - layout_tsk: TensorKeyLayout { + layout_tsk: GLWETensorKeyLayout { n: Degree(TEST_N_GLWE), base2k: Base2K(TEST_BASE2K), k: TorusPrecision(52), diff --git a/poulpy-schemes/src/tfhe/bdd_arithmetic/test.rs b/poulpy-schemes/src/tfhe/bdd_arithmetic/test.rs index 1c2e69d..19155ea 100644 --- a/poulpy-schemes/src/tfhe/bdd_arithmetic/test.rs +++ b/poulpy-schemes/src/tfhe/bdd_arithmetic/test.rs @@ -2,43 +2,24 @@ use std::time::Instant; use poulpy_backend::FFT64Ref; use poulpy_core::{ - TakeGGSW, TakeGLWEPlaintext, - layouts::{ - GGSWLayout, GLWELayout, GLWESecret, LWEInfos, LWESecret, - prepared::{GLWESecretPrepared, PrepareAlloc}, - }, + GGSWNoise, GLWEDecrypt, GLWENoise, ScratchTakeCore, + layouts::{GGSWLayout, GLWELayout, GLWESecret, GLWESecretPreparedFactory, LWEInfos, LWESecret, prepared::GLWESecretPrepared}, }; use poulpy_hal::{ - api::{ - ModuleNew, ScratchAvailable, ScratchOwnedAlloc, ScratchOwnedBorrow, SvpApplyDftToDft, SvpApplyDftToDftInplace, - SvpPPolAlloc, SvpPPolBytesOf, SvpPrepare, TakeScalarZnx, TakeSlice, TakeVecZnx, TakeVecZnxBig, TakeVecZnxDft, - VecZnxAddInplace, VecZnxAddNormal, VecZnxAddScalarInplace, VecZnxAutomorphism, VecZnxAutomorphismInplace, - VecZnxBigAddInplace, VecZnxBigAddSmallInplace, VecZnxBigAlloc, VecZnxBigAutomorphismInplace, VecZnxBigBytesOf, - VecZnxBigNormalize, VecZnxBigNormalizeTmpBytes, VecZnxBigSubSmallNegateInplace, VecZnxCopy, VecZnxDftAddInplace, - VecZnxDftAlloc, VecZnxDftApply, VecZnxDftBytesOf, VecZnxDftCopy, VecZnxFillUniform, VecZnxIdftApplyConsume, - VecZnxIdftApplyTmpA, VecZnxNegateInplace, VecZnxNormalize, VecZnxNormalizeInplace, VecZnxNormalizeTmpBytes, VecZnxRotate, - VecZnxRotateInplace, VecZnxRotateInplaceTmpBytes, VecZnxRshInplace, VecZnxSub, VecZnxSubInplace, VecZnxSwitchRing, - VmpApplyDftToDft, VmpApplyDftToDftAdd, VmpApplyDftToDftTmpBytes, VmpPMatAlloc, VmpPrepare, ZnAddNormal, ZnFillUniform, - ZnNormalizeInplace, - }, + api::{ModuleNew, ScratchOwnedAlloc, ScratchOwnedBorrow}, layouts::{Backend, Module, Scratch, ScratchOwned}, - oep::{ - ScratchAvailableImpl, ScratchOwnedAllocImpl, ScratchOwnedBorrowImpl, TakeMatZnxImpl, TakeScalarZnxImpl, TakeSvpPPolImpl, - TakeVecZnxBigImpl, TakeVecZnxDftImpl, TakeVecZnxDftSliceImpl, TakeVecZnxImpl, TakeVecZnxSliceImpl, - }, source::Source, }; use rand::RngCore; use crate::tfhe::{ bdd_arithmetic::{ - Add, BDDKey, BDDKeyLayout, BDDKeyPrepared, FheUintBlocks, FheUintBlocksPrep, FheUintBlocksPrepDebug, Sub, - TEST_BDD_KEY_LAYOUT, TEST_BLOCK_SIZE, TEST_GGSW_INFOS, TEST_GLWE_INFOS, TEST_N_LWE, - }, - blind_rotation::{ - BlincRotationExecute, BlindRotationAlgo, BlindRotationKey, BlindRotationKeyAlloc, BlindRotationKeyEncryptSk, - BlindRotationKeyPrepared, CGGI, + Add, BDDKey, BDDKeyEncryptSk, BDDKeyLayout, BDDKeyPrepared, BDDKeyPreparedFactory, ExecuteBDDCircuit2WTo1W, + FheUintBlockDebugPrepare, FheUintBlocks, FheUintBlocksPrepare, FheUintBlocksPrepared, FheUintBlocksPreparedDebug, + FheUintBlocksPreparedEncryptSk, FheUintBlocksPreparedFactory, Sub, TEST_BDD_KEY_LAYOUT, TEST_BLOCK_SIZE, TEST_GGSW_INFOS, + TEST_GLWE_INFOS, TEST_N_LWE, }, + blind_rotation::{BlindRotationAlgo, BlindRotationKey, BlindRotationKeyFactory, CGGI}, }; #[test] @@ -48,64 +29,21 @@ fn test_bdd_2w_to_1w_fft64_ref() { fn test_bdd_2w_to_1w() where - Module: ModuleNew + SvpPPolAlloc + SvpPrepare + VmpPMatAlloc, + Module: ModuleNew + + GLWESecretPreparedFactory + + GLWEDecrypt + + GLWENoise + + FheUintBlocksPreparedFactory + + FheUintBlocksPreparedEncryptSk + + FheUintBlockDebugPrepare + + BDDKeyEncryptSk + + BDDKeyPreparedFactory + + GGSWNoise + + FheUintBlocksPrepare + + ExecuteBDDCircuit2WTo1W, + BlindRotationKey, BRA>: BlindRotationKeyFactory, ScratchOwned: ScratchOwnedAlloc + ScratchOwnedBorrow, - Module: VecZnxAddScalarInplace - + VecZnxDftBytesOf - + VecZnxBigNormalize - + VecZnxDftApply - + SvpApplyDftToDftInplace - + VecZnxIdftApplyConsume - + VecZnxNormalizeTmpBytes - + VecZnxFillUniform - + VecZnxSubInplace - + VecZnxAddInplace - + VecZnxNormalizeInplace - + VecZnxAddNormal - + VecZnxNormalize - + VecZnxSub - + VmpPrepare, - Scratch: TakeVecZnxDft + ScratchAvailable + TakeVecZnx + TakeGGSW + TakeScalarZnx + TakeSlice, - Module: VecZnxCopy + VecZnxNegateInplace + VmpApplyDftToDftTmpBytes + VmpApplyDftToDft + VmpApplyDftToDftAdd, - Module: VecZnxBigAddInplace + VecZnxBigAddSmallInplace + VecZnxBigNormalize, - Scratch: TakeVecZnxDft + TakeVecZnxBig + TakeGLWEPlaintext, - Module: VecZnxAutomorphism - + VecZnxSwitchRing - + VecZnxBigBytesOf - + VecZnxIdftApplyTmpA - + SvpApplyDftToDft - + VecZnxBigAlloc - + VecZnxDftAlloc - + VecZnxBigNormalizeTmpBytes - + SvpPPolBytesOf - + VecZnxRotateInplace - + VecZnxBigAutomorphismInplace - + VecZnxRshInplace - + VecZnxDftCopy - + VecZnxAutomorphismInplace - + VecZnxBigSubSmallNegateInplace - + VecZnxRotateInplaceTmpBytes - + VecZnxBigBytesOf - + VecZnxDftAddInplace - + VecZnxRotate - + ZnFillUniform - + ZnAddNormal - + ZnNormalizeInplace, - BE: Backend - + ScratchOwnedAllocImpl - + ScratchOwnedBorrowImpl - + TakeVecZnxDftImpl - + ScratchAvailableImpl - + TakeVecZnxImpl - + TakeScalarZnxImpl - + TakeSvpPPolImpl - + TakeVecZnxBigImpl - + TakeVecZnxDftSliceImpl - + TakeMatZnxImpl - + TakeVecZnxSliceImpl, - BlindRotationKey, BRA>: PrepareAlloc, BRA, BE>>, - BlindRotationKeyPrepared, BRA, BE>: BlincRotationExecute, - BlindRotationKey, BRA>: BlindRotationKeyAlloc + BlindRotationKeyEncryptSk, + Scratch: ScratchTakeCore, { let glwe_infos: GLWELayout = TEST_GLWE_INFOS; let ggsw_infos: GGSWLayout = TEST_GGSW_INFOS; @@ -122,7 +60,8 @@ where let mut sk_glwe: GLWESecret> = GLWESecret::alloc_from_infos(&glwe_infos); sk_glwe.fill_ternary_prob(0.5, &mut source_xs); - let sk_glwe_prep: GLWESecretPrepared, BE> = sk_glwe.prepare_alloc(&module, scratch.borrow()); + let mut sk_glwe_prep: GLWESecretPrepared, BE> = GLWESecretPrepared::alloc_from_infos(&module, &glwe_infos); + sk_glwe_prep.prepare(&module, &sk_glwe); let a: u32 = source.next_u32(); let b: u32 = source.next_u32(); @@ -130,12 +69,15 @@ where println!("a: {a}"); println!("b: {b}"); - let mut a_enc_prep: FheUintBlocksPrep, BE, u32> = FheUintBlocksPrep::, BE, u32>::alloc(&module, &ggsw_infos); - let mut b_enc_prep: FheUintBlocksPrep, BE, u32> = FheUintBlocksPrep::, BE, u32>::alloc(&module, &ggsw_infos); + let mut a_enc_prep: FheUintBlocksPrepared, u32, BE> = + FheUintBlocksPrepared::, u32, BE>::alloc(&module, &ggsw_infos); + let mut b_enc_prep: FheUintBlocksPrepared, u32, BE> = + FheUintBlocksPrepared::, u32, BE>::alloc(&module, &ggsw_infos); let mut c_enc: FheUintBlocks, u32> = FheUintBlocks::, u32>::alloc(&module, &glwe_infos); - let mut c_enc_prep_debug: FheUintBlocksPrepDebug, u32> = - FheUintBlocksPrepDebug::, u32>::alloc(&module, &ggsw_infos); - let mut c_enc_prep: FheUintBlocksPrep, BE, u32> = FheUintBlocksPrep::, BE, u32>::alloc(&module, &ggsw_infos); + let mut c_enc_prep_debug: FheUintBlocksPreparedDebug, u32> = + FheUintBlocksPreparedDebug::, u32>::alloc(&module, &ggsw_infos); + let mut c_enc_prep: FheUintBlocksPrepared, u32, BE> = + FheUintBlocksPrepared::, u32, BE>::alloc(&module, &ggsw_infos); a_enc_prep.encrypt_sk( &module, @@ -178,17 +120,19 @@ where let bdd_key_infos: BDDKeyLayout = TEST_BDD_KEY_LAYOUT; + let mut bdd_key: BDDKey, BRA> = BDDKey::alloc_from_infos(&bdd_key_infos); + let now: Instant = Instant::now(); - let bdd_key: BDDKey, Vec, BRA> = BDDKey::encrypt_sk( + bdd_key.encrypt_sk( &module, &sk_lwe, &sk_glwe, - &bdd_key_infos, &mut source_xa, &mut source_xe, scratch.borrow(), ); - let bdd_key_prepared: BDDKeyPrepared, Vec, BRA, BE> = bdd_key.prepare_alloc(&module, scratch.borrow()); + let mut bdd_key_prepared: BDDKeyPrepared, BRA, BE> = BDDKeyPrepared::alloc_from_infos(&module, &bdd_key_infos); + bdd_key_prepared.prepare(&module, &bdd_key, scratch.borrow()); println!("BDD-KGEN: {} ms", now.elapsed().as_millis()); let now: Instant = Instant::now(); diff --git a/poulpy-schemes/src/tfhe/blind_rotation/algorithms/cggi/key_prepared.rs b/poulpy-schemes/src/tfhe/blind_rotation/algorithms/cggi/key_prepared.rs index fe3e795..bc1ab98 100644 --- a/poulpy-schemes/src/tfhe/blind_rotation/algorithms/cggi/key_prepared.rs +++ b/poulpy-schemes/src/tfhe/blind_rotation/algorithms/cggi/key_prepared.rs @@ -33,7 +33,14 @@ where } } - fn blind_rotation_key_prepare( + fn blind_rotation_key_prepare_tmp_bytes(&self, infos: &A) -> usize + where + A: BlindRotationKeyInfos, + { + self.ggsw_prepare_tmp_bytes(infos) + } + + fn prepare_blind_rotation_key( &self, res: &mut BlindRotationKeyPrepared, other: &BlindRotationKey, diff --git a/poulpy-schemes/src/tfhe/blind_rotation/layouts/key_prepared.rs b/poulpy-schemes/src/tfhe/blind_rotation/layouts/key_prepared.rs index c18e71c..cf533c1 100644 --- a/poulpy-schemes/src/tfhe/blind_rotation/layouts/key_prepared.rs +++ b/poulpy-schemes/src/tfhe/blind_rotation/layouts/key_prepared.rs @@ -14,7 +14,11 @@ pub trait BlindRotationKeyPreparedFactory { where A: BlindRotationKeyInfos; - fn blind_rotation_key_prepare( + fn blind_rotation_key_prepare_tmp_bytes(&self, infos: &A) -> usize + where + A: BlindRotationKeyInfos; + + fn prepare_blind_rotation_key( &self, res: &mut BlindRotationKeyPrepared, other: &BlindRotationKey, @@ -32,6 +36,14 @@ impl BlindRotationKeyPrepared, BRA, { module.blind_rotation_key_prepared_alloc(infos) } + + pub fn prepare_tmp_bytes(module: &M, infos: &A) -> usize + where + A: BlindRotationKeyInfos, + M: BlindRotationKeyPreparedFactory, + { + module.blind_rotation_key_prepare_tmp_bytes(infos) + } } impl BlindRotationKeyPrepared { @@ -39,7 +51,7 @@ impl BlindRotationKeyPrepared, { - module.blind_rotation_key_prepare(self, other, scratch); + module.prepare_blind_rotation_key(self, other, scratch); } } diff --git a/poulpy-schemes/src/tfhe/circuit_bootstrapping/circuit.rs b/poulpy-schemes/src/tfhe/circuit_bootstrapping/circuit.rs index 5b3ea4d..a627e0c 100644 --- a/poulpy-schemes/src/tfhe/circuit_bootstrapping/circuit.rs +++ b/poulpy-schemes/src/tfhe/circuit_bootstrapping/circuit.rs @@ -18,10 +18,21 @@ use crate::tfhe::{ blind_rotation::{ BlindRotationAlgo, BlindRotationExecute, LookUpTableLayout, LookUpTableRotationDirection, LookupTable, LookupTableFactory, }, - circuit_bootstrapping::CircuitBootstrappingKeyPrepared, + circuit_bootstrapping::{CircuitBootstrappingKeyInfos, CircuitBootstrappingKeyPrepared}, }; pub trait CirtuitBootstrappingExecute { + fn circuit_bootstrapping_execute_tmp_bytes( + &self, + block_size: usize, + extension_factor: usize, + res_infos: &R, + cbt_infos: &A, + ) -> usize + where + R: GGSWInfos, + A: CircuitBootstrappingKeyInfos; + fn circuit_bootstrapping_execute_to_constant( &self, res: &mut R, @@ -68,6 +79,7 @@ impl CircuitBootstrappingKeyPre module.circuit_bootstrapping_execute_to_constant(res, lwe, self, log_domain, extension_factor, scratch); } + #[allow(clippy::too_many_arguments)] pub fn execute_to_exponent( &self, module: &M, @@ -107,6 +119,27 @@ where ScratchOwned: ScratchOwnedAlloc + ScratchOwnedBorrow, Scratch: ScratchTakeCore, { + fn circuit_bootstrapping_execute_tmp_bytes( + &self, + block_size: usize, + extension_factor: usize, + res_infos: &R, + cbt_infos: &A, + ) -> usize + where + R: GGSWInfos, + A: CircuitBootstrappingKeyInfos, + { + self.blind_rotation_execute_tmp_bytes( + block_size, + extension_factor, + res_infos, + &cbt_infos.brk_infos(), + ) + .max(self.glwe_trace_tmp_bytes(res_infos, res_infos, &cbt_infos.atk_infos())) + .max(self.ggsw_from_gglwe_tmp_bytes(res_infos, &cbt_infos.tsk_infos())) + } + fn circuit_bootstrapping_execute_to_constant( &self, res: &mut R, diff --git a/poulpy-schemes/src/tfhe/circuit_bootstrapping/key_prepared.rs b/poulpy-schemes/src/tfhe/circuit_bootstrapping/key_prepared.rs index db39a45..6adca70 100644 --- a/poulpy-schemes/src/tfhe/circuit_bootstrapping/key_prepared.rs +++ b/poulpy-schemes/src/tfhe/circuit_bootstrapping/key_prepared.rs @@ -75,6 +75,16 @@ where .collect(), } } + + fn circuit_bootstrapping_key_prepare_tmp_bytes(&self, infos: &A) -> usize + where + A: CircuitBootstrappingKeyInfos, + { + self.blind_rotation_key_prepare_tmp_bytes(&infos.brk_infos()) + .max(self.prepare_tensor_key_tmp_bytes(&infos.tsk_infos())) + .max(self.prepare_glwe_automorphism_key_tmp_bytes(&infos.atk_infos())) + } + fn circuit_bootstrapping_key_prepare( &self, res: &mut CircuitBootstrappingKeyPrepared, diff --git a/poulpy-schemes/src/tfhe/mod.rs b/poulpy-schemes/src/tfhe/mod.rs index b91a937..85c84d4 100644 --- a/poulpy-schemes/src/tfhe/mod.rs +++ b/poulpy-schemes/src/tfhe/mod.rs @@ -1,3 +1,3 @@ -// pub mod bdd_arithmetic; +pub mod bdd_arithmetic; pub mod blind_rotation; pub mod circuit_bootstrapping;