Zero Mission — Live network visualization · Project in testing

Zero Mission
Cryptographic Stack

Every primitive, documented.

Zero Protocol uses nine cryptographic primitives, each chosen for a specific purpose. This page documents the complete stack, wire formats, KDF labels, and key-at-rest protection schemes.

sphinx.rspq_sphinx.rscrypto.rskey_protect.rspq_kdf.rs
Primitives

Nine primitives, zero choices left to chance.

ML-KEM-768

ml-kem = "=0.3.0-pre"

NIST FIPS 203

PQ Sphinx V2 per-hop handshake (pq_sphinx.rs), HS circuit (hs_circuit.rs), client-guard 0x30/0x31 handshake

Encapsulation key (EK)1184 B
Ciphertext (CT)1088 B
Shared secret (SS)32 B
CT array (pq_cts)4 × 1088 = 4352 B
PQ V2 header total4929 B

Hybrid with X25519: attacker must break both simultaneously. Trial decapsulation fills unused slots with random CTs.

X25519

x25519-dalek = "2"

RFC 7748

Sphinx per-hop ECDH (sphinx.rs build_sphinx_packet()), HS circuit sessions (hs_circuit.rs), client-node session establishment

Key size32 B
ALPHA field32 B (ephemeral key in header)
Usagebuild_sphinx_packet() + HsSphinxCircuit
HsIdentitydh_secret (hidden_service.rs)

Alpha re-randomization: multiply by blinding scalar derived from k_blind after each hop.

ChaCha20

chacha20 = "0.9"

C03-1 fix

Sphinx BETA routing layer keystream — xor_stream() in sphinx.rs. Replaces earlier BLAKE2b-CTR (security fix C03-1).

KeyPer-packet unique ECDH output (k_enc)
NonceAll-zeros (safe: key is unique per packet)
Usagexor_stream(beta, k_enc) to peel routing layer

Key is derived per packet from ECDH shared secret, so nonce reuse is safe — each key is cryptographically unique.

XChaCha20-Poly1305

chacha20poly1305 = "0.10"

AEAD

Node private key encryption at rest (key_protect.rs), encrypted backup archives (node_ops.rs), HS client sessions (hs_client.rs)

Nonce24 B (XChaCha20 extended nonce)
Tag16 B Poly1305 MAC
Key derivationArgon2id → XChaCha20-Poly1305 (Unix)
Payload AEADkey k_pay, deterministic nonce sphinx_payload_nonce(k_pay)

C04-1 fix: payload nonce is deterministic, domain-separated — prevents nonce reuse across hops.

BLAKE2b

blake2 = "0.10"

KDF / MAC

Sphinx KDF tree (derive_hop_keys()), Sphinx MAC (compute_mac()), DHT node IDs, circuit key derivation (pq_kdf.rs)

k_enc label"zero-sphinx-v1-enc"
k_mac label"zero-sphinx-v1-mac"
k_blind label"zero-sphinx-v1-blind"
k_pay label"zero-sphinx-v1-pay"
k_reply label"zero-sphinx-v1-reply"
DHT node IDBLAKE2b-256(Ed25519 signing pubkey)
PQ routing"zero-pq-sphinx-v2-routing"
Circuit key"zero-pq-v1-ck:" prefix (pq_kdf.rs)

C04-4 fix: each label is unique and unambiguous — prevents cross-context key confusion. Native keyed mode for MAC.

Ed25519

ed25519-dalek = "2"

RFC 8032

Node advertisements (node_ads.rs), DHT node descriptors, hidden service identity (hidden_service.rs), release manifest signing

NodeAd prefixb"zero-node-ad-v2"
Release domain"zero-release-v1"
DNS signingZeroDnsRecord canonical bytes
HsIdentitysigning_key in hidden_service.rs
Persistence64 B raw: 32B seed + 32B X25519 sk

All node advertisements are self-certified. DHT storage nodes cannot forge records.

Argon2id

argon2 = "0.5"

UNIX

Unix node private key wrapping (key_protect.rs), encrypted backup archives — same derivation path

Memory (m)64 MiB
Iterations (t)3
Parallelism (p)1
Salt16 B random
Output32 B key → XChaCha20-Poly1305
File magicZKP\x01 (4B) + method 0x01 + salt + nonce + ciphertext

