Closed Dylan-yxn closed 4 years ago
Errors after Resclae() occur in the DCKKS scheme, but I have tested that they do not occur in the CKKS scheme.
Hello,
Is it possible to provide a minimal code reproducing the behavior ? In particular, how are you decrypting the ciphertext ?
Thank you for your reply. Here is my code:
....
//input
for j:= range pi.input{
pi.input[j] = complex(1, 0)
}
/*CKG*/
...
/*RKG*/
...
encoder := ckks.NewEncoder(params)
encInputs := make([]*ckks.Ciphertext, N, N)
encryptor := ckks.NewEncryptorFromPk(params, pk)
for i := range encInputs {
encInputs[i] = ckks.NewCiphertext(params, 1,params.MaxLevel(),params.Scale)
}
pt := ckks.NewPlaintext(params,params.MaxLevel(),params.Scale)
for i, pi := range P {
encoder.Encode(pt,pi.input,slots)
encryptor.Encrypt(pt, encInputs[i])
}
evaluator := ckks.NewEvaluator(params)
/*caculate*/
result := encInputs[0]
evaluator.MulRelin(result,encInputs[1],rlk,result)
fmt.Println(math.Log2(result.Scale()))
evaluator.Rescale(result,params.Scale,result)
fmt.Println(math.Log2(result.Scale()))
/*CKS*/
zero := params.NewPolyQ()
cksCombined := cks.AllocateShare()
for _, pi := range P[1:] {
cks.GenShare(pi.sk.Get(), zero, result, pi.cksShare)
}
encOut := ckks.NewCiphertext(params, 1,params.MaxLevel(),params.Scale)
for _, pi := range P {
cks.AggregateShares(pi.cksShare, cksCombined, cksCombined)
}
cks.KeySwitch(cksCombined,result, encOut)
/*decrypt*/
decryptor := ckks.NewDecryptor(params, P[0].sk)
ptres := ckks.NewPlaintext(params,params.MaxLevel(),params.Scale)
decryptor.Decrypt(encOut, ptres)
res := encoder.Decode(ptres,slots)
fmt.Printf(" %6f %6f %6f %6f %6f\n",
round(res[0]), round(res[1]), round(res[2]), round(res[3]), round(res[4]))
If I didn't use Rescale (), I would get the correct answer, but I got the following answer after using:
Thank you very much. I'll take a look and get back to you as soon as I figured out what is going on.
There is something I do not understand in your code. You have
The CKS already decrypts the ciphertext if you switch to the key zero, therefor all you need to to is to call encOut.Plaintext() to switch the element to a type plaintext and be able to decode it.
Thanks for your reminder.
res := encoder.Decode(encOut.Plaintext(),slots)
But after decrypting, the answer still has the same error.
Could you give me a link go your entire go file? It will be easier for me to find where the bug is occurring
Here is my code: https://github.com/Dylan-yxn/examples_dckks
I found what was going wrong and why the rescale made it decrypt bad.
First, I was wrong, your decryption code was correct my bad for that, it was partially decrypting to the secret-key of P[0], and then P[0] would finish the decryption with his own key. You can revert the code to its previous state.
Then the bad decryption is occurring because
encOut := ckks.NewCiphertext(params, 1, params.MaxLevel(), params.Scale)
is created at max level. But the level of the ciphertext after you rescale is reduced by one (this is also why it was working fine without rescale), so instead you should use
encOut := ckks.NewCiphertext(params, 1, result.Level(), params.Scale)
Tell me if it fixes it
I tried:
encOut := ckks.NewCiphertext(params, 1 ,result.Level(),result.Scale())
and
encOut := ckks.NewCiphertext(params, 1 ,result.Level(),params.Scale)
But it didn't work.
Did you revert the code to its original decryption state? Because its working fine for me on the code that you provided.
Thank you for your explanation. It can now be decrypted normally.
Hi, when I use Rescale() after Mul, the result is wrong. And it doesn't just happen occasionally. Here is my code:
if we decrypt after MulRelin, we will get the corrext answer. And we decrypt after Rescale(), we will get a huge answer . The answer is different every time.
Here is one of answer:
I wonder if my usage of Rescale () is wrong. How to use it correctly.