Updated packing to clean values correctly

This commit is contained in:
Pro7ech
2025-10-30 15:58:30 +01:00
parent a6970669dd
commit 3cd79e5a90
19 changed files with 127 additions and 93 deletions

View File

@@ -1,17 +1,16 @@
use std::marker::PhantomData;
use poulpy_core::{GLWECopy, GLWEPacking, ScratchTakeCore, layouts::GGSWPrepared};
use poulpy_core::{
GLWECopy, GLWEPacking, ScratchTakeCore,
layouts::{GGLWEInfos, GGLWEPreparedToRef, GGSWPrepared, GLWEAutomorphismKeyHelper, GetGaloisElement},
};
use poulpy_hal::{
api::ModuleLogN,
layouts::{Backend, DataMut, DataRef, Module, Scratch},
};
use crate::tfhe::{
bdd_arithmetic::{
BDDKeyPrepared, BitSize, ExecuteBDDCircuit, FheUint, FheUintPrepared, GetBitCircuitInfo, GetGGSWBit, UnsignedInteger,
circuits,
},
blind_rotation::BlindRotationAlgo,
use crate::tfhe::bdd_arithmetic::{
BitSize, ExecuteBDDCircuit, FheUint, FheUintPrepared, GetBitCircuitInfo, GetGGSWBit, UnsignedInteger, circuits,
};
impl<T: UnsignedInteger, BE: Backend> ExecuteBDDCircuit2WTo1W<T, BE> for Module<BE> where
@@ -24,21 +23,21 @@ where
Self: Sized + ModuleLogN + ExecuteBDDCircuit<T, BE> + GLWEPacking<BE> + GLWECopy,
{
/// Operations Z x Z -> Z
fn execute_bdd_circuit_2w_to_1w<R, C, A, B, DK, BRA>(
fn execute_bdd_circuit_2w_to_1w<R, C, A, B, K, H>(
&self,
out: &mut FheUint<R, T>,
circuit: &C,
a: &FheUintPrepared<A, T, BE>,
b: &FheUintPrepared<B, T, BE>,
key: &BDDKeyPrepared<DK, BRA, BE>,
key: &H,
scratch: &mut Scratch<BE>,
) where
BRA: BlindRotationAlgo,
DK: DataRef,
C: GetBitCircuitInfo<T>,
R: DataMut,
A: DataRef,
B: DataRef,
K: GGLWEPreparedToRef<BE> + GetGaloisElement + GGLWEInfos,
H: GLWEAutomorphismKeyHelper<K, BE>,
Scratch<BE>: ScratchTakeCore<BE>,
{
// Collects inputs into a single array
@@ -103,19 +102,19 @@ macro_rules! define_bdd_2w_to_1w_trait {
($(#[$meta:meta])* $vis:vis $trait_name:ident, $method_name:ident) => {
$(#[$meta])*
$vis trait $trait_name<T: UnsignedInteger, BE: Backend> {
fn $method_name<A, M, K, BRA, B>(
fn $method_name<A, M, K, H, B>(
&mut self,
module: &M,
a: &FheUintPrepared<A, T, BE>,
b: &FheUintPrepared<B, T, BE>,
key: &BDDKeyPrepared<K, BRA, BE>,
key: &H,
scratch: &mut Scratch<BE>,
) where
M: ExecuteBDDCircuit2WTo1W<T, BE>,
A: DataRef,
B: DataRef,
K: DataRef,
BRA: BlindRotationAlgo,
K: GGLWEPreparedToRef<BE> + GetGaloisElement + GGLWEInfos,
H: GLWEAutomorphismKeyHelper<K, BE>,
Scratch<BE>: ScratchTakeCore<BE>;
}
};
@@ -125,19 +124,19 @@ macro_rules! define_bdd_2w_to_1w_trait {
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<D: DataMut, BE: Backend> $trait_name<$ty, BE> for FheUint<D, $ty> {
fn $method_name<A, M, K, BRA, B>(
fn $method_name<A, M, K, H, B>(
&mut self,
module: &M,
a: &FheUintPrepared<A, $ty, BE>,
b: &FheUintPrepared<B, $ty, BE>,
key: &BDDKeyPrepared<K, BRA, BE>,
key: &H,
scratch: &mut Scratch<BE>,
) where
M: ExecuteBDDCircuit2WTo1W<$ty, BE>,
A: DataRef,
B: DataRef,
K: DataRef,
BRA: BlindRotationAlgo,
K: GGLWEPreparedToRef<BE> + GetGaloisElement + GGLWEInfos,
H: GLWEAutomorphismKeyHelper<K, BE>,
Scratch<BE>: ScratchTakeCore<BE>,
{
module.execute_bdd_circuit_2w_to_1w(self, &$output_circuits, a, b, key, scratch)

View File

@@ -12,10 +12,7 @@ use poulpy_hal::{
};
use std::{collections::HashMap, marker::PhantomData};
use crate::tfhe::{
bdd_arithmetic::{BDDKeyPrepared, FromBits, ToBits, UnsignedInteger},
blind_rotation::BlindRotationAlgo,
};
use crate::tfhe::bdd_arithmetic::{FromBits, ToBits, UnsignedInteger};
/// An FHE ciphertext encrypting the bits of an [UnsignedInteger].
pub struct FheUint<D: Data, T: UnsignedInteger> {
@@ -39,6 +36,18 @@ impl<T: UnsignedInteger> FheUint<Vec<u8>, T> {
}
}
impl<'a, T: UnsignedInteger> FheUint<&'a mut [u8], T> {
pub fn from_glwe_to_mut<G>(glwe: &'a mut G) -> Self
where
G: GLWEToMut,
{
FheUint {
bits: glwe.to_mut(),
_phantom: PhantomData,
}
}
}
impl<D: DataRef, T: UnsignedInteger> LWEInfos for FheUint<D, T> {
fn base2k(&self) -> poulpy_core::layouts::Base2K {
self.bits.base2k()
@@ -145,16 +154,12 @@ impl<D: DataRef, T: UnsignedInteger + FromBits> FheUint<D, T> {
impl<D: DataMut, T: UnsignedInteger> FheUint<D, T> {
/// Packs Vec<GLWE(bit[i])> into [FheUint].
pub fn pack<G, D1, M, BRA: BlindRotationAlgo, BE: Backend>(
&mut self,
module: &M,
mut bits: Vec<G>,
key: &BDDKeyPrepared<D1, BRA, BE>,
scratch: &mut Scratch<BE>,
) where
pub fn pack<G, M, K, H, BE: Backend>(&mut self, module: &M, mut bits: Vec<G>, keys: &H, scratch: &mut Scratch<BE>)
where
G: GLWEToMut + GLWEToRef + GLWEInfos,
D1: DataRef,
M: ModuleLogN + GLWEPacking<BE> + GLWECopy,
K: GGLWEPreparedToRef<BE> + GetGaloisElement + GGLWEInfos,
H: GLWEAutomorphismKeyHelper<K, BE>,
Scratch<BE>: ScratchTakeCore<BE>,
{
// Repacks the GLWE ciphertexts bits
@@ -164,10 +169,7 @@ impl<D: DataMut, T: UnsignedInteger> FheUint<D, T> {
cts.insert(T::bit_index(i) << log_gap, ct);
}
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());
module.glwe_pack(&mut self.bits, cts, log_gap, keys, scratch);
}
#[allow(clippy::too_many_arguments)]

View File

@@ -51,8 +51,10 @@ where
let mut scratch: ScratchOwned<BE> = ScratchOwned::alloc(1 << 22);
let mut res: FheUint<Vec<u8>, u32> = FheUint::<Vec<u8>, u32>::alloc_from_infos(&glwe_infos);
let mut a_enc_prep: FheUintPrepared<Vec<u8>, u32, BE> = FheUintPrepared::<Vec<u8>, u32, BE>::alloc_from_infos(module, &ggsw_infos);
let mut b_enc_prep: FheUintPrepared<Vec<u8>, u32, BE> = FheUintPrepared::<Vec<u8>, u32, BE>::alloc_from_infos(module, &ggsw_infos);
let mut a_enc_prep: FheUintPrepared<Vec<u8>, u32, BE> =
FheUintPrepared::<Vec<u8>, u32, BE>::alloc_from_infos(module, &ggsw_infos);
let mut b_enc_prep: FheUintPrepared<Vec<u8>, u32, BE> =
FheUintPrepared::<Vec<u8>, u32, BE>::alloc_from_infos(module, &ggsw_infos);
let a: u32 = source.next_u32();
let b: u32 = source.next_u32();

View File

@@ -51,8 +51,10 @@ where
let mut scratch: ScratchOwned<BE> = ScratchOwned::alloc(1 << 22);
let mut res: FheUint<Vec<u8>, u32> = FheUint::<Vec<u8>, u32>::alloc_from_infos(&glwe_infos);
let mut a_enc_prep: FheUintPrepared<Vec<u8>, u32, BE> = FheUintPrepared::<Vec<u8>, u32, BE>::alloc_from_infos(module, &ggsw_infos);
let mut b_enc_prep: FheUintPrepared<Vec<u8>, u32, BE> = FheUintPrepared::<Vec<u8>, u32, BE>::alloc_from_infos(module, &ggsw_infos);
let mut a_enc_prep: FheUintPrepared<Vec<u8>, u32, BE> =
FheUintPrepared::<Vec<u8>, u32, BE>::alloc_from_infos(module, &ggsw_infos);
let mut b_enc_prep: FheUintPrepared<Vec<u8>, u32, BE> =
FheUintPrepared::<Vec<u8>, u32, BE>::alloc_from_infos(module, &ggsw_infos);
let a: u32 = source.next_u32();
let b: u32 = source.next_u32();

View File

@@ -78,7 +78,8 @@ where
// println!("k: {k}");
let mut k_enc_prep: FheUintPrepared<Vec<u8>, u32, BE> = FheUintPrepared::<Vec<u8>, u32, BE>::alloc_from_infos(module, &ggsw_k_infos);
let mut k_enc_prep: FheUintPrepared<Vec<u8>, u32, BE> =
FheUintPrepared::<Vec<u8>, u32, BE>::alloc_from_infos(module, &ggsw_k_infos);
k_enc_prep.encrypt_sk(
module,
k,

View File

@@ -71,7 +71,8 @@ where
let k: u32 = source.next_u32();
let mut k_enc_prep: FheUintPrepared<Vec<u8>, u32, BE> = FheUintPrepared::<Vec<u8>, u32, BE>::alloc_from_infos(module, &ggsw_infos);
let mut k_enc_prep: FheUintPrepared<Vec<u8>, u32, BE> =
FheUintPrepared::<Vec<u8>, u32, BE>::alloc_from_infos(module, &ggsw_infos);
k_enc_prep.encrypt_sk(
module,
k,

View File

@@ -51,8 +51,10 @@ where
let mut scratch: ScratchOwned<BE> = ScratchOwned::alloc(1 << 22);
let mut res: FheUint<Vec<u8>, u32> = FheUint::<Vec<u8>, u32>::alloc_from_infos(&glwe_infos);
let mut a_enc_prep: FheUintPrepared<Vec<u8>, u32, BE> = FheUintPrepared::<Vec<u8>, u32, BE>::alloc_from_infos(module, &ggsw_infos);
let mut b_enc_prep: FheUintPrepared<Vec<u8>, u32, BE> = FheUintPrepared::<Vec<u8>, u32, BE>::alloc_from_infos(module, &ggsw_infos);
let mut a_enc_prep: FheUintPrepared<Vec<u8>, u32, BE> =
FheUintPrepared::<Vec<u8>, u32, BE>::alloc_from_infos(module, &ggsw_infos);
let mut b_enc_prep: FheUintPrepared<Vec<u8>, u32, BE> =
FheUintPrepared::<Vec<u8>, u32, BE>::alloc_from_infos(module, &ggsw_infos);
let a: u32 = source.next_u32();
let b: u32 = source.next_u32();

View File

@@ -51,8 +51,10 @@ where
let mut scratch: ScratchOwned<BE> = ScratchOwned::alloc(1 << 22);
let mut res: FheUint<Vec<u8>, u32> = FheUint::<Vec<u8>, u32>::alloc_from_infos(&glwe_infos);
let mut a_enc_prep: FheUintPrepared<Vec<u8>, u32, BE> = FheUintPrepared::<Vec<u8>, u32, BE>::alloc_from_infos(module, &ggsw_infos);
let mut b_enc_prep: FheUintPrepared<Vec<u8>, u32, BE> = FheUintPrepared::<Vec<u8>, u32, BE>::alloc_from_infos(module, &ggsw_infos);
let mut a_enc_prep: FheUintPrepared<Vec<u8>, u32, BE> =
FheUintPrepared::<Vec<u8>, u32, BE>::alloc_from_infos(module, &ggsw_infos);
let mut b_enc_prep: FheUintPrepared<Vec<u8>, u32, BE> =
FheUintPrepared::<Vec<u8>, u32, BE>::alloc_from_infos(module, &ggsw_infos);
let a: u32 = source.next_u32();
let b: u32 = source.next_u32() & 15;

View File

@@ -51,8 +51,10 @@ where
let mut scratch: ScratchOwned<BE> = ScratchOwned::alloc(1 << 22);
let mut res: FheUint<Vec<u8>, u32> = FheUint::<Vec<u8>, u32>::alloc_from_infos(&glwe_infos);
let mut a_enc_prep: FheUintPrepared<Vec<u8>, u32, BE> = FheUintPrepared::<Vec<u8>, u32, BE>::alloc_from_infos(module, &ggsw_infos);
let mut b_enc_prep: FheUintPrepared<Vec<u8>, u32, BE> = FheUintPrepared::<Vec<u8>, u32, BE>::alloc_from_infos(module, &ggsw_infos);
let mut a_enc_prep: FheUintPrepared<Vec<u8>, u32, BE> =
FheUintPrepared::<Vec<u8>, u32, BE>::alloc_from_infos(module, &ggsw_infos);
let mut b_enc_prep: FheUintPrepared<Vec<u8>, u32, BE> =
FheUintPrepared::<Vec<u8>, u32, BE>::alloc_from_infos(module, &ggsw_infos);
let a: u32 = source.next_u32();
let b: u32 = source.next_u32();

View File

@@ -51,8 +51,10 @@ where
let mut scratch: ScratchOwned<BE> = ScratchOwned::alloc(1 << 22);
let mut res: FheUint<Vec<u8>, u32> = FheUint::<Vec<u8>, u32>::alloc_from_infos(&glwe_infos);
let mut a_enc_prep: FheUintPrepared<Vec<u8>, u32, BE> = FheUintPrepared::<Vec<u8>, u32, BE>::alloc_from_infos(module, &ggsw_infos);
let mut b_enc_prep: FheUintPrepared<Vec<u8>, u32, BE> = FheUintPrepared::<Vec<u8>, u32, BE>::alloc_from_infos(module, &ggsw_infos);
let mut a_enc_prep: FheUintPrepared<Vec<u8>, u32, BE> =
FheUintPrepared::<Vec<u8>, u32, BE>::alloc_from_infos(module, &ggsw_infos);
let mut b_enc_prep: FheUintPrepared<Vec<u8>, u32, BE> =
FheUintPrepared::<Vec<u8>, u32, BE>::alloc_from_infos(module, &ggsw_infos);
let a: u32 = source.next_u32();
let b: u32 = source.next_u32();

View File

@@ -51,8 +51,10 @@ where
let mut scratch: ScratchOwned<BE> = ScratchOwned::alloc(1 << 22);
let mut res: FheUint<Vec<u8>, u32> = FheUint::<Vec<u8>, u32>::alloc_from_infos(&glwe_infos);
let mut a_enc_prep: FheUintPrepared<Vec<u8>, u32, BE> = FheUintPrepared::<Vec<u8>, u32, BE>::alloc_from_infos(module, &ggsw_infos);
let mut b_enc_prep: FheUintPrepared<Vec<u8>, u32, BE> = FheUintPrepared::<Vec<u8>, u32, BE>::alloc_from_infos(module, &ggsw_infos);
let mut a_enc_prep: FheUintPrepared<Vec<u8>, u32, BE> =
FheUintPrepared::<Vec<u8>, u32, BE>::alloc_from_infos(module, &ggsw_infos);
let mut b_enc_prep: FheUintPrepared<Vec<u8>, u32, BE> =
FheUintPrepared::<Vec<u8>, u32, BE>::alloc_from_infos(module, &ggsw_infos);
let a: u32 = source.next_u32();
let b: u32 = source.next_u32() & 15;

View File

@@ -51,8 +51,10 @@ where
let mut scratch: ScratchOwned<BE> = ScratchOwned::alloc(1 << 22);
let mut res: FheUint<Vec<u8>, u32> = FheUint::<Vec<u8>, u32>::alloc_from_infos(&glwe_infos);
let mut a_enc_prep: FheUintPrepared<Vec<u8>, u32, BE> = FheUintPrepared::<Vec<u8>, u32, BE>::alloc_from_infos(module, &ggsw_infos);
let mut b_enc_prep: FheUintPrepared<Vec<u8>, u32, BE> = FheUintPrepared::<Vec<u8>, u32, BE>::alloc_from_infos(module, &ggsw_infos);
let mut a_enc_prep: FheUintPrepared<Vec<u8>, u32, BE> =
FheUintPrepared::<Vec<u8>, u32, BE>::alloc_from_infos(module, &ggsw_infos);
let mut b_enc_prep: FheUintPrepared<Vec<u8>, u32, BE> =
FheUintPrepared::<Vec<u8>, u32, BE>::alloc_from_infos(module, &ggsw_infos);
let a: u32 = source.next_u32();
let b: u32 = source.next_u32() & 15;

View File

@@ -51,8 +51,10 @@ where
let mut scratch: ScratchOwned<BE> = ScratchOwned::alloc(1 << 22);
let mut res: FheUint<Vec<u8>, u32> = FheUint::<Vec<u8>, u32>::alloc_from_infos(&glwe_infos);
let mut a_enc_prep: FheUintPrepared<Vec<u8>, u32, BE> = FheUintPrepared::<Vec<u8>, u32, BE>::alloc_from_infos(module, &ggsw_infos);
let mut b_enc_prep: FheUintPrepared<Vec<u8>, u32, BE> = FheUintPrepared::<Vec<u8>, u32, BE>::alloc_from_infos(module, &ggsw_infos);
let mut a_enc_prep: FheUintPrepared<Vec<u8>, u32, BE> =
FheUintPrepared::<Vec<u8>, u32, BE>::alloc_from_infos(module, &ggsw_infos);
let mut b_enc_prep: FheUintPrepared<Vec<u8>, u32, BE> =
FheUintPrepared::<Vec<u8>, u32, BE>::alloc_from_infos(module, &ggsw_infos);
let a: u32 = source.next_u32();
let b: u32 = source.next_u32();

View File

@@ -51,8 +51,10 @@ where
let mut scratch: ScratchOwned<BE> = ScratchOwned::alloc(1 << 22);
let mut res: FheUint<Vec<u8>, u32> = FheUint::<Vec<u8>, u32>::alloc_from_infos(&glwe_infos);
let mut a_enc_prep: FheUintPrepared<Vec<u8>, u32, BE> = FheUintPrepared::<Vec<u8>, u32, BE>::alloc_from_infos(module, &ggsw_infos);
let mut b_enc_prep: FheUintPrepared<Vec<u8>, u32, BE> = FheUintPrepared::<Vec<u8>, u32, BE>::alloc_from_infos(module, &ggsw_infos);
let mut a_enc_prep: FheUintPrepared<Vec<u8>, u32, BE> =
FheUintPrepared::<Vec<u8>, u32, BE>::alloc_from_infos(module, &ggsw_infos);
let mut b_enc_prep: FheUintPrepared<Vec<u8>, u32, BE> =
FheUintPrepared::<Vec<u8>, u32, BE>::alloc_from_infos(module, &ggsw_infos);
let a: u32 = source.next_u32();
let b: u32 = source.next_u32();

View File

@@ -378,16 +378,6 @@ fn post_process<R, A, M, H, K, BE: Backend>(
cts.insert(i * (1 << log_gap_out), ct);
}
module.glwe_pack(&mut cts, log_gap_out, auto_keys, scratch);
let packed: &mut GLWE<Vec<u8>> = cts.remove(&0).unwrap();
res.trace(
module,
log_n - log_gap_out,
log_n,
packed,
auto_keys,
scratch,
);
module.glwe_pack(res, cts, log_gap_out, auto_keys, scratch);
}
}