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 and/or Boolean modules (based on core_crypto) are recommended.
The core_crypto module offers an API to low-level cryptographic primitives and objects, like lwe_encryption or rlwe_ciphertext. The goal is to propose an easy-to-use API for cryptographers.
The overall code architecture is split in two parts: one for entity definitions and another focused on algorithms. 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 add or modify existing algorithms, or to have direct access to the raw data. Even if the LWE ciphertext object is defined, along with functions giving access to the body, it is also possible to bypass these to get directly the ith element of LWE mask.
For instance, the code to encrypt and then decrypt a message looks like:
use tfhe::core_crypto::prelude::*;// DISCLAIMER: these toy example parameters are not guaranteed to be secure or yield correct// computations// Define parameters for LweCiphertext creationlet lwe_dimension =LweDimension(742);let lwe_noise_distribution =Gaussian::from_dispersion_parameter(StandardDev(0.000007069849454709433), 0.0);let ciphertext_modulus =CiphertextModulus::new_native();// Create the PRNGletmut seeder =new_seeder();let seeder = seeder.as_mut();letmut encryption_generator =EncryptionRandomGenerator::<ActivatedRandomGenerator>::new(seeder.seed(), seeder);letmut secret_generator =SecretRandomGenerator::<ActivatedRandomGenerator>::new(seeder.seed());// Create the LweSecretKeylet lwe_secret_key =allocate_and_generate_new_binary_lwe_secret_key(lwe_dimension, &mut secret_generator);// Create the plaintextlet msg =3u64;let plaintext =Plaintext(msg <<60);// Create a new LweCiphertextletmut lwe =LweCiphertext::new(0u64, lwe_dimension.to_lwe_size(), ciphertext_modulus);encrypt_lwe_ciphertext(&lwe_secret_key,&mut lwe, plaintext, lwe_noise_distribution,&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 encodinglet cleartext = rounded >>60;// Check we recovered the original messageassert_eq!(cleartext, msg);