OpenFHE Crash Course

OpenFHE Crash Course

OpenFHE is a popular, open-source C++ library for Fully Homomorphic Encryption (FHE), a powerful cryptographic technique that allows computation on encrypted data. It implements several leading FHE schemes, including BFV, BGV, CKKS and DM/CGGI. The library can sometimes be tricky to install and use for new users: this articles aims at giving a detailed installation procedure and resources to quickly get started and start writing your FHE application. This guide provides a detailed installation procedure for Ubuntu and a Docker-based alternative for OS independent installation.

While a more beginner-friendly Python wrapper exists for OpenFHE, I personally think it is best to directly use the C++ library as the Python wrapper can sometimes limit your application due to missing methods for some classes. It also allows for lower level optimizations once you become good with OpenFHE. Let’s dive into it.

Getting started

All the necessary material for this tutorial is in a companion Github repository, so start by cloning it:

git clone https://github.com/jdumezy/openfhe-crash-course

Dependencies

To successfully compile OpenFHE, you first have to install some essential compilation tools and libraries:

  • git to clone the repository
  • cmake and make to build the library
  • clang to compile the library (g++ can also be used, but clang usually leads to better performances)
  • openmp for parallelization

Those can be installed by running:

sudo apt-get update
sudo apt-get install cmake git clang make libomp-dev

Installing OpenFHE directly

Start by cloning the OpenFHE repository:

git clone https://github.com/openfheorg/openfhe-development.git
cd openfhe-development

Now that you are inside the openfhe-development directory, start by creating a build directory in which we will build the library:

mkdir build
cd build

In this new directory, let’s call cmake to prepare the compilation of the library and specify the compiler we want to use:

cmake .. -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++

Then, we can compile the library, using multiple cores with the -j option to speed-up the process. This can take several minutes.

make -j$(nproc)

You can then try to run one of the provided example to make sure everything works as expected:

./bin/examples/pke/simple-real-numbers

You should see several outputs in your command line of input and resulting vectors.

The final step is to install the OpenFHE library system-wide, which is necessary to link against it in your own standalone projects:

sudo make install

Using the provided Dockerfile

If you have trouble with the native installation or prefer an isolated environment, you can use the Dockerfile included in the Github repository to build and install OpenFHE in a Docker container. From the root of your openfhe-crash-course directory, run the build command. This will also compile OpenFHE inside the image, which can take several minutes.

docker build -t openfhe-crash-course .

You can then try to run one of the provided example:

docker run -it openfhe-crash-course ./build/bin/examples/pke/simple-real-numbers

To develop effectively, you need to connect your local project files to the container. We do this with a bind mount with the -v flag. This allows to edit the files on your host machine, and build and run your code in the container. You can then launch a terminal in the docker container for the next steps:

docker run -it -v "$(pwd):/usr/src/app/openfhe-crash-course" openfhe-crash-course bash

You will directly be in the openfhe-development directory and ready to go for the next step.

Creating a new example

Now that you are up running, we can move on to starting creating your own application. A first and easy way to start prototyping with OpenFHE without installing and dealing with cmake is to create a new example. We can do that by switching to the example folder in the openfhe-development folder:

touch src/pke/examples/my-example.cpp

You can then edit my-example.cpp with your favorite code editor. A simple example is given as part of the repository in example/my-example.cpp (requires OpenFHE version 1.3 or higher). To build your application, go back to the build directory and run

cd build
cmake ..
make my-example

This command will only compile your example, and the output executable will be in bin/examples/pke/my-example , which you can then run with:

./bin/examples/pke/my-example

Creating a project

First, make sure that OpenFHE is installed with make install . Then, you can rely on the CMakeLists.txt included in the repository, as well as the basic project structure.

openfhe-crash-course
├── CMakeLists.txt
└── src
    ├── include # header files
    │   └── test.hpp
    ├── lib # cpp files
    │   └── test.cpp
    └── main.cpp # main file containing the main function

Similarly to OpenFHE, you can compile the example project by following the same procedure in the openfhe-crash-course directory:

mkdir build && cd build
cmake ..
make

Additional tips

Smart features

I advise adding set(CMAKE_EXPORT_COMPILE_COMMANDS ON) in the root CMakeLists.txt of openfhe-development or your project. This will create a compile_commands.json file that can then be used by tools like clangd for smart features.

Performances

To get the best performances possible, you should pass additional flags to cmake . This is because, by default, cmake creates a “Debug” build, which is slow because it contains extra debugging information. For testing performance or running a real application, always use a “Release” build. An additional optimization is to tell the compiler to use native optimizations.

cmake .. -DCMAKE_C_COMPILER=clang \
         -DCMAKE_CXX_COMPILER=clang++ \
         -DWITH_NATIVEOPT=ON \
         -DCMAKE_BUILD_TYPE=Release

From an application perspective, when using leveled schemes like BFV/BGV and CKKS, a general advice is to try to reduce the multiplicative depth, and avoid generating unnecessary keys (like rotations keys) as they tend to be quite large.

More details are given on OpenFHE’s repository.

If you happen to find an error in this guide, please open a GitHub issue