diff --git a/poulpy-core/src/layouts/glwe.rs b/poulpy-core/src/layouts/glwe.rs index d47f8cd..0f0e7f0 100644 --- a/poulpy-core/src/layouts/glwe.rs +++ b/poulpy-core/src/layouts/glwe.rs @@ -207,7 +207,10 @@ pub trait GLWEToMut { fn to_mut(&mut self) -> GLWE<&mut [u8]>; } -impl GLWEToMut for GLWE { +impl GLWEToMut for GLWE +where + Self: GLWEToRef, +{ fn to_mut(&mut self) -> GLWE<&mut [u8]> { GLWE { k: self.k, 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 d69bfe1..63692fe 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 @@ -54,7 +54,7 @@ where self.execute_bdd_circuit(&mut out_bits, &helper, circuit, scratch_1); // Repacks the bits - out.pack(self, out_bits, &key.cbt.atk, scratch_1); + out.pack(self, out_bits, key, scratch_1); } } diff --git a/poulpy-schemes/src/tfhe/bdd_arithmetic/ciphertexts/fhe_uint.rs b/poulpy-schemes/src/tfhe/bdd_arithmetic/ciphertexts/fhe_uint.rs index f8a5e12..697bcc4 100644 --- a/poulpy-schemes/src/tfhe/bdd_arithmetic/ciphertexts/fhe_uint.rs +++ b/poulpy-schemes/src/tfhe/bdd_arithmetic/ciphertexts/fhe_uint.rs @@ -1,8 +1,8 @@ use poulpy_core::{ GLWECopy, GLWEDecrypt, GLWEEncryptSk, GLWEPacking, GLWERotate, LWEFromGLWE, ScratchTakeCore, layouts::{ - Base2K, Degree, GGLWEInfos, GGLWEPreparedToRef, GLWE, GLWEInfos, GLWEPlaintextLayout, GLWESecretPreparedToRef, GLWEToRef, - LWEInfos, LWEToMut, Rank, TorusPrecision, prepared::GLWEAutomorphismKeyPrepared, + Base2K, Degree, GGLWEInfos, GGLWEPreparedToRef, GLWE, GLWEInfos, GLWEPlaintextLayout, GLWESecretPreparedToRef, GLWEToMut, + GLWEToRef, LWEInfos, LWEToMut, Rank, TorusPrecision, }, }; use poulpy_hal::{ @@ -12,7 +12,10 @@ use poulpy_hal::{ }; use std::{collections::HashMap, marker::PhantomData}; -use crate::tfhe::bdd_arithmetic::{FromBits, ToBits, UnsignedInteger}; +use crate::tfhe::{ + bdd_arithmetic::{BDDKeyPrepared, FromBits, ToBits, UnsignedInteger}, + blind_rotation::BlindRotationAlgo, +}; /// An FHE ciphertext encrypting the bits of an [UnsignedInteger]. pub struct FheUint { @@ -141,37 +144,113 @@ impl FheUint { } impl FheUint { - #[allow(dead_code)] - pub(crate) fn pack( + /// Packs Vec into [FheUint]. + pub fn pack( &mut self, module: &M, - mut tmp_res: Vec>, - auto_keys: &HashMap>, + mut bits: Vec, + key: &BDDKeyPrepared, scratch: &mut Scratch, ) where - D1: DataMut, - ATK: DataRef, + G: GLWEToMut + GLWEToRef + GLWEInfos, + D1: DataRef, M: ModuleLogN + GLWEPacking + GLWECopy, Scratch: ScratchTakeCore, { // Repacks the GLWE ciphertexts bits let log_gap: usize = module.log_n() - T::LOG_BITS as usize; - let mut cts: HashMap> = HashMap::new(); - for (i, ct) in tmp_res.iter_mut().enumerate().take(T::BITS as usize) { + let mut cts: HashMap = HashMap::new(); + for (i, ct) in bits.iter_mut().enumerate().take(T::BITS as usize) { cts.insert(T::bit_index(i) << log_gap, ct); } - module.glwe_pack(&mut cts, log_gap, auto_keys, scratch); + module.glwe_pack(&mut cts, log_gap, &key.cbt.atk, scratch); // And copies the repacked ciphertext on the receiver. module.glwe_copy(&mut self.bits, cts.remove(&0).unwrap()); } + + // pub fn copy_byte( + // &mut self, + // module: &M, + // byte_self: usize, + // byte_a: usize, + // a: &FheUint, + // keys: &BDDKeyPrepared, + // scratch: &mut Scratch, + // ) where + // D0: DataRef, + // D1: DataRef, + // BRA: BlindRotationAlgo, + // M:ModuleLogN + GLWERotate + GLWETrace + GLWESub + GLWEAdd, + // Scratch: ScratchTakeBDD, + // { + // let (mut tmp_fhe_uint_byte, scratch_1) = scratch.take_fhe_uint(a); + // + // + // let log_gap: usize = module.log_n() - T::LOG_BITS as usize; + // module.glwe_rotate(-((T::bit_index(byte_a << 3) << log_gap) as i64), tmp_fhe_uint_byte, self); + // module.glwe_trace_inplace(&mut tmp_fhe_uint_byte, module.log_n() - 3, module.log_n(),&keys.cbt.atk, scratch); + // + // let log_gap: usize = module.log_n() - T::LOG_BITS as usize; + // let rot: i64 = (T::bit_index(byte_self << 3) << log_gap) as i64; + // + // Move starting byte index to first coefficient + // module.glwe_rotate_inplace(-rot, &mut self.bits, scratch); + // + // Stores this byte (everything else zeroed) into tmp_trace + // let (mut tmp_trace, scratch_1) = scratch.take_glwe(self); + // module.glwe_trace( + // &mut tmp_trace, + // module.log_n() - 3, + // module.log_n(), + // self, + // &keys.cbt.atk, + // scratch_1, + // ); + // + // Subtracts the byte + // module.glwe_sub_inplace(&mut self.bits, &tmp_trace); + // + // module.glwe_add_inplace(&mut self.bits, &tmp_fhe_uint_byte); + // + // Moves back into the original position + // module.glwe_rotate_inplace(-rot, &mut self.bits, scratch); + // + // } } -impl FheUint { - pub fn get_bit(&self, module: &M, bit: usize, res: &mut L, ks: &K, scratch: &mut Scratch) +impl GLWEToMut for FheUint { + fn to_mut(&mut self) -> GLWE<&mut [u8]> { + self.bits.to_mut() + } +} + +pub trait ScratchTakeBDD +where + Self: ScratchTakeCore, +{ + fn take_fhe_uint(&mut self, infos: &A) -> (FheUint<&mut [u8], T>, &mut Self) where - L: LWEToMut, + A: GLWEInfos, + { + let (glwe, scratch) = self.take_glwe(infos); + ( + FheUint { + bits: glwe, + _phantom: PhantomData, + }, + scratch, + ) + } +} + +impl ScratchTakeBDD for Scratch where Self: ScratchTakeCore {} + +impl FheUint { + pub fn get_bit(&self, module: &M, bit: usize, res: &mut R, ks: &K, scratch: &mut Scratch) + where + R: LWEToMut, K: GGLWEPreparedToRef + GGLWEInfos, M: ModuleLogN + LWEFromGLWE + GLWERotate, Scratch: ScratchTakeCore,