Modulus missmatch after EvalCompareSchemeSwitch()

Hi guys,

i tried to compare two CKKS ciphertexts with EvalCompareSchemeSwitch() and it throws a Modulus missmatch error. Can you tell me why this is thrown and how to avoid it?

SchSwchParams params;
    params.SetSecurityLevelCKKS(sl);
    params.SetSecurityLevelFHEW(slBin);
    params.SetCtxtModSizeFHEWLargePrec(logQ_LWE);
    params.SetNumSlotsCKKS(4096);
    params.SetNumValues(4096);
    params.SetComputeArgmin(true);
    params.SetOneHotEncoding(oneHot);

auto ctCompareDistances = serverCC->EvalCompareSchemeSwitching(ct_1, ct_2);

Please provide a minimum working example that can be compiled. Have you followed the example from openfhe-development/src/pke/examples/scheme-switching.cpp at main · openfheorg/openfhe-development · GitHub?

I cannot provide you a working example, because one of the ciphertext vectors i want to compare is the result of some computations for euclidian distance. The other vector is created with the value i want to compare. Heres some pseudo code:

    vector radius(zeros.size(), 0.5);
    auto ct_radius = serverCC->Encrypt(serverPublicKey, serverCC->MakeCKKSPackedPlaintext(radius, 1, 0, nullptr, slots));
    auto ct_result = // result of euclidian distance calculations

    auto ctCompareDistances = serverCC->EvalCompareSchemeSwitching(ct_radius, ct_result, slots, slots);

// This runs into a modulus missmatch error


// If I replace ct_result with for example
    vector some_other_vector(zeros.size(), 1.568);
    auto ct_some_other_vector = serverCC->Encrypt(serverPublicKey, serverCC->MakeCKKSPackedPlaintext(some_other_vector, 1, 0, nullptr, slots));

    auto ctCompareDistances = serverCC->EvalCompareSchemeSwitching(ct_radius, ct_some_other_vector, slots, slots);

// This somehow works

What is the condition for throwing a modulus missmatch?

The condition for throwing a modulus missmatch error is a modulus missmatch – without a compilable code, I can’t say where it happens, although I suspect that since ct_result is a result of leveled computations, the issue lies there.

  • Can you subtract ct_radius and ct_result and decrypt without errors?
  • What scaling technique are you using? You might need to manually align the scaling factors (it is a good practice to check ct_result->GetLevel() and ct_result->GetNoiseScaleDeg()).
  • Go to ckksrns-schemeswitching.cpp in SWITCHCKKSRNS::EvalCompareSchemeSwitching and check at which point the error occurs.

Hi @andreea.alexandru,

what do you mean with manually aligning the scaling factors? I checked ct_result->GetLevel() and ct_result->GetNoiseScaleDeg() and it gave me 3 and 2. What do i have to do with this information? =) I tried so much but i can’t bring this to run …

You only gave one piece of response to the above questions, which is not sufficient to identify the problem. Are you able to subtract ct_radius and ct_result and decrypt without errors? What scaling technique are you using? If you are using FIXEDMANUAL, you need to manually align the scaling factors of ct_result and ct_radius, by running ModReduceInPlace on ct_result. At which point in EvalCompareSchemeSwitching is the error thrown? Again, without a minimum working example, it is difficult to guess the problem in vacuum.

Yes, that works fine.

I’m using FLEXIBLEAUTO.

I tried to debug and dive into it and it is thrown in

 return GetScheme()->EvalCompareSchemeSwitching(ciphertext1, ciphertext2, numCtxts, numSlots, pLWE, scaleSign,
                                                       unit);

in the cryptocontext.h file

Please try to come up with a small minimum working example that can be run and recreates the issue. I could not recreate the issue on my end even when one of the ciphertexts to be compared is obtained as a result of encrypted computations involving multiplications and rotations.