mirror of
https://github.com/zama-ai/tfhe-rs.git
synced 2026-01-08 22:28:01 -05:00
chore: use dedicated types for compressed modswitched conformance
This commit is contained in:
committed by
Nicolas Sarlin
parent
dac999b279
commit
f9c2a5d423
@@ -46,7 +46,7 @@ impl_destroy_on_type!(CompressedFheBool);
|
||||
impl_clone_on_type!(CompressedFheBool);
|
||||
impl_serialize_deserialize_on_type!(CompressedFheBool);
|
||||
impl_safe_serialize_on_type!(CompressedFheBool);
|
||||
impl_safe_deserialize_conformant_on_type!(CompressedFheBool, FheBoolConformanceParams);
|
||||
impl_safe_deserialize_conformant_on_type!(CompressedFheBool, CompressedFheBoolConformanceParams);
|
||||
impl_try_encrypt_with_client_key_on_type!(CompressedFheBool{crate::high_level_api::CompressedFheBool}, bool);
|
||||
|
||||
#[no_mangle]
|
||||
|
||||
@@ -359,7 +359,7 @@ macro_rules! create_integer_wrapper_type {
|
||||
|
||||
impl_safe_serialize_on_type!([<Compressed $name>]);
|
||||
|
||||
impl_safe_deserialize_conformant_on_type!([<Compressed $name>], [<$name ConformanceParams>]);
|
||||
impl_safe_deserialize_conformant_on_type!([<Compressed $name>], [<Compressed $name ConformanceParams>]);
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn [<compressed_ $name:snake _decompress>](
|
||||
|
||||
@@ -135,17 +135,45 @@ impl<PackingScalar: UnsignedInteger> CompressedModulusSwitchedLweCiphertext<Pack
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub enum MsDecompressionType {
|
||||
ClassicPbs,
|
||||
MultiBitPbs(LweBskGroupingFactor),
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct CompressedModulusSwitchedLweCiphertextConformanceParams<Scalar>
|
||||
where
|
||||
Scalar: UnsignedInteger,
|
||||
{
|
||||
pub ct_params: LweCiphertextConformanceParams<Scalar>,
|
||||
pub ms_decompression_type: MsDecompressionType,
|
||||
}
|
||||
|
||||
impl<Scalar: UnsignedInteger> ParameterSetConformant
|
||||
for CompressedModulusSwitchedLweCiphertext<Scalar>
|
||||
{
|
||||
type ParameterSet = LweCiphertextConformanceParams<Scalar>;
|
||||
type ParameterSet = CompressedModulusSwitchedLweCiphertextConformanceParams<Scalar>;
|
||||
|
||||
fn is_conformant(&self, lwe_ct_parameters: &LweCiphertextConformanceParams<Scalar>) -> bool {
|
||||
fn is_conformant(
|
||||
&self,
|
||||
compressed_ct_parameters: &CompressedModulusSwitchedLweCiphertextConformanceParams<Scalar>,
|
||||
) -> bool {
|
||||
let Self {
|
||||
packed_integers,
|
||||
lwe_dimension,
|
||||
} = self;
|
||||
|
||||
let CompressedModulusSwitchedLweCiphertextConformanceParams {
|
||||
ct_params,
|
||||
ms_decompression_type,
|
||||
} = compressed_ct_parameters;
|
||||
|
||||
let LweCiphertextConformanceParams {
|
||||
lwe_dim: params_lwe_dim,
|
||||
ct_modulus,
|
||||
} = ct_params;
|
||||
|
||||
let lwe_size = lwe_dimension.to_lwe_size().0;
|
||||
|
||||
let number_bits_to_pack = lwe_size * packed_integers.log_modulus().0;
|
||||
@@ -153,12 +181,9 @@ impl<Scalar: UnsignedInteger> ParameterSetConformant
|
||||
let len = number_bits_to_pack.div_ceil(Scalar::BITS);
|
||||
|
||||
packed_integers.packed_coeffs().len() == len
|
||||
&& *lwe_dimension == lwe_ct_parameters.lwe_dim
|
||||
&& lwe_ct_parameters.ct_modulus.is_power_of_two()
|
||||
&& matches!(
|
||||
lwe_ct_parameters.ms_decompression_method,
|
||||
MsDecompressionType::ClassicPbs
|
||||
)
|
||||
&& lwe_dimension == params_lwe_dim
|
||||
&& ct_modulus.is_power_of_two()
|
||||
&& matches!(ms_decompression_type, MsDecompressionType::ClassicPbs)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -511,9 +511,12 @@ impl MultiBitModulusSwitchedLweCiphertext for FromCompressionMultiBitModulusSwit
|
||||
impl<Scalar: UnsignedInteger + CastInto<usize> + CastFrom<usize>> ParameterSetConformant
|
||||
for CompressedModulusSwitchedMultiBitLweCiphertext<Scalar>
|
||||
{
|
||||
type ParameterSet = LweCiphertextConformanceParams<Scalar>;
|
||||
type ParameterSet = CompressedModulusSwitchedLweCiphertextConformanceParams<Scalar>;
|
||||
|
||||
fn is_conformant(&self, lwe_ct_parameters: &LweCiphertextConformanceParams<Scalar>) -> bool {
|
||||
fn is_conformant(
|
||||
&self,
|
||||
compressed_ct_parameters: &CompressedModulusSwitchedLweCiphertextConformanceParams<Scalar>,
|
||||
) -> bool {
|
||||
let Self {
|
||||
body,
|
||||
packed_mask,
|
||||
@@ -523,22 +526,30 @@ impl<Scalar: UnsignedInteger + CastInto<usize> + CastFrom<usize>> ParameterSetCo
|
||||
grouping_factor,
|
||||
} = self;
|
||||
|
||||
let lwe_dim = lwe_dimension.0;
|
||||
let CompressedModulusSwitchedLweCiphertextConformanceParams {
|
||||
ct_params,
|
||||
ms_decompression_type,
|
||||
} = compressed_ct_parameters;
|
||||
|
||||
let LweCiphertextConformanceParams {
|
||||
lwe_dim: params_lwe_dim,
|
||||
ct_modulus,
|
||||
} = ct_params;
|
||||
|
||||
*body >> packed_mask.log_modulus().0 == Scalar::ZERO
|
||||
&& packed_mask.is_conformant(&lwe_dim)
|
||||
&& packed_mask.is_conformant(&lwe_dimension.0)
|
||||
&& packed_diffs
|
||||
.as_ref()
|
||||
.is_none_or(|packed_diffs| packed_diffs.is_conformant(&lwe_dim))
|
||||
&& *lwe_dimension == lwe_ct_parameters.lwe_dim
|
||||
&& lwe_ct_parameters.ct_modulus.is_power_of_two()
|
||||
&& match lwe_ct_parameters.ms_decompression_method {
|
||||
.is_none_or(|packed_diffs| packed_diffs.is_conformant(&lwe_dimension.0))
|
||||
&& lwe_dimension == params_lwe_dim
|
||||
&& ct_modulus.is_power_of_two()
|
||||
&& match ms_decompression_type {
|
||||
MsDecompressionType::ClassicPbs => false,
|
||||
MsDecompressionType::MultiBitPbs(expected_grouping_factor) => {
|
||||
expected_grouping_factor.0 == grouping_factor.0
|
||||
}
|
||||
}
|
||||
&& *uncompressed_ciphertext_modulus == lwe_ct_parameters.ct_modulus
|
||||
&& uncompressed_ciphertext_modulus == ct_modulus
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -753,13 +753,6 @@ pub type LweCiphertextMutView<'data, Scalar> = LweCiphertext<&'data mut [Scalar]
|
||||
pub struct LweCiphertextConformanceParams<T: UnsignedInteger> {
|
||||
pub lwe_dim: LweDimension,
|
||||
pub ct_modulus: CiphertextModulus<T>,
|
||||
pub ms_decompression_method: MsDecompressionType,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub enum MsDecompressionType {
|
||||
ClassicPbs,
|
||||
MultiBitPbs(LweBskGroupingFactor),
|
||||
}
|
||||
|
||||
impl<C: Container> ParameterSetConformant for LweCiphertext<C>
|
||||
@@ -777,9 +770,14 @@ where
|
||||
ciphertext_modulus,
|
||||
} = self;
|
||||
|
||||
check_encrypted_content_respects_mod(data, lwe_ct_parameters.ct_modulus)
|
||||
&& self.lwe_size() == lwe_ct_parameters.lwe_dim.to_lwe_size()
|
||||
&& *ciphertext_modulus == lwe_ct_parameters.ct_modulus
|
||||
let LweCiphertextConformanceParams {
|
||||
lwe_dim,
|
||||
ct_modulus,
|
||||
} = lwe_ct_parameters;
|
||||
|
||||
check_encrypted_content_respects_mod(data, *ct_modulus)
|
||||
&& self.lwe_size() == lwe_dim.to_lwe_size()
|
||||
&& ciphertext_modulus == ct_modulus
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -9,9 +9,12 @@ 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 crate::shortint::ciphertext::{
|
||||
CompressedModulusSwitchedCiphertext, CompressedModulusSwitchedCiphertextConformanceParams,
|
||||
Degree,
|
||||
};
|
||||
use crate::shortint::{AtomicPatternParameters, CompressedCiphertext};
|
||||
use crate::{ClientKey, FheBool, ServerKey, Tag};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use tfhe_versionable::Versionize;
|
||||
|
||||
@@ -111,12 +114,38 @@ impl FheTryEncrypt<bool, ClientKey> for CompressedFheBool {
|
||||
}
|
||||
}
|
||||
|
||||
impl ParameterSetConformant for CompressedFheBool {
|
||||
type ParameterSet = FheBoolConformanceParams;
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct CompressedFheBoolConformanceParams(
|
||||
pub(crate) CompressedModulusSwitchedCiphertextConformanceParams,
|
||||
);
|
||||
|
||||
fn is_conformant(&self, params: &FheBoolConformanceParams) -> bool {
|
||||
impl<P: Into<AtomicPatternParameters>> From<P> for CompressedFheBoolConformanceParams {
|
||||
fn from(params: P) -> Self {
|
||||
let mut params = params.into().to_compressed_modswitched_conformance_param();
|
||||
params.degree = crate::shortint::ciphertext::Degree::new(1);
|
||||
Self(params)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&ServerKey> for CompressedFheBoolConformanceParams {
|
||||
fn from(sk: &ServerKey) -> Self {
|
||||
let mut parameter_set = Self(
|
||||
sk.key
|
||||
.pbs_key()
|
||||
.key
|
||||
.compressed_modswitched_conformance_params(),
|
||||
);
|
||||
parameter_set.0.degree = crate::shortint::ciphertext::Degree::new(1);
|
||||
parameter_set
|
||||
}
|
||||
}
|
||||
|
||||
impl ParameterSetConformant for CompressedFheBool {
|
||||
type ParameterSet = CompressedFheBoolConformanceParams;
|
||||
|
||||
fn is_conformant(&self, params: &CompressedFheBoolConformanceParams) -> bool {
|
||||
match &self.inner {
|
||||
InnerCompressedFheBool::Seeded(seeded) => seeded.is_conformant(¶ms.0),
|
||||
InnerCompressedFheBool::Seeded(seeded) => seeded.is_conformant(¶ms.0.into()),
|
||||
InnerCompressedFheBool::ModulusSwitched(ct) => ct.is_conformant(¶ms.0),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
pub use base::{FheBool, FheBoolConformanceParams};
|
||||
pub use compressed::CompressedFheBool;
|
||||
pub use compressed::{CompressedFheBool, CompressedFheBoolConformanceParams};
|
||||
pub use squashed_noise::SquashedNoiseFheBool;
|
||||
|
||||
pub(in crate::high_level_api) use compressed::InnerCompressedFheBool;
|
||||
|
||||
@@ -318,6 +318,7 @@ fn compressed_bool_test_case(setup_fn: impl FnOnce() -> (ClientKey, Device)) {
|
||||
|
||||
mod cpu {
|
||||
use super::*;
|
||||
use crate::high_level_api::booleans::compressed::CompressedFheBoolConformanceParams;
|
||||
use crate::safe_serialization::{DeserializationConfig, SerializationConfig};
|
||||
use crate::shortint::parameters::PARAM_MESSAGE_2_CARRY_2_KS_PBS;
|
||||
use crate::FheBoolConformanceParams;
|
||||
@@ -707,12 +708,14 @@ mod cpu {
|
||||
.serialize_into(&a, &mut serialized)
|
||||
.unwrap();
|
||||
|
||||
let params = FheBoolConformanceParams::from(&server_key);
|
||||
let params = CompressedFheBoolConformanceParams::from(&server_key);
|
||||
let deserialized_a = DeserializationConfig::new(1 << 20)
|
||||
.deserialize_from::<CompressedFheBool>(serialized.as_slice(), ¶ms)
|
||||
.unwrap();
|
||||
|
||||
assert!(deserialized_a.is_conformant(&FheBoolConformanceParams::from(block_params)));
|
||||
assert!(
|
||||
deserialized_a.is_conformant(&CompressedFheBoolConformanceParams::from(block_params))
|
||||
);
|
||||
|
||||
let decrypted: bool = deserialized_a.decompress().decrypt(&keys);
|
||||
assert_eq!(decrypted, clear_a);
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
use std::marker::PhantomData;
|
||||
|
||||
use tfhe_versionable::Versionize;
|
||||
|
||||
use crate::backward_compatibility::integers::{
|
||||
@@ -6,20 +8,20 @@ use crate::backward_compatibility::integers::{
|
||||
use crate::conformance::ParameterSetConformant;
|
||||
use crate::core_crypto::prelude::SignedNumeric;
|
||||
use crate::high_level_api::global_state;
|
||||
use crate::high_level_api::integers::signed::base::FheIntConformanceParams;
|
||||
use crate::high_level_api::integers::{FheInt, FheIntId};
|
||||
use crate::high_level_api::keys::InternalServerKey;
|
||||
use crate::high_level_api::re_randomization::ReRandomizationMetadata;
|
||||
use crate::high_level_api::traits::Tagged;
|
||||
use crate::integer::block_decomposition::DecomposableInto;
|
||||
use crate::integer::ciphertext::{
|
||||
CompressedModulusSwitchedRadixCiphertextConformanceParams,
|
||||
CompressedModulusSwitchedSignedRadixCiphertext,
|
||||
CompressedSignedRadixCiphertext as IntegerCompressedSignedRadixCiphertext,
|
||||
};
|
||||
use crate::integer::parameters::RadixCiphertextConformanceParams;
|
||||
use crate::named::Named;
|
||||
use crate::prelude::FheTryEncrypt;
|
||||
use crate::{ClientKey, Tag};
|
||||
use crate::shortint::AtomicPatternParameters;
|
||||
use crate::{ClientKey, ServerKey, Tag};
|
||||
|
||||
/// Compressed [FheInt]
|
||||
///
|
||||
@@ -153,10 +155,51 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<Id: FheIntId> ParameterSetConformant for CompressedFheInt<Id> {
|
||||
type ParameterSet = FheIntConformanceParams<Id>;
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct CompressedFheIntConformanceParams<Id: FheIntId> {
|
||||
pub(crate) params: CompressedSignedRadixCiphertextConformanceParams,
|
||||
pub(crate) id: PhantomData<Id>,
|
||||
}
|
||||
|
||||
fn is_conformant(&self, params: &FheIntConformanceParams<Id>) -> bool {
|
||||
impl<Id: FheIntId, P: Into<AtomicPatternParameters>> From<P>
|
||||
for CompressedFheIntConformanceParams<Id>
|
||||
{
|
||||
fn from(params: P) -> Self {
|
||||
let params = params.into();
|
||||
Self {
|
||||
params: CompressedSignedRadixCiphertextConformanceParams(
|
||||
CompressedModulusSwitchedRadixCiphertextConformanceParams {
|
||||
shortint_params: params.to_compressed_modswitched_conformance_param(),
|
||||
num_blocks_per_integer: Id::num_blocks(params.message_modulus()),
|
||||
},
|
||||
),
|
||||
id: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<Id: FheIntId> From<&ServerKey> for CompressedFheIntConformanceParams<Id> {
|
||||
fn from(sk: &ServerKey) -> Self {
|
||||
Self {
|
||||
params: CompressedSignedRadixCiphertextConformanceParams(
|
||||
CompressedModulusSwitchedRadixCiphertextConformanceParams {
|
||||
shortint_params: sk
|
||||
.key
|
||||
.pbs_key()
|
||||
.key
|
||||
.compressed_modswitched_conformance_params(),
|
||||
num_blocks_per_integer: Id::num_blocks(sk.key.pbs_key().message_modulus()),
|
||||
},
|
||||
),
|
||||
id: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<Id: FheIntId> ParameterSetConformant for CompressedFheInt<Id> {
|
||||
type ParameterSet = CompressedFheIntConformanceParams<Id>;
|
||||
|
||||
fn is_conformant(&self, params: &CompressedFheIntConformanceParams<Id>) -> bool {
|
||||
let Self {
|
||||
ciphertext,
|
||||
id: _,
|
||||
@@ -178,12 +221,17 @@ pub enum CompressedSignedRadixCiphertext {
|
||||
ModulusSwitched(CompressedModulusSwitchedSignedRadixCiphertext),
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct CompressedSignedRadixCiphertextConformanceParams(
|
||||
pub(crate) CompressedModulusSwitchedRadixCiphertextConformanceParams,
|
||||
);
|
||||
|
||||
impl ParameterSetConformant for CompressedSignedRadixCiphertext {
|
||||
type ParameterSet = RadixCiphertextConformanceParams;
|
||||
fn is_conformant(&self, params: &RadixCiphertextConformanceParams) -> bool {
|
||||
type ParameterSet = CompressedSignedRadixCiphertextConformanceParams;
|
||||
fn is_conformant(&self, params: &CompressedSignedRadixCiphertextConformanceParams) -> bool {
|
||||
match self {
|
||||
Self::Seeded(ct) => ct.is_conformant(params),
|
||||
Self::ModulusSwitched(ct) => ct.is_conformant(params),
|
||||
Self::Seeded(ct) => ct.is_conformant(¶ms.0.into()),
|
||||
Self::ModulusSwitched(ct) => ct.is_conformant(¶ms.0),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
use crate::high_level_api::integers::signed::base::{FheInt, FheIntConformanceParams, FheIntId};
|
||||
use crate::high_level_api::integers::signed::compressed::CompressedFheInt;
|
||||
use crate::high_level_api::integers::signed::compressed::{
|
||||
CompressedFheInt, CompressedFheIntConformanceParams,
|
||||
};
|
||||
use crate::high_level_api::{FheId, IntegerId};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use tfhe_versionable::NotVersioned;
|
||||
@@ -52,6 +54,7 @@ macro_rules! static_int_type {
|
||||
|
||||
// Conformance Params
|
||||
pub type [<FheInt $num_bits ConformanceParams>] = FheIntConformanceParams<[<FheInt $num_bits Id>]>;
|
||||
pub type [<CompressedFheInt $num_bits ConformanceParams>] = CompressedFheIntConformanceParams<[<FheInt $num_bits Id>]>;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -13,8 +13,8 @@ use crate::shortint::parameters::test_params::{
|
||||
use crate::shortint::parameters::PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128;
|
||||
use crate::{
|
||||
generate_keys, set_server_key, CompactCiphertextList, CompactPublicKey, CompressedFheInt16,
|
||||
CompressedFheInt32, ConfigBuilder, DeserializationConfig, FheInt256, FheInt32,
|
||||
FheInt32ConformanceParams, FheInt8, SerializationConfig,
|
||||
CompressedFheInt32, CompressedFheInt32ConformanceParams, ConfigBuilder, DeserializationConfig,
|
||||
FheInt256, FheInt32, FheInt32ConformanceParams, FheInt8, SerializationConfig,
|
||||
};
|
||||
use rand::{random, thread_rng, Rng};
|
||||
|
||||
@@ -242,12 +242,12 @@ fn test_safe_deserialize_conformant_compressed_fhe_int32() {
|
||||
.serialize_into(&a, &mut serialized)
|
||||
.unwrap();
|
||||
|
||||
let params = FheInt32ConformanceParams::from(&server_key);
|
||||
let params = CompressedFheInt32ConformanceParams::from(&server_key);
|
||||
let deserialized_a = DeserializationConfig::new(1 << 20)
|
||||
.deserialize_from::<CompressedFheInt32>(serialized.as_slice(), ¶ms)
|
||||
.unwrap();
|
||||
|
||||
let params = FheInt32ConformanceParams::from(block_params);
|
||||
let params = CompressedFheInt32ConformanceParams::from(block_params);
|
||||
assert!(deserialized_a.is_conformant(¶ms));
|
||||
|
||||
let decrypted: i32 = deserialized_a.decompress().decrypt(&client_key);
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
use std::marker::PhantomData;
|
||||
|
||||
use tfhe_versionable::Versionize;
|
||||
|
||||
use crate::backward_compatibility::integers::{
|
||||
@@ -5,9 +7,7 @@ use crate::backward_compatibility::integers::{
|
||||
};
|
||||
use crate::conformance::ParameterSetConformant;
|
||||
use crate::core_crypto::prelude::UnsignedNumeric;
|
||||
use crate::high_level_api::integers::unsigned::base::{
|
||||
FheUint, FheUintConformanceParams, FheUintId,
|
||||
};
|
||||
use crate::high_level_api::integers::unsigned::base::{FheUint, FheUintId};
|
||||
use crate::high_level_api::keys::InternalServerKey;
|
||||
use crate::high_level_api::re_randomization::ReRandomizationMetadata;
|
||||
use crate::high_level_api::traits::{FheTryEncrypt, Tagged};
|
||||
@@ -15,11 +15,12 @@ use crate::high_level_api::{global_state, ClientKey};
|
||||
use crate::integer::block_decomposition::DecomposableInto;
|
||||
use crate::integer::ciphertext::{
|
||||
CompressedModulusSwitchedRadixCiphertext,
|
||||
CompressedModulusSwitchedRadixCiphertextConformanceParams,
|
||||
CompressedRadixCiphertext as IntegerCompressedRadixCiphertext,
|
||||
};
|
||||
use crate::integer::parameters::RadixCiphertextConformanceParams;
|
||||
use crate::named::Named;
|
||||
use crate::Tag;
|
||||
use crate::shortint::AtomicPatternParameters;
|
||||
use crate::{ServerKey, Tag};
|
||||
|
||||
/// Compressed [FheUint]
|
||||
///
|
||||
@@ -151,10 +152,51 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<Id: FheUintId> ParameterSetConformant for CompressedFheUint<Id> {
|
||||
type ParameterSet = FheUintConformanceParams<Id>;
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct CompressedFheUintConformanceParams<Id: FheUintId> {
|
||||
pub(crate) params: CompressedRadixCiphertextConformanceParams,
|
||||
pub(crate) id: PhantomData<Id>,
|
||||
}
|
||||
|
||||
fn is_conformant(&self, params: &FheUintConformanceParams<Id>) -> bool {
|
||||
impl<Id: FheUintId, P: Into<AtomicPatternParameters>> From<P>
|
||||
for CompressedFheUintConformanceParams<Id>
|
||||
{
|
||||
fn from(params: P) -> Self {
|
||||
let params = params.into();
|
||||
Self {
|
||||
params: CompressedRadixCiphertextConformanceParams(
|
||||
CompressedModulusSwitchedRadixCiphertextConformanceParams {
|
||||
shortint_params: params.to_compressed_modswitched_conformance_param(),
|
||||
num_blocks_per_integer: Id::num_blocks(params.message_modulus()),
|
||||
},
|
||||
),
|
||||
id: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<Id: FheUintId> From<&ServerKey> for CompressedFheUintConformanceParams<Id> {
|
||||
fn from(sk: &ServerKey) -> Self {
|
||||
Self {
|
||||
params: CompressedRadixCiphertextConformanceParams(
|
||||
CompressedModulusSwitchedRadixCiphertextConformanceParams {
|
||||
shortint_params: sk
|
||||
.key
|
||||
.pbs_key()
|
||||
.key
|
||||
.compressed_modswitched_conformance_params(),
|
||||
num_blocks_per_integer: Id::num_blocks(sk.key.pbs_key().message_modulus()),
|
||||
},
|
||||
),
|
||||
id: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<Id: FheUintId> ParameterSetConformant for CompressedFheUint<Id> {
|
||||
type ParameterSet = CompressedFheUintConformanceParams<Id>;
|
||||
|
||||
fn is_conformant(&self, params: &CompressedFheUintConformanceParams<Id>) -> bool {
|
||||
let Self {
|
||||
ciphertext,
|
||||
id: _,
|
||||
@@ -176,12 +218,17 @@ pub enum CompressedRadixCiphertext {
|
||||
ModulusSwitched(CompressedModulusSwitchedRadixCiphertext),
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct CompressedRadixCiphertextConformanceParams(
|
||||
pub(crate) CompressedModulusSwitchedRadixCiphertextConformanceParams,
|
||||
);
|
||||
|
||||
impl ParameterSetConformant for CompressedRadixCiphertext {
|
||||
type ParameterSet = RadixCiphertextConformanceParams;
|
||||
fn is_conformant(&self, params: &RadixCiphertextConformanceParams) -> bool {
|
||||
type ParameterSet = CompressedRadixCiphertextConformanceParams;
|
||||
fn is_conformant(&self, params: &CompressedRadixCiphertextConformanceParams) -> bool {
|
||||
match self {
|
||||
Self::Seeded(ct) => ct.is_conformant(params),
|
||||
Self::ModulusSwitched(ct) => ct.is_conformant(params),
|
||||
Self::Seeded(ct) => ct.is_conformant(¶ms.0.into()),
|
||||
Self::ModulusSwitched(ct) => ct.is_conformant(¶ms.0),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -267,7 +314,7 @@ mod test {
|
||||
|
||||
let ct = CompressedFheUint8::try_encrypt(0_u64, &client_key).unwrap();
|
||||
|
||||
assert!(ct.is_conformant(&FheUintConformanceParams::from(
|
||||
assert!(ct.is_conformant(&CompressedFheUintConformanceParams::from(
|
||||
PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128
|
||||
)));
|
||||
|
||||
@@ -291,9 +338,11 @@ mod test {
|
||||
|
||||
breaker(i, &mut ct_clone);
|
||||
|
||||
assert!(!ct_clone.is_conformant(&FheUintConformanceParams::from(
|
||||
PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128
|
||||
)));
|
||||
assert!(
|
||||
!ct_clone.is_conformant(&CompressedFheUintConformanceParams::from(
|
||||
PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128
|
||||
))
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -322,9 +371,11 @@ mod test {
|
||||
|
||||
breaker(i, &mut ct_clone);
|
||||
|
||||
assert!(!ct_clone.is_conformant(&FheUintConformanceParams::from(
|
||||
PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128
|
||||
)));
|
||||
assert!(
|
||||
!ct_clone.is_conformant(&CompressedFheUintConformanceParams::from(
|
||||
PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128
|
||||
))
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -339,7 +390,7 @@ mod test {
|
||||
|
||||
let ct = CompressedFheUint8::try_encrypt(0_u64, &client_key).unwrap();
|
||||
|
||||
assert!(ct.is_conformant(&FheUintConformanceParams::from(
|
||||
assert!(ct.is_conformant(&CompressedFheUintConformanceParams::from(
|
||||
PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128
|
||||
)));
|
||||
|
||||
@@ -359,9 +410,11 @@ mod test {
|
||||
.seed
|
||||
.0 = rng.gen::<u128>();
|
||||
}
|
||||
assert!(ct_clone.is_conformant(&FheUintConformanceParams::from(
|
||||
PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128
|
||||
)));
|
||||
assert!(
|
||||
ct_clone.is_conformant(&CompressedFheUintConformanceParams::from(
|
||||
PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128
|
||||
))
|
||||
);
|
||||
|
||||
let mut ct_clone_decompressed = ct_clone.decompress();
|
||||
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
use crate::high_level_api::integers::unsigned::base::{
|
||||
FheUint, FheUintConformanceParams, FheUintId,
|
||||
};
|
||||
use crate::high_level_api::integers::unsigned::compressed::CompressedFheUint;
|
||||
use crate::high_level_api::integers::unsigned::compressed::{
|
||||
CompressedFheUint, CompressedFheUintConformanceParams,
|
||||
};
|
||||
use crate::high_level_api::integers::{FheId, IntegerId};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use tfhe_versionable::NotVersioned;
|
||||
@@ -56,6 +58,7 @@ macro_rules! static_int_type {
|
||||
|
||||
// Conformance Params
|
||||
pub type [<FheUint $num_bits ConformanceParams>] = FheUintConformanceParams<[<FheUint $num_bits Id>]>;
|
||||
pub type [<CompressedFheUint $num_bits ConformanceParams>] = CompressedFheUintConformanceParams<[<FheUint $num_bits Id>]>;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -9,8 +9,8 @@ use crate::shortint::parameters::*;
|
||||
use crate::{
|
||||
ClientKey, CompactCiphertextList, CompactCiphertextListConformanceParams, CompactPublicKey,
|
||||
CompressedCompactPublicKey, CompressedFheUint16, CompressedFheUint256, CompressedFheUint32,
|
||||
CompressedPublicKey, CompressedServerKey, FheInt16, FheInt32, FheInt8, FheUint128, FheUint16,
|
||||
FheUint256, FheUint32, FheUint32ConformanceParams,
|
||||
CompressedFheUint32ConformanceParams, CompressedPublicKey, CompressedServerKey, FheInt16,
|
||||
FheInt32, FheInt8, FheUint128, FheUint16, FheUint256, FheUint32, FheUint32ConformanceParams,
|
||||
};
|
||||
use rand::prelude::*;
|
||||
|
||||
@@ -506,12 +506,12 @@ fn test_safe_deserialize_conformant_compressed_fhe_uint32() {
|
||||
.serialize_into(&a, &mut serialized)
|
||||
.unwrap();
|
||||
|
||||
let params = FheUint32ConformanceParams::from(&server_key);
|
||||
let params = CompressedFheUint32ConformanceParams::from(&server_key);
|
||||
let deserialized_a = DeserializationConfig::new(1 << 20)
|
||||
.deserialize_from::<CompressedFheUint32>(serialized.as_slice(), ¶ms)
|
||||
.unwrap();
|
||||
|
||||
assert!(deserialized_a.is_conformant(&FheUint32ConformanceParams::from(block_params)));
|
||||
assert!(deserialized_a.is_conformant(&CompressedFheUint32ConformanceParams::from(block_params)));
|
||||
|
||||
let decrypted: u32 = deserialized_a.decompress().decrypt(&client_key);
|
||||
assert_eq!(decrypted, clear_a);
|
||||
|
||||
@@ -18,9 +18,9 @@ use crate::shortint::parameters::{
|
||||
use crate::{
|
||||
set_server_key, ClientKey, CompactCiphertextList, CompactCiphertextListConformanceParams,
|
||||
CompactPublicKey, CompressedCompactPublicKey, CompressedFheUint16, CompressedFheUint256,
|
||||
CompressedFheUint32, ConfigBuilder, DeserializationConfig, FheBool, FheInt16, FheInt32,
|
||||
FheInt8, FheUint128, FheUint16, FheUint256, FheUint32, FheUint32ConformanceParams, FheUint8,
|
||||
GpuIndex, MatchValues, SerializationConfig,
|
||||
CompressedFheUint32, CompressedFheUint32ConformanceParams, ConfigBuilder,
|
||||
DeserializationConfig, FheBool, FheInt16, FheInt32, FheInt8, FheUint128, FheUint16, FheUint256,
|
||||
FheUint32, FheUint32ConformanceParams, FheUint8, GpuIndex, MatchValues, SerializationConfig,
|
||||
};
|
||||
use rand::{random, Rng};
|
||||
|
||||
@@ -554,9 +554,11 @@ fn test_safe_deserialize_conformant_compressed_fhe_uint32_gpu() {
|
||||
.unwrap();
|
||||
|
||||
let params = if i == 0 {
|
||||
FheUint32ConformanceParams::from(PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128)
|
||||
CompressedFheUint32ConformanceParams::from(
|
||||
PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128,
|
||||
)
|
||||
} else if i == 1 {
|
||||
FheUint32ConformanceParams::from(
|
||||
CompressedFheUint32ConformanceParams::from(
|
||||
PARAM_GPU_MULTI_BIT_GROUP_4_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128,
|
||||
)
|
||||
} else {
|
||||
|
||||
@@ -17,6 +17,7 @@ macro_rules! expand_pub_use_fhe_type(
|
||||
|
||||
// ConformanceParams
|
||||
[<$fhe_type_name ConformanceParams>],
|
||||
[<Compressed $fhe_type_name ConformanceParams>],
|
||||
)*
|
||||
};
|
||||
}
|
||||
@@ -74,7 +75,8 @@ use strum::FromRepr;
|
||||
mod tests;
|
||||
|
||||
pub use crate::high_level_api::booleans::{
|
||||
CompressedFheBool, FheBool, FheBoolConformanceParams, SquashedNoiseFheBool,
|
||||
CompressedFheBool, CompressedFheBoolConformanceParams, FheBool, FheBoolConformanceParams,
|
||||
SquashedNoiseFheBool,
|
||||
};
|
||||
|
||||
#[cfg(feature = "extended-types")]
|
||||
|
||||
@@ -7,7 +7,10 @@ use crate::integer::backward_compatibility::ciphertext::{
|
||||
CompressedModulusSwitchedSignedRadixCiphertextVersions,
|
||||
};
|
||||
use crate::integer::parameters::RadixCiphertextConformanceParams;
|
||||
use crate::shortint::ciphertext::{CompressedModulusSwitchedCiphertext, MaxDegree};
|
||||
use crate::shortint::ciphertext::{
|
||||
CompressedModulusSwitchedCiphertext, CompressedModulusSwitchedCiphertextConformanceParams,
|
||||
MaxDegree,
|
||||
};
|
||||
use crate::shortint::parameters::Degree;
|
||||
|
||||
/// An object to store a ciphertext using less memory.
|
||||
@@ -44,9 +47,12 @@ pub struct CompressedModulusSwitchedRadixCiphertext(
|
||||
);
|
||||
|
||||
impl ParameterSetConformant for CompressedModulusSwitchedRadixCiphertext {
|
||||
type ParameterSet = RadixCiphertextConformanceParams;
|
||||
type ParameterSet = CompressedModulusSwitchedRadixCiphertextConformanceParams;
|
||||
|
||||
fn is_conformant(&self, params: &RadixCiphertextConformanceParams) -> bool {
|
||||
fn is_conformant(
|
||||
&self,
|
||||
params: &CompressedModulusSwitchedRadixCiphertextConformanceParams,
|
||||
) -> bool {
|
||||
let Self(ct) = self;
|
||||
|
||||
ct.is_conformant(params)
|
||||
@@ -87,9 +93,12 @@ pub struct CompressedModulusSwitchedSignedRadixCiphertext(
|
||||
);
|
||||
|
||||
impl ParameterSetConformant for CompressedModulusSwitchedSignedRadixCiphertext {
|
||||
type ParameterSet = RadixCiphertextConformanceParams;
|
||||
type ParameterSet = CompressedModulusSwitchedRadixCiphertextConformanceParams;
|
||||
|
||||
fn is_conformant(&self, params: &RadixCiphertextConformanceParams) -> bool {
|
||||
fn is_conformant(
|
||||
&self,
|
||||
params: &CompressedModulusSwitchedRadixCiphertextConformanceParams,
|
||||
) -> bool {
|
||||
let Self(ct) = self;
|
||||
|
||||
ct.is_conformant(params)
|
||||
@@ -103,10 +112,30 @@ pub(crate) struct CompressedModulusSwitchedRadixCiphertextGeneric {
|
||||
pub last_block: Option<CompressedModulusSwitchedCiphertext>,
|
||||
}
|
||||
|
||||
impl ParameterSetConformant for CompressedModulusSwitchedRadixCiphertextGeneric {
|
||||
type ParameterSet = RadixCiphertextConformanceParams;
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct CompressedModulusSwitchedRadixCiphertextConformanceParams {
|
||||
pub shortint_params: CompressedModulusSwitchedCiphertextConformanceParams,
|
||||
pub num_blocks_per_integer: usize,
|
||||
}
|
||||
|
||||
fn is_conformant(&self, params: &RadixCiphertextConformanceParams) -> bool {
|
||||
impl From<CompressedModulusSwitchedRadixCiphertextConformanceParams>
|
||||
for RadixCiphertextConformanceParams
|
||||
{
|
||||
fn from(value: CompressedModulusSwitchedRadixCiphertextConformanceParams) -> Self {
|
||||
Self {
|
||||
shortint_params: value.shortint_params.into(),
|
||||
num_blocks_per_integer: value.num_blocks_per_integer,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ParameterSetConformant for CompressedModulusSwitchedRadixCiphertextGeneric {
|
||||
type ParameterSet = CompressedModulusSwitchedRadixCiphertextConformanceParams;
|
||||
|
||||
fn is_conformant(
|
||||
&self,
|
||||
params: &CompressedModulusSwitchedRadixCiphertextConformanceParams,
|
||||
) -> bool {
|
||||
let Self {
|
||||
paired_blocks,
|
||||
last_block,
|
||||
|
||||
@@ -20,7 +20,10 @@ use crate::core_crypto::prelude::{
|
||||
};
|
||||
|
||||
use super::backward_compatibility::atomic_pattern::*;
|
||||
use super::ciphertext::{CompressedModulusSwitchedCiphertext, Degree};
|
||||
use super::ciphertext::{
|
||||
CompressedModulusSwitchedCiphertext, CompressedModulusSwitchedCiphertextConformanceParams,
|
||||
Degree,
|
||||
};
|
||||
use super::client_key::atomic_pattern::AtomicPatternClientKey;
|
||||
use super::engine::ShortintEngine;
|
||||
use super::parameters::{
|
||||
@@ -608,6 +611,19 @@ impl AtomicPatternParameters {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn to_compressed_modswitched_conformance_param(
|
||||
&self,
|
||||
) -> CompressedModulusSwitchedCiphertextConformanceParams {
|
||||
match self {
|
||||
Self::Standard(pbsparameters) => {
|
||||
pbsparameters.to_compressed_modswitched_conformance_param()
|
||||
}
|
||||
Self::KeySwitch32(key_switch32_pbsparameters) => {
|
||||
key_switch32_pbsparameters.to_compressed_modswitched_conformance_param()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ParameterSetConformant for AtomicPatternServerKey {
|
||||
|
||||
@@ -4,7 +4,7 @@ use super::common::*;
|
||||
use crate::conformance::ParameterSetConformant;
|
||||
use crate::core_crypto::prelude::compressed_modulus_switched_lwe_ciphertext::CompressedModulusSwitchedLweCiphertext;
|
||||
use crate::core_crypto::prelude::compressed_modulus_switched_multi_bit_lwe_ciphertext::CompressedModulusSwitchedMultiBitLweCiphertext;
|
||||
use crate::core_crypto::prelude::LweCiphertextConformanceParams;
|
||||
use crate::core_crypto::prelude::CompressedModulusSwitchedLweCiphertextConformanceParams;
|
||||
use crate::shortint::backward_compatibility::ciphertext::{
|
||||
CompressedModulusSwitchedCiphertextVersions,
|
||||
InternalCompressedModulusSwitchedCiphertextVersions,
|
||||
@@ -48,10 +48,32 @@ pub struct CompressedModulusSwitchedCiphertext {
|
||||
pub(crate) atomic_pattern: AtomicPatternKind,
|
||||
}
|
||||
|
||||
impl ParameterSetConformant for CompressedModulusSwitchedCiphertext {
|
||||
type ParameterSet = CiphertextConformanceParams;
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct CompressedModulusSwitchedCiphertextConformanceParams {
|
||||
pub ct_params: CompressedModulusSwitchedLweCiphertextConformanceParams<u64>,
|
||||
pub message_modulus: MessageModulus,
|
||||
pub carry_modulus: CarryModulus,
|
||||
pub degree: Degree,
|
||||
pub atomic_pattern: AtomicPatternKind,
|
||||
}
|
||||
|
||||
fn is_conformant(&self, param: &CiphertextConformanceParams) -> bool {
|
||||
impl From<CompressedModulusSwitchedCiphertextConformanceParams> for CiphertextConformanceParams {
|
||||
fn from(value: CompressedModulusSwitchedCiphertextConformanceParams) -> Self {
|
||||
Self {
|
||||
ct_params: value.ct_params.ct_params,
|
||||
message_modulus: value.message_modulus,
|
||||
carry_modulus: value.carry_modulus,
|
||||
degree: value.degree,
|
||||
noise_level: NoiseLevel::NOMINAL,
|
||||
atomic_pattern: value.atomic_pattern,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ParameterSetConformant for CompressedModulusSwitchedCiphertext {
|
||||
type ParameterSet = CompressedModulusSwitchedCiphertextConformanceParams;
|
||||
|
||||
fn is_conformant(&self, param: &CompressedModulusSwitchedCiphertextConformanceParams) -> bool {
|
||||
let Self {
|
||||
compressed_modulus_switched_lwe_ciphertext,
|
||||
degree,
|
||||
@@ -60,11 +82,19 @@ impl ParameterSetConformant for CompressedModulusSwitchedCiphertext {
|
||||
atomic_pattern,
|
||||
} = self;
|
||||
|
||||
compressed_modulus_switched_lwe_ciphertext.is_conformant(¶m.ct_params)
|
||||
&& *message_modulus == param.message_modulus
|
||||
&& *carry_modulus == param.carry_modulus
|
||||
&& *atomic_pattern == param.atomic_pattern
|
||||
&& *degree == param.degree
|
||||
let CompressedModulusSwitchedCiphertextConformanceParams {
|
||||
ct_params,
|
||||
message_modulus: param_message_modulus,
|
||||
carry_modulus: param_carry_modulus,
|
||||
degree: param_degree,
|
||||
atomic_pattern: param_atomic_pattern,
|
||||
} = param;
|
||||
|
||||
compressed_modulus_switched_lwe_ciphertext.is_conformant(ct_params)
|
||||
&& message_modulus == param_message_modulus
|
||||
&& carry_modulus == param_carry_modulus
|
||||
&& atomic_pattern == param_atomic_pattern
|
||||
&& degree == param_degree
|
||||
}
|
||||
}
|
||||
|
||||
@@ -76,9 +106,12 @@ pub(crate) enum InternalCompressedModulusSwitchedCiphertext {
|
||||
}
|
||||
|
||||
impl ParameterSetConformant for InternalCompressedModulusSwitchedCiphertext {
|
||||
type ParameterSet = LweCiphertextConformanceParams<u64>;
|
||||
type ParameterSet = CompressedModulusSwitchedLweCiphertextConformanceParams<u64>;
|
||||
|
||||
fn is_conformant(&self, param: &LweCiphertextConformanceParams<u64>) -> bool {
|
||||
fn is_conformant(
|
||||
&self,
|
||||
param: &CompressedModulusSwitchedLweCiphertextConformanceParams<u64>,
|
||||
) -> bool {
|
||||
match self {
|
||||
Self::Classic(a) => a.is_conformant(param),
|
||||
Self::MultiBit(a) => a.is_conformant(param),
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
use crate::core_crypto::prelude::{LweCiphertextConformanceParams, MsDecompressionType};
|
||||
use crate::core_crypto::prelude::{
|
||||
CompressedModulusSwitchedLweCiphertextConformanceParams, LweCiphertextConformanceParams,
|
||||
MsDecompressionType,
|
||||
};
|
||||
use crate::shortint::backward_compatibility::parameters::ClassicPBSParametersVersions;
|
||||
use crate::shortint::ciphertext::CompressedModulusSwitchedCiphertextConformanceParams;
|
||||
use crate::shortint::parameters::{
|
||||
AtomicPatternKind, CarryModulus, CiphertextConformanceParams, CiphertextModulus,
|
||||
DecompositionBaseLog, DecompositionLevelCount, Degree, DynamicDistribution,
|
||||
@@ -121,7 +125,6 @@ impl ClassicPBSParameters {
|
||||
ct_params: LweCiphertextConformanceParams {
|
||||
lwe_dim: expected_dim,
|
||||
ct_modulus: ciphertext_modulus,
|
||||
ms_decompression_method: MsDecompressionType::ClassicPbs,
|
||||
},
|
||||
message_modulus,
|
||||
carry_modulus,
|
||||
@@ -130,4 +133,44 @@ impl ClassicPBSParameters {
|
||||
noise_level,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn to_compressed_modswitched_conformance_param(
|
||||
&self,
|
||||
) -> CompressedModulusSwitchedCiphertextConformanceParams {
|
||||
let (atomic_pattern, expected_dim) = match self.encryption_key_choice {
|
||||
EncryptionKeyChoice::Big => (
|
||||
AtomicPatternKind::Standard(PBSOrder::KeyswitchBootstrap),
|
||||
self.glwe_dimension
|
||||
.to_equivalent_lwe_dimension(self.polynomial_size),
|
||||
),
|
||||
EncryptionKeyChoice::Small => (
|
||||
AtomicPatternKind::Standard(PBSOrder::BootstrapKeyswitch),
|
||||
self.lwe_dimension,
|
||||
),
|
||||
};
|
||||
|
||||
let message_modulus = self.message_modulus;
|
||||
let ciphertext_modulus = self.ciphertext_modulus;
|
||||
let carry_modulus = self.carry_modulus;
|
||||
|
||||
let degree = Degree::new(message_modulus.0 - 1);
|
||||
|
||||
let ct_params = LweCiphertextConformanceParams {
|
||||
lwe_dim: expected_dim,
|
||||
ct_modulus: ciphertext_modulus,
|
||||
};
|
||||
|
||||
let compressed_ct_params = CompressedModulusSwitchedLweCiphertextConformanceParams {
|
||||
ct_params,
|
||||
ms_decompression_type: MsDecompressionType::ClassicPbs,
|
||||
};
|
||||
|
||||
CompressedModulusSwitchedCiphertextConformanceParams {
|
||||
ct_params: compressed_ct_params,
|
||||
message_modulus,
|
||||
carry_modulus,
|
||||
atomic_pattern,
|
||||
degree,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,9 +7,11 @@ pub use crate::core_crypto::commons::parameters::{
|
||||
NoiseEstimationMeasureBound, PolynomialSize, RSigmaFactor,
|
||||
};
|
||||
use crate::core_crypto::prelude::{
|
||||
LweCiphertextConformanceParams, LweKeyswitchKeyConformanceParams, MsDecompressionType,
|
||||
CompressedModulusSwitchedLweCiphertextConformanceParams, LweCiphertextConformanceParams,
|
||||
LweKeyswitchKeyConformanceParams, MsDecompressionType,
|
||||
};
|
||||
use crate::shortint::backward_compatibility::parameters::KeySwitch32PBSParametersVersions;
|
||||
use crate::shortint::ciphertext::CompressedModulusSwitchedCiphertextConformanceParams;
|
||||
use crate::shortint::parameters::ModulusSwitchType;
|
||||
|
||||
use super::{
|
||||
@@ -143,7 +145,6 @@ impl KeySwitch32PBSParameters {
|
||||
ct_params: LweCiphertextConformanceParams {
|
||||
lwe_dim: expected_dim,
|
||||
ct_modulus: ciphertext_modulus,
|
||||
ms_decompression_method: MsDecompressionType::ClassicPbs,
|
||||
},
|
||||
message_modulus,
|
||||
carry_modulus,
|
||||
@@ -153,6 +154,38 @@ impl KeySwitch32PBSParameters {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn to_compressed_modswitched_conformance_param(
|
||||
&self,
|
||||
) -> CompressedModulusSwitchedCiphertextConformanceParams {
|
||||
let expected_dim = self
|
||||
.glwe_dimension
|
||||
.to_equivalent_lwe_dimension(self.polynomial_size);
|
||||
|
||||
let message_modulus = self.message_modulus;
|
||||
let ciphertext_modulus = self.ciphertext_modulus;
|
||||
let carry_modulus = self.carry_modulus;
|
||||
|
||||
let degree = Degree::new(message_modulus.0 - 1);
|
||||
|
||||
let ct_params = LweCiphertextConformanceParams {
|
||||
lwe_dim: expected_dim,
|
||||
ct_modulus: ciphertext_modulus,
|
||||
};
|
||||
|
||||
let compressed_ct_params = CompressedModulusSwitchedLweCiphertextConformanceParams {
|
||||
ct_params,
|
||||
ms_decompression_type: MsDecompressionType::ClassicPbs,
|
||||
};
|
||||
|
||||
CompressedModulusSwitchedCiphertextConformanceParams {
|
||||
ct_params: compressed_ct_params,
|
||||
message_modulus,
|
||||
carry_modulus,
|
||||
atomic_pattern: AtomicPatternKind::KeySwitch32,
|
||||
degree,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn ciphertext_modulus_for_key(&self, key_choice: EncryptionKeyChoice) -> CiphertextModulus {
|
||||
match key_choice {
|
||||
EncryptionKeyChoice::Big => self.ciphertext_modulus,
|
||||
|
||||
@@ -65,6 +65,7 @@ pub use v1_5 as current_params;
|
||||
|
||||
pub use super::atomic_pattern::{AtomicPatternKind, AtomicPatternParameters};
|
||||
use super::backward_compatibility::parameters::modulus_switch_noise_reduction::ModulusSwitchNoiseReductionParamsVersions;
|
||||
use super::ciphertext::CompressedModulusSwitchedCiphertextConformanceParams;
|
||||
pub use super::ciphertext::{Degree, MaxNoiseLevel, NoiseLevel};
|
||||
use super::server_key::PBSConformanceParams;
|
||||
pub use super::PBSOrder;
|
||||
@@ -366,6 +367,15 @@ impl PBSParameters {
|
||||
Self::MultiBitPBS(param) => param.to_shortint_conformance_param(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn to_compressed_modswitched_conformance_param(
|
||||
&self,
|
||||
) -> CompressedModulusSwitchedCiphertextConformanceParams {
|
||||
match self {
|
||||
Self::PBS(param) => param.to_compressed_modswitched_conformance_param(),
|
||||
Self::MultiBitPBS(param) => param.to_compressed_modswitched_conformance_param(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Copy, Clone, Deserialize, Debug, PartialEq, Versionize)]
|
||||
|
||||
@@ -1,7 +1,12 @@
|
||||
use crate::core_crypto::entities::{
|
||||
LweCiphertextConformanceParams, MsDecompressionType, MultiBitBootstrapKeyConformanceParams,
|
||||
LweCiphertextConformanceParams, MultiBitBootstrapKeyConformanceParams,
|
||||
};
|
||||
use crate::core_crypto::prelude::{
|
||||
CompressedModulusSwitchedLweCiphertextConformanceParams, MsDecompressionType,
|
||||
};
|
||||
use crate::shortint::ciphertext::{
|
||||
CompressedModulusSwitchedCiphertextConformanceParams, Degree, NoiseLevel,
|
||||
};
|
||||
use crate::shortint::ciphertext::{Degree, NoiseLevel};
|
||||
use crate::shortint::parameters::{
|
||||
AtomicPatternKind, CarryModulus, CiphertextConformanceParams, CiphertextModulus,
|
||||
DecompositionBaseLog, DecompositionLevelCount, DynamicDistribution, EncryptionKeyChoice,
|
||||
@@ -78,7 +83,6 @@ impl MultiBitPBSParameters {
|
||||
ct_params: LweCiphertextConformanceParams {
|
||||
lwe_dim: expected_dim,
|
||||
ct_modulus: ciphertext_modulus,
|
||||
ms_decompression_method: MsDecompressionType::MultiBitPbs(self.grouping_factor),
|
||||
},
|
||||
message_modulus,
|
||||
carry_modulus,
|
||||
@@ -87,6 +91,46 @@ impl MultiBitPBSParameters {
|
||||
noise_level,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn to_compressed_modswitched_conformance_param(
|
||||
&self,
|
||||
) -> CompressedModulusSwitchedCiphertextConformanceParams {
|
||||
let (atomic_pattern, expected_dim) = match self.encryption_key_choice {
|
||||
EncryptionKeyChoice::Big => (
|
||||
AtomicPatternKind::Standard(PBSOrder::KeyswitchBootstrap),
|
||||
self.glwe_dimension
|
||||
.to_equivalent_lwe_dimension(self.polynomial_size),
|
||||
),
|
||||
EncryptionKeyChoice::Small => (
|
||||
AtomicPatternKind::Standard(PBSOrder::BootstrapKeyswitch),
|
||||
self.lwe_dimension,
|
||||
),
|
||||
};
|
||||
|
||||
let message_modulus = self.message_modulus;
|
||||
let ciphertext_modulus = self.ciphertext_modulus;
|
||||
let carry_modulus = self.carry_modulus;
|
||||
|
||||
let degree = Degree::new(message_modulus.0 - 1);
|
||||
|
||||
let ct_params = LweCiphertextConformanceParams {
|
||||
lwe_dim: expected_dim,
|
||||
ct_modulus: ciphertext_modulus,
|
||||
};
|
||||
|
||||
let compressed_ct_params = CompressedModulusSwitchedLweCiphertextConformanceParams {
|
||||
ct_params,
|
||||
ms_decompression_type: MsDecompressionType::MultiBitPbs(self.grouping_factor),
|
||||
};
|
||||
|
||||
CompressedModulusSwitchedCiphertextConformanceParams {
|
||||
ct_params: compressed_ct_params,
|
||||
message_modulus,
|
||||
carry_modulus,
|
||||
atomic_pattern,
|
||||
degree,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<&PBSConformanceParams> for MultiBitBootstrapKeyConformanceParams<u64> {
|
||||
|
||||
@@ -84,7 +84,9 @@ use super::atomic_pattern::{
|
||||
use super::backward_compatibility::server_key::{
|
||||
SerializableShortintBootstrappingKeyVersions, ServerKeyVersions,
|
||||
};
|
||||
use super::ciphertext::unchecked_create_trivial_with_lwe_size;
|
||||
use super::ciphertext::{
|
||||
unchecked_create_trivial_with_lwe_size, CompressedModulusSwitchedCiphertextConformanceParams,
|
||||
};
|
||||
use super::noise_squashing::Shortint128BootstrappingKey;
|
||||
use super::parameters::KeySwitch32PBSParameters;
|
||||
use super::PBSParameters;
|
||||
@@ -728,12 +730,9 @@ impl<AP: AtomicPattern> GenericServerKey<AP> {
|
||||
pub fn conformance_params(&self) -> CiphertextConformanceParams {
|
||||
let lwe_dim = self.ciphertext_lwe_dimension();
|
||||
|
||||
let ms_decompression_method = self.atomic_pattern.ciphertext_decompression_method();
|
||||
|
||||
let ct_params = LweCiphertextConformanceParams {
|
||||
lwe_dim,
|
||||
ct_modulus: self.ciphertext_modulus,
|
||||
ms_decompression_method,
|
||||
};
|
||||
|
||||
CiphertextConformanceParams {
|
||||
@@ -746,6 +745,30 @@ impl<AP: AtomicPattern> GenericServerKey<AP> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn compressed_modswitched_conformance_params(
|
||||
&self,
|
||||
) -> CompressedModulusSwitchedCiphertextConformanceParams {
|
||||
let lwe_dim = self.ciphertext_lwe_dimension();
|
||||
|
||||
let ct_params = LweCiphertextConformanceParams {
|
||||
lwe_dim,
|
||||
ct_modulus: self.ciphertext_modulus,
|
||||
};
|
||||
|
||||
let compressed_ct = CompressedModulusSwitchedLweCiphertextConformanceParams {
|
||||
ct_params,
|
||||
ms_decompression_type: self.atomic_pattern.ciphertext_decompression_method(),
|
||||
};
|
||||
|
||||
CompressedModulusSwitchedCiphertextConformanceParams {
|
||||
ct_params: compressed_ct,
|
||||
message_modulus: self.message_modulus,
|
||||
carry_modulus: self.carry_modulus,
|
||||
degree: Degree::new(self.message_modulus.0 - 1),
|
||||
atomic_pattern: self.atomic_pattern.kind(),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn encoding(&self, padding_bit: PaddingBit) -> ShortintEncoding<u64> {
|
||||
ShortintEncoding {
|
||||
ciphertext_modulus: self.ciphertext_modulus,
|
||||
|
||||
Reference in New Issue
Block a user