Hello!
I encountered this problem. I need to calculate the composition of polynomials in encrypted form using the CKKS scheme.
To do this, I take a vector of my values, encrypt it and execute the EvalPolyPS() function (The comments indicated to use it if the degree of the polynomial is greater than 5).
Then I perform the EvalPolyPS() function on the obtained result again.
Then, when decrypting, I encounter the error “The decryption failed because the approximation error is too high. Check the parameters.”
I tried changing the parameters and bootstrapping, but the error still remains. Could you tell me what needs to be done? Maybe I made a mistake somewhere? I am attaching my code below.
uint32_t multDepth = 6;
uint32_t scaleModSize = 4096;
uint32_t batchSize = 16;
std::vector<double> input1 = {1, 2, 0, 3, 6, 5};
CCParams<CryptoContextCKKSRNS> parameters;
parameters.SetMultiplicativeDepth(multDepth);
parameters.SetScalingModSize(scaleModSize);
parameters.SetBatchSize(batchSize);
SecretKeyDist secretKeyDist = UNIFORM_TERNARY;
parameters.SetSecretKeyDist(secretKeyDist);
parameters.SetSecurityLevel(HEStd_NotSet);
parameters.SetRingDim(1 << 14);
#if NATIVEINT == 128 && !defined(__EMSCRIPTEN__)
ScalingTechnique rescaleTech = FIXEDAUTO;
usint dcrtBits = 78;
usint firstMod = 89;
#else
ScalingTechnique rescaleTech = FLEXIBLEAUTO;
usint dcrtBits = 59;
usint firstMod = 60;
#endif
parameters.SetScalingModSize(dcrtBits);
parameters.SetScalingTechnique(rescaleTech);
parameters.SetFirstModSize(firstMod);
uint32_t numIterations = 2;
std::vector<uint32_t> levelBudget = {3, 3};
std::vector<uint32_t> bsgsDim = {0, 0};
uint32_t levelsAvailableAfterBootstrap = 10;
usint depth =
levelsAvailableAfterBootstrap + FHECKKSRNS::GetBootstrapDepth(levelBudget, secretKeyDist) + (numIterations - 1);
parameters.SetMultiplicativeDepth(depth);
CryptoContext<DCRTPoly> cc = GenCryptoContext(parameters);
cc->Enable(PKE);
cc->Enable(KEYSWITCH);
cc->Enable(LEVELEDSHE);
cc->Enable(ADVANCEDSHE);
cc->Enable(FHE);
std::cout << "CKKS scheme is using ring dimension " << cc->GetRingDimension() << std::endl << std::endl;
auto keys = cc->KeyGen();
cc->EvalBootstrapSetup(levelBudget, bsgsDim, batchSize);
cc->EvalMultKeyGen(keys.secretKey);
cc->EvalBootstrapKeyGen(keys.secretKey, batchSize);
///Poly_coef
std::vector<double> f4_coef = {(315.0/128.0), 0, (-105.0/32.0), 0, (189.0/64.0), 0, (-45.0/32.0), 0, (35.0/128.0)};
std::vector<double> g4_coef = {(5850.0/pow(2.0,10)), 0, (-34974.0/pow(2.0,10)), 0, (97015.0/pow(2.0,10)), 0, (-113492.0/pow(2.0,10)), 0, (46623.0/pow(2.0,10))};
// Encoding as plaintexts
Plaintext ptxt1 = cc->MakeCKKSPackedPlaintext(input);
auto ctxt = cc->Encrypt(keys.publicKey, ptxt1);
auto poly_1 = cc->EvalPolyPS(ctxt,f4_coef);
auto poly_1_b_1 = cc->EvalBootstrap(poly_1);
auto res = cc->EvalPolyPS(poly_1_b_1,g4_coef);
Plaintext result;
cc->Decrypt(keys.secretKey, res, &result);
result->SetLength(batchSize);
std::cout << "res = " << result << std::endl;