Problems with evaluating the square root

Hi together,

i have problems calculating the square root using EvalChebyshevFunction.
My code is as follows:

    uint32_t ringDim      = 131072;
    uint32_t batchSize    = 4;
    uint32_t multDepth    = 30;
    uint32_t scaleModSize = 50;
    uint32_t firstModSize = 60;

//Setting CKKS crypto context parameters
    SecurityLevel sl      = HEStd_128_classic;
    BINFHE_PARAMSET slBin = TOY;
    CCParams<CryptoContextCKKSRNS> parameters;
    parameters.SetMultiplicativeDepth(multDepth);
    parameters.SetSecurityLevel(sl);
    parameters.SetRingDim(ringDim);
    parameters.SetBatchSize(batchSize);
    parameters.SetScalingModSize(scaleModSize);
    parameters.SetFirstModSize(firstModSize);
    parameters.SetScalingTechnique(FLEXIBLEAUTO);
    CryptoContext<DCRTPoly> clientCC = GenCryptoContext(parameters);
    clientCC->EvalSumKeyGen(clientKP.secretKey, clientKP.publicKey);

    // Enabled features that we need
    clientCC->Enable(PKE);
    clientCC->Enable(KEYSWITCH);
    clientCC->Enable(LEVELEDSHE);
    clientCC->Enable(ADVANCEDSHE);
    clientCC->Enable(FHE);

    std::cout << "Cryptocontext generated" << std::endl;
    KeyPair<DCRTPoly> clientKP = clientCC->KeyGen();
    std::cout << "Keypair generated" << std::endl;

After that i made some computations on two encrypted input vectors:

// Computations on the ciphertext
    auto ctSubs = serverCC->EvalSub(encPoints[0], serverC);
    auto ctSquares = serverCC->EvalSquare(ctSubs);
    auto ctSum = serverCC->EvalSum(ctSquares, 2);

    double lowerBound = 0;
    double upperBound = 4;

    // We can input any lambda function, which inputs a double and returns a double.
    auto ctRoot = serverCC->EvalChebyshevFunction([](double x) -> double { return std::sqrt(x); }, 
    ctSum, lowerBound, upperBound, 50);

The plain results are:

Sub result: 0.0567057, 0.0601369, -1000
Square result: 0.00321554, 0.00361645, 1e+06
Sum result: 0.00683198, 1e+06, 1e+06
Root result: [ nan nan nan ]

Sub, Sum and Square results are correct. Can you tell me why there is “nan” after evaluating the square root of ctSum ?

Thank you!

Your inputs are out of the approximation range you specified. Ensure your data falls within the valid range of (\text{lowerBound}, \text{upperbound}).
There might be other issues in your program but you can start your troubleshooting by fixing the range problem.

Hi @Caesar,

Can you tell me more about these two values? I’m not sure how to set them properly. As you can see my results are very small. Do I have to set the upperBound and lowerBound according to the input values? So min and max or?

The sum result (input to the Chebyshev approximation) contains large values (1e+06) that are out of the approximation range (0,4). Your input values must be \gt \text{lowerBound} and \lt \text{upperBound}.

Note that if the range is large, function approximation may not be accurate and you may need to set the approximation degree quite large.

If you do not want to evaluate the function over those large input values, try multiplying them by 0 to get rid of them.

1 Like

Thanks man, that helped a lot! But i have another question: I don’t actually know the upperBound and lowerBound in plain text. I want to get the min and max from the encrypted vector before each approximation in order to set the upperBound and lowerBound dynamically. Do you know an approach for this?

I think the only way is to analyze the distribution of the inputs and check how they evolve in your application. Finding min and max is inefficient in CKKS, let alone you need them in plaintext to call EvalChebyshevFunction.

1 Like