feat(hlapi): add XofKeySet

This adds a specialized struct that is able to generate keys for the
high_level_api in a way that is compatible with the NIST/MPC protocol

There are still things to be done in later commits:
- Backward compatibility
- NIST compliant ClientKey generation
This commit is contained in:
Thomas Montaigu
2025-09-11 12:40:39 +02:00
committed by tmontaigu
parent 7e1c8f7db5
commit d1c190fac6
12 changed files with 1573 additions and 91 deletions

View File

@@ -11,6 +11,7 @@ use crate::core_crypto::commons::parameters::*;
use crate::core_crypto::commons::traits::*;
use crate::core_crypto::entities::*;
use rayon::prelude::*;
use tfhe_csprng::seeders::Seed;
/// Fill an [`LWE bootstrap key`](`LweBootstrapKey`) with an actual bootstrapping key constructed
/// from an input key [`LWE secret key`](`LweSecretKey`) and an output key
@@ -390,6 +391,41 @@ pub fn generate_seeded_lwe_bootstrap_key<
OutputCont: ContainerMut<Element = OutputScalar>,
// Maybe Sized allows to pass Box<dyn Seeder>.
NoiseSeeder: Seeder + ?Sized,
{
let mut generator = EncryptionRandomGenerator::<DefaultRandomGenerator>::new(
output.compression_seed().seed,
noise_seeder,
);
generate_seeded_lwe_bootstrap_key_with_pre_seeded_generator(
input_lwe_secret_key,
output_glwe_secret_key,
output,
noise_distribution,
&mut generator,
)
}
pub fn generate_seeded_lwe_bootstrap_key_with_pre_seeded_generator<
NoiseDistribution,
InputKeyCont,
OutputKeyCont,
OutputCont,
ByteGen,
>(
input_lwe_secret_key: &LweSecretKey<InputKeyCont>,
output_glwe_secret_key: &GlweSecretKey<OutputKeyCont>,
output: &mut SeededLweBootstrapKey<OutputCont>,
noise_distribution: NoiseDistribution,
generator: &mut EncryptionRandomGenerator<ByteGen>,
) where
NoiseDistribution: Distribution,
InputKeyCont: Container,
OutputKeyCont: Container,
OutputCont: ContainerMut<Element = OutputKeyCont::Element>,
InputKeyCont::Element: Copy + CastInto<OutputKeyCont::Element>,
OutputKeyCont::Element: Encryptable<Uniform, NoiseDistribution>,
ByteGen: ByteRandomGenerator,
{
assert!(
output.input_lwe_dimension() == input_lwe_secret_key.lwe_dimension(),
@@ -415,11 +451,6 @@ pub fn generate_seeded_lwe_bootstrap_key<
output.polynomial_size()
);
let mut generator = EncryptionRandomGenerator::<DefaultRandomGenerator>::new(
output.compression_seed().seed,
noise_seeder,
);
let gen_iter = generator
.try_fork_from_config(output.encryption_fork_config(Uniform, noise_distribution))
.unwrap();
@@ -492,6 +523,49 @@ where
bsk
}
pub fn allocate_and_generate_lwe_bootstrapping_key_with_pre_seeded_generator<
LweCont,
GlweCont,
ByteGen,
>(
input_lwe_secret_key: &LweSecretKey<LweCont>,
output_glwe_secret_key: &GlweSecretKey<GlweCont>,
decomp_base_log: DecompositionBaseLog,
decomp_level_count: DecompositionLevelCount,
noise_distribution: DynamicDistribution<GlweCont::Element>,
ciphertext_modulus: CiphertextModulus<GlweCont::Element>,
noise_generator: &mut EncryptionRandomGenerator<ByteGen>,
) -> SeededLweBootstrapKeyOwned<GlweCont::Element>
where
LweCont: Container,
GlweCont: Container,
LweCont::Element: Copy + CastInto<GlweCont::Element>,
GlweCont::Element:
UnsignedInteger + Encryptable<Uniform, DynamicDistribution<GlweCont::Element>>,
ByteGen: ByteRandomGenerator,
{
let mut lwe_bootstrapping_key = SeededLweBootstrapKeyOwned::new(
GlweCont::Element::ZERO,
output_glwe_secret_key.glwe_dimension().to_glwe_size(),
output_glwe_secret_key.polynomial_size(),
decomp_base_log,
decomp_level_count,
input_lwe_secret_key.lwe_dimension(),
CompressionSeed::from(Seed(0)),
ciphertext_modulus,
);
generate_seeded_lwe_bootstrap_key_with_pre_seeded_generator(
input_lwe_secret_key,
output_glwe_secret_key,
&mut lwe_bootstrapping_key,
noise_distribution,
noise_generator,
);
lwe_bootstrapping_key
}
/// Parallel variant of [`generate_seeded_lwe_bootstrap_key`], it is recommended to use this
/// function for better key generation times as LWE bootstrapping keys can be quite large.
pub fn par_generate_seeded_lwe_bootstrap_key<

