Secure-FL | Abstract Method Results Code Architecture Data Flow Sequence Citation GitHub ↗
Preprint · 2026

Secure-FL: Zero-Knowledge Proofs for
Dual-Verifiable Federated Learning

Krishant Timilsina  ·  Bindu Paudel  ·  Arun Kumar Timilsina
Department of Electronics and Computer Engineering, Pulchowk Campus
Code Results Cite

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.

Local SGD
→
PySNARK
delta-bound proof
→
SHA-256
param commit
→
Upload
Client pipeline (per round, per client)
Verify proofs
→
FedJSCM
aggregation
→
Circom SNARK
aggregation proof
→
Broadcast
Server pipeline (per round)
Secure-FL system architecture
Figure 1. End-to-end system architecture. Clients generate PySNARK delta-bound proofs alongside SHA-256 parameter commitments; the server verifies all proofs before aggregation and produces a Circom/SnarkJS SNARK of the FedJSCM update.

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

✓ Norm-violating attacks (blocked) Updates with ‖Δθ‖₂ > B are rejected. The attacker must commit to the actual norm in the ZKP — inflating it causes the circuit to fail.
✓ Parameter substitution (blocked) SHA-256 commitment covers the full parameter state dict. Swapping parameters after proof generation causes a hash mismatch at the server.
✓ Aggregation tampering (blocked) The server Groth16 proof binds the broadcast parameters to the accepted client updates. Clients can verify the server did not deviate from FedJSCM.
✗ Within-bound poisoning (out of scope) Adversarial updates that satisfy the norm constraint pass all checks. This is a known limitation documented in the threat model — Byzantine-robust aggregation is complementary.

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.
Overhead heatmap across datasets and rigor levels
Figure 2. Wall-clock overhead ratio (ZKP / baseline) across datasets and rigor levels.
Proof time decomposition
Figure 3. Proof time breakdown per round: client PySNARK vs. server Circom/SnarkJS.

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.
Accuracy vs rounds across conditions
Figure 4. Test accuracy over rounds: honest baseline, undefended attack (B), and ZKP defense (C).
Attack recovery summary across datasets
Figure 5. Defense recovery (%) across datasets and attacker counts. Values >100% indicate ZKP filtering improves over the honest baseline in some folds.
Accuracy under sustained gradient poisoning attack
Figure 6. Accuracy under sustained gradient poisoning: condition A (honest), B (attack, no ZKP), C (attack + ZKP defense). ZKP defense tracks the honest baseline throughout training.

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.

Limitations. Within-bound poisoning is not blocked by norm-bound ZKPs. The CIFAR-10 and MedMNIST results above are with the corrected ResNet18 architecture (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 scheduling on MNIST
Figure 7. StabilityMonitor rigor scheduling on MNIST. The monitor transitions from high to low rigor as training stabilises, reducing proof overhead.
Accuracy vs overhead scatter plot
Figure 8. Accuracy vs. time overhead across all configurations. Adaptive rigor sits closest to the ideal top-left corner (high accuracy, low overhead).

Adaptive Rigor — Overhead Reduction vs Fixed-High

Dataset Server Proof Rate at Convergence Overhead Reduction vs High
MNIST69.6%−8.2%
CIFAR-1075.1%−17.7%
MedMNIST84.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:

@misc{timilsina2026securefl, title = {Secure-FL: Zero-Knowledge Proofs for Dual-Verifiable Federated Learning}, author = {Timilsina, Krishant and Paudel, Bindu and Timilsina, Arun Kumar}, year = {2026}, url = {https://github.com/krishantt/secure-fl}, note = {Preprint} }