콘텐츠로 이동

마이그레이션 가이드: DESILO FHE 1.x에서 2.0으로

DESILO FHE 2.0에는 API, 지원되는 설정 및 직렬화 형식에서 호환성을 깨는 여러 변경 사항이 포함되어 있습니다.

이 가이드는 기존 프로그램을 DESILO FHE 1.x에서 2.0으로 이전하는 데 필요한 변경 사항을 설명합니다. 신규 기능과 성능 개선 사항에 대한 전체 내용은 릴리스 노트를 참고하시기 바랍니다.

1. 엔진 생성 방식 변경

Engine 생성자의 모든 인자는 이제 키워드 인자로만 전달할 수 있습니다. 또한 두 인자의 이름이 변경되었습니다.

1.x 2.0
use_bootstrap bootstrap
use_multiparty multiparty

변경 전:

from desilofhe import Engine

engine = Engine("gpu", use_bootstrap=True)

변경 후:

from desilofhe import Engine

engine = Engine(mode="gpu", bootstrap=True)

다자간 연산 설정에도 동일한 변경 사항이 적용됩니다.

engine = Engine(mode="gpu", multiparty=True)

인자 없이 엔진을 생성하는 것은 여전히 가능합니다.

engine = Engine()

기본 설정은 최대 곱셈 레벨이 7인 CKKS 엔진입니다.

1.x의 use_bootstrap=True는 10레벨 부트스트랩 엔진을 생성했지만, 2.0의 bootstrap=True는 17레벨 부트스트랩 엔진을 생성합니다. 따라서 엔진 파라미터, 키 크기, 부트스트랩 후의 레벨이 함께 달라집니다.

다음 생성자 인자와 옵션도 제거되거나 변경되었습니다.

1.x 2.0
use_bootstrap_to_14_levels=True bootstrap=True (17레벨 부트스트랩)
use_bootstrap_to_17_levels=True bootstrap=True
compact=True 제거되었습니다. CKKS는 항상 고밀도(compact) 표현을 사용합니다.
slot_count 제거되었습니다. 행렬 곱셈 및 희소 인코딩 이전을 참고하세요.
log_coeff_count, special_prime_count, log_slot_count 제거되었습니다. CKKS 파라미터 변경을 참고하세요.
mode="async gpu" mode="gpu". 이제 gpu 모드가 비동기로 동작하며, "async gpu"를 사용하면 오류가 발생합니다.

기본 설정의 다자간 연산 엔진은 최대 곱셈 레벨이 4에서 10으로 늘었고, 최대 레벨은 29에서 23으로 줄었습니다. 레벨별 슬롯 수도 바뀌었으니 다자간 연산을 참고하세요.

GL 엔진

GLEngine이 제거되었습니다. 이제 GL 엔진은 Engine에 form 또는 shape 인자를 전달하여 생성합니다. GLCiphertext, GLPlaintext, GLSecretKey 같은 GL 전용 자료형은 Ciphertext, Plaintext, SecretKey 등 CKKS와 공통인 자료형으로 대체되었습니다.

변경 전:

from desilofhe import GLEngine

engine = GLEngine()
engine = GLEngine((256, 32, 32), "gpu")

변경 후:

from desilofhe import Engine

engine = Engine(form="matrix")
engine = Engine(shape=(256, 32, 32), mode="gpu")

2. 회전 및 순환 연산 변경

DESILO FHE 2.0에서는 roll과 rotate의 이동 방향을 구분합니다.

  • roll은 각 요소를 오른쪽으로 이동시킵니다.
  • rotate는 각 요소를 왼쪽으로 이동시킵니다.

이전 버전의 rotate는 현재 roll에 해당하는 방향으로 이동시켰습니다. 기존 코드의 동작을 유지하려면 rotate를 roll로, 회전 키를 순환 키로 변경해야 합니다. 순환 함수로 바꿀 때 이동량을 나타내는 인자 이름은 delta에서 shift로 바뀝니다.

Warning

기존 rotate 호출은 2.0에서도 오류 없이 실행되지만, 반대 방향으로 이동합니다. 결과가 오류 없이 달라지므로 모든 rotate 호출을 검토해야 합니다.

변경 전:

rotated = engine.rotate(ciphertext, rotation_key, delta=1)

변경 후:

rolled = engine.roll(ciphertext, roll_key, shift=1)

1.x의 이동 방향을 유지하려면 관련 함수, 키 및 인자를 다음과 같이 변경합니다.

