Random values after decryption of the same input

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!

Could you try the following configuration setting when instantiating the crypto context:

cryptoContext->SetMultiplicationTechnique(BEHZ);

There is a bug with deep computations for HPS* modes (Multiplicative depth limitation for HPS, HPSPOVERQ and HPSOVERQLEVELED modes of BFV · Issue #280 · openfheorg/openfhe-development · GitHub; the fix is about to be merged to the dev branch, but it will take a couple of weeks until we publish the new release with it).

If BEHZ works, then it is because of the bug that will soon be fixed. If not, let us continue debugging.

Bumping this. Is your issue resolved?