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 104a8d8..402f412 100644 --- a/poulpy-schemes/src/tfhe/bdd_arithmetic/ciphertexts/fhe_uint.rs +++ b/poulpy-schemes/src/tfhe/bdd_arithmetic/ciphertexts/fhe_uint.rs @@ -234,20 +234,14 @@ impl FheUint { let trace_start = (T::LOG_BITS - T::LOG_BYTES) as usize; let rot: i64 = (T::bit_index(dst << 3) << log_gap) as i64; - // Move a to self and align byte - module.glwe_rotate(-rot, &mut self.bits, a); + module.glwe_copy(self, a); - // Stores this byte (everything else zeroed) into tmp_trace - let (mut tmp_trace, scratch_1) = scratch.take_glwe(a); - module.glwe_trace(&mut tmp_trace, trace_start, self, keys, scratch_1); - - // Subtracts to self to zero it - module.glwe_sub_inplace(&mut self.bits, &tmp_trace); + self.zero_byte(module, dst, keys, scratch); // Isolate the byte to transfer from a let (mut tmp_fhe_uint_byte, scratch_1) = scratch.take_fhe_uint(b); - // Move a[byte_a] into a[0] + // Move a[byte_a] into a[dst] module.glwe_rotate( -((T::bit_index(src << 3) << log_gap) as i64), &mut tmp_fhe_uint_byte, @@ -257,11 +251,11 @@ impl FheUint { // Zeroes all other bytes module.glwe_trace_inplace(&mut tmp_fhe_uint_byte, trace_start, keys, scratch_1); + // Moves back self[0] to self[byte_tg] + module.glwe_rotate_inplace(rot, &mut tmp_fhe_uint_byte, scratch_1); + // Add self[0] += a[0] module.glwe_add_inplace(&mut self.bits, &tmp_fhe_uint_byte); - - // Moves back self[0] to self[byte_tg] - module.glwe_rotate_inplace(rot, &mut self.bits, scratch); } } @@ -313,6 +307,31 @@ impl GLWEToRef for FheUint { } impl FheUint { + pub fn zero_byte(&mut self, module: &M, byte: usize, keys: &H, scratch: &mut Scratch) + where + H: GLWEAutomorphismKeyHelper, + K: GGLWEPreparedToRef + GGLWEInfos + GetGaloisElement, + M: ModuleLogN + GLWERotate + GLWETrace + GLWESub + GLWEAdd + GLWECopy, + Scratch: ScratchTakeBDD, + { + let log_gap: usize = module.log_n() - T::LOG_BITS as usize; + let trace_start = (T::LOG_BITS - T::LOG_BYTES) as usize; + let rot: i64 = (T::bit_index(byte << 3) << log_gap) as i64; + + // Move a to self and align byte + 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, trace_start, self, keys, scratch_1); + + // Subtracts to self to zero it + module.glwe_sub_inplace(&mut self.bits, &tmp_trace); + + // Move a to self and align byte + module.glwe_rotate_inplace(rot, &mut self.bits, scratch); + } + pub fn sext(&mut self, module: &M, byte: usize, keys: &H, scratch: &mut Scratch) where M:, diff --git a/poulpy-schemes/src/tfhe/bdd_arithmetic/tests/test_suite/fheuint.rs b/poulpy-schemes/src/tfhe/bdd_arithmetic/tests/test_suite/fheuint.rs index 8938513..78e1de4 100644 --- a/poulpy-schemes/src/tfhe/bdd_arithmetic/tests/test_suite/fheuint.rs +++ b/poulpy-schemes/src/tfhe/bdd_arithmetic/tests/test_suite/fheuint.rs @@ -58,7 +58,7 @@ where } pub fn sext(x: u32, byte: usize) -> u32 { - x | ((x >> (byte << 3)) & 1) * (0xFFFF_FFFF & (0xFFFF_FFFF << (byte << 3))) + x | (((x >> (byte << 3)) & 1) * (0xFFFF_FFFF << (byte << 3))) } pub fn test_fhe_uint_splice_u8(test_context: &TestContext) diff --git a/poulpy-schemes/src/tfhe/bdd_arithmetic/tests/test_suite/glwe_blind_selection.rs b/poulpy-schemes/src/tfhe/bdd_arithmetic/tests/test_suite/glwe_blind_selection.rs index 7bbe62a..d453789 100644 --- a/poulpy-schemes/src/tfhe/bdd_arithmetic/tests/test_suite/glwe_blind_selection.rs +++ b/poulpy-schemes/src/tfhe/bdd_arithmetic/tests/test_suite/glwe_blind_selection.rs @@ -129,7 +129,7 @@ where res.decrypt(module, &mut pt, sk_glwe_prep, scratch.borrow()); let idx = ((k >> bit_start) & mask) as usize; - if idx.is_multiple_of(3) { + if !idx.is_multiple_of(3) { assert_eq!(0, pt.decode_coeff_i64(TorusPrecision(base2k.as_u32()), 0)); } else { assert_eq!(