use super::{CompressedServerKey, ServerKey};
use crate::high_level_api::backward_compatibility::keys::ClientKeyVersions;
use crate::high_level_api::config::Config;
use crate::high_level_api::keys::{CompactPrivateKey, IntegerClientKey};
use crate::high_level_api::SquashedNoiseCiphertextState;
use crate::integer::ciphertext::NoiseSquashingCompressionPrivateKey;
use crate::integer::compression_keys::CompressionPrivateKeys;
use crate::integer::noise_squashing::{NoiseSquashingPrivateKey, NoiseSquashingPrivateKeyView};
use crate::integer::oprf::OprfPrivateKey;
use crate::named::Named;
use crate::prelude::Tagged;
use crate::shortint::parameters::ReRandomizationParameters;
use crate::shortint::MessageModulus;
use crate::Tag;
use tfhe_csprng::seeders::Seed;
use tfhe_versionable::Versionize;
#[derive(Clone, Debug, serde::Serialize, serde::Deserialize, Versionize)]
#[versionize(ClientKeyVersions)]
pub struct ClientKey {
pub(crate) key: IntegerClientKey,
pub(crate) tag: Tag,
}
impl ClientKey {
pub fn generate<C: Into<Config>>(config: C) -> Self {
let config: Config = config.into();
Self {
key: IntegerClientKey::from(config.inner),
tag: Tag::default(),
}
}
pub fn generate_with_seed<C: Into<Config>>(config: C, seed: Seed) -> Self {
let config: Config = config.into();
Self {
key: IntegerClientKey::with_seed(config.inner, seed),
tag: Tag::default(),
}
}
pub fn computation_parameters(&self) -> crate::shortint::AtomicPatternParameters {
self.key.block_parameters()
}
#[allow(clippy::type_complexity)]
pub fn into_raw_parts(
self,
) -> (
crate::integer::ClientKey,
Option<CompactPrivateKey>,
Option<CompressionPrivateKeys>,
Option<NoiseSquashingPrivateKey>,
Option<NoiseSquashingCompressionPrivateKey>,
Option<ReRandomizationParameters>,
Option<OprfPrivateKey>,
Tag,
) {
let (cks, cpk, cppk, nsk, nscpk, cpkrndp, oprf) = self.key.into_raw_parts();
(cks, cpk, cppk, nsk, nscpk, cpkrndp, oprf, self.tag)
}
#[allow(clippy::too_many_arguments)]
pub fn from_raw_parts(
key: crate::integer::ClientKey,
dedicated_compact_private_key: Option<(
crate::integer::CompactPrivateKey<Vec<u64>>,
crate::shortint::parameters::key_switching::ShortintKeySwitchingParameters,
)>,
compression_key: Option<CompressionPrivateKeys>,
noise_squashing_key: Option<NoiseSquashingPrivateKey>,
noise_squashing_compression_key: Option<NoiseSquashingCompressionPrivateKey>,
cpk_re_randomization_params: Option<ReRandomizationParameters>,
oprf_private_key: Option<OprfPrivateKey>,
tag: Tag,
) -> Self {
Self {
key: IntegerClientKey::from_raw_parts(
key,
dedicated_compact_private_key,
compression_key,
noise_squashing_key,
noise_squashing_compression_key,
cpk_re_randomization_params,
oprf_private_key,
),
tag,
}
}
pub fn generate_server_key(&self) -> ServerKey {
ServerKey::new(self)
}
pub fn generate_compressed_server_key(&self) -> CompressedServerKey {
CompressedServerKey::new(self)
}
pub(crate) fn message_modulus(&self) -> MessageModulus {
self.key.block_parameters().message_modulus()
}
pub(crate) fn private_noise_squashing_decryption_key(
&self,
state: SquashedNoiseCiphertextState,
) -> NoiseSquashingPrivateKeyView<'_> {
match state {
SquashedNoiseCiphertextState::Normal => self
.key
.noise_squashing_private_key
.as_ref()
.map(|key| key.as_view())
.expect(
"No noise squashing private key in your ClientKey, cannot decrypt. \
Did you call `enable_noise_squashing` when creating your Config?",
),
SquashedNoiseCiphertextState::PostDecompression => self
.key
.noise_squashing_compression_private_key
.as_ref()
.map(|key| key.private_key_view())
.expect(
"No noise squashing private key in your ClientKey, cannot decrypt. \
Did you call `enable_noise_squashing_compression` when creating your Config?",
),
}
}
}
impl Tagged for ClientKey {
fn tag(&self) -> &Tag {
&self.tag
}
fn tag_mut(&mut self) -> &mut Tag {
&mut self.tag
}
}
impl AsRef<crate::integer::ClientKey> for ClientKey {
fn as_ref(&self) -> &crate::integer::ClientKey {
&self.key.key
}
}
impl Named for ClientKey {
const NAME: &'static str = "high_level_api::ClientKey";
}