Metadata-Version: 2.4
Name: uvfl
Version: 0.2.0
Summary: Secure Vertical Federated Learning: ADP + Selective HE + ZKP, with a pluggable threat-detection / audit engine.
Author-email: MD Imran Ahmed <you@example.com>
Maintainer-email: MD Imran Ahmed <you@example.com>
License: MIT
Project-URL: Homepage, https://github.com/your-username/uvfl
Project-URL: Repository, https://github.com/your-username/uvfl
Project-URL: Issues, https://github.com/your-username/uvfl/issues
Keywords: federated-learning,vertical-federated-learning,differential-privacy,homomorphic-encryption,zero-knowledge-proof,privacy,security
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Science/Research
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Classifier: Topic :: Security :: Cryptography
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: numpy>=1.24
Requires-Dist: PyYAML>=6.0
Provides-Extra: he
Requires-Dist: tenseal>=0.3.14; extra == "he"
Provides-Extra: examples
Requires-Dist: pandas>=1.5; extra == "examples"
Requires-Dist: scikit-learn>=1.2; extra == "examples"
Requires-Dist: matplotlib>=3.6; extra == "examples"
Requires-Dist: ucimlrepo>=0.0.7; extra == "examples"
Provides-Extra: dev
Requires-Dist: pytest>=7; extra == "dev"
Requires-Dist: build>=1.0; extra == "dev"
Requires-Dist: twine>=4.0; extra == "dev"
Provides-Extra: all
Requires-Dist: tenseal>=0.3.14; extra == "all"
Requires-Dist: pandas>=1.5; extra == "all"
Requires-Dist: scikit-learn>=1.2; extra == "all"
Requires-Dist: matplotlib>=3.6; extra == "all"
Requires-Dist: ucimlrepo>=0.0.7; extra == "all"
Dynamic: license-file

# U-VFL — runnable reference implementation

A clean, reproducible implementation of the **U-VFL** framework from the paper
*"U-VFL: A Unified Framework for Secure Vertical Federated Learning with Adaptive
Privacy and Verifiable Computation"* (Ahmed et al., ICONIP 2026), so it can be
**installed and tested on any machine** against the real UCI Heart Disease
dataset — or any clinical CSV you supply.

It implements the three security modules over a two-party Vertical FL (SplitNN):

- **ADP** — Adaptive Differential Privacy (decaying privacy budget)
- **SHE** — Sensitivity-driven Selective Homomorphic Encryption (**real CKKS** via TenSEAL)
- **ZKP** — a verifiable-integrity check that rejects tampered gradients

---

## Install

```bash
pip install uvfl            # core (numpy-only knobs)
pip install "uvfl[all]"     # + real CKKS HE + the high-level helpers
```

## 60-second usage

**Low-level — drop the three knobs into your own training loop:**
```python
import uvfl, numpy as np
tri = uvfl.Trilemma(uvfl.ADP(epsilon_max=5), uvfl.SHE(high_risk_fraction=0.3), uvfl.ZKP())
payload = tri.protect(gradient, round_t=t, total_rounds=T)   # privacy+encrypt+commit
gradient, integrity_ok = tri.open(payload)                   # verify + recover
```

**High-level — fully-secured VFL in one call:**
```python
model = uvfl.fit("data.csv", target="diagnosis")     # ADP+SHE+ZKP applied automatically
print(model.report())
best  = uvfl.autotune("data.csv", target="diagnosis")  # search configs, keep best by F1
```

**Distributed (2 medical sites + 1 master), data never leaves a site:**
```python
# site 1 VM:          uvfl.serve_party("siteA.csv", port=8001)
# site 2 VM (labels): uvfl.serve_party("siteB.csv", port=8001, target="diagnosis")
# master VM:
model = uvfl.train_federated(["http://SITE1_IP:8001", "http://SITE2_IP:8001"])
```

Empirical proof suite: `uvfl.validate("data.csv", target="diagnosis")`. See
`VALIDATION.md`, `DISTRIBUTED.md`, `ROADMAP.md`.

---

## ⚠️ Please read first — what this is and isn't

This is an **independent, clean-room re-implementation built from the paper's
equations** — it is *not* the authors' original experiment code. Consequently:

