use crate::backward_compatibility::cpk_re_randomization::ReRandomizationMetadataVersions;
use crate::core_crypto::commons::math::random::XofSeed;
use crate::high_level_api::keys::CompactPublicKey;
pub use crate::high_level_api::keys::ReRandomizationSupport;
use crate::high_level_api::tag::SmallVec;
use crate::integer::ciphertext::{ReRandomizationSeed, ReRandomizationSeedHasher};
use tfhe_versionable::Versionize;
#[derive(Clone, Copy, Debug, Default)]
pub enum ReRandomizationMode<'key> {
UseLegacyCPKIfNeeded { cpk: &'key CompactPublicKey },
#[default]
UseAvailableMode,
}
impl<'key> From<&'key CompactPublicKey> for ReRandomizationMode<'key> {
fn from(value: &'key CompactPublicKey) -> Self {
Self::UseLegacyCPKIfNeeded { cpk: value }
}
}
pub trait ReRandomize: ReRandContextAdd {
fn re_randomize<'a, RRD: Into<ReRandomizationMode<'a>>>(
&mut self,
re_randomization_mode: RRD,
seed: ReRandomizationSeed,
) -> crate::Result<()>;
}
pub trait ReRandContextAdd {
fn add_to_re_randomization_context(&self, context: &mut ReRandomizationContext);
}
#[allow(dead_code)]
pub trait NistSubmissionReRandomize: ReRandContextAdd {
fn nist_submission_re_randomize(
&mut self,
compact_public_key: &CompactPublicKey,
seed: ReRandomizationSeed,
) -> crate::Result<()>;
}
impl<T: ReRandomize> NistSubmissionReRandomize for T {
fn nist_submission_re_randomize(
&mut self,
compact_public_key: &CompactPublicKey,
seed: ReRandomizationSeed,
) -> crate::Result<()> {
self.re_randomize(compact_public_key, seed)
}
}
pub struct ReRandomizationContext {
pub(in crate::high_level_api) inner: crate::integer::ciphertext::ReRandomizationContext,
}
impl ReRandomizationContext {
pub fn new<'a>(
rerand_seeder_domain_separator: [u8; XofSeed::DOMAIN_SEP_LEN],
fn_description: impl IntoIterator<Item = &'a [u8]>,
public_encryption_domain_separator: [u8; XofSeed::DOMAIN_SEP_LEN],
) -> Self {
Self {
inner: crate::integer::ciphertext::ReRandomizationContext::new(
rerand_seeder_domain_separator,
fn_description,
public_encryption_domain_separator,
),
}
}
pub fn new_with_hasher<'a>(
fn_description: impl IntoIterator<Item = &'a [u8]>,
public_encryption_domain_separator: [u8; XofSeed::DOMAIN_SEP_LEN],
seed_hasher: ReRandomizationSeedHasher,
) -> Self {
Self {
inner: crate::integer::ciphertext::ReRandomizationContext::new_with_hasher(
fn_description,
public_encryption_domain_separator,
seed_hasher,
),
}
}
pub fn add_ciphertext<Data: ReRandContextAdd + ?Sized>(&mut self, data: &Data) {
data.add_to_re_randomization_context(self);
}
pub fn finalize(self) -> ReRandomizationSeedGen {
ReRandomizationSeedGen {
inner: self.inner.finalize(),
}
}
}
pub struct ReRandomizationSeedGen {
inner: crate::integer::ciphertext::ReRandomizationSeedGen,
}
impl ReRandomizationSeedGen {
pub fn next_seed(&mut self) -> crate::Result<ReRandomizationSeed> {
self.inner.next_seed()
}
}
#[derive(
Default, Clone, Debug, serde::Serialize, serde::Deserialize, Versionize, PartialEq, Eq,
)]
#[versionize(ReRandomizationMetadataVersions)]
pub struct ReRandomizationMetadata {
inner: SmallVec,
}
impl ReRandomizationMetadata {
pub fn new(data: &[u8]) -> Self {
let mut inner = SmallVec::default();
inner.set_data(data);
Self { inner }
}
pub fn data(&self) -> &[u8] {
self.inner.data()
}
pub fn set_data(&mut self, data: &[u8]) {
self.inner.set_data(data);
}
pub fn clear(&mut self) {
self.inner.clear();
}
}