Hello, OpenFHE Team!
I have been conducting tests related to the approximation error of the CKKS scheme in the OpenFHE library. However, I encountered inaccurate results with the following code, and I would like to ask whether this is a bug or intended behavior:
int main() {
CCParams<CryptoContextCKKSRNS> parameters;
parameters.SetMultiplicativeDepth(2);
parameters.SetScalingTechnique(FLEXIBLEAUTO);
CryptoContext<DCRTPoly> cc = GenCryptoContext(parameters);
cc->Enable(PKE);
cc->Enable(LEVELEDSHE);
auto keys = cc->KeyGen();
cc->EvalMultKeyGen(keys.secretKey);
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_real_distribution<> dis(-10000, 10000);
std::vector<double> x1;
std::vector<double> x2;
for (int i = 0; i < 10; ++i) {
x1.push_back(dis(gen));
}
for (int i = 0; i < 10; ++i) {
x2.push_back(2);
}
Plaintext ptxt = cc->MakeCKKSPackedPlaintext(x1);
Plaintext two = cc->MakeCKKSPackedPlaintext(x2);
auto c = cc->Encrypt(keys.publicKey, ptxt);
auto c2 = c;
c2 = cc->EvalMult(c,two);
c = cc->EvalSub(c2, c);
c2 = cc->EvalMult(c,two);
c = cc->EvalSub(c2, c);
auto ctxtResult = c;
Plaintext ptxtResult;
cc->Decrypt(keys.secretKey, ctxtResult, &ptxtResult);
ptxtResult->SetLength(10);
std::vector<std::complex<double>> ptxtVector = ptxt->GetCKKSPackedValue();
std::vector<std::complex<double>> ptxtResultVector = ptxtResult->GetCKKSPackedValue();
std::cout << "ptxt: " << ptxt->GetCKKSPackedValue() << std::endl;
std::cout << "ptxtResult: " << ptxtResult->GetCKKSPackedValue() << std::endl;
return 0;
}
The result of the above code is:
ptxt: [ (-4518.65,0) (-6672.61,0) (8182.46,0) (4077.88,0) (4919.93,0) (7687.54,0) (-6666.36,0) (-9725.97,0) (-213.667,0) (8150.64,0) ]
ptxtResult: [ (-101.752,0) (-58.4617,0) (-15.5489,0) (49.0504,0) (-35.0718,0) (-103.309,0) (-100.685,0) (-172.045,0) (58.4681,0) (-21.6191,0) ]
,which seems to me weird because Dec(c) (= ptxtResult) must be very close to ptxt value.
Additional Info:
When I change MultiplicativeDepth(1), it throws error The decryption failed because the approximation error is too high. Check the parameters.
For MultiplicativeDepth(3), ptxt and ptxtResult are very close, with negligible errors.