Libertaria Wire Frame Protocol
LWF v3 — Encrypted by Default
The Libertaria Wire Frame (LWF) protocol is the wire format used by the Libertaria protocol stack – a separate project that converges with Nexus OS at the networking layer. LWF v3 encrypts all frames by default; cleartext is the exception, not the rule.
Overview
LWF provides a structured frame format for Libertaria's decentralized communication protocols. It operates alongside UTCP and TCP/IP on the same network:
| EtherType | Protocol | Purpose |
|---|---|---|
0x0800 | IPv4 | Legacy TCP/IP (LwIP) |
0x86DD | IPv6 | Dual-stack connectivity (LwIP) |
0x88B5 | UTCP | Nexus sovereign transport |
0x4C57 | LWF | Libertaria protocol stack |
LWF v3 Frame Format
LWF v3 (VERSION 0x03) introduces mandatory encryption and a full Ed25519 signature in the trailer. Total frame overhead is 156 bytes.
Header (88 bytes)
The header is transmitted in cleartext – routers can read routing hints but cannot tamper with the payload. The header serves as Additional Authenticated Data (AAD) for the encryption layer.
LWF v3 Header (88 bytes):
Offset Field Type Size Description
──────────────────────────────────────────────────────────────
0x00 version u8 1 0x03 (LWF v3)
0x01 flags u8 1 Frame flags (see below)
0x02 frame_type u16 2 Protocol message type
0x04 src_cellid [16]u8 16 Source CellID
0x14 dst_cellid [16]u8 16 Destination CellID
0x24 src_hint [8]u8 8 Source routing hint
0x2C dst_hint [8]u8 8 Destination routing hint
0x34 seq u32 4 Sequence number
0x38 payload_len u32 4 Payload length (ciphertext)
0x3C nonce [24]u8 24 Encryption nonce
0x54 _reserved [4]u8 4 Reserved (zero)
──────────────────────────────────────────────────────────────
Total: 88 bytesPayload (variable)
Encrypted by default. Raw bytes when CLEARTEXT flag is set.
Trailer (68 bytes)
LWF v3 Trailer (68 bytes):
Offset Field Type Size Description
──────────────────────────────────────────────────────────────
0x00 signature [64]u8 64 Ed25519 signature over header + payload
0x40 crc32c u32 4 CRC32-C of entire frame (header + payload + signature)
──────────────────────────────────────────────────────────────
Total: 68 bytesTotal Overhead
| Component | v2 Size | v3 Size |
|---|---|---|
| Header | 88 bytes | 88 bytes |
| Trailer | 36 bytes | 68 bytes |
| Total overhead | 124 bytes | 156 bytes |
The 32-byte increase buys a full 64-byte Ed25519 signature (v2 used a truncated hash) and a CRC32-C integrity check. Non-negotiable for a protocol that encrypts by default.
Flag Semantics
| Bit | Flag | Value | Meaning |
|---|---|---|---|
| 0 | CLEARTEXT | 0x01 | Payload is NOT encrypted. The exception, not the rule. |
| 1 | RELAY | 0x02 | Frame should be forwarded by intermediate nodes |
| 2 | FRAGMENT | 0x04 | Frame is a fragment of a larger message |
| 3 | PRIORITY | 0x08 | High-priority frame (scheduler hint) |
| 4 | Reserved | 0x10 | Must be 0 |
| 5 | Reserved | 0x20 | Must be 0 |
| 6 | SESSION_CIPHER | 0x40 | Cipher mode select: 0 = Mode A (Noise XX), 1 = Mode B (XChaCha20-Poly1305) |
| 7 | Reserved | 0x80 | Must be 0 |
Invalid Flag Combinations
CLEARTEXT + SESSION_CIPHER (0x01 | 0x40 = 0x41) is an invalid combination. If a frame arrives with both flags set, it must be rejected. Cleartext frames have no cipher to select. Receivers drop the frame and increment a counter; no NACK is sent (do not help an attacker probe flag logic).
Default State
When flags = 0x00: the frame is encrypted using Mode A (Noise XX). This is the default for all live session traffic. Cleartext must be explicitly opted into.
Dual Cipher Model
LWF v3 supports two encryption modes, selected by the SESSION_CIPHER flag.
Mode A — Noise XX (Default)
For live, interactive sessions between two nodes that have completed a Noise XX handshake.
Noise Protocol Name: Noise_XX_25519_ChaChaPoly_BLAKE2b
| Property | Value |
|---|---|
| Protocol | Noise_XX_25519_ChaChaPoly_BLAKE2b |
| DH Function | X25519 (Curve25519 scalar multiplication) |
| Cipher | ChaCha20-Poly1305 (AEAD) |
| Hash / KDF | BLAKE2b (keyed BLAKE2b as HMAC-like KDF) |
| Nonce | Sequential (8-byte LE counter, zero-padded to 12 bytes for AEAD) |
| Auth tag | 16 bytes (Poly1305, appended to ciphertext) |
| AAD | LWF header (88 bytes) |
| Identity | BLAKE3(remote_static) = peer key ID (QVL ecosystem standard) |
| Library | Monocypher (freestanding C — no std, no heap) |
| Use case | Live sessions, real-time communication, UTCP tunneling |
Crypto split: BLAKE2b is used for the Noise KDF (keyed hashing for key derivation during handshake). BLAKE3 is used for identity — QVL key IDs, content addressing, and trust binding. This split exists because Monocypher provides freestanding BLAKE2b with native keying (stronger than HMAC construction), while BLAKE3 is the Libertaria ecosystem standard hash for everything outside the Noise transport.
3-message handshake:
-> e— Initiator sends ephemeral X25519 public key (32 bytes, cleartext)<- e, ee, s, es— Responder: ephemeral + 2 DH + encrypted static (32+48+payload bytes)-> s, se— Initiator: encrypted static + DH (48+payload bytes)
After message 3, both sides call split() to derive transport CipherStates (send + recv). The session is keyed by (session_id[16] + source_hint[8]) in the capsule's 8-slot session table with LRU eviction.
Mode A provides forward secrecy through the Noise XX handshake. Sequential nonces are efficient but require both peers to maintain state. If a peer restarts, the session must be re-established.
Mode B — XChaCha20-Poly1305
For store-and-forward, offline messages, and scenarios where the recipient may not be online.
| Property | Value |
|---|---|
| Handshake | None – uses long-term keys or pre-shared keys |
| Cipher | XChaCha20-Poly1305 |
| Nonce | 24-byte random (full nonce field in header) |
| Auth tag | 16 bytes (included in ciphertext) |
| Overhead | 40 bytes total (24-byte nonce + 16-byte tag) |
| AAD | LWF header (88 bytes) |
| Use case | Store-and-forward, mesh relay, offline messages |
Mode B uses random nonces – no state required. A frame encrypted with Mode B can sit in a relay node's queue for hours or days and be decrypted when the recipient comes online. The 24-byte nonce provides a collision probability of ~2^-96 even at high message volumes.
Cipher Selection Logic
if flags & CLEARTEXT:
# No encryption. Payload is raw.
if flags & SESSION_CIPHER:
REJECT # Invalid combination
# Signature still required in trailer.
elif flags & SESSION_CIPHER:
# Mode B: XChaCha20-Poly1305
# nonce = random 24 bytes (full header nonce field)
# encrypt(key, nonce, plaintext, aad=header)
else:
# Mode A: Noise XX / ChaCha20-Poly1305 (DEFAULT)
# nonce = sequential counter (8 bytes, zero-padded in header)
# encrypt(session_key, nonce, plaintext, aad=header)Integration with Rumpk
LWF v3 integration follows the principle: crypto runs in the membrane; the kernel does routing only.
Kernel Layer (NetSwitch + LWF Adapter)
- The NetSwitch routes frames with EtherType
0x4C57to the LWF handler fiber - The LWF adapter parses the 88-byte header in-place (zero-copy)
- Routing decisions use
dst_cellid,dst_hint, and theRELAYflag - The kernel never decrypts payloads – it reads cleartext hints and forwards
RELAY_FORWARDframes are re-queued to the VirtIO TX ring with updated hop hints
Membrane Layer (Capsule NPL)
- Decryption happens in the Capsule's address space (userland)
- Noise XX session state is per-connection, managed by the Capsule
- Ed25519 signature verification before decryption (reject tampered frames early)
- CRC32-C check on receive (reject corrupted frames before any crypto)
Syscalls
| Syscall | Number | Purpose |
|---|---|---|
SYS_LWF_RECV | 0x700 | Receive an LWF frame via ION copy |
SYS_LWF_SEND | 0x701 | Send an LWF frame via ION copy |
CSpace Capabilities
| Capability | Slot | Permission |
|---|---|---|
LWF_RX | 0x600 | READ |
LWF_TX | 0x601 | WRITE |
Pledge
LWF operations require the PLEDGE_INET bit. A process without PLEDGE_INET cannot send or receive LWF frames.
Capsule Integration
The Capsule NPL (the Libertaria stack's Nexus-native process) uses LWF for all its network communication:
- Capsule receives LWF frames via
SYS_LWF_RECV - Verifies CRC32-C, then Ed25519 signature
- Decrypts payload (Mode A or Mode B based on flags)
- Parses the LWF payload (protocol-specific messages)
- Sends responses via
SYS_LWF_SEND(encrypts, signs, computes CRC) - Runs an event loop with heartbeat: recv → verify → decrypt → parse → respond → yield
The Capsule has been verified stable for 30+ seconds of continuous operation with zero faults.
Implementation
The Libertaria stack is implemented in ~15,000 lines of Zig across 24 test suites. It is maintained as a separate project and converges with Nexus OS when the Capsule runs as an NPL payload inside Rumpk.