GarudaNet is a host-side Rust reference implementation of
EPIC-PQ-WSN-2026-DD01: a post-quantum protected wireless-sensor network with
pairwise-masked secure aggregation and a hash-based accumulator.
| Design area | Implementation |
|---|---|
| Ascon data plane (§4, §6) | Ascon-AEAD128 frames, header-bound associated data, structured nonces, direction-separated session keys, 64-frame replay windows for the current and previous epochs |
| PQ identity and join (§5, §7) | PA-signed device-certificate policy, revocation/role/epoch checks, ML-KEM-512 adapter, ML-DSA-44 (sensor) / ML-DSA-65 (PA/gateway) identity adapter, full transcript binding, mutual confirmation, labelled key derivation |
| Fragmentation (§6.3) | 64-byte fragments, out-of-order reassembly, duplicate/conflict checks, object-level Ascon-Hash256 validation |
| MPC aggregation (§8) | Pairwise and self masking, 32-bit modular vectors, Shamir GF(2^8) sharing, signed survivor roster, fail-closed threshold, complete dropout-edge enforcement, range-check and clip utilities |
| Accumulator (§9) | Domain-separated Merkle tree, chained epoch digest, membership witnesses, adjacency-based non-membership witnesses |
| Aggregator/GW (§10) | Epoch state machine, signed attestation, gateway membership/threshold/dimension/replay policy |
| Persistence (§10.2) | Hardware-authenticated hash-chain journal, disruption-safe A/B slots, monotonic epoch/version floors, boot recovery proofs, and verified reset key erasure |
| Embedded core | Independent allocation-free no_std crate with fixed-capacity frames, replay state, TRNG health tests, opaque protected-key handles, and Zephyr/RIOT adapter contracts |
| Revocation & rejoin | Epoch-scoped revocation list distribution, max CRL size, offline-sensor policy, make-before-break rekey wired to management message profile (ManagementPayload) |
| Threat model | Documented in security/threat-model.md — assets (A1–A12), adversaries (ADV-1–ADV-6), explicit non-goals (NG-1–NG-6), and claim→assumption mapping |
| Fuzz testing | Structure-aware fuzz targets: frame open, join decode, fragment reassembly, journal recover, gateway verify; property test for "AEAD fail ⇒ no replay commit" |
The default parameter profile is n=32, t=22, d=4, R=2^32, a
300-second epoch, and a 1024-epoch rekey interval. Configuration validation
enforces 16 <= n <= 64, 2t > n, d <= 8, quantisation overflow safety,
and the design's epoch/rekey bounds.
cargo fmt --check
cargo test --all-features --offline
cargo clippy --all-targets --all-features --offline -- -D warnings
cargo run --release --offline
cargo test -p garudanet-core --all-features --offline
cargo check -p garudanet-core --all-features --offlineThe demo executes a real ML-KEM-512 round trip and ML-DSA-44 signed aggregate, then verifies the accumulator chain at the gateway boundary. PA and gateway identities now use ML-DSA-65 (NIST SL-3) while sensors remain at ML-DSA-44 (SL-2) to conserve energy and code size.
The join demo executes serialized M1-M4 messages with PA-signed ML-DSA-65
credentials, ephemeral ML-KEM, transcript signatures, Ascon key confirmation,
downgrade/revocation checks, and make-before-break rekeying. Standard revisions,
dependency versions, pending-errata policy, test-vector provenance, and
production-binding parameters are recorded in security/crypto-provenance.toml.
The focused example models two sensor nodes and a gateway. For this small topology the gateway co-locates the aggregator and accumulator roles. Each node executes the certificate-authenticated ML-KEM-512 join, encrypts its masked reading in an Ascon-AEAD128 frame, and sends it to the gateway. The gateway rejects tampering and replay, reconstructs the threshold masks, verifies the ML-DSA-44 attestation and both Merkle witnesses, and releases only the aggregate.
cargo run --release --offline --example two_node_gatewayExpected aggregate for node readings [21, 55] and [24, 60]:
gateway released aggregate: [45, 115]
src/persistence.rs authenticates every record with a hardware-held keyed hash
over the preceding tag, so deletion, reordering, and rewriting fail recovery.
Durable state alternates between authenticated A/B slots. Boot selects the
newest valid generation only when its epoch, firmware, and configuration are
consistent with hardware monotonic floors; it then erases volatile epoch keys
and emits a keyed recovery proof bound to the secure-boot measurement.
SignedUpdateManifest binds component, image digest, firmware/configuration
versions, and required boot measurement under the provisioning verifier. It
rejects unauthorized images and rollback before a bootloader performs staged,
disruption-safe installation. This is an RFC 9019/SUIT architecture boundary,
not a replacement for MCUboot, TF-M, or a vendor ROM secure-boot implementation.
The allocation-free core and RTOS/pqm4 measurement procedure are documented in
embedded/README.md. Run scripts/run-pqm4.sh with a pinned PQM4_ROOT and a
real Cortex-M4 board to collect functional, test-vector, cycle, stack, and
code-size evidence.
| Document | Location |
|---|---|
| Threat model | security/threat-model.md |
| Crypto provenance & production binding | security/crypto-provenance.toml |
| Hardware RoT evidence pack | security/hardware-rot-evidence.md |
| Operational limits | security/operational-limits.md |
| Formal/symbolic analysis plan | security/formal-analysis.md |
| Side-channel baseline | security/side-channel-baseline.md |
| External review checklist | security/external-review-checklist.md |
| Scalability analysis | security/scalability-analysis.md |
| Fuzz targets (5) | fuzz/fuzz_targets/ |
The repository now provides hardware-facing traits, RTOS adapter contracts, and a reproducible pqm4 harness, but does not claim that host tests constitute real secure-element, TrustZone, MCUboot, radio, or physical energy evidence. The RustCrypto ML-KEM/ML-DSA crates are useful for interoperable host validation but are not independently audited; embedded deployments should bind the same protocol interfaces to audited pqm4/PQClean or an HSM and execute the WP6 validation programme.