README.md (4572B)
1 # ppad-bolt8 2 3 [](https://hackage.haskell.org/package/ppad-bolt8) 4  5 [](https://docs.ppad.tech/bolt8) 6 7 A pure Haskell implementation of [BOLT #8][bolt8], the Lightning 8 Network's encrypted and authenticated transport: the 9 `Noise_XK_secp256k1_ChaChaPoly_SHA256` handshake, followed by 10 length-prefixed, authenticated encryption of messages with periodic key 11 rotation. 12 13 ## Usage 14 15 A sample GHCi session: 16 17 ``` 18 > :set -XOverloadedStrings 19 > import qualified Data.ByteString as BS 20 > import qualified Lightning.Protocol.BOLT8 as BOLT8 21 > 22 > -- static keypairs (use 32 bytes of secure randomness in practice) 23 > let Just i = BOLT8.keypair (BS.replicate 32 0x11) 24 > let Just r = BOLT8.keypair (BS.replicate 32 0x21) 25 > 26 > -- ephemeral entropy MUST be fresh, uniformly random bytes 27 > let i_ent = BS.replicate 32 0x12 28 > let r_ent = BS.replicate 32 0x22 29 > 30 > -- the initiator knows the responder's static public key 31 > let Right (msg1, i_hs) = BOLT8.act1 i (BOLT8.keypair_pub r) i_ent 32 > let Right (msg2, r_hs) = BOLT8.act2 r r_ent msg1 33 > let Right (msg3, i_res) = BOLT8.act3 i_hs msg2 34 > let Right r_res = BOLT8.finalize r_hs msg3 35 > 36 > -- the responder has authenticated the initiator's static key 37 > BOLT8.handshake_remote_static r_res == BOLT8.keypair_pub i 38 True 39 > 40 > -- each side gets a Sender and a Receiver 41 > let i_snd = BOLT8.handshake_sender i_res 42 > let r_rcv = BOLT8.handshake_receiver r_res 43 > 44 > -- every operation returns the next state; never reuse an old one 45 > let Right (ct, i_snd') = BOLT8.encrypt i_snd "hello" 46 > let Right (pt, r_rcv') = BOLT8.decrypt r_rcv ct 47 > pt 48 "hello" 49 > 50 > -- on a byte stream: decrypt the 18-byte header, which says how many 51 > -- bytes to read next, then decrypt the rest of the frame 52 > let Right (ct', _) = BOLT8.encrypt i_snd' "world" 53 > let (hdr, rest) = BS.splitAt 18 ct' 54 > let Right (n, pending) = BOLT8.decrypt_header r_rcv' hdr 55 > n 56 21 57 > fmap fst (BOLT8.decrypt_body pending (BS.take n rest)) 58 Right "world" 59 ``` 60 61 The `Sender` and `Receiver` are independent, so a writer thread can own 62 one and a reader thread the other. Any error from a handshake or 63 transport function means the connection must be closed. 64 65 ## Documentation 66 67 Haddocks (API documentation, etc.) are hosted at 68 [docs.ppad.tech/bolt8][hadoc]. 69 70 ## Specification 71 72 This library implements BOLT #8 as of [lightning/bolts@1aadb719][spec] 73 (2026-09-21), a copy of which is in `etc/08-transport.md`. 74 75 The library is pure, and leaves the following to the caller: 76 77 * Network I/O, including reading exactly the number of bytes each step 78 requires, and terminating the connection on any failure. 79 * Generating ephemeral keys: `act1` and `act2` take the ephemeral 80 secret key as 32 bytes of caller-supplied entropy. 81 82 ## Security 83 84 This library aims at the maximum security achievable in a 85 garbage-collected language under an optimizing compiler such as GHC, in 86 which strict constant-timeness can be [challenging to achieve][const]. 87 88 The implementation passes all BOLT #8 Appendix A test vectors, 89 including every handshake failure case and the message vectors spanning 90 two key rotations. The cryptography is provided by 91 [ppad-secp256k1][secp] (ECDH, using constant-time scalar 92 multiplication), [ppad-aead][aead] (ChaCha20-Poly1305, with 93 constant-time MAC verification), [ppad-hkdf][hkdf] and 94 [ppad-sha256][sha256]. 95 96 Session state is a pure value that each operation advances. Reusing an 97 old `Sender` reuses a nonce, and reusing an old `Receiver` accepts 98 replayed frames; see the module documentation. 99 100 If you discover any vulnerabilities, please disclose them via 101 security@ppad.tech. 102 103 ## Development 104 105 You'll require [Nix][nixos] with [flake][flake] support enabled. Enter a 106 development shell with: 107 108 ``` 109 $ nix develop 110 ``` 111 112 Then do e.g.: 113 114 ``` 115 $ cabal build 116 $ cabal test 117 $ cabal bench 118 ``` 119 120 [bolt8]: https://github.com/lightning/bolts/blob/master/08-transport.md 121 [spec]: https://github.com/lightning/bolts/blob/1aadb719b4007c4cea0ba6e36b08c4fb53788dee/08-transport.md 122 [nixos]: https://nixos.org/ 123 [flake]: https://nixos.org/manual/nix/unstable/command-ref/new-cli/nix3-flake.html 124 [hadoc]: https://docs.ppad.tech/bolt8 125 [const]: https://www.chosenplaintext.ca/articles/beginners-guide-constant-time-cryptography.html 126 [secp]: https://git.ppad.tech/secp256k1 127 [aead]: https://git.ppad.tech/aead 128 [hkdf]: https://git.ppad.tech/hkdf 129 [sha256]: https://git.ppad.tech/sha256