Introducing the Concrete Framework
Today, we are proud to announce the first official release of Concrete, an open source framework that enables developers to use homomorphic encryption in their applications without having to learn cryptography.
Fully Homomorphic Encryption (FHE) is a powerful technique that enables computing on encrypted data. While this idea has been around for decades, it suffered three major issues: it was too slow, too hard to use, and too limited in terms of what you could do with it. With Concrete, all this changes!
In this post, we will explain how we are addressing these three challenges, and why we are confident that we can make FHE ubiquitously applicable by 2025. If you are interested in the theory behind homomorphic encryption, read our blog post series on TFHE.
TFHE is all you need
Homomorphic encryption allows users to perform computations on encrypted data without first decrypting that data. To guarantee security, random noise needs to be added to the data before it is encrypted, which means that every time an operation is performed on the encrypted data, this noise grows to a point where it overflows on the actual data.
Dealing with this noise has led to two different approaches in FHE. The first approach, called “leveled” (e.g. BGV and CKKS) tries to do just enough computation to avoid noise overflowing the data; the second approach called “bootstrapped” (e.g. TFHE) applies a special operation called bootstrapping to reduce noise as needed. This led to a tradeoff when choosing a scheme: either you could do a limited number of fast operations, or you could do an unlimited number of slower operations.
Another key difference between homomorphic schemes is the type of operation they enable. For example, libraries implementing BGV and CKKS schemes currently only support additions and multiplications, which means non-linear functions need to be approximated using polynomials. On the other hand, the original TFHE library supported boolean gates, which means any function could be computed exactly. While using approximations is fine for statistical computing like machine learning, it doesn’t work when you need an exact result such as when dealing with healthcare data or financial transactions. For this, you need the exactness that TFHE offers.
Concrete implements a variant of TFHE that enables the best of both worlds by supporting both leveled and fast bootstrapped operations as well as approximate or exact evaluation of arbitrary functions, on both booleans and integers. There is no longer any limitation as to which kind of application you can run with FHE.
Concrete is also the first framework to implement programmable bootstrapping, a technique whereby a univariate function can be computed for free during the bootstrapping operation itself. The only downside of these added features is the smaller precision of the encoded data, which is currently limited to 16 bits.
As a developer, you can mix and match the approaches depending on the requirements of your application without switching between frameworks or using multiple FHE schemes. We do however strongly recommend using the exact paradigm to avoid introducing approximation errors at runtime, which is why this is the default in the high-level APIs of the framework.
FHE can now be used by anyone, without knowing cryptography
When you code applications, you probably don’t think too much about how the machine will execute that code. This is because compilers and other high-level languages abstract away much of the complexity of how computers work, leaving you free to focus on what matters most: your product. However, you do want to be able to tweak things as needed, perhaps by writing some assembly code or leveraging some specific hardware acceleration. This is the philosophy behind the Concrete framework: all the complexity of FHE is hidden under the high-level APIs, while still being accessible in the low-level APIs. Here is an example showing how to do a simple addition using Concrete’s Rust frontend:
Putting aside the client-server setup and encryption, the addition itself is just as you would expect for any integer. This is a radical departure from other FHE frameworks where you would have needed to specify such things as encodings, parameters, padding, etc. In Concrete, these are all managed automatically by default.
Under the hood, this simple piece of code actually calls several libraries:
- Concrete, the top level crate, simply called Concrete, contains a Rust frontend that abstracts away all the complexity of FHE, so that developers can focus on their applications. The frontend is built on top of Concrete Arithmetics.
- Concrete Arithmetics, a set of developer-friendly Rust crates that implement boolean, integer, and (soon) floating point FHE arithmetics on top of Concrete Core. Optimal implementations for several precisions (1-16 bits) are provided out of the box, with pre-defined parameters for various security levels. Noise is also managed automatically via a combination of leveled and bootstrapped operations.
- Concrete Core, a Rust library that provides low level, hardware accelerated cryptographic primitives. This library is meant for expert cryptographers and hardware acceleration engineers. Concrete Core is highly modular, making it easy to create an accelerator (GPU, FPGA, ASIC, …) for part or all of the cryptographic primitives, which will then automatically trickle up into the Arithmetics and Frontend libraries.
In most cases, you won’t need to go into the lower level libraries, and the frontend should be enough. However, if you need more fine-grained control, you can always use the boolean, integer, or short integers libraries directly. And if you really want to go deep, you can use the crypto-level core library!
Optimizing FHE parameters for a given application
By default, the Concrete library uses a fixed set of FHE parameters, which provide a good tradeoff between performance and convenience. You can think of this as local optimization: the parameters are optimal for a specific set of crypto operations but do not take into account the application as a whole. To provide an extra layer of performance, Concrete also comes with a special compiler that does a global optimization pass, taking into account the entire application, as well as the hardware it will run on. The Concrete Compiler, which is based on MLIR, enables finding the most optimal FHE parameters, thus yielding the best possible theoretical performance for a given application.
Currently, the compiler only supports a Python frontend, and more specifically a Numpy frontend. This choice was made to maximize support for machine learning models, which are typically written in Python and represented as Numpy tensor circuits. Concrete Numpy is what is currently used in Concrete ML, our privacy-preserving machine learning library.
We are working on bridging the compiler and the Rust frontend and will be releasing this in the future.
What’s next in Concrete
While FHE can already be used in many applications, it is still too slow for complex applications. Bridging this performance gap and making FHE work in real-time is the last bridge we have to cross at Zama to enable every application to offer privacy by design. While GPU and FPGAs can provide up to 100x improvements in latency and throughput, we believe we need to reach the 1000x mark to consider FHE usable in 80% of applications, and 10,000x to support 95% of applications. This can only be achieved through new computing platforms, whether ASICs dedicated to FHE or other types of high-performance compute engines. We are actively working with partners on this and expect the first commercial FHE accelerators to hit the market in the next 24 months.
While we work on improving performance, we will continue to ship new features, such as:
- 32 and 64 bit FHE arithmetics
- homomorphic floating point arithmetics
- an optimized FHE math library
- support for the compiler in the Rust frontend
- better client-server separation
- FPGA acceleration
- support for third-party hardware accelerators
- and many more!
Concrete is open source, so if you would like to contribute, we welcome pull requests and suggestions!