Skip to content

Commit

Permalink
feat(hlapi): add tag system
Browse files Browse the repository at this point in the history
Tag

The `Tag` allows to store bytes alongside of entities (keys, and ciphertext)
the main purpose of this system is to `tag` / identify ciphertext with their keys.

* When encrypted, a ciphertext gets the tag of the key used to encrypt it.
* Ciphertexts resulting from operations (add, sub, etc.) get the tag from the ServerKey used
* PublicKey gets its tag from the ClientKey that was used to create it
* ServerKey gets its tag from the ClientKey that was used to create it

User can change the tag of any entities at any point.

BREAKING CHANGE: Many of the into_raw_parts and from_raw_parts changed
to accommodate the addition of the `tag``
  • Loading branch information
tmontaigu committed Sep 4, 2024
1 parent 15e3474 commit 44ec753
Show file tree
Hide file tree
Showing 42 changed files with 2,242 additions and 606 deletions.
4 changes: 2 additions & 2 deletions tfhe/src/high_level_api/array.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ pub fn fhe_uint_array_eq<Id: FheUintId>(lhs: &[FheUint<Id>], rhs: &[FheUint<Id>]
let result = cpu_keys
.pbs_key()
.all_eq_slices_parallelized(&tmp_lhs, &tmp_rhs);
FheBool::new(result)
FheBool::new(result, cpu_keys.tag.clone())
})
}

Expand All @@ -37,6 +37,6 @@ pub fn fhe_uint_array_contains_sub_slice<Id: FheUintId>(
let result = cpu_keys
.pbs_key()
.contains_sub_slice_parallelized(&tmp_lhs, &tmp_pattern);
FheBool::new(result)
FheBool::new(result, cpu_keys.tag.clone())
})
}
72 changes: 63 additions & 9 deletions tfhe/src/high_level_api/backward_compatibility/booleans.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
#![allow(deprecated)]

use serde::{Deserialize, Serialize};
use tfhe_versionable::{Versionize, VersionsDispatch};
use tfhe_versionable::{Upgrade, Version, Versionize, VersionsDispatch};

use crate::high_level_api::booleans::InnerBooleanVersionOwned;
use crate::high_level_api::booleans::{
InnerBoolean, InnerBooleanVersionOwned, InnerCompressedFheBool,
};
use crate::integer::ciphertext::{CompactCiphertextList, DataKind};
use crate::{CompactCiphertextList as HlCompactCiphertextList, CompressedFheBool, Error, FheBool};
use crate::{
CompactCiphertextList as HlCompactCiphertextList, CompressedFheBool, Error, FheBool, Tag,
};
use std::convert::Infallible;

// Manual impl
#[derive(Serialize, Deserialize)]
Expand All @@ -14,19 +19,60 @@ pub(crate) enum InnerBooleanVersionedOwned {
V0(InnerBooleanVersionOwned),
}

#[derive(Version)]
pub struct FheBoolV0 {
pub(in crate::high_level_api) ciphertext: InnerBoolean,
}

impl Upgrade<FheBool> for FheBoolV0 {
type Error = Infallible;

fn upgrade(self) -> Result<FheBool, Self::Error> {
Ok(FheBool {
ciphertext: self.ciphertext,
tag: Tag::default(),
})
}
}

#[derive(VersionsDispatch)]
pub enum FheBoolVersions {
V0(FheBool),
V0(FheBoolV0),
V1(FheBool),
}

#[derive(VersionsDispatch)]
pub enum CompactFheBoolVersions {
V0(CompactFheBool),
}

#[derive(VersionsDispatch)]
pub enum InnerCompressedFheBoolVersions {
V0(InnerCompressedFheBool),
}

// Before V1 where we added the Tag, the CompressedFheBool
// was simply the inner enum
type CompressedFheBoolV0 = InnerCompressedFheBool;

impl Upgrade<CompressedFheBool> for CompressedFheBoolV0 {
type Error = Infallible;

fn upgrade(self) -> Result<CompressedFheBool, Self::Error> {
Ok(CompressedFheBool {
inner: match self {
Self::Seeded(s) => Self::Seeded(s),
Self::ModulusSwitched(m) => Self::ModulusSwitched(m),
},
tag: Tag::default(),
})
}
}

#[derive(VersionsDispatch)]
pub enum CompressedFheBoolVersions {
V0(CompressedFheBool),
V0(CompressedFheBoolV0),
V1(CompressedFheBool),
}

#[derive(VersionsDispatch)]
Expand Down Expand Up @@ -56,14 +102,18 @@ impl CompactFheBool {
.iter_mut()
.for_each(|info| *info = DataKind::Boolean);

let hl_list = HlCompactCiphertextList(self.list);
let hl_list = HlCompactCiphertextList {
inner: self.list,
tag: Tag::default(),
};
let list = hl_list.expand()?;

let block = list
.inner
.get::<crate::integer::BooleanBlock>(0)
.ok_or_else(|| Error::new("Failed to expand compact list".to_string()))??;

let mut ciphertext = FheBool::new(block);
let mut ciphertext = FheBool::new(block, Tag::default());
ciphertext.ciphertext.move_to_device_of_server_key_if_set();
Ok(ciphertext)
}
Expand All @@ -86,17 +136,21 @@ impl CompactFheBoolList {
.iter_mut()
.for_each(|info| *info = DataKind::Boolean);

let hl_list = HlCompactCiphertextList(self.list);
let hl_list = HlCompactCiphertextList {
inner: self.list,
tag: Tag::default(),
};
let list = hl_list.expand()?;
let len = list.len();

(0..len)
.map(|idx| {
let block = list
.inner
.get::<crate::integer::BooleanBlock>(idx)
.ok_or_else(|| Error::new("Failed to expand compact list".to_string()))??;

let mut ciphertext = FheBool::new(block);
let mut ciphertext = FheBool::new(block, Tag::default());
ciphertext.ciphertext.move_to_device_of_server_key_if_set();
Ok(ciphertext)
})
Expand Down
22 changes: 19 additions & 3 deletions tfhe/src/high_level_api/backward_compatibility/compact_list.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,24 @@
use tfhe_versionable::VersionsDispatch;
use std::convert::Infallible;
use tfhe_versionable::{Upgrade, Version, VersionsDispatch};

use crate::CompactCiphertextList;
use crate::{CompactCiphertextList, Tag};

#[derive(Version)]
pub struct CompactCiphertextListV0(crate::integer::ciphertext::CompactCiphertextList);

impl Upgrade<CompactCiphertextList> for CompactCiphertextListV0 {
type Error = Infallible;

fn upgrade(self) -> Result<CompactCiphertextList, Self::Error> {
Ok(CompactCiphertextList {
inner: self.0,
tag: Tag::default(),
})
}
}

#[derive(VersionsDispatch)]
pub enum CompactCiphertextListVersions {
V0(CompactCiphertextList),
V0(CompactCiphertextListV0),
V1(CompactCiphertextList),
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,24 @@
use tfhe_versionable::VersionsDispatch;
use std::convert::Infallible;
use tfhe_versionable::{Upgrade, Version, VersionsDispatch};

use crate::CompressedCiphertextList;
use crate::{CompressedCiphertextList, Tag};

#[derive(Version)]
pub struct CompressedCiphertextListV0(crate::integer::ciphertext::CompressedCiphertextList);

impl Upgrade<CompressedCiphertextList> for CompressedCiphertextListV0 {
type Error = Infallible;

fn upgrade(self) -> Result<CompressedCiphertextList, Self::Error> {
Ok(CompressedCiphertextList {
inner: self.0,
tag: Tag::default(),
})
}
}

#[derive(VersionsDispatch)]
pub enum CompressedCiphertextListVersions {
V0(CompressedCiphertextList),
V0(CompressedCiphertextListV0),
V1(CompressedCiphertextList),
}
Loading

0 comments on commit 44ec753

Please sign in to comment.