The Lightning Network uses source-based onion routing with the SPHINX protocol to enable private, censorship-resistant payments. The sender controls the entire routing path while intermediate nodes only see their immediate neighbors, ensuring transaction privacy across the network.
1. Introduction: What is Onion Routing?
Onion routing is a privacy-preserving technique where data is wrapped in multiple layers of encryption—like the layers of an onion. As the data passes through each node in the network, one layer is “peeled” off, revealing only the next destination.
Key Concept: The Lightning Network adapted this technique (originally from the Tor network) specifically for payment routing, using a variant called SPHINX.
Why Onion Routing for Lightning?
Traditional internet routing reveals the sender, receiver, and all intermediaries to each routing node. Lightning Network needed a protocol that:
Hides payment source and destination
Prevents censorship
Maintains efficiency for financial transactions
Protects against traffic analysis
2. Source-Based Routing: The Sender is in Control
2.1 Overview
In the Lightning Network, the sending node determines the complete payment path from source to destination. This is called source-based pathfinding.
Important: Unlike traditional internet routing where routers decide the path, in Lightning the sender has full control over:
The exact route (sequence of nodes)
Total number of hops
Total fees paid
Time-lock values (CLTV) at each hop
2.2 Path Discovery Process
The sender builds their routing strategy using three key data sources:
Network Topology (Channel Graph)
The sender maintains a local “map” of the Lightning Network by collecting:
Node announcements: Public keys and addresses of Lightning nodes
Channel announcements: Information about payment channels between nodes
Channel updates: Routing policies (fees, timelocks) for each channel
This information is gathered through the gossip protocol—a peer-to-peer mechanism where nodes share network topology data.
Practical Example: Alice Pays Dave
Let’s follow a concrete example:
Scenario Setup:
Alice wants to pay Dave 4,999,999 millisatoshis (≈ 5,000 sats) for a coffee
Dave generates an invoice containing:
amount: 4,999,999 msatspayment_hash: Hash of a secret preimagepayee_pub_key: Dave’s public keymin_final_cltv_expiry_delta: 9 blocks (safety buffer)
Alice’s Network View:
Alice’s available paths to Dave:
Path 1: Alice → Bob → Charlie → Dave
- Channel AB (fee: 200 base + 2000 ppm)
- Channel BC (fee: 100 base + 1000 ppm)
- Channel CD (fee: none, Dave is receiver)
Path 2: Alice → Eve → Charlie → Dave
- Channel AE (fee: 300 base + 3000 ppm)
- Channel EC (fee: 100 base + 1000 ppm)
- Channel CD (fee: none, Dave is receiver)
Fee Calculation (Working Backwards)
Alice must calculate fees backwards from the destination:
Path 1 Calculation:
Dave receives: 4,999,999 msats
Charlie’s fee: 100 + (1000/1,000,000) × 4,999,999 = 5,100 msats
Charlie forwards: 5,005,099 msats
Bob’s fee: 200 + (2000/1,000,000) × 5,005,099 = 10,211 msats
Bob forwards: 5,015,310 msats
Total Alice pays: 5,015,310 msats (15,311 msats in fees)
Path 2 Calculation:
Dave receives: 4,999,999 msats
Charlie’s fee: 5,100 msats (same as above)
Charlie forwards: 5,005,099 msats
Eve’s fee: 300 + (3000/1,000,000) × 5,005,099 = 15,316 msats
Eve forwards: 5,020,415 msats
Total Alice pays: 5,020,415 msats (20,416 msats in fees)
Result: Alice selects Path 1 as it’s cheaper by 5,105 msats.
3. Constructing the Onion: Layer-by-Layer Encryption
3.1 The Onion Packet Structure
Once Alice has selected her path, she constructs the onion packet—a fixed-size encrypted message containing instructions for each hop.
Key Components:
Version byte: Protocol version identifier
Ephemeral public key: Used for shared secret derivation (different for each hop)
Routing information: Encrypted payloads for each hop (1300 bytes fixed size)
HMAC: Message authentication code for integrity verification
3.2 What Each Hop Needs to Know
Each intermediate node receives a hop payload containing:
Hop Payload Fields:
├── short_channel_id # Which channel to forward on
├── amt_to_forward # Amount to send (minus their fee)
├── outgoing_cltv_value # Time-lock value for next hop
└── hmac # Authentication for next hop’s packet
Critical Privacy Feature: Each hop payload is encrypted specifically for that node—no other node can decrypt it.
3.3 Example: Building Alice’s Onion
Using our Alice → Bob → Charlie → Dave example:
Step 1: Dave’s Payload (Innermost Layer)
Payload for Dave:
- amt_to_forward: 4,999,999 msats
- outgoing_cltv_value: 1010 (current height 1001 + 9 block delta)
- Payment is final (no next hop)
Step 2: Wrap with Charlie’s Payload
Payload for Charlie:
- short_channel_id: CD (channel to Dave)
- amt_to_forward: 4,999,999 msats
- outgoing_cltv_value: 1010
- Encrypted payload for Dave (Charlie cannot read this)
Step 3: Wrap with Bob’s Payload
Payload for Bob:
- short_channel_id: BC (channel to Charlie)
- amt_to_forward: 5,005,099 msats
- outgoing_cltv_value: 1020 (1010 + Charlie’s 10 block delta)
- Encrypted payload for Charlie (Bob cannot read this)
Step 4: Final Onion Sent to Bob
Complete Onion Packet:
- Version: 0
- Ephemeral key: [Bob’s ephemeral public key]
- Routing info: [Bob’s payload | Encrypted(Charlie’s payload | Encrypted(Dave’s payload))]
- HMAC: [Authentication code]
3.4 The SPHINX Protocol: Advanced Encryption
The Lightning Network uses a modified SPHINX Mix Format with these features:
Shared Secret Derivation
Each hop derives a shared secret using Elliptic Curve Diffie-Hellman (ECDH)
The ephemeral key is randomized at each hop using a “blinding factor”
This prevents linking packets across hops
Key Generation Formula
For hop i:
- Shared secret: ss[i] = ECDH(node_private_key[i], ephemeral_public_key[i])
- Blinding factor: b[i] = HMAC-SHA256(ss[i], “blinding”)
- Next ephemeral key: ephemeral_key[i+1] = ephemeral_key[i] * b[i]
Stream Cipher (ChaCha20)
Lightning uses ChaCha20 (not AES) for:
Performance optimization
Generating cipher streams to encrypt/decrypt payloads
Maintaining fixed packet size
4. Intermediate Nodes: Limited Visibility by Design
4.1 What Each Hop Can See
When Bob (an intermediate node) receives the onion packet, he can ONLY:
Decrypt his own layer using his private key
Read his hop payload containing:
Which channel to forward on (
short_channel_id)How much to forward (
amt_to_forward)What timelock to use (
outgoing_cltv_value)
See predecessor: He knows Alice sent the packet to him
See successor: He knows he should forward to Charlie
4.2 What Each Hop CANNOT See
Bob cannot determine:
Who is the original sender (could be Alice, or she might be forwarding)
Who is the final recipient (Dave? Or is Charlie forwarding further?)
Total path length (how many hops total?)
His position in the route (is he hop 1, 2, 3, or n?)
Contents of other hops’ payloads
The original payment amount
Critical Privacy Mechanism: The onion packet size remains constant at 1,300 bytes at every hop. After Bob removes his payload, the packet is padded with encrypted “junk data” to maintain the same size.
4.3 The Forwarding Process
Bob’s Actions:
1. Receive onion from Alice
2. Verify HMAC (check integrity)
3. Decrypt his layer using shared secret
4. Extract his hop payload:
- Channel BC
- Forward 5,005,099 msats
- CLTV value 1020
5. Remove his payload from packet
6. Left-shift remaining data
7. Add random padding to maintain 1,300 bytes
8. Construct new onion with updated ephemeral key
9. Forward to Charlie via channel BC
Charlie’s Actions: Same process—Charlie:
Decrypts his layer
Extracts payload for channel CD
Forwards to Dave
Still doesn’t know this is the final hop
Dave’s Actions:
Receives final payload
Sees empty HMAC (indicating final destination)
Verifies he has the preimage for payment_hash
Claims the payment
4.4 Visual Analogy: Nested Envelopes
Think of the onion like nested, locked boxes:
┌─────────────────────────────────────┐
│ For Bob (locked with Bob’s key) │
│ ┌───────────────────────────────┐ │
│ │ For Charlie (Charlie’s key) │ │
│ │ ┌─────────────────────────┐ │ │
│ │ │ For Dave (Dave’s key) │ │ │
│ │ │ [Payment: 5000 sats] │ │ │
│ │ └─────────────────────────┘ │ │
│ └───────────────────────────────┘ │
└─────────────────────────────────────┘
Bob opens his box, finds instructions and another locked box for Charlie
Bob hands Charlie’s box to Charlie (can’t open it himself)
Charlie opens his box, finds instructions and Dave’s box
Dave opens his box and finds the payment
5. Privacy Guarantees
The combination of source routing and SPHINX onion routing provides these security properties:
5.1 Core Privacy Features
Feature Implementation Benefit Route Anonymity Sender determines path No intermediate node sees full route Source Hiding Ephemeral keys Sender’s identity hidden from intermediaries Destination Hiding Layered encryption Recipient identity hidden until final hop Position Hiding Fixed packet size Nodes can’t determine their position Path Length Hiding Constant 1,300 byte packets Total hop count is unknown Unlinkability Key blinding Packets can’t be correlated across hops
5.2 What the Network Sees
From a network observer’s perspective:
Observer sees: Encrypted packet traffic between nodes
Observer CANNOT determine:
- Which packets belong to the same payment
- Payment source
- Payment destination
- Payment route
- Payment amount
5.3 Practical Privacy Considerations
Important Caveats:
Timing attacks: Sophisticated attackers might correlate payments by timing
Amount analysis: If amounts are unique, they could potentially be tracked
Route selection: Using optimal (cheapest) routes reduces anonymity sets
Network topology: Public channels reveal possible routes
Mitigation Strategies:
Random route selection (sacrifice cost for privacy)
Shadow routing (add dummy time delays)
Multi-path payments (split across routes)
Blinded paths (recipient hides last hops)
6. Technical Implementation Details
6.1 BOLT #4 Specification
The Lightning Network onion routing protocol is formally defined in BOLT #4: Onion Routing Protocol.
Key Technical Specifications:
Packet size: 1,366 bytes total
1 byte version
33 bytes ephemeral public key (compressed)
1,300 bytes routing information
32 bytes HMAC
Encryption: ChaCha20-Poly1305
Shared secret: ECDH with secp256k1
Hash function: SHA-256 for HMACs
6.2 Replay Protection
Problem: Attackers could potentially replay old onion packets to confuse nodes or steal funds.
Solution: Lightning implements multi-layered replay protection:
Ephemeral key log: Nodes maintain a log of used ephemeral keys and reject duplicates
Payment hash binding: HMAC includes payment_hash in associated data
HTLC timelock expiry: Once HTLCs expire, replay logs can be garbage collected
Economic disincentive: Reusing payment_hash lets nodes claim the full payment
6.3 Error Handling and Failure Messages
When a payment fails, error information must propagate back to the sender while maintaining privacy.
Error Return Process:
1. Node detecting error (e.g., Charlie):
- Derives error key from shared secret
- Creates error packet with failure reason
- Encrypts error packet
- Sends back to predecessor (Bob)
2. Each intermediate node (Bob):
- Derives error key from their shared secret
- Adds another layer of encryption
- Forwards back to predecessor (Alice)
3. Sender (Alice):
- Receives encrypted error packet
- Peels layers using shared secrets
- Identifies which hop failed
- Sees failure reason (e.g., “insufficient balance”)
Common Error Types:
temporary_channel_failure: Channel temporarily unavailableamount_below_minimum: Payment amount too smallfee_insufficient: Routing fee too lowincorrect_cltv_expiry: Time-lock value mismatchchannel_disabled: Channel not accepting payments
6.4 Modifications from Original SPHINX
Lightning Network adapted the SPHINX protocol with these changes:
Change Reason MAC over entire header No need for SURB (Single-Use Reply Blocks) Removed end-to-end payload Reduce packet size, not needed for payments ChaCha20 instead of LIONESS Performance optimization Added per-hop payload Provide routing instructions (amount, channel, CLTV) Payment hash in HMAC Strengthen replay protection using HTLC properties
7. Complete Example Walkthrough
Let’s trace the complete journey of our example payment:
Phase 1: Invoice Generation
Dave creates invoice:
{
“amount”: 4999999,
“payment_hash”: “a1b2c3...”,
“payee_pub_key”: “02dave...”,
“min_final_cltv_expiry_delta”: 9
}
Phase 2: Path Finding
Alice builds channel graph from gossip:
- Discovers Path 1: Alice → Bob → Charlie → Dave (cheaper)
- Calculates fees: 15,311 msats
- Determines CLTV values at each hop
Phase 3: Onion Construction
Alice creates onion packet:
- Generates ephemeral keys for each hop
- Derives shared secrets
- Encrypts hop payloads (Dave → Charlie → Bob)
- Constructs 1,366 byte onion packet
Phase 4: Payment Initiation
Alice → Bob:
- update_add_htlc message
- payment_hash: a1b2c3...
- amount_msat: 5,015,310
- cltv_expiry: 1030
- onion_routing_packet: [1,366 byte onion]
Phase 5: Forwarding (Bob)
Bob receives packet:
1. Verifies HMAC
2. Derives shared secret using ephemeral key
3. Decrypts his layer
4. Reads: “Forward 5,005,099 on channel BC, CLTV 1020”
5. Verifies he can forward (sufficient balance, fee acceptable)
6. Peels his layer, maintains 1,300 bytes with padding
7. Generates new ephemeral key (blinded)
8. Sends update_add_htlc to Charlie
Phase 6: Forwarding (Charlie)
Charlie receives packet:
1. Verifies HMAC
2. Decrypts his layer
3. Reads: “Forward 4,999,999 on channel CD, CLTV 1010”
4. Verifies forwarding requirements
5. Peels layer, maintains packet size
6. Sends update_add_htlc to Dave
Phase 7: Payment Settlement
Dave receives packet:
1. Verifies HMAC
2. Decrypts final layer
3. Sees empty HMAC (indicates final destination)
4. Checks payment_hash matches invoice
5. Verifies amount: 4,999,999 msats
6. Reveals preimage: “preimage123...”
7. Updates commitment with Charlie (claims HTLC)
Payment propagates backwards:
Charlie ← preimage ← Dave (claims his HTLC from Bob)
Bob ← preimage ← Charlie (claims his HTLC from Alice)
Alice ← preimage ← Bob (payment complete!)
8. Advanced Topics
8.1 Trampoline Routing
For lightweight clients that can’t maintain full channel graph:
Client connects to “trampoline node”
Trampoline nodes handle pathfinding
Creates nested onion routing (onion within onion)
8.2 Multi-Path Payments (MPP)
Split large payments across multiple routes:
Sender creates multiple smaller payments
Each follows different path
Recipient atomically accepts/rejects all parts
Improves payment reliability and privacy
8.3 Blinded Paths (BOLT #12)
Enhanced recipient privacy:
Recipient creates “blinded route” for last few hops
Sender doesn’t know recipient’s actual node
Useful for receiver privacy and unannounced channels
9. Security Analysis
9.1 Attack Vectors and Mitigations
Timing Analysis:
Attack: Correlate payment timing across hops
Mitigation: Random delays, batching, trampoline routing
Balance Probing:
Attack: Send fake payments to discover channel balances
Mitigation: Return generic errors, rate limiting
Traffic Analysis:
Attack: Monitor network traffic patterns
Mitigation: Tor integration, decoy traffic, MPP
Route Fingerprinting:
Attack: Unique route selections identify users
Mitigation: Route randomization, shadow routing
9.2 Comparison with Tor
Aspect Tor Lightning Path Selection Random guards + middle + exit Source-based (sender chooses) Optimization Balanced load Cost-optimized (fees/latency) Anonymity Set Large (random selection) Smaller (deterministic routing) Performance Higher latency tolerated Low latency required Packet Format Original SPHINX Modified SPHINX
Key Difference: Lightning prioritizes performance and cost over maximum anonymity, trading off some privacy for payment efficiency.
10. Resources and Further Reading
Official Documentation
BOLT #4: Onion Routing Protocol - Official specification
lightning-onion Repository - Go implementation
Educational Resources
Mastering the Lightning Network, Chapter 10 - Comprehensive book chapter
Elle Mouton: Onion Routing Preliminaries - Excellent visual tutorial with diagrams
Voltage Blog: What is Onion Routing - Beginner-friendly explanation
Academic Papers
Danezis & Goldberg (2009): “Sphinx: A Compact and Provably Secure Mix Format” - Original SPHINX paper
“How Lightning’s Routing Diminishes its Anonymity” - Analysis of privacy trade-offs
Network Visualization
LnRouter Graph Visualization - Explore Lightning Network topology
1ML.com - Network statistics and node explorer
11. Glossary
Channel Graph: Local map of Lightning Network topology built from gossip protocol messages
CLTV (CheckLockTimeVerify): Time-lock mechanism ensuring HTLCs expire at specific block heights
Ephemeral Key: Temporary public key used once per payment to derive shared secrets
Gossip Protocol: P2P mechanism for nodes to share network topology information
Hop Payload: Encrypted instructions for each intermediate node in payment route
HTLC (Hash Time-Locked Contract): Conditional payment that requires cryptographic proof (preimage)
Onion Packet: Fixed-size encrypted message containing routing instructions for all hops
Payment Hash: SHA-256 hash of preimage used in HTLC contracts
Preimage: Secret value whose hash is in the invoice; revealing it claims the payment
Shared Secret: Secret derived through ECDH, known only to sender and specific hop
Source Routing: Routing paradigm where sender determines complete path (vs. router-determined)
SPHINX: Cryptographic packet format providing layered encryption and unlinkability
Pros/Cons
Lightning Network’s onion routing represents a sophisticated balance between:
Privacy: Hiding sender, receiver, and route information
Performance: Enabling instant, low-latency payments
Efficiency: Optimizing for low fees and high success rates
Decentralization: Avoiding trusted third parties
The SPHINX-based implementation ensures that no single intermediary node can:
Determine the payment source or destination
Learn their position in the route
Discover the total path length
Link packets belonging to the same payment
This privacy-preserving architecture, combined with source-based routing, creates a censorship-resistant payment network where users maintain control over their transaction paths while protecting their financial privacy.


