Concrete v2.8: Interoperability with TFHE-rs and Automatic Module Tracing

October 8, 2024
Quentin Bourgerie

We’re excited to announce the release of Concrete v2.8, packed with powerful new features and improvements. This update introduces two major enhancements: the interoperability between TFHE-rs and Concrete and automatic module tracing for an easier way to fine-tune module compilation. Additionally, we’ve made many improvements to our documentation, including new tutorials showcasing real-world use cases. Concrete v2.8 also includes various optimizations and bug fixes, especially in the Concrete GPU runtime, which makes Fully Homomorphic Encryption (FHE) evaluations faster. As always, you’ll find all the details, performance improvements and bug fixes in the full release note.

Concrete interoperability with TFHE-rs

Zama has 2 leading technology platforms of FHE: Concrete and TFHE-rs, each serving different needs. Concrete is optimized for small integers (~8 bits) and employs advanced optimizations like reducing bitwidth, partitioning computation graphs, and fine-tuning cryptographic parameters. In contrast, TFHE-rs handles larger integers (up to 128 bits) using a static set of cryptographic parameters.

Both platforms have unique strengths, and with Concrete v2.8, we’re introducing interoperability between TFHE-rs and Concrete to allow developers to convert integers between Concrete and TFHE-rs, leveraging the best of both tools.

The following example shows how to use this interoperability, you can find the full explanations in the interoperability documentation.

# A function which take two TFHE-rs integer convert into concrete representation, make a computation then convert the result inro TFHE-rs integer
def compute(tfhers_x, tfhers_y):
      ####### TFHE-rs to Concrete #########
      x = tfhers.to_native(tfhers_x)
      y = tfhers.to_native(tfhers_y)
      ####### Concrete Computation ########
      res = your_function_optimized_by_co(x, y)
      ####### Concrete to TFHE-rs #########
      tfhers_res = tfhers.from_native(res, tfhers_type)
      ####### Concrete to TFHE-rs #########
      return tfhers_res

You can compile this function like any other in Concrete, using TFHE-rs integers as the input-set:

compiler = fhe.Compiler(compute, {"tfhers_x": "encrypted", "tfhers_y": "encrypted"})
inputset = [(tfhers_int(randint(128)), tfhers_int(randint(128))) for _ in range(100)]
circuit = compiler.compile(inputset)

This feature is currently in beta, and while we’re continuously improving it, expect changes to the API as we expand its capabilities. Please note that Concrete ML is not yet compatible with TFHE-rs, but we’re working on this, with an update expected by the end of Q4.

Better modules

In Concrete v2.7 we introduced modules that allow you to compile multiple functions simultaneously. However, manually defining composition rules and input-sets for each function can be complex and error-prone. To address this, Concrete v2.8 introduces automatic module tracing, making it easier to define and fine-tune modules based on the natural flow of Python code. 

In the following code snippet, you can see the definition of a module and the definition of a pipeline that allows the compiler to understand how the module will be used, and then compute the composition rules and input-set of each function.

from concrete import fhe
from fhe import Wired

# Module declaration without composition rules
@fhe.module()
class MyModule:
      @fhe.function({"x": "encrypted"})
      def increment(x):
      		return (x + 1) % 100
      @fhe.function({"x": "encrypted"})
      def decrement(x):
      		return (x - 1) % 100
      @fhe.function({"x": "encrypted"})
      def decimate(x):
      		return (x / 10) % 100

# Define a unique inpuset for the whole module
inputset = [np.random.randint(1, 100, size=()) for _ in range(100)]

# Iterate over the inpuset and write a natural Python code with composition
with MyModule.wire_pipeline(inputset) as samples:
     for s in samples:
      		MyModule.increment(MyModule.decimate(MyModule.decrement(s)))

# Compile without providing inputset for each function
module = MyModule.compile()

More tutorials and examples

With this release, we also added a few new tutorials showcasing interesting use cases of  FHE and Concrete:

We encourage you to explore these tutorials. If you develop your own use cases with Concrete, let us know and we’ll be happy to feature them in the future releases.

Additional improvements

Concrete v2.8 also includes various optimizations and bug fixes, especially in the Concrete GPU runtime, which makes FHE evaluations faster. These improvements don’t require any API changes, so you can enjoy the benefits without additional efforts. For more details, refer to our GitHub or the full release notes.

Thank you for your continued support and feedback. We strive to make FHE more accessible and efficient for everyone.

Additional links

Read more related posts