View File

@@ -110,6 +110,41 @@ pub fn generate_seeded_lwe_compact_public_key<
OutputKeyCont: ContainerMut<Element = Scalar>,
// Maybe Sized allows to pass Box<dyn Seeder>.
NoiseSeeder: Seeder + ?Sized,
{
let mut generator = EncryptionRandomGenerator::<DefaultRandomGenerator>::new(
output.compression_seed().seed,
noise_seeder,
);
generate_seeded_lwe_compact_public_key_with_pre_seeded_generator(
lwe_secret_key,
output,
noise_distribution,
&mut generator,
);
}
/// Fill a [`seeded LWE compact public key`](`LweCompactPublicKey`) with an actual public key
/// constructed from a private [`LWE secret key`](`LweSecretKey`).
///
/// This uses an already seeded generator
pub fn generate_seeded_lwe_compact_public_key_with_pre_seeded_generator<
Scalar,
NoiseDistribution,
InputKeyCont,
OutputKeyCont,
ByteGen,
>(
lwe_secret_key: &LweSecretKey<InputKeyCont>,
output: &mut SeededLweCompactPublicKey<OutputKeyCont>,
noise_distribution: NoiseDistribution,
generator: &mut EncryptionRandomGenerator<ByteGen>,
) where
Scalar: Encryptable<Uniform, NoiseDistribution>,
NoiseDistribution: Distribution,
InputKeyCont: Container<Element = Scalar>,
OutputKeyCont: ContainerMut<Element = Scalar>,
ByteGen: ByteRandomGenerator,
{
assert!(
output.ciphertext_modulus().is_native_modulus(),
@@ -124,11 +159,6 @@ pub fn generate_seeded_lwe_compact_public_key<
output.lwe_dimension()
);
let mut generator = EncryptionRandomGenerator::<DefaultRandomGenerator>::new(
output.compression_seed().seed,
noise_seeder,
);
let mut tmp_mask = vec![Scalar::ZERO; output.lwe_dimension().0];
generator.fill_slice_with_random_uniform_mask(tmp_mask.as_mut());

View File

@@ -13,6 +13,7 @@ use crate::core_crypto::commons::math::random::{
use crate::core_crypto::commons::parameters::*;
use crate::core_crypto::commons::traits::*;
use crate::core_crypto::entities::*;
use tfhe_csprng::seeders::Seed;
/// Fill an [`LWE keyswitch key`](`LweKeyswitchKey`) with an actual keyswitching key constructed
/// from an input and an output key [`LWE secret key`](`LweSecretKey`).
@@ -407,6 +408,43 @@ pub fn generate_seeded_lwe_keyswitch_key<
KSKeyCont: ContainerMut<Element = OutputScalar>,
// Maybe Sized allows to pass Box<dyn Seeder>.
NoiseSeeder: Seeder + ?Sized,
{
let mut generator = EncryptionRandomGenerator::<DefaultRandomGenerator>::new(
lwe_keyswitch_key.compression_seed().seed,
noise_seeder,
);
generate_seeded_lwe_keyswitch_key_with_pre_seeded_generator(
input_lwe_sk,
output_lwe_sk,
lwe_keyswitch_key,
noise_distribution,
&mut generator,
)
}
pub fn generate_seeded_lwe_keyswitch_key_with_pre_seeded_generator<
InputScalar,
OutputScalar,
NoiseDistribution,
InputKeyCont,
OutputKeyCont,
KSKeyCont,
ByteGen,
>(
input_lwe_sk: &LweSecretKey<InputKeyCont>,
output_lwe_sk: &LweSecretKey<OutputKeyCont>,
lwe_keyswitch_key: &mut SeededLweKeyswitchKey<KSKeyCont>,
noise_distribution: NoiseDistribution,
generator: &mut EncryptionRandomGenerator<ByteGen>,
) where
InputScalar: UnsignedInteger + CastInto<OutputScalar>,
OutputScalar: Encryptable<Uniform, NoiseDistribution>,
NoiseDistribution: Distribution,
InputKeyCont: Container<Element = InputScalar>,
OutputKeyCont: Container<Element = OutputScalar>,
KSKeyCont: ContainerMut<Element = OutputScalar>,
ByteGen: ByteRandomGenerator,
{
assert!(
lwe_keyswitch_key.input_key_lwe_dimension() == input_lwe_sk.lwe_dimension(),
@@ -439,11 +477,6 @@ pub fn generate_seeded_lwe_keyswitch_key<
let mut decomposition_plaintexts_buffer =
PlaintextListOwned::new(OutputScalar::ZERO, PlaintextCount(decomp_level_count.0));
let mut generator = EncryptionRandomGenerator::<DefaultRandomGenerator>::new(
lwe_keyswitch_key.compression_seed().seed,
noise_seeder,
);
// Iterate over the input key elements and the destination lwe_keyswitch_key memory
for (input_key_element, mut keyswitch_key_block) in input_lwe_sk
.as_ref()
@@ -473,7 +506,7 @@ pub fn generate_seeded_lwe_keyswitch_key<
&mut keyswitch_key_block,
&decomposition_plaintexts_buffer,
noise_distribution,
&mut generator,
generator,
);
}
}
@@ -527,6 +560,44 @@ where
new_lwe_keyswitch_key
}
pub fn allocate_and_generate_lwe_key_switching_key_with_pre_seeded_generator<
InputLweCont,
OutputLweCont,
>(
input_lwe_secret_key: &LweSecretKey<InputLweCont>,
output_lwe_secret_key: &LweSecretKey<OutputLweCont>,
decomp_base_log: DecompositionBaseLog,
decomp_level_count: DecompositionLevelCount,
noise_distribution: DynamicDistribution<InputLweCont::Element>,
ciphertext_modulus: CiphertextModulus<InputLweCont::Element>,
noise_generator: &mut EncryptionRandomGenerator<DefaultRandomGenerator>,
) -> SeededLweKeyswitchKeyOwned<InputLweCont::Element>
where
InputLweCont: Container,
InputLweCont::Element:
UnsignedInteger + Encryptable<Uniform, DynamicDistribution<InputLweCont::Element>>,
OutputLweCont: Container<Element = InputLweCont::Element>,
{
let mut key_switching_key = SeededLweKeyswitchKeyOwned::new(
InputLweCont::Element::ZERO,
decomp_base_log,
decomp_level_count,
input_lwe_secret_key.lwe_dimension(),
output_lwe_secret_key.lwe_dimension(),
CompressionSeed::from(Seed(0)),
ciphertext_modulus,
);
generate_seeded_lwe_keyswitch_key_with_pre_seeded_generator(
input_lwe_secret_key,
output_lwe_secret_key,
&mut key_switching_key,
noise_distribution,
noise_generator,
);
key_switching_key
}
/// A generator for producing chunks of an LWE keyswitch key.
///
/// This struct allows for the generation of LWE keyswitch key chunks, which can be used to

