mirror of
https://github.com/zama-ai/tfhe-rs.git
synced 2026-01-09 22:57:59 -05:00
feat: make XofKeySet serializable
This commit is contained in:
committed by
tmontaigu
parent
e4b230aaf1
commit
736185bb31
@@ -19,9 +19,11 @@ pub use tfhe_csprng::seeders::{Seed, Seeder, XofSeed};
|
||||
/// Module to proxy the serialization for `tfhe-csprng::Seed` to avoid adding serde as a
|
||||
/// dependency to `tfhe-csprng`
|
||||
pub mod serialization_proxy {
|
||||
// use crate::core_crypto::backward_compatibility::commons::math::random::{
|
||||
// XofSeedSerdeDefVersioned, XofSeedSerdeDefVersionedOwned,
|
||||
// };
|
||||
pub(crate) use serde::{Deserialize, Serialize};
|
||||
pub(crate) use tfhe_csprng::seeders::Seed;
|
||||
|
||||
pub(crate) use tfhe_csprng::seeders::{Seed, XofSeed};
|
||||
// See https://serde.rs/remote-derive.html
|
||||
// Serde calls this the definition of the remote type. It is just a copy of the remote data
|
||||
// structure. The `remote` attribute gives the path to the actual type we intend to derive code
|
||||
@@ -29,6 +31,16 @@ pub mod serialization_proxy {
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[serde(remote = "Seed")]
|
||||
pub(crate) struct SeedSerdeDef(pub u128);
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[serde(remote = "XofSeed")]
|
||||
pub(crate) struct XofSeedSerdeDef(#[serde(getter = "XofSeed::bytes")] Vec<u8>);
|
||||
|
||||
impl From<XofSeedSerdeDef> for XofSeed {
|
||||
fn from(value: XofSeedSerdeDef) -> Self {
|
||||
Self::from_bytes(value.0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) use serialization_proxy::*;
|
||||
|
||||
@@ -12,3 +12,4 @@ pub mod keys;
|
||||
#[cfg(feature = "strings")]
|
||||
pub mod strings;
|
||||
pub mod tag;
|
||||
pub mod xof_key_set;
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
use tfhe_versionable::VersionsDispatch;
|
||||
|
||||
use crate::high_level_api::xof_key_set::{CompressedXofKeySet, XofKeySet};
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub enum CompressedXofKeySetVersioned<'vers> {
|
||||
V0(&'vers CompressedXofKeySet),
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub enum CompressedXofKeySetVersionedOwned {
|
||||
V0(CompressedXofKeySet),
|
||||
}
|
||||
|
||||
#[derive(VersionsDispatch)]
|
||||
pub enum XofKeySetVersions {
|
||||
V0(XofKeySet),
|
||||
}
|
||||
@@ -17,6 +17,7 @@ use crate::integer::compression_keys::CompressionPrivateKeys;
|
||||
use crate::integer::noise_squashing::CompressedNoiseSquashingKey;
|
||||
#[cfg(test)]
|
||||
use crate::integer::noise_squashing::NoiseSquashingPrivateKey;
|
||||
use crate::named::Named;
|
||||
#[cfg(test)]
|
||||
use crate::shortint::atomic_pattern::compressed::{
|
||||
CompressedAtomicPatternServerKey, CompressedStandardAtomicPatternServerKey,
|
||||
@@ -49,7 +50,12 @@ use serde::{Deserialize, Serialize};
|
||||
use tfhe_csprng::seeders::Seed;
|
||||
use tfhe_csprng::seeders::XofSeed;
|
||||
use tfhe_fft::c64;
|
||||
use tfhe_versionable::{Unversionize, Versionize, VersionizeOwned};
|
||||
|
||||
use crate::core_crypto::commons::math::random::XofSeedSerdeDef;
|
||||
use crate::high_level_api::backward_compatibility::xof_key_set::{
|
||||
CompressedXofKeySetVersioned, CompressedXofKeySetVersionedOwned, XofKeySetVersions,
|
||||
};
|
||||
use crate::integer::compression_keys::CompressionKey;
|
||||
use crate::integer::key_switching_key::{
|
||||
CompressedKeySwitchingKeyMaterial, KeySwitchingKeyMaterial,
|
||||
@@ -74,12 +80,44 @@ use crate::shortint::noise_squashing::{
|
||||
/// regarding the random generator used, and the order of key generation
|
||||
///
|
||||
/// [NIST document]: https://eprint.iacr.org/2025/699
|
||||
#[derive(Clone, Serialize, Deserialize)]
|
||||
pub struct CompressedXofKeySet {
|
||||
#[serde(with = "XofSeedSerdeDef")]
|
||||
seed: XofSeed,
|
||||
compressed_public_key: CompressedCompactPublicKey,
|
||||
compressed_server_key: CompressedServerKey,
|
||||
}
|
||||
|
||||
impl Versionize for CompressedXofKeySet {
|
||||
type Versioned<'vers> = CompressedXofKeySetVersioned<'vers>;
|
||||
|
||||
fn versionize(&self) -> Self::Versioned<'_> {
|
||||
CompressedXofKeySetVersioned::V0(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl VersionizeOwned for CompressedXofKeySet {
|
||||
type VersionedOwned = CompressedXofKeySetVersionedOwned;
|
||||
|
||||
fn versionize_owned(self) -> Self::VersionedOwned {
|
||||
CompressedXofKeySetVersionedOwned::V0(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl Unversionize for CompressedXofKeySet {
|
||||
fn unversionize(
|
||||
versioned: Self::VersionedOwned,
|
||||
) -> Result<Self, tfhe_versionable::UnversionizeError> {
|
||||
match versioned {
|
||||
CompressedXofKeySetVersionedOwned::V0(v0) => Ok(v0),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Named for CompressedXofKeySet {
|
||||
const NAME: &'static str = "CompressedXofKeySet";
|
||||
}
|
||||
|
||||
impl CompressedXofKeySet {
|
||||
#[cfg(test)]
|
||||
fn with_seed(pub_seed: XofSeed, priv_seed: XofSeed, ck: &ClientKey) -> crate::Result<Self> {
|
||||
@@ -550,12 +588,17 @@ impl CompressedXofKeySet {
|
||||
/// To create such key set, first create a [CompressedXofKeySet] then decompress it
|
||||
///
|
||||
/// [NIST document]: https://eprint.iacr.org/2025/699
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[derive(Clone, Serialize, Deserialize, Versionize)]
|
||||
#[versionize(XofKeySetVersions)]
|
||||
pub struct XofKeySet {
|
||||
public_key: CompactPublicKey,
|
||||
server_key: ServerKey,
|
||||
}
|
||||
|
||||
impl Named for XofKeySet {
|
||||
const NAME: &'static str = "XofKeySet";
|
||||
}
|
||||
|
||||
impl XofKeySet {
|
||||
pub fn into_raw_parts(self) -> (CompactPublicKey, ServerKey) {
|
||||
(self.public_key, self.server_key)
|
||||
@@ -1190,7 +1233,7 @@ where
|
||||
mod test {
|
||||
use crate::core_crypto::prelude::new_seeder;
|
||||
use crate::prelude::*;
|
||||
use crate::xof_key_set::CompressedXofKeySet;
|
||||
use crate::xof_key_set::{CompressedXofKeySet, XofKeySet};
|
||||
use crate::{XofSeed, *};
|
||||
|
||||
#[test]
|
||||
@@ -1227,8 +1270,26 @@ mod test {
|
||||
|
||||
let compressed_key_set = CompressedXofKeySet::with_seed(pub_seed, priv_seed, &cks).unwrap();
|
||||
|
||||
let compressed_size_limit = 1 << 30;
|
||||
let mut data = vec![];
|
||||
crate::safe_serialization::safe_serialize(
|
||||
&compressed_key_set,
|
||||
&mut data,
|
||||
compressed_size_limit,
|
||||
)
|
||||
.unwrap();
|
||||
let compressed_key_set: CompressedXofKeySet =
|
||||
crate::safe_serialization::safe_deserialize(data.as_slice(), compressed_size_limit)
|
||||
.unwrap();
|
||||
|
||||
let key_set = compressed_key_set.decompress();
|
||||
|
||||
let size_limit = 1 << 32;
|
||||
let mut data = vec![];
|
||||
crate::safe_serialization::safe_serialize(&key_set, &mut data, size_limit).unwrap();
|
||||
let key_set: XofKeySet =
|
||||
crate::safe_serialization::safe_deserialize(data.as_slice(), size_limit).unwrap();
|
||||
|
||||
let (pk, sk) = key_set.into_raw_parts();
|
||||
|
||||
assert!(sk.is_conformant(&config.into()));
|
||||
|
||||
@@ -120,11 +120,6 @@ impl CompressedStandardAtomicPatternServerKey {
|
||||
&self.bootstrapping_key
|
||||
}
|
||||
|
||||
#[cfg(all(feature = "integer", test))]
|
||||
pub(crate) fn bootstrapping_key_mut(&mut self) -> &mut ShortintCompressedBootstrappingKey<u64> {
|
||||
&mut self.bootstrapping_key
|
||||
}
|
||||
|
||||
pub fn pbs_order(&self) -> PBSOrder {
|
||||
self.pbs_order
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user