The TFHE cryptographic scheme relies on a variant of Regev cryptosystem and is based on a problem so difficult that it is even post-quantum resistant.
Some cryptographic parameters will require tuning to ensure both the correctness of the result and the security of the computation.
To make it simpler, we've provided two sets of parameters, which ensure correct computations for a certain probability with the standard security of 128 bits. There exists an error probability due to the probabilistic nature of the encryption, which requires adding randomness (noise) following a Gaussian distribution. If this noise is too large, the decryption will not give a correct result. There is a trade-off between efficiency and correctness: generally, using a less efficient parameter set (in terms of computation time) leads to a smaller risk of having an error during homomorphic evaluation.
In the two proposed sets of parameters, the only difference lies in this error probability. The default parameter set ensures an error probability of at most when computing a programmable bootstrapping (i.e., any gates but the not
). The other one is closer to the error probability claimed in the original TFHE paper, namely , but it is up-to-date regarding security requirements.
The following array summarizes this:
Parameter set | Error probability |
---|---|
You can also create your own set of parameters. This is an unsafe
operation as failing to properly fix the parameters will result in an incorrect and/or insecure computation:
DEFAULT_PARAMETERS
TFHE_LIB_PARAMETERS
In tfhe::boolean
, the available operations are mainly related to their equivalent Boolean gates (i.e., AND, OR... etc). What follows are examples of a unary gate (NOT) and a binary gate (XOR). The last one is about the ternary MUX gate, which allows homomorphic computation of conditional statements of the form If..Then..Else
.
This library is meant to be used both on the server side and the client side. The typical use case should follow the subsequent steps:
On the client side, generate the client
and server keys
.
Send the server key
to the server.
Then any number of times:
On the client side, encrypt the input data with the client key
.
Transmit the encrypted input to the server.
On the server side, perform homomorphic computation with the server key
.
Transmit the encrypted output to the client.
On the client side, decrypt the output data with the client key
.
In the first step, the client creates two keys, the client key
and the server key
, with the tfhe::boolean::gen_keys
function:
The client_key
is of type ClientKey
. It is secret and must never be transmitted. This key will only be used to encrypt and decrypt data.
The server_key
is of type ServerKey
. It is a public key and can be shared with any party. This key has to be sent to the server because it is required for homomorphic computation.
Note that both the client_key
and server_key
implement the Serialize
and Deserialize
traits. This way you can use any compatible serializer to store/send the data. To store the server_key
in a binary file, you can use the bincode
library:
Once the server key is available on the server side, it is possible to perform some homomorphic computations. The client needs to encrypt some data and send it to the server. Again, the Ciphertext
type implements the Serialize
and the Deserialize
traits, so that any serializer and communication tool suiting your use case can be employed:
Anyone (the server or a third party) with the public key can also encrypt some (or all) of the inputs. The public key can only be used to encrypt, not to decrypt.
Once the encrypted inputs are on the server side, the server_key
can be used to homomorphically execute the desired Boolean circuit:
Once the encrypted output is on the client side, the client_key
can be used to decrypt it:
This contains the operations available in tfhe::boolean, along with code examples.
Let ct_1, ct_2, ct_3
be three Boolean ciphertexts. Then, the MUX gate (abbreviation of MUltipleXer) is equivalent to the operation:
This example shows how to use the MUX ternary gate:
Since the ServerKey
and ClientKey
types both implement the Serialize
and Deserialize
traits, you are free to use any serializer that suits you to save and load the keys to disk.
Here is an example using the bincode
serialization library, which serializes to a binary format: