Re-encrypting decrypted plaintext throws OpenFHEException

I am trying to run the following code, which tries to re-encrypt a decrypted plaintext, but it throws an OpenFHEException in a recursive call from the second Encrypt. Where am I going wrong?

#include <openfhe.h>

using namespace lbcrypto;

int main()
{
    CCParams<CryptoContextBGVRNS> params;
    params.SetPlaintextModulus(65537);

    CryptoContext<DCRTPoly> cc = GenCryptoContext(params);
    cc->Enable(PKE | LEVELEDSHE);

    KeyPair<DCRTPoly> kp = cc->KeyGen();

    std::vector<int64_t> vec(10, 1L);
    Plaintext plain = cc->MakePackedPlaintext(vec);
    Ciphertext<DCRTPoly> cipher = cc->Encrypt(kp.publicKey, plain);

    cc->Decrypt(kp.secretKey, cipher, &plain);
    cipher = cc->Encrypt(kp.publicKey, plain);
}

More specifically, I am getting the following exception:

terminate called after throwing an instance of 'lbcrypto::OpenFHEException'
  what():  openfhe-development/src/core/include/lattice/hal/default/dcrtpoly-impl.h:l.705:DropLastElements(): DropLastElements: Too few towers in input.

This is not the right (secure) way to use a plaintext. To encode a vector, MakePackedPlaintext should be used for an input vector (similar to how plain is generated). The plain plaintext in your code seems to be reused for the next plaintext (without calling any MakePackedPlaintext or an equivalent functionality). The plaintext that is populated by Decrypt automatically erases an instance of DCRTPoly so that it could not be used for any secret key recovery attack, i.e., extract the error from the decrypted polynomial.

You should instead use plain->GetPackedValue() to extract a vector of integers and encode it as a new plaintext by using MakePackedPlaintext before invoking the second Encrypt.

1 Like