-
Notifications
You must be signed in to change notification settings - Fork 137
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Updated to release 1.1.0 Signed-off-by: Farhan Ahmed <Farhan.Ahmed@ibm.com> * Potential fix to notebook image centering Signed-off-by: Farhan Ahmed <Farhan.Ahmed@ibm.com> * Updated setup-crypto.md Signed-off-by: Farhan Ahmed <Farhan.Ahmed@ibm.com> * Notebook fix Signed-off-by: Farhan Ahmed <Farhan.Ahmed@ibm.com> Signed-off-by: Farhan Ahmed <Farhan.Ahmed@ibm.com>
- Loading branch information
Showing
67 changed files
with
7,448 additions
and
243 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,14 @@ | ||
# IBMFL tutorials and Demos | ||
# IBMFL Tutorials and Demos | ||
|
||
In this directory, we have a collection of jupyter notebooks to demonstrate how to use IBM FL to run some of our examples. | ||
|
||
**Note:** please run all notebooks from the main notebook directory, i.e., open `Notebooks` (the main notebook directory) via `jupyter notebook`, so all images in the notebooks can render properly. | ||
**Note:** please run all notebooks from the main notebook directory, i.e., open `Notebooks` (the main notebook directory) via `jupyter notebook`, so all images in the notebooks can render properly. | ||
|
||
* [Training a Keras CNN model on MNIST dataset](./keras_mnist_classifier) | ||
* [Training a PyTorch model on MNIST dataset](./pytorch_classifier) | ||
* [Mitigating bias of the global model on Adult dataset via local reweighing](./sklearn_logclassification_rw) | ||
* [Trying out a cartpole reinforcement learning example](./reinforcement_learning_cartpole/cartpole.ipynb) | ||
* [Understanding quorum setup and party drop out](./tf_quorum_reconnect) | ||
* [Understanding quorum setup and party drop out](./tf_quorum_reconnect) | ||
* [Training a TensorFlow model using homomorphic encryption](./crypto_fhe_tensorflow) | ||
* [Training a PyTorch model using homomorphic encryption](./crypto_fhe_pytorch) | ||
* [Training a Scikit-learn model using homomorphic encryption](./crypto_fhe_sklearn) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,204 @@ | ||
{ | ||
"cells": [ | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"# Key Setup for Homomorphic Encryption System in IBM FL" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"### Outline:\n", | ||
"- [Environment Setup](#env)\n", | ||
"- [Generate HE Key Files](#setup)" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"### Environment Setup : Add conda environment to Jupyter Notebook <a name=\"env\"></a>\n", | ||
"\n", | ||
"Please ensure that you have activated the `conda` environment following the instructions in the project README.\n", | ||
"\n", | ||
"Once done, run the following commands in your terminal to install your conda environment into the Jupyter Notebook:\n", | ||
"\n", | ||
"1. Once you have activated the conda environment, install the `ipykernel` package: `conda install -c anaconda ipykernel`\n", | ||
"\n", | ||
"2. Next, install the `ipykernel` module within Jupyter Notebook: `python -m ipykernel install --user --name=<conda_env>`\n", | ||
"\n", | ||
"3. Please install the `matplotlib` package for your conda environment. \n", | ||
"\n", | ||
"4. Finally, restart the jupyter notebook once done. Ensure that you are running this Notebook from `<project_path>/Notebooks`, where project_path is the directory where the IBMFL repository was cloned.\n", | ||
"\n", | ||
"When the Notebook is up and running it may prompt you to choose the kernel. Use the drop down to choose the kernel name same as that chosen when running `conda activate <conda_env>`. If no prompt shows up, you can change the kernel by clicking _Kernel_ > _Change kernel_ > _`<conda_env>`_." | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"### Homomorphic Encryption (HE)\n", | ||
"\n", | ||
"In IBM-FL, HE functionalities are implemented using *[IBM HElayers software development kit (SDK)](https://github.com/IBM/helayers)*, and in particular, its *[PyHElayers](https://github.com/IBM/helayers#pyhelayers-python-package)* Python package. You can install `pyhelayers` in your conda environment by running `pip install pyhelayers`. Note that `pyhelayers` is currently supported only on Linux (x86 and IBM Z)." | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"#### Set up directories" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"import sys\n", | ||
"sys.path.append('../../..')\n", | ||
"import os\n", | ||
"os.chdir(\"../../..\")" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"### Generate HE Key Files <a name=\"setup\"></a>" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"The HE crypto system uses a public key and a secret key. As shown in the figure, secure aggregation using the HE crypto system requires the aggregator to obtain the public key and the parties to share the private key. In what follows, we will go into detail into how to generate the HE keys. In a real production environment, securely distributing the keys is a crucial aspect. However, in this tutorial, our focus is on secure aggregation under HE, and we do not include the important aspect of key distribution." | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"<img src=\"images/FL_HE_keys.png\" width=\"512\"/>\n", | ||
"<figcaption><center>Parties share an HE private key, and share with the aggregator an HE public key.</center></figcaption>" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"There are two ways to generate HE keys.\n", | ||
"\n", | ||
"#### 1. Use Default Parameters (Easiest Way)\n", | ||
"The easiest way to generate HE keys is to run the `generate_store_HE_keys()` method that takes the following arguments:\n", | ||
"\n", | ||
"- `path_for_public_key`: Path at which the public key file of HELayers will be stored.\n", | ||
"- `path_for_secret_key`: Path at which the secret key file of HELayers will be stored.\n", | ||
"- `HE_parames` (optional): Dictionary specifying the parametes of Homomorphic Encryption (HE). When using the default parameters, this argument is not required.\n", | ||
"\n", | ||
"In HE-based aggregation in IBM-FL, all parties will have the access to the secret key. The aggregator will not have access to the secret key. It is worth noting that the secret key is used for decryption. Any entity that has an access to the secret key can decrypt the model updates from any party, and it is important that the parties protect the secret key. \n", | ||
"\n", | ||
"The public key file, often called as the context file, has the public key (along with some other parameters) required to perform homomorphic operations. In HE-based aggregation, the aggregator will have only the public key context file. Since the aggregator does not have the secret key, it cannot learn anything from the ciphertexts it receives from the parties. The aggregator performs aggregation under encryption (using the public key context file).\n" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"from ibmfl.crypto.generate_store_HE_keys import generate_store_HE_keys\n", | ||
"\n", | ||
"# Path for public key context file\n", | ||
"ctx_file = os.path.join(os.getcwd(), 'Notebooks/fhe.context')\n", | ||
"# Path for secret key context file\n", | ||
"key_file = os.path.join(os.getcwd(), 'Notebooks/fhe.key')\n", | ||
"\n", | ||
"generate_store_HE_keys(path_for_public_key = ctx_file, path_for_secret_key = key_file)" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"#### 2. Specify HE Parameters\n", | ||
"The second way to generate HE keys allows the user to specify custom parameters. This is suitable for applications that may require a fine-grained control of cryptographic parameters such as the security level. \n", | ||
"\n", | ||
"IBM FL uses the *[Cheon-Kim-Kim-Song (CKKS) scheme](https://eprint.iacr.org/2016/421.pdf)* for Homomorphic Encryption. As mentioned before, HE functionalities are implemented using *[IBM HElayers software development kit (SDK)](https://github.com/IBM/helayers)*, and in particular, its *[PyHElayers](https://github.com/IBM/helayers#pyhelayers-python-package)* Python package. \n", | ||
"\n", | ||
"There are four key parameters for the CKKS HE implementation in `PyHElayers`. These parameters can be set by inputing a dictionary `HE_params` with the following keys to `generate_store_HE_keys()`:\n", | ||
"\n", | ||
"- `security_level`: indicates the strength of the encryption system. At a high level, $n$ bits of security level implies that an attacker needs roughly $2^n$ operations to break the system. The higher the security level, more secure the system is. At the same time, a higher security level incurs higher costs in terms of compute time, network bandwidth (size of encrypted model update), and secret/public key sizes. `security_level` must be a positive integer, and its default value is set to 128 bits. It is advisable to use a minimum security strength of 112 bits, see e.g., [here](https://www.ibm.com/docs/en/ds8870/7.5.0?topic=security-nist-sp-800-131a-conformance).\n", | ||
"\n", | ||
"- `multiplication_depth`: specifies the supported number of sequential multiplication operations. The `crypto_iter_average` fusion handler computes a weighted average with encrypted model parameters and plaintext weights -- this is one stage of (parallel) multiplications. Thus, it suffices to consider multiplication depth of 1. If one wants to perform more complicated operations under encryption, a higher value of `multiplication_depth` may be necessary. It is worth noting that a higher multiplication depth incurs higher costs in terms of compute time, network bandwidth, and key sizes. `multiplication_depth` must be a positive integer, and its default value is set to 1. \n", | ||
"\n", | ||
"- `integer_part_precision`: indicates the range of plaintext that can be accurately encrypted by the HE system. In particular, $\\ell$ bits of integer part precision implies that the plaintext (before and after computation) should lie between $[2^{-\\ell}, 2^{\\ell}]$. `integer_part_preceision` must be a positive integer, and its default value is set to 10 bits.\n", | ||
"\n", | ||
"- `fractional_part_precision`: indicates the precision that the HE system will preserve during computations. Specifically, $\\ell$ bits of fractional part precision implies that the precision up to $\\ell$ bits after the floating point will be preserved, i.e., the precision will be $2^{-\\ell}$. `fractional_part_precision` must be a positive integer, and its default value is set to 30 bits.\n", | ||
"\n", | ||
" - Setting higher values of integer part and fractional part precision will help reduce any loss in the accuracy of the model due to the homomorphic encryption used during aggregation. However, higher values of precision incur higher costs in terms of compute time, network bandwidth, and key sizes. \n", | ||
"\n", | ||
"- `num_slots`: (i.e., number of slots) indicates the size of a batch of plainext that will be encrypted together by the HE system. When the security level, multiplication depth, integer and fractional part precisions are fixed, the CKKS HE scheme allows only a limited range of values for the number of slots. Choosing a higher value of number of slots is likely to increase the size of ciphertext (in bytes) as well as the time taken by HE operations. `num_slots` must be a positive integer that is a power to two, and its default value is set to 2048.\n", | ||
"\n", | ||
"Completely describing the parameters of the CKKS HE crypto system is beyond the scope of this tutorial. These parameters should be chosen carefully to avoid security issue. For complete description of CKKS parameters, please refer to *[Cheon-Kim-Kim-Song (CKKS) paper](https://eprint.iacr.org/2016/421.pdf)*. If you choose parameters that are incompatible, `HELayers` will throw an error saying that the specified parameters are infeasible. " | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"Next, we will generate HE keys with custom parameters. Suppose that our application is highly privacy sensitive, and let us choose a larger value of `security level` -- 256 bits. \n", | ||
"(Note: It turns out that, for 256 bits security level, the number of slots need to be at least 4096.) " | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"from ibmfl.crypto.generate_store_HE_keys import generate_store_HE_keys\n", | ||
"\n", | ||
"# Path for public key context file\n", | ||
"ctx_file = os.path.join(os.getcwd(), 'Notebooks/fhe.context')\n", | ||
"# Path for secret key context file\n", | ||
"key_file = os.path.join(os.getcwd(), 'Notebooks/fhe.key')\n", | ||
"\n", | ||
"HE_params = {\n", | ||
" 'security_level': 256,\n", | ||
" 'integer_part_precision': 10,\n", | ||
" 'fractional_part_precision': 20,\n", | ||
" 'multiplication_depth': 1,\n", | ||
" 'num_slots': 4096 \n", | ||
"}\n", | ||
"\n", | ||
"generate_store_HE_keys(path_for_public_key = ctx_file, path_for_secret_key = key_file, HE_params = HE_params)" | ||
] | ||
} | ||
], | ||
"metadata": { | ||
"kernelspec": { | ||
"display_name": "Python 3 (ipykernel)", | ||
"language": "python", | ||
"name": "python3" | ||
}, | ||
"language_info": { | ||
"codemirror_mode": { | ||
"name": "ipython", | ||
"version": 3 | ||
}, | ||
"file_extension": ".py", | ||
"mimetype": "text/x-python", | ||
"name": "python", | ||
"nbconvert_exporter": "python", | ||
"pygments_lexer": "ipython3", | ||
"version": "3.7.9" | ||
} | ||
}, | ||
"nbformat": 4, | ||
"nbformat_minor": 4 | ||
} |
Oops, something went wrong.