Turn off RNS in CKKS

Hello!

For academic propose I’m interest to use CKKS without RNS. The security in this case is not important, so if the way is to have modulus less than 60 bits is not a problem.

I tried using low parameters like this, but always got a size 3 of RNS.

    CCParams<CryptoContextCKKSRNS> parameters;
    parameters.SetMultiplicativeDepth(1);
    parameters.SetScalingModSize(20);
    parameters.SetFirstModSize(20);
    parameters.SetBatchSize(1024);
    parameters.SetRingDim(2048);
    parameters.SetSecurityLevel(HEStd_NotSet);

There is a way?

Currently we only support RNS variants of CKKS (for efficiency). If you are trying to instantiate a cryptocontext with a single RNS modulus, you can set the first modulus to that size, e.g., 60, and set the multiplicative depth to 0. Note that this supports only additive homomorphic encryption (depth should be set to 1 to support one multiplication). Please also make sure the scaling technique is not set to FLEXIBLEAUTOEXT as this adds an an auxiliary RNS modulus; all other modes don’t.

Note that the number of RNS limbs depends not on security but functionality (multiplicative depth).

Perfect! That work perfect! I don’t know why I put the first modulus to a low value… has no sense je.

If I only change the multiplicative depth from 0 to 1. I leave the scaling technique to FIXEDMANUAL, the same first modulo size, same ring degree, etc.

The “only” change will be that in one I will have only one limb of RNS and in the other two limbs?
There is another change that I’m not seeing?

Correct, FLEXIBLEAUTOEXT adds an extra RNS limb to reduce the initial encryption noise to modulus switching noise, as described in Approximate Homomorphic Encryption with Reduced Approximation Error

Perfect!
I had an issue with this. I make as you said and work perfectly. I tested it by encrypting an input of 784 integer values in the range [0,255] and decrypting an seeing if in get the same.
In my machine at home it work perfect, but today when I try it in the computer of my work the output is all wrong. Many values has 3 or 4 orders of magnitude of difference, and other 17…

The computers are “similar”… One has a i5 12gen and the other i7 11gen. Or may be is the way the seed is generating in each machine?
The parameters that I’m using are this:

    parameters.SetMultiplicativeDepth(0);
    parameters.SetScalingModSize(50);
    parameters.SetFirstModSize(60);
    parameters.SetBatchSize(1024);
    parameters.SetRingDim(2048);
    parameters.SetScalingTechnique(FIXEDMANUAL);
    parameters.SetSecurityLevel(HEStd_NotSet);

If I put the multiplicative depth to one, it works.
If I put the scalingModSize to 55 or 60, it gets worst. The difference between input and output goes up to more than 19 orders of magnitude.
So, to understand a little bit more, it’s possible the scenario that I’m describing? What can it be?

Also if I make the ring dimension bigger, I still get the same wrong result.

Ideas?

Note that in CKKS we assume the values are close to unity, i.e., the scaling factor of 50 means all values get scaled up by 2^{50}. The first modulus determines how much room above unity we have, i.e., if we set it to 60, this means for the encoded complex numbers we reserve up to 10 bits (up to 1024). You are working with large values. So it is possible you are going over this bound. For instance, if you set the scaling factor to 40, it should work (as you will have up to 20 bits for the integral part). You can also add a limb (by increasing the multiplicative depth by 1) to support much larger messages. In your case, the messages could be up to 60-50+50 = 60 larger if you set the depth to 1.

That I get, I tried with scaling factor of 20,30 and 40 also. And all gets wrong.

For the test I’m doing, i need only one limb, so it is like I do not have RNS.

The strange thing is that with the same parameters in one machine works and in other no.

PD: If i only interested in the decimal part, I can put a scaling factor of 1? no? (I just try it and it doesn’t work)
PD2: Another detail, that I don’t know if can be a issue, my input of 784 int values has a lot of zeros. This can have some impact?
PD3: Total extra, in SEAL I did a similar experiment using a modulus = {60, 30}. You know if the way SEAL is implemented is like FLEXIBLEAUTOEXT? Because I read that the reserve one of the modulus for something… but didn’t find info about it. Only that the last one (30) is call special prime…