fix(tfhe): fix various docstring content and LweMask creation bug

This commit is contained in:
Arthur Meyre
2022-12-09 20:14:29 +01:00
committed by jborfila
parent 3a2434b5ff
commit f792cc2737
8 changed files with 96 additions and 25 deletions

View File

@@ -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);
///

View File

@@ -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,
/// );

View File

@@ -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);
///

View File

@@ -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>,

View File

@@ -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)

View File

@@ -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();

View File

@@ -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`].

View File

@@ -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