tfhe/high_level_api/booleans/
compressed.rsuse crate::backward_compatibility::booleans::{
CompressedFheBoolVersions, InnerCompressedFheBoolVersions,
};
use crate::conformance::ParameterSetConformant;
use crate::high_level_api::global_state::with_cpu_internal_keys;
use crate::high_level_api::traits::Tagged;
use crate::integer::BooleanBlock;
use crate::named::Named;
use crate::prelude::FheTryEncrypt;
use crate::shortint::ciphertext::{CompressedModulusSwitchedCiphertext, Degree};
use crate::shortint::CompressedCiphertext;
use crate::{ClientKey, FheBool, FheBoolConformanceParams, Tag};
use serde::{Deserialize, Serialize};
use tfhe_versionable::Versionize;
#[derive(Clone, Serialize, Deserialize, Versionize)]
#[versionize(InnerCompressedFheBoolVersions)]
pub enum InnerCompressedFheBool {
Seeded(CompressedCiphertext),
ModulusSwitched(CompressedModulusSwitchedCiphertext),
}
#[derive(Clone, Serialize, Deserialize, Versionize)]
#[versionize(CompressedFheBoolVersions)]
pub struct CompressedFheBool {
pub(in crate::high_level_api) inner: InnerCompressedFheBool,
pub(crate) tag: Tag,
}
impl Tagged for CompressedFheBool {
fn tag(&self) -> &Tag {
&self.tag
}
fn tag_mut(&mut self) -> &mut Tag {
&mut self.tag
}
}
impl CompressedFheBool {
pub(in crate::high_level_api) fn new(ciphertext: CompressedCiphertext, tag: Tag) -> Self {
Self {
inner: InnerCompressedFheBool::Seeded(ciphertext),
tag,
}
}
pub fn decompress(&self) -> FheBool {
let ciphertext = BooleanBlock::new_unchecked(match &self.inner {
InnerCompressedFheBool::Seeded(seeded) => seeded.decompress(),
InnerCompressedFheBool::ModulusSwitched(modulus_switched) => {
with_cpu_internal_keys(|sk| sk.pbs_key().key.decompress(modulus_switched))
}
});
let mut ciphertext = FheBool::new(ciphertext, self.tag.clone());
ciphertext.ciphertext.move_to_device_of_server_key_if_set();
ciphertext
}
}
impl FheTryEncrypt<bool, ClientKey> for CompressedFheBool {
type Error = crate::Error;
fn try_encrypt(value: bool, key: &ClientKey) -> Result<Self, Self::Error> {
let mut ciphertext = key.key.key.key.encrypt_compressed(u64::from(value));
ciphertext.degree = Degree::new(1);
Ok(Self::new(ciphertext, key.tag.clone()))
}
}
impl ParameterSetConformant for CompressedFheBool {
type ParameterSet = FheBoolConformanceParams;
fn is_conformant(&self, params: &FheBoolConformanceParams) -> bool {
match &self.inner {
InnerCompressedFheBool::Seeded(seeded) => seeded.is_conformant(¶ms.0),
InnerCompressedFheBool::ModulusSwitched(ct) => ct.is_conformant(¶ms.0),
}
}
}
impl Named for CompressedFheBool {
const NAME: &'static str = "high_level_api::CompressedFheBool";
}
impl FheBool {
pub fn compress(&self) -> CompressedFheBool {
with_cpu_internal_keys(|sk| {
let inner = InnerCompressedFheBool::ModulusSwitched(
sk.pbs_key()
.key
.switch_modulus_and_compress(&self.ciphertext.on_cpu().0),
);
CompressedFheBool {
inner,
tag: sk.tag.clone(),
}
})
}
}