1.x 2.0
rotate(ciphertext, rotation_key, delta) roll(ciphertext, roll_key, shift)
rotate(ciphertext, fixed_rotation_key) roll(ciphertext, fixed_roll_key)
rotate_batch(ciphertext, rotation_key, deltas) roll_many(ciphertext, roll_key, shifts)
rotate_batch(ciphertext, fixed_rotation_keys) roll_many(ciphertext, fixed_roll_keys)
create_rotation_key(secret_key) create_roll_key(secret_key)
create_fixed_rotation_key(secret_key, delta) create_fixed_roll_key(secret_key, shift)
회전 키 순환 키
고정 회전 키 고정 순환 키

1.15 버전에서 도입된 roll과 roll_many를 이미 사용하고 있다면 이동 방향은 그대로입니다. 다만 이 함수들은 이제 회전 키 대신 순환 키를 받으므로 키를 바꿔야 합니다.

1.x 2.0
roll(ciphertext, rotation_key, shift) roll(ciphertext, roll_key, shift)
roll_many(ciphertext, rotation_key, shifts) roll_many(ciphertext, roll_key, shifts)
sum(ciphertext, rotation_key, axis) sum(ciphertext, roll_key, axis)
bootstrap(ciphertext, relinearization_key, conjugation_key, rotation_key, small_bootstrap_key) bootstrap(ciphertext, relinearization_key, conjugation_key, roll_key, small_bootstrap_key)

CKKS에서는 2.0에서도 rotate, rotate_many, 회전 키, 고정 회전 키를 사용할 수 있으며, delta와 deltas 인자로 왼쪽으로 이동시킵니다. rotate_many는 rotate_batch의 2.0 이름입니다. 1.x와 마찬가지로 GL은 rotate를 지원하지 않으므로, 회전 키 대신 순환 키로 roll을 사용해야 합니다.

순환 키 생성

새로운 순환 키 생성 함수를 사용합니다.

secret_key = engine.create_secret_key()

roll_key = engine.create_roll_key(secret_key)
fixed_roll_key = engine.create_fixed_roll_key(secret_key, shift=1)

고정 순환 키는 CKKS와 GL 모두에서 사용할 수 있습니다.

행렬 (GL) 엔진에서는 고정 순환 키를 생성할 때 축을 지정해야 합니다.

fixed_roll_key = engine.create_fixed_roll_key(secret_key, shift=1, axis=0)

CKKS에서는 axis 속성의 값이 None입니다.

level 인자는 이제 반드시 키워드 인자로 전달해야 합니다.

fixed_roll_key = engine.create_fixed_roll_key(secret_key, shift=1, level=2)

이는 shift, axis, level이라는 세 정수 인자 사이의 혼동을 방지하기 위한 변경입니다.

부트스트랩 키 재사용

부트스트랩 키를 roll, roll_many, rotate, rotate_many, sum 연산에 직접 사용할 수 있습니다. 이미 부트스트랩을 사용하는 프로그램이라면 별도의 순환 키를 생략하여 메모리 사용량을 줄일 수 있습니다. roll을 참고하세요.

3. 연산 키 변경

DESILO FHE 2.0에는 키가 필요한 대부분의 연산에 사용할 수 있는 연산 키(Evaluation Key)가 도입되었습니다. 이전 버전에서는 일부 연산, 특히 부트스트랩을 수행할 때 여러 개의 키를 별도로 전달해야 했습니다.

연산 키는 연산에 필요한 키들을 하나로 통합하여 키 관리를 간소화합니다. 암호화와 복호화에는 여전히 각각의 키가 사용됩니다. 기존 코드를 이전할 때 여러 키를 개별적으로 전달하는 대신 통합 연산 키를 사용하는 것을 고려해보실 수 있습니다.

변경 전:

bootstrapped = engine.bootstrap(
    ciphertext, relinearization_key, conjugation_key, bootstrap_key
)

변경 후:

evaluation_key = engine.create_evaluation_key(secret_key)
bootstrapped = engine.bootstrap(ciphertext, evaluation_key)

연산 키는 multiply, square, relinearize, conjugate, roll, roll_many, rotate, rotate_many, sum, bootstrap, merge_bootstrap과 다항식 평가 함수들에 사용할 수 있습니다. CKKS에서만 사용할 수 있으며, 고정 순환 키나 고정 회전 키 대신에는 사용할 수 없습니다. 연산 키에 포함되는 키는 create_evaluation_key를 참고하세요.

4. GL 곱셈 변경

GL의 아다마르 곱셈 API가 CKKS와 일관성을 갖도록 변경되었습니다.

1.x 2.0
hadamard_multiply multiply
create_hadamard_multiplication_key create_relinearization_key
아다마르 곱셈 키 재선형화 키

변경 전:

result = engine.hadamard_multiply(
    ciphertext1, ciphertext2, hadamard_multiplication_key
)

