OpenFHE Lattice Cryptography Library - Scheme switching between CKKS and FHEW experimental capability
This document describes how to use the scheme switching functionality to convert between CKKS and FHEW ciphertexts and perform intermediate operations.
The example for this code is located in scheme-switching.cpp. The file gives examples on how to run:
EvalCKKStoFHEW
, which converts a CKKS ciphertext to FHEW ciphertexts;EvalFHEWtoCKKS
, which converts FHEW ciphertexts to a CKKS ciphertext;- how to combine the two with intermediate operations, for example the floor function or a polynomial;
EvalCompareSchemeSwitching
, which returns the result of the comparison between two CKKS ciphertexts via transformation to FHEW ciphertexts and comparison;EvalMinSchemeSwitching
,EvalMinSchemeSwitchingAlt
andEvalMaxSchemeSwitching
,EvalMaxSchemeSwitchingAlt
respectively, which return the min and argmin, respectively max and argmax, of a vector of reals packed inside a CKKS ciphertext, via iterated scheme switching.
CKKS->FHEW We can transform a CKKS ciphertext (slot-packed and under public key encryption) into FHEW ciphertexts (symmetric key encryption), where each FHEW ciphertext encrypts a slot of the CKKS ciphertext. The conversion is done by computing the scaled homomorphic decoding (via a linear transform which can be precomputed), modulus switching, key switching, LWE extraction from RLWE, and another modulus switching.
The features that need to be enabled are PKE, KEYSWITCH, LEVELEDSHE and SCHEMESWITCH.
The user has to generate a CKKS cryptocontext and keys with the desired parameters, as well as to set up the FHEW cryptocontext and
private key through EvalCKKStoFHEWSetup
and the automorphism keys and key switch hints through EvalCKKStoFHEWKeyGen
. The setup is
completed by calling EvalCKKStoFHEWPrecompute
which takes as argument the scale with which to multiply the decoding matrix, which
in most cases should be chosen by the user to be Q / (scFactor * p), where Q is the CKKS ciphertext modulus on level 0, scFactor is the
CKKS scaling factor for that level, and p is the desired FHEW plaintext modulus. If the scale is left to be the default value of 1, the
implicit FHEW plaintext modulus will be Q / scFactor, and the user should take this into account. Finally, the user can also divide
separately the messages by p, and input plaintexts in the unit circle, then scale only by Q / scFactor and recover the initial message
in FHEW.
After the setup and precomputation, the user should call EvalCKKStoFHEW
. The number of slots to be converted is specified by the user,
otherwise it defaults to the number of slots specified in the CKKS scheme. Note that FHEW plaintexts are integers, so the messages from
CKKS will be rounded.
FHEW->CKKS We can transform a number of FHEW ciphertexts (symmetric key encryption) into a CKKS ciphertext (public key encryption) encrypting in its slots the input messages. The conversion is done by evaluating the FHEW decryption homomorphically (via a linear transform, which cannot be precomputed because it depends on the ciphertexts), then computing the polynomial interpolation of the modular reduction function (approximated via the sine function), and finally postprocessing the ciphertext to the appropriate message range.
The features that need to be enabled are PKE, KEYSWITCH, LEVELEDSHE, ADVANCEDSHE and SCHEMESWITCH.
The user has to generate a CKKS cryptocontext and keys with the desired parameters, as well as a FHEW cryptocontext and private key.
The setup also includes precomputing the necessary automorphism keys and CKKS encryption of the FHEW secret key, as well as other
information for switching from FHEW to CKKS, through EvalFHEWtoCKKSSetup
and EvalFHEWtoCKKSKeyGen
.
The conversion between FHEW to CKKS is called via EvalFHEWtoCKKS
, where the user has to specify the number of ciphertexts to
convert into a single CKKS ciphertext, the FHEW plaintext modulus (by default 4), and if the output is not binary, the range for
postprocessing the CKKS ciphertext after the Chebyshev polynomial evaluation. The example SwitchFHEWtoCKKS()
illustrates this aspect.
Importantly, for correct CKKS decryption, the messages have to be much smaller than the FHEW plaintext modulus used when encrypting in FHEW. The reason for this is that the modular reduction approximation implemented works well around zero, so m/p should be very small. (If this does not happen, only small messages will be converted correctly.) Moreover, since the postprocessing implies multiplying by the FHEW plaintext modulus used, which can be large depending on the target application, some loss of precision is expected when the message space is large.
CKKS->FHEW->operation->CKKS With the previous two modules in place, we can also work with CKKS ciphertexts, convert them to FHEW, perform operations on them, and then convert the result back to CKKS.
The user has to generate a CKKS cryptocontext and keys with the desired parameters, then call EvalSchemeSwitchingSetup
and
EvalSchemeSwitchingKeyGen
, which combine the setups for both conversions, then the precomputation for the CKKS to FHEW conversion
EvalCKKStoFHEWPrecompute
as above or EvalCompareSwitchPrecompute
, and the BTKeyGen
for the desired intermediate FHEW computations.
After calling EvalCKKStoFHEW
, the user then applies the desired functions on the FHEW ciphertexts. In the example
FloorViaSchemeSwitching()
the function is generalized floor/shifted truncation, in the example ComparisonViaSchemeSwitching()
the function is comparison between two vectors, and in the example FuncViaSchemeSwitching()
the function is specified and computed
through GenerateLUTviaFunction
.
Finally, EvalFHEWtoCKKS
should be called to switch back to CKKS, where the plaintext modulus of the output of the above function should
be specified (e.g., 4 for the output of comparison).
Recall that FHEW supports integers, while CKKS encodes real values. Therefore, a rounding is done during the conversion. For instance, to
correctly compare numbers that are very close to each other, the user has to scale the inputs with the desired precision. The example
ComparisonViaSchemeSwitching()
shows how to do this via EvalCompareSwitchPrecompute
.
Currently, the code does not support an arbitrary function to be applied to the intermediate FHEW ciphertexts if they have to be converted
back to CKKS. The reason is that (1) the current implementation of GenerateLUTviaFunction
works only for the small decryption ciphertext
modulus q = 2048, which allows a plaintext modulus of at most p = 8 (GetMaxPlaintextSpace()
) and (2) the current implementation of light
bootstrapping to convert FHEW ciphertexts to a CKKS ciphertext approximates correctly the modular function only arround zero, which requires
the messagee m << p. Instead of specifying directly the larger plaintext modulus in EvalFHEWtoCKKS
, which is required to postprocess
the ciphertext obtained after the Chebyshev evaluation, one can supply the plaintext modulus as 4, which returns a ciphertext
encrypting FloorViaSchemeSwitching()
.
FHEW->CKKS->operation->FHEW
This functionality is the mirror of the above. The user should call EvalSchemeSwitchingSetup
, EvalSchemeSwitchingKeyGen
,
EvalCKKStoFHEWPrecompute
, and generate the keys which are required for the intermediate CKKS computations. After calling EvalFHEWtoCKKS
,
the user can then apply the desired functions on the CKKS ciphertext. In the example PolyViaSchemeSwitching
, this intermediate function
involves rotations, multiplications and additions. Finally, EvalCKKStoFHEW
should be called to switch back to FHEW (where the plaintext
modulus to be used in decryption was used to compute the scale in EvalCKKStoFHEWPrecompute
).
Iterated scheme switching: min/argmin and max/argmax We also support repeated scheme switching between CKKS and FHEW with intermediate computations in each scheme. One such example is computing the minimum and argminimum, respectively the maximum and argmaximum, of a vector encrypted initially in a CKKS ciphertext.
The functionality is computed in a binary tree approach. First, the first half is compared to the second half of the vector: the difference is computed in CKKS, then switched to FHEW where the signs of the difference are computed, and switched back to CKKS. Second, using multiplication in CKKS, only half of the slots are selected to update the vector for the next iteration (the ones corresponding to a negative difference for min and the ones corresponding to a positive difference for max), and the process repeats until reaching a vector of length of one.
We provide two instantiation of the above intuition, EvalMinSchemeSwitching
which performs more operations in CKKS and is exemplified
in ArgminViaSchemeSwitching()
, and EvalMinSchemeSwitchingAlt
which performs more operations in FHEW and is exemplified in
ArgminViaSchemeSwitchingAlt()
.
For a good precision of the output, we require a large scaling factor and large first modsize in CKKS, as well as large ciphertext modulus and plaintext modulus in FHEW. Note that because CKKS is an approximate scheme, performing more operations in CKKS can lead to a decrease in precision.
The user should call EvalSchemeSwitchingSetup
, then EvalSchemeSwitchingKeyGen
, specifying whether the argmin/argmax should have a
one-hot encoding or not, as well as if the alternative computation method mentioned above should be used, then EvalCompareSwitchPrecompute
specifying if an additional scaling if desired. As mentioned above, the user can manually scale the inputs to [-0.5, 0.5], (such that
the difference of values is between [-1, 1]) in which case the precomputation does not need to have any scaling, and this is
exemplified in ArgminViaSchemeSwitchingUnit()
and ArgminViaSchemeSwitchingUnitAlt()
.
Finally, the user should call EvalMinSchemeSwitching
or EvalMinSchemeSwitchingAlt
to obtain the minimum value and the argmin, and
respectively, EvalMaxSchemeSwitching
or EvalMaxSchemeSwitchingAlt
to obtain the maximum value and the argmax.
Current limitations
- Scheme switching is currently supported only for CKKS and FHEW/TFHE.
- Switching from CKKS to FHEW is only supported for the first consecutive slots in the CKKS ciphertext.
- Switching to CKKS the result of an arbitrary function evaluation in FHEW is not yet supported. Only functions with binary outputs or small outputs with respect to the FHEW plaintext space are supported.
- Computing the min/max via scheme switching is only implemented for vectors of size a power of two.
- Large memory consumption for large number of slots (because of the linear transform required in the switching and that the keys are created with the maximum number of levels)
- Only GINX with uniform ternary secrets is currently supported for scheme switching.