Plaintext space for FHEW/TFHE

FHEW and TFHE work with small plaintext space. Typically, in one ciphertext we can encrypt one single element of Z_p (integers mod p) for small p (I would expect p from 2 to 2^8 or maybe up to 2^16).

However, I could not find a way of passing the value of p to the constructor of TFHE… I mean, the function GenerateBinFHEContext receives other parameters, but not p. So is there a way of passing the desired p to the crypto context before we generate the keys?

Playing with the parameters GenerateBinFHEContext receives, more specifically, with logQ, I managed to increase the value of p, as the code below shows. However, the maximum value I obtained was 2^3. So this is my second question: is there a way to instantiate TFHE with p>2^3?

#include "binfhecontext.h"
using namespace lbcrypto;

int main() {

    int logQ = 11; // OpenFHE does not support logQ < 11 and logQ > 29
                    // logQ = 11 --> max p = 4
                    // 12 <= logQ <= 29 --> max p = 8
                    
    auto cc = BinFHEContext();
    cc.GenerateBinFHEContext(STD128, true, logQ);
    auto sk = cc.KeyGen();

    std::cout << "Generating the bootstrapping keys..." << std::endl;
    cc.BTKeyGen(sk);
    int p = cc.GetMaxPlaintextSpace().ConvertToInt();  // Obtain the maximum plaintext space

    std::cout << "logQ = " << logQ << std::endl;
    std::cout << "Maximum plaintext modulus: p = " << p << std::endl;

    return 0;
}

General functionalities for TFHE only support p up to 3 bits, which is controlled by Q, as you noticed. In the Encrypt and Decrypt functions, you can also specify the plaintext modulus.

When you want to go to higher values of p, OpenFHE currently only implements operations such as digit decomposition into smaller plaintexts, which you can use to implement multi-precision operations, and floor or sign based on this decomposition technique. Please see eval-decomp.cpp, eval-flooring.cpp, eval-sign.cpp.