Hi all!
I want to implement encrypted equality testing using BFV. I follow the simple approach described here. I set the plaintext modulus to 65537 and the multiplicative depth to 20. Here is the function for equality testing:
Ciphertext<DCRTPoly> homomorphicEqualityTesting(Ciphertext<DCRTPoly> encA, Ciphertext<DCRTPoly> encB, Ciphertext<DCRTPoly> encOne, CryptoContext<DCRTPoly> cryptoContext) {
auto encDiff = cryptoContext->EvalSub(encA, encB);
encDiff = homomorphicModularExponentiation(encDiff, cryptoContext);
encDiff = cryptoContext->EvalSub(encOne, encDiff);
return encDiff;
}
And here is the function of modular exponentiation:
Ciphertext<DCRTPoly> homomorphicModularExponentiation(Ciphertext<DCRTPoly> encX, CryptoContext<DCRTPoly> cryptoContext) {
auto encTmp = cryptoContext->EvalMult(encX, encX);
for(int i = 0; i < 15; i++) {
encTmp = cryptoContext->EvalMult(encTmp, encTmp);
}
return encTmp;
}
Here is the test function:
void testOfTest(int numOfBatches, int batchSize, int elemToSerachFor, int minValue, int maxValue) {
CryptoContext<DCRTPoly> cryptoContext = initializeCryptoContext(batchSize);
KeyPair<DCRTPoly> keyPair = generateKeyPair(cryptoContext);
std::vector<std::vector<int64_t>> database;
for(int i = 0; i < numOfBatches; i++) {
std::vector<int64_t> databaseSlice = generateRandomVector(batchSize, minValue, maxValue);
database.push_back(databaseSlice);
}
std::vector<Ciphertext<DCRTPoly>> encDatabase;
for(int i = 0; i < numOfBatches; i++) {
Plaintext ptxtDatabaseSlice = cryptoContext->MakePackedPlaintext(database[i]);
Ciphertext<DCRTPoly> encDatabaseSlice = cryptoContext->Encrypt(keyPair.publicKey, ptxtDatabaseSlice);
encDatabase.push_back(encDatabaseSlice);
}
Ciphertext<DCRTPoly> encOne = encryptSingleElem(batchSize, 1, cryptoContext, keyPair.publicKey);
Ciphertext<DCRTPoly> encElemToSearchFor = encryptSingleElem(batchSize, elemToSerachFor, cryptoContext, keyPair.publicKey);
std::vector<Ciphertext<DCRTPoly>> encResults;
for(int i = 0; i < numOfBatches; i++) {
Ciphertext<DCRTPoly> encResult = homomorphicEqualityTesting(encDatabase[i], encElemToSearchFor, encOne, cryptoContext);
encResults.push_back(encResult);
}
for(int i = 0; i < numOfBatches; i++) {
Plaintext ptxtResult;
cryptoContext->Decrypt(keyPair.secretKey, encResults[i], &ptxtResult);
ptxtResult->SetLength(batchSize);
std::vector<int64_t> result = ptxtResult->GetPackedValue();
for(int j = 0; j < batchSize; j++) {
std::cout << result[j] << " ";
}
std::cout << std::endl;
}
}
When I call the test function with numOfBatches=1
and the batchSize=256
everything works fine (I get only 1 and 0 after decryption) but when I call the test function with numOfBatches=32
and the batchSize=8
for some batches the decryption works (I get 1 and 0) but for some batches I get very strange values like (-5509 19460 -25039 -24726 19495 12063 24810 -9765). Moreover, these random values keep changing even if the input is the same (all batches are equal to the same element).
Here is an output:
0 0 0 1 0 1 0 0
1 0 1 0 0 0 0 0
0 0 1 0 1 0 0 0
0 1 0 0 0 0 0 0
0 0 0 0 0 0 1 1
-1074 -27247 24542 -15958 10608 16018 -7609 -10575
0 0 0 0 0 1 0 1
0 0 1 0 1 0 0 0
1 0 0 0 0 1 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 1
0 1 0 0 1 0 1 0
0 1 1 0 0 0 0 0
-31041 -32112 17006 -3799 7846 3162 8590 -15833
13335 28060 2432 7404 -20624 -8614 26625 -2894
0 0 0 0 0 0 1 0
0 1 0 0 0 1 1 0
0 0 0 0 0 1 0 1
-20950 1617 9498 12941 20948 2068 74 4989
1 0 0 0 0 0 0 0
0 0 0 0 0 0 0 1
13412 25042 4172 7590 7307 -5292 18913 8290
0 0 1 0 0 0 0 0
0 0 0 0 0 1 0 1
1 0 0 1 1 0 0 0
0 0 0 0 1 0 1 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
-16108 -30268 -25958 32224 17820 23270 31443 -2917
0 0 0 1 0 1 1 0
0 0 0 0 0 0 0 0
1 0 0 1 0 0 0 1
Do you have any ideas about what I’m doing wrong?
Thank you very much!