Hello,
I am currently experimenting with the re-encryption in a multi party setup using CKKS scheme, the idea is to re-encrypt the ciphertext which was encrypted using the shared public key. The setup is the following:
Parties 1 and 2 and their corresponding secret shares of key pairs kp1
and kp2
are used to create the shared public key (SharedPubKey). The ciphertext ct1 is encrypted using the shared public key. The receiver has the key pair kp3 and provides its public key for the re-encryption process.
I tried to perform a re-encryption in a following way:
// Ciphertext
ct1 = cc->Encrypt(SharedPubKey, plaintext);
// Party 1
evalKey1 = cc->ReKeyGen(kp1.secretKey, kp3.publicKey);
REct1 = cc->ReEncrypt(ct1, evalKey1);
// Party 2
evalKey2 = cc->ReKeyGen(kp2.secretKey, kp3.publicKey);
REct2 = cc->ReEncrypt(REct1, evalKey2);
//Receiver
cc->Decrypt(kp3.secretKey, REct2, &Result);
but this results with an error saying that decryption cannot be done due to the high approximation error[1], which probably means that the procedure is not correct.
The crypto context parameters are: multDepth = 1, scaleFactorBits = 50 and batchSize = 64. Following functionalities are enabled: PKE, KEYSWITCH, PRE, LEVELEDSHE, ADVANCEDSHE, MULTIPARTY. I went through a similar post on this topic (proxy re-encryption using ckks) and unit tests for multi party, ckks and multiHopPRE.
I would appreciate any feedback on this matter.
Thanks
[1] src/pke/lib/encoding/ckkspackedencoding.cpp:515 The decryption failed because the approximation error is too high. Check the parameters.
EDIT:
just found in src/pke/include/cryptocontext.h:2368 MultipartyKeyGen(const PublicKey<Element> publicKey, bool makeSparse = false, bool fresh = false)
when creating keypair kp2 for the party 2, ‘fresh’ parameter should be set to true, in order for re-encryption to work in a multi party setup. Then, only party 2 would need to do the following:
// Party 2
evalKey2 = cc->ReKeyGen(kp2.secretKey, kp3.publicKey);
REct2 = cc->ReEncrypt(ct1, evalKey2);
// Receiver
cc->Decrypt(kp3.secretKey, REct2, &Result);
It is however then also possible to decrypt the ct1 using only kp2.secretKey.