Docs/Technical

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)

BLEFastest
irohNAT punch
TorAnonymous
DHTFallback

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

x25519-dalekKey agreement
ed25519-dalekSignatures
chacha20poly1305AEAD
hkdf + sha2KDF
snowNoise protocol
randCSPRNG
zeroizeMemory cleanup

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

Noise_XX_25519_ChaChaPoly_SHA256

Application Layer

Per-message encryption & signing

ChaCha20-Poly1305 + Ed25519
Your message (innermost layer)

Noise XX Handshake

Alice (Initiator)
Bob (Responder)
Ephemeral public key

32 bytes, unencrypted

Ephemeral + Static key

80 bytes, partially encrypted with DH(e,e)

Static key

48 bytes, fully encrypted

Symmetric transport keys established (one per direction)

Message Exchange Protocol

After Noise handshake, an application-level exchange runs over the encrypted channel:

1

MsgCount

Announce queued messages

2

MsgData

Transmit encrypted messages

3

MsgAck

Per-message acknowledgment

4

Complete

Signal exchange done

Security Risks

BLE Range Limitation

Low

~10m range limits interception to physical proximity

BLE Advertising Metadata

Low

Rotating IDs derived via HKDF prevent device tracking

Relay Attack (MITM)

Low

Noise XX provides mutual authentication — MITM requires real-time key substitution

Radio Jamming / DoS

Medium

Radio-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

Sender
Encrypt & Publish

BitTorrent Mainline DHT

Thousands of independent nodes worldwide

Slots 0-100 · BEP44 mutable items

Poll & Decrypt
Recipient

Key Derivation Chain

X25519 public keySHA-512Ed25519 seedBEP44 signing key

Slot Enumeration

Medium

Observers can correlate slots 0-100 to a single recipient by access patterns

Volume Analysis

Medium

Number of occupied slots reveals approximate message count

IP Address Exposure

Medium

DHT participation reveals the device's IP address to DHT peers

Timing Correlation

Medium

Publish/fetch timing can correlate sender and recipient

No Confidentiality at Rest

Low

Mitigated by application-level encryption; DHT nodes see only ciphertext

Stale Message Replay

Low

48h 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

Tor v3 onion routing (3-hop)

Transport Layer

Message framing

WebSocket over TCP

Application Layer

Per-message encryption & signing

ChaCha20-Poly1305 + Ed25519
Your message (innermost layer)

No exit nodes used. All connections are .onion-to-.onion, remaining entirely within the Tor network.

Connection Protocol

Client
Server (.onion)
SOCKS5 tunnel

Routes through Tor to .onion:80

WebSocket upgrade

HTTP 101 Switching Protocols

Ed25519 identity key

32-byte public key

Ed25519 identity key

Server sends own public key

Nonce challenge

32-byte random nonce

Nonce response

Echo nonce back

"OK"

Contact verified

Authenticated — encrypted messages flow bidirectionally

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

Medium

DHT queries for .onion addresses are not anonymous; DHT peers see the lookup

Timing Correlation

Medium

Message timing patterns visible to ISP-level observers watching both endpoints

Message Size Analysis

Low

No padding; file transfer sizes are observable at the network level

Tor Circuit Compromise

Low

Requires 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

QUIC / TLS 1.3 / ChaCha20-Poly1305

Application Layer

Per-message encryption & signing

ChaCha20-Poly1305 + Ed25519
Your message (innermost layer)

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

Medium

n0 relay sees connection patterns and IP addresses of both peers

IP Address Exposure

Medium

Both peers' IPs visible to relay; no anonymity layer

DHT Endpoint Visibility

Low

Published EndpointIds are publicly queryable on the DHT

Message Size Analysis

Low

Packet 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.

Device AHas internet
BLE Gossip
Device BRelay (can't read)
Later
Device CIntended recipient
Store Limits

50 MB max, 48-hour TTL

Acceptance

Probabilistic via bloom filter digests

Metadata Leakage

None — relay sees only encrypted blobs

Chunking

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

medium
OfflineMax: ~500B/packet (chunked)

DHT Network

Encryption

ChaCha20-Poly1305 (app layer only)

Forward Secrecy

Per-message ephemeral ECDH

Anonymity

IP visible to DHT peers

low
OfflineMax: ~950B/slot (chunked)

Tor P2P

Encryption

ChaCha20-Poly1305 + Tor circuit encryption

Forward Secrecy

Per-message (ECDH) + per-circuit (Tor DH)

Anonymity

Strong — .onion-to-.onion, 3-hop

high
OfflineMax: Unlimited (WebSocket)

iroh (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

low
OfflineMax: 100 MB

Attack Surface Analysis

Compromised Recipient Exchange Key

Attacker obtains the recipient's long-term X25519 exchange secret.

BLELow

Requires physical proximity (~10m) to intercept radio signals

DHTHigh

Messages persist on public DHT for 48 hours — attacker can fetch and decrypt

Tor P2PMedium

Must intercept in real-time; Tor anonymity makes targeting difficult

irohMedium

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

Can't decrypt

Tor Relays

Route encrypted circuits; guard knows client IP

Can't decrypt

n0 Relay

See connection metadata and encrypted packets

Can't decrypt

BLE

No infrastructure to compromise

Can't decrypt

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.