In CKKS, what happens to the imaginary component "under the hood"?

I know that we don’t typically use the imaginary component in CKKS, but there’s something I’m trying to explore that involves math on the imaginary component. The following uses the OpenFHE python library. The following is some simple sample code that was adapted from simple-real-numbers.py

import openfhe

if __name__ == '__main__':
    mult_depth = 1
    scale_mod_size = 50
    batch_size = 8

    parameters = openfhe.CCParamsCKKSRNS()
    parameters.SetMultiplicativeDepth(mult_depth)
    parameters.SetScalingModSize(scale_mod_size)
    parameters.SetBatchSize(batch_size)

    cc = openfhe.GenCryptoContext(parameters)
    cc.Enable(openfhe.PKESchemeFeature.PKE)
    cc.Enable(openfhe.PKESchemeFeature.KEYSWITCH)
    cc.Enable(openfhe.PKESchemeFeature.LEVELEDSHE)

    print("The CKKS scheme is using ring dimension: " + str(cc.GetRingDimension()))

    keys = cc.KeyGen()
    cc.EvalMultKeyGen(keys.secretKey)
    cc.EvalRotateKeyGen(keys.secretKey, [1, -2])

    x1 = [0.25, 0.5, 0.75, 1.0, 2.0, 3.0, 4.0, 5.0]
    for i, el in enumerate(x1):
        x1[i] = el + (2 * el * 1j)

    ptx1 = cc.MakeCKKSPackedPlaintext(x1)

    print("Input x1: " + str(ptx1))

    # Encrypt the encoded vectors
    c1 = cc.Encrypt(keys.publicKey, ptx1)

    c_add = cc.EvalAdd(c1, c1)
    c_mult = cc.EvalMult(c1, c1)

    precision = 8
    print("Results of homomorphic computations:")
    result = cc.Decrypt(c_add, keys.secretKey)
    result.SetLength(batch_size)
    print("x1 + x1 = " + str(result))
    print("Estimated precision in bits: " + str(result.GetLogPrecision()))

    # Decrypt the result of multiplication
    result = cc.Decrypt(c_mult,keys.secretKey)
    result.SetLength(batch_size)
    print("x1 * x1 = " + str(result))

I’m guessing that I can’t expect to get meaningful math operations out of the imaginary component?

Currently, the imaginary part of messages in CKKS is used to estimate the magnitude of the error to be used in the decryption noise flooding openfhe-development/src/pke/examples/CKKS_NOISE_FLOODING.md at main · openfheorg/openfhe-development · GitHub. Prior to this design choice (and maybe again in the future), CKKS was supporting computations on complex numbers, meaning that you should have seen correct results in the imaginary component as well.

Gotcha! Security concerns aside, do you know, off the top of your head, how far back I’d need to go to get the math on complex numbers to work out?

To PALISADE v1.10.5 [October 2, 2020] :slight_smile: You can access that release at v1.10.5 · PALISADE / PALISADE Release · GitLab