Please share your code in a minimal reproducible example
Rotation
So I have a plaintext with the following elements (6 14 24 36 ...)
. If I encrypt, rotate by two, and then decrypt, I get the following plaintext (24 36 ...)
but I need to have (24 36 6 14...)
.
This is expected behavior (not sure if that’s what you’re asking). Here’s how I’d accomplish what you’re asking:
initial_values = [6, 14, 24, 36, ...]
mask = [1, 1, 0, 0]
masked_values = mask * initial_values # [6, 14, 0, 0, ....]
rotated_initials = [24, 36, ....]
rotated_masked = [0, 0, 6, 14, ...]
finally_rotated = rotated_initials + rotated_masked
There might be a better way to do this, but I’m not sure.
std::out_of_range
Also, if I have a ciphertext where the plaintext is (80 124 110 86 50 ... ) with size 8 and values [ 80 124 110 86 50 0 0 0 ]
(this is the output of one of my prints) and I try to rotate by 4 (i = 2), I get the following error:
I can’t say for sure without seeing your code, but see the following code where we try to cc->EvalRotate
by an index that we did not generate a rotation key for (cc->EvalRotateKeyGen
).
See the below:
#include <fstream>
#include <iostream>
#include <iterator>
#include <random>
#include "openfhe.h"
#include "math/hal.h"
using namespace lbcrypto;
bool shouldTrack;
int main() {
CCParams<CryptoContextBFVRNS> parameters;
parameters.SetPlaintextModulus(65537);
parameters.SetMaxRelinSkDeg(3);
CryptoContext<DCRTPoly> cc = GenCryptoContext(parameters);
// enable features that you wish to use
cc->Enable(PKE);
cc->Enable(KEYSWITCH);
cc->Enable(LEVELEDSHE);
int32_t n = cc->GetCryptoParameters()->GetElementParams()->GetCyclotomicOrder() / 2;
// Initialize the public key containers.
KeyPair<DCRTPoly> kp = cc->KeyGen();
std::vector<int32_t> indexList = {1, 1000};
cc->EvalRotateKeyGen(kp.secretKey, indexList);
std::vector<int64_t> vectorOfInts = {80, 124, 110, 86, 50};
Plaintext intArray = cc->MakePackedPlaintext(vectorOfInts);
auto ciphertext = cc->Encrypt(kp.publicKey, intArray);
// Adding an index that we did not generate keys for
indexList.emplace_back(-1);
// Lets see what happens now
for (auto &rotIdx: indexList){
std::cout << "Starting rotation by:" << rotIdx<< std::endl;
auto permutedCiphertext = cc->EvalRotate(ciphertext, rotIdx);
std::cout << "Successfully rotated by:" << rotIdx<< std::endl;
}
}
I’ll have to look for the source code, but hopefully there’s a way to generate more informative error messages