Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
To install Liberate.FHE, there are a few prerequisites that need to be met. First, you will need an Nvidia graphics card. Additionally, CUDA and Python must also be installed. Only after meeting these requirements can you proceed with the installation of Liberate.FHE.
Detailed steps to install Liberate.FHE can be found on How to Install. After downloading Liberate.FHE from GitHub, it needs to be installed as a Python package
version test
Liberate.FHE is an open-source Fully Homomorphic Encryption (FHE) library for bridging the gap between theory and practice with a focus on performance and accuracy.
Liberate.FHE is designed to be user-friendly while delivering robust performance, high accuracy, and a comprehensive suite of convenient APIs for developing real-world privacy-preserving applications.
Liberate.FHE is a pure Python and CUDA implementation of FHE. So, Liberate.FHE supports multi-GPU operations natively.
The main idea behind the design decisions is that non-cryptographers can use the library; it should be easily hackable and integrated with more extensive software frameworks.
Additionally, several design decisions were made to maximize the usability of the developed software:
Make the number of dependencies minimal.
Make the library easy to understand and modify.
Set the usage of multiple GPUs as the default.
Make the resulting library easily integrated with the pre-existing software, especially Artificial Intelligence (AI) related ones.
Anyone can easily start to use Liberate.FHE by following Quick Start after installing the library via Installation.
RNS-CKKS scheme is supported.
Python is natively supported.
Multiple GPU acceleration is supported.
Multiparty FHE is supported.
CKKS bootstrapping
Liberate.FHE CPU version
IND-CPA-D Security for CKKS
Liberate.FHE is available under the BSD 3-Clause Clear license. If you have any questions, please contact us at contact@desilo.ai.
Support forum: TBD
Liberate.FHE natively supports python programming language. To install and use Liberate.FHE, please follow the steps below:
Liberate.FHE runs on single or multiple GPUs. Running Liberate.FHE on GPUs requires installing . Additionally, you need to install that matches the version of you intend to use. Theses settings are necessary for GPU-based operations.
To build Liberate.FHE, you need to install , a dependency manager and packaging tool for Python. It is recommended to set up a virtual environment to manage the project in an isolated environment.
Clone the of Liberate.FHE to obtain the latest source codes.
Use poetry to install the project dependencies. Open a terminal and run the command poetry install
. This will automatically install all the required packages for the Liberate.FHE.
To compile CUDA by running the setup.py
file. In the terminal, run the command poetry run python setup.py install
. This command will compile CUDA files.
Build the project by running the command poetry build
in the terminal. This will create a distributable format of the package.
Install the Liberate.FHE by running the command poetry run python -m pip install .
in the terminal. This will install the Liberate.FHE library into your system.
The following example shows the high level APIs of Liberate.FHE which can be used quickly and easily.
To use homomorphic encryption, you need to configure security parameters according to your requirements. These parameters should be decided based on several factors such as the number of data elements, the number of multiplications, and the desired precision. The presets provide parameter options of different levels for convenience. You can also modify the parameters if needed.
After setting the parameters, you can generate the engine by providing the parameters and any additional options you need.
Homomorphic encryption uses various types of keys for encryption, decryption and homomorphic operations (a.k.a. homomorphic evaluations). The most basic keys are a Secret Key sk
and a Public Key pk
. The sk
is a private key used for decryption and should not be exposed to external entities. The pk
is a key used for encryption and is shared with external users. In addition, an Evaluation Key evk
, also known as a Re-linearization Key, is generated for multiplication operations.
In CKKS, data is encrypted through the Encode -> Encrypt process.
The liberate.fhe
library provides a shortcut function called encorypt
for convenience, which combines the encode and encrypt steps.
To perform operations using encrypted data, you can utilize the homomorphic operation functions provided by the liberate.FHE
library.
After performing the homomorphic operations, you can decrypt the ciphertext ct
and decode it to obtain the original data.
The liberate.FHE
library provides shortcut functions called decrode
for convenience, which combines the decrypt and decode steps.
Operating System : Liberate.FHE is compatible with .
Python : Liberate.FHE requires version 3.10 or above. You can download and install Python from the official website. And we recommend using the python virtual environment.
PyTorch : Liberate.FHE uses the package. When you install Liberate.FHE, it automatically installs PyTorch.
CUDA : If you want to utilize the GPU, install . Ensure that you choose a version of CUDA that is compatible with PyTorch, and install it accordingly.
To start using homomorphic encryption such as the CKKS scheme with the liberate.fhe
package, you need to import the necessary packages. The liberate.fhe
package is the essential for using the CKKS scheme. Additionally, pre-configured information can be found in the liberate.fhe
package's .
For more detailed information on the parameters used for engine generation, you can refer to the .
Please refer to the for information on generating different keys.
For more detailed information on the homomorphic operations used, you can refer to the .
This section is a brief guide on how to start programming homomorphic encryption applications using the liberate.fhe
package with the CKKS scheme. It includes steps such as package import, engine configuration and creation, homomorphic key generation, data encoding and encryption, performing operations on encrypted data, decryption and decoding. For more detailed information, please refer to the .
The purpose of this tutorial is to calculate the mean and variance for all the data using approximately 10 million encrypted records. This will enable more accurate and reliable data analysis. Additionally, by using Liberate.FHE as in this tutorial, you can confirm that it is possible to implement Homomorphic operations with very simple code.
In this tutorial, you can find the complete codes for mean and variance as follows:
Import the package you want to use. fhe
is an essential package from the Liberate Library for homomorphic encryption. fhe.presets
is a package that provides convenience for importing pre-configured homomorphic parameters.
To create the CKKS engine, we utilize pre-configured parameters. For this tutorial, the engine has been created using the gold
parameter. In the case of gold
, the value of logN
is 16, there are 4 special primes
, and a total of 34 levels are available.3.
We will generate the keys to be used in the computation. The keys used in this tutorial are as follows.
sk
: The secret key is a confidential piece of information that is kept secret by the data owner or a trusted entity. The secret key is typically used for decrypting data. In homomorphic encryption, it is used to decrypt the results of computations performed on encrypted data. The secrecy of the secret key is crucial for the security of the encrypted data. If compromised, an attacker could decrypt the results and potentially gain access to sensitive information.
pk
: The public key is a component of the homomorphic encryption system that is openly shared. The public key is used for encrypting data. While it can be used to encrypt data, it cannot be used to decrypt the results of computations performed on that data. Unlike the secret key, the public key is shared openly and does not need to be protected in the same way. Its security is not compromised even if it is known to potential adversaries.
evk
: The evaluation key is a cryptographic component used in homomorphic encryption schemes that support relinearization. It is used during the relinearization process to transform ciphertexts, typically after multiplication operations. While not as sensitive as the secret key, the relinearization key may still require protection, and its use is generally limited to trusted entities.
gk
: The Galois key is a cryptographic component used in certain homomorphic encryption schemes to support specific operations, particularly rotations and linear transformations in the Galois field. The Galois key enables the efficient execution of mathematical operations on encrypted data while preserving the confidentiality of the underlying information. While the Galois key is an important component, it is not as sensitive as the secret key in homomorphic encryption.
In this tutorial, we will calculate the average and variance of approximately 10 million data points. These 10 million data points will be generated assuming they represent the ages of the population in a specific city. Therefore, we assume the age ranges from 0 years old to 99 years old and generate them using a random function. Additionally, we will trim the data slightly to match the number of security parameters we have set, rather than exactly 10 million. Since we have set logN
to 16, the number of available slots is 32,768. Hence, the number of ciphertexts we will use is approximately round(10,000,000/32,768) = 305. We will then proceed with encoding and encrypting using the encrypt function. With the data prepared, we can now begin by calculating the mean (average).
The code for calculating mean in Liberate.FHE is as follows.
Calculate the total of all the values in the dataset.
To calculate the average, divide the sum by the number of values .
Therefore, we use the add
function to calculate the sum of all ciphertexts.
To calculate the average of all encrypted texts, use the mean provided by Liberate.FHE.
Now, we can use the average value obtained in this way to calculate the variance.
The formula to calculate dispersion is as follows.
Calculate the average of the data : Utilize the previously computed average.
Subtract the average from each data point.
Calculate the sum of all squared deviations.
Divide the sum of squared deviation by the number of values.
To calculate the difference between each data point and the previously calculated average, we can use the sub
function from Liberate.FHE. Then, we can calculate the square of the differences using the square
function. By summing up the squared differences and using the mean
function, we can obtain the variance.
To use Liberate.FHE, a GPU is required. This document explains how to set up and install the Nvidia graphics card driver and CUDA. It provides steps to identify and install the GPU, update package lists, install Nvidia drivers, verify the installation, install the CUDA toolkit, set environment variables, and verify the CUDA installation.
Before you begin, it's essential to identify the Nvidia GPU model in your system. You can use the following commands to check:
If the Nvidia graphics card is not installed or an incompatible version of CUDA is installed, install a new version.
Ensure that your package lists are up to date.
Check available graphic cards.
Automatically install the recommended drivers.
Alternatively, manually install the desired version.
Don't forget to restart the server after installing the graphic card driver.
Please ensure that the graphics card is in working order.
If you encounter any issues during the installation or need further customization, you can refer to the official Nvidia documentation or seek help from the Ubuntu community forums.
Make sure your GPU is CUDA-compatible. You can find a list of CUDA-enabled GPUs on the Nvidia website.
Please refer to the instructions provided above.
Visit the Nvidia CUDA Toolkit download page.
Assuming you've downloaded the toolkit:
Add CUDA to your PATH
and update LD_LIBRARY_PATH
. You can do this by adding the following lines to your ~/.bashrc
or ~/.zshrc
file:
Remember to provide the source for your updated profile:
Please verify if CUDA has been installed correctly by executing the following command:
This should display the CUDA compiler version.
This document offers comprehensive guidelines for installing Python on Ubuntu. It discusses multiple installation methods, such as utilizing APT, Anaconda
, or pyenv
for Python version management. The document also provides detailed instructions for installing Anaconda
, setting up a virtual environment with Anaconda, and installing and configuring pyenv
for Python version and virtual environment management.
Before installing Python on Ubuntu, it is important to check if Python is already installed on your system. You can do this by running the following command:
If Python ^3.10
is not already installed, you have the option to use APT to install it on your system. To do so, please follow these steps:
To update the system repository list, use the following command:sudo apt install python3
To set up Python, install the required dependencies using the following command:sudo apt
Install the latest version of Python with the command:
(Recommended) Using Anaconda or pyenv
Instead of directly installing Python on your system, it is recommended to use Python version management tools like Anaconda or pyenv.
Anaconda is a software package that includes Python and R programming languages. It is widely used in scientific computing for various fields like data science, machine learning, and large-scale data processing.
If you are using Linux and want to use GUI packages, you will need to install additional dependencies for Qt.
To install the latest version of Anaconda, follow these steps:
Download the latest version of Anaconda from the official website:shasum -a 256
(Recommended) Ensure the integrity of the installer's data by verifying it with SHA-256. For additional details on hash verification, please refer to the documentation on cryptographic hash validation.
Install Anaconda by running the downloaded installer :
Update all packages in Anaconda
Set up a Python Virtual Environment using Anaconda :
Activate the virtual environment :
For more information on how to use Anaconda and its features, please refer to the official documentation.
Pyenv is a tool that enables you to conveniently handle multiple Python versions and virtual environments.
To configure pyenv, you can simply follow these steps :
Download pyenv using the following command:
Update pyenv to the latest version :
To ensure proper configuration, please add the necessary settings to your shell startup file (~/.bashrc
, ~/.zshrc
, etc.), based on your shell environment.
For Bash :
For Zsh :
To install the Python version you want, you can use pyenv. First check the available Python versions using the command pyenv install --list
. Then, install a specific version by running the appropriate command.
To start, create a Python virtual environment and activate it :
To learn more about using pyenv
and its features, please refer to the official documentation.
The Multiparty FHE (MFHE) approach combines the features of a distributed trust model and the privacy-preserving capabilities of homomorphic encryption. In the MFHE, no single participant stores the secret key for decryption. This decryption system ensures that no one can access encrypted data alone, and decryption requires consensus from all participants.
Liberate.FHE provides a of multiparty FHE algorithm where is the number of participants. of means that all participants who were involved in the key generation process must also be involved in the decryption process. Liberate.FHE's MFHE is designed to follow the technique introduced in this and this papers. This approach shares similarities with the single-key method in terms of homomorphic operations but differs in the manner keys are generated. All participants have their own secret keys, and a collective public key is generated by the participants' public keys. Therefore the collective encryption key should be generated again whenever there is a change in the member of participants. However, the computation time and the size of a ciphertext are almost identical to that of the single-key encryption. Decryption should be done interactively with the participation of all parties involved. Liberate.FHE offers user-friendly APIs of all the MFHE processes for supporting real-world multiple participants' use cases.
In this tutorial, we will explore the usage of the Multiparty scheme in Liberate.FHE. The structure of this tutorial is as follows:
Required Package Import
Parameter Configuration & Generate CKKS Engine
Generation of keys required for operations
Secret Key
Collective Public Key
Collective Evaluation Key
Collective Rotation Key
Encryption
Homomorphic Operations
Decryption
Import the necessary packages in Liberare.FHE.
Set up the homomorphic parameters and create the CKKS engine.
Set the number of participants in num_parties and generate the corresponding secret key.
To generate a collective public key, several steps are required. First, the Common Reference String (CRS), which is a value that each party needs to share, is generated. Then, each party generates their public key using their own secret key and the shared CRS. After generating the public key for each party, the collective public key is created using these keys and shared with each party.
All participants will be shared with the CRS value. Then, each party will generate the secret shared evks_share using the shared CRS and their own secret key (sk). The generated evks_share will be used to create evks_sum and shared with all parties. Each participant will use the shared evks_sum and their sk to generate evk_sum_mult, and then share the generated evk_sum_mult to create the collective evaluation key (cevk) and share it with all participants.
The process of generating the Collective Rotation Key (crotk) is the same as the process of cpk.
Encryption follows the same process as general encryption, except that it uses cpk
.
The Homomorphic Encryption operation is similar to the usual process of Homomorphic Encryption, with the only difference being that it utilizes a collectively generated key by all participants.
The process of decryption consists of three steps. These steps are multiparty_decrypt_head
, multiparty_decrypt_partial
, and the final step multiparty_decrypt_fusion
. One participant uses the head
function, while the remaining participants use the partial
function. Then, the participant who wants to see the decrypted result executes the fusion
function.
The code used in this tutorial is as follows:
TBD
TBD
with re-linearization, rescale
TBD
TBD
TBD
Please refer to the respective page for instructions on how to install a .
Please refer to the respective page for instructions on how to install a .
Please refer to the respective page for instructions on how to install a .
Clone the of Liberate.FHE to obtain the latest source code.
Use poetry to install the project dependencies. Open the terminal and run the command poetry install
. This will automatically install all the required packages for the Liberate.FHE.
To build CUDA by running the setup.py
file. In the terminal, run the command poetry run python setup.py install
. This command will build CUDA files.
Install the Liberate.FHE by running the command poetry run python -m pip install .
in the terminal. This will install the Liberate.FHE library into your system.
TBD
BSD 3-Clause Clear License
Copyright (c) 2023 DESILO Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted (subject to the limitations in the disclaimer below) provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
Neither the name of DESILO Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE DESILO INC. AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE DESILO INC. OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
This comprehensive document provides in-depth information on the usage and functions of the groundbreaking Liberate.FHE library for Homomorphic Encryption. It covers various essential aspects, starting with a detailed explanation of the context and engine generation, which forms the foundation for the library's powerful capabilities. It then delves into the key generation process, ensuring the secure creation of encryption keys that are vital for protecting sensitive data.
Moreover, this document elaborates on the encoding and decoding mechanisms employed by the Liberate.FHE library, enabling seamless transformation of data into encrypted form and vice versa. It also explores the encryption and decryption processes, shedding light on the secure procedures employed to safeguard information while allowing computations to be performed on encrypted data.
In addition to these core functionalities, the document provides insights into the diverse arithmetic functions available within the Liberate.FHE library. These functions empower users to perform mathematical operations on encrypted data, opening up a world of possibilities for secure computations. Furthermore, it highlights support functions that enhance the overall usability and efficiency of the library, ensuring smooth integration and seamless operation.
Last but not least, this document showcases the utility functions offered by the Liberate.FHE library, including the ability to save, load, and print data structures. These functions provide convenient ways to manage and manipulate encrypted data, enabling users to easily store, retrieve, and analyze information as needed.
Overall, this comprehensive document serves as an indispensable guide for users seeking to harness the full potential of the Liberate.FHE library for Homomorphic Encryption. It covers a wide range of topics, ensuring a thorough understanding of the library's capabilities and empowering users to leverage its advanced features for secure and efficient computations.
This documentation only covers the high-level APIs of the library. That is, only the publicly exposed functions are explained. There are numerous internal functions that compose the library; however, those are not documented herein.
The function API is broken down into 7 parts:
Context generation
Key generation
The basic blocks of encoding/decoding and encrypting/decrypting
Arithmetic functions
Support functions
Runtime reflection
Utility functions such as save, load, export, import, upload (to GPUs), and download (from GPUs)
Liberate.FHE differentiates itself from other packages in that
All intermediate calculations are explicitly executed as integers. No float or double conversions occur during computation.
All intermediate calculations and modular reductions are exact, as they are done using the Montgomery Reduction technique.
Texts, including Cipher, Key, and Plain, are stored in GPUs in split form. In particular, the split is alongside the RNS channels, with the exception of the special primes. Special primes are repeated (copied) onto all the GPUs for faster execution of key switching. For details of the partitioning scheme, refer to rns_partition.py
under the ntt
folder.
Rescaling is done before the multiplication, not after the multiplication.
The input message is pre-permuted before encoding. This is done to achieve a cyclic-rotation effect by permuting the coefficients. Similarly, the decoded message is post-permuted to restore the intended form..
As a result of Rescale Before Multiplication, intermediate cipher texts are multiplied with the square of the scale factor. That is . To compensate for the squared , cipher texts are rescaled right before decryption as well.
There are 2 proprietary formulas used for rescaling and key switching. The effect of using these methods results in algorithmic exactness.
Primes are selected according to a proprietary condition that prevents drift of the rescale error, that is . The square term comes from multiplication because rescale error is always the consequence of binary multiplication.
The deviation error, relative to the size of the text, that arises from rescaling is explicitly corrected during the decryption stage. This correction significantly enhances the accuracy of homomorphic operations.
There are 2 stages of the context generation.
The first is the CKKS context generation. The generated CKKS context includes basic information about the polynomial length, primes, and etc. The generated context is also saved in the cache folder for faster access at later times if a context with the same configuration is requested.
By default, scale primes with the bit lengths of from 20 to 59 are generated. However, usage of primes under 30 bits are not recommended for accuracy reasons as density of primes in the bit range are sparse, hampering downed the quality of the primes distribution. Also, note that the context support 2 precision types, that are 32 bits and 64 bits integers. Although, it is highly unlikely the 32 bits precision will be used in real situations, the case is included for completeness.
The grammar of calling the context generate functions is as follows:
where,
buffer_bit_length
: Specifies the bit length of coefficients. For 64-bit integers, use 62 (default), and for 32-bit integers, use 30.
scale_bits
: Specifies the scale. The scale will be set to . Note that the bits allocated for the integral part of the message will be buffer_bit_length - scale_bits - 2
.
logN
: Specifies the length of the message polynomial. The length of the polynomial is , and the actual length of the message that can be encoded in the polynomial is . The means you can fill the polynomial with complex numbers.
num_scales
: Specifies the number of utilizable homomorphic levels. If not specified explicitly, the context generator will generate the maximum number of levels available given the logN
and the security requirements.
num_special_primes
: This number corresponds to the factor in hybrid key switching. The specified number of primes will be subtracted from the available levels and then used for key switching.
sigma
: The standard deviation of the discrete Gaussian sampling, when generating small errors.
uniform_ternary_secret
: Selects the random algorithm when sampling the secret key. Currently this parameter has no effect, and the engine sticks to the uniform ternary sampling method.
cache_folder
: The path to the cache folder.
security_bits
: Specifies the strength of the security in terms of bits.
quantum
: Specifies the quantum security measures. The value can be either post_quantum
or pre_quantum
.
distribution
: Specifies the security model. The security level is measured by sampling and measuring the hardness. This parameter selects the sampling method in the process. Note that this is not the sampling distribution for error generation.
read_cache
: If set to true, and if the cache for the input parameters exists, the context generator will read in the cache instead of generating a fresh one.
save_cache
: If set to true, a newly generated context will be saved to a cache file.
verbose
: If set to true, invoking the generator will print out diagnostic messages.
The second is the engine generation. An engine contains numerous pre-calculated caches for calculating the NTT transformation and modular operations. The pre-calculated caches are moved to available GPUs at the generation time so that following calculation won't need to move around the caches. Note that these engine parameters are volatile, that means they are not saved to the disk.
Note that you do not need to generate the ckks_context and hand it over to the engine generator, as it is done internally, and automatically.
At the time of engine generation, you can specify which GPUs to use. This will give you the opportunity to experiment with deployment configurations.
The calling API is identical to that of context generation, such that
Semantics of the parameters are the same as the context generation.
In most usage scenarios, you would only need to specify the logN
and all the rest will be automatically generated.
For example,
will generate the most typical CKKS engine for you.
We have preset parameters that can deliver the best performance for user convenience. These settings are composed of values that can yield optimal results in logN
, num_special_primes
, and number of GPUs (devices
). We have named these settings bronze
, silver
, gold
, and platinum
(you may have heard these names somewhere before. Yes, that's right. Just as you might think). Bronze
corresponds to the setting when logN
is 14, and the subsequent settings are composed of values 15, 16, and 17 respectively. These settings are provided in the form of Python dictionaries, and users can easily modify them as they wish. By providing these preset values, users can avoid the hassle of manually adjusting parameters to achieve the optimal results.
The arguments provided in presets.params
are as follows:
And you can use level 7 in bronze
, level 16 in silver
, level 34 in gold
, and level 72 in platinum
.
You can find descriptions for each parameter in the Liberate.FHE document.
The secret keysk is the randomly generated secret key. The Homomorphic Encryption Standard recommends refresh of the random seed occasionally. In case of refresh, issue
and then, generate a secret key.
Generating a public keypk requires a sk. Equipped with a sk, you can issue
to obtain a public key.
Note that, public keys generated with the same sk
have all different values, as it is the security requirement. Although different in values, all the cipher messages that are generated with the same sk
will work equally well under homomorphic operations; cipher texts encrypted under the same sk
but different pk
can be mixed in homomorphic operation. However, in any operation, their currency level must match.
The Evaluation Keyevk is used for multiplication. It can be generated with
The galois key galk is a collection of key switch keys that enable the cyclic rotations. For a polynomial of length , all possible rotations can be represented by rotations. The galk contains such keys. The key generation API is
.
In some occasions, you may want to generate a rotation key for a particular rotation. The most typically expected case is where the rotation is repeated frequently is a computation circuit and you want to accelerate the rotation by directly applying a rotation instead of a successive composition of rotations. In such case, use the following API
. Issuing the above function will generate a rotation key valid for the particular rotation.
Conjugation is a transformation of a complex number to . The key for such operation can be generated with
You can change the secret key of a cipher text to a different secret key. The key switch key is used for such operation. You can issue the following command to generate the key switch key
, where ksk is the key switch key, sk_from is the secret key used to encrypt the cipher text, and sk_to is the new secret key with which you want to encrypt the cipher text.
A message is an array of complex numbers of which the length .
In most cases, the message goes through a usage cycle as
encode → encrypt → Homomorphic Operations → decrypt → decode
The following subsections explain the API for each stage in the usage cycle, except for the homomorphic operations phase. APIs for the operation phase are enumerated in a separate (following) section.
, where pt denotes a plain text and m a message and level denotes the homomorphic level you wnat to use. Note that the pt you get is a pre-permuted version of the encoded plain text.
, where ct denotes the cipher text, pk is a public key and level is homomorphic level you want to use.
, where ct denotes the cipher text, pk is a public key and level is homomorphic level you want to use.
, where sk
is a secret key.
, where sk
is a secret key and level is homomorphic level you want to use.
Note that you do not need to post-permute the message m
. It is automatically handled for you.
, where sk
is a secret key.
There are numerous homomorphic arithmetic functions supported. The following subsections explain each of them.
Note that a
and b
can both be cipher texts, or can be plain texts (or a messages). If one of the operands is message, the message will be automatically encoded to match the required format of the plain text.
Also that a
and b
can both be cipher text or can be plain texts(or messages). If one of the operands is message, the message will be automatically encoded to match the required format of the plain text.
Also note that, the sace where both a
and b
are plain texts(messages) is mermitted since triplet of additions may occur and two of the operands are plain texts.
If
a
andb
are at different levels, the engine will do a proper leveling on one of the inputs and calculate the results. The resultant will have the highest level of the two.
Likewise, for subtraction use
.
A word of warning here.
Do NOT attempt to add or subtract cipher texts directly. Use the API.
Since the cipher texts are, by implementation, PyTorch tensors, you may be attempted to add or subtract them directly by using a + b
of a - b
. Don't. Although, the numbers contained in the tensors are
Coefficients of the Number Theoretic Transformation (NTT) coefficients.
The Montgomery form numbers.
The context engine will do proper computations for you, and hence do not attempt to do it yourself unless you are undeniably certain about what you're doing.
. Composition and permittance of the input parameters are the same as the add/substration. However, one caveat still persists: Division is not provided as an API function.
Since division is inherently iterative, meaning it consumes multiple levels, its API is not provided in the engine API. You will have to devise your own function using the Newton-Rhapson or the Goldschmidt algorithm.
If
a
andb
are at different levels, the engine will do a proper leveling on one of the inputs and calculate the results. The resultant will have the highest level of the two.
. Most of the aspects are similar to multiplication, but it is a bit faster than using the mult
function because it has been optimized.
Cyclically rotate a cipher text using
, where ct
is the cipher text, ksk
is the galk
, shift
is the shift distance of the rotation. And if you use the return_circuit
option, you can check wich index you have moved to. Signedness of the shift
determines the direction of the shift. A positive shift
denotes shifting right, and a negative the opposite direction of left.
In case you generated a key switching key that can accommodate one rotation, you can also issue
.
You can conjugate a cipher text by simply calling
.
Note that key switching occurs internally when performing multiplication, rotation, and conjugation. For some reason if you want to change the secret key used to encrypt a cipher text, you can do
, where the original secret key and the new secret key are embedded in the key switching key ksk
. Note that the ct
must already have been encrypted with the secret key that matches the original secret key embedded in the ksk
. Otherwise, you will be confronted with a broken cipher text.
If necessary, you can use the following functions to have more control over homomorphic operations. The functions are issued in the calls of homomorphic multiplication, however you can have finer control over how the multiplications are done by calling them individually.
Homomorphic multiplication, is in fact a sequential combination of rescale
, cc_mult
, and relinearize
. In building a computation circuit you can apply some optimization techniques at atomic levels to achieve greater performance. The following are such atomic functions that consist a multiplication.
, where a
and b
are input parameters that can be a cipher text, an encoded plain text, or a message respectively, and d0
, d1
, and d2
are components of a raw product.
, where ct_mult
has d0, d1, and d2 are the results of applying the something manual multiply function, and new_ct
is the relinearized cipher text.
, ct_rescaled
have plus one levels compared to the ct
.
The rationale behind the design decision is that the rescaling is always done at least in pairs. Obviously, in multiplications two cipher texts get involved and since we are rescaling before multiplication the operation necessitates rescaling of the two involving cipher texts.
A circumstance will occur frequently where you want to operate on two cipher text but their levels are different. The level up function is the rescue for such circumstances. Matching levels of cipher texts is not an easy business as it might look at first glance; Deviation from rescaling kicks in and the deviation must match at both operands together with the RNS channel lengths. The following function will do the job for you and ease up the headache.
The engine will do multiple (if necessasary) levelings to make the level of the new_ct
to reach the level_to
. If the level of the ct
is already higher or equal to the level_to
the function will return raising an exception.
You can investigate the status of the cipher text or the engine at runtime, using
The num_level
gives you the number of multiplications you can do with a cipher text.
You can investigate the level at which the cipher text is by issuing
. Note that the level
goes up from zero until it reaches depletion at the num_level
. That means a freshly encrypted cipher texts will always have the level 0.
You can figure out the kind of a text by calling
. The text can be a plain text
, a key
, or an array of keys
(a key switching key). The data_struct_str
will give you a self-explanatory description of what kind of the data_struct
is.
You can save all variable with data_struct
like cipher text
, secret key
, public key
, key swithching key
, rotation key
and galois key
.
You can load all variable with data_struct
like cipher text
, secret key
, public key
, key swithching key
, rotation key
and galois key
and you can use move_to_gpu
to select whether to move to GPU(True) or CPU(False).
You can copy a variable with data_struct using Clone function.
TBD
grade | logN | special primes | devices | scale_bits | num slots | num levels |
---|---|---|---|---|---|---|
bronze
14
1
1
40
8192
7
silver
15
2
1
40
16384
16
gold
16
4
Full
40
32768
34
platinium
17
6
Full
40
65536
72