Sigil Protocol Documentation
Technical reference for the Sigil datagram routing protocol. Derived from the whitepaper.
Introduction
Sigil is a datagram-level addressing and routing protocol where cryptographic public keys serve as permanent network addresses. It is substrate-agnostic: the same Sigil identity works over UDP/IP, Bluetooth Low Energy, Wi-SUN mesh, or raw Ethernet.
Sigil does not encrypt payloads — it is an addressing and routing layer analogous to IP. Encryption is the responsibility of the protocol above.
A sigil is a unique symbol inscribed with intent — your public key is your sigil, your permanent identity on any network substrate.
Design Principles
- Key = Address. Your Ed25519 public key is your address. No registries, no allocation authorities, no DNS.
- Substrate agnosticism. The protocol is indifferent to the physical transport. Bearers are pluggable.
- No payload encryption. Sigil delivers datagrams like IP delivers packets. Encrypt above.
- Binary wire format. All messages use fixed-layout binary encoding with TLV extensions for evolvability. No protobuf, no schema compilers, no codegen.
- Probing as a first-class primitive. Path characterization (RTT, MTU, loss) is built into the protocol.
- Federated discovery. Registrars are independently operated metadata servers. No DHT, no global consensus.
- Algorithm agility. Every Sigil field carries an algorithm identifier. The protocol supports key algorithm migration without wire format changes.
Security Model
Sigil partitions security responsibilities into three zones:
Infrastructure Plane
Registrar API, Relay API, and Registrar-to-Registrar federation MUST use TLS 1.3 (or DTLS 1.3 for UDP-based access). All credential exchange — PSK proofs, JWTs, allocation tokens, metadata — travels over encrypted channels.
Control Plane
Probes and ProbeAcks are authenticated with BLAKE2s-128 MAC using direction-bound session keys derived from both peers' identity keys:
shared_secret = X25519(A_private, B_public)(lo, hi) = sort_lexicographic(A_sigil, B_sigil)probe_key_lo→hi = BLAKE2s(secret ‖ lo ‖ hi ‖ "sigil-probe-lo→hi")probe_key_hi→lo = BLAKE2s(secret ‖ lo ‖ hi ‖ "sigil-probe-hi→lo")Each direction uses a distinct key. This prevents probe reflection attacks: an on-path attacker who reflects a Probe back to its sender cannot produce a valid ProbeAck because the MAC key for the return direction is different.
Data Plane
Application datagrams are explicitly unauthenticated at the Sigil layer. The src_sigil field can be spoofed, just as IP source addresses can be spoofed. This is a stated design choice:
- Per-packet Ed25519 signing (~60us per operation) is unacceptable for high-throughput paths
- Authentication belongs to the layer above (Noise, QUIC, TLS, application HMAC)
- This preserves the "Sigil = IP" analogy
Sigil Addressing
A Sigil address is a public key prefixed by a 1-byte algorithm identifier. The algo byte determines key length — no separate length field is needed.
algo | Algorithm | Key Size | Signature Size | Status |
|---|---|---|---|---|
0x00 | Ed25519 | 32B | 64B | Active |
0x01 | Ed448 | 57B | 114B | Reserved |
0x02 | ML-DSA-65 (Dilithium) | 1952B | 3293B | Reserved (PQ) |
0x03 | SLH-DSA-128s (SPHINCS+) | 32B | 7856B | Reserved (PQ) |
For display, Sigil addresses use Bech32m encoding with the human-readable prefix sigil1. Bech32m provides a checksum and is case-insensitive, making it safer for human entry than base58.
Ed25519 keys occupy a space of ~2252. At 1 trillion devices, collision probability is ~10-52. Accidental collision is physically impossible at any conceivable network scale.
Node Roles
Five named roles based on function:
Peer
Any endpoint node. Has a Sigil. Sends and receives datagrams. The fundamental unit.
Registrar
Federated signaling/metadata server. Stores connection metadata, enforces access policies, mediates connection signaling.
Relay
Packet forwarder (TURN-equivalent). Forwards datagrams when direct paths fail. Allocation-based with rate limits.
Mixer
Onion routing forwarder. Peels one Sphinx layer per hop. Publishes its mixing key to a Mixer Directory.
Supernode
A node running multiple roles (Registrar + Relay + Mixer) for operational simplicity.
Wire Format
Common Envelope
Every Sigil message begins with a 4-byte envelope:
Offset Size Field0 1B version Protocol version (0x01)1 1B msg_type Determines body layout2 2B total_length Big-endian, bytes after this fieldMessage Type Registry
| Range | Category | Types |
|---|---|---|
0x01-0x04 | Bearer (hot path) | Datagram, Probe, ProbeAck, PathReport |
0x10-0x1F | Registrar API | Publish, Query, ConnectIntent, Verification, Delegate |
0x20-0x2F | Relay API | Allocate, Heartbeat, Forward, RateLimit |
0x30-0x3F | Federation | Sync, Ack |
0x40-0x4F | Mixer | Directory |
0x50-0x5F | Key lifecycle | Succession, Revocation |
Datagram Layout (0x01)
For Ed25519-to-Ed25519: header = 4 + 1 + 32 + 1 + 32 + 1 = 71 bytes.
[4B envelope][1B src_algo][32B src_sigil][1B dst_algo][32B dst_sigil][1B flags][...payload]Flags:
- Bit 0 — Mixer: payload is a Sphinx packet
- Bit 1 — Control: payload is a control message (Probe, ProbeAck, PathReport)
- Bit 7 — Extensions present
TLV Extensions
Any message may carry TLV (Type-Length-Value) extensions after its fixed body. Unknown extension types are skipped by reading ext_length and advancing. This is the forward-compatibility mechanism.
Byte Order
All multi-byte integers are big-endian (network byte order). The binary wire encoding is the canonical form — signatures cover bytes as they appear on the wire.
Access Policies
Four modes controlling who can obtain a Peer's connection metadata from a Registrar:
Open (0x00)
Unrestricted. Anyone who queries gets connection details.
PSK (0x01)
Pre-shared key. Registrar issues a nonce challenge; querier responds with HKDF(psk, nonce).
Token (0x02)
JWT signed by a trusted issuer. Registrar verifies signature and claims before releasing metadata.
Delegate (0x03)
Real-time consent. The Registrar asks the Peer whether to authorize each incoming connection request.
Delegate mode is genuinely novel. No other P2P system has real-time consent-based discovery. It enables privacy-first applications, parental controls, enterprise access control, and consent-driven connectivity.
Route Characterization
Every route to a destination is characterized by four metrics:
- MTU (bytes) — maximum payload without fragmentation
- Hop count — intermediate forwarding nodes (0 = direct)
- Loss rate (0.0-1.0) — estimated drop probability
- Delay (milliseconds) — estimated one-way latency
Probing
Probes use the Datagram with flags bit 1 set. Both Probe and ProbeAck carry a BLAKE2s-128 MAC derived from the peers' shared probe authentication key.
- MTU discovery: sender sends Probes of increasing
pad_bytes. The largest Probe that receives an Ack establishes the path MTU. - Loss estimation: computed from sequence gaps over a sliding window.
- Continuous probing: active routes are re-probed every 30s. Routes that degrade transition to
staleand the Peer fails over.
Route Table
Each route has a state: candidate → probing → active → stale. Default selection prefers lowest measured RTT, respects MTU constraints, and factors in loss rate. Multi-path is supported — a Peer may maintain multiple active routes.
Connection Establishment
NAT traversal through Registrar-mediated signaling:
- Peer A queries B's Registrar with credentials
- A sends ConnectIntent with its own candidates
- Registrar delivers ConnectNotification to B
- Both sides probe simultaneously (UDP hole-punching)
- Successful probes become active routes
- Datagrams flow over the best active route
Candidate Verification
Registrars verify candidate address ownership before serving metadata. Two paths:
- Source IP pinning: UDP candidates matching the TLS connection source IP are implicitly verified.
- Callback: Registrar sends a CandidateChallenge to the claimed address. The Peer signs and returns a CandidateResponse.
Unverifiable candidates are never served to queriers.
Relay Protocol
Relays forward datagrams when direct paths fail (symmetric NAT, firewalled UDP). They are authenticated, rate-limited, and bind allocations to verified addresses.
Allocation Lifecycle
- REQUESTED — AllocateRequest, source address recorded
- BOUND — Token issued, address bound
- ACTIVE — First heartbeat confirms liveness
- EXPIRED — No heartbeat within TTL
Rate Limits
Each allocation has configurable forwarding budgets (defaults):
- 100 packets/second
- 128 KB/second
- 32 concurrent senders
Exceeding limits triggers a RelayRateLimit notification back to the sender. Relays are last-resort forwarders, not general-purpose proxies.
Onion Routing (Mixer Circuits)
The sender chooses the circuit and constructs the Sphinx header. Circuit topology is never published.
- Mixer nodes publish rotating X25519 mixing keys (24h rotation for forward secrecy)
- Sender fetches the Mixer Directory, selects N nodes, performs X25519 key agreement per hop
- All Sphinx packets are fixed-size at every hop, preventing traffic analysis by packet size
- Fixed circuit length (network-wide parameter) prevents position inference
Privacy is a single-protocol, single-dependency solution — no external Tor daemon required. The anonymity set is the Sigil network itself.
Bearer Abstraction
| Value | Bearer | Typical MTU | Notes |
|---|---|---|---|
0x00 | UDP4 | ~1280B | IPv4 UDP |
0x01 | UDP6 | ~1280B | IPv6 UDP |
0x02 | Bluetooth | ~512B | BLE L2CAP CoC |
0x03 | Wi-SUN | ~2047B | 802.15.4g mesh |
0x04 | Ethernet | ~1500B | Raw Ethernet L2 |
Bearer Trait
trait Bearer { fn send(&self, addr: &[u8], bytes: &[u8]) -> Result<()>; fn recv(&self) -> Result<(Vec<u8>, Vec<u8>)>; fn mtu(&self) -> usize; fn bearer_type(&self) -> BearerType;}Datagram bearers deliver one Sigil message per bearer frame. The bearer is responsible for framing. Substrates below ~128B MTU are structurally incompatible and should use a gateway.
Crate Architecture
sigil-wire no_std Binary codec, zero-copysigil-crypto no_std Crypto traits + implssigil-core no_std Protocol state machinessigil-sim std Deterministic simulationsigil-runtime std System impls (tokio, OS)Key design constraints:
sigil-wireandsigil-coreareno_std— they run on Cortex-M microcontrollers with zero allocator for datagram parsing- All crypto is behind traits — swap between test doubles (deterministic) and real implementations (Ed25519, X25519, BLAKE2s)
- State machines are pure: feed bytes in, get
Actionvariants out. No async, no I/O, no side effects
Key Dependencies
ed25519-dalek,x25519-dalek— identity signing and key agreementblake2— hashing and MAC (no_std)zeroize— secret memory erasuretokio,axum— runtime (only insigil-runtime)
Key Lifecycle
Key Succession
A Sigil owner can migrate to a new key by publishing a KeySuccession record signed by the old key. The succession_seq field is a monotonically increasing counter — Registrars reject any succession record with a lower or equal sequence number.
KeySuccession (msg_type 0x50): [1B old_algo][old_key][1B new_algo][new_key] [8B succession_seq][8B effective_at] [signature by old key]Key Revocation
At Sigil creation, the owner generates a separate revocation keypair and registers the revocation public key with their Registrar(s). An attacker who compromises the Sigil private key cannot forge a revocation unless they also compromise the revocation key.
KeyRevocation (msg_type 0x51): [1B algo][sigil][8B revoked_at] [1B rev_algo][rev_pubkey][signature by rev key]Comparison with Prior Art
| Property | Sigil | iroh | libp2p | Yggdrasil |
|---|---|---|---|---|
| Key = Address | Yes | Yes | Hash | Derived |
| Multi-Bearer | Native | Adapters | Partial | No |
| No Payload Encryption | Yes | No | No | No |
| Federated Discovery | Yes | Partial | DHT | Multicast |
| Onion Routing | Sphinx | No | No | No |
no_std Embedded | Yes | No | No | No |
| Algorithm Agility | Yes | No | Yes | No |
Sigil and iroh occupy different layers of the stack. Iroh is an application-layer library giving encrypted QUIC connections. Sigil is a network-layer protocol giving datagram routing. They could compose: an iroh endpoint using a Sigil bearer instead of UDP.