- **Absolute numbers will differ from the paper** (different seed, data curation,
  optimiser, and the fact that the math describes a SplitNN while the paper also
  mentions XGBoost). The code reproduces the *mechanisms and the qualitative
  story*, not the exact 0.85/0.83 figures.
- **HE is real.** Encryption uses CKKS (Microsoft SEAL via TenSEAL) when
  installed. The selective-vs-full speedup is **measured**, not assumed.
- **ZKP is an honest stand-in, not a zk-SNARK.** It uses a hash commitment +
  Fiat–Shamir challenge to *demonstrate the property* (a tampered/malicious
  gradient is rejected, soundness ≈ `1 − 2^−κ`). A deployment would use
  Groth16/PLONK over the gradient circuit. The paper itself notes "ZKP lacks
  concrete implementation benchmarks", so this matches its scope.
- **Two honest discrepancies we found vs. the paper**, worth discussing:
  1. With CKKS *slot-packing*, a small gradient fits in one ciphertext whether
     full or selective, giving **no** speedup. Selective HE only helps when the
     parameter count exceeds slot capacity (per-component encryption). We
     therefore encrypt **per-component**, where the measured speedup is
     `≈ 1 / high_risk_fraction` (≈ 3.3× at 30%). This is internally more
     coherent than the paper's headline (which states *both* 8.5× and 20–34×).
  2. The methodology describes SplitNN gradient exchange; "XGBoost" is mentioned
     once in limitations. We implement the SplitNN that the equations describe.

Nothing here is tuned to force the paper's numbers — results are whatever the
seeded run produces.

---

## 1. Setup (pick one)

**Requires Python 3.9–3.12.** CPU only — no GPU, no PyTorch.

### Option A — venv + pip (works everywhere)
```bash
cd uvfl
python3 -m venv .venv && source .venv/bin/activate     # Windows: .venv\Scripts\activate
pip install -r requirements.txt
pip install -r requirements-he.txt        # optional: real CKKS HE (recommended)
```

### Option B — conda
```bash
cd uvfl
conda env create -f environment.yml
conda activate uvfl
pip install -r requirements-he.txt         # optional: real CKKS HE
```

### Option C — make
```bash
cd uvfl
make setup        # core deps
make setup-he     # + real HE (optional)
```

> If TenSEAL will not install on your platform, **skip `requirements-he.txt`** —
> the SHE module falls back to a clearly-labelled cost simulation and everything
> still runs.

---

## 2. Run it

```bash
# Real UCI Heart Disease (auto-downloads via ucimlrepo -> UCI URL -> mirror)
python run.py

# YOUR OWN real-life dataset (a CSV with a label column)
python run.py --data /path/to/your_clinical_data.csv --target outcome

# Offline smoke test (synthetic data, no internet)
python run.py --synthetic

# Faster / narrower sweeps
python run.py --epochs 40 --scenarios S1 S5 --noise 0.5 1.0
make run            # == python run.py
make run-synthetic  # == python run.py --synthetic
```

A full run takes well under a minute on a laptop.

### Outputs (in `outputs/`)
- `results.csv` — every scenario × noise level: accuracy, precision, recall, F1, F2, timings
- `results.json` — same, plus the efficiency table and ZKP soundness demo
- `fig_accuracy_f1_vs_noise.png`, `fig_pareto.png`, `fig_comparative_bar.png`, `fig_confusion_matrices.png`

---

## 2b. Distributed deployment (the real 3-VM setup) + proving it works

The single-process run above validates the *algorithm*. There is also a **real
distributed implementation** — two data parties + a master/aggregation server,
talking over HTTP — that maps onto a 3-VM deployment (two feature VMs + one
master VM). No extra dependencies (stdlib transport).

```bash
# simulate all 3 nodes on one machine
python -m uvfl.distributed.run_local --data heart.csv              # clean run
python -m uvfl.distributed.run_local --data heart.csv --byzantine-mitm 0.5  # integrity test

# run the full PROOF suite (writes outputs/VALIDATION_REPORT.md)
python -m uvfl.distributed.validate  --data heart.csv
```

The validation suite empirically proves all five claims (correctness, ADP
privacy, SHE confidentiality, ZKP integrity, efficiency). See **`VALIDATION.md`**
for the methodology, **`DISTRIBUTED.md`** to deploy on the actual VMs, and
**`ROADMAP.md`** for next steps. In the distributed system, raw features never
leave a party VM, labels never leave the master, and high-risk gradient
components are CKKS-encrypted with each party's public key (only that party can
decrypt).

