While using bootstrap with the following program, three questions came to mind.
- Isn’t the accuracy of the bootstrapped ciphertext low?
I can observe a 50-bit → 10-bit error.
-
The scale value of the bootstrapped ciphertext is squared. It seems like (scale) is correct, not (scale^2).
-
As a post-bootstrap calculation practice, I multiplied 1 by the bootstrapped ciphertext and got the wrong answer.
The program is as follows.
#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 << 16);
parameters.SetNumLargeDigits(3);
parameters.SetKeySwitchTechnique(HYBRID);
ScalingTechnique rescaleTech = FIXEDMANUAL;
usint dcrtBits = 50;
usint firstMod = 59;
parameters.SetScalingModSize(dcrtBits);
parameters.SetScalingTechnique(rescaleTech);
parameters.SetFirstModSize(firstMod);
std::vector<uint32_t> levelBudget = {3, 3};
std::vector<uint32_t> bsgsDim = {0, 0};
uint32_t approxBootstrapDepth = 9;
uint32_t levelsAvailableAfterBootstrap = 6;
usint depth = levelsAvailableAfterBootstrap + FHECKKSRNS::GetBootstrapDepth(approxBootstrapDepth, 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);
uint32_t numSlots=8;
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;
std::cout << "ciphertextAfter scale value : " << ciphertextAfter->GetScalingFactor() << std::endl << std::endl;
ciphertextAfter = cryptoContext->Rescale(ciphertextAfter);
Plaintext result;
cryptoContext->Decrypt(keyPair.secretKey, ciphertextAfter, &result);
result->SetLength(numSlots);
std::cout << "Output after bootstrapping \n\t" << result << std::endl;
std::vector<double> example(8, 1);
Plaintext exmaple_p = cryptoContext->MakeCKKSPackedPlaintext(example);
Ciphertext<DCRTPoly> exmaple_result = cryptoContext->EvalMult(ciphertextAfter, ptxt);
exmaple_result = cryptoContext->Rescale(exmaple_result);
cryptoContext->Decrypt(keyPair.secretKey, exmaple_result, &result);
result->SetLength(numSlots);
std::cout << "Output of multiplying \n\t" << result << std::endl;
}
The output is as follows.
CKKS scheme is using ring dimension 65536
Input: (0.62200457, 0.91855678, 0.47443048, 0.13907816, 0.75322639, 0.31923514, 0.44027182, 0.6205233, ... ); Estimated precision: 50 bits
Initial number of levels remaining: 1
Number of levels remaining after bootstrapping: 6
ciphertextAfter scale value : 1.26765e+30
Output after bootstrapping
(0.62120326, 0.91950136, 0.47396747, 0.13998224, 0.75340914, 0.31880892, 0.44032047, 0.62021078, ... ); Estimated precision: 10 bits
Output of multiplying
(0.38636131, 0.84450783, 0.22584997, 0.019939034, 0.5680056, 0.10228517, 0.19387869, 0.38522217, ... ); Estimated precision: 11 bits
Please let me know if I’m wrong or have any comments regarding these questions.
Thank you in advance.