ARCH1.md (6919B)
1 # BOLT4 Architecture 2 3 ## Overview 4 5 BOLT4 specifies the onion routing protocol for Lightning Network payments. 6 The protocol enables source-routed payments where each intermediate node 7 only learns the identity of its immediate predecessor and successor. 8 9 The implementation divides into six logical layers: 10 11 ``` 12 ┌─────────────────────────────────────────────────────────┐ 13 │ Public API │ 14 │ construct, process, unwrapError, createBlindedPath │ 15 ├─────────────────────────────────────────────────────────┤ 16 │ Packet Construction │ 17 │ Session keys, filler generation, layered encryption │ 18 ├──────────────────────┬──────────────────────────────────┤ 19 │ Packet Processing │ Error Handling │ 20 │ Decrypt, extract, │ Failure codes, obfuscation, │ 21 │ forward/terminate │ attribution │ 22 ├──────────────────────┴──────────────────────────────────┤ 23 │ Route Blinding │ 24 │ Blinded paths, encrypted recipient data │ 25 ├─────────────────────────────────────────────────────────┤ 26 │ Types/Codec │ 27 │ OnionPacket, HopPayload, TLV encoding, BigSize │ 28 ├─────────────────────────────────────────────────────────┤ 29 │ Cryptographic Primitives │ 30 │ Key derivation, ECDH, blinding, ChaCha20 streams │ 31 └─────────────────────────────────────────────────────────┘ 32 ``` 33 34 ## Module Structure 35 36 ``` 37 Lightning.Protocol.BOLT4 38 ├── Prim -- Cryptographic primitives 39 ├── Types -- Core data types 40 ├── Codec -- Serialization (BigSize, TLV) 41 ├── Construct -- Packet construction (sender) 42 ├── Process -- Packet processing (receiver) 43 ├── Error -- Failure messages and attribution 44 └── Blinding -- Route blinding (optional) 45 ``` 46 47 ## Layer Details 48 49 ### 1. Cryptographic Primitives (Prim) 50 51 Core crypto operations used throughout: 52 53 **Key Derivation** (HMAC-SHA256 with key-type prefixes): 54 - `rho` (0x72686f): generates obfuscation stream 55 - `mu` (0x6d75): HMAC for packet integrity 56 - `um` (0x756d): HMAC for error messages 57 - `pad` (0x706164): filler generation 58 - `ammag` (0x616d6d6167): error obfuscation 59 60 **Shared Secret**: ECDH between ephemeral key and hop pubkey, then SHA256. 61 62 **Blinding Factor**: SHA256(ephemeral_pubkey || shared_secret). 63 64 **Pseudo-Random Stream**: ChaCha20 with derived key, 96-bit zero nonce, 65 encrypting zeros to produce keystream. 66 67 ### 2. Types 68 69 **OnionPacket** (1366 bytes): 70 ``` 71 ┌─────────┬──────────────┬─────────────┬──────┐ 72 │ version │ ephemeral_pk │ hop_payloads│ hmac │ 73 │ 1 byte │ 33 bytes │ 1300 bytes │ 32 │ 74 └─────────┴──────────────┴─────────────┴──────┘ 75 ``` 76 77 **HopPayload**: Variable-length TLV stream with BigSize length prefix. 78 Contains routing info (amt_to_forward, cltv, short_channel_id, etc.). 79 80 **FailureMessage**: 2-byte code + failure-specific data + optional TLV. 81 82 ### 3. Codec 83 84 **BigSize**: Variable-length integer encoding (1, 3, 5, or 9 bytes). 85 86 **TLV**: Type-Length-Value records with BigSize type and length fields. 87 88 Standard payload TLV types: 89 - 2: amt_to_forward 90 - 4: outgoing_cltv_value 91 - 6: short_channel_id 92 - 8: payment_data 93 - 10: encrypted_recipient_data 94 - 12: current_path_key 95 96 ### 4. Packet Construction (Sender) 97 98 Algorithm (reverse iteration from final hop to first): 99 100 1. Generate random session key 101 2. Derive ephemeral keypair for first hop 102 3. Compute shared secrets and blinding factors for all hops 103 4. Initialize 1300-byte buffer with random bytes (using pad key) 104 5. For each hop (reverse order): 105 a. Right-shift buffer by payload size 106 b. Insert: BigSize length + payload + HMAC 107 c. XOR entire buffer with rho stream 108 d. Compute new HMAC using mu key 109 6. Overwrite tail with filler (accounts for accumulated shifts) 110 7. Return: version || ephemeral_pk || buffer || final_hmac 111 112 ### 5. Packet Processing (Receiver) 113 114 1. Validate version (must be 0x00) 115 2. Compute shared secret via ECDH 116 3. Derive mu, rho keys 117 4. Verify HMAC (constant-time compare) 118 5. Generate 2600-byte stream, XOR with hop_payloads (extended) 119 6. Parse BigSize length, extract payload and next_hmac 120 7. Decision: 121 - next_hmac == 0: final destination 122 - next_hmac != 0: forward to next hop 123 8. For forwarding: compute blinded ephemeral key, shift buffer 124 125 ### 6. Error Handling 126 127 **Construction** (failing node): 128 1. Build failure message (code + data) 129 2. Pad to ≥256 bytes 130 3. Prepend length and compute HMAC using um key 131 4. XOR with ammag stream 132 133 **Unwrapping** (origin): 134 1. For each hop (forward order): 135 - Derive ammag, um keys from shared secret 136 - XOR to decrypt 137 - Check HMAC 138 - If valid: found failing node 139 - If invalid: strip layer, continue 140 141 ### 7. Route Blinding (Optional) 142 143 Creates paths where intermediate nodes don't know their position: 144 145 1. Generate ephemeral keypair (e₀, E₀) 146 2. For each node i: 147 - Compute shared secret ss_i = SHA256(ECDH(e_i, N_i)) 148 - Derive rho_i for encrypting recipient data 149 - Compute blinded node ID: B_i = HMAC("blinded_node_id", ss_i) × N_i 150 - Blind ephemeral key for next hop 151 3. Encrypt per-hop data with ChaCha20-Poly1305 152 153 ## Constants 154 155 ```haskell 156 onionPacketSize = 1366 -- total packet size 157 hopPayloadsSize = 1300 -- payload area 158 maxHops = 20 -- typical maximum 159 hmacSize = 32 -- HMAC-SHA256 output 160 pubkeySize = 33 -- compressed secp256k1 161 versionByte = 0x00 -- protocol version 162 ``` 163 164 ## Dependencies 165 166 Internal (ppad-*): 167 - ppad-secp256k1: ECDH, point multiplication, pubkey parsing 168 - ppad-sha256: hashing for shared secrets, blinding 169 - ppad-hmac-sha256: key derivation, packet integrity 170 - ppad-chacha: pseudo-random stream generation 171 172 External: none (besides GHC boot libs).