Hi OpenFHE team!
In my algorithm implementation, I found a series of weird outputs. For example, I set MultiplicativeDepth = 0 and scaleModSize = 58. In a for loop, EvalAdd(c1, c2) will pop up random number when c1 = 5 and c2 = 8188. Such as added 8188.000000: (7869.013, ... ); Estimated precision: 43 bits
. And also pop up random numbers in scaleModSize = 59 and 57. scaleModSize = 59 case will pop up random number in c1 = 5 and c2 = 4092. Such as added 4092.000000: (3867.0186, ... ); Estimated precision: 44 bits
. scaleModSize=57 case: added 16380.000000: (15929.009, ... ); Estimated precision: 42 bits
A weird question. But when you add some MultiplicativeDepth, it returns normal. I know MultipcativeDepth = 0 is some kind of edge value for parameter setting. But seems I don’t use the Mult function in all calculation processes, it shouldn’t be abnormal, If Multipcative Depth = 0 isn’t allowed, then the result should pop up the random number at the begin of the loop instead of the right result. By the way, I tried all four modes (FLEXIBLEAUTO、FLEXIBLEAUTOEXT、FIXEDMANUAL、FIXEDAUTO) and still came up with the same result.
Here is the MWE
#include <iostream>
#include "openfhe.h"
using namespace std;
using namespace lbcrypto;
int main() {
uint32_t multDepth = 0;
uint32_t scaleModSize = 58;
CCParams<CryptoContextCKKSRNS> parameters;
parameters.SetMultiplicativeDepth(multDepth);
parameters.SetScalingModSize(scaleModSize);
parameters.SetFirstModSize(60);
std::cout << "depth:" << parameters.GetMultiplicativeDepth() << std::endl;
std::cout << "scaleModSize:" << parameters.GetScalingModSize() << std::endl;
CryptoContext<DCRTPoly> cc = GenCryptoContext(parameters);
cc->Enable(PKE);
cc->Enable(KEYSWITCH);
cc->Enable(LEVELEDSHE);
cc->Enable(ADVANCEDSHE);
std::cout << "CKKS scheme is using ring dimension " << cc->GetRingDimension() << std::endl << std::endl;
auto keys = cc->KeyGen();
cc->EvalMultKeyGen(keys.secretKey);
std::vector<double> x1 = {5};
Plaintext ptxt1 = cc->MakeCKKSPackedPlaintext(x1);
std::cout << "Input x1: " << ptxt1 << std::endl;
std::cout.precision(8);
auto c1 = cc->Encrypt(keys.publicKey, ptxt1);
for(double i = 0; i < 65537; i++) {
auto c2 = cc->Encrypt(keys.publicKey, cc->MakeCKKSPackedPlaintext(vector<double>{i}));
auto added = cc->EvalAdd(c1, c2);
Plaintext p;
cc->Decrypt(keys.secretKey, added, &p);
p->SetLength(1);
cout << "added " << to_string(i) << ":\t" << p << endl;
}
return 0;
}
Is this a bug?
I would really appreciate any insights or explanations regarding this behavior.
Thank you for your help!
Best regards,
wowblk