Questions regarding implementation with TFHE-rs

Hi team!
I’m involved in developing a research project using TFHE-rs. During my implementation, I got some interesting results thus have the following questions:

  1. For a simple math formula such as |a - b| < c * d, I used both high-level FheInt16 APIs and Radix-based integer APIs (with param PARAM_MESSAGE_2_CARRY_2_KS_PBS, 8 blocks), but found out the former was even ~5% faster than the latter.
    Actually I expected Radix-based integer would be faster than FheInt16. So I wonder if my result is reasonable? Or Radix indeed should be faster instead, and something is wrong with my code?

  2. Based on my test, a serialized ServerKey is ~109.5 Mega bytes, and a serialized FheInt16 is ~131.6 Kilo bytes or 680 bytes (compressed).
    Are these numbers correct? And if they are correct, I wonder how you manage to achieve such a big compression factor for FheInt, after all a compressed FheInt16 is 193 times smaller than the original.

Thank you and I look forward to your reply :slight_smile:

Another question I just discovered: for the server side, how to compress a FheInt16 to a CompressedFheInt16?
I realize the client can get compressed integer by CompressedFheInt16::try_encrypt(), but is it possible for the server to convert the computation result, a general integer, to compressed integer?

Hello @vesperl

For the performance it’s hard to say without the code example, it’s possible there are some fluctuations when benchmarking code due to various factors. FheInt16 are based on RadixCiphertext so performance should be very very similar.

The numbers look correct.

For the compression it uses a seeding strategy. The mask on an LWE ciphertext is publicly known and generated by a CSPRNG which is deterministic, so instead of sending the mask values we just send the seed used to generate the masks and then when decompressing the CSPRNG re-generates the exact same values.

It is not possible to compress a ciphertext on the server side, the reason being that re generating the masks once computations have been done is not possible at the moment (there might be some techniques for that but that’s not clear yet and likely a research topic).

Cheers!

Thanks for your timely reply!

Following the first question, if FheInt16 and RadixCiphertext have similiar performance, is there any other APIs (probably low-level) to use to achieve a potentially better performance?

One further question:
What could be the best practice if I want to compute square root using TFHE-rs?
I know there are many ways to do it, such as Newton’s method, polynomial approximation, and the famous fast algorithm of computing the inverse of square root. But could you provide some recommendations from your point of view?

We do have lower level API:

  • shortint (from which the integer API is built)
  • core_crypto (from which shortint is built on)

As if often the case when going to lower levels of abstractions, you have a better potential for performances as you have more control, but, you also have more work to do and more responsibilities.

In this case that means reimplementing all the large integer arithmetic by hand if you choose shortint, if you choose core_crypo, you would also need to implement ‘small integer arithemetic’.
On top of that since this is FHE, you would also have to manage the noise and error propabilities, which are things abstracted by integer API and and FheUint based API.

As for square root, this is not something we have yet worked on, and so we cannot provide any meaningful recommentations

Cool good to know that. Thank you for the detailed response, and wish you a nice weekend.