Thank you for helping on this. Here is the simple python script i used for it:
from openfhe import *
import random
ring_dim = 2**17
batch_size = ring_dim // 2
if get_native_int() == 128:
rescale_tech = ScalingTechnique.FIXEDAUTO
dcrt_bits = 78
first_mod = 89
else:
rescale_tech = ScalingTechnique.FLEXIBLEAUTO
dcrt_bits = 59
first_mod = 60
secret_key_dist = SecretKeyDist.UNIFORM_TERNARY
parameters = CCParamsCKKSRNS()
parameters.SetScalingModSize(dcrt_bits)
parameters.SetFirstModSize(first_mod)
parameters.SetScalingTechnique(rescale_tech)
parameters.SetNumLargeDigits(3)
parameters.SetSecretKeyDist(secret_key_dist)
parameters.SetSecurityLevel(SecurityLevel.HEStd_128_classic)
parameters.SetRingDim(ring_dim)
parameters.SetBatchSize(batch_size)
parameters.SetKeySwitchTechnique(HYBRID)
level_budget = [4, 4]
levels_available_after_bootstrap = 20
num_slots = batch_size
depth_bootstrap = FHECKKSRNS.GetBootstrapDepth(level_budget, secret_key_dist)
depth = levels_available_after_bootstrap + depth_bootstrap
parameters.SetMultiplicativeDepth(depth)
cryptocontext = GenCryptoContext(parameters)
cryptocontext.Enable(PKESchemeFeature.PKE)
cryptocontext.Enable(PKESchemeFeature.KEYSWITCH)
cryptocontext.Enable(PKESchemeFeature.LEVELEDSHE)
cryptocontext.Enable(PKESchemeFeature.ADVANCEDSHE)
cryptocontext.Enable(PKESchemeFeature.FHE)
key_pair = cryptocontext.KeyGen()
cryptocontext.EvalMultKeyGen(key_pair.secretKey)
cryptocontext.EvalBootstrapSetup(level_budget, slots=num_slots)
cryptocontext.EvalBootstrapKeyGen(key_pair.secretKey, num_slots)
x = [random.uniform(-1.0, 1.0) for _ in range(batch_size)]
print(f"`Input` Result:\n {x[:10]}")
print()
ptx = cryptocontext.MakeCKKSPackedPlaintext(x, level=depth - 1)
ctx = cryptocontext.Encrypt(key_pair.publicKey, ptx)
lvl = ctx.GetLevel()
print(f"Mul-Depth: {lvl}")
print(f"Initial number of levels remaining: {depth - lvl}")
print()
ctx_refreshed = cryptocontext.EvalBootstrap(ctx)
res_ptx = cryptocontext.Decrypt(key_pair.secretKey, ctx_refreshed)
res_ptx.SetLength(batch_size)
res_vec = res_ptx.GetRealPackedValue()
res_vec = [round(val, 2) for val in res_vec]
print(f"Decrypted `Bootstrapp` Result:\n {res_vec[:10]}")
The issue happens when running this on the latest version of openfhe-python v1.3.0.0.20.4
installed directly by pip3.8
and pip3.10
. It also produces consistently the same nan
result when built from source. And here is a sample of the output:
`Input` Result:
[0.17675434979084526, -0.37504098062076374, 0.4796583872715898, 0.937460265167543, -0.7410684847721298, 0.8124632153799727, 0.714340313325494, -0.013021436593108726, -0.25327522311343964, 0.6103009698880677]
Mul-Depth: 41
Initial number of levels remaining: 1
Decrypted `Bootstrapp` Result:
[nan, nan, nan, nan, nan, nan, nan, nan, nan, nan]
I so happened to have a docker version somewhere with an older build and here is the output of pip show openfhe
on the docker
Name: openfhe
Version: 0.8.4
Summary: Python wrapper for OpenFHE C++ library.
Home-page: https://github.com/openfheorg/openfhe-python
Author: OpenFHE Team
Author-email: contact@openfhe.org
License: BSD-2-Clause
Location: /openfhe-python
Editable project location: /openfhe-python
Requires: pybind11, pybind11-global, pybind11-stubgen
This version seems to work as expected and here is the output for the same script above:
`Input` Result:
[0.8923063639960698, -0.13170292096094283, 0.821223452909841, 0.15983270791434356, 0.14807709174686567, -0.6526677159492442, -0.5970628388908674, -0.1773637033776172, -0.0922501974693466, 0.9817870849703605]
Mul-Depth: 41
Initial number of levels remaining: 1
Decrypted `Bootstrapp` Result:
[0.89, -0.13, 0.82, 0.16, 0.15, -0.65, -0.6, -0.18, -0.09, 0.98]