Concrete v2.10: Introducing Rust Support and Improved TFHE-rs Interoperability

April 10, 2025
Quentin Bourgerie

Concrete v2.10 introduces a powerful new tool:  Concrete for Rust – an integration that brings Fully Homomorphic Encryption (FHE) directly to the Rust ecosystem. It’s a significant step toward production-grade FHE applications in modern systems programming.

If you’ve already experimented with Concrete, you’re likely familiar with the [.c-inline-code]concrete-python[.c-inline-code] frontend. This tool allows you to compile a Python program into its Fully Homomorphic Encryption (FHE) equivalent, and then use the client and server SDKs to handle encryption, evaluation, and decryption. Now, with this new Rust support, advanced users who previously used the low-level C++ API can now harness the power of Concrete directly in Rust. 

Why Rust?

For the past few years, Python has proven to be a great target for Concrete. It’s flexible, easy to use, and has a strong ecosystem for scientific computing. That’s why tools like [.c-inline-code]concrete-ml[.c-inline-code] have been able to support so many machine learning models so quickly. Python is perfect for trying out new ideas and building prototypes fast, and [.c-inline-code]concrete-python[.c-inline-code] integrates very well with it. 

However, when it’s time to move from a prototype to a real production system, Python can be limiting, and that’s where Rust comes in. At Zama, we have always appreciated Rust for its safety when writing cryptographic code. But beyond memory safety, Rust is also becoming a more and more popular choice for building reliable, large-scale applications.

With the first release of Concrete for Rust, our goal was to bring together the best of both worlds: the ease of prototyping from Python, and the strong, safe foundations of Rust for production-ready deployment.

Getting started: Concrete in Rust

Let’s walk through a simple example to see how Concrete in Rust works.

Step 1 — Define and compile a module in Python.

We start by using [.c-inline-code]concrete-python[.c-inline-code] to generate an artifact compatible with the [.c-inline-code]concrete-compiler[.c-inline-code]. This artifact will then be imported and used within a Rust project, demonstrating how the Rust integration fits into the broader Concrete toolchain.

First, install [.c-inline-code]concrete-python[.c-inline-code] using pip: 

pip install concrete-python

Then we define a simple module with two functions, inc and dec, which respectively increase and decrease an 8-bit integer (i.e., computations are done modulus 2^8):

from concrete import fhe


@fhe.module()
class MyModule:
  @fhe.function({"x": "encrypted"})
  def inc(x):
      return (x+1) % 2**8
   @fhe.function({"x": "encrypted"})
  def dec(x):
      return (x-1) % 2**8


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


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

Note that the Python code used in this example is intentionally simple and intended only for testing purposes. In practice, you can write any compatible logic in your program.

After executing the script, you will get a file named [.c-inline-code]test.zip[.c-inline-code], which contains the compiled artifact that you will use in your Rust project. 

Step 2 — Use the module in Rust.

To support this workflow, we have published two crates on crates.io:

  • [.c-inline-code]concrete_macro[.c-inline-code], which enables importing a [.c-inline-code]concrete-compiler[.c-inline-code] artifact at build time.
  • [.c-inline-code]concrete[.c-inline-code], which provides the client and server APIs for encryption, evaluation, and decryption.

Firstly initialize your rust project and add concrete dependencies:

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

Using [.c-inline-code]concrete_macro[.c-inline-code], you can easily import your precompiled module into your Rust project with FHE:

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

Under the hood, the procedural macro performs several tasks to integrate the precompiled module:

  • Unzipping the [.c-inline-code]concrete-compiler[.c-inline-code] artifact
  • Triggering a recompilation step
  • Reading metadata
  • Generating corresponding client/server APIs

In the above example, the module includes two functions, [.c-inline-code]inc[.c-inline-code] and [.c-inline-code]dec[.c-inline-code], these functions are now available in Rust. You can run a full FHE workflow:

fn main() {
  use concrete::common::Tensor;
 
  let input = Tensor::new(vec![5], vec![]);
  let expected_output = Tensor::new(vec![6], vec![]);


  // Step 1 (Client side) : keygen
  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();


  // Step 2 (Client side) : Create the client stub of the inc function
  let mut inc_client = my_module::client::inc::ClientFunction::new(&client_keyset, encryption_csprng);


  // Step 3 (Client side) : Encrypt the input and get the evaluation keys
  let encrypted_input = inc_client.prepare_inputs(input);
  let evaluation_keys = keyset.get_server();


  // Step 4 (Server side) : Create the server stub of the inc function
  let mut inc_server = my_module::server::inc::ServerFunction::new();


  // Step 5 (Server side) : Invoke the server stub with the evaluation keys and the encrypted input
  let encrypted_output = inc_server.invoke(&evaluation_keys, encrypted_input);


  // Step 6 (Client side) : Decrypt the output
  let decrypted_output = inc_client.process_outputs(encrypted_output);


  // Assert that the decrypted output is equal to the expected output
  assert_eq!(decrypted_output.values(), expected_output.values());
}

Note: The Rust API is currently in beta, meaning it’s still experimental and may evolve in future releases. We’re actively working on improvements—feel free to try it out, share your feedback, and stay tuned for the updates!

Improvements on TFHE-rs interoperability

In addition to Rust support, Concrete v2.10 also brings several enhancements to interoperability with TFHE-rs—making it easier to combine the strengths of both ecosystems.

For more details, check out the release notes.

Additional links

Read more related posts

No items found.