Introduction to our FHE compiler

Using fully homomorphic encryption (FHE), anyone can perform computations directly on private (i.e. encrypted) data, without ever having to decrypt it. FHE has the power to improve how we interact with existing applications and enable entirely new applications—from allowing sophisticated parties to protect their trading strategies while trading on blockchains (i.e. hidden trading strategies) to fine-tuning advanced machine learning models over sensitive data sets (e.g. customized AI agents).

However, using the technology today is really difficult for a non-expert.

Our next-generation compiler is designed to make it easy for any engineer to write highly optimized FHE programs (benchmarks available here). Instead of rewriting an application in some niche eDSL, our vision is that engineers should bring their existing program written in a mainstream language and simply add directives to indicate which functions are FHE programs and which inputs/outputs should be kept hidden! If you’re familiar with RiscZero or Succinct, we’d say our approach is closest in spirit to theirs (though we focus on FHE rather than ZK).

Initially, we support C. Depending on demand, we may add support for Rust as well.

Brief intro to FHE

FHE is the next generation of public key cryptography. In addition to being able to encrypt and decrypt data, we can now perform arithmetic, logical, and comparison operations directly over the encrypted data without ever decrypting said data. This means we can process data for purposes such as order book matching in financial systems or ML inference while protecting the user data going into these systems.

FHE relies on a special type of cryptography called lattice based cryptography.

Certain variants of FHE, such as threshold FHE (which we won’t go into here), enable running arbitrary computer programs over multiple users’ private data. Users can thus protect their data while still allowing it to be used in an application.

You may wonder how FHE differs from other privacy-preserving technologies. Briefly, some nice things about FHE include:

  • The computation itself is non-interactive, so it’s great for decentralized settings where parties may be in very different locations around the world.
  • FHE is resistant to many attacks, e.g. FHE is not susceptible to the broad range of attacks trusted execution environments (TEEs) are susceptible to.
  • FHE is post-quantum, meaning FHE is secure against attacks from a quantum computer. An alternative way of thinking about this property is that FHE is “future-proof” even when ciphertexts are stored by an adversary for the day when quantum computers are available.

How Parasol differs from our first-generation compiler

If you worked with our first-generation FHE compiler, you may wonder how our new one differs.

Some important changes to call out include:

  • Moving away from an eDSL approach. Now developers write directly in a mainstream language.
  • Moving from the BFV scheme to our own variant of Torus FHE (TFHE). This allows us to support comparison operations more easily and cheaply.
  • Unlimited computation over encrypted data. Previously, we could only support running a limited number of operations on encrypted data.
  • Program composability. Previously, a developer could create different programs using our compiler and these programs would not automatically be compatible with one another. Programs generated using our new compiler no longer have this issue.

Some hardcore technical details about our approach

Feel free to skip this! You don’t need to understand these details to work with our tools.

The full stack

Listed in order of top layer to bottom layer, Parasol consists of:

LLVM-based compiler: What developers interact with to write and compile their FHE programs.

Virtual processor: Efficiently runs what’s output by the compiler. We have our own instruction set (ISA); we may consider switching to RISC-V in the future.

FHE library: Implements low-level cryptographic operations in our variant of the TFHE scheme.

How things fit together

We build an LLVM-based compiler to provide a great developer experience. This approach has two benefits. First, it allows developers to use a variety of mainstream programming languages like Rust, C, or C++, with the only changes to their programs being the directives mentioned above. Second, it allows us to leverage decades of optimizations and transformations that are already built into LLVM.

Building the Parasol compiler was very technically challenging and required designing and implementing a virtual processor that operates over a mix of plaintext and encrypted data (aka the parasol processor). The processor is integrated as a backend for the LLVM toolchain, which requires us to map our instruction set architecture to the internal LLVM representations. We adopt an out-of-order processor design and feature dynamic scheduling within instructions to maximize parallelism.

Our compiler and processor rely on an in-house created variant of the TFHE scheme. We chose TFHE as it gives developers access to a variety of operations—most importantly, comparisons. A key feature of FHE is “bootstrapping” which is an operation to reduce noise in ciphertexts, allowing us to compute indefinitely. It tends to be a relatively expensive operation to perform, and there are various flavors of bootstrapping for the TFHE scheme.

What’s special about our TFHE variant is that it utilizes circuit bootstrapping and (homomorphic) multiplexer trees to realize arbitrary computation. This form of bootstrapping, if configured correctly, allows us to extract and maximize parallelism in programs. In taking this approach, we rely on a cheap multiplexer operation to do data propagation. In contrast, when working with functional/programmable bootstrapping, data propagation is instead achieved through the much more expensive bootstrap operation. If you’d like to learn more about this, feel free to jump here.

The benefits of our approach may not be obvious on laptops or smaller machines but maximizing parallelism will be key to unlocking FHE’s performance promise over the coming years. Note that in running programs locally you will not experience much, if any, performance advantage from our tech as you need dozens of cores.