From a0dae1c9ae711f8ccdca96e9e0f72ac602e35f7b Mon Sep 17 00:00:00 2001 From: Arthur Meyre Date: Wed, 4 Jan 2023 17:06:20 +0100 Subject: [PATCH] docs(tfhe): updated user documentation and API documentation --- README.md | 21 +- tfhe/Cargo.toml | 4 +- tfhe/docs/{Booleans => Boolean}/operations.md | 0 tfhe/docs/{Booleans => Boolean}/parameters.md | 0 .../{Booleans => Boolean}/serialization.md | 0 tfhe/docs/{Booleans => Boolean}/tutorial.md | 0 tfhe/docs/SUMMARY.md | 14 +- tfhe/docs/c_api/tutorial.md | 14 +- tfhe/docs/core_crypto/presentation.md | 62 +++++ tfhe/docs/core_crypto/tutorial.md | 244 ++++++++++++++++++ tfhe/docs/getting_started/benchmarks.md | 4 +- tfhe/docs/getting_started/installation.md | 2 +- tfhe/docs/getting_started/operations.md | 2 +- tfhe/src/boolean/engine/mod.rs | 5 + tfhe/src/boolean/mod.rs | 2 - tfhe/src/boolean/prelude.rs | 6 +- tfhe/src/boolean/public_key/mod.rs | 2 + .../core_crypto/algorithms/ggsw_encryption.rs | 15 +- .../core_crypto/algorithms/glwe_encryption.rs | 13 +- .../algorithms/glwe_sample_extraction.rs | 4 + .../algorithms/glwe_secret_key_generation.rs | 3 + .../lwe_bootstrap_key_conversion.rs | 4 + .../lwe_bootstrap_key_generation.rs | 26 ++ .../core_crypto/algorithms/lwe_encryption.rs | 39 +-- .../core_crypto/algorithms/lwe_keyswitch.rs | 51 +--- .../lwe_keyswitch_key_generation.rs | 3 + .../algorithms/lwe_linear_algebra.rs | 4 +- ...we_private_functional_packing_keyswitch.rs | 16 +- ...tional_packing_keyswitch_key_generation.rs | 10 +- .../lwe_programmable_bootstrapping.rs | 23 ++ .../algorithms/lwe_public_key_generation.rs | 15 ++ .../algorithms/lwe_secret_key_generation.rs | 3 + tfhe/src/core_crypto/algorithms/lwe_wopbs.rs | 82 ++++++ tfhe/src/core_crypto/algorithms/misc.rs | 2 + tfhe/src/core_crypto/algorithms/mod.rs | 4 + .../seeded_ggsw_ciphertext_decompression.rs | 2 + ...eded_ggsw_ciphertext_list_decompression.rs | 2 + .../seeded_glwe_ciphertext_decompression.rs | 2 + ...eded_glwe_ciphertext_list_decompression.rs | 2 + .../seeded_lwe_bootstrap_key_decompression.rs | 2 + ...eeded_lwe_ciphertext_list_decompression.rs | 2 + .../seeded_lwe_keyswitch_key_decompression.rs | 2 + .../seeded_lwe_public_key_decompression.rs | 2 + .../seeded_lwe_public_key_generation.rs | 14 + .../commons/computation_buffers.rs | 9 + tfhe/src/core_crypto/commons/dispersion.rs | 2 +- .../commons/generators/encryption.rs | 2 + .../src/core_crypto/commons/generators/mod.rs | 3 + .../core_crypto/commons/generators/secret.rs | 3 + .../core_crypto/commons/generators/seeder.rs | 8 +- .../commons/math/random/generator.rs | 1 + .../core_crypto/commons/math/random/mod.rs | 2 + tfhe/src/core_crypto/commons/mod.rs | 3 + tfhe/src/core_crypto/commons/numeric/mod.rs | 2 +- tfhe/src/core_crypto/commons/parameters.rs | 5 + .../core_crypto/commons/traits/container.rs | 2 + .../traits/contiguous_entity_container.rs | 3 + .../core_crypto/commons/traits/create_from.rs | 2 + tfhe/src/core_crypto/commons/traits/mod.rs | 3 + tfhe/src/core_crypto/entities/cleartext.rs | 2 + .../core_crypto/entities/ggsw_ciphertext.rs | 2 + .../entities/ggsw_ciphertext_list.rs | 2 + .../core_crypto/entities/glwe_ciphertext.rs | 18 ++ .../entities/glwe_ciphertext_list.rs | 2 + .../core_crypto/entities/glwe_secret_key.rs | 2 + .../core_crypto/entities/gsw_ciphertext.rs | 2 + .../core_crypto/entities/lwe_bootstrap_key.rs | 55 ++++ .../core_crypto/entities/lwe_ciphertext.rs | 34 +++ .../entities/lwe_ciphertext_list.rs | 2 + .../core_crypto/entities/lwe_keyswitch_key.rs | 50 ++++ ...rivate_functional_packing_keyswitch_key.rs | 2 + ...e_functional_packing_keyswitch_key_list.rs | 2 + .../core_crypto/entities/lwe_public_key.rs | 2 + .../core_crypto/entities/lwe_secret_key.rs | 2 + tfhe/src/core_crypto/entities/mod.rs | 5 + tfhe/src/core_crypto/entities/plaintext.rs | 2 + .../core_crypto/entities/plaintext_list.rs | 2 + tfhe/src/core_crypto/entities/polynomial.rs | 2 + .../core_crypto/entities/polynomial_list.rs | 2 + .../entities/seeded_ggsw_ciphertext.rs | 2 + .../entities/seeded_ggsw_ciphertext_list.rs | 2 + .../entities/seeded_glwe_ciphertext.rs | 2 + .../entities/seeded_glwe_ciphertext_list.rs | 2 + .../entities/seeded_lwe_bootstrap_key.rs | 2 + .../entities/seeded_lwe_ciphertext_list.rs | 2 + .../entities/seeded_lwe_keyswitch_key.rs | 2 + .../entities/seeded_lwe_public_key.rs | 2 + tfhe/src/core_crypto/fft_impl/mod.rs | 1 + tfhe/src/core_crypto/mod.rs | 2 +- tfhe/src/core_crypto/prelude.rs | 5 + tfhe/src/core_crypto/seeders.rs | 6 + tfhe/src/lib.rs | 15 ++ tfhe/src/shortint/ciphertext/mod.rs | 11 +- tfhe/src/shortint/engine/mod.rs | 5 + tfhe/src/shortint/mod.rs | 2 - tfhe/src/shortint/parameters/mod.rs | 2 +- .../shortint/parameters/parameters_wopbs.rs | 2 + .../parameters_wopbs_message_carry.rs | 2 + tfhe/src/shortint/prelude.rs | 8 +- tfhe/src/shortint/public_key/compressed.rs | 2 +- tfhe/src/shortint/public_key/mod.rs | 2 + tfhe/src/shortint/server_key/compressed.rs | 2 + tfhe/src/test_user_docs.rs | 15 +- 103 files changed, 935 insertions(+), 134 deletions(-) rename tfhe/docs/{Booleans => Boolean}/operations.md (100%) rename tfhe/docs/{Booleans => Boolean}/parameters.md (100%) rename tfhe/docs/{Booleans => Boolean}/serialization.md (100%) rename tfhe/docs/{Booleans => Boolean}/tutorial.md (100%) create mode 100644 tfhe/docs/core_crypto/presentation.md create mode 100644 tfhe/docs/core_crypto/tutorial.md diff --git a/README.md b/README.md index a977b38be..257861810 100644 --- a/README.md +++ b/README.md @@ -40,10 +40,29 @@ production-ready library for all the advanced features of TFHE. To use the latest version of `TFHE-rs` in your project, you first need to add it as a dependency in your `Cargo.toml`: ++ For x86_64-based machines running Unix-like OSes: + ```toml -tfhe = { version = "*", features = [ "boolean","shortint","x86_64-unix" ] } +tfhe = { version = "*", features = ["boolean", "shortint", "x86_64-unix"] } ``` ++ For Apple Silicon or aarch64-based machines running Unix-like OSes: + +```toml +tfhe = { version = "*", features = ["boolean", "shortint", "aarch64-unix"] } +``` +Note: users with ARM devices must use `TFHE-rs` by compiling using the `nightly` toolchain. + + ++ For x86_64-based machines with the [`rdseed instruction`](https://en.wikipedia.org/wiki/RDRAND) +running Windows: + +```toml +tfhe = { version = "*", features = ["boolean", "shortint", "x86_64"] } +``` + +Note: aarch64-based machines are not yet supported for Windows as it's currently missing an entropy source to be able to seed the [CSPRNGs](https://en.wikipedia.org/wiki/Cryptographically_secure_pseudorandom_number_generator) used in TFHE-rs + Here is a full example evaluating a Boolean circuit: ```rust diff --git a/tfhe/Cargo.toml b/tfhe/Cargo.toml index 237c93110..34f1a396f 100644 --- a/tfhe/Cargo.toml +++ b/tfhe/Cargo.toml @@ -92,8 +92,8 @@ __profiling = [] seeder_unix = ["concrete-csprng/seeder_unix"] seeder_x86_64_rdseed = ["concrete-csprng/seeder_x86_64_rdseed"] -# These target_arch features enable a set of public features for concrete-core if users want a known -# good/working configuration for concrete-core. +# These target_arch features enable a set of public features for tfhe if users want a known +# good/working configuration for tfhe. # For a target_arch that does not yet have such a feature, one can still enable features manually or # create a feature for said target_arch to make its use simpler. x86_64 = ["generator_x86_64_aesni", "seeder_x86_64_rdseed"] diff --git a/tfhe/docs/Booleans/operations.md b/tfhe/docs/Boolean/operations.md similarity index 100% rename from tfhe/docs/Booleans/operations.md rename to tfhe/docs/Boolean/operations.md diff --git a/tfhe/docs/Booleans/parameters.md b/tfhe/docs/Boolean/parameters.md similarity index 100% rename from tfhe/docs/Booleans/parameters.md rename to tfhe/docs/Boolean/parameters.md diff --git a/tfhe/docs/Booleans/serialization.md b/tfhe/docs/Boolean/serialization.md similarity index 100% rename from tfhe/docs/Booleans/serialization.md rename to tfhe/docs/Boolean/serialization.md diff --git a/tfhe/docs/Booleans/tutorial.md b/tfhe/docs/Boolean/tutorial.md similarity index 100% rename from tfhe/docs/Booleans/tutorial.md rename to tfhe/docs/Boolean/tutorial.md diff --git a/tfhe/docs/SUMMARY.md b/tfhe/docs/SUMMARY.md index c720f53a2..2a8c298fe 100644 --- a/tfhe/docs/SUMMARY.md +++ b/tfhe/docs/SUMMARY.md @@ -10,11 +10,11 @@ * [Benchmarks](getting\_started/benchmarks.md) * [Security and Cryptography](getting\_started/security\_and\_cryptography.md) -## Booleans -* [Tutorial](Booleans/tutorial.md) -* [Operations](Booleans/operations.md) -* [Cryptographic Parameters](Booleans/parameters.md) -* [Serialization/Deserialization](Booleans/serialization.md) +## Boolean +* [Tutorial](Boolean/tutorial.md) +* [Operations](Boolean/operations.md) +* [Cryptographic Parameters](Boolean/parameters.md) +* [Serialization/Deserialization](Boolean/serialization.md) ## Shortint * [Tutorial](shortint/tutorial.md) @@ -25,6 +25,10 @@ ## C API * [Tutorial](c_api/tutorial.md) +## Low-Level Core Cryptography +* [Quick Start](core_crypto/presentation.md) +* [Tutorial](core_crypto/tutorial.md) + ## Developers * [Contributing](dev/contributing.md) diff --git a/tfhe/docs/c_api/tutorial.md b/tfhe/docs/c_api/tutorial.md index f1909ec62..adb2e6bcf 100644 --- a/tfhe/docs/c_api/tutorial.md +++ b/tfhe/docs/c_api/tutorial.md @@ -2,15 +2,15 @@ ## Using the C API -Welcome to this `TFHE-rs` C API tutorial! +Welcome to this TFHE-rs C API tutorial! -This library exposes a C binding to the `TFHE-rs` primitives to implement _Fully Homomorphic Encryption_ (FHE) programs. +This library exposes a C binding to the TFHE-rs primitives to implement _Fully Homomorphic Encryption_ (FHE) programs. -## First steps using `TFHE-rs` C API +## First steps using TFHE-rs C API -### Setting-up `TFHE-rs` C API for use in a C program. +### Setting-up TFHE-rs C API for use in a C program. -`TFHE-rs` C API can be built on a Unix x86\_64 machine using the following command: +TFHE-rs C API can be built on a Unix x86\_64 machine using the following command: ```shell RUSTFLAGS="-C target-cpu=native" cargo build --release --features=x86_64-unix,boolean-c-api,shortint-c-api -p tfhe @@ -26,7 +26,7 @@ All features are opt-in, but for simplicity here, the C API is enabled for boole The `tfhe.h` header as well as the static (.a) and dynamic (.so) `libtfhe` binaries can then be found in "${REPO\_ROOT}/target/release/" -The build system needs to be set up so that the C or C++ program links against `TFHE-rs` C API binaries. +The build system needs to be set up so that the C or C++ program links against TFHE-rs C API binaries. Here is a minimal CMakeLists.txt allowing to do just that: @@ -175,4 +175,4 @@ int main(void) ## Audience -Programmers wishing to use `TFHE-rs` but who are unable to use Rust (for various reasons) can use these bindings in their language of choice, as long as it can interface with C code to bring `TFHE-rs` functionalities to said language. +Programmers wishing to use TFHE-rs but who are unable to use Rust (for various reasons) can use these bindings in their language of choice, as long as it can interface with C code to bring TFHE-rs functionalities to said language. diff --git a/tfhe/docs/core_crypto/presentation.md b/tfhe/docs/core_crypto/presentation.md new file mode 100644 index 000000000..95051d6c8 --- /dev/null +++ b/tfhe/docs/core_crypto/presentation.md @@ -0,0 +1,62 @@ +# Overview of the `core_crypto` Module + +The `core_crypto` module from TFHE-rs is dedicated to the implementation of the cryptographic tools related to TFHE. To construct an FHE application, the [shortint](../shortint/tutorial.md) and/or [Boolean](../Boolean/tutorial.md) modules (based on this one) are recommended. + +The `core_crypto` module offers an API to low-level cryptographic primitives and objects, like `lwe_encryption` or `rlwe_ciphertext`. Its goal is to propose an easy-to-use API for cryptographers. + +The overall code architecture is split in two parts: one for the entity definitions, and another one focused on the algorithms. For instance, the entities contain the definition of useful types, like LWE ciphertext or bootstrapping keys. The algorithms are then naturally defined to work using these entities. + +The API is convenient to easily add or modify existing algorithms or to have direct access to the raw data. For instance, even if the LWE ciphertext object is defined along with functions giving access to he body, this is also possible to bypass these to get directly the $$i^{th}$$ element of LWE mask. + + +For instance, the code to encrypt and then decrypt a message looks like: +```rust +use tfhe::core_crypto::prelude::*; + +// DISCLAIMER: these toy example parameters are not guaranteed to be secure or yield correct +// computations +// Define parameters for LweCiphertext creation +let lwe_dimension = LweDimension(742); +let lwe_modular_std_dev = StandardDev(0.000007069849454709433); + +// Create the PRNG +let mut seeder = new_seeder(); +let seeder = seeder.as_mut(); +let mut encryption_generator = + EncryptionRandomGenerator::::new(seeder.seed(), seeder); +let mut secret_generator = + SecretRandomGenerator::::new(seeder.seed()); + +// Create the LweSecretKey +let lwe_secret_key = + allocate_and_generate_new_binary_lwe_secret_key(lwe_dimension, &mut secret_generator); + +// Create the plaintext +let msg = 3u64; +let plaintext = Plaintext(msg << 60); + +// Create a new LweCiphertext +let mut lwe = LweCiphertext::new(0u64, lwe_dimension.to_lwe_size()); + +encrypt_lwe_ciphertext( + &lwe_secret_key, + &mut lwe, + plaintext, + lwe_modular_std_dev, + &mut encryption_generator, +); + +let decrypted_plaintext = decrypt_lwe_ciphertext(&lwe_secret_key, &lwe); + +// Round and remove encoding +// First create a decomposer working on the high 4 bits corresponding to our encoding. +let decomposer = SignedDecomposer::new(DecompositionBaseLog(4), DecompositionLevelCount(1)); +let rounded = decomposer.closest_representable(decrypted_plaintext.0); + +// Remove the encoding +let cleartext = rounded >> 60; + +// Check we recovered the original message +assert_eq!(cleartext, msg); +``` + diff --git a/tfhe/docs/core_crypto/tutorial.md b/tfhe/docs/core_crypto/tutorial.md new file mode 100644 index 000000000..40fe56bd0 --- /dev/null +++ b/tfhe/docs/core_crypto/tutorial.md @@ -0,0 +1,244 @@ +# Tutorial + +## Using the `core_crypto` primitives + +Welcome to this tutorial about TFHE-rs `core_crypto` module! + +### Setting-up TFHE-rs to use the `core_crypto` module + +To use `TFHE-rs`, first it has to be added as a dependency in the `Cargo.toml`: + +```toml +tfhe = { version = "0.2.0", features = [ "x86_64-unix" ] } +``` + +Here, this enables the `x86_64-unix` feature to have efficient implementations of various algorithms for `x86_64` CPUs on a Unix-like system. The 'unix' suffix indicates that the `UnixSeeder`, which uses `/dev/random` to generate random numbers, is actived as a fallback if no hardware number generator is available, like `rdseed` on `x86_64` or if the [`Randomization Services`](https://developer.apple.com/documentation/security/1399291-secrandomcopybytes?language=objc) on Apple platforms are not available. To avoid having the `UnixSeeder` as a potential fallback or to run on non-Unix systems (e.g., Windows), the `x86_64` feature is sufficient. + +For Apple Silicon, the `aarch64-unix` or `aarch64` feature should be enabled. Note that `aarch64` is not supported on Windows as it's currently missing an entropy source required to seed the [CSPRNGs](https://en.wikipedia.org/wiki/Cryptographically_secure_pseudorandom_number_generator) used in TFHE-rs. + +In short: +For x86_64-based machines running Unix-like OSes: + +```toml +tfhe = { version = "0.2.0", features = ["x86_64-unix"] } +``` + +For Apple Silicon or aarch64-based machines running Unix-like OSes: + +```toml +tfhe = { version = "0.2.0", features = ["aarch64-unix"] } +``` + +For x86_64-based machines with the [`rdseed instruction`](https://en.wikipedia.org/wiki/RDRAND) running Windows: + +```toml +tfhe = { version = "0.2.0", features = ["x86_64"] } +``` + +### Commented code to double a 2 bits message in a leveled fashion and using a PBS with the `core_crypto` module. + +As a complete example showing the usage of some common primitives of the `core_crypto` APIs, the following Rust code homomorphically computes 2 * 3 using two different methods. First using a cleartext multiplication and second using a PBS. + +```rust +use tfhe::core_crypto::prelude::*; + +pub fn main() { + // DISCLAIMER: these toy example parameters are not guaranteed to be secure or yield correct + // computations + // Define the parameters for a 4 bits message able to hold the doubled 2 bits message + let small_lwe_dimension = LweDimension(742); + let glwe_dimension = GlweDimension(1); + let polynomial_size = PolynomialSize(2048); + let lwe_modular_std_dev = StandardDev(0.000007069849454709433); + let glwe_modular_std_dev = StandardDev(0.00000000000000029403601535432533); + let pbs_base_log = DecompositionBaseLog(23); + let pbs_level = DecompositionLevelCount(1); + + // Request the best seeder possible, starting with hardware entropy sources and falling back to + // /dev/random on Unix systems if enabled via cargo features + let mut boxed_seeder = new_seeder(); + // Get a mutable reference to the seeder as a trait object from the Box returned by new_seeder + let seeder = boxed_seeder.as_mut(); + + // Create a generator which uses a CSPRNG to generate secret keys + let mut secret_generator = + SecretRandomGenerator::::new(seeder.seed()); + + // Create a generator which uses two CSPRNGs to generate public masks and secret encryption + // noise + let mut encryption_generator = + EncryptionRandomGenerator::::new(seeder.seed(), seeder); + + println!("Generating keys..."); + + // Generate an LweSecretKey with binary coefficients + let small_lwe_sk = + LweSecretKey::generate_new_binary(small_lwe_dimension, &mut secret_generator); + + // Generate a GlweSecretKey with binary coefficients + let glwe_sk = + GlweSecretKey::generate_new_binary(glwe_dimension, polynomial_size, &mut secret_generator); + + // Create a copy of the GlweSecretKey re-interpreted as an LweSecretKey + let big_lwe_sk = glwe_sk.clone().into_lwe_secret_key(); + + // Generate the bootstrapping key, we use the parallel variant for performance reason + let std_bootstrapping_key = par_allocate_and_generate_new_lwe_bootstrap_key( + &small_lwe_sk, + &glwe_sk, + pbs_base_log, + pbs_level, + glwe_modular_std_dev, + &mut encryption_generator, + ); + + // Create the empty bootstrapping key in the Fourier domain + let mut fourier_bsk = FourierLweBootstrapKey::new( + std_bootstrapping_key.input_lwe_dimension(), + std_bootstrapping_key.glwe_size(), + std_bootstrapping_key.polynomial_size(), + std_bootstrapping_key.decomposition_base_log(), + std_bootstrapping_key.decomposition_level_count(), + ); + + // Use the conversion function (a memory optimized version also exists but is more complicated + // to use) to convert the standard bootstrapping key to the Fourier domain + convert_standard_lwe_bootstrap_key_to_fourier(&std_bootstrapping_key, &mut fourier_bsk); + // We don't need the standard bootstrapping key anymore + drop(std_bootstrapping_key); + + // Our 4 bits message space + let message_modulus = 1u64 << 4; + + // Our input message + let input_message = 3u64; + + // Delta used to encode 4 bits of message + a bit of padding on u64 + let delta = (1_u64 << 63) / message_modulus; + + // Apply our encoding + let plaintext = Plaintext(input_message * delta); + + // Allocate a new LweCiphertext and encrypt our plaintext + let lwe_ciphertext_in: LweCiphertextOwned = allocate_and_encrypt_new_lwe_ciphertext( + &small_lwe_sk, + plaintext, + lwe_modular_std_dev, + &mut encryption_generator, + ); + + // Compute a cleartext multiplication by 2 + let mut cleartext_multiplication_ct = lwe_ciphertext_in.clone(); + println!("Performing cleartext multiplication..."); + lwe_ciphertext_cleartext_mul( + &mut cleartext_multiplication_ct, + &lwe_ciphertext_in, + Cleartext(2), + ); + + // Decrypt the cleartext multiplication result + let cleartext_multipliation_plaintext: Plaintext = + decrypt_lwe_ciphertext(&small_lwe_sk, &cleartext_multiplication_ct); + + // Create a SignedDecomposer to perform the rounding of the decrypted plaintext + // We pass a DecompositionBaseLog of 5 and a DecompositionLevelCount of 1 indicating we want to + // round the 5 MSB, 1 bit of padding plus our 4 bits of message + let signed_decomposer = + SignedDecomposer::new(DecompositionBaseLog(5), DecompositionLevelCount(1)); + + // Round and remove our encoding + let cleartext_multiplication_result: u64 = + signed_decomposer.closest_representable(cleartext_multipliation_plaintext.0) / delta; + + println!("Checking result..."); + assert_eq!(6, cleartext_multiplication_result); + println!( + "Cleartext multiplication result is correct! \ + Expected 6, got {cleartext_multiplication_result}" + ); + + // Now we will use a PBS to compute the same multiplication, it is NOT the recommended way of + // doing this operation in terms of performance as it's much more costly than a multiplication + // with a cleartext, however it resets the noise in a ciphertext to a nominal level and allows + // to evaluate arbitrary functions so depending on your use case it can be a better fit. + + // Here we will define a helper function to generate an accumulator for a PBS + fn generate_accumulator( + polynomial_size: PolynomialSize, + glwe_size: GlweSize, + message_modulus: usize, + delta: u64, + f: F, + ) -> GlweCiphertextOwned + where + F: Fn(u64) -> u64, + { + // N/(p/2) = size of each block, to correct noise from the input we introduce the notion of + // box, which manages redundancy to yield a denoised value for several noisy values around + // a true input value. + let box_size = polynomial_size.0 / message_modulus; + + // Create the accumulator + let mut accumulator_u64 = vec![0_u64; polynomial_size.0]; + + // Fill each box with the encoded denoised value + for i in 0..message_modulus { + let index = i * box_size; + accumulator_u64[index..index + box_size] + .iter_mut() + .for_each(|a| *a = f(i as u64) * delta); + } + + let half_box_size = box_size / 2; + + // Negate the first half_box_size coefficients to manage negacyclicity and rotate + for a_i in accumulator_u64[0..half_box_size].iter_mut() { + *a_i = (*a_i).wrapping_neg(); + } + + // Rotate the accumulator + accumulator_u64.rotate_left(half_box_size); + + let accumulator_plaintext = PlaintextList::from_container(accumulator_u64); + + let accumulator = + allocate_and_trivially_encrypt_new_glwe_ciphertext(glwe_size, &accumulator_plaintext); + + accumulator + } + + // Generate the accumulator for our multiplication by 2 using a simple closure + let accumulator: GlweCiphertextOwned = generate_accumulator( + polynomial_size, + glwe_dimension.to_glwe_size(), + message_modulus as usize, + delta, + |x: u64| 2 * x, + ); + + // Allocate the LweCiphertext to store the result of the PBS + let mut pbs_multiplication_ct = + LweCiphertext::new(0u64, big_lwe_sk.lwe_dimension().to_lwe_size()); + println!("Computing PBS..."); + programmable_bootstrap_lwe_ciphertext( + &lwe_ciphertext_in, + &mut pbs_multiplication_ct, + &accumulator, + &fourier_bsk, + ); + + // Decrypt the PBS multiplication result + let pbs_multipliation_plaintext: Plaintext = + decrypt_lwe_ciphertext(&big_lwe_sk, &pbs_multiplication_ct); + + // Round and remove our encoding + let pbs_multiplication_result: u64 = + signed_decomposer.closest_representable(pbs_multipliation_plaintext.0) / delta; + + println!("Checking result..."); + assert_eq!(6, pbs_multiplication_result); + println!( + "Mulitplication via PBS result is correct! Expected 6, got {pbs_multiplication_result}" + ); +} +``` diff --git a/tfhe/docs/getting_started/benchmarks.md b/tfhe/docs/getting_started/benchmarks.md index 3df402de0..2b498fbbf 100644 --- a/tfhe/docs/getting_started/benchmarks.md +++ b/tfhe/docs/getting_started/benchmarks.md @@ -4,11 +4,11 @@ Due to their nature, homomorphic operations are obviously slower than their clea All the benchmarks had been launched on an AWS m6i.metal with the following specifications: Intel(R) Xeon(R) Platinum 8375C CPU @ 2.90GHz and 512GB of RAM. -## Booleans +## Boolean This measures the execution time of a single binary boolean gate. -### tfhe.rs::booleans. +### tfhe.rs::boolean. | Parameter set | concrete-fft | concrete-fft + avx512 | | --------------------- | ------------ | --------------------- | diff --git a/tfhe/docs/getting_started/installation.md b/tfhe/docs/getting_started/installation.md index a0f00722c..98c58074e 100644 --- a/tfhe/docs/getting_started/installation.md +++ b/tfhe/docs/getting_started/installation.md @@ -25,7 +25,7 @@ This crate exposes two kinds of data types. Each kind is enabled by activating i The different data types and keys exposed by the crate can be serialized / deserialized. -More information can be found [here](../Booleans/serialization.md) for boolean and [here](../shortint/serialization.md) for shortint. +More information can be found [here](../Boolean/serialization.md) for boolean and [here](../shortint/serialization.md) for shortint. ## Supported platforms diff --git a/tfhe/docs/getting_started/operations.md b/tfhe/docs/getting_started/operations.md index d538a1a8b..0011b63ac 100644 --- a/tfhe/docs/getting_started/operations.md +++ b/tfhe/docs/getting_started/operations.md @@ -14,7 +14,7 @@ The list of supported operations by the homomorphic Booleans is: | `xnor` | Binary | | `cmux` | Ternary | -A walk-through using homomorphic Booleans can be found [here](../Booleans/tutorial.md). +A walk-through using homomorphic Booleans can be found [here](../Boolean/tutorial.md). ## ShortInt diff --git a/tfhe/src/boolean/engine/mod.rs b/tfhe/src/boolean/engine/mod.rs index 1715d7278..57eb1f184 100644 --- a/tfhe/src/boolean/engine/mod.rs +++ b/tfhe/src/boolean/engine/mod.rs @@ -1,3 +1,8 @@ +//! Module with the engine definitions. +//! +//! Engines are required to abstract cryptographic notions and efficiently manage memory from the +//! underlying `core_crypto` module. + use crate::boolean::ciphertext::Ciphertext; use crate::boolean::parameters::BooleanParameters; use crate::boolean::{ClientKey, PublicKey, PLAINTEXT_FALSE, PLAINTEXT_TRUE}; diff --git a/tfhe/src/boolean/mod.rs b/tfhe/src/boolean/mod.rs index 6ab6c24ee..c9981baa3 100644 --- a/tfhe/src/boolean/mod.rs +++ b/tfhe/src/boolean/mod.rs @@ -1,5 +1,3 @@ -//! Welcome to the TFHE-rs `boolean` module documentation! -//! //! # Description //! This library makes it possible to execute boolean gates over encrypted bits. //! It allows to execute a boolean circuit on an untrusted server because both circuit inputs and diff --git a/tfhe/src/boolean/prelude.rs b/tfhe/src/boolean/prelude.rs index 8a778b5cf..cba386757 100644 --- a/tfhe/src/boolean/prelude.rs +++ b/tfhe/src/boolean/prelude.rs @@ -1,4 +1,8 @@ -#![doc(hidden)] +//! Module with the definition of the prelude. +//! +//! The TFHE-rs preludes include convenient imports. +//! Having `tfhe::boolean::prelude::*;` should be enough to start using the lib. + pub use super::ciphertext::Ciphertext; pub use super::client_key::ClientKey; pub use super::gen_keys; diff --git a/tfhe/src/boolean/public_key/mod.rs b/tfhe/src/boolean/public_key/mod.rs index 5f5a2ffb0..e87d4973c 100644 --- a/tfhe/src/boolean/public_key/mod.rs +++ b/tfhe/src/boolean/public_key/mod.rs @@ -1,3 +1,5 @@ +//! Module with the definition of the encryption PublicKey. + use crate::boolean::ciphertext::Ciphertext; use crate::boolean::client_key::ClientKey; use crate::boolean::engine::{BooleanEngine, WithThreadLocalEngine}; diff --git a/tfhe/src/core_crypto/algorithms/ggsw_encryption.rs b/tfhe/src/core_crypto/algorithms/ggsw_encryption.rs index ab674e77b..f23ef5814 100644 --- a/tfhe/src/core_crypto/algorithms/ggsw_encryption.rs +++ b/tfhe/src/core_crypto/algorithms/ggsw_encryption.rs @@ -1,3 +1,6 @@ +//! Module containing primitives pertaining to [`GGSW ciphertext +//! encryption`](`GgswCiphertext#ggsw-encryption`). + use crate::core_crypto::algorithms::slice_algorithms::*; use crate::core_crypto::algorithms::*; use crate::core_crypto::commons::dispersion::DispersionParameter; @@ -10,8 +13,8 @@ use rayon::prelude::*; /// Encrypt a plaintext in a [`GGSW ciphertext`](`GgswCiphertext`). /// -/// See the [`formal definition`](`GgswCiphertext#ggsw-encryption`) for the definition of the -/// encryption algorithm. +/// See the [`GGSW ciphertext formal definition`](`GgswCiphertext#ggsw-encryption`) for the +/// definition of the encryption algorithm. /// /// ``` /// use tfhe::core_crypto::prelude::*; @@ -307,6 +310,10 @@ fn encrypt_ggsw_level_matrix_row( } } +/// Convenience function to share the core logic of the seeded GGSW encryption between all +/// functions needing it. +/// +/// Allows to efficiently encrypt lists of seeded GGSW. pub fn encrypt_seeded_ggsw_ciphertext_with_existing_generator( glwe_secret_key: &GlweSecretKey, output: &mut SeededGgswCiphertext, @@ -463,6 +470,10 @@ pub fn encrypt_seeded_ggsw_ciphertext( ) } +/// Convenience function to share the core logic of the parallele seeded GGSW encryption between all +/// functions needing it. +/// +/// Allows to efficiently encrypt lists of seeded GGSW. pub fn par_encrypt_seeded_ggsw_ciphertext_with_existing_generator< Scalar, KeyCont, diff --git a/tfhe/src/core_crypto/algorithms/glwe_encryption.rs b/tfhe/src/core_crypto/algorithms/glwe_encryption.rs index fbb91497f..7c8d0b7f8 100644 --- a/tfhe/src/core_crypto/algorithms/glwe_encryption.rs +++ b/tfhe/src/core_crypto/algorithms/glwe_encryption.rs @@ -1,3 +1,6 @@ +//! Module containing primitives pertaining to [`GLWE ciphertext +//! encryption`](`GlweCiphertext#glwe-encryption`). + use crate::core_crypto::algorithms::polynomial_algorithms::*; use crate::core_crypto::commons::dispersion::DispersionParameter; use crate::core_crypto::commons::generators::EncryptionRandomGenerator; @@ -146,7 +149,7 @@ pub fn encrypt_glwe_ciphertext_assign( } /// Convenience function to share the core logic of the seeded GLWE assign encryption between all -/// functions needing it +/// functions needing it. pub fn encrypt_seeded_glwe_ciphertext_assign_with_existing_generator< Scalar, KeyCont, @@ -762,6 +765,8 @@ where new_ct } +/// Convenience function to share the core logic of the seeded GLWE encryption between all +/// functions needing it. pub fn encrypt_seeded_glwe_ciphertext_with_exsiting_generator< Scalar, KeyCont, @@ -920,8 +925,10 @@ pub fn encrypt_seeded_glwe_ciphertext( input_lwe_secret_key: &LweSecretKey, output_glwe_secret_key: &GlweSecretKey, @@ -220,6 +231,8 @@ pub fn par_generate_lwe_bootstrap_key( input_lwe_secret_key: &LweSecretKey, output_glwe_secret_key: &GlweSecretKey, @@ -254,6 +267,11 @@ where bsk } +/// Fill a [`seeded LWE bootstrap key`](`SeededLweBootstrapKey`) with an actual seeded bootstrapping +/// key constructed from an input key [`LWE secret key`](`LweSecretKey`) and an output key +/// [`GLWE secret key`](`GlweSecretKey`) +/// +/// Consider using [`par_generate_seeded_lwe_bootstrap_key`] for better key generation times. pub fn generate_seeded_lwe_bootstrap_key< Scalar, InputKeyCont, @@ -327,6 +345,12 @@ pub fn generate_seeded_lwe_bootstrap_key< } } +/// Allocate a new [`seeded LWE bootstrap key`](`SeededLweBootstrapKey`) and fill it with an actual +/// seeded bootstrapping key constructed from an input key [`LWE secret key`](`LweSecretKey`) and an +/// output key [`GLWE secret key`](`GlweSecretKey`) +/// +/// Consider using [`par_allocate_and_generate_new_seeded_lwe_bootstrap_key`] for better key +/// generation times. pub fn allocate_and_generate_new_seeded_lwe_bootstrap_key< Scalar, InputKeyCont, @@ -443,6 +467,8 @@ pub fn par_generate_seeded_lwe_bootstrap_key< }) } +/// Parallel variant of [`allocate_and_generate_new_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_allocate_and_generate_new_seeded_lwe_bootstrap_key< Scalar, InputKeyCont, diff --git a/tfhe/src/core_crypto/algorithms/lwe_encryption.rs b/tfhe/src/core_crypto/algorithms/lwe_encryption.rs index ac8dd982c..2d8e466df 100644 --- a/tfhe/src/core_crypto/algorithms/lwe_encryption.rs +++ b/tfhe/src/core_crypto/algorithms/lwe_encryption.rs @@ -1,4 +1,5 @@ -//! Module containing functions related to LWE ciphertext encryption and decryption +//! Module containing primitives pertaining to [`LWE ciphertext encryption and +//! decryption`](`LweCiphertext#lwe-encryption`). use crate::core_crypto::algorithms::slice_algorithms::*; use crate::core_crypto::algorithms::*; @@ -41,23 +42,8 @@ pub fn fill_lwe_mask_and_body_for_encryption( /// Encrypt an input plaintext in an output [`LWE ciphertext`](`LweCiphertext`). /// -/// # Formal Definition -/// -/// ## LWE Encryption -/// ###### inputs: -/// - $\mathsf{pt}\in\mathbb{Z}\_q$: a plaintext -/// - $\vec{s}\in\mathbb{Z}\_q^n$: a secret key -/// - $\mathcal{D\_{\sigma^2,\mu}}$: a normal distribution of variance $\sigma^2$ and a mean $\mu$ -/// -/// ###### outputs: -/// - $\mathsf{ct} = \left( \vec{a} , b\right) \in \mathsf{LWE}^n\_{\vec{s}}( \mathsf{pt} )\subseteq -/// \mathbb{Z}\_q^{(n+1)}$: an LWE ciphertext -/// -/// ###### algorithm: -/// 1. uniformly sample a vector $\vec{a}\in\mathbb{Z}\_q^n$ -/// 2. sample an integer error term $e \hookleftarrow \mathcal{D\_{\sigma^2,\mu}}$ -/// 3. compute $b = \left\langle \vec{a} , \vec{s} \right\rangle + \mathsf{pt} + e \in\mathbb{Z}\_q$ -/// 4. output $\left( \vec{a} , b\right)$ +/// See the [`LWE ciphertext formal definition`](`LweCiphertext#lwe-encryption`) for the definition +/// of the encryption algorithm. /// /// # Example /// @@ -360,21 +346,8 @@ where /// /// # Formal Definition /// -/// ## LWE Decryption -/// ###### inputs: -/// - $\mathsf{ct} = \left( \vec{a} , b\right) \in \mathsf{LWE}^n\_{\vec{s}}( \mathsf{pt} )\subseteq -/// \mathbb{Z}\_q^{(n+1)}$: an LWE ciphertext -/// - $\vec{s}\in\mathbb{Z}\_q^n$: a secret key -/// -/// ###### outputs: -/// - $\mathsf{pt}\in\mathbb{Z}\_q$: a plaintext -/// -/// ###### algorithm: -/// 1. compute $\mathsf{pt} = b - \left\langle \vec{a} , \vec{s} \right\rangle \in\mathbb{Z}\_q$ -/// 2. output $\mathsf{pt}$ -/// -/// **Remark:** Observe that the decryption is followed by a decoding phase that will contain a -/// rounding. +/// See the [`LWE ciphertext formal definition`](`LweCiphertext#lwe-decryption`) for the definition +/// of the encryption algorithm. pub fn decrypt_lwe_ciphertext( lwe_secret_key: &LweSecretKey, lwe_ciphertext: &LweCiphertext, diff --git a/tfhe/src/core_crypto/algorithms/lwe_keyswitch.rs b/tfhe/src/core_crypto/algorithms/lwe_keyswitch.rs index 7c7941af2..5cbac95b7 100644 --- a/tfhe/src/core_crypto/algorithms/lwe_keyswitch.rs +++ b/tfhe/src/core_crypto/algorithms/lwe_keyswitch.rs @@ -1,3 +1,6 @@ +//! Module containing primitives pertaining to [`LWE ciphertext +//! keyswitch`](`LweKeyswitchKey#lwe-keyswitch`). + use crate::core_crypto::algorithms::slice_algorithms::*; use crate::core_crypto::commons::math::decomposition::SignedDecomposer; use crate::core_crypto::commons::numeric::UnsignedInteger; @@ -9,53 +12,7 @@ use crate::core_crypto::entities::*; /// /// # Formal Definition /// -/// ## LWE Keyswitch -/// -/// This homomorphic procedure transforms an input -/// [`LWE ciphertext`](`crate::core_crypto::entities::LweCiphertext`) -/// $\mathsf{ct}\_{\mathsf{in}} = -/// \left( \vec{a}\_{\mathsf{in}} , b\_{\mathsf{in}}\right) \in \mathsf{LWE}^{n\_{\mathsf{in}}}\_ -/// {\vec{s}\_{\mathsf{in}}}( \mathsf{pt} ) \subseteq \mathbb{Z}\_q^{(n\_{\mathsf{in}}+1)}$ into an -/// output [`LWE ciphertext`](`crate::core_crypto::entities::LweCiphertext`) -/// $\mathsf{ct}\_{\mathsf{out}} = -/// \left( \vec{a}\_{\mathsf{out}} , b\_{\mathsf{out}}\right) \in -/// \mathsf{LWE}^{n\_{\mathsf{out}}}\_{\vec{s}\_{\mathsf{out}}}( \mathsf{pt} )\subseteq -/// \mathbb{Z}\_q^{(n\_{\mathsf{out}}+1)}$ where $n\_{\mathsf{in}} = |\vec{s}\_{\mathsf{in}}|$ and -/// $n\_{\mathsf{out}} = |\vec{s}\_{\mathsf{out}}|$. It requires a -/// [`key switching key`](`crate::core_crypto::entities::LweKeyswitchKey`). -/// The input ciphertext is encrypted under the -/// [`LWE secret key`](`crate::core_crypto::entities::LweSecretKey`) -/// $\vec{s}\_{\mathsf{in}}$ and the output ciphertext is -/// encrypted under the [`LWE secret key`](`crate::core_crypto::entities::LweSecretKey`) -/// $\vec{s}\_{\mathsf{out}}$. -/// -/// $$\mathsf{ct}\_{\mathsf{in}} \in \mathsf{LWE}^{n\_{\mathsf{in}}}\_{\vec{s}\_{\mathsf{in}}}( -/// \mathsf{pt} ) ~~~~~~~~~~\mathsf{KSK}\_{\vec{s}\_{\mathsf{in}}\rightarrow -/// \vec{s}\_{\mathsf{out}}}$$ $$ \mathsf{keyswitch}\left(\mathsf{ct}\_{\mathsf{in}} , \mathsf{KSK} -/// \right) \rightarrow \mathsf{ct}\_{\mathsf{out}} \in -/// \mathsf{LWE}^{n\_{\mathsf{out}}}\_{\vec{s}\_{\mathsf{out}}} \left( \mathsf{pt} \right)$$ -/// -/// ## Algorithm -/// ###### inputs: -/// - $\mathsf{ct}\_{\mathsf{in}} = \left( \vec{a}\_{\mathsf{in}} , b\_{\mathsf{in}}\right) \in -/// \mathsf{LWE}^{n\_{\mathsf{in}}}\_{\vec{s}\_{\mathsf{in}}}( \mathsf{pt} )$: an [`LWE -/// ciphertext`](`LweCiphertext`) with $\vec{a}\_{\mathsf{in}}=\left(a\_0, \cdots -/// a\_{n\_{\mathsf{in}}-1}\right)$ -/// - $\mathsf{KSK}\_{\vec{s}\_{\mathsf{in}}\rightarrow \vec{s}\_{\mathsf{out}}}$: a -/// [`key switching key`](`crate::core_crypto::entities::LweKeyswitchKey`) -/// -/// ###### outputs: -/// - $\mathsf{ct}\_{\mathsf{out}} \in \mathsf{LWE}^{n\_{\mathsf{out}}}\_{\vec{s}\_{\mathsf{out}}} -/// \left( \mathsf{pt} \right)$: an -/// [`LWE ciphertext`](`crate::core_crypto::entities::LweCiphertext`) -/// -/// ###### algorithm: -/// 1. set $\mathsf{ct}=\left( 0 , \cdots , 0 , b\_{\mathsf{in}} \right) \in -/// \mathbb{Z}\_q^{(n\_{\mathsf{out}}+1)}$ -/// 2. compute $\mathsf{ct}\_{\mathsf{out}} = \mathsf{ct} - -/// \sum\_{i=0}^{n\_{\mathsf{in}}-1} \mathsf{decompProduct}\left( a\_i , \overline{\mathsf{ct}\_i} -/// \right)$ -/// 3. output $\mathsf{ct}\_{\mathsf{out}}$ +/// See [`LWE keyswitch key`](`LweKeyswitchKey#lwe-keyswitch`). /// /// # Example /// diff --git a/tfhe/src/core_crypto/algorithms/lwe_keyswitch_key_generation.rs b/tfhe/src/core_crypto/algorithms/lwe_keyswitch_key_generation.rs index 3da9978cb..0cd7ec796 100644 --- a/tfhe/src/core_crypto/algorithms/lwe_keyswitch_key_generation.rs +++ b/tfhe/src/core_crypto/algorithms/lwe_keyswitch_key_generation.rs @@ -1,3 +1,6 @@ +//! Module containing primitives pertaining to [`LWE keyswitch keys +//! generation`](`LweKeyswitchKey#key-switching-key`). + use crate::core_crypto::algorithms::*; use crate::core_crypto::commons::dispersion::DispersionParameter; use crate::core_crypto::commons::generators::EncryptionRandomGenerator; diff --git a/tfhe/src/core_crypto/algorithms/lwe_linear_algebra.rs b/tfhe/src/core_crypto/algorithms/lwe_linear_algebra.rs index 98b552cad..88225c46c 100644 --- a/tfhe/src/core_crypto/algorithms/lwe_linear_algebra.rs +++ b/tfhe/src/core_crypto/algorithms/lwe_linear_algebra.rs @@ -1,5 +1,5 @@ -//! Module containing functions related to LWE ciphertext linear algebra, like addition, -//! multiplication, etc. +//! Module containing primitives pertaining to [`LWE ciphertext`](`LweCiphertext`) linear algebra, +//! like addition, multiplication, etc. use crate::core_crypto::algorithms::slice_algorithms::*; use crate::core_crypto::commons::numeric::UnsignedInteger; 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 cc9a394db..540a4b71d 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 @@ -1,3 +1,12 @@ +//! Module containing primitives pertaining to LWE ciphertext private functional keyswitch and +//! packing keyswitch. +//! +//! Formal description can be found in: \ +//!      Chillotti, I., Gama, N., Georgieva, M. et al. \ +//!      TFHE: Fast Fully Homomorphic Encryption Over the Torus. \ +//!      J. Cryptol 33, 34–91 (2020). \ +//!      + use crate::core_crypto::algorithms::polynomial_algorithms::*; use crate::core_crypto::algorithms::slice_algorithms::*; use crate::core_crypto::commons::math::decomposition::SignedDecomposer; @@ -5,6 +14,8 @@ use crate::core_crypto::commons::parameters::*; use crate::core_crypto::commons::traits::*; use crate::core_crypto::entities::*; +/// Apply a private functional keyswitch on an input [`LWE ciphertext`](`LweCiphertext`) and write +/// the result in an output [`GLWE ciphertext`](`GlweCiphertext`). pub fn private_functional_keyswitch_lwe_ciphertext_into_glwe_ciphertext< Scalar, KeyCont, @@ -58,7 +69,10 @@ pub fn private_functional_keyswitch_lwe_ciphertext_into_glwe_ciphertext< } } -pub fn private_functional_keyswitch_lwe_ciphertext_list_and_pack_in_glwe_cipheretext< +/// Apply a private functional keyswitch on each [`LWE ciphertext`](`LweCiphertext`) of an input +/// [`LWE ciphertext list`](`LweCiphertextList`) and pack the result in an output +/// [`GLWE ciphertext`](`GlweCiphertext`). +pub fn private_functional_keyswitch_lwe_ciphertext_list_and_pack_in_glwe_ciphertext< Scalar, KeyCont, InputCont, 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 0a0d85289..a2fce610b 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 @@ -1,3 +1,6 @@ +//! Module containing primitives pertaining to [`LWE private functional packing keyswitch key +//! generation`](`LwePrivateFunctionalPackingKeyswitchKey`). + use crate::core_crypto::algorithms::slice_algorithms::*; use crate::core_crypto::algorithms::*; use crate::core_crypto::commons::dispersion::DispersionParameter; @@ -8,6 +11,11 @@ use crate::core_crypto::commons::traits::*; use crate::core_crypto::entities::*; use rayon::prelude::*; +/// Fill an [`LWE private functional packing keyswitch +/// key`](`LwePrivateFunctionalPackingKeyswitchKey`) with an actual key. +/// +/// Consider using [`par_generate_lwe_private_functional_packing_keyswitch_key`] for better key +/// generation times. pub fn generate_lwe_private_functional_packing_keyswitch_key< Scalar, InputKeyCont, @@ -118,7 +126,7 @@ 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. +/// use this variant for better key generation times. pub fn par_generate_lwe_private_functional_packing_keyswitch_key< Scalar, InputKeyCont, diff --git a/tfhe/src/core_crypto/algorithms/lwe_programmable_bootstrapping.rs b/tfhe/src/core_crypto/algorithms/lwe_programmable_bootstrapping.rs index 8534db6df..ce65b4536 100644 --- a/tfhe/src/core_crypto/algorithms/lwe_programmable_bootstrapping.rs +++ b/tfhe/src/core_crypto/algorithms/lwe_programmable_bootstrapping.rs @@ -1,3 +1,6 @@ +//! Module containing primitives pertaining to the [`LWE programmable +//! bootstrap`](`LweBootstrapKey#programmable-bootstrapping`). + use crate::core_crypto::commons::computation_buffers::ComputationBuffers; use crate::core_crypto::commons::parameters::*; use crate::core_crypto::commons::traits::*; @@ -8,6 +11,12 @@ use crate::core_crypto::fft_impl::math::fft::{Fft, FftView}; use concrete_fft::c64; use dyn_stack::{DynStack, SizeOverflow, StackReq}; +/// Perform a blind rotation given an input [`LWE ciphertext`](`LweCiphertext`), modifying a look-up +/// table passed as a [`GLWE ciphertext`](`GlweCiphertext`) and an [`LWE bootstrap +/// key`](`LweBootstrapKey`) in the fourier domain. +/// +/// If you want to manage the computation memory manually you can use +/// [`blind_rotate_assign_mem_optimized`]. pub fn blind_rotate_assign( input: &LweCiphertext, lut: &mut GlweCiphertext, @@ -39,6 +48,9 @@ pub fn blind_rotate_assign( blind_rotate_assign_mem_optimized(input, lut, fourier_bsk, fft, stack); } +/// Memory optimized version of [`blind_rotate_assign`], the caller must provide +/// a properly configured [`FftView`] object and a `DynStack` used as a memory buffer having a +/// capacity at least as large as the result of [`blind_rotate_assign_mem_optimized_requirement`]. pub fn blind_rotate_assign_mem_optimized( input: &LweCiphertext, lut: &mut GlweCiphertext, @@ -66,6 +78,13 @@ pub fn blind_rotate_assign_mem_optimized_requirement( blind_rotate_assign_scratch::(glwe_size, polynomial_size, fft) } +/// Perform a programmable bootsrap given an input [`LWE ciphertext`](`LweCiphertext`), a +/// look-up table passed as a [`GLWE ciphertext`](`GlweCiphertext`) and an [`LWE bootstrap +/// key`](`LweBootstrapKey`) in the fourier domain. The result is written in the provided output +/// [`LWE ciphertext`](`LweCiphertext`). +/// +/// If you want to manage the computation memory manually you can use +/// [`programmable_bootstrap_lwe_ciphertext_mem_optimized`]. pub fn programmable_bootstrap_lwe_ciphertext( input: &LweCiphertext, output: &mut LweCiphertext, @@ -106,6 +125,10 @@ pub fn programmable_bootstrap_lwe_ciphertext( lwe_secret_key: &LweSecretKey, output: &mut LwePublicKey, @@ -31,6 +38,10 @@ pub fn generate_lwe_public_key( encrypt_lwe_ciphertext_list(lwe_secret_key, output, &zeros, noise_parameters, generator) } +/// Allocate a new [`LWE public key`](`LwePublicKey`) and fill it with an actual public key +/// constructed from a private [`LWE secret key`](`LweSecretKey`). +/// +/// Consider using [`par_allocate_and_generate_new_lwe_public_key`] for better key generation times. pub fn allocate_and_generate_new_lwe_public_key( lwe_secret_key: &LweSecretKey, zero_encryption_count: LwePublicKeyZeroEncryptionCount, @@ -53,6 +64,8 @@ where pk } +/// Parallel variant of [`generate_lwe_public_key`], it is recommended to use this function for +/// better key generation times as LWE public keys can be quite large. pub fn par_generate_lwe_public_key( lwe_secret_key: &LweSecretKey, output: &mut LwePublicKey, @@ -79,6 +92,8 @@ pub fn par_generate_lwe_public_key( par_encrypt_lwe_ciphertext_list(lwe_secret_key, output, &zeros, noise_parameters, generator) } +/// Parallel variant of [`allocate_and_generate_new_lwe_public_key`], it is recommended to use this +/// function for better key generation times as LWE public keys can be quite large. pub fn par_allocate_and_generate_new_lwe_public_key( lwe_secret_key: &LweSecretKey, zero_encryption_count: LwePublicKeyZeroEncryptionCount, diff --git a/tfhe/src/core_crypto/algorithms/lwe_secret_key_generation.rs b/tfhe/src/core_crypto/algorithms/lwe_secret_key_generation.rs index e729f06ab..9524dfea2 100644 --- a/tfhe/src/core_crypto/algorithms/lwe_secret_key_generation.rs +++ b/tfhe/src/core_crypto/algorithms/lwe_secret_key_generation.rs @@ -1,3 +1,6 @@ +//! Module containing primitives pertaining to the generation of +//! [`LWE secret keys`](`LweSecretKey`). + use crate::core_crypto::commons::generators::SecretRandomGenerator; use crate::core_crypto::commons::math::random::{RandomGenerable, UniformBinary}; use crate::core_crypto::commons::numeric::Numeric; diff --git a/tfhe/src/core_crypto/algorithms/lwe_wopbs.rs b/tfhe/src/core_crypto/algorithms/lwe_wopbs.rs index d9504dbc5..11b146bb0 100644 --- a/tfhe/src/core_crypto/algorithms/lwe_wopbs.rs +++ b/tfhe/src/core_crypto/algorithms/lwe_wopbs.rs @@ -1,3 +1,5 @@ +//! Module containing primitives pertaining to the Wopbs (WithOut padding PBS). + use crate::core_crypto::algorithms::*; use crate::core_crypto::commons::dispersion::DispersionParameter; use crate::core_crypto::commons::generators::EncryptionRandomGenerator; @@ -14,6 +16,12 @@ use concrete_fft::c64; use dyn_stack::{DynStack, SizeOverflow, StackReq}; use rayon::prelude::*; +/// Allocate a new [`list of LWE private functional packing keyswitch +/// keys`](`LwePrivateFunctionalPackingKeyswitchKeyList`) and fill it with actual keys required to +/// perform a circuit bootstrap. +/// +/// Consider using [`par_allocate_and_generate_new_circuit_bootstrap_lwe_pfpksk_list`] for better +/// key generation times. pub fn allocate_and_generate_new_circuit_bootstrap_lwe_pfpksk_list< Scalar, LweKeyCont, @@ -56,6 +64,12 @@ where cbs_pfpksk_list } +/// Fill a [`list of LWE private functional packing keyswitch +/// keys`](`LwePrivateFunctionalPackingKeyswitchKeyList`) with actual keys required to perform a +/// circuit bootstrap. +/// +/// Consider using [`par_generate_circuit_bootstrap_lwe_pfpksk_list`] for better key generation +/// times. pub fn generate_circuit_bootstrap_lwe_pfpksk_list< Scalar, OutputCont, @@ -128,6 +142,9 @@ pub fn generate_circuit_bootstrap_lwe_pfpksk_list< } } +/// Parallel variant of [`allocate_and_generate_new_circuit_bootstrap_lwe_pfpksk_list`], it is +/// recommended to use this function for better key generation times as the generated keys can be +/// quite large. pub fn par_allocate_and_generate_new_circuit_bootstrap_lwe_pfpksk_list< Scalar, LweKeyCont, @@ -170,6 +187,8 @@ where cbs_pfpksk_list } +/// Parallel variant of [`generate_circuit_bootstrap_lwe_pfpksk_list`], it is recommended to use +/// this function for better key generation times as the generated keys can be quite large. pub fn par_generate_circuit_bootstrap_lwe_pfpksk_list< Scalar, OutputCont, @@ -245,6 +264,26 @@ pub fn par_generate_circuit_bootstrap_lwe_pfpksk_list< } #[allow(clippy::too_many_arguments)] +/// Fill the `output` [`LWE ciphertext list`](`LweCiphertextList`) with the bit extraction of the +/// `input` [`LWE ciphertext`](`LweCiphertext`), extracting `number_of_bits_to_extract` bits +/// starting from the bit at index `delta_log` (0-indexed) included, and going towards the most +/// significant bits. +/// +/// Output bits are ordered from the MSB to the LSB. Each one of them is output in a distinct [`LWE +/// ciphertext`](`LweCiphertext`), containing the encryption of the bit scaled by q/2 (i.e., the +/// most significant bit in the plaintext representation). +/// +/// The caller must provide a properly configured [`FftView`] object and a `DynStack` used as a +/// memory buffer having a capacity at least as large as the result of +/// [`extract_bits_from_lwe_ciphertext_mem_optimized_requirement`]. +/// +/// # Formal Definition +/// +/// This function takes as input an [`LWE ciphertext`](`LweCiphertext`) +/// $$\mathsf{ct\} = \mathsf{LWE}^n\_{\vec{s}}( \mathsf{m}) \subseteq \mathbb{Z}\_q^{(n+1)}$$ +/// which encrypts some message `m`. We extract bits $m\_i$ of this message into individual LWE +/// ciphertexts. Each of these ciphertexts contains an encryption of $m\_i \cdot q/2$, i.e. +/// $$\mathsf{ct\_i} = \mathsf{LWE}^n\_{\vec{s}}( \mathsf{m\_i} \cdot q/2 )$$. pub fn extract_bits_from_lwe_ciphertext_mem_optimized< Scalar, InputCont, @@ -280,6 +319,7 @@ pub fn extract_bits_from_lwe_ciphertext_mem_optimized< ) } +/// Return the required memory for [`extract_bits_from_lwe_ciphertext_mem_optimized`]. pub fn extract_bits_from_lwe_ciphertext_mem_optimized_requirement( lwe_dimension: LweDimension, ksk_output_key_lwe_dimension: LweDimension, @@ -297,6 +337,46 @@ pub fn extract_bits_from_lwe_ciphertext_mem_optimized_requirement( } #[allow(clippy::too_many_arguments)] +/// Perform a boolean circuit bootstrapping followed by a vertical packing to evaluate a look-up +/// table on an [`LWE ciphertext list`](`LweCiphertextList`). The term "boolean" refers to the fact +/// the input ciphertexts encrypt a single bit of message. +/// +/// The provided "big" `luts` look-up table is expected to be divisible into the same number of +/// chunks of polynomials as there are ciphertexts in the `output` [`LWE Ciphertext +/// list`](`LweCiphertextList`). Each chunk of polynomials is used as a look-up table to evaluate +/// during the vertical packing operation to fill an output ciphertext. +/// +/// Note that there should be enough polynomials provided in each chunk to perform the vertical +/// packing given the number of boolean input ciphertexts. The number of boolean input ciphertexts +/// is in fact a number of bits. For this example let's say we have 16 input ciphertexts +/// representing 16 bits and want to output 4 ciphertexts. The "big" `luts` will need to be +/// divisible into 4 chunks of equal size. If the polynomial size used is $1024 = 2^{10}$ then each +/// chunk must contain $2^6 = 64$ polynomials ($2^6 * 2^{10} = 2^{16}$) to match the amount of +/// values representable by the 16 input ciphertexts each encrypting a bit. The "big" `luts` then +/// has a layout looking as follows: +/// +/// ```text +/// small lut for 1st output ciphertext|...|small lut for 4th output ciphertext +/// |[polynomial 1] ... [polynomial 64]|...|[polynomial 1] ... [polynomial 64]| +/// ``` +/// +/// The polynomials in the above representation are not necessarily the same, this is just for +/// illustration purposes. +/// +/// It is also possible in the above example to have a single polynomial of size $2^{16} = 65 536$ +/// for each chunk if the polynomial size is supported for computation. Chunks containing a single +/// polynomial of size $2^{10} = 1024$ would work for example for 10 input ciphertexts as that +/// polynomial size is supported for computations. The "big" `luts` layout would then look as +/// follows for that 10 bits example (still with 4 output ciphertexts): +/// +/// ```text +/// small lut for 1st output ciphertext|...|small lut for 4th output ciphertext +/// |[ polynomial 1 ]|...|[ polynomial 1 ]| +/// ``` +/// +/// The caller must provide a properly configured [`FftView`] object and a `DynStack` used as a +/// memory buffer having a capacity at least as large as the result of +/// [`circuit_bootstrap_boolean_vertical_packing_lwe_ciphertext_list_mem_optimized_requirement`]. pub fn circuit_bootstrap_boolean_vertical_packing_lwe_ciphertext_list_mem_optimized< Scalar, InputCont, @@ -337,6 +417,8 @@ pub fn circuit_bootstrap_boolean_vertical_packing_lwe_ciphertext_list_mem_optimi } #[allow(clippy::too_many_arguments)] +/// Return the required memory for +/// [`circuit_bootstrap_boolean_vertical_packing_lwe_ciphertext_list_mem_optimized`]. pub fn circuit_bootstrap_boolean_vertical_packing_lwe_ciphertext_list_mem_optimized_requirement< Scalar, >( diff --git a/tfhe/src/core_crypto/algorithms/misc.rs b/tfhe/src/core_crypto/algorithms/misc.rs index ebd5b174e..520c931ed 100644 --- a/tfhe/src/core_crypto/algorithms/misc.rs +++ b/tfhe/src/core_crypto/algorithms/misc.rs @@ -1,3 +1,5 @@ +//! Miscellaneous algorithms. + use crate::core_crypto::prelude::*; /// Convenience function using a bit trick to determine whether a scalar is a power of 2. diff --git a/tfhe/src/core_crypto/algorithms/mod.rs b/tfhe/src/core_crypto/algorithms/mod.rs index 44ac2088f..f02e3096d 100644 --- a/tfhe/src/core_crypto/algorithms/mod.rs +++ b/tfhe/src/core_crypto/algorithms/mod.rs @@ -1,3 +1,7 @@ +//! This module contains algorithms manipulating FHE entities as well as some convenience algorithms +//! operating on [`slices of scalars`](`slice_algorithms`) and on +//! [`polynomials`](`polynomial_algorithms`). + pub mod ggsw_encryption; pub mod glwe_encryption; pub mod glwe_sample_extraction; diff --git a/tfhe/src/core_crypto/algorithms/seeded_ggsw_ciphertext_decompression.rs b/tfhe/src/core_crypto/algorithms/seeded_ggsw_ciphertext_decompression.rs index 7bbc6c501..8fdc28cae 100644 --- a/tfhe/src/core_crypto/algorithms/seeded_ggsw_ciphertext_decompression.rs +++ b/tfhe/src/core_crypto/algorithms/seeded_ggsw_ciphertext_decompression.rs @@ -1,3 +1,5 @@ +//! Module with primitives pertaining to [`SeededGgswCiphertext`] decompression. + use crate::core_crypto::algorithms::*; use crate::core_crypto::commons::math::random::RandomGenerator; use crate::core_crypto::commons::traits::*; diff --git a/tfhe/src/core_crypto/algorithms/seeded_ggsw_ciphertext_list_decompression.rs b/tfhe/src/core_crypto/algorithms/seeded_ggsw_ciphertext_list_decompression.rs index c2d70aff2..632310a20 100644 --- a/tfhe/src/core_crypto/algorithms/seeded_ggsw_ciphertext_list_decompression.rs +++ b/tfhe/src/core_crypto/algorithms/seeded_ggsw_ciphertext_list_decompression.rs @@ -1,3 +1,5 @@ +//! Module with primitives pertaining to [`SeededGgswCiphertextList`] decompression. + use crate::core_crypto::algorithms::*; use crate::core_crypto::commons::math::random::RandomGenerator; use crate::core_crypto::commons::traits::*; diff --git a/tfhe/src/core_crypto/algorithms/seeded_glwe_ciphertext_decompression.rs b/tfhe/src/core_crypto/algorithms/seeded_glwe_ciphertext_decompression.rs index 42dc83f35..a78f2d009 100644 --- a/tfhe/src/core_crypto/algorithms/seeded_glwe_ciphertext_decompression.rs +++ b/tfhe/src/core_crypto/algorithms/seeded_glwe_ciphertext_decompression.rs @@ -1,3 +1,5 @@ +//! Module with primitives pertaining to [`SeededGlweCiphertext`] decompression. + use crate::core_crypto::commons::math::random::RandomGenerator; use crate::core_crypto::commons::traits::*; use crate::core_crypto::entities::*; diff --git a/tfhe/src/core_crypto/algorithms/seeded_glwe_ciphertext_list_decompression.rs b/tfhe/src/core_crypto/algorithms/seeded_glwe_ciphertext_list_decompression.rs index ad5fd97b4..d2ec96e4c 100644 --- a/tfhe/src/core_crypto/algorithms/seeded_glwe_ciphertext_list_decompression.rs +++ b/tfhe/src/core_crypto/algorithms/seeded_glwe_ciphertext_list_decompression.rs @@ -1,3 +1,5 @@ +//! Module with primitives pertaining to [`SeededGlweCiphertextList`] decompression. + use crate::core_crypto::commons::math::random::RandomGenerator; use crate::core_crypto::commons::traits::*; use crate::core_crypto::entities::*; diff --git a/tfhe/src/core_crypto/algorithms/seeded_lwe_bootstrap_key_decompression.rs b/tfhe/src/core_crypto/algorithms/seeded_lwe_bootstrap_key_decompression.rs index bba22f880..197e41795 100644 --- a/tfhe/src/core_crypto/algorithms/seeded_lwe_bootstrap_key_decompression.rs +++ b/tfhe/src/core_crypto/algorithms/seeded_lwe_bootstrap_key_decompression.rs @@ -1,3 +1,5 @@ +//! Module with primitives pertaining to [`SeededLweBootstrapKey`] decompression. + use crate::core_crypto::algorithms::*; use crate::core_crypto::commons::math::random::RandomGenerator; use crate::core_crypto::commons::traits::*; diff --git a/tfhe/src/core_crypto/algorithms/seeded_lwe_ciphertext_list_decompression.rs b/tfhe/src/core_crypto/algorithms/seeded_lwe_ciphertext_list_decompression.rs index fe0e851ca..fdf4d9a43 100644 --- a/tfhe/src/core_crypto/algorithms/seeded_lwe_ciphertext_list_decompression.rs +++ b/tfhe/src/core_crypto/algorithms/seeded_lwe_ciphertext_list_decompression.rs @@ -1,3 +1,5 @@ +//! Module with primitives pertaining to [`SeededLweCiphertextList`] decompression. + use crate::core_crypto::commons::math::random::RandomGenerator; use crate::core_crypto::commons::traits::*; use crate::core_crypto::entities::*; diff --git a/tfhe/src/core_crypto/algorithms/seeded_lwe_keyswitch_key_decompression.rs b/tfhe/src/core_crypto/algorithms/seeded_lwe_keyswitch_key_decompression.rs index fbcf339a5..5965ddd42 100644 --- a/tfhe/src/core_crypto/algorithms/seeded_lwe_keyswitch_key_decompression.rs +++ b/tfhe/src/core_crypto/algorithms/seeded_lwe_keyswitch_key_decompression.rs @@ -1,3 +1,5 @@ +//! Module with primitives pertaining to [`SeededLweKeyswitchKey`] decompression. + use crate::core_crypto::algorithms::*; use crate::core_crypto::commons::math::random::RandomGenerator; use crate::core_crypto::commons::traits::*; diff --git a/tfhe/src/core_crypto/algorithms/seeded_lwe_public_key_decompression.rs b/tfhe/src/core_crypto/algorithms/seeded_lwe_public_key_decompression.rs index 10c161622..bd49bbfd7 100644 --- a/tfhe/src/core_crypto/algorithms/seeded_lwe_public_key_decompression.rs +++ b/tfhe/src/core_crypto/algorithms/seeded_lwe_public_key_decompression.rs @@ -1,3 +1,5 @@ +//! Module with primitives pertaining to [`SeededLwePublicKey`] decompression. + use crate::core_crypto::algorithms::*; use crate::core_crypto::commons::math::random::RandomGenerator; use crate::core_crypto::commons::traits::*; diff --git a/tfhe/src/core_crypto/algorithms/seeded_lwe_public_key_generation.rs b/tfhe/src/core_crypto/algorithms/seeded_lwe_public_key_generation.rs index c9c2b00f9..a3504d774 100644 --- a/tfhe/src/core_crypto/algorithms/seeded_lwe_public_key_generation.rs +++ b/tfhe/src/core_crypto/algorithms/seeded_lwe_public_key_generation.rs @@ -1,3 +1,5 @@ +//! Module with primitives pertaining to [`SeededLwePublicKey`] generation. + use crate::core_crypto::algorithms::*; use crate::core_crypto::commons::dispersion::DispersionParameter; use crate::core_crypto::commons::math::random::CompressionSeed; @@ -5,6 +7,9 @@ use crate::core_crypto::commons::parameters::*; use crate::core_crypto::commons::traits::*; use crate::core_crypto::entities::*; +/// Fill a [`seeded LWE public key`](`SeededLwePublicKey`) with an actual public key. +/// +/// Consider using [`par_generate_seeded_lwe_public_key`] for better key generation times. pub fn generate_seeded_lwe_public_key( lwe_secret_key: &LweSecretKey, output: &mut SeededLwePublicKey, @@ -38,6 +43,11 @@ pub fn generate_seeded_lwe_public_key( lwe_secret_key: &LweSecretKey, zero_encryption_count: LwePublicKeyZeroEncryptionCount, @@ -64,6 +74,8 @@ where pk } +/// Parallel variant of [`par_generate_seeded_lwe_public_key`], it is recommended to use this +/// function for better key generation times as LWE public keys can be quite large. pub fn par_generate_seeded_lwe_public_key( lwe_secret_key: &LweSecretKey, output: &mut SeededLwePublicKey, @@ -97,6 +109,8 @@ pub fn par_generate_seeded_lwe_public_key( lwe_secret_key: &LweSecretKey, zero_encryption_count: LwePublicKeyZeroEncryptionCount, diff --git a/tfhe/src/core_crypto/commons/computation_buffers.rs b/tfhe/src/core_crypto/commons/computation_buffers.rs index 23f1443be..c12dec191 100644 --- a/tfhe/src/core_crypto/commons/computation_buffers.rs +++ b/tfhe/src/core_crypto/commons/computation_buffers.rs @@ -1,20 +1,29 @@ +//! Module containing primitives to manage computations buffers for memory optimized fft primitives. + use core::mem::MaybeUninit; use dyn_stack::DynStack; #[derive(Default)] +/// Struct containing a resizable buffer that can be used with a `DynStack` to provide memory +/// buffers for memory optimized fft primitives. pub struct ComputationBuffers { memory: Vec>, } impl ComputationBuffers { + /// Create a new emtpy [`ComputationBuffers`] instance. pub fn new() -> Self { ComputationBuffers { memory: Vec::new() } } + /// Resize the underlying memory buffer, reallocating memory when capacity exceeds the current + /// buffer capacity. pub fn resize(&mut self, capacity: usize) { self.memory.resize_with(capacity, MaybeUninit::uninit); } + /// Return a `DynStack` borrowoing from the managed memory buffer for use with optimized fft + /// primitives or other functions using `DynStack` to manage temporary memory. pub fn stack(&mut self) -> DynStack<'_> { DynStack::new(&mut self.memory) } diff --git a/tfhe/src/core_crypto/commons/dispersion.rs b/tfhe/src/core_crypto/commons/dispersion.rs index 2c017fa0f..fd86373da 100644 --- a/tfhe/src/core_crypto/commons/dispersion.rs +++ b/tfhe/src/core_crypto/commons/dispersion.rs @@ -1,4 +1,4 @@ -//! Noise distribution +//! Module containing noise distribution primitives. //! //! When dealing with noise, we tend to use different representation for the same value. In //! general, the noise is specified by the standard deviation of a gaussian distribution, which diff --git a/tfhe/src/core_crypto/commons/generators/encryption.rs b/tfhe/src/core_crypto/commons/generators/encryption.rs index 8af0c73a3..30e165d33 100644 --- a/tfhe/src/core_crypto/commons/generators/encryption.rs +++ b/tfhe/src/core_crypto/commons/generators/encryption.rs @@ -1,3 +1,5 @@ +//! Module containing primitives pertaining to random generation in the context of encryption. + use crate::core_crypto::commons::dispersion::DispersionParameter; use crate::core_crypto::commons::math::random::{ ByteRandomGenerator, Gaussian, ParallelByteRandomGenerator, RandomGenerable, RandomGenerator, diff --git a/tfhe/src/core_crypto/commons/generators/mod.rs b/tfhe/src/core_crypto/commons/generators/mod.rs index 6e92ced03..09f88508c 100644 --- a/tfhe/src/core_crypto/commons/generators/mod.rs +++ b/tfhe/src/core_crypto/commons/generators/mod.rs @@ -1,3 +1,6 @@ +//! Module containing various APIs wrapping `concrete-csprng` generators for specialized use in +//! [`TFHE-rs`](`crate`). + mod encryption; pub use encryption::EncryptionRandomGenerator; diff --git a/tfhe/src/core_crypto/commons/generators/secret.rs b/tfhe/src/core_crypto/commons/generators/secret.rs index 3b3c46dfd..b3ebe30a1 100644 --- a/tfhe/src/core_crypto/commons/generators/secret.rs +++ b/tfhe/src/core_crypto/commons/generators/secret.rs @@ -1,3 +1,6 @@ +//! Module containing primitives pertaining to random generation in the context of secret key +//! generation. + use crate::core_crypto::commons::math::random::{ ByteRandomGenerator, RandomGenerable, RandomGenerator, Seed, UniformBinary, }; diff --git a/tfhe/src/core_crypto/commons/generators/seeder.rs b/tfhe/src/core_crypto/commons/generators/seeder.rs index d5c3e207b..3d63b675b 100644 --- a/tfhe/src/core_crypto/commons/generators/seeder.rs +++ b/tfhe/src/core_crypto/commons/generators/seeder.rs @@ -1,3 +1,5 @@ +//! Module containing primitives pertaining to random generation in the context of seeds generation. + use crate::core_crypto::commons::math::random::{ ByteRandomGenerator, RandomGenerable, RandomGenerator, Seed, Seeder, Uniform, }; @@ -15,9 +17,9 @@ use crate::core_crypto::commons::math::random::{ /// /// ## Is it safe? /// -/// The answer to this question is the following: as long as the the CSPRNG used in this [`Seeder`] -/// is seeded with a [`Seed`] coming from an entropy source then yes, seeding other CSPRNGs using -/// this CSPRNG is safe. +/// The answer to this question is the following: as long as the CSPRNG used in this [`Seeder`] is +/// seeded with a [`Seed`] coming from an entropy source then yes, seeding other CSPRNGs using this +/// CSPRNG is safe. /// /// ## Why is it deterministic? /// diff --git a/tfhe/src/core_crypto/commons/math/random/generator.rs b/tfhe/src/core_crypto/commons/math/random/generator.rs index 5d45e95f6..f8fea38f2 100644 --- a/tfhe/src/core_crypto/commons/math/random/generator.rs +++ b/tfhe/src/core_crypto/commons/math/random/generator.rs @@ -31,6 +31,7 @@ pub mod serialization_proxy { pub(crate) use serialization_proxy::*; #[derive(PartialEq, Eq, Debug, Clone, Copy, Serialize, Deserialize)] +/// New type to manage seeds used for compressed/seeded types. pub struct CompressionSeed { #[serde(with = "SeedSerdeDef")] pub seed: Seed, diff --git a/tfhe/src/core_crypto/commons/math/random/mod.rs b/tfhe/src/core_crypto/commons/math/random/mod.rs index e2a18a71d..6cb2c7302 100644 --- a/tfhe/src/core_crypto/commons/math/random/mod.rs +++ b/tfhe/src/core_crypto/commons/math/random/mod.rs @@ -15,6 +15,7 @@ //! [`RandomGenerator`] instead. use crate::core_crypto::commons::numeric::FloatingPoint; +/// Convenience alias for the most efficient CSPRNG implementation available. pub use activated_random_generator::ActivatedRandomGenerator; pub use gaussian::*; pub use generator::*; @@ -38,6 +39,7 @@ mod uniform_msb; mod uniform_ternary; mod uniform_with_zeros; +/// A trait giving a type the ability to be randomly generated according to a given distribution. pub trait RandomGenerable where Self: Sized, diff --git a/tfhe/src/core_crypto/commons/mod.rs b/tfhe/src/core_crypto/commons/mod.rs index 96d07125d..8531f2d9c 100644 --- a/tfhe/src/core_crypto/commons/mod.rs +++ b/tfhe/src/core_crypto/commons/mod.rs @@ -1,4 +1,7 @@ #![allow(dead_code)] +//! Module containing common mathematical objects/cryptographic primitives like random generators or +//! traits expected to be re-used in various algorithms and entities implementations. +//! //! # Dispersion //! This module contains the functions used to compute the variance, standard //! deviation, etc. diff --git a/tfhe/src/core_crypto/commons/numeric/mod.rs b/tfhe/src/core_crypto/commons/numeric/mod.rs index 9ece5979d..c377d3da8 100644 --- a/tfhe/src/core_crypto/commons/numeric/mod.rs +++ b/tfhe/src/core_crypto/commons/numeric/mod.rs @@ -1,4 +1,4 @@ -//! Generic numeric types. +//! Generic numeric traits. //! //! This module contains types and traits to manipulate numeric types in a generic manner. For //! instance, in the standard library, the `f32` and `f64` trait share a lot of methods of the diff --git a/tfhe/src/core_crypto/commons/parameters.rs b/tfhe/src/core_crypto/commons/parameters.rs index 4a99fa07e..24a06758a 100644 --- a/tfhe/src/core_crypto/commons/parameters.rs +++ b/tfhe/src/core_crypto/commons/parameters.rs @@ -1,3 +1,8 @@ +//! Module with new-types wrapping basic rust types, giving them a particular meaning, to avoid +//! common mistakes when passing parameters to functions. +//! +//! These types have 0 overhead compared to the type being wrapped. + use serde::{Deserialize, Serialize}; /// The number plaintexts in a plaintext list. diff --git a/tfhe/src/core_crypto/commons/traits/container.rs b/tfhe/src/core_crypto/commons/traits/container.rs index 16848421d..eb35856e7 100644 --- a/tfhe/src/core_crypto/commons/traits/container.rs +++ b/tfhe/src/core_crypto/commons/traits/container.rs @@ -1,3 +1,5 @@ +//! Module with traits pertaining to container manipulation. + /// A trait to manipulate various immutable container types transparently. pub trait Container: AsRef<[Self::Element]> { type Element; diff --git a/tfhe/src/core_crypto/commons/traits/contiguous_entity_container.rs b/tfhe/src/core_crypto/commons/traits/contiguous_entity_container.rs index 5749cb94e..6968d489b 100644 --- a/tfhe/src/core_crypto/commons/traits/contiguous_entity_container.rs +++ b/tfhe/src/core_crypto/commons/traits/contiguous_entity_container.rs @@ -1,3 +1,6 @@ +//! Module with traits pertaining to efficient contiguous containers of complex entities +//! manipulation. + use super::create_from::*; use rayon::prelude::*; diff --git a/tfhe/src/core_crypto/commons/traits/create_from.rs b/tfhe/src/core_crypto/commons/traits/create_from.rs index 63d1c1585..b166c63fc 100644 --- a/tfhe/src/core_crypto/commons/traits/create_from.rs +++ b/tfhe/src/core_crypto/commons/traits/create_from.rs @@ -1,3 +1,5 @@ +//! Module with primitives pertaining to generic entity creations. + /// Trait to be able to create structs in contexts where the concrete type may not be known ahead of /// time. pub trait CreateFrom { diff --git a/tfhe/src/core_crypto/commons/traits/mod.rs b/tfhe/src/core_crypto/commons/traits/mod.rs index 0067e9671..34b71d8f7 100644 --- a/tfhe/src/core_crypto/commons/traits/mod.rs +++ b/tfhe/src/core_crypto/commons/traits/mod.rs @@ -1,3 +1,6 @@ +//! Module containing common traits used throughout the [`core_crypto +//! module`](`crate::core_crypto`). + pub mod container; pub mod contiguous_entity_container; pub mod create_from; diff --git a/tfhe/src/core_crypto/entities/cleartext.rs b/tfhe/src/core_crypto/entities/cleartext.rs index 75cf72337..4ea131ebf 100644 --- a/tfhe/src/core_crypto/entities/cleartext.rs +++ b/tfhe/src/core_crypto/entities/cleartext.rs @@ -1,3 +1,5 @@ +//! Module containing the definition of the Cleartext. + use crate::core_crypto::commons::numeric::Numeric; /// A cleartext, not encoded, value. diff --git a/tfhe/src/core_crypto/entities/ggsw_ciphertext.rs b/tfhe/src/core_crypto/entities/ggsw_ciphertext.rs index fd5821ac1..7f1cc7582 100644 --- a/tfhe/src/core_crypto/entities/ggsw_ciphertext.rs +++ b/tfhe/src/core_crypto/entities/ggsw_ciphertext.rs @@ -1,3 +1,5 @@ +//! Module containing the definition of the GgswCiphertext. + use crate::core_crypto::commons::parameters::*; use crate::core_crypto::commons::traits::*; use crate::core_crypto::entities::*; diff --git a/tfhe/src/core_crypto/entities/ggsw_ciphertext_list.rs b/tfhe/src/core_crypto/entities/ggsw_ciphertext_list.rs index 78adac746..2b1a623ee 100644 --- a/tfhe/src/core_crypto/entities/ggsw_ciphertext_list.rs +++ b/tfhe/src/core_crypto/entities/ggsw_ciphertext_list.rs @@ -1,3 +1,5 @@ +//! Module containing the definition of the GgswCiphertextList. + use crate::core_crypto::commons::parameters::*; use crate::core_crypto::commons::traits::*; use crate::core_crypto::entities::*; diff --git a/tfhe/src/core_crypto/entities/glwe_ciphertext.rs b/tfhe/src/core_crypto/entities/glwe_ciphertext.rs index 88dbf3095..7b05b2c49 100644 --- a/tfhe/src/core_crypto/entities/glwe_ciphertext.rs +++ b/tfhe/src/core_crypto/entities/glwe_ciphertext.rs @@ -1,3 +1,5 @@ +//! Module containing the definition of the GlweCiphertext. + use crate::core_crypto::commons::parameters::*; use crate::core_crypto::commons::traits::*; use crate::core_crypto::entities::*; @@ -203,6 +205,22 @@ pub fn glwe_ciphertext_mask_size( /// /// When we set $k=1$ a GLWE ciphertext becomes an RLWE ciphertext. /// When we set $N=1$ a GLWE ciphertext becomes an LWE ciphertext with $n=k$. +/// +/// ## GLWE Encryption +/// ###### inputs: +/// - $\mathsf{PT}\in\mathcal{R}\_q$: a plaintext +/// - $\vec{S} \in\mathcal{R}\_q^k$: a secret key +/// - $\mathcal{D\_{\sigma^2,\mu}}$: a normal distribution of variance $\sigma^2$ and mean $\mu$ +/// +/// ###### outputs: +/// - $\mathsf{CT} = \left( \vec{A} , B \right) \in \mathsf{GLWE}\_{\vec{S}}( \mathsf{PT} )\subseteq +/// \mathcal{R}\_q^{k+1}$: an GLWE ciphertext +/// +/// ###### algorithm: +/// 1. uniformly sample each coefficient of the polynomial vector $\vec{A}\in\mathcal{R}^k\_q$ +/// 2. sample each integer error coefficient of an error polynomial $E\in\mathcal{R}\_q$ from +/// $\mathcal{D\_{\sigma^2,\mu}}$ 3. compute $B = \left\langle \vec{A} , \vec{S} \right\rangle + +/// \mathsf{PT} + E \in\mathcal{R}\_q$ 4. output $\left( \vec{A} , B \right)$ #[derive(Clone, Debug, PartialEq)] pub struct GlweCiphertext { data: C, diff --git a/tfhe/src/core_crypto/entities/glwe_ciphertext_list.rs b/tfhe/src/core_crypto/entities/glwe_ciphertext_list.rs index bfb8f7dc0..57819694a 100644 --- a/tfhe/src/core_crypto/entities/glwe_ciphertext_list.rs +++ b/tfhe/src/core_crypto/entities/glwe_ciphertext_list.rs @@ -1,3 +1,5 @@ +//! Module containing the definition of the GlweCiphertextList. + use crate::core_crypto::commons::parameters::*; use crate::core_crypto::commons::traits::*; use crate::core_crypto::entities::*; diff --git a/tfhe/src/core_crypto/entities/glwe_secret_key.rs b/tfhe/src/core_crypto/entities/glwe_secret_key.rs index 79dd71597..d3096c496 100644 --- a/tfhe/src/core_crypto/entities/glwe_secret_key.rs +++ b/tfhe/src/core_crypto/entities/glwe_secret_key.rs @@ -1,3 +1,5 @@ +//! Module containing the definition of the GlweSecretKey. + use crate::core_crypto::algorithms::*; use crate::core_crypto::commons::generators::SecretRandomGenerator; use crate::core_crypto::commons::math::random::{RandomGenerable, UniformBinary}; diff --git a/tfhe/src/core_crypto/entities/gsw_ciphertext.rs b/tfhe/src/core_crypto/entities/gsw_ciphertext.rs index 4be3c7516..af162d8e5 100644 --- a/tfhe/src/core_crypto/entities/gsw_ciphertext.rs +++ b/tfhe/src/core_crypto/entities/gsw_ciphertext.rs @@ -1,3 +1,5 @@ +//! Module containing the definition of the GswCiphertext. + use crate::core_crypto::commons::parameters::*; use crate::core_crypto::commons::traits::*; diff --git a/tfhe/src/core_crypto/entities/lwe_bootstrap_key.rs b/tfhe/src/core_crypto/entities/lwe_bootstrap_key.rs index 60821492d..d4bc4b6a8 100644 --- a/tfhe/src/core_crypto/entities/lwe_bootstrap_key.rs +++ b/tfhe/src/core_crypto/entities/lwe_bootstrap_key.rs @@ -1,3 +1,5 @@ +//! Module containing the definition of the LweBootstrapKey. + use crate::core_crypto::commons::parameters::*; use crate::core_crypto::commons::traits::*; use crate::core_crypto::entities::*; @@ -40,6 +42,59 @@ use crate::core_crypto::entities::*; /// \ldots, s\_{\mathsf{out},k\_{\mathsf{out}}-1,N\_{\mathsf{out}}-1}) \in /// \mathbb{Z}^{n\_{\mathsf{out}}}$, where $n\_{\mathsf{out}} = k\_{\mathsf{out}} \cdot /// N\_{\mathsf{out}}$. +/// +/// ## Programmable Bootstrapping +/// +/// This homomorphic procedure allows to both reduce the noise of a ciphertext and to evaluate a +/// Look-Up Table (LUT) on the encrypted plaintext at the same time, i.e., it transforms an input +/// [`LWE ciphertext`](`LweCiphertext`) +/// $\mathsf{ct}\_{\mathsf{in}} = \left( +/// \vec{a}\_{\mathsf{in}} , b\_{\mathsf{in}}\right) \in +/// \mathsf{LWE}^{n\_{\mathsf{in}}}\_{\vec{s}\_{\mathsf{in}}}( \mathsf{pt} ) \subseteq +/// \mathbb{Z}\_q^{(n\_{\mathsf{in}}+1)}$ into an output [`LWE ciphertext`](`LweCiphertext`) +/// $\mathsf{ct}\_{\mathsf{out}} = \left( \vec{a}\_{\mathsf{out}} , +/// b\_{\mathsf{out}}\right) \in \mathsf{LWE}^{n\_{\mathsf{out}}}\_{\vec{s}\_{\mathsf{out}}}( +/// \mathsf{LUT(pt)} )\subseteq \mathbb{Z}\_q^{(n\_{\mathsf{out}}+1)}$ where $n\_{\mathsf{in}} = +/// |\vec{s}\_{\mathsf{in}}|$ and $n\_{\mathsf{out}} = |\vec{s}\_{\mathsf{out}}|$, such that the +/// noise in this latter is set to a fixed (reduced) amount. It requires a +/// [`bootstrapping key`](`LweBootstrapKey`). +/// +/// The input ciphertext is encrypted under the +/// [`LWE secret key`](`LweSecretKey`) +/// $\vec{s}\_{\mathsf{in}}$ and the +/// output ciphertext is encrypted under the +/// [`LWE secret key`](`LweSecretKey`) +/// $\vec{s}\_{\mathsf{out}}$. +/// +/// $$\mathsf{ct}\_{\mathsf{in}} \in \mathsf{LWE}^{n\_{\mathsf{in}}}\_{\vec{s}\_{\mathsf{in}}}( +/// \mathsf{pt} ) ~~~~~~~~~~\mathsf{BSK}\_{\vec{s}\_{\mathsf{in}}\rightarrow +/// \vec{S}\_{\mathsf{out}}}$$ $$ \mathsf{PBS}\left(\mathsf{ct}\_{\mathsf{in}} , \mathsf{BSK} +/// \right) \rightarrow \mathsf{ct}\_{\mathsf{out}} \in +/// \mathsf{LWE}^{n\_{\mathsf{out}}}\_{\vec{s}\_{\mathsf{out}}} \left( \mathsf{pt} \right)$$ +/// +/// ## Algorithm +/// ###### inputs: +/// - $\mathsf{ct}\_{\mathsf{in}} = \left( \vec{a}\_{\mathsf{in}} , b\_{\mathsf{in}}\right) \in +/// \mathsf{LWE}^{n\_{\mathsf{in}}}\_{\vec{s}\_{\mathsf{in}}}( \mathsf{pt} )$: an [`LWE +/// ciphertext`](`LweCiphertext`) with $\vec{a}\_{\mathsf{in}}=\left(a\_0, \cdots +/// a\_{n\_{\mathsf{in}}-1}\right)$ +/// - $\mathsf{BSK}\_{\vec{s}\_{\mathsf{in}}\rightarrow \vec{S}\_{\mathsf{out}}}$: a bootstrapping +/// key as defined above +/// - $\mathsf{LUT} \in \mathcal{R}\_q$: a LUT represented as a polynomial \_with redundancy\_ +/// +/// ###### outputs: +/// - $\mathsf{ct}\_{\mathsf{out}} \in \mathsf{LWE}^{n\_{\mathsf{out}}}\_{\vec{s}\_{\mathsf{out}}} +/// \left( \mathsf{LUT(pt)} \right)$: an [`LWE ciphertext`](`LweCiphertext`) +/// +/// ###### algorithm: +/// 1. Compute $\tilde{a}\_i \in \mathbb{Z}\_{2N\_{\mathsf{out}}} \leftarrow \lfloor \frac{2 +/// N\_{\mathsf{out}} \cdot a\_i}{q} \rceil$, for $i= 0, 1, \ldots, n\_{\mathsf{in}-1}$ +/// 2. Compute $\tilde{b}\_\mathsf{in} \in \mathbb{Z}\_{2N\_{\mathsf{out}}} \leftarrow \lfloor +/// \frac{2 N\_{\mathsf{out}} \cdot b\_\mathsf{in}}{q} \rceil$ +/// 3. Set $\mathsf{ACC} = (0, \ldots, 0, \mathsf{LUT} \cdot X^{-\tilde{b}\_\mathsf{in}})$ +/// 4. Compute $\mathsf{ACC} = \mathsf{CMux}(\overline{\overline{\mathsf{CT}\_i}}, \mathsf{ACC} +/// \cdot X^{\tilde{a}\_i}, \mathsf{ACC})$, for $i= 0, 1, \ldots, n\_{\mathsf{in}-1}$ +/// 5. Output $\mathsf{ct}\_{\mathsf{out}} \leftarrow \mathsf{SampleExtract}(\mathsf{ACC})$ #[derive(Clone, Debug, PartialEq, Eq, serde::Serialize, serde::Deserialize)] pub struct LweBootstrapKey { // An LweBootstrapKey is literally a GgswCiphertextList, so we wrap a GgswCiphetextList and use diff --git a/tfhe/src/core_crypto/entities/lwe_ciphertext.rs b/tfhe/src/core_crypto/entities/lwe_ciphertext.rs index 771d65004..ddc7105e6 100644 --- a/tfhe/src/core_crypto/entities/lwe_ciphertext.rs +++ b/tfhe/src/core_crypto/entities/lwe_ciphertext.rs @@ -1,3 +1,5 @@ +//! Module containing the definition of the LweCiphertext. + use crate::core_crypto::commons::parameters::*; use crate::core_crypto::commons::traits::*; @@ -91,6 +93,38 @@ impl<'data, T> CreateFrom<&'data mut [T]> for LweBody<&'data mut T> { /// In an LWE ciphertext, it is the length of the vector $\vec{a}$. /// At [`encryption`](`crate::core_crypto::algorithms::encrypt_lwe_ciphertext`) time, it is /// the number of uniformly random integers generated. +/// +/// ## LWE Encryption +/// ###### inputs: +/// - $\mathsf{pt}\in\mathbb{Z}\_q$: a plaintext +/// - $\vec{s}\in\mathbb{Z}\_q^n$: a secret key +/// - $\mathcal{D\_{\sigma^2,\mu}}$: a normal distribution of variance $\sigma^2$ and a mean $\mu$ +/// +/// ###### outputs: +/// - $\mathsf{ct} = \left( \vec{a} , b\right) \in \mathsf{LWE}^n\_{\vec{s}}( \mathsf{pt} )\subseteq +/// \mathbb{Z}\_q^{(n+1)}$: an LWE ciphertext +/// +/// ###### algorithm: +/// 1. uniformly sample a vector $\vec{a}\in\mathbb{Z}\_q^n$ +/// 2. sample an integer error term $e \hookleftarrow \mathcal{D\_{\sigma^2,\mu}}$ +/// 3. compute $b = \left\langle \vec{a} , \vec{s} \right\rangle + \mathsf{pt} + e \in\mathbb{Z}\_q$ +/// 4. output $\left( \vec{a} , b\right)$ +/// +/// ## LWE Decryption +/// ###### inputs: +/// - $\mathsf{ct} = \left( \vec{a} , b\right) \in \mathsf{LWE}^n\_{\vec{s}}( \mathsf{pt} )\subseteq +/// \mathbb{Z}\_q^{(n+1)}$: an LWE ciphertext +/// - $\vec{s}\in\mathbb{Z}\_q^n$: a secret key +/// +/// ###### outputs: +/// - $\mathsf{pt}\in\mathbb{Z}\_q$: a plaintext +/// +/// ###### algorithm: +/// 1. compute $\mathsf{pt} = b - \left\langle \vec{a} , \vec{s} \right\rangle \in\mathbb{Z}\_q$ +/// 3. output $\mathsf{pt}$ +/// +/// **Remark:** Observe that the decryption is followed by a decoding phase that will contain a +/// rounding. #[derive(Clone, Debug, PartialEq, Eq, serde::Serialize, serde::Deserialize)] pub struct LweCiphertext { data: C, diff --git a/tfhe/src/core_crypto/entities/lwe_ciphertext_list.rs b/tfhe/src/core_crypto/entities/lwe_ciphertext_list.rs index 5eccfcb90..197eb2443 100644 --- a/tfhe/src/core_crypto/entities/lwe_ciphertext_list.rs +++ b/tfhe/src/core_crypto/entities/lwe_ciphertext_list.rs @@ -1,3 +1,5 @@ +//! Module containing the definition of the LweCiphertextList. + use crate::core_crypto::commons::parameters::*; use crate::core_crypto::commons::traits::*; use crate::core_crypto::entities::*; diff --git a/tfhe/src/core_crypto/entities/lwe_keyswitch_key.rs b/tfhe/src/core_crypto/entities/lwe_keyswitch_key.rs index 8c5c02559..e205c0a45 100644 --- a/tfhe/src/core_crypto/entities/lwe_keyswitch_key.rs +++ b/tfhe/src/core_crypto/entities/lwe_keyswitch_key.rs @@ -1,3 +1,5 @@ +//! Module containing the definition of the LweKeyswitchKey. + use crate::core_crypto::commons::parameters::*; use crate::core_crypto::commons::traits::*; use crate::core_crypto::entities::*; @@ -23,6 +25,54 @@ use crate::core_crypto::entities::*; /// where $\vec{s}\_{\mathsf{in}} = \left( s\_0 , \cdots , s\_{\mathsf{in}-1} \right)$ and for all /// $0\le i { data: C, diff --git a/tfhe/src/core_crypto/entities/lwe_private_functional_packing_keyswitch_key.rs b/tfhe/src/core_crypto/entities/lwe_private_functional_packing_keyswitch_key.rs index b1b020e6a..fed591066 100644 --- a/tfhe/src/core_crypto/entities/lwe_private_functional_packing_keyswitch_key.rs +++ b/tfhe/src/core_crypto/entities/lwe_private_functional_packing_keyswitch_key.rs @@ -1,3 +1,5 @@ +//! Module containing the definition of the LwePrivateFunctionalPackingKeyswitchKey. + use crate::core_crypto::commons::parameters::*; use crate::core_crypto::commons::traits::*; use crate::core_crypto::entities::*; diff --git a/tfhe/src/core_crypto/entities/lwe_private_functional_packing_keyswitch_key_list.rs b/tfhe/src/core_crypto/entities/lwe_private_functional_packing_keyswitch_key_list.rs index 6270475c6..04c01fb19 100644 --- a/tfhe/src/core_crypto/entities/lwe_private_functional_packing_keyswitch_key_list.rs +++ b/tfhe/src/core_crypto/entities/lwe_private_functional_packing_keyswitch_key_list.rs @@ -1,3 +1,5 @@ +//! Module containing the definition of the LwePrivateFunctionalPackingKeyswitchKeyList. + use crate::core_crypto::commons::parameters::*; use crate::core_crypto::commons::traits::*; use crate::core_crypto::entities::*; diff --git a/tfhe/src/core_crypto/entities/lwe_public_key.rs b/tfhe/src/core_crypto/entities/lwe_public_key.rs index 57d5871fb..969e11542 100644 --- a/tfhe/src/core_crypto/entities/lwe_public_key.rs +++ b/tfhe/src/core_crypto/entities/lwe_public_key.rs @@ -1,3 +1,5 @@ +//! Module containing the definition of the LwePublicKey. + use crate::core_crypto::commons::parameters::*; use crate::core_crypto::commons::traits::*; use crate::core_crypto::entities::*; diff --git a/tfhe/src/core_crypto/entities/lwe_secret_key.rs b/tfhe/src/core_crypto/entities/lwe_secret_key.rs index 71be75d94..22742b234 100644 --- a/tfhe/src/core_crypto/entities/lwe_secret_key.rs +++ b/tfhe/src/core_crypto/entities/lwe_secret_key.rs @@ -1,3 +1,5 @@ +//! Module containing the definition of the LweSecretKey. + use crate::core_crypto::algorithms::*; use crate::core_crypto::commons::generators::SecretRandomGenerator; use crate::core_crypto::commons::math::random::{RandomGenerable, UniformBinary}; diff --git a/tfhe/src/core_crypto/entities/mod.rs b/tfhe/src/core_crypto/entities/mod.rs index 437c1a1e9..b907fe84d 100644 --- a/tfhe/src/core_crypto/entities/mod.rs +++ b/tfhe/src/core_crypto/entities/mod.rs @@ -1,3 +1,8 @@ +//! Module containing the definitions of the entities. +//! +//! Entities represent either mathematical or cryptographic objects. They contain usual methods +//! associated to the object, e.g., `get_mask` for the entity `LweCiphertext`. + pub mod cleartext; pub mod ggsw_ciphertext; pub mod ggsw_ciphertext_list; diff --git a/tfhe/src/core_crypto/entities/plaintext.rs b/tfhe/src/core_crypto/entities/plaintext.rs index 96fc1d661..6e2201f74 100644 --- a/tfhe/src/core_crypto/entities/plaintext.rs +++ b/tfhe/src/core_crypto/entities/plaintext.rs @@ -1,3 +1,5 @@ +//! Module containing the definition of the Plaintext. + use crate::core_crypto::commons::traits::*; /// A plaintext (encoded) value. diff --git a/tfhe/src/core_crypto/entities/plaintext_list.rs b/tfhe/src/core_crypto/entities/plaintext_list.rs index 22c80c4e6..de136aeeb 100644 --- a/tfhe/src/core_crypto/entities/plaintext_list.rs +++ b/tfhe/src/core_crypto/entities/plaintext_list.rs @@ -1,3 +1,5 @@ +//! Module containing the definition of the PlaintextList. + use crate::core_crypto::commons::parameters::*; use crate::core_crypto::commons::traits::*; use crate::core_crypto::entities::*; diff --git a/tfhe/src/core_crypto/entities/polynomial.rs b/tfhe/src/core_crypto/entities/polynomial.rs index 3edd2986f..7b04bdcb2 100644 --- a/tfhe/src/core_crypto/entities/polynomial.rs +++ b/tfhe/src/core_crypto/entities/polynomial.rs @@ -1,3 +1,5 @@ +//! Module containing the definition of the Polynomial. + use crate::core_crypto::commons::parameters::*; use crate::core_crypto::commons::traits::*; use std::ops::{Deref, DerefMut}; diff --git a/tfhe/src/core_crypto/entities/polynomial_list.rs b/tfhe/src/core_crypto/entities/polynomial_list.rs index b3af0b8a4..aa690b1e0 100644 --- a/tfhe/src/core_crypto/entities/polynomial_list.rs +++ b/tfhe/src/core_crypto/entities/polynomial_list.rs @@ -1,3 +1,5 @@ +//! Module containing the definition of the PolynomialList. + use crate::core_crypto::commons::parameters::*; use crate::core_crypto::commons::traits::*; use crate::core_crypto::entities::*; diff --git a/tfhe/src/core_crypto/entities/seeded_ggsw_ciphertext.rs b/tfhe/src/core_crypto/entities/seeded_ggsw_ciphertext.rs index c04f7ee50..3d3cc1e8e 100644 --- a/tfhe/src/core_crypto/entities/seeded_ggsw_ciphertext.rs +++ b/tfhe/src/core_crypto/entities/seeded_ggsw_ciphertext.rs @@ -1,3 +1,5 @@ +//! Module containing the definition of the SeededGgswCiphertext. + use crate::core_crypto::algorithms::*; use crate::core_crypto::commons::math::random::{ActivatedRandomGenerator, CompressionSeed}; use crate::core_crypto::commons::parameters::*; diff --git a/tfhe/src/core_crypto/entities/seeded_ggsw_ciphertext_list.rs b/tfhe/src/core_crypto/entities/seeded_ggsw_ciphertext_list.rs index b29352d62..ca3a98d0e 100644 --- a/tfhe/src/core_crypto/entities/seeded_ggsw_ciphertext_list.rs +++ b/tfhe/src/core_crypto/entities/seeded_ggsw_ciphertext_list.rs @@ -1,3 +1,5 @@ +//! Module containing the definition of the SeededGgswCiphertextList. + use crate::core_crypto::algorithms::*; use crate::core_crypto::commons::math::random::{ActivatedRandomGenerator, CompressionSeed}; use crate::core_crypto::commons::parameters::*; diff --git a/tfhe/src/core_crypto/entities/seeded_glwe_ciphertext.rs b/tfhe/src/core_crypto/entities/seeded_glwe_ciphertext.rs index 0a4f69cdb..80646154d 100644 --- a/tfhe/src/core_crypto/entities/seeded_glwe_ciphertext.rs +++ b/tfhe/src/core_crypto/entities/seeded_glwe_ciphertext.rs @@ -1,3 +1,5 @@ +//! Module containing the definition of the SeededGlweCiphertext. + use crate::core_crypto::algorithms::*; use crate::core_crypto::commons::math::random::{ActivatedRandomGenerator, CompressionSeed}; use crate::core_crypto::commons::parameters::*; diff --git a/tfhe/src/core_crypto/entities/seeded_glwe_ciphertext_list.rs b/tfhe/src/core_crypto/entities/seeded_glwe_ciphertext_list.rs index 27447f41e..ef300d0dd 100644 --- a/tfhe/src/core_crypto/entities/seeded_glwe_ciphertext_list.rs +++ b/tfhe/src/core_crypto/entities/seeded_glwe_ciphertext_list.rs @@ -1,3 +1,5 @@ +//! Module containing the definition of the SeededGlweCiphertextList. + use crate::core_crypto::algorithms::*; use crate::core_crypto::commons::math::random::{ActivatedRandomGenerator, CompressionSeed}; use crate::core_crypto::commons::parameters::*; diff --git a/tfhe/src/core_crypto/entities/seeded_lwe_bootstrap_key.rs b/tfhe/src/core_crypto/entities/seeded_lwe_bootstrap_key.rs index 59b318a30..711bb555b 100644 --- a/tfhe/src/core_crypto/entities/seeded_lwe_bootstrap_key.rs +++ b/tfhe/src/core_crypto/entities/seeded_lwe_bootstrap_key.rs @@ -1,3 +1,5 @@ +//! Module containing the definition of the SeededLweBoostrapKey. + use crate::core_crypto::algorithms::*; use crate::core_crypto::commons::math::random::{ActivatedRandomGenerator, CompressionSeed}; use crate::core_crypto::commons::parameters::*; diff --git a/tfhe/src/core_crypto/entities/seeded_lwe_ciphertext_list.rs b/tfhe/src/core_crypto/entities/seeded_lwe_ciphertext_list.rs index b1ee2d745..7db98085a 100644 --- a/tfhe/src/core_crypto/entities/seeded_lwe_ciphertext_list.rs +++ b/tfhe/src/core_crypto/entities/seeded_lwe_ciphertext_list.rs @@ -1,3 +1,5 @@ +//! Module containing the definition of the SeededLweCiphertextList. + use crate::core_crypto::algorithms::*; use crate::core_crypto::commons::math::random::{ActivatedRandomGenerator, CompressionSeed}; use crate::core_crypto::commons::parameters::*; diff --git a/tfhe/src/core_crypto/entities/seeded_lwe_keyswitch_key.rs b/tfhe/src/core_crypto/entities/seeded_lwe_keyswitch_key.rs index 476531441..26a343f17 100644 --- a/tfhe/src/core_crypto/entities/seeded_lwe_keyswitch_key.rs +++ b/tfhe/src/core_crypto/entities/seeded_lwe_keyswitch_key.rs @@ -1,3 +1,5 @@ +//! Module containing the definition of the SeededLweKeyswitchKey. + use crate::core_crypto::algorithms::*; use crate::core_crypto::commons::math::random::{ActivatedRandomGenerator, CompressionSeed}; use crate::core_crypto::commons::parameters::*; diff --git a/tfhe/src/core_crypto/entities/seeded_lwe_public_key.rs b/tfhe/src/core_crypto/entities/seeded_lwe_public_key.rs index 35df687a3..4e9524997 100644 --- a/tfhe/src/core_crypto/entities/seeded_lwe_public_key.rs +++ b/tfhe/src/core_crypto/entities/seeded_lwe_public_key.rs @@ -1,3 +1,5 @@ +//! Module containing the definition of the SeededLwePublicKey. + use crate::core_crypto::algorithms::*; use crate::core_crypto::commons::math::random::{ActivatedRandomGenerator, CompressionSeed}; use crate::core_crypto::commons::parameters::*; diff --git a/tfhe/src/core_crypto/fft_impl/mod.rs b/tfhe/src/core_crypto/fft_impl/mod.rs index 1044bbf08..27405f34e 100644 --- a/tfhe/src/core_crypto/fft_impl/mod.rs +++ b/tfhe/src/core_crypto/fft_impl/mod.rs @@ -1,3 +1,4 @@ +#![doc(hidden)] pub use concrete_fft::c64; use core::mem::MaybeUninit; diff --git a/tfhe/src/core_crypto/mod.rs b/tfhe/src/core_crypto/mod.rs index 209d1c358..187b816b3 100644 --- a/tfhe/src/core_crypto/mod.rs +++ b/tfhe/src/core_crypto/mod.rs @@ -1,4 +1,4 @@ -//! Welcome to the TFHE-rs `core_crypto` module documentation! +//! # Description //! //! This library contains a set of low-level primitives which can be used to implement *Fully //! Homomorphically Encrypted* (FHE) programs. In a nutshell, fully homomorphic encryption makes it diff --git a/tfhe/src/core_crypto/prelude.rs b/tfhe/src/core_crypto/prelude.rs index a99c060c0..7891253fa 100644 --- a/tfhe/src/core_crypto/prelude.rs +++ b/tfhe/src/core_crypto/prelude.rs @@ -1,3 +1,8 @@ +//! Module with the definition of the prelude. +//! +//! The TFHE-rs preludes include convenient imports. +//! Having `tfhe::core_crypto::prelude::*;` should be enough to start using the lib. + pub use super::algorithms::{polynomial_algorithms, slice_algorithms, *}; pub use super::commons::dispersion::*; pub use super::commons::generators::{EncryptionRandomGenerator, SecretRandomGenerator}; diff --git a/tfhe/src/core_crypto/seeders.rs b/tfhe/src/core_crypto/seeders.rs index fd2c45bf1..0593663b7 100644 --- a/tfhe/src/core_crypto/seeders.rs +++ b/tfhe/src/core_crypto/seeders.rs @@ -1,3 +1,9 @@ +//! This module contains methods to get a random seed. +//! +//! Seeding depends on the underlying OS/hardware. Here, many strategies are proposed to (securely) +//! obtain a seed. A random seed is useful to have compressed keys and is used as a prerequisite +//! for cryptographically secure pseudo random number generators. + pub use crate::core_crypto::commons::math::random::Seeder; #[cfg(all(target_os = "macos", not(feature = "__wasm_api")))] pub use concrete_csprng::seeders::AppleSecureEnclaveSeeder; diff --git a/tfhe/src/lib.rs b/tfhe/src/lib.rs index d1f807f44..e6fb0d458 100644 --- a/tfhe/src/lib.rs +++ b/tfhe/src/lib.rs @@ -1,3 +1,7 @@ +//! Welcome to the TFHR-rs API documentation! +//! +//! TFHE-rs is a fully homomorphic encryption (FHE) library that implements Zama's variant of TFHE. + #![cfg_attr(feature = "__wasm_api", allow(dead_code))] #![cfg_attr(feature = "nightly-avx512", feature(stdsimd, avx512_target_feature))] #![deny(rustdoc::broken_intra_doc_links)] @@ -6,11 +10,22 @@ pub mod c_api; #[cfg(feature = "boolean")] +/// Welcome to the TFHE-rs [`boolean`](`crate::boolean`) module documentation! +/// +/// # Special module attributes /// cbindgen:ignore pub mod boolean; + +/// Welcome to the TFHE-rs [`core_crypto`](`crate::core_crypto`) module documentation! +/// +/// # Special module attributes /// cbindgen:ignore pub mod core_crypto; + #[cfg(feature = "shortint")] +/// Welcome to the TFHE-rs [`shortint`](`crate::shortint`) module documentation! +/// +/// # Special module attributes /// cbindgen:ignore pub mod shortint; diff --git a/tfhe/src/shortint/ciphertext/mod.rs b/tfhe/src/shortint/ciphertext/mod.rs index fa837f126..19c9d61c9 100644 --- a/tfhe/src/shortint/ciphertext/mod.rs +++ b/tfhe/src/shortint/ciphertext/mod.rs @@ -1,14 +1,11 @@ -//! Module with the definition of a short-integer ciphertext. +//! Module with the definition of the Ciphertext. use crate::core_crypto::entities::*; use crate::shortint::parameters::{CarryModulus, MessageModulus}; use serde::{Deserialize, Deserializer, Serialize, Serializer}; use std::cmp; use std::fmt::Debug; -/// This indicates the number of operations that has been done. -/// -/// For instances, computing and addition increases this number by 1, whereas a multiplication by -/// a constant $\lambda$ increases it by $\lambda$. +/// This tracks the number of operations that has been done. #[derive(Debug, PartialEq, Eq, Copy, Clone, Serialize, Deserialize)] pub struct Degree(pub usize); @@ -77,8 +74,8 @@ impl Degree { } } -/// A structure representing a short-integer ciphertext. -/// It is used to evaluate a short-integer circuits homomorphically. +/// A structure representing a shortint ciphertext. +/// It is used to homomorphically evaluate a shortint circuits. /// Internally, it uses a LWE ciphertext. #[derive(Clone)] pub struct Ciphertext { diff --git a/tfhe/src/shortint/engine/mod.rs b/tfhe/src/shortint/engine/mod.rs index 2b957398c..5d62a414f 100644 --- a/tfhe/src/shortint/engine/mod.rs +++ b/tfhe/src/shortint/engine/mod.rs @@ -1,3 +1,8 @@ +//! Module with the engine definitions. +//! +//! Engines are required to abstract cryptographic notions and efficiently manage memory from the +//! underlying `core_crypto` module. + use crate::core_crypto::algorithms::*; use crate::core_crypto::commons::computation_buffers::ComputationBuffers; use crate::core_crypto::commons::generators::{ diff --git a/tfhe/src/shortint/mod.rs b/tfhe/src/shortint/mod.rs index 72c24cf04..6083d4d1e 100755 --- a/tfhe/src/shortint/mod.rs +++ b/tfhe/src/shortint/mod.rs @@ -1,5 +1,3 @@ -//! Welcome to the TFHE-rs `shortint` module documentation! -//! //! # Description //! //! This library makes it possible to execute modular operations over encrypted short integer. diff --git a/tfhe/src/shortint/parameters/mod.rs b/tfhe/src/shortint/parameters/mod.rs index 41ba376e6..b981dd559 100644 --- a/tfhe/src/shortint/parameters/mod.rs +++ b/tfhe/src/shortint/parameters/mod.rs @@ -1,5 +1,5 @@ #![allow(clippy::excessive_precision)] -//! Module with the definition of parameters for short-integers. +//! Module with the definition of cryptographic parameters. //! //! This module provides the structure containing the cryptographic parameters required for the //! homomorphic evaluation of integer circuits as well as a list of secure cryptographic parameter diff --git a/tfhe/src/shortint/parameters/parameters_wopbs.rs b/tfhe/src/shortint/parameters/parameters_wopbs.rs index 1acc92f36..5c955f728 100644 --- a/tfhe/src/shortint/parameters/parameters_wopbs.rs +++ b/tfhe/src/shortint/parameters/parameters_wopbs.rs @@ -1,3 +1,5 @@ +//! #Warning experimental + pub use crate::core_crypto::commons::dispersion::{DispersionParameter, StandardDev}; pub use crate::core_crypto::commons::parameters::{ DecompositionBaseLog, DecompositionLevelCount, GlweDimension, LweDimension, PolynomialSize, diff --git a/tfhe/src/shortint/parameters/parameters_wopbs_message_carry.rs b/tfhe/src/shortint/parameters/parameters_wopbs_message_carry.rs index dcb4b4dd1..bf2d1aaaa 100644 --- a/tfhe/src/shortint/parameters/parameters_wopbs_message_carry.rs +++ b/tfhe/src/shortint/parameters/parameters_wopbs_message_carry.rs @@ -1,3 +1,5 @@ +//! #Warning experimental + pub use crate::core_crypto::commons::dispersion::{DispersionParameter, StandardDev}; pub use crate::core_crypto::commons::parameters::{ DecompositionBaseLog, DecompositionLevelCount, GlweDimension, LweDimension, PolynomialSize, diff --git a/tfhe/src/shortint/prelude.rs b/tfhe/src/shortint/prelude.rs index 367f842d7..c081d1ef8 100644 --- a/tfhe/src/shortint/prelude.rs +++ b/tfhe/src/shortint/prelude.rs @@ -1,3 +1,9 @@ +//! Module with the definition of the prelude. +//! +//! The TFHE-rs preludes include convenient imports. +//! Having `tfhe::shortint::prelude::*;` should be enough to start using the lib. + +pub use super::ciphertext::Ciphertext; pub use super::client_key::ClientKey; pub use super::gen_keys; pub use super::parameters::{ @@ -11,6 +17,4 @@ pub use super::parameters::{ PARAM_MESSAGE_4_CARRY_4, }; pub use super::public_key::PublicKey; - -pub use super::ciphertext::Ciphertext; pub use super::server_key::ServerKey; diff --git a/tfhe/src/shortint/public_key/compressed.rs b/tfhe/src/shortint/public_key/compressed.rs index ef89df7cc..cb8fd56d6 100644 --- a/tfhe/src/shortint/public_key/compressed.rs +++ b/tfhe/src/shortint/public_key/compressed.rs @@ -1,4 +1,4 @@ -//! Module with the definition of the PublicKey. +//! Module with the definition of the compressed PublicKey. use crate::core_crypto::entities::*; use crate::shortint::ciphertext::Ciphertext; use crate::shortint::engine::ShortintEngine; diff --git a/tfhe/src/shortint/public_key/mod.rs b/tfhe/src/shortint/public_key/mod.rs index d8ddab391..3f15cf952 100644 --- a/tfhe/src/shortint/public_key/mod.rs +++ b/tfhe/src/shortint/public_key/mod.rs @@ -1,3 +1,5 @@ +//! Module with the definition of the encryption PublicKey. + pub mod compressed; pub mod standard; diff --git a/tfhe/src/shortint/server_key/compressed.rs b/tfhe/src/shortint/server_key/compressed.rs index 572d15a31..d662c2b29 100644 --- a/tfhe/src/shortint/server_key/compressed.rs +++ b/tfhe/src/shortint/server_key/compressed.rs @@ -1,3 +1,5 @@ +//! Module with the definition of the CompressedServerKey. + use super::MaxDegree; use crate::core_crypto::prelude::*; use crate::shortint::engine::ShortintEngine; diff --git a/tfhe/src/test_user_docs.rs b/tfhe/src/test_user_docs.rs index f674e405e..8437d61d9 100644 --- a/tfhe/src/test_user_docs.rs +++ b/tfhe/src/test_user_docs.rs @@ -5,10 +5,10 @@ doctest!("../docs/getting_started/quick_start.md", quick_start); doctest!("../docs/getting_started/operations.md", operations); // Booleans -doctest!("../docs/Booleans/parameters.md", booleans_parameters); -doctest!("../docs/Booleans/operations.md", booleans_operations); -doctest!("../docs/Booleans/serialization.md", booleans_serialization); -doctest!("../docs/Booleans/tutorial.md", booleans_tutorial); +doctest!("../docs/Boolean/parameters.md", booleans_parameters); +doctest!("../docs/Boolean/operations.md", booleans_operations); +doctest!("../docs/Boolean/serialization.md", booleans_serialization); +doctest!("../docs/Boolean/tutorial.md", booleans_tutorial); // Shortint doctest!("../docs/shortint/parameters.md", shortint_parameters); @@ -16,6 +16,13 @@ doctest!("../docs/shortint/serialization.md", shortint_serialization); doctest!("../docs/shortint/tutorial.md", shortint_tutorial); doctest!("../docs/shortint/operations.md", shortint_operations); +// core_crypto +doctest!( + "../docs/core_crypto/presentation.md", + core_crypto_presentation +); +doctest!("../docs/core_crypto/tutorial.md", core_crypto_turorial); + // doctest!("../docs/tutorials/serialization.md", serialization_tuto); // doctest!( // "../docs/tutorials/circuit_evaluation.md",