Plaintext legacy keys are auto-migrated on first load when ZERO_KEY_PASSPHRASE env var is set.

DPAPI

windows-sys = "0.52"

WINDOWS

IPC auth token (ipc.rs CryptProtectData/CryptUnprotectData), node private key wrapping on Windows (key_protect.rs METHOD_DPAPI=0x02)

Method byte0x02
Bound toWindows user logon key
IPC tokenTOKEN_EXPIRY_SECS=28800 (8h)
File magicZKP\x01 (4B) + method 0x02 + opaque DPAPI blob

DPAPI binds the encrypted key to the Windows user account — cannot be decrypted on another machine or as another user.

subtle (constant-time)

subtle = "2"

CT ops

IPC token comparison, reply MAC verification (sphinx.rs verify_reply_mac()), binary hash comparison in release_manager.rs

verify_reply_mac()Constant-time BLAKE2b comparison
IPC tokenct_eq() comparison to prevent timing attacks
Release hashBinary SHA-256 comparison

All security-sensitive comparisons use subtle to prevent timing side-channel attacks.

KDF Labels — derive_hop_keys()

BLAKE2b KDF tree labels.

Five independent 32-byte keys derived per hop from the shared ECDH secret. Unambiguous labels prevent cross-context key confusion (C04-4 fix).

Sphinx V1 (sphinx.rs)
zero-sphinx-v1-enck_encChaCha20 BETA routing layer keystream
zero-sphinx-v1-mack_macBLAKE2b keyed header MAC (gamma field)
zero-sphinx-v1-blindk_blindAlpha re-randomization scalar
zero-sphinx-v1-payk_payPayload XChaCha20-Poly1305 AEAD key
zero-sphinx-v1-replyk_replyMSG_SPHINX_REPLY authentication key
PQ Sphinx V2 (pq_sphinx.rs, pq_kdf.rs)
zero-pq-sphinx-v2-routingPQ hybrid routing secret (pq_sphinx.rs)
zero-pq-v1-ck:Circuit key derivation (pq_kdf.rs) — prefix || ss_x || ss_pq
zero-pq-sphinx-v2-*Per-hop keys in PQ Sphinx V2 (same structure as V1)
Wire Formats

Sphinx packet layouts.

V1 Sphinx (sphinx.rs)

SPHINX_LEN=1600 B
OffsetSizeFieldDescription
032 BalphaEphemeral X25519 public key
3232 BgammaHeader MAC — BLAKE2b keyed with k_mac over alpha‖beta
64512 BbetaRouting layers — 4 hops × 64 B/slot (32B addr + 32B MAC)
5761024 BpayloadEncrypted payload — XChaCha20-Poly1305 per hop

ALPHA(32) + GAMMA(32) + BETA(512) + PAYLOAD(1024) = 1600 B — fits single Ethernet frame, avoids fragmentation

V2 PQ Sphinx (pq_sphinx.rs)

HEADER=4929 B
OffsetSizeFieldDescription
01versionPQ_SPHINX_VERSION_V2 = 0x02
132alphaX25519 ephemeral key
3332gammaHeader MAC
65512betaRouting layers (same structure as V1)
5774352pq_ctsML-KEM-768 ciphertexts: 4 × 1088 B (real + random fill)
4929varpayloadEncrypted payload

PQ_CT_ARRAY_LEN = 4×1088 = 4352 B. Unused slots filled with random CTs for indistinguishability.

key_protect.rs

Key protection on disk.

Node private keys are never stored in plaintext. Two methods are available — one per platform.

method 0x01Unix

Argon2id + XChaCha20-Poly1305

[4B magic "ZKP\x01"][1B method=0x01][16B salt][24B nonce][ciphertext+16B tag]
method 0x02Windows

DPAPI

[4B magic "ZKP\x01"][1B method=0x02][opaque DPAPI blob]

Auto-migration: Plaintext legacy keys are automatically encrypted on first load when ZERO_KEY_PASSPHRASE (Unix) or DPAPI (Windows) is available.

replay.rs

Replay protection.

WINDOW_SIZE65,536
Data structureHashSet<[u8;24]> + VecDeque (FIFO)
Lifetime at L365536 / 25 pkt/s = 43.7 min
Memory per window~4 MB
Persistencereplay_window_<port>.bin
CoveragePer-circuit + global both enforced