@alecatalfamo/fedhomo
flwr new @alecatalfamo/fedhomoFedHomo ๐
Federated Learning with Homomorphic Encryption using Flower and TenSEAL.
This example implements the FedAvg strategy with CKKS homomorphic encryption: model weights are encrypted on the client side before being sent to the server, which aggregates them without ever seeing plaintext data.
Both MNIST and CIFAR-10 datasets are supported and can be selected via the pyproject.toml configuration.
Project Structure
fedhomo/ โโโ fedhomo/ โ โโโ init.py โ โโโ client_app.py โ โโโ client.py โ โโโ encrypted_client.py โ โโโ crypto.py โ โโโ encryption_utils.py โ โโโ dataset.py โ โโโ model.py โ โโโ server_app.py โ โโโ strategy.py โ โโโ train.py โโโ keys/ โโโ generated_keys.py โโโ pyproject.toml โโโ README.md
Requirements
Install the dependencies with:
pip install -e .
This will install Flower, TenSEAL, PyTorch and all required dependencies.
Generate Keys
Before running the example, generate the TenSEAL CKKS keys:
mkdir -p keys python generated_keys.py
This will populate the keys/ folder with the encryption context and keys used by clients and server.
Configuration
In pyproject.toml, you can configure the run:
[tool.flwr.app.config] dataset = "mnist" # or "cifar10" num-server-rounds = 3 num-clients = 2
Run with Flower (Simulation Mode)
flwr run .
Run with Flower (Deployment Mode)
- Start the SuperLink:
flower-superlink --insecure
- Start the SuperNodes:
flower-supernode --insecure --superlink 127.0.0.1:9092 \ --clientappio-api-address 0.0.0.0:9094 \ --node-config "partition-id=0 num-partitions=2" flower-supernode --insecure --superlink 127.0.0.1:9092 \ --clientappio-api-address 0.0.0.0:9095 \ --node-config "partition-id=1 num-partitions=2" ... and so on for more clients
flwr run . --run-config num-server-rounds=3
Notes
First Round Decryption Warning
During the first training round, clients may log a decryption warning or error. This is expected behavior: the server aggregates encrypted weights from scratch and the initial aggregation may produce a ciphertext that is slightly malformed before the model stabilizes. From the second round onwards the process runs cleanly.
How It Works
Key generation โ CKKS keys are generated once via generated_keys.py and stored in the keys/ folder.
Client encryption โ each client encrypts its model weights using the TenSEAL CKKS context before sending them to the server.
Server aggregation โ the server aggregates encrypted weights directly via the custom strategy HomomorphicFedAvg defined in strategy.py, without decrypting them.
Client decryption โ aggregated weights are sent back to clients, which decrypt them locally and update the model.