TFHE-rs
WebsiteLibrariesProduct & ServicesDevelopersSupport
1.0
1.0
  • Welcome to TFHE-rs
  • Get Started
    • What is TFHE-rs?
    • Installation
    • Quick start
    • Benchmarks
      • CPU Benchmarks
        • Integer
        • Programmable bootstrapping
      • GPU Benchmarks
        • Integer
        • Programmable bootstrapping
      • Zero-knowledge proof benchmarks
    • Security and cryptography
  • FHE Computation
    • Types
      • Integer
      • Strings
      • Array
    • Operations
      • Arithmetic operations
      • Bitwise operations
      • Comparison operations
      • Min/Max operations
      • Ternary conditional operations
      • Casting operations
      • Boolean Operations
      • String Operations
    • Core workflow
      • Configuration and key generation
      • Server key
      • Encryption
      • Decryption
      • Parameters
    • Data handling
      • Compressing ciphertexts/keys
      • Serialization/deserialization
      • Data versioning
    • Advanced features
      • Encrypted pseudo random values
      • Overflow detection
      • Public key encryption
      • Trivial ciphertexts
      • Zero-knowledge proofs
      • Multi-threading with Rayon crate
    • Tooling
      • PBS statistics
      • Generic trait bounds
      • Debugging
  • Configuration
    • Advanced Rust setup
    • GPU acceleration
    • Parallelized PBS
  • Integration
    • JS on WASM API
    • High-level API in C
  • Tutorials
    • Homomorphic parity bit
    • Homomorphic case changing on Ascii string
    • SHA256 with Boolean API
    • All tutorials
  • References
    • API references
    • Fine-grained APIs
      • Quick start
      • Boolean
        • Operations
        • Cryptographic parameters
        • Serialization/Deserialization
      • Shortint
        • Operations
        • Cryptographic parameters
        • Serialization/Deserialization
      • Integer
        • Operations
        • Cryptographic parameters
        • Serialization/Deserialization
    • Core crypto API
      • Quick start
      • Tutorial
  • Explanations
    • TFHE deep dive
  • Developers
    • Contributing
    • Release note
    • Feature request
    • Bug report
Powered by GitBook

Libraries

  • TFHE-rs
  • Concrete
  • Concrete ML
  • fhEVM

Developers

  • Blog
  • Documentation
  • Github
  • FHE resources

Company

  • About
  • Introduction to FHE
  • Media
  • Careers
On this page
  • General method to write an homomorphic circuit program
  • API levels.

Was this helpful?

Export as PDF
  1. References
  2. Fine-grained APIs

Quick start

This library makes it possible to execute homomorphic operations over encrypted data, where the data are either Booleans, short integers (named shortint in the rest of this documentation), or integers up to 256 bits. It allows you to execute a circuit on an untrusted server because both circuit inputs and outputs are kept private. Data are indeed encrypted on the client side, before being sent to the server. On the server side, every computation is performed on ciphertexts.

The server, however, has to know the circuit to be evaluated. At the end of the computation, the server returns the encryption of the result to the user. Then the user can decrypt it with the secret key.

General method to write an homomorphic circuit program

The overall process to write an homomorphic program is the same for all types. The basic steps for using the TFHE-rs library are the following:

  1. Choose a data type (Boolean, shortint, integer)

  2. Import the library

  3. Create client and server keys

  4. Encrypt data with the client key

  5. Compute over encrypted data using the server key

  6. Decrypt data with the client key

API levels.

This library has different modules, with different levels of abstraction.

There is the core_crypto module, which is the lowest level API with the primitive functions and types of the TFHE scheme.

Above the core_crypto module, there are the Boolean, shortint, and integer modules, which contain easy to use APIs enabling evaluation of Boolean, short integer, and integer circuits.

Finally, there is the high-level module built on top of the Boolean, shortint, integer modules. This module is meant to abstract cryptographic complexities: no cryptographical knowledge is required to start developing an FHE application. Another benefit of the high-level module is the drastically simplified development process compared to lower level modules.

