How to set Q value

Hello developers!

I have a question about mod Q in CKKS.

I understand that the OpenFHE specifications determine a certain mod Q value when N is set.

And to set a large mod Q, I can use the parameters.SetNumLargeDigits(dnum) function, right?

I set the maximum dnum value at N=2^15, and obtained log Q=810.

Generally, with N=2^15, I can set a maximum of log Q=881, right?

Therefore, the Q value I set is 71 smaller.

I would like to obtain the maximum mod Q value. Is there any other way to set that value?

The SetNumLargeDigits is a function that controls the decomposition performed during the relinearization phase (see the d_\text{num} value in https://eprint.iacr.org/2021/204.pdf). It controls the magnitude of the additional modulus P if HYBRID key switching is used. I am not aware of how that deals with the main modulus Q.

Thank you for providing details about SetNumLargeDigits.

If anyone knows how to control modulus Q, please let me know.

You can control Q by adjusting the multiplicative depth.

Generally speaking, you should not set Q manually. OpenFHE handles that based on the desired security level and functionality.

Following your reply, I tried experimenting with the following parameter settings, but received an error telling me to increase the order N.

This code has ring Dimension=2^15, q_0 size=59, q_i size=50, and depth=16. With this order, modulus Q should be able to be used up to 881, so 59+50*16=859, and this code should not result in an error.

Why did this occur?

code:

#define PROFILE

#include "openfhe.h"

using namespace lbcrypto;

int main(int argc, char* argv[]) {
    CCParams<CryptoContextCKKSRNS> parameters;

    SecretKeyDist secretKeyDist = SPARSE_TERNARY;
    parameters.SetSecretKeyDist(secretKeyDist);

    parameters.SetSecurityLevel(HEStd_128_classic);
    parameters.SetRingDim(1 << 15);

    parameters.SetKeySwitchTechnique(HYBRID);

    ScalingTechnique rescaleTech = FIXEDMANUAL;
    usint dcrtBits               = 50;
    usint firstMod               = 59;

    parameters.SetScalingModSize(dcrtBits);
    parameters.SetScalingTechnique(rescaleTech);
    parameters.SetFirstModSize(firstMod);

    usint depth = 16;
    parameters.SetMultiplicativeDepth(depth);

    CryptoContext<DCRTPoly> cryptoContext = GenCryptoContext(parameters);

    std::cout << cryptoContext->GetModulus().GetMSB() << std::endl;

    std::cout << depth << std::endl;
}

error message:

openfhe-development/src/pke/lib/scheme/ckksrns/ckksrns-parametergeneration.cpp:l.149:ParamsGenCKKSRNSInternal(): The specified ring dimension (32768) does not comply with HE standards recommendation (65536).

Consider that by fixing HYBRID key switching, the modulus is extended from \log(Q) to \log(QP), where the magnitude of P depends on the decomposition of the ciphertext (d_\text{num} value). See page 29 of https://eprint.iacr.org/2021/204.pdf

1 Like

To add more info to @narger’s response.

There are other moduli used internally in OpenFHE, and P is one of them. The totatlity of \log_2{}QP is used to define the security level. Note also that Q itself might include additional moduli more than just (1+depth) moduli depending.

OpenFHE automatically selects a specific ring dimension to ensure the desired security level is met for the needed functionality (which is mostly defined by the specified scheme, circuit depth, and moduli sizes).

So in your case, you need to decrease the depth and/or the dcrtBits if you want to maintain the ring dimension at 2^{15}.
Or you can select a different key switching algorithm that requires smaller P and that by itself is a topic of its own.