CKKS Bootstrappping
When a ciphertext is created, it has a fixed multiplication count called a level. When two cipehrtexts are multiplied, the resulting ciphertext will have the level reduced by one compared to the input ciphertexts. A ciphertext with level 0 can no longer be multiplied. It is possible to reset this level to a higher value by the bootstrapping operation.
Bootstrapping operation requires the bootstrap key. The bootstrap key incorporates every single fixed rotation key that is needed by the bootstrap operation. Because of this, the bootstrap key is quite large (about 12.3GB).
from desilofhe import Engine
engine = Engine(use_bootstrap=True)
secret_key = engine.create_secret_key()
public_key = engine.create_public_key(secret_key)
relinearization_key = engine.create_relinearization_key(secret_key)
conjugation_key = engine.create_conjugation_key(secret_key)
bootstrap_key = engine.create_bootstrap_key(secret_key, stage_count=3)
message = [-1, 0, 1]
ciphertext = engine.encrypt(message, public_key, level=0)
bootstrapped = engine.bootstrap(
ciphertext, relinearization_key, conjugation_key, bootstrap_key
)
Alternatively, the bootstrapping operation can be performed using the rotation key and the small bootstrap key instead of the bootstrapping key. This approach reduces memory usage to around 3.8GB but makes the operation slower.
from desilofhe import Engine
engine = Engine(use_bootstrap=True)
secret_key = engine.create_secret_key()
public_key = engine.create_public_key(secret_key)
relinearization_key = engine.create_relinearization_key(secret_key)
conjugation_key = engine.create_conjugation_key(secret_key)
rotation_key = engine.create_rotation_key(secret_key)
small_bootstrap_key = engine.create_small_bootstrap_key(secret_key)
message = [-1, 0, 1]
ciphertext = engine.encrypt(message, public_key, level=0)
bootstrapped = engine.bootstrap(
ciphertext,
relinearization_key,
conjugation_key,
rotation_key,
small_bootstrap_key,
)
bootstrapped_stage_count_5 = engine.bootstrap(
ciphertext,
relinearization_key,
conjugation_key,
rotation_key,
small_bootstrap_key,
stage_count=5,
)
Benchmark
Here are the benchmarks of the bootstrapping operation. The experiments were performed on an Intel(R) Core(TM) i7-10700K CPU @ 3.80GHz for the CPU measurements and an NVIDIA GeForce RTX 5090 for the GPU measurements. These values are the averages of 10 runs.
Key Size |
Stage Count |
Runtime (s) Single Thread |
4 Threads |
16 Threads |
GPU |
---|---|---|---|---|---|
Small | 3 | 106.522 | 43.652 | 31.606 | 5.491 |
Small | 4 | 69.354 | 28.463 | 20.566 | 3.386 |
Small | 5 | 66.456 | 26.981 | 19.198 | 2.924 |
Medium | 3 | 30.313 | 12.799 | 9.825 | 0.975 |
Medium | 4 | 24.776 | 10.228 | 7.848 | 0.813 |
Medium | 5 | 22.499 | 9.518 | 7.166 | 0.775 |
Large | 3 | 27.716 | 11.924 | 9.565 | 0.925 |
Large | 4 | 24.111 | 10.184 | 8.144 | 0.822 |
Large | 5 | 21.334 | 8.908 | 6.921 | 0.733 |