변경 후:

result = engine.multiply(ciphertext1, ciphertext2, relinearization_key)

이제 GL에서는 재선형화 없이도 곱셈을 수행할 수 있습니다. 이 경우 결과 암호문은 일반적인 2개 대신 3개의 다항식을 포함하며, 재선형화하지 않고 직접 복호화할 수 있습니다.

이를 통해 재선형화된 암호문이 필요하지 않은 경우 불필요한 연산 비용을 절약할 수 있습니다. 현재 2.0.0에서 3개의 다항식을 가진 암호문에 지원되는 연산은 복호화뿐이지만 점차 추가될 예정입니다.

5. 부트스트랩 설정 변경

DESILO FHE 2.0에서는 17레벨 부트스트랩만 지원합니다.

다음 설정과 기능들은 더 이상 지원되지 않습니다.

1.x 2.0
다른 일반 부트스트랩 방식 (use_bootstrap, use_bootstrap_to_14_levels) 17레벨 부트스트랩 사용 (bootstrap=True)
손실 부트스트랩 (lossy_bootstrap, lossy_merge_bootstrap, create_lossy_bootstrap_key) 일반 부트스트랩 사용
부호 부트스트랩 (sign_bootstrap, sign_merge_bootstrap) 직접적인 대체 기능 없음
병합 부트스트랩 키 (create_merge_bootstrap_key) 부트스트랩 키 또는 연산 키로 merge_bootstrap 사용
대형 부트스트랩 키 (create_bootstrap_key(..., size="large")) 지원되는 부트스트랩 키 사용
사용자 지정 부트스트랩 스테이지 수 (stage_count) 기본 설정 사용

create_bootstrap_key의 두 번째 인자는 stage_count가 아니라 size입니다.

mod_raise 함수와 사용자 지정 비밀값을 사용하는 비밀 키(create_secret_key(secret))는 제거되었습니다. 이 기능들은 사용자 지정 부트스트랩을 위해 도입되었지만, 17레벨 부트스트랩의 모듈러스 구성에서는 더 이상 사용자 지정 부트스트랩을 지원할 수 없습니다.

사용자 지정 부트스트랩을 사용하는 프로그램은 지원되는 부트스트랩 설정을 사용하도록 연산 과정을 재설계해야 합니다.

6. CKKS 파라미터 변경

CKKS에서 슬롯 수 65536(max_level 37~77)은 더 이상 지원되지 않습니다. 이 설정은 키의 크기가 과도하게 크고 저레벨에서 인코딩 및 디코딩 오차가 컸습니다.

65536 슬롯을 사용하는 프로그램은 다른 CKKS 설정으로 변경해야 합니다. 가장 큰 CKKS 엔진이 제공하는 36개의 곱셈 레벨보다 많은 레벨이 필요한 경우에는 부트스트랩 엔진을 사용하시기 바랍니다.

다항식 계수 개수의 로그값을 직접 지정하는 기능도 더 이상 지원되지 않습니다. Engine(log_coeff_count, special_prime_count, ...) 생성자와 log_slot_count 인자가 제거되었습니다. 대신 Engine(max_level=...) 같은 미리 정의된 엔진 설정을 사용해야 합니다.

7. GL 형상 변경

(16, 256, 256)이나 (4, 1024, 1024)처럼 가장 안쪽 차원의 크기가 256 이상인 GL 형상은 더 이상 지원되지 않습니다. 이러한 형상을 사용하는 프로그램은 다른 지원되는 형상으로 변경해야 합니다.

DESILO FHE 2.0에는 새로운 배치 크기 162와 486도 추가되어 GL 형상을 선택할 때 더 다양한 구성을 사용할 수 있습니다. 지원되는 GL 형상과 최대 레벨의 전체 목록은 지원되는 형상을 참고하시기 바랍니다.

8. 행렬 곱셈 및 희소 (Sparse) 인코딩 이전

CKKS 행렬 곱셈과 희소 인코딩은 더 이상 지원되지 않습니다. multiply_matrix, encode_to_plain_matrix, encode_to_light_plain_matrix, PlainMatrix, LightPlainMatrix, CKKS 행렬 곱셈 키, Engine의 slot_count 인자가 이에 해당합니다. 이러한 기능을 사용하는 프로그램은 연산 과정을 변경해야 합니다.

연산의 특성에 따라 다음과 같은 대안을 고려할 수 있습니다.

  • 효율적인 패킹 기법과 암호문 순환 및 곱셈을 사용하여 CKKS 행렬 곱셈을 직접 구현합니다.
  • 행렬 중심의 적합한 연산을 GL로 이전합니다.

