Announcing TFHE-rs v0.2.0

April 13, 2023
Jean-Baptiste Orfila

TFHE-rs v0.2.0 adds support for large homomorphic unsigned integers up to 256 bits. A high-level API, along with booleans and shortints, have been added to make your builds easier. The new update also integrates a parallelized version of Programmable Bootstrapping (PBS), improving its latency.

Large precision integers

TFHE-rs now offers you the possibility to work with unsigned integers up to 256 bits. Additions, subtractions, multiplications, and some common programming-related operations—like shifting and bitwise operations—have been added. 

Using RadixCiphertext or CRTCiphertext, the ‘integer’ API lets you choose one of two possibilities to represent large messages: Radix decomposition or Residue Number Systems (RNS). Your choice will depend on the relevant use case. Radix includes more operators while the RNS decomposition offers faster arithmetic operators.

Here is an example which first computes a min between two Radix-based ciphertexts, then performs a multiplication between two CRT-based ciphertexts:

let param = PARAM_MESSAGE_2_CARRY_2;

//Radix-based integers over 8 bits
let num_block = 4;
let (cks, sks) = gen_keys_radix(&param, num_block);

let clear_0 = 157;
let clear_1 = 127;

let mut ct_0 = cks.encrypt(clear_0);
let mut ct_1 = cks.encrypt(clear_1);

let ct_res = sks.smart_min_parallelized(&mut ct_0, &mut ct_1);

let dec_res = cks.decrypt(&ct_res);

assert_eq!(u64::min(clear_0, clear_1), dec_res)
//CRT-based integer modulus 3*4*5*7 = 420
//To work with homomorphic unsigned integers > 8 bits
let basis = vec![3,4,5,7];
let modulus = 420;

let param = PARAM_MESSAGE_3_CARRY_3;
let (cks, sks) = gen_keys_crt(&param, basis.clone());


let clear_0 = 234;
let clear_1 = 123;


// encryption of an integer
let mut ct_zero = cks.encrypt(clear_0);
let mut ct_one = cks.encrypt(clear_1);


// mul the two ciphertexts
let ct_res = sks.smart_crt_mul(&mut ct_zero, &mut ct_one);

// decryption of ct_res
let dec_res = cks.decrypt(&ct_res);

assert_eq!((clear_0*clear_1) % modulus, dec_res % modulus);

High-level API

TFHE-rs now includes a high-level API. This mimics the Rust approach by defining types related to homomorphic unsigned integers. Arithmetic operators are wrapped so that they are called in the same manner as clear operations, for instance, an addition between two ciphertexts is done using the ‘+’ symbol. Since comparison operators cannot be overloaded in Rust, they are called using a simple function (e.g.,--“.eq()” for an equality). Complex cryptographic operations have been eliminated. Radix is the default decomposition used to represent large integers.

This example shows how to compute a shift, a multiplication, and an addition over encrypted unsigned integers of 16 bits:

// Client-side
let config = ConfigBuilder::all_disabled()
   .enable_default_uint16()
   .build();

let (client_key, server_key) = generate_keys(config);

let clear_a = 12345u16;
let clear_b = 6789u16;
let clear_c = 1011u16;

let a = FheUint16::encrypt(clear_a, &client_key);
let b = FheUint16::encrypt(clear_b, &client_key);
let c = FheUint16::encrypt(clear_c, &client_key);

// Server-side
set_server_key(server_key);
let result = ((a << 2u16) * b) + c;

// Client-side
let decrypted_result: u16 = result.decrypt(&client_key);
let clear_result = ((clear_a << 2) * clear_b) + clear_c;
assert_eq!(decrypted_result, clear_result);

To help integrate TFHE-rs in existing applications, a C API is also included.

Additional Features

The latest update of TFHE-rs also includes:

  • The choice of encryption key: At key generation, the client obtains two secret keys: a large one and a small one. To maximize performance when computing a PBS, the larger key became the default. You now have the choice between the two secret keys;
  • A smaller public encryption key: As a consequence of choosing an encryption key, a smaller secret encryption key implies a smaller public key. The size has been reduced from several GB to less than one GB;
  • The ability to compute a PBS over 128-bit ciphertext: The new version of Concrete-FFT has been integrated, so it is now possible to compute PBS over 128-bit ciphertexts; 
  • The choice of the ciphertext modulus: For cryptographers using the lower API (namely, core-crypto), the modulus ciphertext can be modified to use any powers of two smaller than 2^128;
  • Parallel Programmable Bootstrapping: The lower API of TFHE-rs now includes a parallel implementation of PBS, based on research conducted by Joye-Paillier in [JP22]. A dedicated blog post will be soon published about relevant performance enhancements.

What’s next?

The next version of TFHE-rs will include faster arithmetic operators by including the CRT decomposition in the high-level API by default. Overall, performance will improve through standardizing parallel bootstrapping within the process. Further cryptographic features will also be integrated, so stay tuned for news on future updates. 

Additional links

[JP22]: Joye, M., Paillier, P. (2022). Blind Rotation in Fully Homomorphic Encryption with Extended Keys. In: Dolev, S., Katz, J., Meisels, A. (eds) Cyber Security, Cryptology, and Machine Learning. CSCML 2022. Lecture Notes in Computer Science, vol 13301. Springer, Cham. https://doi.org/10.1007/978-3-031-07689-3_1

Read more related posts