HElib is a C++ library that allows us to perform Fully Homomorphic Encryption (FHE).
I plan to go through the theoretical part in later posts, but for now I’ll show how to write a simple program in HElib. This program will sum 2 and 3 using FHE.
Other than the samples provided with the library, there are other sources and tutorials for starting with HElib, but I think they present some advanced concepts (e.g., ciphertext packing) which might be confusing at the beginning. For this reason, I’ll try to make this example as simple as possible.
The first thing we need to do is to declare the parameters used in this FHE scheme. I provide a short description of each of them now, but I plan to get into details in another post:
long m = 0; // Specific modulus long p = 1021; // Plaintext base [default=2], should be a prime number long r = 1; // Lifting [default=1] long L = 16; // Number of levels in the modulus chain [default=heuristic] long c = 3; // Number of columns in key-switching matrix [default=2] long w = 64; // Hamming weight of secret key long d = 0; // Degree of the field extension [default=1] long k = 128; // Security parameter [default=80] long s = 0; // Minimum number of slots [default=0]
These parameters will be used to find the proper value of m using the function FindM:
m = FindM(k,L,c,p, d, s, 0);
After than, we create a FHEcontext object to hold all the parameters:
FHEcontext context(m, p, r); buildModChain(context, L, c);
The encryption will use a polynomial, so the next step is to create this polynomial using the ZZX class from NTL:
ZZX G = context.alMod.getFactorsOverZZ();
Next, we use the context to create the public key and the secret key:
FHESecKey secretKey(context); const FHEPubKey& publicKey = secretKey; secretKey.GenSecKey(w);
And this ends the initialization part. Now we can actually start encrypting things and doing operations over the encrypted data.
HElib uses the Ctxt class to hold ciphertexts, and we want two of those:
Ctxt ctx1(publicKey); Ctxt ctx2(publicKey);
ctx1 will be the encryption of the value 2, and ctx2 will be the encryption of the value 3. Note that the values are given to the encryption method in the form of polynomials ZZX:
publicKey.Encrypt(ctx1, to_ZZX(2)); publicKey.Encrypt(ctx2, to_ZZX(3));
Let’s create another ciphertext to hold the sum Enc(2) + Enc(3), and actually do the sum. HElib overloads the operator +=, which makes it simpler to sum ciphertexts:
Ctxt ctSum = ctx1; ctSum += ctx2;
Finally, we create a polynomial that will hold the decrypted value of the sum, and decrypt the ciphertext ctSum into it using the secret key:
ZZX ptSum; secretKey.Decrypt(ptSum, ctSum);
And this is it. If we check ptSum, we should see that it holds the value 5.
To summarize, the initialization part might look intimidating, but after the context and the keys are created, the summation itself is simply done using the familiar += operator on the ciphertexts.
Although this is a simple example, HElib allows us to do more advanced things that are needed for practical applications. Most of those can be found in the samples that come with HElib, so that’s a good next stop.
The complete code for this example is available at GitHub.