다만 소규모 프로그램에서는 GL에 필요한 형상이 지나치게 클 수 있습니다. 향후 CKKS 행렬 곱셈을 위한 추가 예제나 라이브러리 기능을 제공할 예정입니다. 제거된 CKKS 행렬 곱셈 및 희소 인코딩 기능을 직접 대체하는 API는 없습니다.

9. CUDA 환경 변경

DESILO FHE 2.0에서는 CUDA 13.2와 CUDA 13.4만 지원합니다. 이전 CUDA 툴체인을 사용하는 프로그램은 빌드 및 실행 환경을 업데이트해야 합니다.

특히 CUDA 13.0은 중첩된 스레드 분기(thread divergence)가 있는 커널에서 잘못된 결과를 오류 없이 생성할 수 있는 컴파일러 버그로 인해 더 이상 지원되지 않습니다. 이 문제는 CUDA 12.8에서 처음 발생하였으며 CUDA 13.2.2에서 수정되었습니다. DESILO FHE에서 해당 문제가 발현된 적은 없지만, 예방적 조치로 영향을 받는 CUDA 버전의 지원을 중단하였습니다.

업그레이드할 때는 설치된 NVIDIA 드라이버가 선택한 CUDA 버전과 호환되는지 확인하시기 바랍니다.

10. 직렬화된 데이터 및 키 이전

DESILO FHE 2.0에서는 직렬화 형식이 전면 개편되었습니다. 이전 버전에서 직렬화한 데이터와 키는 2.0과 호환되지 않습니다.

프로그램에 필요한 데이터와 키를 새로 생성해야 합니다.

권장하는 이전 절차는 다음과 같습니다.

  1. 이전 버전의 라이브러리를 사용하여 기존 데이터를 읽어들입니다.
  2. 가능한 경우 원본 평문 데이터를 복원합니다.
  3. DESILO FHE 2.0으로 업그레이드합니다.
  4. 변경된 엔진 설정을 사용하여 새로운 키를 생성합니다.
  5. 원본 데이터를 다시 인코딩하고 암호화합니다.
  6. DESILO FHE 2.0을 사용하여 새로운 데이터와 키를 직렬화합니다.

원본 평문이 없는 경우 비밀 키와 이전 버전의 라이브러리가 필요할 수 있습니다. 이전 직렬화 형식을 새로운 형식으로 직접 변환하는 기능은 지원되지 않습니다.

마이그레이션 체크리스트

DESILO FHE 2.0을 사용하는 프로그램을 배포하기 전에 다음 항목을 확인하시기 바랍니다.

  • [ ] Engine 생성자의 모든 인자를 키워드 인자로 전달하도록 변경합니다.
  • [ ] use_bootstrap과 use_multiparty를 새로운 이름으로 변경합니다.
  • [ ] 제거된 생성자 인자(compact, slot_count, use_bootstrap_to_14_levels, use_bootstrap_to_17_levels, log_coeff_count, special_prime_count, log_slot_count)와 mode="async gpu"를 더 이상 사용하지 않습니다.
  • [ ] GLEngine을 Engine(form="matrix") 또는 Engine(shape=...)로 변경합니다.
  • [ ] 기존 rotate 호출을 검토하고 필요한 경우 roll로 변경합니다.
  • [ ] roll, roll_many, sum, bootstrap에 전달하던 회전 키를 순환 키로 변경합니다.
  • [ ] rotate를 roll로 바꾼 곳에서 고정 회전 키를 고정 순환 키로 변경합니다.
  • [ ] 고정 순환 키 생성 시 level을 키워드 인자로 전달하도록 변경합니다.
  • [ ] rotate를 roll로 바꾼 곳에서 delta 인자를 shift로 변경합니다.
  • [ ] GL의 hadamard_multiply 호출을 multiply로 변경합니다.
  • [ ] GL의 아다마르 곱셈 키를 재선형화 키로 변경합니다.
  • [ ] 부트스트랩에 17레벨 설정을 사용하도록 변경합니다.
  • [ ] 지원이 중단된 CKKS 행렬 곱셈 및 희소 인코딩 기능을 더 이상 사용하지 않습니다.
  • [ ] CKKS와 GL에 지원되는 형상과 파라미터를 사용합니다.
  • [ ] CUDA 환경을 지원되는 버전으로 변경합니다.
  • [ ] 이전에 직렬화한 데이터와 키를 새로운 형식으로 이전합니다.
  • [ ] 테스트를 다시 실행하여 연산 결과의 정확도를 확인합니다.

DESILO FHE 2.0의 변경 사항에 대한 자세한 내용은 릴리스 노트를 참고하시기 바랍니다.