Hi everyone, I am trying to understand the approximate modular reduction step during bootstrapping.
I suppose OpenFHE implements the scaled cosine technique by Han & Ki. By assuming K = 512 and r = 3, I tried approximating the scaled cosine using the formula in Table I, here. I tried to print out the coefficients (by adding print statements to EvalChebyshevSeries), but saw a discrepancy between when I manually approximate the scaled cosine versus when I call bootstrapping. Could you help me understand what function the bootstrapping modular reduction approximates?
Here is a small working example. Thank you so much for your help.
#include <iostream>
#include <vector>
#include <chrono>
#include "openfhe.h"
using namespace std;
using namespace lbcrypto;
int main() {
CCParams<CryptoContextCKKSRNS> parameters;
int batchsize = 1 << 14;
parameters.SetSecurityLevel(HEStd_NotSet);
parameters.SetRingDim(1 << 15);
parameters.SetBatchSize(batchsize);
usint scalingModSize = 59;
parameters.SetScalingModSize(scalingModSize);
std::vector<uint32_t> levelBudget = {3, 3};
std::vector<uint32_t> bsgsDim = {16, 16};
SecretKeyDist secretKeyDist = UNIFORM_TERNARY;
uint32_t levelsAvailableAfterBootstrap = 7;
usint depth = levelsAvailableAfterBootstrap + FHECKKSRNS::GetBootstrapDepth(levelBudget, secretKeyDist);
parameters.SetMultiplicativeDepth(depth);
CryptoContext<DCRTPoly> cc = GenCryptoContext(parameters);
cc->Enable(PKE);
cc->Enable(KEYSWITCH);
cc->Enable(LEVELEDSHE);
cc->Enable(ADVANCEDSHE);
cc->Enable(FHE);
auto keyPair = cc->KeyGen();
cc->EvalMultKeyGen(keyPair.secretKey);
cc->EvalBootstrapSetup({3, 3}, {16, 16}, batchsize);
cc->EvalBootstrapKeyGen(keyPair.secretKey, batchsize);
vector<double> input = {1};
Plaintext plaintext = cc->MakeCKKSPackedPlaintext(input);
auto ciphertext = cc->Encrypt(keyPair.publicKey, plaintext);
// Assuming K = 512 and r = 3
ciphertext = cc->EvalChebyshevFunction([](double x) -> double { return std::cos((double)M_PI * ((double)x - 0.25) / (double)4.0); }, ciphertext, -64, 64, 89);
ciphertext = cc->EvalBootstrap(ciphertext);
return 0;
}
Output:
Chebyshev coefficients:
0.155704, -0.0308194, 0.161869, ...
Chebyshev coefficients:
0.154214, -0.003767, 0.160320, ...