CKKS 부트스트랩 (Bootstrapping)
암호문은 생성시 잔여 곱셈 횟수가 설정이 되어있고 이후 곱셈을 할 때마다 결과물의 잔여 곱셈 횟수(level)가 줄어드는 방식입니다. 잔여 곱셈 횟수가 0인 암호문은 더이상 곱셈을 할 수 없고 부트스트래핑 연산을 해야합니다.
일반 부트스트랩
부트스트랩 연산에는 부트스트랩 키가 필요합니다. 부트스트랩 연산에 필요한 모든 고정 회전 키로 이루어져 있어서 크기가 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
)
간이 부트스트랩 키
부트스트랩 키를 대신해 회전 키와 간이 부트스트랩 키를 사용해서도 부트스트랩을 수행할 수 있습니다. 회전 키를 사용하여 메모리 사용이 3.8GB 정도로 적지만 느립니다.
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,
)
벤치마크
다음은 부트스트랩의 성능 벤치마크입니다. 실험환경은 CPU의 경우 Intel(R) Core(TM) i7-10700K CPU @ 3.80GHz 을 사용하였고 GPU의 경우 NVIDIA GeForce RTX 5090를 사용하였습니다. 10번 측정한 값의 평균치입니다.
Key Size |
Stage Count |
Runtime (s) 1 Thread |
4 Threads |
16 Threads |
GPU |
---|---|---|---|---|---|
Small | 3 | 108.075 | 44.001 | 32.100 | 3.130 |
Small | 4 | 70.137 | 28.427 | 20.841 | 2.020 |
Small | 5 | 66.095 | 26.853 | 19.449 | 1.842 |
Medium | 3 | 30.512 | 12.734 | 9.924 | 0.823 |
Medium | 4 | 24.765 | 10.231 | 7.923 | 0.673 |
Medium | 5 | 23.176 | 9.517 | 7.202 | 0.627 |
Large | 3 | 28.122 | 11.860 | 9.626 | 0.793 |
Large | 4 | 23.889 | 10.150 | 8.202 | 0.695 |
Large | 5 | 20.840 | 8.815 | 6.943 | 0.600 |
희소 부트스트랩
희소 부트스트랩은 암호문의 슬롯 갯수를 줄여서 부트스트랩 속도를 빠르게 하는 기법입니다. 간이 부트스트랩 키를 사용하거나 부트스트랩 키를 생성해서 수행할 수 있습니다.
부트스트랩 키
from desilofhe import Engine
engine = Engine(slot_count=1024, 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, 0] * 256
ciphertext = engine.encrypt(message, public_key, level=0)
bootstrapped = engine.bootstrap(
ciphertext, relinearization_key, conjugation_key, bootstrap_key
)
간이 부트스트랩 키
from desilofhe import Engine
engine = Engine(slot_count=1024, 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, 0] * 256
ciphertext = engine.encrypt(message, public_key, level=0)
bootstrapped = engine.bootstrap(
ciphertext,
relinearization_key,
conjugation_key,
rotation_key,
small_bootstrap_key,
stage_count=1,
)
벤치마크
다음은 희소 부트스트랩의 성능 벤치마크입니다. 실험환경은 CPU의 경우 Intel(R) Core(TM) i7-10700K CPU @ 3.80GHz 을 사용하였고 GPU의 경우 NVIDIA GeForce RTX 5090를 사용하였습니다. 10번 측정한 값의 평균치입니다.
Slot Count |
Key Size |
Stage Count |
Runtime (s) 1 Thread |
4 Threads |
16 Threads |
GPU |
---|---|---|---|---|---|---|
32 | Small | 1 | 43.207 | 16.995 | 12.354 | 0.976 |
32 | Small | 2 | 32.293 | 12.706 | 9.275 | 0.729 |
32 | Medium | 1 | 26.593 | 10.781 | 8.058 | 0.625 |
32 | Medium | 2 | 25.485 | 10.108 | 7.387 | 0.582 |
32 | Large | 1 | 26.619 | 10.819 | 8.171 | 0.627 |
1024 | Small | 2 | 70.202 | 28.229 | 20.147 | 1.606 |
1024 | Small | 3 | 48.467 | 19.313 | 13.929 | 1.129 |
1024 | Small | 4 | 45.378 | 17.606 | 12.716 | 1.058 |
1024 | Medium | 2 | 29.102 | 11.945 | 9.077 | 0.721 |
1024 | Medium | 3 | 25.554 | 10.296 | 7.699 | 0.626 |
1024 | Medium | 4 | 23.830 | 9.540 | 7.168 | 0.603 |
1024 | Large | 2 | 27.669 | 11.450 | 9.020 | 0.716 |
1024 | Large | 3 | 24.548 | 10.021 | 7.713 | 0.626 |
손실 부트스트랩
손실 부트스트랩은 부트스트랩 내부 연산 순서를 변경하여서 노이즈가 증가하는 대신 빠른 속도를 얻는 기법입니다. 결과물의 소수점 유효자리가 대강 절반 정도 줄어듭니다. 일반적으로는 일반 부트스트랩의 사용이 권장됩니다만 필요한 정확도에 따라서 의미가 있을 수도 있습니다. 간이 부트스트랩 키를 사용하거나 손실 부트스트랩 키를 생성해서 수행할 수 있습니다.
손실 부트스트랩 키
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)
lossy_bootstrap_key = engine.create_lossy_bootstrap_key(
secret_key, stage_count=3
)
message = [-1, 0, 1]
ciphertext = engine.encrypt(message, public_key, level=0)
bootstrapped = engine.lossy_bootstrap(
ciphertext, relinearization_key, conjugation_key, lossy_bootstrap_key
)
간이 부트스트랩 키
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.lossy_bootstrap(
ciphertext,
relinearization_key,
conjugation_key,
rotation_key,
small_bootstrap_key,
)
bootstrapped_stage_count_5 = engine.lossy_bootstrap(
ciphertext,
relinearization_key,
conjugation_key,
rotation_key,
small_bootstrap_key,
stage_count=5,
)
벤치마크
다음은 손실 부트스트랩의 성능 벤치마크입니다. 실험환경은 CPU의 경우 Intel(R) Core(TM) i7-10700K CPU @ 3.80GHz 을 사용하였고 GPU의 경우 NVIDIA GeForce RTX 5090를 사용하였습니다. 10번 측정한 값의 평균치입니다.
Key Size |
Stage Count |
Runtime (s) 1 Thread |
4 Threads |
16 Threads |
GPU |
---|---|---|---|---|---|
Small | 3 | 84.058 | 34.761 | 26.129 | 3.017 |
Small | 4 | 59.371 | 24.093 | 17.840 | 1.955 |
Small | 5 | 59.641 | 23.720 | 17.447 | 1.779 |
Medium | 3 | 27.120 | 11.205 | 8.637 | 0.761 |
Medium | 4 | 23.035 | 9.387 | 7.270 | 0.643 |
Medium | 5 | 21.642 | 8.918 | 6.769 | 0.604 |
Large | 3 | 25.321 | 10.529 | 8.464 | 0.745 |
Large | 4 | 22.407 | 9.362 | 7.495 | 0.658 |
Large | 5 | 19.441 | 8.513 | 6.613 | 0.596 |