diff --git a/tfhe/src/core_crypto/algorithms/ggsw_encryption.rs b/tfhe/src/core_crypto/algorithms/ggsw_encryption.rs index 297f5112b..708ee6ec5 100644 --- a/tfhe/src/core_crypto/algorithms/ggsw_encryption.rs +++ b/tfhe/src/core_crypto/algorithms/ggsw_encryption.rs @@ -184,7 +184,7 @@ fn encrypt_ggsw_level_matrix_row( let mut body = row_as_glwe.get_mut_body(); body.as_mut().copy_from_slice(sk_poly.as_ref()); - update_slice_with_wrapping_scalar_mul(body.as_mut(), factor); + slice_wrapping_scalar_mul_assign(body.as_mut(), factor); encrypt_glwe_ciphertext_in_place(glwe_secret_key, row_as_glwe, noise_parameters, generator); } else { diff --git a/tfhe/src/core_crypto/algorithms/glwe_encryption.rs b/tfhe/src/core_crypto/algorithms/glwe_encryption.rs index fa04369c2..e4e249934 100644 --- a/tfhe/src/core_crypto/algorithms/glwe_encryption.rs +++ b/tfhe/src/core_crypto/algorithms/glwe_encryption.rs @@ -37,7 +37,7 @@ pub fn encrypt_glwe_ciphertext_in_place( generator.update_slice_with_wrapping_add_random_noise(body.as_mut(), noise_parameters); - update_polynomial_with_wrapping_add_multisum( + polynomial_wrapping_add_multisum_assign( &mut body.as_mut_polynomial(), &mask.as_polynomial_list(), &glwe_secret_key.as_polynomial_list(), @@ -85,12 +85,12 @@ pub fn encrypt_glwe_ciphertext( generator.fill_slice_with_random_noise(body.as_mut(), noise_parameters); - update_polynomial_with_wrapping_add( + polynomial_wrapping_add_assign( &mut body.as_mut_polynomial(), &input_plaintext_list.as_polynomial(), ); - update_polynomial_with_wrapping_add_multisum( + polynomial_wrapping_add_multisum_assign( &mut body.as_mut_polynomial(), &mask.as_polynomial_list(), &glwe_secret_key.as_polynomial_list(), @@ -186,7 +186,7 @@ pub fn decrypt_glwe_ciphertext( output_plaintext_list .as_mut() .copy_from_slice(body.as_ref()); - update_polynomial_with_wrapping_sub_multisum( + polynomial_wrapping_sub_multisum_assign( &mut output_plaintext_list.as_mut_polynomial(), &mask.as_polynomial_list(), &glwe_secret_key.as_polynomial_list(), diff --git a/tfhe/src/core_crypto/algorithms/glwe_sample_extraction.rs b/tfhe/src/core_crypto/algorithms/glwe_sample_extraction.rs index 5c3b22462..936a54e6b 100644 --- a/tfhe/src/core_crypto/algorithms/glwe_sample_extraction.rs +++ b/tfhe/src/core_crypto/algorithms/glwe_sample_extraction.rs @@ -41,7 +41,7 @@ pub fn extract_lwe_sample_from_glwe_ciphertext( // We reverse the polynomial lwe_mask_poly.reverse(); // We compute the opposite of the proper coefficients - update_slice_with_wrapping_opposite(&mut lwe_mask_poly[0..opposite_count]); + slice_wrapping_opposite_assign(&mut lwe_mask_poly[0..opposite_count]); // We rotate the polynomial properly lwe_mask_poly.rotate_left(opposite_count); } diff --git a/tfhe/src/core_crypto/algorithms/lwe_keyswitch.rs b/tfhe/src/core_crypto/algorithms/lwe_keyswitch.rs index 393331590..f417f4f3c 100644 --- a/tfhe/src/core_crypto/algorithms/lwe_keyswitch.rs +++ b/tfhe/src/core_crypto/algorithms/lwe_keyswitch.rs @@ -32,10 +32,7 @@ pub fn keyswitch_lwe_ciphertext( ); // Clear the output ciphertext, as it will get updated gradually - output_lwe_ciphertext - .as_mut() - .iter_mut() - .for_each(|elt| *elt = Scalar::ZERO); + output_lwe_ciphertext.as_mut().fill(Scalar::ZERO); // Copy the input body to the output ciphertext *output_lwe_ciphertext.get_mut_body().0 = *input_lwe_ciphertext.get_body().0; @@ -55,7 +52,7 @@ pub fn keyswitch_lwe_ciphertext( for (level_key_ciphertext, decomposed) in keyswitch_key_block.iter().rev().zip(decomposition_iter) { - update_slice_with_wrapping_sub_scalar_mul( + slice_wrapping_sub_scalar_mul_assign( output_lwe_ciphertext.as_mut(), level_key_ciphertext.as_ref(), decomposed.value(), diff --git a/tfhe/src/core_crypto/algorithms/lwe_linear_algebra.rs b/tfhe/src/core_crypto/algorithms/lwe_linear_algebra.rs index 00492bdb3..77769740e 100644 --- a/tfhe/src/core_crypto/algorithms/lwe_linear_algebra.rs +++ b/tfhe/src/core_crypto/algorithms/lwe_linear_algebra.rs @@ -14,7 +14,7 @@ pub fn lwe_ciphertext_in_place_addition( LhsCont: ContainerMut, RhsCont: Container, { - update_slice_with_wrapping_add(lhs.as_mut(), rhs.as_ref()); + slice_wrapping_add_assign(lhs.as_mut(), rhs.as_ref()); } pub fn lwe_ciphertext_addition( @@ -47,7 +47,7 @@ where Scalar: UnsignedInteger, InCont: ContainerMut, { - update_slice_with_wrapping_opposite(ct.as_mut()); + slice_wrapping_opposite_assign(ct.as_mut()); } pub fn lwe_ciphertext_in_place_cleartext_multiplication( @@ -57,7 +57,7 @@ pub fn lwe_ciphertext_in_place_cleartext_multiplication( Scalar: UnsignedInteger, InCont: ContainerMut, { - update_slice_with_wrapping_scalar_mul(lhs.as_mut(), rhs.0); + slice_wrapping_scalar_mul_assign(lhs.as_mut(), rhs.0); } pub fn lwe_ciphertext_in_place_subtraction( @@ -68,7 +68,7 @@ pub fn lwe_ciphertext_in_place_subtraction( LhsCont: ContainerMut, RhsCont: Container, { - update_slice_with_wrapping_sub(lhs.as_mut(), rhs.as_ref()); + slice_wrapping_sub_assign(lhs.as_mut(), rhs.as_ref()); } pub fn lwe_ciphertext_cleartext_multiplication( diff --git a/tfhe/src/core_crypto/algorithms/lwe_private_functional_packing_keyswitch.rs b/tfhe/src/core_crypto/algorithms/lwe_private_functional_packing_keyswitch.rs index bc1fa41d6..cc9a394db 100644 --- a/tfhe/src/core_crypto/algorithms/lwe_private_functional_packing_keyswitch.rs +++ b/tfhe/src/core_crypto/algorithms/lwe_private_functional_packing_keyswitch.rs @@ -49,7 +49,7 @@ pub fn private_functional_keyswitch_lwe_ciphertext_into_glwe_ciphertext< // We compute the multiplication of a ciphertext from the private functional // keyswitching key with a piece of the decomposition and subtract it to the buffer for (level_key_cipher, decomposed) in keyswitch_key_block.iter().rev().zip(decomp) { - update_slice_with_wrapping_sub_scalar_mul( + slice_wrapping_sub_scalar_mul_assign( output_glwe_ciphertext.as_mut(), level_key_cipher.as_ref(), decomposed.value(), @@ -87,11 +87,8 @@ pub fn private_functional_keyswitch_lwe_ciphertext_list_and_pack_in_glwe_ciphere .as_mut_polynomial_list() .iter_mut() .for_each(|mut poly| { - update_polynomial_with_wrapping_monic_monomial_mul( - &mut poly, - MonomialDegree(degree), - ) + polynomial_wrapping_monic_monomial_mul_assign(&mut poly, MonomialDegree(degree)) }); - update_slice_with_wrapping_add(output.as_mut(), buffer.as_ref()); + slice_wrapping_add_assign(output.as_mut(), buffer.as_ref()); } } diff --git a/tfhe/src/core_crypto/algorithms/lwe_private_functional_packing_keyswitch_key_generation.rs b/tfhe/src/core_crypto/algorithms/lwe_private_functional_packing_keyswitch_key_generation.rs index 431211d73..e57a0131e 100644 --- a/tfhe/src/core_crypto/algorithms/lwe_private_functional_packing_keyswitch_key_generation.rs +++ b/tfhe/src/core_crypto/algorithms/lwe_private_functional_packing_keyswitch_key_generation.rs @@ -94,7 +94,7 @@ pub fn generate_lwe_private_functional_packing_keyswitch_key< .map(DecompositionLevel) .zip(messages.chunks_exact_mut(polynomial_size.0)) { - update_slice_with_wrapping_add_scalar_mul( + slice_wrapping_add_scalar_mul_assign( message.as_mut(), polynomial.as_ref(), DecompositionTerm::new( @@ -204,7 +204,7 @@ pub fn par_generate_lwe_private_functional_packing_keyswitch_key< .map(DecompositionLevel) .zip(messages.chunks_exact_mut(polynomial_size.0)) { - update_slice_with_wrapping_add_scalar_mul( + slice_wrapping_add_scalar_mul_assign( message.as_mut(), polynomial.as_ref(), DecompositionTerm::new( diff --git a/tfhe/src/core_crypto/algorithms/polynomial_algorithms.rs b/tfhe/src/core_crypto/algorithms/polynomial_algorithms.rs index 6ed9cac4e..89e2013bd 100644 --- a/tfhe/src/core_crypto/algorithms/polynomial_algorithms.rs +++ b/tfhe/src/core_crypto/algorithms/polynomial_algorithms.rs @@ -1,11 +1,17 @@ +//! Module providing algorithms to perform computations on polynomials modulo $X^{N} + 1$. + use crate::core_crypto::algorithms::slice_algorithms::*; use crate::core_crypto::commons::numeric::UnsignedInteger; use crate::core_crypto::commons::parameters::MonomialDegree; use crate::core_crypto::commons::traits::*; use crate::core_crypto::entities::*; -/// Adds a polynomial with unsinged integers coefficients to another one in place, wrapping around -/// (similar to computing modulo $$2^{n\_bits}$$) when exceeding the unsigned integer capacity. +/// Adds a polynomial to the output polynomial. +/// +/// # Note +/// +/// Computations wrap around (similar to computing modulo $2^{n\_{bits}}$) when exceeding the +/// unsigned integer capacity. /// /// # Example /// @@ -14,10 +20,10 @@ use crate::core_crypto::entities::*; /// use tfhe::core_crypto::entities::*; /// let mut first = Polynomial::from_container(vec![1u8, 2, 3, 4, 5, 6]); /// let second = Polynomial::from_container(vec![255u8, 255, 255, 1, 2, 3]); -/// update_polynomial_with_wrapping_add(&mut first, &second); +/// polynomial_wrapping_add_assign(&mut first, &second); /// assert_eq!(first.as_ref(), &[0u8, 1, 2, 5, 7, 9]); /// ``` -pub fn update_polynomial_with_wrapping_add( +pub fn polynomial_wrapping_add_assign( lhs: &mut Polynomial, rhs: &Polynomial, ) where @@ -26,11 +32,11 @@ pub fn update_polynomial_with_wrapping_add( InputCont: Container, { assert_eq!(lhs.polynomial_size(), rhs.polynomial_size()); - update_slice_with_wrapping_add(lhs.as_mut(), rhs.as_ref()) + slice_wrapping_add_assign(lhs.as_mut(), rhs.as_ref()) } -/// Adds the sum of the element-wise product between two lists of unsigned integer polynomial to the -/// output polynomial. +/// Adds the sum of the element-wise product between two lists of polynomials to the output +/// polynomial. /// /// I.e., if the output polynomial is $C(X)$, for a collection of polynomials $(P\_i(X)))\_i$ /// and another collection of polynomials $(B\_i(X))\_i$ we perform the operation: @@ -38,6 +44,11 @@ pub fn update_polynomial_with_wrapping_add( /// C(X) := C(X) + \sum\_i P\_i(X) \times B\_i(X) mod (X^{N} + 1) /// $$ /// +/// # Note +/// +/// Computations wrap around (similar to computing modulo $2^{n\_{bits}}$) when exceeding the +/// unsigned integer capacity. +/// /// # Example /// /// ``` @@ -47,10 +58,10 @@ pub fn update_polynomial_with_wrapping_add( /// let poly_list = PolynomialList::from_container(vec![100_u8, 20, 3, 4, 5, 6], PolynomialSize(3)); /// let bin_poly_list = PolynomialList::from_container(vec![0, 1, 1, 1, 0, 0], PolynomialSize(3)); /// let mut output = Polynomial::new(250, PolynomialSize(3)); -/// update_polynomial_with_wrapping_add_multisum(&mut output, &poly_list, &bin_poly_list); +/// polynomial_wrapping_add_multisum_assign(&mut output, &poly_list, &bin_poly_list); /// assert_eq!(output.as_ref(), &[231, 96, 120]); /// ``` -pub fn update_polynomial_with_wrapping_add_multisum( +pub fn polynomial_wrapping_add_multisum_assign( output: &mut Polynomial, poly_list_1: &PolynomialList, poly_list_2: &PolynomialList, @@ -61,12 +72,17 @@ pub fn update_polynomial_with_wrapping_add_multisum, { for (poly_1, poly_2) in poly_list_1.iter().zip(poly_list_2.iter()) { - update_polynomial_with_wrapping_add_mul(output, &poly_1, &poly_2); + polynomial_wrapping_add_mul_assign(output, &poly_1, &poly_2); } } -/// Adds the result of the product between two integer polynomials, reduced modulo $(X^{N}+1)$, -/// to the output polynomial. +/// Adds the result of the product between two polynomials, reduced modulo $(X^{N}+1)$, to the +/// output polynomial. +/// +/// # Note +/// +/// Computations wrap around (similar to computing modulo $2^{n\_{bits}}$) when exceeding the +/// unsigned integer capacity. /// /// # Example /// @@ -76,10 +92,10 @@ pub fn update_polynomial_with_wrapping_add_multisum( +pub fn polynomial_wrapping_add_mul_assign( output: &mut Polynomial, lhs: &Polynomial, rhs: &Polynomial, @@ -126,6 +142,11 @@ pub fn update_polynomial_with_wrapping_add_mul( +pub fn polynomial_wrapping_monic_monomial_div_assign( output: &mut Polynomial, monomial_degree: MonomialDegree, ) where @@ -163,6 +184,11 @@ pub fn update_polynomial_with_wrapping_monic_monomial_div( /// Multiplies (mod $(X^{N}+1)$), the output polynomial with a monic monomial of a given degree i.e. /// $X^{degree}$. /// +/// # Note +/// +/// Computations wrap around (similar to computing modulo $2^{n\_{bits}}$) when exceeding the +/// unsigned integer capacity. +/// /// # Examples /// /// ``` @@ -170,10 +196,10 @@ pub fn update_polynomial_with_wrapping_monic_monomial_div( /// use tfhe::core_crypto::commons::parameters::*; /// use tfhe::core_crypto::entities::*; /// let mut poly = Polynomial::from_container(vec![1u8, 2, 3]); -/// update_polynomial_with_wrapping_monic_monomial_mul(&mut poly, MonomialDegree(2)); +/// polynomial_wrapping_monic_monomial_mul_assign(&mut poly, MonomialDegree(2)); /// assert_eq!(poly.as_ref(), &[254, 253, 1]); /// ``` -pub fn update_polynomial_with_wrapping_monic_monomial_mul( +pub fn polynomial_wrapping_monic_monomial_mul_assign( output: &mut Polynomial, monomial_degree: MonomialDegree, ) where @@ -196,8 +222,8 @@ pub fn update_polynomial_with_wrapping_monic_monomial_mul( .for_each(|a| *a = a.wrapping_neg()); } -/// Subtracts the sum of the element-wise product between two lists of integer polynomials, -/// to the output polynomial. +/// Subtracts the sum of the element-wise product between two lists of polynomials, to the output +/// polynomial. /// /// I.e., if the output polynomial is $C(X)$, for two lists of polynomials $(P\_i(X)))\_i$ and /// $(B\_i(X))\_i$ we perform the operation: @@ -205,6 +231,11 @@ pub fn update_polynomial_with_wrapping_monic_monomial_mul( /// C(X) := C(X) + \sum\_i P\_i(X) \times B\_i(X) mod (X^{N} + 1) /// $$ /// +/// # Note +/// +/// Computations wrap around (similar to computing modulo $2^{n\_{bits}}$) when exceeding the +/// unsigned integer capacity. +/// /// # Example /// /// ``` @@ -215,10 +246,10 @@ pub fn update_polynomial_with_wrapping_monic_monomial_mul( /// PolynomialList::from_container(vec![100 as u8, 20, 3, 4, 5, 6], PolynomialSize(3)); /// let bin_poly_list = PolynomialList::from_container(vec![0, 1, 1, 1, 0, 0], PolynomialSize(3)); /// let mut output = Polynomial::new(250 as u8, PolynomialSize(3)); -/// update_polynomial_with_wrapping_sub_multisum(&mut output, &poly_list, &bin_poly_list); +/// polynomial_wrapping_sub_multisum_assign(&mut output, &poly_list, &bin_poly_list); /// assert_eq!(output.as_ref(), &[13, 148, 124]); /// ``` -pub fn update_polynomial_with_wrapping_sub_multisum( +pub fn polynomial_wrapping_sub_multisum_assign( output: &mut Polynomial, poly_list_1: &PolynomialList, poly_list_2: &PolynomialList, @@ -229,12 +260,17 @@ pub fn update_polynomial_with_wrapping_sub_multisum, { for (poly_1, poly_2) in poly_list_1.iter().zip(poly_list_2.iter()) { - update_polynomial_with_wrapping_sub_mul(output, &poly_1, &poly_2); + polynomial_wrapping_sub_mul_assign(output, &poly_1, &poly_2); } } -/// Subtracts the result of the product between two integer polynomials, reduced modulo $(X^{N}+1)$, -/// to the output polynomial. +/// Subtracts the result of the product between two polynomials, reduced modulo $(X^{N}+1)$, to the +/// output polynomial. +/// +/// # Note +/// +/// Computations wrap around (similar to computing modulo $2^{n\_{bits}}$) when exceeding the +/// unsigned integer capacity. /// /// # Example /// @@ -244,10 +280,10 @@ pub fn update_polynomial_with_wrapping_sub_multisum( +pub fn polynomial_wrapping_sub_mul_assign( output: &mut Polynomial, lhs: &Polynomial, rhs: &Polynomial, @@ -321,8 +357,8 @@ mod test { r %= polynomial_size; // multiply by X^r and then divides by X^r - update_polynomial_with_wrapping_monic_monomial_mul(&mut poly, MonomialDegree(r)); - update_polynomial_with_wrapping_monic_monomial_div(&mut poly, MonomialDegree(r)); + polynomial_wrapping_monic_monomial_mul_assign(&mut poly, MonomialDegree(r)); + polynomial_wrapping_monic_monomial_div_assign(&mut poly, MonomialDegree(r)); // test assert_eq!(&poly, &ground_truth); @@ -332,15 +368,15 @@ mod test { r_big = r_big % polynomial_size + 2048; // multiply by X^r_big and then divides by X^r_big - update_polynomial_with_wrapping_monic_monomial_mul(&mut poly, MonomialDegree(r_big)); - update_polynomial_with_wrapping_monic_monomial_div(&mut poly, MonomialDegree(r_big)); + polynomial_wrapping_monic_monomial_mul_assign(&mut poly, MonomialDegree(r_big)); + polynomial_wrapping_monic_monomial_div_assign(&mut poly, MonomialDegree(r_big)); // test assert_eq!(&poly, &ground_truth); // divides by X^r_big and then multiply by X^r_big - update_polynomial_with_wrapping_monic_monomial_mul(&mut poly, MonomialDegree(r_big)); - update_polynomial_with_wrapping_monic_monomial_div(&mut poly, MonomialDegree(r_big)); + polynomial_wrapping_monic_monomial_mul_assign(&mut poly, MonomialDegree(r_big)); + polynomial_wrapping_monic_monomial_div_assign(&mut poly, MonomialDegree(r_big)); // test assert_eq!(&poly, &ground_truth); diff --git a/tfhe/src/core_crypto/algorithms/slice_algorithms.rs b/tfhe/src/core_crypto/algorithms/slice_algorithms.rs index 07ded5c87..b7728af65 100644 --- a/tfhe/src/core_crypto/algorithms/slice_algorithms.rs +++ b/tfhe/src/core_crypto/algorithms/slice_algorithms.rs @@ -1,8 +1,13 @@ +//! Module providing algorithms to perform computations on raw slices. + use crate::core_crypto::commons::numeric::UnsignedInteger; -/// Computes a dot product between two slices containing unsigned integers, wrapping -/// around (similar to computing modulo $$2^{n\_bits}$$) when exceeding the unsigned integer -/// capacity. +/// Computes a dot product between two slices containing unsigned integers. +/// +/// # Note +/// +/// Computations wrap around (similar to computing modulo $2^{n\_{bits}}$) when exceeding the +/// unsigned integer capacity. /// /// # Example /// @@ -31,9 +36,12 @@ where }) } -/// Adds a slice containing unsigned integers to another one element-wise, wrapping -/// around (similar to computing modulo $$2^{n\_bits}$$) when exceeding the unsigned integer -/// capacity. +/// Adds a slice containing unsigned integers to another one element-wise. +/// +/// # Note +/// +/// Computations wrap around (similar to computing modulo $2^{n\_{bits}}$) when exceeding the +/// unsigned integer capacity. /// /// # Example /// @@ -68,9 +76,12 @@ where .for_each(|(out, (&lhs, &rhs))| *out = lhs.wrapping_add(rhs)); } -/// Adds a slice containing unsigned integers to another one element-wise and in place, wrapping -/// around (similar to computing modulo $$2^{n\_bits}$$) when exceeding the unsigned integer -/// capacity. +/// Adds a slice containing unsigned integers to another one element-wise and in place. +/// +/// # Note +/// +/// Computations wrap around (similar to computing modulo $2^{n\_{bits}}$) when exceeding the +/// unsigned integer capacity. /// /// # Example /// @@ -78,10 +89,10 @@ where /// use tfhe::core_crypto::algorithms::slice_algorithms::*; /// let mut first = vec![1u8, 2, 3, 4, 5, 6]; /// let second = vec![255u8, 255, 255, 1, 2, 3]; -/// update_slice_with_wrapping_add(&mut first, &second); +/// slice_wrapping_add_assign(&mut first, &second); /// assert_eq!(&first, &[0u8, 1, 2, 5, 7, 9]); /// ``` -pub fn update_slice_with_wrapping_add(lhs: &mut [Scalar], rhs: &[Scalar]) +pub fn slice_wrapping_add_assign(lhs: &mut [Scalar], rhs: &[Scalar]) where Scalar: UnsignedInteger, { @@ -97,10 +108,14 @@ where .for_each(|(lhs, &rhs)| *lhs = (*lhs).wrapping_add(rhs)); } -/// Adds a slice containing unsigned integers to another one mutiplied by a scalar, element-wise and -/// in place, wrapping around (similar to computing modulo $$2^{n\_bits}$$) when exceeding the -/// unsigned integer capacity. Let *a*,*b* be two slices, let *c* be a scalar, this computes: -/// *a <- a+bc* +/// Adds a slice containing unsigned integers to another one mutiplied by a scalar. +/// +/// Let *a*,*b* be two slices, let *c* be a scalar, this computes: *a <- a+bc* +/// +/// # Note +/// +/// Computations wrap around (similar to computing modulo $2^{n\_{bits}}$) when exceeding the +/// unsigned integer capacity. /// /// # Example /// @@ -109,10 +124,10 @@ where /// let mut first = vec![1u8, 2, 3, 4, 5, 6]; /// let second = vec![255u8, 255, 255, 1, 2, 3]; /// let scalar = 4u8; -/// update_slice_with_wrapping_add_scalar_mul(&mut first, &second, scalar); +/// slice_wrapping_add_scalar_mul_assign(&mut first, &second, scalar); /// assert_eq!(&first, &[253u8, 254, 255, 8, 13, 18]); /// ``` -pub fn update_slice_with_wrapping_add_scalar_mul( +pub fn slice_wrapping_add_scalar_mul_assign( lhs: &mut [Scalar], rhs: &[Scalar], scalar: Scalar, @@ -130,9 +145,12 @@ pub fn update_slice_with_wrapping_add_scalar_mul( .for_each(|(lhs, &rhs)| *lhs = (*lhs).wrapping_add(rhs.wrapping_mul(scalar))); } -/// Subtracts a slice containing unsigned integers to another one, element-wise and in place, -/// wrapping around (similar to computing modulo $$2^{n\_bits}$$) when exceeding the unsigned -/// integer capacity. +/// Subtracts a slice containing unsigned integers to another one, element-wise and in place. +/// +/// # Note +/// +/// Computations wrap around (similar to computing modulo $2^{n\_{bits}}$) when exceeding the +/// unsigned integer capacity. /// /// # Example /// @@ -140,10 +158,10 @@ pub fn update_slice_with_wrapping_add_scalar_mul( /// use tfhe::core_crypto::algorithms::slice_algorithms::*; /// let mut first = vec![1u8, 2, 3, 4, 5, 6]; /// let second = vec![255u8, 255, 255, 1, 2, 3]; -/// update_slice_with_wrapping_sub(&mut first, &second); +/// slice_wrapping_sub_assign(&mut first, &second); /// assert_eq!(&first, &[2u8, 3, 4, 3, 3, 3]); /// ``` -pub fn update_slice_with_wrapping_sub(lhs: &mut [Scalar], rhs: &[Scalar]) +pub fn slice_wrapping_sub_assign(lhs: &mut [Scalar], rhs: &[Scalar]) where Scalar: UnsignedInteger, { @@ -160,9 +178,14 @@ where } /// Subtracts a slice containing unsigned integers to another one mutiplied by a scalar, -/// element-wise and in place, wrapping around (similar to computing modulo $$2^{n\_bits}$$) when -/// exceeding the unsigned integer capacity. Let *a*,*b* be two slices, let *c* be a scalar, this -/// computes: *a <- a-bc* +/// element-wise and in place. +/// +/// Let *a*,*b* be two slices, let *c* be a scalar, this computes: *a <- a-bc* +/// +/// # Note +/// +/// Computations wrap around (similar to computing modulo $2^{n\_{bits}}$) when exceeding the +/// unsigned integer capacity. /// /// # Example /// @@ -171,9 +194,9 @@ where /// let mut first = vec![1u8, 2, 3, 4, 5, 6]; /// let second = vec![255u8, 255, 255, 1, 2, 3]; /// let scalar = 4u8; -/// update_slice_with_wrapping_sub_scalar_mul(&mut first, &second, scalar); +/// slice_wrapping_sub_scalar_mul_assign(&mut first, &second, scalar); /// assert_eq!(&first, &[5u8, 6, 7, 0, 253, 250]); -pub fn update_slice_with_wrapping_sub_scalar_mul( +pub fn slice_wrapping_sub_scalar_mul_assign( lhs: &mut [Scalar], rhs: &[Scalar], scalar: Scalar, @@ -191,19 +214,22 @@ pub fn update_slice_with_wrapping_sub_scalar_mul( .for_each(|(lhs, &rhs)| *lhs = (*lhs).wrapping_sub(rhs.wrapping_mul(scalar))); } -/// Computes the opposite of a slice containing unsigned integers, element-wise and in place, -/// wrapping around (similar to computing modulo $$2^{n\_bits}$$) when exceeding the unsigned -/// integer capacity. +/// Computes the opposite of a slice containing unsigned integers, element-wise and in place. +/// +/// # Note +/// +/// Computations wrap around (similar to computing modulo $2^{n\_{bits}}$) when exceeding the +/// unsigned integer capacity. /// /// # Example /// /// ``` /// use tfhe::core_crypto::algorithms::slice_algorithms::*; /// let mut first = vec![1u8, 2, 3, 4, 5, 6]; -/// update_slice_with_wrapping_opposite(&mut first); +/// slice_wrapping_opposite_assign(&mut first); /// assert_eq!(&first, &[255u8, 254, 253, 252, 251, 250]); /// ``` -pub fn update_slice_with_wrapping_opposite(slice: &mut [Scalar]) +pub fn slice_wrapping_opposite_assign(slice: &mut [Scalar]) where Scalar: UnsignedInteger, { @@ -212,9 +238,12 @@ where .for_each(|elt| *elt = (*elt).wrapping_neg()); } -/// Multiplies a slice containing unsigned integers by a scalar, element-wise and in place, wrapping -/// around (similar to computing modulo $$2^{n\_bits}$$) when exceeding the unsigned integer -/// capacity. +/// Multiplies a slice containing unsigned integers by a scalar, element-wise and in place. +/// +/// # Note +/// +/// Computations wrap around (similar to computing modulo $2^{n\_{bits}}$) when exceeding the +/// unsigned integer capacity. /// /// # Example /// @@ -222,10 +251,10 @@ where /// use tfhe::core_crypto::algorithms::slice_algorithms::*; /// let mut first = vec![1u8, 2, 3, 4, 5, 6]; /// let scalar = 252; -/// update_slice_with_wrapping_scalar_mul(&mut first, scalar); +/// slice_wrapping_scalar_mul_assign(&mut first, scalar); /// assert_eq!(&first, &[252, 248, 244, 240, 236, 232]); /// ``` -pub fn update_slice_with_wrapping_scalar_mul(lhs: &mut [Scalar], rhs: Scalar) +pub fn slice_wrapping_scalar_mul_assign(lhs: &mut [Scalar], rhs: Scalar) where Scalar: UnsignedInteger, { diff --git a/tfhe/src/core_crypto/fft_impl/crypto/bootstrap.rs b/tfhe/src/core_crypto/fft_impl/crypto/bootstrap.rs index db71ad7a0..5addbaed2 100644 --- a/tfhe/src/core_crypto/fft_impl/crypto/bootstrap.rs +++ b/tfhe/src/core_crypto/fft_impl/crypto/bootstrap.rs @@ -233,7 +233,7 @@ impl<'a> FourierLweBootstrapKeyView<'a> { lut.as_mut_polynomial_list() .iter_mut() .for_each(|mut poly| { - update_polynomial_with_wrapping_monic_monomial_div( + polynomial_wrapping_monic_monomial_div_assign( &mut poly, MonomialDegree(monomial_degree), ) @@ -254,7 +254,7 @@ impl<'a> FourierLweBootstrapKeyView<'a> { // We rotate ct_1 by performing ct_1 <- ct_1 * X^{a_hat} for mut poly in ct1.as_mut_polynomial_list().iter_mut() { - update_polynomial_with_wrapping_monic_monomial_mul( + polynomial_wrapping_monic_monomial_mul_assign( &mut poly, MonomialDegree(pbs_modulus_switch( *lwe_mask_element, diff --git a/tfhe/src/core_crypto/fft_impl/crypto/wop_pbs/mod.rs b/tfhe/src/core_crypto/fft_impl/crypto/wop_pbs/mod.rs index e69b472b2..2d612d9a0 100644 --- a/tfhe/src/core_crypto/fft_impl/crypto/wop_pbs/mod.rs +++ b/tfhe/src/core_crypto/fft_impl/crypto/wop_pbs/mod.rs @@ -1022,7 +1022,7 @@ pub fn blind_rotate>( ct_1.as_mut_polynomial_list() .iter_mut() .for_each(|mut poly| { - update_polynomial_with_wrapping_monic_monomial_div(&mut poly, monomial_degree) + polynomial_wrapping_monic_monomial_div_assign(&mut poly, monomial_degree) }); monomial_degree.0 <<= 1; cmux(ct_0, ct_1, ggsw, fft, stack); diff --git a/tfhe/src/core_crypto/fft_impl/crypto/wop_pbs/tests.rs b/tfhe/src/core_crypto/fft_impl/crypto/wop_pbs/tests.rs index 9cf6d29ba..205ac3031 100644 --- a/tfhe/src/core_crypto/fft_impl/crypto/wop_pbs/tests.rs +++ b/tfhe/src/core_crypto/fft_impl/crypto/wop_pbs/tests.rs @@ -322,10 +322,7 @@ fn test_circuit_bootstrapping_binary() { let multiplying_factor = 0u64.wrapping_sub(value); - update_slice_with_wrapping_scalar_mul( - expected_decryption.as_mut(), - multiplying_factor, - ); + slice_wrapping_scalar_mul_assign(expected_decryption.as_mut(), multiplying_factor); let decomposer = SignedDecomposer::new(base_log_cbs, DecompositionLevelCount(current_level));