mirror of
https://github.com/zama-ai/tfhe-rs.git
synced 2026-01-08 22:28:01 -05:00
fix(tfhe): fix various docstring content and LweMask creation bug
This commit is contained in:
@@ -25,7 +25,7 @@ use crate::core_crypto::entities::*;
|
||||
///
|
||||
/// // DISCLAIMER: these toy example parameters are not guaranteed to be secure or yield correct
|
||||
/// // computations
|
||||
/// // Define parameters for GgswCiphertext creation
|
||||
/// // Define parameters for GlweCiphertext creation
|
||||
/// let glwe_size = GlweSize(2);
|
||||
/// let polynomial_size = PolynomialSize(1024);
|
||||
/// let glwe_modular_std_dev = StandardDev(0.00000000000000029403601535432533);
|
||||
@@ -157,7 +157,7 @@ pub fn encrypt_glwe_ciphertext_assign<Scalar, KeyCont, OutputCont, Gen>(
|
||||
///
|
||||
/// // DISCLAIMER: these toy example parameters are not guaranteed to be secure or yield correct
|
||||
/// // computations
|
||||
/// // Define parameters for GgswCiphertext creation
|
||||
/// // Define parameters for GlweCiphertext creation
|
||||
/// let glwe_size = GlweSize(2);
|
||||
/// let polynomial_size = PolynomialSize(1024);
|
||||
/// let glwe_modular_std_dev = StandardDev(0.00000000000000029403601535432533);
|
||||
@@ -187,8 +187,8 @@ pub fn encrypt_glwe_ciphertext_assign<Scalar, KeyCont, OutputCont, Gen>(
|
||||
///
|
||||
/// encrypt_glwe_ciphertext(
|
||||
/// &glwe_secret_key,
|
||||
/// &plaintext_list,
|
||||
/// &mut glwe,
|
||||
/// &plaintext_list,
|
||||
/// glwe_modular_std_dev,
|
||||
/// &mut encryption_generator,
|
||||
/// );
|
||||
@@ -217,8 +217,8 @@ pub fn encrypt_glwe_ciphertext_assign<Scalar, KeyCont, OutputCont, Gen>(
|
||||
/// ```
|
||||
pub fn encrypt_glwe_ciphertext<Scalar, KeyCont, InputCont, OutputCont, Gen>(
|
||||
glwe_secret_key: &GlweSecretKey<KeyCont>,
|
||||
input_plaintext_list: &PlaintextList<InputCont>,
|
||||
output_glwe_ciphertext: &mut GlweCiphertext<OutputCont>,
|
||||
input_plaintext_list: &PlaintextList<InputCont>,
|
||||
noise_parameters: impl DispersionParameter,
|
||||
generator: &mut EncryptionRandomGenerator<Gen>,
|
||||
) where
|
||||
@@ -287,7 +287,7 @@ pub fn encrypt_glwe_ciphertext<Scalar, KeyCont, InputCont, OutputCont, Gen>(
|
||||
///
|
||||
/// // DISCLAIMER: these toy example parameters are not guaranteed to be secure or yield correct
|
||||
/// // computations
|
||||
/// // Define parameters for GgswCiphertext creation
|
||||
/// // Define parameters for GlweCiphertext creation
|
||||
/// let glwe_size = GlweSize(2);
|
||||
/// let polynomial_size = PolynomialSize(1024);
|
||||
/// let glwe_modular_std_dev = StandardDev(0.00000000000000029403601535432533);
|
||||
@@ -397,8 +397,8 @@ pub fn encrypt_glwe_ciphertext_list<Scalar, KeyCont, InputCont, OutputCont, Gen>
|
||||
{
|
||||
encrypt_glwe_ciphertext(
|
||||
glwe_secret_key,
|
||||
&encoded,
|
||||
&mut ciphertext,
|
||||
&encoded,
|
||||
noise_parameters,
|
||||
generator,
|
||||
);
|
||||
@@ -408,6 +408,25 @@ pub fn encrypt_glwe_ciphertext_list<Scalar, KeyCont, InputCont, OutputCont, Gen>
|
||||
/// Decrypt a [`GLWE ciphertext`](`GlweCiphertext`) in a (scalar) plaintext list.
|
||||
///
|
||||
/// See [`encrypt_glwe_ciphertext`] for usage.
|
||||
///
|
||||
/// # Formal Definition
|
||||
///
|
||||
/// ## GLWE Decryption
|
||||
/// ###### inputs:
|
||||
/// - $\mathsf{CT} = \left( \vec{A} , B \right) \in \mathsf{GLWE}\_{\vec{S}}( \mathsf{PT} )\subseteq
|
||||
/// \mathcal{R}\_q^{k+1}$: an GLWE ciphertext
|
||||
/// - $\vec{S} \in\mathcal{R}\_q^k$: a secret key
|
||||
///
|
||||
/// ###### outputs:
|
||||
/// - $\mathsf{PT}\in\mathcal{R}\_q$: a plaintext
|
||||
///
|
||||
/// ###### algorithm:
|
||||
///
|
||||
/// 1. compute $\mathsf{PT} = B - \left\langle \vec{A} , \vec{S} \right\rangle \in\mathcal{R}\_q$
|
||||
/// 2. output $\mathsf{PT}$
|
||||
///
|
||||
/// **Remark:** Observe that the decryption is followed by a decoding phase that will contain a
|
||||
/// rounding.
|
||||
pub fn decrypt_glwe_ciphertext<Scalar, KeyCont, InputCont, OutputCont>(
|
||||
glwe_secret_key: &GlweSecretKey<KeyCont>,
|
||||
input_glwe_ciphertext: &GlweCiphertext<InputCont>,
|
||||
@@ -496,6 +515,7 @@ pub fn decrypt_glwe_ciphertext_list<Scalar, KeyCont, InputCont, OutputCont>(
|
||||
}
|
||||
|
||||
/// A trivial encryption uses a zero mask and no noise.
|
||||
///
|
||||
/// It is absolutely not secure, as the body contains a direct copy of the plaintext.
|
||||
/// However, it is useful for some FHE algorithms taking public information as input. For
|
||||
/// example, a trivial GLWE encryption of a public lookup table is used in the programmable
|
||||
@@ -503,7 +523,7 @@ pub fn decrypt_glwe_ciphertext_list<Scalar, KeyCont, InputCont, OutputCont>(
|
||||
///
|
||||
/// By definition a trivial encryption can be decrypted by any [`GLWE secret key`](`GlweSecretKey`).
|
||||
///
|
||||
/// Encrypt an input (scalar) plaintext list in a [`GLWE ciphertext`](`GlweCiphertext`).
|
||||
/// Trivially encrypt an input (scalar) plaintext list in a [`GLWE ciphertext`](`GlweCiphertext`).
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
@@ -516,7 +536,7 @@ pub fn decrypt_glwe_ciphertext_list<Scalar, KeyCont, InputCont, OutputCont>(
|
||||
///
|
||||
/// // DISCLAIMER: these toy example parameters are not guaranteed to be secure or yield correct
|
||||
/// // computations
|
||||
/// // Define parameters for GgswCiphertext creation
|
||||
/// // Define parameters for GlweCiphertext creation
|
||||
/// let glwe_size = GlweSize(2);
|
||||
/// let polynomial_size = PolynomialSize(1024);
|
||||
///
|
||||
@@ -580,6 +600,7 @@ pub fn trivially_encrypt_glwe_ciphertext<Scalar, InputCont, OutputCont>(
|
||||
}
|
||||
|
||||
/// A trivial encryption uses a zero mask and no noise.
|
||||
///
|
||||
/// It is absolutely not secure, as the body contains a direct copy of the plaintext.
|
||||
/// However, it is useful for some FHE algorithms taking public information as input. For
|
||||
/// example, a trivial GLWE encryption of a public lookup table is used in the programmable
|
||||
@@ -587,8 +608,8 @@ pub fn trivially_encrypt_glwe_ciphertext<Scalar, InputCont, OutputCont>(
|
||||
///
|
||||
/// By definition a trivial encryption can be decrypted by any [`GLWE secret key`](`GlweSecretKey`).
|
||||
///
|
||||
/// Allocate a new [`GLWE ciphertext`](`GlweCiphertext`) and encrypt an input (scalar) plaintext
|
||||
/// list in it.
|
||||
/// Allocate a new [`GLWE ciphertext`](`GlweCiphertext`) and trivially encrypt an input (scalar)
|
||||
/// plaintext list in it.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
@@ -601,7 +622,7 @@ pub fn trivially_encrypt_glwe_ciphertext<Scalar, InputCont, OutputCont>(
|
||||
///
|
||||
/// // DISCLAIMER: these toy example parameters are not guaranteed to be secure or yield correct
|
||||
/// // computations
|
||||
/// // Define parameters for GgswCiphertext creation
|
||||
/// // Define parameters for GlweCiphertext creation
|
||||
/// let glwe_size = GlweSize(2);
|
||||
/// let polynomial_size = PolynomialSize(1024);
|
||||
///
|
||||
|
||||
@@ -24,7 +24,7 @@ use crate::core_crypto::entities::*;
|
||||
///
|
||||
/// // DISCLAIMER: these toy example parameters are not guaranteed to be secure or yield correct
|
||||
/// // computations
|
||||
/// // Define parameters for GgswCiphertext creation
|
||||
/// // Define parameters for GlweCiphertext creation
|
||||
/// let glwe_size = GlweSize(2);
|
||||
/// let polynomial_size = PolynomialSize(1024);
|
||||
/// let glwe_modular_std_dev = StandardDev(0.00000000000000029403601535432533);
|
||||
@@ -57,8 +57,8 @@ use crate::core_crypto::entities::*;
|
||||
///
|
||||
/// encrypt_glwe_ciphertext(
|
||||
/// &glwe_secret_key,
|
||||
/// &plaintext_list,
|
||||
/// &mut glwe,
|
||||
/// &plaintext_list,
|
||||
/// glwe_modular_std_dev,
|
||||
/// &mut encryption_generator,
|
||||
/// );
|
||||
|
||||
@@ -39,7 +39,7 @@ where
|
||||
///
|
||||
/// // DISCLAIMER: these toy example parameters are not guaranteed to be secure or yield correct
|
||||
/// // computations
|
||||
/// // Define parameters for GgswCiphertext creation
|
||||
/// // Define parameters for GlweCiphertext creation
|
||||
/// let glwe_size = GlweSize(2);
|
||||
/// let polynomial_size = PolynomialSize(1024);
|
||||
///
|
||||
|
||||
@@ -101,6 +101,8 @@ where
|
||||
bsk
|
||||
}
|
||||
|
||||
/// Parallel variant of [`generate_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_lwe_bootstrap_key<Scalar, InputKeyCont, OutputKeyCont, OutputCont, Gen>(
|
||||
input_lwe_secret_key: &LweSecretKey<InputKeyCont>,
|
||||
output_glwe_secret_key: &GlweSecretKey<OutputKeyCont>,
|
||||
|
||||
@@ -117,6 +117,8 @@ pub fn generate_lwe_private_functional_packing_keyswitch_key<
|
||||
}
|
||||
}
|
||||
|
||||
/// Parallel variant of [`generate_lwe_private_functional_packing_keyswitch_key`]. You may want to
|
||||
/// use this variant for bette key generation times.
|
||||
pub fn par_generate_lwe_private_functional_packing_keyswitch_key<
|
||||
Scalar,
|
||||
InputKeyCont,
|
||||
@@ -186,7 +188,7 @@ pub fn par_generate_lwe_private_functional_packing_keyswitch_key<
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let palintext_count = PlaintextCount(
|
||||
let plaintext_count = PlaintextCount(
|
||||
lwe_pfpksk.decomposition_level_count().0 * lwe_pfpksk.output_polynomial_size().0,
|
||||
);
|
||||
|
||||
@@ -197,7 +199,7 @@ pub fn par_generate_lwe_private_functional_packing_keyswitch_key<
|
||||
.for_each(
|
||||
|((&input_key_bit, mut keyswitch_key_block), mut loop_generator)| {
|
||||
// We instantiate a buffer
|
||||
let mut messages = PlaintextListOwned::new(Scalar::ZERO, palintext_count);
|
||||
let mut messages = PlaintextListOwned::new(Scalar::ZERO, plaintext_count);
|
||||
|
||||
// We fill the buffer with the powers of the key bits
|
||||
for (level, mut message) in (1..=decomp_level_count.0)
|
||||
|
||||
@@ -233,19 +233,43 @@ impl<Scalar, C: Container<Element = Scalar>> GlweCiphertext<C> {
|
||||
/// let polynomial_size = PolynomialSize(1024);
|
||||
///
|
||||
/// // Create a new GlweCiphertext
|
||||
/// let glwe = GlweCiphertext::new(0u64, glwe_size, polynomial_size);
|
||||
/// let mut glwe = GlweCiphertext::new(0u64, glwe_size, polynomial_size);
|
||||
///
|
||||
/// assert_eq!(glwe.glwe_size(), glwe_size);
|
||||
/// assert_eq!(glwe.polynomial_size(), polynomial_size);
|
||||
/// assert_eq!(glwe.get_body().polynomial_size(), polynomial_size);
|
||||
/// assert_eq!(glwe.get_mut_body().polynomial_size(), polynomial_size);
|
||||
/// assert_eq!(
|
||||
/// glwe.get_mask().glwe_dimension(),
|
||||
/// glwe_size.to_glwe_dimension()
|
||||
/// );
|
||||
/// assert_eq!(
|
||||
/// glwe.get_mut_mask().glwe_dimension(),
|
||||
/// glwe_size.to_glwe_dimension()
|
||||
/// );
|
||||
/// assert_eq!(glwe.get_mask().polynomial_size(), polynomial_size);
|
||||
/// assert_eq!(glwe.get_mut_mask().polynomial_size(), polynomial_size);
|
||||
///
|
||||
/// // Demonstrate how to recover the allocated container
|
||||
/// let underlying_container: Vec<u64> = glwe.into_container();
|
||||
///
|
||||
/// // Recreate a ciphertext using from_container
|
||||
/// let glwe = GlweCiphertext::from_container(underlying_container, polynomial_size);
|
||||
/// let mut glwe = GlweCiphertext::from_container(underlying_container, polynomial_size);
|
||||
///
|
||||
/// assert_eq!(glwe.glwe_size(), glwe_size);
|
||||
/// assert_eq!(glwe.polynomial_size(), polynomial_size);
|
||||
/// assert_eq!(glwe.get_body().polynomial_size(), polynomial_size);
|
||||
/// assert_eq!(glwe.get_mut_body().polynomial_size(), polynomial_size);
|
||||
/// assert_eq!(
|
||||
/// glwe.get_mask().glwe_dimension(),
|
||||
/// glwe_size.to_glwe_dimension()
|
||||
/// );
|
||||
/// assert_eq!(
|
||||
/// glwe.get_mut_mask().glwe_dimension(),
|
||||
/// glwe_size.to_glwe_dimension()
|
||||
/// );
|
||||
/// assert_eq!(glwe.get_mask().polynomial_size(), polynomial_size);
|
||||
/// assert_eq!(glwe.get_mut_mask().polynomial_size(), polynomial_size);
|
||||
/// ```
|
||||
pub fn from_container(container: C, polynomial_size: PolynomialSize) -> GlweCiphertext<C> {
|
||||
assert!(
|
||||
@@ -293,6 +317,8 @@ impl<Scalar, C: Container<Element = Scalar>> GlweCiphertext<C> {
|
||||
}
|
||||
|
||||
/// Return an immutable view to the [`GlweBody`] of a [`GlweCiphertext`].
|
||||
///
|
||||
/// See [`GlweCiphertext::from_container`] for usage.
|
||||
pub fn get_body(&self) -> GlweBody<&[Scalar]> {
|
||||
let body = &self.data.as_ref()[glwe_ciphertext_mask_size(
|
||||
self.glwe_size().to_glwe_dimension(),
|
||||
@@ -303,6 +329,8 @@ impl<Scalar, C: Container<Element = Scalar>> GlweCiphertext<C> {
|
||||
}
|
||||
|
||||
/// Return an immutable view to the [`GlweMask`] of a [`GlweCiphertext`].
|
||||
///
|
||||
/// See [`GlweCiphertext::from_container`] for usage.
|
||||
pub fn get_mask(&self) -> GlweMask<&[Scalar]> {
|
||||
GlweMask::from_container(
|
||||
&self.as_ref()[0..glwe_ciphertext_mask_size(
|
||||
@@ -353,6 +381,8 @@ impl<Scalar, C: ContainerMut<Element = Scalar>> GlweCiphertext<C> {
|
||||
}
|
||||
|
||||
/// Mutable variant of [`GlweCiphertext::get_body`].
|
||||
///
|
||||
/// See [`GlweCiphertext::from_container`] for usage.
|
||||
pub fn get_mut_body(&mut self) -> GlweBody<&mut [Scalar]> {
|
||||
let glwe_dimension = self.glwe_size().to_glwe_dimension();
|
||||
let polynomial_size = self.polynomial_size();
|
||||
@@ -364,6 +394,8 @@ impl<Scalar, C: ContainerMut<Element = Scalar>> GlweCiphertext<C> {
|
||||
}
|
||||
|
||||
/// Mutable variant of [`GlweCiphertext::get_mask`].
|
||||
///
|
||||
/// See [`GlweCiphertext::from_container`] for usage.
|
||||
pub fn get_mut_mask(&mut self) -> GlweMask<&mut [Scalar]> {
|
||||
let polynomial_size = self.polynomial_size();
|
||||
let glwe_dimension = self.glwe_size().to_glwe_dimension();
|
||||
|
||||
@@ -25,9 +25,9 @@ impl<C: Container> LweMask<C> {
|
||||
/// // Define parameters for LweMask creation
|
||||
/// let lwe_dimension = LweDimension(600);
|
||||
///
|
||||
/// let lwe_body = LweMask::from_container(vec![0u64; lwe_dimension.0]);
|
||||
/// let lwe_mask = LweMask::from_container(vec![0u64; lwe_dimension.0]);
|
||||
///
|
||||
/// assert_eq!(lwe_body.lwe_dimension(), lwe_dimension);
|
||||
/// assert_eq!(lwe_mask.lwe_dimension(), lwe_dimension);
|
||||
/// ```
|
||||
pub fn from_container(container: C) -> Self {
|
||||
LweMask { data: container }
|
||||
@@ -110,17 +110,27 @@ impl<Scalar, C: Container<Element = Scalar>> LweCiphertext<C> {
|
||||
/// let lwe_size = LweSize(601);
|
||||
///
|
||||
/// // Create a new LweCiphertext
|
||||
/// let lwe = LweCiphertext::new(0u64, lwe_size);
|
||||
/// let mut lwe = LweCiphertext::new(0u64, lwe_size);
|
||||
///
|
||||
/// assert_eq!(lwe.lwe_size(), lwe_size);
|
||||
/// assert_eq!(lwe.get_mask().lwe_dimension(), lwe_size.to_lwe_dimension());
|
||||
/// assert_eq!(
|
||||
/// lwe.get_mut_mask().lwe_dimension(),
|
||||
/// lwe_size.to_lwe_dimension()
|
||||
/// );
|
||||
///
|
||||
/// // Demonstrate how to recover the allocated container
|
||||
/// let underlying_container: Vec<u64> = lwe.into_container();
|
||||
///
|
||||
/// // Recreate a ciphertext using from_container
|
||||
/// let lwe = LweCiphertext::from_container(underlying_container);
|
||||
/// let mut lwe = LweCiphertext::from_container(underlying_container);
|
||||
///
|
||||
/// assert_eq!(lwe.lwe_size(), lwe_size);
|
||||
/// assert_eq!(lwe.get_mask().lwe_dimension(), lwe_size.to_lwe_dimension());
|
||||
/// assert_eq!(
|
||||
/// lwe.get_mut_mask().lwe_dimension(),
|
||||
/// lwe_size.to_lwe_dimension()
|
||||
/// );
|
||||
/// ```
|
||||
pub fn from_container(container: C) -> LweCiphertext<C> {
|
||||
assert!(
|
||||
@@ -152,8 +162,10 @@ impl<Scalar, C: Container<Element = Scalar>> LweCiphertext<C> {
|
||||
}
|
||||
|
||||
/// Return an immutable view to the [`LweMask`] of an [`LweCiphertext`].
|
||||
///
|
||||
/// See [`LweCiphertext::from_container`] for usage.
|
||||
pub fn get_mask(&self) -> LweMask<&[Scalar]> {
|
||||
LweMask::from_container(&self.as_ref()[0..=self.lwe_size().to_lwe_dimension().0])
|
||||
LweMask::from_container(&self.as_ref()[0..self.lwe_size().to_lwe_dimension().0])
|
||||
}
|
||||
|
||||
/// Return a view of the [`LweCiphertext`]. This is useful if an algorithm takes a view by
|
||||
@@ -186,9 +198,11 @@ impl<Scalar, C: ContainerMut<Element = Scalar>> LweCiphertext<C> {
|
||||
}
|
||||
|
||||
/// Mutable variant of [`LweCiphertext::get_mask`].
|
||||
///
|
||||
/// See [`LweCiphertext::from_container`] for usage.
|
||||
pub fn get_mut_mask(&mut self) -> LweMask<&mut [Scalar]> {
|
||||
let lwe_dimension = self.lwe_size().to_lwe_dimension();
|
||||
LweMask::from_container(&mut self.as_mut()[0..=lwe_dimension.0])
|
||||
LweMask::from_container(&mut self.as_mut()[0..lwe_dimension.0])
|
||||
}
|
||||
|
||||
/// Mutable variant of [`LweCiphertext::as_view`].
|
||||
|
||||
@@ -32,7 +32,7 @@ impl<Scalar, C: Container<Element = Scalar>> PlaintextList<C> {
|
||||
/// ```
|
||||
/// use tfhe::core_crypto::prelude::*;
|
||||
///
|
||||
/// // Define parameters for LweSecretKey creation
|
||||
/// // Define parameters for PlaintextList creation
|
||||
/// let plaintext_count = PlaintextCount(1024);
|
||||
///
|
||||
/// // Create a new PlaintextList
|
||||
|
||||
Reference in New Issue
Block a user