Skip to content

Migration Guide: DESILO FHE 1.x to 2.0

DESILO FHE 2.0 introduces several breaking changes to its API, supported configurations, and serialization format.

This guide explains the changes required to migrate existing applications from DESILO FHE 1.x to 2.0. For a complete overview of new features and performance improvements, see the release notes.

1. Update Engine Construction

All arguments to the Engine constructor are now keyword-only. Additionally, two arguments have been renamed:

1.x 2.0
use_bootstrap bootstrap
use_multiparty multiparty

Before:

from desilofhe import Engine

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

After:

from desilofhe import Engine

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

The same change applies to multiparty configurations:

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

Creating an engine without arguments is still supported:

engine = Engine()

The default configuration is a CKKS engine with seven multiplicative levels.

use_bootstrap=True created a 10-level bootstrapping engine in 1.x, while bootstrap=True creates a 17-level bootstrapping engine in 2.0. The engine parameters, key sizes, and the number of levels after bootstrapping change accordingly.

The following constructor arguments and options have also been removed or changed:

1.x 2.0
use_bootstrap_to_14_levels=True bootstrap=True (17-level bootstrapping)
use_bootstrap_to_17_levels=True bootstrap=True
compact=True Removed. The compact representation is always used for CKKS.
slot_count Removed. See Migrate Matrix Multiplication and Sparse Encoding.
log_coeff_count, special_prime_count, log_slot_count Removed. See Update CKKS Parameters.
mode="async gpu" mode="gpu". The gpu mode now runs asynchronously, and "async gpu" raises an error.

For multiparty engines, the default configuration now supports 10 multiplicative levels instead of 4, and the maximum level is 23 instead of 29. The slot count for each level has also changed; see Multiparty Computation.

GL Engine

GLEngine has been removed. GL engines are now created with Engine using the form or shape argument. The GL-specific data types, such as GLCiphertext, GLPlaintext, and GLSecretKey, have been replaced with the data types shared with CKKS, such as Ciphertext, Plaintext, and SecretKey.

Before:

from desilofhe import GLEngine

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

After:

from desilofhe import Engine

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

2. Update Rotation and Roll Operations

DESILO FHE 2.0 distinguishes between roll and rotate:

  • roll shifts elements to the right.
  • rotate shifts elements to the left.

In previous versions, rotate used the direction now associated with roll. To preserve the behavior of existing code, replace rotate with roll and rotation keys with roll keys. When moving to the roll functions, the shift amount argument changes from delta to shift.

Warning

Existing rotate calls still run without errors in 2.0, but shift the elements in the opposite direction. Review every rotate call, because the results change silently.

Before:

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

After:

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

To keep the shift direction of 1.x, change the functions, keys, and arguments as follows:

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)
Rotation key Roll key
Fixed rotation key Fixed roll key

Code already using roll and roll_many, introduced in version 1.15, keeps the same shift direction. However, these functions now take a roll key instead of a rotation key, so the key must be replaced:

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)

For CKKS, rotate, rotate_many, rotation keys, and fixed rotation keys are still available in 2.0 and shift the elements to the left with the delta and deltas arguments. rotate_many is the 2.0 name of rotate_batch. As in 1.x, GL does not support rotate; use roll with a roll key instead of a rotation key.

Creating Roll Keys

Use the new roll key creation functions:

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)

Fixed roll keys are supported by both CKKS and GL.

For a matrix (GL) engine, a fixed roll key requires an axis:

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

For CKKS, the axis property is None.

The level argument must now be passed by keyword:

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

This avoids ambiguity between shift, axis, and level.

Reusing Bootstrap Keys

Bootstrap keys can be used directly with roll, roll_many, rotate, rotate_many, and sum. If your application already uses bootstrapping, you may be able to eliminate separate roll keys and reduce memory usage. See roll.

3. Update Evaluation Keys

DESILO FHE 2.0 introduces a unified Evaluation Key that can be used for most operations that require a key. Previously, some operations, particularly bootstrapping, required multiple separate keys. The Evaluation Key simplifies key management by combining the keys required for evaluation. Encryption and decryption still use their respective keys. When migrating existing code, consider using an Evaluation Key instead of passing multiple individual keys.

Before:

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

After:

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

The Evaluation Key can be used with multiply, square, relinearize, conjugate, roll, roll_many, rotate, rotate_many, sum, bootstrap, merge_bootstrap, and the polynomial evaluation functions. It is available only for CKKS, and cannot be used in place of a fixed roll key or a fixed rotation key. For the keys it contains, see create_evaluation_key.

4. Update GL Multiplication

The GL Hadamard multiplication API has been renamed to match CKKS.

1.x 2.0
hadamard_multiply multiply
create_hadamard_multiplication_key create_relinearization_key
Hadamard multiplication key Relinearization key

Before:

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

After:

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

GL multiplication can now also be performed without relinearization. The resulting ciphertext contains three polynomials rather than two and can be decrypted directly. This can eliminate unnecessary relinearization overhead when no subsequent operation requires a relinearized ciphertext.

As of 2.0.0, the only operation available for a ciphertext with three polynomials is decryption, but more operations will be supported in the future.

5. Update Bootstrapping Configurations

DESILO FHE 2.0 supports only 17-level bootstrapping.

The following configurations and features are no longer supported:

