Transport Security
Complete technical documentation of Ekko's cryptographic architecture, transport-level security, and attack surface analysis.
Version 1.0 · March 2026
Overview
Ekko is a censorship-resistant messaging application that delivers messages through multiple independent transport channels. All transports share a common application-level encryption layer.
Transport Priority (automatic fallback)
Messages are encrypted once at the application layer before being handed to any transport.
Core Cryptographic Primitives
All cryptographic operations are implemented in Rust using audited crates. No custom cryptography.
Key Types
Identity
Ed25519
Lifetime: Device lifetime
Purpose: Signing & authentication
32-byte secret + 32-byte public
Exchange
X25519
Lifetime: Device lifetime
Purpose: Static key agreement
32-byte secret + 32-byte public
Ephemeral
X25519
Lifetime: Single message
Purpose: Forward secrecy
32-byte secret + 32-byte public
Algorithms
Encryption
ChaCha20-Poly1305
256-bit key, 96-bit nonce
Key Agreement
X25519 ECDH
32-byte shared secret
Key Derivation
HKDF-SHA256
RFC 5869
Signatures
Ed25519
64-byte deterministic
Fingerprints
BLAKE2b-256
128 bits displayed
Memory Cleanup
Zeroize
ZeroizeOnDrop trait
Rust Crate Dependencies
Message Encryption Pipeline
Every message, regardless of transport, passes through this pipeline.
Encryption (Sender)
Plaintext Message
content_type, content, filename, metadata
Generate Message ID
16 random bytes from OS CSPRNG
Generate Ephemeral X25519 Keypair
Fresh keypair created — destroyed after use
ECDH Key Agreement
DH(ephemeral_secret, recipient_public) → 32-byte shared secret
HKDF-SHA256 Key Derivation
salt=message_id, info="DeadDrop-v1-message-key" → 32-byte key
ChaCha20-Poly1305 Encrypt
random 12-byte nonce, AAD=message_id → ciphertext + 16-byte auth tag
Ed25519 Sign
Sign(identity_secret, message_id || ciphertext) → 64-byte signature
Encrypted Message
message_id + ephemeral_pub + nonce + ciphertext + timestamp + signature
Decryption (Recipient)
Encrypted Message Received
From any transport (BLE, DHT, Tor, iroh)
Verify Ed25519 Signature
Verify(sender_public, message_id || ciphertext, signature) — reject if invalid
ECDH Key Recovery
DH(recipient_secret, ephemeral_public) → same 32-byte shared secret
HKDF-SHA256 Key Derivation
Same salt + info → same 32-byte encryption key
ChaCha20-Poly1305 Decrypt
Verify auth tag, decrypt ciphertext → reject if tag fails
Plaintext Message
Original content recovered and stored locally
Forward Secrecy
Each message generates a fresh ephemeral key. After the DH operation, the ephemeral secret is consumed by Rust's ownership system and zeroized. Past ciphertexts cannot be recovered.
Limitation
No Double Ratchet — each message is independently encrypted. If the recipient's exchange key is compromised before decryption, in-transit messages are vulnerable.
BLE (Bluetooth Low Energy)
Direct device-to-device messaging within ~10m. No network infrastructure required.
Encryption Layers
Transport Layer
Session encryption, mutual authentication
Application Layer
Per-message encryption & signing
Noise XX Handshake
32 bytes, unencrypted
80 bytes, partially encrypted with DH(e,e)
48 bytes, fully encrypted
Message Exchange Protocol
After Noise handshake, an application-level exchange runs over the encrypted channel:
MsgCount
Announce queued messages
MsgData
Transmit encrypted messages
MsgAck
Per-message acknowledgment
Complete
Signal exchange done
Security Risks
BLE Range Limitation
Low~10m range limits interception to physical proximity
BLE Advertising Metadata
LowRotating IDs derived via HKDF prevent device tracking
Relay Attack (MITM)
LowNoise XX provides mutual authentication — MITM requires real-time key substitution
Radio Jamming / DoS
MediumRadio-level jamming can prevent BLE communication; no mitigation possible at protocol level
DHT (Distributed Hash Table)
Messages encrypted and published to the public BitTorrent Mainline DHT as BEP44 mutable items.
How DHT Delivery Works
BitTorrent Mainline DHT
Thousands of independent nodes worldwide
Slots 0-100 · BEP44 mutable items
Key Derivation Chain
Slot Enumeration
MediumObservers can correlate slots 0-100 to a single recipient by access patterns
Volume Analysis
MediumNumber of occupied slots reveals approximate message count
IP Address Exposure
MediumDHT participation reveals the device's IP address to DHT peers
Timing Correlation
MediumPublish/fetch timing can correlate sender and recipient
No Confidentiality at Rest
LowMitigated by application-level encryption; DHT nodes see only ciphertext
Stale Message Replay
Low48h TTL, message ID dedup, and BEP44 sequence numbers prevent replay
Tor P2P (Onion-Routed Peer-to-Peer)
Devices create Tor v3 onion services and establish direct WebSocket connections through the Tor network.
Encryption Layers (3 deep)
Network Layer
Anonymity, circuit encryption
Transport Layer
Message framing
Application Layer
Per-message encryption & signing
No exit nodes used. All connections are .onion-to-.onion, remaining entirely within the Tor network.
Connection Protocol
Routes through Tor to .onion:80
HTTP 101 Switching Protocols
32-byte public key
Server sends own public key
32-byte random nonce
Echo nonce back
Contact verified
Platform Implementation
iOS
Tor.framework
ADD_ONION via control port
SOCKS5 :9050
macOS
Tor.framework
ADD_ONION via control port
SOCKS5 :9050
Android
tor_hidden_service
Automatic
SOCKS5 :9050
DHT Rendezvous Metadata
MediumDHT queries for .onion addresses are not anonymous; DHT peers see the lookup
Timing Correlation
MediumMessage timing patterns visible to ISP-level observers watching both endpoints
Message Size Analysis
LowNo padding; file transfer sizes are observable at the network level
Tor Circuit Compromise
LowRequires control of both guard and rendezvous point; v3 onion services mitigate
iroh (QUIC-Based P2P)
QUIC-based P2P from n0.computer with NAT traversal and UDP hole-punching. Custom ALPN protocol deaddrop/msg/v1.
Double Encryption
Transport Layer
Transport confidentiality via iroh
Application Layer
Per-message encryption & signing
What the Relay Server Can See
Message content
Double-encrypted — app layer + QUIC
Message metadata
Timestamps and sizes
Connection patterns
EndpointIds reveal who contacts whom
IP addresses
Both peers' IPs visible
Message frequency
Timing patterns observable
Message decryption
Even if QUIC is broken, app-layer protects
Relay Metadata Visibility
Mediumn0 relay sees connection patterns and IP addresses of both peers
IP Address Exposure
MediumBoth peers' IPs visible to relay; no anonymity layer
DHT Endpoint Visibility
LowPublished EndpointIds are publicly queryable on the DHT
Message Size Analysis
LowPacket sizes visible to relay and network observers
BLE Gossip (Proximity Relay)
After standard BLE exchange, devices relay encrypted messages for third-party recipients using the existing Noise-encrypted channel. Relays can't read or identify recipients.
50 MB max, 48-hour TTL
Probabilistic via bloom filter digests
None — relay sees only encrypted blobs
4-byte length prefix + 500-byte chunks
Comparative Security Matrix
Side-by-side comparison of security properties across all four transport layers.
Bluetooth (BLE)
Encryption
ChaCha20-Poly1305 (2 layers: Noise + app)
Forward Secrecy
Per-session (Noise) + per-message (ECDH)
Anonymity
Physical proximity required
mediumDHT Network
Encryption
ChaCha20-Poly1305 (app layer only)
Forward Secrecy
Per-message ephemeral ECDH
Anonymity
IP visible to DHT peers
lowTor P2P
Encryption
ChaCha20-Poly1305 + Tor circuit encryption
Forward Secrecy
Per-message (ECDH) + per-circuit (Tor DH)
Anonymity
Strong — .onion-to-.onion, 3-hop
highiroh (QUIC)
Encryption
ChaCha20-Poly1305 (2 layers: TLS 1.3 + app)
Forward Secrecy
Per-message (ECDH) + per-connection (TLS 1.3)
Anonymity
IP visible to relay server
lowAttack Surface Analysis
Compromised Recipient Exchange Key
Attacker obtains the recipient's long-term X25519 exchange secret.
Requires physical proximity (~10m) to intercept radio signals
Messages persist on public DHT for 48 hours — attacker can fetch and decrypt
Must intercept in real-time; Tor anonymity makes targeting difficult
Must intercept in real-time via relay or network position
Compromised Sender Identity Key
Attacker obtains the sender's Ed25519 identity signing key.
All transports equally affected
Cannot decrypt past messages (identity keys are for signing, not encryption). Can impersonate the sender going forward until the key is revoked or rotated.
Global Passive Adversary
A network-level observer watching all traffic (ISP, nation state).
BLE
Radio signals within ~10m
Content (encrypted)
DHT
IPs, slot patterns, timing
Content, sender identity
Tor
Circuit existence only
.onion addresses, content, peer IDs
iroh
IPs, relay connections
Content (double-encrypted)
Compromised Infrastructure
Attacker controls DHT nodes, Tor relays, or the n0 relay server.
DHT Nodes
Store/serve ciphertext; cannot decrypt
Tor Relays
Route encrypted circuits; guard knows client IP
n0 Relay
See connection metadata and encrypted packets
BLE
No infrastructure to compromise
Nonce Reuse
ChaCha20-Poly1305 is catastrophically broken by nonce reuse with the same key.
Random 96-bit nonces
Generated per message via OS CSPRNG
Unique keys per message
HKDF with message_id salt ensures different key even if nonce collides
Counter-based transport nonces
Noise protocol uses counters — guaranteed unique within session
Residual risk: Negligible. Birthday bound for 96-bit nonces is 2²⁸ messages per key, and keys are never reused.
This document describes the cryptographic architecture as implemented. No system is perfectly secure — security depends on correct implementation, secure key management, and operational practices. Regular security audits of the Rust cryptographic core are recommended.