Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ns/doc strings #1981

Merged
merged 1 commit into from
Jan 20, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 53 additions & 9 deletions tfhe/docs/tutorials/ascii_fhe_string.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
# Homomorphic case changing on Ascii string

This tutorial demonstrates how to build a data type that represents an ASCII string in Fully Homomorphic Encryption (FHE) by implementing to\_lower and to\_upper functions.
This tutorial demonstrates how to build your own data type that represents an ASCII string in Fully Homomorphic Encryption (FHE) by implementing to\_lower and to\_upper functions.

An ASCII character is stored in 7 bits. To store an encrypted ASCII, we use the `FheUint8`:
{% hint style="info" %}
Since version 0.11, **TFHE-rs** has introduced the `strings` feature, which provides an easy to use FHE strings API. See the [fhe strings guide](../guides/strings.md) for more information.
{% endhint %}


An ASCII character is stored in 7 bits. In this tutorial, we use the `FheUint8` to store an encrypted ASCII:

* The uppercase letters are in the range \[65, 90]
* The lowercase letters are in the range \[97, 122]
Expand All @@ -24,13 +29,10 @@ To use the `FheUint8` type, enable the `integer` feature:
# Cargo.toml

[dependencies]
# Default configuration for x86 Unix machines:
tfhe = { version = "0.11.0", features = ["integer"] }
```

Refer to the [installation guide](../getting\_started/installation.md) for other configurations.

The `FheAsciiString::encrypt` function performs data validation to ensure the input string contains only ASCII characters.
The `MyFheString::encrypt` function performs data validation to ensure the input string contains only ASCII characters.

In FHE operations, direct branching on encrypted values is not possible. However, you can evaluate a boolean condition to obtain the desired outcome. Here is an example to check and convert the 'char' to a lowercase without using a branch:

Expand Down Expand Up @@ -83,7 +85,7 @@ use tfhe::{generate_keys, set_server_key, ClientKey, ConfigBuilder, FheUint8};

const UP_LOW_DISTANCE: u8 = 32;

struct FheAsciiString {
struct MyFheString {
bytes: Vec<FheUint8>,
}

Expand All @@ -95,7 +97,7 @@ fn to_lower(c: &FheUint8) -> FheUint8 {
c + FheUint8::cast_from(c.gt(64) & c.lt(91)) * UP_LOW_DISTANCE
}

impl FheAsciiString {
impl MyFheString {
fn encrypt(string: &str, client_key: &ClientKey) -> Self {
assert!(
string.is_ascii(),
Expand Down Expand Up @@ -140,7 +142,7 @@ fn main() {

set_server_key(server_key);

let my_string = FheAsciiString::encrypt("Hello Zama, how is it going?", &client_key);
let my_string = MyFheString::encrypt("Hello Zama, how is it going?", &client_key);
let verif_string = my_string.decrypt(&client_key);
println!("Start string: {verif_string}");

Expand All @@ -155,3 +157,45 @@ fn main() {
assert_eq!(verif_string, "hello zama, how is it going?");
}
```

## Using **TFHE-rs** strings feature
This code can be greatly simplified by using the `strings` feature from **TFHE-rs**.

First, add the feature in your `Cargo.toml`
```toml
# Cargo.toml

[dependencies]
tfhe = { version = "0.11.0", features = ["strings"] }
```

The `FheAsciiString` type allows to simply do homomorphic case changing of encrypted strings (and much more!):
```rust
use tfhe::prelude::*;
use tfhe::{generate_keys, set_server_key, ConfigBuilder, FheAsciiString};

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

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

set_server_key(server_key);

let my_string =
FheAsciiString::try_encrypt("Hello Zama, how is it going?", &client_key).unwrap();
let verif_string = my_string.decrypt(&client_key);
println!("Start string: {verif_string}");

let my_string_upper = my_string.to_uppercase();
let verif_string = my_string_upper.decrypt(&client_key);
println!("Upper string: {verif_string}");
assert_eq!(verif_string, "HELLO ZAMA, HOW IS IT GOING?");

let my_string_lower = my_string_upper.to_lowercase();
let verif_string = my_string_lower.decrypt(&client_key);
println!("Lower string: {verif_string}");
assert_eq!(verif_string, "hello zama, how is it going?");
}
```

You can read more about this in the [FHE strings documentation](../guides/strings.md)
3 changes: 2 additions & 1 deletion tfhe/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,8 @@ mod js_on_wasm_api;
feature = "shortint",
feature = "boolean",
feature = "integer",
feature = "zk-pok"
feature = "zk-pok",
feature = "strings"
))]
mod test_user_docs;

Expand Down
Loading