Skip to content
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
5 changes: 0 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -136,11 +136,6 @@ assert result == add(2, 6)
<a href="#about" > ↑ Back to top </a>
</p>

>[!Note]
>**Zama 5-Question Developer Survey**
>
>We want to hear from you! Take 1 minute to share your thoughts and helping us enhance our documentation and libraries. **[👉 Click here](https://www.zama.ai/developer-survey)** to participate.

## Resources

### Concrete deep dive
Expand Down
9 changes: 0 additions & 9 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,12 +57,3 @@ Collaborate with us to advance the FHE spaces and drive innovation together.
* [Check the latest release note](https://github.com/zama-ai/concrete/releases)
* [Request a feature](https://github.com/zama-ai/concrete/issues/new?assignees=\&labels=feature\&projects=\&template=features.md)
* [Report a bug](https://github.com/zama-ai/concrete/issues/new?assignees=\&labels=bug%2C+triage\&projects=\&template=bug\_report.md)

***

{% hint style="success" %}

**Zama 5-Question Developer Survey**

We want to hear from you! Take 1 minute to share your thoughts and helping us enhance our documentation and libraries. **👉** [**Click here**](https://www.zama.ai/developer-survey) to participate.
{% endhint %}
1 change: 1 addition & 0 deletions docs/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
* [Debugging and artifact](execution-analysis/debug.md)
* [Performance](optimization/summary.md)
* [GPU acceleration](execution-analysis/gpu_acceleration.md)
* [Rust integration](execution-analysis/rust_integration.md)
* Other
* [Statistics](compilation/statistics.md)
* [Progressbar](execution-analysis/progressbar.md)
Expand Down
6 changes: 0 additions & 6 deletions docs/core-features/table_lookups.md
Original file line number Diff line number Diff line change
Expand Up @@ -224,9 +224,3 @@ for i in range(16):
upper_i**2,
], f"Miscomputation {i=} {circuit.encrypt_run_decrypt(i)} {[lower_i**2, upper_i**2]}"
```

{% hint style="success" %}
**Zama 5-Question Developer Survey**

We want to hear from you! Take 1 minute to share your thoughts and helping us enhance our documentation and libraries. **👉** [**Click here**](https://www.zama.ai/developer-survey) to participate.
{% endhint %}
206 changes: 206 additions & 0 deletions docs/execution-analysis/rust_integration.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,206 @@
# Rust Integration

This document explains how to use Fully Homomorphic Encryption (FHE) modules developed with **concrete-python** directly in Rust programs using the **Concrete** toolchain.

This workflow enables rapid prototyping in Python and seamless deployment in Rust, combining the flexibility of Python with the safety and performance of Rust.

## Overview

- Write and compile FHE modules in Python using `concrete-python`.
- Import the compiled module artifact into Rust using the `concrete-macro` crate.
- Use the generated Rust APIs for encryption, evaluation, and decryption.

## Prerequisites

- Python 3.8+
- Rust 1.70+
- `concrete-python` (>=2.10)
- `concrete` and `concrete-macro` Rust crates (>=2.10.1-rc1)

## Regular example

### Step 1: Define and Compile a Module in Python

Write your FHE logic in Python and compile it to an artifact compatible with the Rust toolchain. Here is an example of a small and simple module:

```python
from concrete import fhe

@fhe.module()
class MyModule:
@fhe.function({"x": "encrypted"})
def inc(x):
return (x + 1) % 256

@fhe.function({"x": "encrypted"})
def dec(x):
return (x - 1) % 256

inputset = fhe.inputset(fhe.uint8)
module = MyModule.compile({"inc": inputset, "dec": inputset})

module.server.save(path="MyModule.zip", via_mlir=True)
```

This produces a `MyModule.zip` artifact containing the compiled FHE module.

### Step 2: Set Up the Rust Project

Initialize a new Rust project and add the required dependencies.

```shell
cargo init
cargo add concrete@=2.10.1-rc1 concrete-macro@=2.10.1-rc1
```

Place the `MyModule.zip` artifact in your project directory.

### Step 3: Import the Python-Compiled Module in Rust

Use the `concrete_macro::from_concrete_python_export_zip!` macro to import the module at build time.

```rust
mod my_module {
use concrete_macro::from_concrete_python_export_zip;
from_concrete_python_export_zip!("MyModule.zip");
}
```

This macro unpacks the artifact, triggers recompilation, reads metadata, and generates Rust APIs for the module's functions.

### Step 4: Use the Module in Rust

You can now use the FHE functions in Rust. The following example demonstrates a full FHE workflow:

```rust
use concrete::common::Tensor;

fn main() {
// Prepare input and expected output tensors
let input = Tensor::new(vec![5], vec![]);
let expected_output = Tensor::new(vec![6], vec![]);

// Key generation
let mut secret_csprng = concrete::common::SecretCsprng::new(0u128);
let mut encryption_csprng = concrete::common::EncryptionCsprng::new(0u128);
let keyset = my_module::new_keyset(secret_csprng.pin_mut(), encryption_csprng.pin_mut());
let client_keyset = keyset.get_client();

// Create client stub for the 'inc' function
let mut inc_client = my_module::client::inc::ClientFunction::new(&client_keyset, encryption_csprng);

// Encrypt input and obtain evaluation keys
let encrypted_input = inc_client.prepare_inputs(input);
let evaluation_keys = keyset.get_server();

// Create server stub for the 'inc' function
let mut inc_server = my_module::server::inc::ServerFunction::new();

// Evaluate the function on encrypted data
let encrypted_output = inc_server.invoke(&evaluation_keys, encrypted_input);

// Decrypt the output
let decrypted_output = inc_client.process_outputs(encrypted_output);

// Check correctness
assert_eq!(decrypted_output.values(), expected_output.values());
}
```

## TFHE-rs Ciphertext Interoperability

Starting from Concrete v2.11, you can define and use modules that operate directly on TFHE-rs ciphertexts, enabling seamless interoperability between Concrete and TFHE-rs in Rust.

### Step 1: Define and Compile a Module with TFHE-rs Types in Python

You can define a module in Python that uses TFHE-rs integer types as arguments and outputs. For example:

```python
from concrete import fhe
from concrete.fhe import tfhers

TFHERS_UINT_8_3_2_4096 = tfhers.TFHERSIntegerType(
False,
bit_width=8,
carry_width=3,
msg_width=2,
params=tfhers.CryptoParams(
lwe_dimension=909,
glwe_dimension=1,
polynomial_size=4096,
pbs_base_log=15,
pbs_level=2,
lwe_noise_distribution=0,
glwe_noise_distribution=2.168404344971009e-19,
encryption_key_choice=tfhers.EncryptionKeyChoice.BIG,
),
)

@fhe.module()
class MyModule:

@fhe.function({"x": "encrypted", "y": "encrypted"})
def my_func(x, y):
x = tfhers.to_native(x)
y = tfhers.to_native(y)
return tfhers.from_native(x + y, TFHERS_UINT_8_3_2_4096)

def t(v):
return tfhers.TFHERSInteger(TFHERS_UINT_8_3_2_4096, v)

inputset = [(t(0), t(0)), (t(2**6), t(2**6))]
my_module = MyModule.compile({"my_func": inputset})
my_module.server.save("test_tfhers.zip", via_mlir=True)
```

This produces a `test_tfhers.zip` artifact compatible with Rust and TFHE-rs.

### Step 2: Use the Module with TFHE-rs Ciphertexts in Rust

You can import and use the module in Rust, passing and receiving native TFHE-rs ciphertexts:

```rust
mod precompile {
use concrete_macro::from_concrete_python_export_zip;
from_concrete_python_export_zip!("src/test_tfhers.zip");
}

use tfhe::prelude::{FheDecrypt, FheEncrypt};
use tfhe::shortint::parameters::v0_10::classic::gaussian::p_fail_2_minus_64::ks_pbs::V0_10_PARAM_MESSAGE_2_CARRY_3_KS_PBS_GAUSSIAN_2M64;
use tfhe::{generate_keys, FheUint8};

fn main() {
// Key generation for TFHE-rs
let config = tfhe::ConfigBuilder::with_custom_parameters(V0_10_PARAM_MESSAGE_2_CARRY_3_KS_PBS_GAUSSIAN_2M64);
let (client_key, _) = generate_keys(config);

// Build Concrete keyset with TFHE-rs client key
let mut secret_csprng = concrete::common::SecretCsprng::new(0u128);
let mut encryption_csprng = concrete::common::EncryptionCsprng::new(0u128);
let keyset = precompile::KeysetBuilder::new()
.with_key_for_my_func_0_arg(&client_key)
.generate(secret_csprng.pin_mut(), encryption_csprng.pin_mut());
let server_keyset = keyset.get_server();

// Encrypt inputs using TFHE-rs
let arg_0 = FheUint8::encrypt(6u8, &client_key);
let arg_1 = FheUint8::encrypt(4u8, &client_key);

// Evaluate the Concrete circuit on TFHE-rs ciphertexts
let mut server = precompile::server::my_func::ServerFunction::new();
let output = server.invoke(&server_keyset, arg_0, arg_1);

// Decrypt the result using TFHE-rs
let decrypted: u8 = output.decrypt(&client_key);
assert_eq!(decrypted, 10);
}
```

This workflow allows you to combine the high-level graph optimizations of Concrete with the operator-level flexibility of TFHE-rs, all within Rust.

## Notes

- The module must be compiled with `via_mlir=True` to be loaded in the Rust program.
- The Rust API is currently in beta and may evolve in future releases.
- The Python and Rust environments must use compatible versions of the Concrete toolchain.
- When using TFHE-rs ciphertext interoperability, ensure that the TFHE-rs client key used for encryption matches the one registered in the Concrete keyset for the corresponding argument.
8 changes: 1 addition & 7 deletions docs/get-started/quick_start.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ inputset = [(2, 3), (0, 0), (1, 6), (7, 7), (7, 1), (3, 2), (6, 1), (1, 7), (4,
Here, our inputset consists of 10 integer pairs, ranging from a minimum of `(0, 0)` to a maximum of `(7, 7)`.

{% hint style="warning" %}
Choosing a representative inputset is critical to allow the compiler to find accurate bounds of all the intermediate values (see more details [here](https://docs.zama.ai/concrete/explanations/compilation#bounds-measurement)). Evaluating the circuit with input values under or over the bounds may result in undefined behavior.
Choosing a representative inputset is critical to allow the compiler to find accurate bounds of all the intermediate values (see more details [here](https://docs.zama.ai/concrete/explanations/compiler_workflow#bounds-measurement)). Evaluating the circuit with input values under or over the bounds may result in undefined behavior.
{% endhint %}

{% hint style="warning" %}
Expand Down Expand Up @@ -149,9 +149,3 @@ encrypted_x, encrypted_y = circuit.encrypt(2, 6)
encrypted_result = circuit.run(encrypted_x, encrypted_y)
result = circuit.decrypt(encrypted_result)
```

{% hint style="success" %}
**Zama 5-Question Developer Survey**

We want to hear from you! Take 1 minute to share your thoughts and helping us enhance our documentation and libraries. **👉** [**Click here**](https://www.zama.ai/developer-survey) to participate.
{% endhint %}
7 changes: 0 additions & 7 deletions docs/tutorials/see-all-tutorials.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,3 @@
* [How to use dynamic table look-ups using Concrete](https://www.zama.ai/post/video-tutorial-how-to-use-dynamic-table-look-ups-using-concrete) - October 2023
* [Dive into Concrete - Zama's Fully Homomorphic Encryption Compiler](https://www.zama.ai/post/video-tutorial-dive-into-concrete-zamas-fully-homomorphic-encryption-compiler) - October 2023
* [How To Get Started With Concrete - Zama's Fully Homomorphic Encryption Compiler](https://www.zama.ai/post/how-to-started-with-concrete-zama-fully-homomorphic-encryption-compiler) - July 2023


{% hint style="success" %}
**Zama 5-Question Developer Survey**

We want to hear from you! Take 1 minute to share your thoughts and helping us enhance our documentation and libraries. **👉** [**Click here**](https://www.zama.ai/developer-survey) to participate.
{% endhint %}
2 changes: 1 addition & 1 deletion frontends/concrete-python/examples/sha1/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ implementation.
In our implementation, only the compression function is implemented in FHE, corresponding to the
`_process_encrypted_chunk_server_side function`. The rest is done client-side in the clear,
including the message expansion. While more of the process could be done in FHE, this tutorial
focuses on demonstrating the use of [Modules](https://docs.zama.ai/concrete/compilation/modules).
focuses on demonstrating the use of [Modules](https://docs.zama.ai/concrete/compilation/combining/composing_functions_with_modules).

Our Module contains 7 functions which can be combined together:
- `xor3` XORs three values together
Expand Down
Loading