1.x 2.0
Other regular bootstrap variants (use_bootstrap, use_bootstrap_to_14_levels) Use 17-level bootstrapping (bootstrap=True)
Lossy bootstrapping (lossy_bootstrap, lossy_merge_bootstrap, create_lossy_bootstrap_key) Use regular bootstrapping
Sign bootstrapping (sign_bootstrap, sign_merge_bootstrap) No direct replacement
Merge bootstrap keys (create_merge_bootstrap_key) Use merge_bootstrap with the bootstrap key or the Evaluation Key
Large bootstrap keys (create_bootstrap_key(..., size="large")) Use the supported bootstrap key
Custom bootstrap stage counts (stage_count) Use the default configuration

The second argument of create_bootstrap_key is now size instead of stage_count.

The mod_raise function and secret keys with custom secret values (create_secret_key(secret)) have been removed. These features were intended for custom bootstrapping, which is no longer supported by the modulus configuration used for 17-level bootstrapping. Applications using custom bootstrapping pipelines must be redesigned to use the supported bootstrapping configuration.

6. Update CKKS Parameters

CKKS configurations with 65,536 slots (max_level 37 to 77) are no longer supported. These configurations required excessively large keys and suffered from significant encoding and decoding errors at low levels. If your application uses 65,536 slots, migrate to a supported CKKS configuration. Applications requiring more than the 36 multiplicative levels provided by the largest supported CKKS engine should use a bootstrap-enabled engine.

Custom configuration of the logarithm of the polynomial coefficient count is also no longer supported. The Engine(log_coeff_count, special_prime_count, ...) constructor and its log_slot_count argument have been removed. Use the predefined engine configurations, such as Engine(max_level=...), instead.

7. Update GL Shapes

GL shapes with an innermost dimension of 256 or larger, such as (16, 256, 256) and (4, 1024, 1024), are no longer supported. Applications using these shapes must select a supported configuration.

DESILO FHE 2.0 also introduces batch counts of 162 and 486, which may provide additional options when selecting a GL shape. For the complete list of supported GL shapes and maximum levels, see supported shapes.

8. Migrate Matrix Multiplication and Sparse Encoding

CKKS matrix multiplication and sparse encoding are no longer supported. This includes multiply_matrix, encode_to_plain_matrix, encode_to_light_plain_matrix, PlainMatrix, LightPlainMatrix, the CKKS matrix multiplication key, and the slot_count argument of Engine. Applications relying on these features require changes to their computation pipelines.

Depending on the workload, possible alternatives include:

  • Implementing CKKS matrix multiplication using efficient packing techniques with ciphertext rolls and multiplications.
  • Migrating suitable matrix-oriented computations to GL.

Note that GL shapes may be too large for some small-scale applications. Additional examples or library functionality for CKKS matrix multiplication are planned for future releases. There is no direct API replacement for the removed CKKS matrix multiplication and sparse encoding features.

9. Update CUDA Environments

DESILO FHE 2.0 supports only CUDA 13.2 and CUDA 13.4. Applications using older CUDA toolchains must update their build and runtime environments.

In particular, CUDA 13.0 is no longer supported because of a compiler bug involving nested thread divergence that can silently produce incorrect results. The issue was introduced in CUDA 12.8 and fixed in CUDA 13.2.2. Although this issue has not been observed in DESILO FHE, support for affected CUDA versions has been removed as a preventive measure.

When upgrading, verify that the installed NVIDIA driver is compatible with the selected CUDA version.

10. Migrate Serialized Data and Keys

DESILO FHE 2.0 uses a completely redesigned serialization format.

Serialized data and keys from previous versions are not compatible with 2.0.

You must regenerate any data and keys required by your application.

A recommended migration procedure is:

  1. Use the previous library version to deserialize existing data.
  2. Recover the original plaintext data where possible.
  3. Upgrade to DESILO FHE 2.0.
  4. Generate new keys using the updated engine configuration.
  5. Re-encode and re-encrypt the original data.
  6. Serialize the new data and keys using DESILO FHE 2.0.

If the original plaintext is unavailable, migration may require access to the appropriate secret keys and the previous library version. Direct conversion between the old and new serialization formats is not supported.

Migration Checklist

Before deploying an application with DESILO FHE 2.0, verify the following:

  • [ ] All Engine constructor arguments use keywords.
  • [ ] use_bootstrap and use_multiparty have been renamed.
  • [ ] Removed constructor arguments (compact, slot_count, use_bootstrap_to_14_levels, use_bootstrap_to_17_levels, log_coeff_count, special_prime_count, log_slot_count) and mode="async gpu" are no longer used.
  • [ ] GLEngine has been replaced with Engine(form="matrix") or Engine(shape=...).
  • [ ] Existing rotate calls have been reviewed and changed to roll where necessary.
  • [ ] Rotation keys passed to roll, roll_many, sum, and bootstrap have been migrated to roll keys.
  • [ ] Fixed rotation keys have been migrated to fixed roll keys where rotate was changed to roll.
  • [ ] Fixed roll key creation uses keyword arguments for level.
  • [ ] The delta argument has been changed to shift where rotate was changed to roll.
  • [ ] GL hadamard_multiply calls have been replaced with multiply.
  • [ ] GL Hadamard multiplication keys have been replaced with relinearization keys.
  • [ ] Bootstrapping uses the 17-level configuration.
  • [ ] Removed CKKS matrix multiplication and sparse encoding features are no longer used.
  • [ ] CKKS and GL configurations use supported shapes and parameters.
  • [ ] CUDA environments use a supported version.
  • [ ] Previously serialized data and keys have been migrated.
  • [ ] Application tests have been re-run to verify numerical accuracy and correctness.

For additional information about the changes introduced in DESILO FHE 2.0, see the release notes.