high-level API

TFHE-rs exposes a high-level API by default that includes datatypes that try to match Rust's native types by having overloaded operators (+, -, ...).

Here is an example of how the high-level API is used:

Use the --release flag to run this example (eg: cargo run --release)

use tfhe::{ConfigBuilder, generate_keys, set_server_key, FheUint8};
use tfhe::prelude::*;

fn main() {
    let config = ConfigBuilder::default()
        .build();

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

    set_server_key(server_key);

    let clear_a = 27u8;
    let clear_b = 128u8;

    let a = FheUint8::encrypt(clear_a, &client_key);
    let b = FheUint8::encrypt(clear_b, &client_key);

    let result = a + b;

    let decrypted_result: u8 = result.decrypt(&client_key);

    let clear_result = clear_a + clear_b;

    assert_eq!(decrypted_result, clear_result);
}

Boolean example

Here is an example of how the library can be used to evaluate a Boolean circuit:

Use the --release flag to run this example (eg: cargo run --release)

use tfhe::boolean::prelude::*;

fn main() {
    // We generate a set of client/server keys, using the default parameters:
    let (client_key, server_key) = gen_keys();

    // We use the client secret key to encrypt two messages:
    let ct_1 = client_key.encrypt(true);
    let ct_2 = client_key.encrypt(false);

    // We use the server public key to execute a boolean circuit:
    // if ((NOT ct_2) NAND (ct_1 AND ct_2)) then (NOT ct_2) else (ct_1 AND ct_2)
    let ct_3 = server_key.not(&ct_2);
    let ct_4 = server_key.and(&ct_1, &ct_2);
    let ct_5 = server_key.nand(&ct_3, &ct_4);
    let ct_6 = server_key.mux(&ct_5, &ct_3, &ct_4);

    // We use the client key to decrypt the output of the circuit:
    let output = client_key.decrypt(&ct_6);
    assert!(output);
}

shortint example

Here is a full example using shortint:

Use the --release flag to run this example (eg: cargo run --release)

use tfhe::shortint::prelude::*;

fn main() {
    // We generate a set of client/server keys
    // using parameters with 2 bits of message and 2 bits of carry
    let (client_key, server_key) = gen_keys(PARAM_MESSAGE_2_CARRY_2);

    let msg1 = 1;
    let msg2 = 0;

    let modulus = client_key.parameters.message_modulus().0;

    // We use the client key to encrypt two messages:
    let ct_1 = client_key.encrypt(msg1);
    let ct_2 = client_key.encrypt(msg2);

    // We use the server public key to execute an integer circuit:
    let ct_3 = server_key.add(&ct_1, &ct_2);

    // We use the client key to decrypt the output of the circuit:
    let output = client_key.decrypt(&ct_3);
    assert_eq!(output, (msg1 + msg2) % modulus);
}

integer example

Use the --release flag to run this example (eg: cargo run --release)

use tfhe::integer::gen_keys_radix;
use tfhe::shortint::parameters::PARAM_MESSAGE_2_CARRY_2;

fn main() {
    // We generate keys to encrypt 16 bits radix-encoded integers
    // using 8 blocks of 2 bits
    let (cks, sks) = gen_keys_radix(PARAM_MESSAGE_2_CARRY_2, 8);

    let clear_a = 2382u16;
    let clear_b = 29374u16;

    let mut a = cks.encrypt(clear_a as u64);
    let mut b = cks.encrypt(clear_b as u64);

    let encrypted_max = sks.smart_max_parallelized(&mut a, &mut b);
    let decrypted_max: u64 = cks.decrypt(&encrypted_max);

    assert_eq!(decrypted_max as u16, clear_a.max(clear_b))
}
PreviousFine-grained APIsNextBoolean

Last updated 2 months ago

Was this helpful?

The library is simple to use and can evaluate homomorphic circuits of arbitrary length. The description of the algorithms can be found in the paper (also available as ).

TFHE
ePrint 2018/421