Hello, I am trying to convert a project to HE domain, and had the following issue when I was using Palisade (now I plan to use OpenFHE instead and I think that the memory consumed will reduce, but haven’t tested this out) -
I noticed that for creation of one ciphertext, my program takes ~43MB RAM, and for ‘n’ ciphertexts in general(large n), takes ‘n’ MB RAM.
In my current benchmark, I am creating an array[10^8], and want to create ciphertext out of each element in the array, which is shooting up the RAM needed.
I am pasting a piece of the Palisade code I am using, where multiple ciphertexts are being created, and using this, if you create something like vecCT v(1000000000), it causes memory overflow.
Can you please tell if Palisade indeed takes lot of memory for ciphertext creation, and if there is any workaround to reduce memory usage by program in case lots of ciphertexts are created?
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include "palisade.h"
using namespace lbcrypto;
using namespace std;
extern uint64_t p; // = 65537;
extern double sigma; //= 3.2;
extern SecurityLevel securityLevel ; //= HEStd_128_classic;
extern uint32_t depth; // = 2;
extern CryptoContext<DCRTPoly> cc; // = CryptoContextFactory<DCRTPoly>::genCryptoContextBFVrns(p, securityLevel, sigma, 0, depth, 0, OPTIMIZED);
extern int32_t n; // = cc->GetCryptoParameters()->GetElementParams()->GetCyclotomicOrder()/2;
extern LPKeyPair<DCRTPoly> kp;
extern bool init_flag;
//data types we will need
using CT = Ciphertext<DCRTPoly> ; //ciphertext
using PT = Plaintext ; //plaintext
using vecCT = vector<CT>; //vector of ciphertexts
using vecPT = vector<PT>; //vector of plaintexts
using vecInt = vector<int64_t>; // vector of ints
using vecChar = vector<char>; // vector of characters
// uint64_t p = 65537;
uint64_t p=12869861377;
double sigma = 3.2;
SecurityLevel securityLevel = HEStd_128_classic;
uint32_t depth = 3;
CryptoContext<DCRTPoly> cc = CryptoContextFactory<DCRTPoly>::genCryptoContextBFVrns(p, securityLevel, sigma, 0, depth, 0, OPTIMIZED);
int32_t n = cc->GetCryptoParameters()->GetElementParams()->GetCyclotomicOrder()/2;
LPKeyPair<DCRTPoly> kp;
bool init_flag=false;
void init()
{
if(init_flag==false)
{
cc->Enable(ENCRYPTION);
cc->Enable(SHE);
kp=cc->KeyGen();
cc->EvalMultKeyGen(kp.secretKey);
// cc->EvalAtIndexKeyGen(kp.secretKey, {1, 2, -1, -2});
init_flag=true;
}
}
vector<int64_t> decrypt_ciphertext_to_plaintext_vector(Ciphertext<DCRTPoly> ciphertext)
{
Plaintext plaintext;
cc->Decrypt(kp.secretKey, ciphertext, &plaintext);
vector<int64_t> v=plaintext->GetPackedValue();
return v;
}
/* Put integer as single element in a plaintext vector, then encrypt that vector and return the ciphertext */
Ciphertext<DCRTPoly> encrypt_plaintext_integer_to_ciphertext(int64_t d)
{
init();
int64_t c=d;
vector<int64_t> vec;
vec.clear();
vec.push_back(c);
Plaintext plaintext = cc->MakePackedPlaintext(vec);
auto ciphertext = cc->Encrypt(kp.publicKey, plaintext);
return ciphertext;
}
int main() {
CT c=encrypt_plaintext_integer_to_ciphertext(10); CT c2=encrypt_plaintext_integer_to_ciphertext(1);
CT c3=encrypt_plaintext_integer_to_ciphertext(10); CT c4=encrypt_plaintext_integer_to_ciphertext(1);
CT c5=encrypt_plaintext_integer_to_ciphertext(10); CT c6=encrypt_plaintext_integer_to_ciphertext(1);
CT c7=encrypt_plaintext_integer_to_ciphertext(10); CT c8=encrypt_plaintext_integer_to_ciphertext(1);
CT c9=encrypt_plaintext_integer_to_ciphertext(10); CT c10=encrypt_plaintext_integer_to_ciphertext(1);
CT c11=encrypt_plaintext_integer_to_ciphertext(10); CT c12=encrypt_plaintext_integer_to_ciphertext(1);
CT c13=encrypt_plaintext_integer_to_ciphertext(10); CT c14=encrypt_plaintext_integer_to_ciphertext(1);
CT c15=encrypt_plaintext_integer_to_ciphertext(10); CT c16=encrypt_plaintext_integer_to_ciphertext(1);
CT c17=encrypt_plaintext_integer_to_ciphertext(10); CT c18=encrypt_plaintext_integer_to_ciphertext(1);
CT c19=encrypt_plaintext_integer_to_ciphertext(10); CT c20=encrypt_plaintext_integer_to_ciphertext(1);
// High memory needed for below
// vecCT vv(1000000000);
// for(int i=0;i<1000000000;i++)
// {
// vv[i]=encrypt_plaintext_integer_to_ciphertext(i);
// vv[i]=cc->EvalAdd(vv[i],encrypt_plaintext_integer_to_ciphertext(1);
// }
return 0;
}