zandGitHub 8028b89224 Run CI on linux-amd64
GitHub-hosted labels on a private repo are refused by the spending
limit, so these jobs never started. linux-amd64 is our own fleet.

Claude-Session: https://claude.ai/code/session_01HuMDfgFssPUptYUzgZ6Cp8
2026-09-24 10:09:47 -07:00
2026-09-24 10:09:47 -07:00
2026-06-02 11:22:17 -07:00
2026-06-28 20:56:59 -07:00

pqrns

pqrns

PQ-RNS: hybrid post-quantum profile for the Reticulum Network Stack. Paper: luxfi/papers/pq-rns. Spec: LP-9701.

Reticulum is the cryptography-based mesh-networking stack designed by Mark Qvist for LoRa, packet radio, KISS modems, serial lines, free-space optical links, and any other half-duplex carrier with at least 5 bps and a 500-byte MTU. It provides initiator-anonymous, coordination-less multi-hop transport with end-to-end encryption and unforgeable delivery acknowledgements, completely without IP.

PQ-RNS extends RNS with a hybrid PQ identity and key-exchange layer without forking the reference protocol:

Purpose Native RNS (classical) PQ-RNS extension (hybrid)
Identity signing Ed25519 Ed25519 + ML-DSA-65 (FIPS 204)
Key exchange X25519 X25519 + ML-KEM-768 (FIPS 203)
Session encryption AES-256-CBC + HMAC-SHA-256 (unchanged)
KDF HKDF-SHA-256 HKDF-SHA-256 over hybrid secret

A capability bit in the announce frame advertises hybrid-PQ support. Two PQ-capable peers upgrade to hybrid automatically; a peer with requirePostQuantum: true refuses classical-only counterparties.

Forward secrecy

Both halves of the KEM are ephemeral per link: a fresh X25519 keypair and a fresh ML-KEM-768 keypair are generated, used to derive the session key, then zeroed. Retrospective decryption requires recovering both ephemerals — the classical leg AND the lattice leg — for every recorded link. Long-term identity keys (Ed25519 + ML-DSA-65) authenticate the transcript only; they never directly wrap session traffic.

Wire-format cost

Component Classical Hybrid Δ
Public identity 64 B ~3.2 KiB +3.1 KiB
Signature (one) 64 B ~2.5 KiB +2.4 KiB
KEX ciphertext (one) 32 B ~1.2 KiB +1.1 KiB
Handshake total (3 pkts) ~192 B ~9 KiB +8.8 KiB
Steady-state per-packet 0.44 bps 0.44 bps 0

For sub-1 Kbps carriers a HYBRID_PSK_RESPONDER mode is available (long-term ML-KEM key pre-shared out-of-band, ephemeral only on the initiator). Trades responder-side ephemeral PFS on the lattice leg for ~3× bandwidth reduction.

Layout

pqrns/
├── cmd/pqrnsd/        daemon: serve PQ-RNS over configured interfaces
├── pkg/identity/      hybrid identity (Ed25519 + X25519 + ML-DSA-65 + ML-KEM-768)
├── pkg/link/          hybrid link establishment + session key derivation
├── pkg/announce/      capability-bearing announce frames
├── pkg/cap/           capability negotiation (require / hybrid_full / hybrid_psk)
└── .github/workflows/ CI gates

Configuration

# ~/.lux/config.yaml — node-side
rns:
  enabled: true
  configPath: ~/.lux/reticulum
  announceInterval: 5m
  interfaces:
    - AutoInterface          # WiFi / Ethernet auto-discovery
    - TCPClientInterface     # explicit TCP carrier
    - LoRaInterface          # RNode LoRa transceiver
  linkTimeout: 30s
  postQuantum: true          # advertise PQ capability
  requirePostQuantum: false  # accept classical peers (default)

Setting requirePostQuantum: true makes the node a strict-PQ enclave; classical-only peers cannot link and any attempt is rejected before key material is exchanged.

Composition

PQ-RNS sits where TCP/IP cannot: mesh / LoRa / packet radio / free-space optical / disconnected networks / contested EW environments. On TCP/IP the equivalent role is held by luxfi/zwing. On top of both rides luxfi/pqsafe for file envelopes, with luxfi/age handling at-rest re-keying when E2E transfer isn't possible.

Application data (file, message, RPC)
     │
     ▼  PQSAFE envelope (ciphertext + signed manifest)
     │
     ▼  Z-Wing (TCP/IP)  OR  PQ-RNS (mesh / LoRa / packet radio)
     │
     ▼  TCP / WiFi / LoRa / packet radio / KISS / serial / optical

Domain separation

const (
    CtxLinkKDF      = "PQRNS-LINK-v1"
    CtxIdentitySig  = "PQRNS-IDENTITY-SIG-v1"
    CtxAnnounceSig  = "PQRNS-ANNOUNCE-SIG-v1"
    CtxRekey        = "PQRNS-LINK-REKEY-v1"
)

Every HKDF derivation and every signature carries an explicit context string. No two layers ever derive a key from the same transcript.

Status

Reference profile for LP-9701. The Lux node already ships PQ-RNS under network/dialer/ (luxfi/node); this repo carries the standalone library + CLI for non-node consumers (file utilities, embedded devices, mesh applications).

The authoritative Reticulum reference is markqvist/Reticulum. PQ-RNS is interoperable with native RNS: a PQ-RNS node looks like an ordinary RNS peer to classical-only nodes.

Paper

luxfi/papers/pq-rns/pq-rns.tex is the authoritative specification. This implementation tracks the paper; any divergence is a bug in the implementation.

License

Apache-2.0 (see LICENSE). The native RNS protocol itself was dedicated to the Public Domain by its author in 2016; PQ-RNS is an Apache-2.0-licensed extension.

S
Description
PQ-RNS: hybrid post-quantum profile (X25519+ML-KEM-768, Ed25519+ML-DSA-65) for the Reticulum Network Stack (LP-9701)
Readme
69 KiB
Languages
Go 100%