Abstract
Federated learning enables collaborative model training without sharing raw data, but malicious clients can submit poisoned gradient updates that corrupt the global model while remaining undetected. We present Secure-FL, a dual-verifiable framework that applies zero-knowledge proofs at both the client and server levels to enforce training integrity without sacrificing data privacy.
Each client proves their parameter update satisfies an L2 norm bound using a Groth16 circuit (PySNARK); the server proves correct FedJSCM momentum aggregation using a Circom/SnarkJS SNARK. A StabilityMonitor adapts proof complexity at runtime, reducing overhead without sacrificing security guarantees.
Across MNIST, CIFAR-10, and MedMNIST, Secure-FL recovers >99.8% of accuracy degradation from gradient-poisoning attacks with 1.39–1.46× wall-clock overhead under high-rigor ZKP, and 1.20–1.28× with adaptive rigor scheduling — a 8–18% reduction at convergence.
Method
Dual-Layer Verification Architecture
Secure-FL places a cryptographic proof at each stage of the federated learning loop. Neither clients nor the server can silently deviate from the agreed protocol.
delta-bound proof
param commit
aggregation
aggregation proof
Client-Side: PySNARK Delta-Bound Circuit
The client runs a Groth16 circuit that asserts ‖Δθ‖₂ ≤ B over a sampled subset of learnable parameters (200–2000 depending on rigor level). The bound B is set server-side as scale × √nlearnable, calibrated per architecture. An SHA-256 hash of the full parameter state dict (weights + BN buffers) is committed alongside the proof, preventing silent parameter substitution.
Server-Side: Circom/SnarkJS Aggregation SNARK
The server generates a Groth16 proof of correct FedJSCM aggregation over a 200-element sampled projection of model parameters each round (FedJSCMAggregation(10, 200) — 10 client slots, 200 parameters). The circuit enforces: (1) active-client flags are binary; (2) inactive slots contribute zero; (3) the weighted average and momentum update are computed correctly. The proving key is generated once from a public Powers-of-Tau (pot13) file and reused across all rounds.
FedJSCM Aggregation
The aggregation rule applies server-side momentum to smooth the global update:
mt+1 = γ·mt + (1−γ)·Δ̄ wt+1 = wt + η·mt+1
where Δ̄ is the weighted average of accepted client deltas. Momentum is reinitialized automatically on architecture changes.
Adaptive Rigor Scheduling
The StabilityMonitor tracks a composite stability score (weighted over parameter variance, loss smoothness, gradient norms, and convergence speed) and switches the proof rigor level at each round. High rigor (2000 sampled params) is used early in training; the monitor relaxes to low (200 params) once the score exceeds 0.90, reducing proof time without changing the security guarantee on the accepted updates.
Threat Model
Results
Accuracy & Time Overhead
5-fold cross-validation, 20 clients, 5 clients per round, 15 rounds. ZKP high = 2000 sampled params; ZKP adaptive = StabilityMonitor-scheduled.
| Dataset | Baseline Acc | ZKP High Acc | Δ Acc | High Overhead | Adaptive Overhead |
|---|---|---|---|---|---|
| MNIST | 98.98% | 98.92% | −0.06 pp | 1.39× | 1.28× |
| CIFAR-10 | 83.86% | 84.38% | +0.52 pp | 1.46× | 1.20× |
| MedMNIST | 94.68% | 95.00% | +0.32 pp | 1.38× | 1.26× |
| Synthetic (small) | 23.99% | — | — | 11.78× | 5.99× |
| † Synthetic small model (~8.7K params) has a disproportionate overhead because the ZKP sample is a large fraction of the total parameter count. Real models (MNIST CNN, ResNet18) show 1.3–1.5× overhead. | |||||
Attack Resilience (Gradient Poisoning)
Attackers submit reversed, scaled gradient updates (120× scale factor, norm ≫ B). Recovery is measured as percentage of attack-induced accuracy loss recovered by ZKP defense.
| Dataset | Honest (A) | No ZKP (B) | ZKP Defense (C) | Attack Impact | Recovery |
|---|---|---|---|---|---|
| MNIST (m=1) | 98.98% | 40.22% | 99.00% | −58.76 pp | 100.0% |
| MNIST (m=2) | 98.98% | 23.54% | 98.80% | −75.44 pp | 99.8% |
| CIFAR-10 (m=1) | 83.86% | 10.00% | 85.60% | −73.86 pp | 102.1% |
| CIFAR-10 (m=2) | 83.86% | 10.00% | 84.52% | −73.86 pp | 101.0% |
| MedMNIST (m=1) | 94.68% | 10.94% | 95.24% | −83.74 pp | 100.6% |
| MedMNIST (m=2) | 94.68% | 10.34% | 95.14% | −84.34 pp | 100.5% |
| m = number of malicious clients (out of 5 sampled per round). Recovery >100% occurs because ZKP filtering improves over the honest baseline in some folds. | |||||
Within-Bound Attacks (Known Limitation)
Adversaries who constrain their update to ‖Δθ‖₂ < B pass all ZKP checks. On MNIST the accuracy degradation is marginal (−0.9 to −1.8 pp). On CIFAR-10 and MedMNIST, within-bound adversarial direction causes severe degradation — this is outside the cryptographic security guarantee and is the subject of ongoing work.
small_input=True); a full rerun with 50 clients is pending. Synthetic-small results are uninformative due to the model's low baseline accuracy.
Adaptive Rigor — Overhead Reduction vs Fixed-High
| Dataset | Server Proof Rate at Convergence | Overhead Reduction vs High |
|---|---|---|
| MNIST | 69.6% | −8.2% |
| CIFAR-10 | 75.1% | −17.7% |
| MedMNIST | 84.7% | −8.9% |
| Server proof rate = fraction of rounds where StabilityMonitor scheduled a server-side SNARK proof. Lower rate → monitor detected convergence and reduced overhead. | ||
Code & Reproducibility
Interactive architecture map →, data flow, round sequence — client proofs, gRPC transport, verification and FedJSCM aggregation, all generated from the repository source. Proofs, aggregation and the stability heuristic run in a single Rust core; rounds are served by the standalone Rust server.
Installation
# Clone and install with uv git clone https://github.com/krishantt/secure-fl cd secure-fl uv sync --all-extras # Install ZKP toolchain (Rust + Circom + SnarkJS) make setup-zkp
Run the benchmark
# Full paper benchmark — all datasets, 5-fold, real ZKP proofs uv run python experiments/full_benchmark.py \ --datasets mnist cifar10 medmnist \ --k-folds 5 --num-clients 20 --clients-per-round 5 \ --require-real-proofs --force # Quick smoke test (2 rounds, 2 clients, 2 folds) uv run python experiments/full_benchmark.py --quick
Interactive attack defense demo
# TUI showing real-time ZKP attack detection uv run python demo/simulate_attack.py --dataset mnist uv run python demo/simulate_attack.py --dataset cifar10 --malicious 2
Python API
from secure_fl.federation.client_runtime import create_client from secure_fl.federation.server import create_server_strategy from secure_fl.models.factory import model_fn # Create a ZKP-enabled client client = create_client( client_id="client_1", model_fn=model_fn("mnist"), train_data=train_dataset, enable_zkp=True, proof_rigor="adaptive", ) # Create server strategy with FedJSCM + ZKP strategy = create_server_strategy( model_fn=model_fn("mnist"), enable_zkp=True, proof_rigor="adaptive", )
Citation
If you use Secure-FL in your work, please cite: