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?