---

## 3. Testing on a real-life dataset

Point `--data` at any CSV and name the label with `--target`:

```bash
python run.py --data hospital_data.csv --target disease
```

- If the CSV has the standard UCI heart columns, it uses the **paper's clinical
  vertical split** (Client A = primary-care features, Client B = cardiac-centre
  features + label).
- Otherwise it **auto-splits features by index** into the two parties and warns.
- Set the exact split, missing-value handling, target binarisation, etc. in
  `config.yaml` under `data:`.

---

## 4. Scenarios (paper's S1/S2/S3/S5)

| ID | Name                | Security on the exchanged gradient            |
|----|---------------------|-----------------------------------------------|
| S1 | No Security         | plaintext (baseline utility)                  |
| S2 | Full HE             | encrypt **all** ∇W_A components (overhead ref) |
| S3 | Fixed DP            | constant high noise, no schedule              |
| S5 | **U-VFL (ours)**    | Adaptive DP + Selective HE + ZKP              |

`noise_level ∈ [0,1]` scales injected DP noise (the paper's 10%–100% grid);
`1.0` = the full configured schedule. S1/S2 do not use DP, so they are
noise-independent (trained once, drawn flat across the grid).

---

## 5. Paper → code map

| Paper                                   | File                  | Notes |
|-----------------------------------------|-----------------------|-------|
| Two-party SplitNN, gradient exchange    | `uvfl/model.py`       | pure NumPy + Adam |
| ADP eqs (1)–(5): `ε_t`, `σ_t`, clipping | `uvfl/adp.py`         | `AdaptiveDP` |
| Fixed DP baseline                       | `uvfl/adp.py`         | `FixedDP` |
| SHE eqs (6)–(11): sensitivity, selection| `uvfl/she.py`         | real CKKS; per-component |
| ZKP prove/verify, soundness             | `uvfl/zkp.py`         | commitment + Fiat–Shamir stand-in |
| Scenarios, security stack               | `uvfl/scenarios.py`   | S1/S2/S3/S5 |
| Metrics, confusion matrices             | `uvfl/metrics.py`     | sklearn |
| Experiment loop, efficiency table       | `uvfl/experiment.py`  | one-time HE benchmark |
| Figures                                 | `uvfl/plots.py`       | matplotlib |
| **Distributed party node (per VM)**     | `uvfl/distributed/party.py`  | bottom model + HE secret key |
| **Master / aggregation node**           | `uvfl/distributed/master.py` | top model + security enforcement |
| **3-VM simulator (localhost)**          | `uvfl/distributed/run_local.py` | start all nodes locally |
| **Proof / validation suite**            | `uvfl/distributed/validate.py`  | the five empirical proofs |
| Proof methodology / VM deploy / roadmap | `VALIDATION.md`, `DISTRIBUTED.md`, `ROADMAP.md` | |

---

## 6. Reproducibility

- Single global `seed` (default 42) in `config.yaml` controls data split, weight
  init, DP noise, and the ZKP demo. Re-running gives identical numbers.
- HE cost is hardware-dependent; the **speedup ratio** (full / selective) is the
  stable, portable quantity.

## 7. Example run (UCI heart.csv mirror, seed 42 — yours will differ)

```
S1  acc~0.738 f1~0.765         (no security)
S2  acc~0.738 f1~0.765         (Full HE, exact -> same utility)
S3  acc~0.770 f1~0.794         (Fixed DP)
S5  acc~0.754 f1~0.783         (U-VFL: ADP+SHE+ZKP)
HE/round: full=633ms  selective=190ms  ->  3.33x speedup (real CKKS)
ZKP soundness: 200/200 honest accepted, 200/200 tampered rejected
```

Takeaway demonstrated on real data: **full cryptographic + privacy protection
keeps accuracy within ~2% of the unsecured baseline**, selective HE is **~3.3×
cheaper** than full HE, and the integrity check **rejects 100%** of tampered
gradients.

## 8. Data & license

UCI Heart Disease (Cleveland) — Janosi, Steinbrunn, Pfisterer, Detrano (1988),
UCI ML Repository (id 45). The dataset is downloaded at runtime and **not
redistributed** here. Code is provided for academic reproducibility.
