Hello everyone!
Thank you for always providing such a great library!
I’m currently conducting research using CKKS and am a beginner.
I’ve never used bootstrapping before, in particular.
So, I have a question: when achieving 128-bit security with ring dimension = 2^16, how should I set the bootstrapping parameters?
I created the following program based on advanced-ckks-bootstrapping.ccp, but an error occurred.
#define PROFILE
#include "openfhe.h"
using namespace lbcrypto;
void BootstrapExample(uint32_t numSlots);
int main(int argc, char* argv[]) {
BootstrapExample(8);
}
void BootstrapExample(uint32_t numSlots) {
CCParams<CryptoContextCKKSRNS> parameters;
SecretKeyDist secretKeyDist = UNIFORM_TERNARY;
parameters.SetSecretKeyDist(secretKeyDist);
parameters.SetSecurityLevel(HEStd_128_classic); //changed
parameters.SetRingDim(1 << 16); //changed
parameters.SetNumLargeDigits(3);
parameters.SetKeySwitchTechnique(HYBRID);
#if NATIVEINT == 128
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);
std::vector<uint32_t> levelBudget = {4, 4}; //changed
std::vector<uint32_t> bsgsDim = {0, 0};
uint32_t levelsAvailableAfterBootstrap = 3; //changed
usint depth = levelsAvailableAfterBootstrap + FHECKKSRNS::GetBootstrapDepth(levelBudget, secretKeyDist);
parameters.SetMultiplicativeDepth(depth);
CryptoContext<DCRTPoly> cryptoContext = GenCryptoContext(parameters);
cryptoContext->Enable(PKE);
cryptoContext->Enable(KEYSWITCH);
cryptoContext->Enable(LEVELEDSHE);
cryptoContext->Enable(ADVANCEDSHE);
cryptoContext->Enable(FHE);
usint ringDim = cryptoContext->GetRingDimension();
std::cout << "CKKS scheme is using ring dimension " << ringDim << std::endl << std::endl;
cryptoContext->EvalBootstrapSetup(levelBudget, bsgsDim, numSlots);
auto keyPair = cryptoContext->KeyGen();
cryptoContext->EvalMultKeyGen(keyPair.secretKey);
cryptoContext->EvalBootstrapKeyGen(keyPair.secretKey, numSlots);
std::vector<double> x;
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_real_distribution<> dis(0.0, 1.0);
for (size_t i = 0; i < numSlots; i++) {
x.push_back(dis(gen));
}
Plaintext ptxt = cryptoContext->MakeCKKSPackedPlaintext(x, 1, depth - 1, nullptr, numSlots);
ptxt->SetLength(numSlots);
std::cout << "Input: " << ptxt << std::endl;
Ciphertext<DCRTPoly> ciph = cryptoContext->Encrypt(keyPair.publicKey, ptxt);
std::cout << "Initial number of levels remaining: " << depth - ciph->GetLevel() << std::endl;
auto ciphertextAfter = cryptoContext->EvalBootstrap(ciph);
std::cout << "Number of levels remaining after bootstrapping: " << depth - ciphertextAfter->GetLevel() << std::endl
<< std::endl;
Plaintext result;
cryptoContext->Decrypt(keyPair.secretKey, ciphertextAfter, &result);
result->SetLength(numSlots);
std::cout << "Output after bootstrapping \n\t" << result << std::endl;
}
openfhe-development/src/pke/lib/scheme/ckksrns/ckksrns-parametergeneration.cpp:l.148:ParamsGenCKKSRNSInternal(): The specified ring dimension (65536) does not comply with HE standards recommendation (131072).
Looking at other papers, it appears that bootstrapping has been successfully performed while achieving 128-bit security with N = 2^16.
Thank you in advance for your help.