Comparing two encrypted vectors of the same size with scheme switching gives wrong output

Hi together,

my application is doing a EvalCompareSchemeSwitching operation on two encrypted vectors of the same size (they are results from previous fhe operations). The initial batch size is 8 but it will be manually changed while i do computations because i get dynamic lengths of vectors as input for every new run. I dont want to set it too high from the beginning.

The two vectors in plain maybe are looking like this with size 16:

v1 = {0.074717, 0.0755024, 0.0758047, 0.0753391, 0.0830566, 0.0765554, 0.0884495, 0.0871232, 0.0853462, 0.0844123, 0.0766145, 0.0805673, 0.0702482, 0.0724547, 0.072666, 0.081887}

v2 = {0.05, 0.05, 0.05, 0.05, 0.05, 0.05, 0.05, 0.05, 0.05, 0.05, 0.05, 0.05, 0.05, 0.05, 0.05, 0.05}

I want to compare the two vectors with the following operation:

auto ctCompare = serverCC->EvalCompareSchemeSwitching(ct_v1, ct_v2);

The result of this operation looks like this:

(1, 1, 0.999998, 0.999999, 0.999999, 0.999999, 0.999999, 1, ... )

Since the initial batch size is 8, I only get 8 values when decrypting the results, right?

I have already tried to enter further parameters in EvalCompareSchemeSwitching().

Unfortunately, I got wrong results (only the first 8 are correct) when entering parameters. Slots here is different from the initial batchsize:

auto ctCompareDistances = serverCC->EvalCompareSchemeSwitching(ct_v1, ct_v2, slots, slots, 0, 1, false);

I want to have a result vector of the same size as v1 or v2 with correct values.
Can you help me there?

What are you dynamically changing, the batch size? You can specify the number of values to convert, but the number of slots you set in your cryptocontext needs to be the largest you are using throughout the computation. Internally, EvalCompareSwitchPrecompute prepares quantities that depend on the number of slots of the cryptocontext from GetNumSlotsCKKS(). Then, you can specify a different number of ciphertexts to convert. You can also specify the number of slots for the output encoding of the result of the compare, but you should be careful where you feed the results.

To check how to deal with decreasing vector size when doing subsequent comparisons, check how EvalMinSchemeSwitching() is implemented.

@andreea.alexandru Thanks for your response! I just set the scheme switching params as follows and it worked. I just set the slot size to 1024 because i dont expect more than 1000 values in the input vectors. Is that the right approach?:

SchSwchParams params;
    params.SetSecurityLevelCKKS(sl);
    params.SetSecurityLevelFHEW(slBin);
    params.SetCtxtModSizeFHEWLargePrec(logQ_LWE);
    params.SetNumSlotsCKKS(1024);
    params.SetNumValues(1024);
    params.SetComputeArgmin(true);
    params.SetOneHotEncoding(oneHot);
    auto privateKeyFHEW = clientCC->EvalSchemeSwitchingSetup(params);
    clientCC->EvalSchemeSwitchingKeyGen(clientKP, privateKeyFHEW);

Yes. In general you should pick the minimum value that covers all the cases in your application as slots and the number of values to switch. In some extreme cases, e.g., when you need a single run with a very large number of values and many runs with very small number of values, you can always run the precomputation for the smaller number of values after the initial run.