I hope someone can help me understand an error I get when using Palisades. I want to only use the first 329 slots of a BGV ciphertext, and zero out the rest (which at some point contains some 'rubbish' I don't want to re-enter the first 329 slots when doing rotations). So I have created a Plaintext called mask that I fill with 1's in the first 329 slots, which I multiply on a ciphertext to zero out everything outside these slots. The complete code generating the error is here:
#include <fstream>
#include <iostream>
#include <iterator>
#include <random>
#include "palisade.h"
using namespace std;
using namespace lbcrypto;
Plaintext mask;
CryptoContext<DCRTPoly> cryptoContext;
Ciphertext<DCRTPoly> RotateLeft(Ciphertext<DCRTPoly> ct, int r, int ll){
/* Rotates the ciphertext ct of length ll with r positions to the right. */
Ciphertext<DCRTPoly> res, shiftR, shiftL;
shiftL=cryptoContext->EvalAtIndex(ct, r);
shiftR=cryptoContext->EvalAtIndex(ct, r-ll);
res=cryptoContext->EvalAdd(shiftR, shiftL);
res=cryptoContext->EvalMult(res,mask);
return res;
}
int main(){
usint plaintextModulus = 65537;
float sigma = 3.2;
SecurityLevel securityLevel = HEStd_128_classic;
uint32_t depth = 6;
////////////////////////////////////////////////////////////
// Parameter generation
////////////////////////////////////////////////////////////
cryptoContext = CryptoContextFactory<DCRTPoly>::genCryptoContextBGVrns(
depth,
plaintextModulus,
securityLevel,
sigma,
2,
OPTIMIZED,
BV,
0,
0,
0,
0,
0,
0,
AUTO);
// enable features that you wish to use
cryptoContext->Enable(ENCRYPTION);
cryptoContext->Enable(SHE);
cryptoContext->Enable(LEVELEDSHE);
LPKeyPair<DCRTPoly> keyPair;
// Perform Key Generation Operation
keyPair = cryptoContext->KeyGen();
if (!keyPair.good()) {
std::cout << "Key generation failed!" << std::endl;
exit(1);
}
//Keys for multiplication
cryptoContext->EvalMultKeysGen(keyPair.secretKey);
//Keys for rotations
cryptoContext->EvalAtIndexKeyGen(keyPair.secretKey,{1,2,3,-326,-327,-328});
vector<int64_t> vecMask;
for(int i=0; i<329; ++i)
vecMask.push_back(1);
mask = cryptoContext->MakePackedPlaintext(vecMask);
std::vector<int64_t> vectorOfBits1;
for(int64_t i=0; i<329; ++i)
vectorOfBits1.push_back((i/2)%2);
Plaintext p1 = cryptoContext->MakePackedPlaintext(vectorOfBits1);
Ciphertext<DCRTPoly> c1=cryptoContext->Encrypt(keyPair.publicKey, p1);
Ciphertext<DCRTPoly> r1=RotateLeft(c1,1,329);
Ciphertext<DCRTPoly> r2=RotateLeft(c1,2,329);
Ciphertext<DCRTPoly> chi_res=cryptoContext->EvalMult(r1,r2);
chi_res=cryptoContext->EvalAdd(chi_res,c1);
}
This results in the error
tower size mismatch; cannot add
If the masking is commented out, everything works fine except c1 will contain the rubbish I want removed. How should I do the masking correctly?