View File

@@ -496,6 +496,47 @@ pub fn generate_seeded_lwe_multi_bit_bootstrap_key<
OutputCont: ContainerMut<Element = Scalar>,
// Maybe Sized allows to pass Box<dyn Seeder>.
NoiseSeeder: Seeder + ?Sized,
{
let mut generator = EncryptionRandomGenerator::<DefaultRandomGenerator>::new(
output.compression_seed().seed,
noise_seeder,
);
generate_seeded_lwe_multi_bit_bootstrap_key_with_pre_seeded_generator(
input_lwe_secret_key,
output_glwe_secret_key,
output,
noise_distribution,
&mut generator,
);
}
/// Fill a [`seeded LWE bootstrap key`](`SeededLweMultiBitBootstrapKey`) with an actual seeded
/// bootstrapping key constructed from an input key [`LWE secret key`](`LweSecretKey`) and an output
/// key [`GLWE secret key`](`GlweSecretKey`)
///
///
/// This uses an already seeded generator
pub fn generate_seeded_lwe_multi_bit_bootstrap_key_with_pre_seeded_generator<
Scalar,
NoiseDistribution,
InputKeyCont,
OutputKeyCont,
OutputCont,
ByteGen,
>(
input_lwe_secret_key: &LweSecretKey<InputKeyCont>,
output_glwe_secret_key: &GlweSecretKey<OutputKeyCont>,
output: &mut SeededLweMultiBitBootstrapKey<OutputCont>,
noise_distribution: NoiseDistribution,
generator: &mut EncryptionRandomGenerator<ByteGen>,
) where
Scalar: Encryptable<Uniform, NoiseDistribution> + CastFrom<usize>,
NoiseDistribution: Distribution,
InputKeyCont: Container<Element = Scalar>,
OutputKeyCont: Container<Element = Scalar>,
OutputCont: ContainerMut<Element = Scalar>,
ByteGen: ByteRandomGenerator,
{
assert!(
output.input_lwe_dimension() == input_lwe_secret_key.lwe_dimension(),
@@ -521,11 +562,6 @@ pub fn generate_seeded_lwe_multi_bit_bootstrap_key<
output.polynomial_size()
);
let mut generator = EncryptionRandomGenerator::<DefaultRandomGenerator>::new(
output.compression_seed().seed,
noise_seeder,
);
assert!(
output.input_lwe_dimension() == input_lwe_secret_key.lwe_dimension(),
"Mismatched LweDimension between input LWE secret key and LWE bootstrap key. \

View File

@@ -205,6 +205,92 @@ where
new_lwe_packing_keyswitch_key
}
pub fn generate_seeded_lwe_packing_keyswitch_key_with_pre_seeded_generator<
Scalar,
NoiseDistribution,
InputKeyCont,
OutputKeyCont,
KSKeyCont,
Gen,
>(
input_lwe_sk: &LweSecretKey<InputKeyCont>,
output_glwe_sk: &GlweSecretKey<OutputKeyCont>,
lwe_packing_keyswitch_key: &mut SeededLwePackingKeyswitchKey<KSKeyCont>,
noise_distribution: NoiseDistribution,
generator: &mut EncryptionRandomGenerator<Gen>,
) where
Scalar: Encryptable<Uniform, NoiseDistribution>,
NoiseDistribution: Distribution,
InputKeyCont: Container<Element = Scalar>,
OutputKeyCont: Container<Element = Scalar>,
KSKeyCont: ContainerMut<Element = Scalar>,
Gen: ByteRandomGenerator,
{
assert!(
lwe_packing_keyswitch_key.input_key_lwe_dimension() == input_lwe_sk.lwe_dimension(),
"The destination LwePackingKeyswitchKey input LweDimension is not equal \
to the input LweSecretKey LweDimension. Destination: {:?}, input: {:?}",
lwe_packing_keyswitch_key.input_key_lwe_dimension(),
input_lwe_sk.lwe_dimension()
);
assert!(
lwe_packing_keyswitch_key.output_key_glwe_dimension() == output_glwe_sk.glwe_dimension(),
"The destination LwePackingKeyswitchKey output LweDimension is not equal \
to the output GlweSecretKey GlweDimension. Destination: {:?}, output: {:?}",
lwe_packing_keyswitch_key.output_key_glwe_dimension(),
output_glwe_sk.glwe_dimension()
);
assert!(
lwe_packing_keyswitch_key.output_key_polynomial_size() == output_glwe_sk.polynomial_size(),
"The destination LwePackingKeyswitchKey output PolynomialSize is not equal \
to the output GlweSecretKey PolynomialSize. Destination: {:?}, output: {:?}",
lwe_packing_keyswitch_key.output_key_polynomial_size(),
output_glwe_sk.polynomial_size()
);
let decomp_base_log = lwe_packing_keyswitch_key.decomposition_base_log();
let decomp_level_count = lwe_packing_keyswitch_key.decomposition_level_count();
let polynomial_size = lwe_packing_keyswitch_key.output_polynomial_size();
let ciphertext_modulus = lwe_packing_keyswitch_key.ciphertext_modulus();
assert!(ciphertext_modulus.is_compatible_with_native_modulus());
// The plaintexts used to encrypt a key element will be stored in this buffer
let mut decomposition_plaintexts_buffer = PlaintextListOwned::new(
Scalar::ZERO,
PlaintextCount(decomp_level_count.0 * polynomial_size.0),
);
// Iterate over the input key elements and the destination lwe_packing_keyswitch_key memory
for (input_key_element, mut packing_keyswitch_key_block) in input_lwe_sk
.as_ref()
.iter()
.zip(lwe_packing_keyswitch_key.iter_mut())
{
// We fill the buffer with the powers of the key elements
for (level, mut messages) in (1..=decomp_level_count.0)
.map(DecompositionLevel)
.rev()
.zip(decomposition_plaintexts_buffer.chunks_exact_mut(polynomial_size.0))
{
// Here we take the decomposition term from the native torus, bring it to the torus we
// are working with by dividing by the scaling factor and the encryption will take care
// of mapping that back to the native torus
*messages.get_mut(0).0 =
DecompositionTerm::new(level, decomp_base_log, *input_key_element)
.to_recomposition_summand()
.wrapping_div(ciphertext_modulus.get_power_of_two_scaling_to_native_torus());
}
encrypt_seeded_glwe_ciphertext_list_with_pre_seeded_generator(
output_glwe_sk,
&mut packing_keyswitch_key_block,
&decomposition_plaintexts_buffer,
noise_distribution,
generator,
);
}
}
/// Fill an [`LWE keyswitch key`](`SeededLwePackingKeyswitchKey`) with an actual keyswitching key
/// constructed from an input [`LWE secret key`](`LweSecretKey`) and an output
/// [`GLWE secret key`](`GlweSecretKey`).
@@ -281,74 +367,18 @@ pub fn generate_seeded_lwe_packing_keyswitch_key<
// Maybe Sized allows to pass Box<dyn Seeder>.
NoiseSeeder: Seeder + ?Sized,
{
assert!(
lwe_packing_keyswitch_key.input_key_lwe_dimension() == input_lwe_sk.lwe_dimension(),
"The destination LwePackingKeyswitchKey input LweDimension is not equal \
to the input LweSecretKey LweDimension. Destination: {:?}, input: {:?}",
lwe_packing_keyswitch_key.input_key_lwe_dimension(),
input_lwe_sk.lwe_dimension()
);
assert!(
lwe_packing_keyswitch_key.output_key_glwe_dimension() == output_glwe_sk.glwe_dimension(),
"The destination LwePackingKeyswitchKey output LweDimension is not equal \
to the output GlweSecretKey GlweDimension. Destination: {:?}, output: {:?}",
lwe_packing_keyswitch_key.output_key_glwe_dimension(),
output_glwe_sk.glwe_dimension()
);
assert!(
lwe_packing_keyswitch_key.output_key_polynomial_size() == output_glwe_sk.polynomial_size(),
"The destination LwePackingKeyswitchKey output PolynomialSize is not equal \
to the output GlweSecretKey PolynomialSize. Destination: {:?}, output: {:?}",
lwe_packing_keyswitch_key.output_key_polynomial_size(),
output_glwe_sk.polynomial_size()
);
let decomp_base_log = lwe_packing_keyswitch_key.decomposition_base_log();
let decomp_level_count = lwe_packing_keyswitch_key.decomposition_level_count();
let polynomial_size = lwe_packing_keyswitch_key.output_polynomial_size();
let ciphertext_modulus = lwe_packing_keyswitch_key.ciphertext_modulus();
assert!(ciphertext_modulus.is_compatible_with_native_modulus());
// The plaintexts used to encrypt a key element will be stored in this buffer
let mut decomposition_plaintexts_buffer = PlaintextListOwned::new(
Scalar::ZERO,
PlaintextCount(decomp_level_count.0 * polynomial_size.0),
);
let mut generator = EncryptionRandomGenerator::<DefaultRandomGenerator>::new(
lwe_packing_keyswitch_key.compression_seed().seed,
noise_seeder,
);
// Iterate over the input key elements and the destination lwe_packing_keyswitch_key memory
for (input_key_element, mut packing_keyswitch_key_block) in input_lwe_sk
.as_ref()
.iter()
.zip(lwe_packing_keyswitch_key.iter_mut())
{
// We fill the buffer with the powers of the key elements
for (level, mut messages) in (1..=decomp_level_count.0)
.map(DecompositionLevel)
.rev()
.zip(decomposition_plaintexts_buffer.chunks_exact_mut(polynomial_size.0))
{
// Here we take the decomposition term from the native torus, bring it to the torus we
// are working with by dividing by the scaling factor and the encryption will take care
// of mapping that back to the native torus
*messages.get_mut(0).0 =
DecompositionTerm::new(level, decomp_base_log, *input_key_element)
.to_recomposition_summand()
.wrapping_div(ciphertext_modulus.get_power_of_two_scaling_to_native_torus());
}
encrypt_seeded_glwe_ciphertext_list_with_pre_seeded_generator(
output_glwe_sk,
&mut packing_keyswitch_key_block,
&decomposition_plaintexts_buffer,
noise_distribution,
&mut generator,
);
}
generate_seeded_lwe_packing_keyswitch_key_with_pre_seeded_generator(
input_lwe_sk,
output_glwe_sk,
lwe_packing_keyswitch_key,
noise_distribution,
&mut generator,
)
}
/// Allocate a new [`seeded LWE keyswitch key`](`SeededLwePackingKeyswitchKey`) and fill it with an

View File

@@ -110,6 +110,14 @@ impl<G: ByteRandomGenerator> EncryptionRandomGenerator<G> {
}
}
#[cfg(all(feature = "integer", test))]
pub(crate) fn from_raw_parts(
mask: MaskRandomGenerator<G>,
noise: NoiseRandomGenerator<G>,
) -> Self {
Self { mask, noise }
}
/// Return the number of remaining bytes for the mask generator, if the generator is bounded.
pub fn remaining_bytes(&self) -> Option<usize> {
self.mask.remaining_bytes()

View File

@@ -3,6 +3,7 @@
use crate::conformance::ParameterSetConformant;
use crate::core_crypto::algorithms::*;
use crate::core_crypto::backward_compatibility::entities::seeded_lwe_packing_keyswitch_key::SeededLwePackingKeyswitchKeyVersions;
use crate::core_crypto::commons::generators::MaskRandomGenerator;
use crate::core_crypto::commons::math::random::{CompressionSeed, DefaultRandomGenerator};
use crate::core_crypto::commons::parameters::*;
use crate::core_crypto::commons::traits::*;
@@ -303,6 +304,35 @@ impl<Scalar: UnsignedInteger, C: Container<Element = Scalar>> SeededLwePackingKe
decompressed_pksk
}
/// Decompress the [`SeededLwePackingKeyswitchKey`] into [`LwePackingKeyswitchKey`]
/// without consuming `self`
pub fn decompress_to_lwe_packing_keyswitch_key_with_pre_seeded_generator<Gen>(
&self,
generator: &mut MaskRandomGenerator<Gen>,
) -> LwePackingKeyswitchKeyOwned<Scalar>
where
Scalar: UnsignedTorus,
Gen: ByteRandomGenerator,
{
let mut decompressed_pksk = LwePackingKeyswitchKeyOwned::new(
Scalar::ZERO,
self.decomposition_base_log(),
self.decomposition_level_count(),
self.input_key_lwe_dimension(),
self.output_key_glwe_dimension(),
self.output_key_polynomial_size(),
self.ciphertext_modulus(),
);
decompress_seeded_lwe_packing_keyswitch_key_with_pre_seeded_generator(
&mut decompressed_pksk,
self,
generator,
);
decompressed_pksk
}
pub fn as_seeded_glwe_ciphertext_list(&self) -> SeededGlweCiphertextListView<'_, Scalar> {
SeededGlweCiphertextListView::from_container(
self.as_ref(),

View File

@@ -46,7 +46,7 @@ macro_rules! export_concrete_array_types {
};
}
pub use crate::core_crypto::commons::math::random::Seed;
pub use crate::core_crypto::commons::math::random::{Seed, XofSeed};
pub use crate::integer::server_key::MatchValues;
use crate::{error, Error, Versionize};
use backward_compatibility::compressed_ciphertext_list::SquashedNoiseCiphertextStateVersions;
@@ -137,6 +137,7 @@ pub use re_randomization::{
pub use strings::ascii::{EncryptableString, FheAsciiString, FheStringIsEmpty, FheStringLen};
pub use tag::Tag;
pub use traits::FheId;
pub mod xof_key_set;
mod booleans;
mod compressed_ciphertext_list;

File diff suppressed because it is too large Load Diff

View File

@@ -49,6 +49,12 @@ impl Named for NoiseSquashingPrivateKey {
const NAME: &'static str = "integer::NoiseSquashingPrivateKey";
}
impl NoiseSquashingPrivateKey {
pub fn noise_squashing_parameters(&self) -> NoiseSquashingParameters {
self.key.noise_squashing_parameters()
}
}
impl CompressedNoiseSquashingKey {
pub fn decompress(&self) -> NoiseSquashingKey {
NoiseSquashingKey {

View File

@@ -120,6 +120,11 @@ 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
}

View File

@@ -109,12 +109,6 @@ pub struct CompressedNoiseSquashingKey {
output_ciphertext_modulus: CoreCiphertextModulus<u128>,
}
impl CompressedNoiseSquashingKey {
pub fn bootstrapping_key(&self) -> &CompressedShortint128BootstrappingKey {
&self.bootstrapping_key
}
}
impl ClientKey {
pub fn new_compressed_noise_squashing_key(
&self,
@@ -243,6 +237,10 @@ impl CompressedNoiseSquashingKey {
)
}
pub fn bootstrapping_key(&self) -> &CompressedShortint128BootstrappingKey {
&self.bootstrapping_key
}
pub fn message_modulus(&self) -> MessageModulus {
self.message_modulus
}