From cc85c441eae95a525443ae30043e831b7e928979 Mon Sep 17 00:00:00 2001 From: Nicolas Sarlin Date: Thu, 16 Jan 2025 13:22:51 +0100 Subject: [PATCH] chore(doc): add strings feature to doctests --- tfhe/docs/tutorials/ascii_fhe_string.md | 62 +++++++++++++++++++++---- tfhe/src/lib.rs | 3 +- 2 files changed, 55 insertions(+), 10 deletions(-) diff --git a/tfhe/docs/tutorials/ascii_fhe_string.md b/tfhe/docs/tutorials/ascii_fhe_string.md index 5792e9f110..24b04e47bc 100644 --- a/tfhe/docs/tutorials/ascii_fhe_string.md +++ b/tfhe/docs/tutorials/ascii_fhe_string.md @@ -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] @@ -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: @@ -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, } @@ -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(), @@ -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}"); @@ -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) diff --git a/tfhe/src/lib.rs b/tfhe/src/lib.rs index dd43fd7ec7..36b4175282 100644 --- a/tfhe/src/lib.rs +++ b/tfhe/src/lib.rs @@ -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;