doc(tfhe): add integer example + mention --release

This commit is contained in:
tmontaigu
2023-04-04 12:18:16 +02:00
parent c206aa89b8
commit b8e64377fa
4 changed files with 90 additions and 16 deletions

View File

@@ -25,7 +25,7 @@
</a>
</p>
**TFHE-rs** is a pure Rust implementation of TFHE for boolean and small integer
**TFHE-rs** is a pure Rust implementation of TFHE for boolean and integer
arithmetics over encrypted data. It includes:
- a **Rust** API
- a **C** API
@@ -63,27 +63,31 @@ tfhe = { version = "*", features = ["boolean", "shortint", "integer", "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
Note that when running code that uses `tfhe-rs`, it is highly recommended
to run in release mode with cargo`s `--release` flag to have the best performances possible,
eg: `cargo run --release`.
Here is a full example evaluating a Boolean circuit:
```rust
use tfhe::boolean::prelude::*;
fn main() {
// We generate a set of client/server keys, using the default parameters:
// We generate a set of client/server keys, using the default parameters:
let (mut client_key, mut server_key) = gen_keys();
// We use the client secret key to encrypt two messages:
// 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)
// 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:
// We use the client key to decrypt the output of the circuit:
let output = client_key.decrypt(&ct_6);
assert_eq!(output, true);
}
@@ -124,6 +128,30 @@ fn main() {
}
```
An example using integer:
```rust
use tfhe::integer::gen_keys_radix;
use tfhe::shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
fn main() {
// We create keys to create 16 bits 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))
}
```
## Contributing
There are two ways to contribute to TFHE-rs:

View File

@@ -5,9 +5,15 @@
To use `TFHE-rs` in your project, you first need to add it as a dependency in your `Cargo.toml`:
```toml
tfhe = { version = "0.2.0", features = [ "boolean", "shortint", "x86_64-unix" ] }
tfhe = { version = "0.2.0", features = [ "boolean", "shortint", "integer", "x86_64-unix" ] }
```
{% hint style="info" %}
When running code that uses `tfhe-rs`, it is highly recommended
to run in release mode with cargo's `--release` flag to have the best performances possible,
eg: `cargo run --release`.
{% endhint %}
## Choosing your features
`TFHE-rs` exposes different `cargo features` to customize the types and features used.
@@ -16,10 +22,11 @@ tfhe = { version = "0.2.0", features = [ "boolean", "shortint", "x86_64-unix" ]
This crate exposes two kinds of data types. Each kind is enabled by activating its corresponding feature in the TOML line. Each kind may have multiple types:
| Kind | Features | Type(s) |
| --------- | ---------- | ----------------------- |
| Booleans | `boolean` | Booleans |
| ShortInts | `shortint` | Short unsigned integers |
| Kind | Features | Type(s) |
| --------- | ---------- | --------------------------------- |
| Booleans | `boolean` | Booleans |
| ShortInts | `shortint` | Short unsigned integers |
| Integers | `integer` | Arbitrary-sized unsigned integers |
### Serialization.

View File

@@ -19,25 +19,29 @@ The overall process to write an homomorphic program is the same for both Boolean
Here is an example to illustrate how the library can be used to evaluate a Boolean circuit:
{% hint style="info" %}
Use the `--release` flag to run this example (eg: `cargo run --release`)
{% endhint %}
```rust
use tfhe::boolean::prelude::*;
fn main() {
// We generate a set of client/server keys, using the default parameters:
// 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:
// 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)
// 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:
// We use the client key to decrypt the output of the circuit:
let output = client_key.decrypt(&ct_6);
assert_eq!(output, true);
}
@@ -47,6 +51,10 @@ fn main() {
And here is a full example using shortint:
{% hint style="info" %}
Use the `--release` flag to run this example (eg: `cargo run --release`)
{% endhint %}
```rust
use tfhe::shortint::prelude::*;
@@ -72,4 +80,32 @@ fn main() {
}
```
### Integer example.
{% hint style="info" %}
Use the `--release` flag to run this example (eg: `cargo run --release`)
{% endhint %}
```rust
use tfhe::integer::gen_keys_radix;
use tfhe::shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
fn main() {
// We create keys for radix represention to create 16 bits 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))
}
```
The library is pretty simple to use, and can evaluate **homomorphic circuits of arbitrary length**. The description of the algorithms can be found in the [TFHE](https://doi.org/10.1007/s00145-019-09319-x) paper (also available as [ePrint 2018/421](https://ia.cr/2018/421)).

View File

@@ -1,5 +1,8 @@
use doc_comment::doctest;
// readme
doctest!("../../README.md", readme);
// Getting started
doctest!("../docs/getting_started/quick_start.md", quick_start);
doctest!("../docs/getting_started/operations.md", operations);