Hello there,
I am looking into parametrizing CKKS with modulus chain containing co-primes of up to 32 bits.
I try to enforce it by setting firstModSize=30
and scalingModSize=27
, while the library is compiled with NATIVEINT=64
.
For context, the parameters are set as per the code snippet below:
lbcrypto::CCParams<lbcrypto::CryptoContextCKKSRNS> parameters;
parameters.SetSecurityLevel(lbcrypto::HEStd_128_classic);
parameters.SetRingDim(1 << 16);
std::vector<uint32_t> levelBudget = {4, 4};
SecretKeyDist secretKeyDist = UNIFORM_TERNARY;
parameters.SetSecretKeyDist(secretKeyDist);
uint32_t depth = 16 + lbcrypto::FHECKKSRNS::GetBootstrapDepth(8, levelBudget, secretKeyDist);
parameters.SetMultiplicativeDepth(depth);
// NATIVEINT comes from OpenFHE #defines.
if (NATIVEINT == 128) {
parameters.SetScalingModSize(78);
parameters.SetFirstModSize(89);
} else { // NATIVEINT=64 or NATIVEINT=32
parameters.SetScalingModSize(27);
parameters.SetFirstModSize(30);
}
However, the modulus chain generated contains co-primes with 60 bits instead of breaking them down into co-primes of half the size – see below.
q_0: 1073479681, log q_0: 29.9996
q_1: 158072833, log q_1: 27.236
q_2: 113246209, log q_2: 26.7549
q_3: 156499969, log q_3: 27.2216
q_4: 114032641, log q_4: 26.7649
q_5: 155189249, log q_5: 27.2095
q_6: 115081217, log q_6: 26.7781
q_7: 154533889, log q_7: 27.2033
q_8: 115212289, log q_8: 26.7797
q_9: 152174593, log q_9: 27.1812
q_10: 115998721, log q_10: 26.7895
q_11: 151388161, log q_11: 27.1737
q_12: 117964801, log q_12: 26.8138
q_13: 151257089, log q_13: 27.1724
q_14: 118751233, log q_14: 26.8234
q_15: 150863873, log q_15: 27.1687
q_16: 120324097, log q_16: 26.8424
q_17: 149815297, log q_17: 27.1586
q_18: 120586241, log q_18: 26.8455
q_19: 147849217, log q_19: 27.1396
q_20: 123863041, log q_20: 26.8842
q_21: 145489921, log q_21: 27.1163
q_22: 125042689, log q_22: 26.8978
q_23: 144310273, log q_23: 27.1046
q_24: 125698049, log q_24: 26.9054
q_25: 142344193, log q_25: 27.0848
q_26: 126222337, log q_26: 26.9114
q_27: 141557761, log q_27: 27.0768
q_28: 126615553, log q_28: 26.9159
q_29: 140771329, log q_29: 27.0688
q_30: 127664129, log q_30: 26.9278
q_31: 138412033, log q_31: 27.0444
q_32: 127795201, log q_32: 26.9293
q_33: 136314881, log q_33: 27.0224
q_34: 130809857, log q_34: 26.9629
q_35: 135135233, log q_35: 27.0098
q_36: 132120577, log q_36: 26.9773
q_37: 134348801, log q_37: 27.0014
q_38: 1152921504606584833, log q_38: 60
q_39: 1152921504598720513, log q_39: 60
q_40: 1152921504597016577, log q_40: 60
q_41: 1152921504595968001, log q_41: 60
q_42: 1152921504592822273, log q_42: 60
q_43: 1152921504592429057, log q_43: 60
Total bit length: 1388.9
Why did it not just generated more co-primes instead of resorting to 60-bit ones?
Then, I recompiled the OpenFHE library with NATIVEINT=32 and recompiled the application with firstModSize=28, with which I got the following runtime error below.
fatal error: in "test_case": lbcrypto::math_error: /home/user/openfhe-development/src/core/lib/math/nbtheory.cpp:518 FirstPrime math exception
The question is how to ensure that each modulus in the chain respects the 32-bit word size.
In the current OpenFHE CKKS implementation is this possible/supported? If so, how to accomplish it?
Thanks in advance