bolt8

Encrypted and authenticated transport, per BOLT #8 (docs.ppad.tech/bolt8).
git clone git://git.ppad.tech/bolt8.git
Log | Files | Refs | README | LICENSE

BOLT8.hs (2610B)


      1 {-# OPTIONS_HADDOCK prune #-}
      2 
      3 -- |
      4 -- Module: Lightning.Protocol.BOLT8
      5 -- Copyright: (c) 2025 Jared Tobin
      6 -- License: MIT
      7 -- Maintainer: Jared Tobin <jared@ppad.tech>
      8 --
      9 -- Encrypted and authenticated transport for the Lightning
     10 -- Network, per
     11 -- [BOLT #8](https://github.com/lightning/bolts/blob/master/08-transport.md).
     12 --
     13 -- This module implements the
     14 -- Noise_XK_secp256k1_ChaChaPoly_SHA256 handshake and
     15 -- subsequent encrypted message transport.
     16 --
     17 -- = Handshake
     18 --
     19 -- A BOLT #8 handshake consists of three acts. The
     20 -- /initiator/ knows the responder's static public key in
     21 -- advance and initiates the connection:
     22 --
     23 -- @
     24 -- (msg1, state) <- act1 i_sec i_pub r_pub entropy
     25 -- -- send msg1 (50 bytes) to responder
     26 -- -- receive msg2 (50 bytes) from responder
     27 -- (msg3, result) <- act3 state msg2
     28 -- -- send msg3 (66 bytes) to responder
     29 -- let session = 'session' result
     30 -- @
     31 --
     32 -- The /responder/ receives the connection and authenticates
     33 -- the initiator:
     34 --
     35 -- @
     36 -- -- receive msg1 (50 bytes) from initiator
     37 -- (msg2, state) <- act2 r_sec r_pub entropy msg1
     38 -- -- send msg2 (50 bytes) to initiator
     39 -- -- receive msg3 (66 bytes) from initiator
     40 -- result <- finalize state msg3
     41 -- let session = 'session' result
     42 -- @
     43 --
     44 -- = Message Transport
     45 --
     46 -- After a successful handshake, use 'encrypt' and 'decrypt'
     47 -- to exchange messages. Each returns an updated 'Session'
     48 -- that must be used for the next operation (keys rotate
     49 -- every 1000 messages):
     50 --
     51 -- @
     52 -- -- sender
     53 -- (ciphertext, session') <- 'encrypt' session plaintext
     54 --
     55 -- -- receiver
     56 -- (plaintext, session') <- 'decrypt' session ciphertext
     57 -- @
     58 --
     59 -- = Message Framing
     60 --
     61 -- BOLT #8 runs over a byte stream, so callers often need to
     62 -- deal with partial buffers. Use 'decrypt_frame' when you
     63 -- have exactly one frame, or 'decrypt_frame_partial' to
     64 -- handle incremental reads and return how many bytes are
     65 -- still needed.
     66 --
     67 -- Maximum plaintext size is 65535 bytes.
     68 
     69 module Lightning.Protocol.BOLT8 (
     70     -- * Keys
     71     Sec
     72   , Pub
     73   , keypair
     74   , parse_pub
     75   , serialize_pub
     76 
     77     -- * Newtypes
     78   , Key32
     79   , key32
     80   , unKey32
     81   , SessionNonce
     82   , unSessionNonce
     83   , MessagePayload
     84   , unMessagePayload
     85   , mkMessagePayload
     86 
     87     -- * Handshake roles
     88   , Initiator
     89   , Responder
     90   , HandshakeFor
     91 
     92     -- * Handshake (initiator)
     93   , act1
     94   , act3
     95 
     96     -- * Handshake (responder)
     97   , act2
     98   , finalize
     99 
    100     -- * Session
    101   , Session
    102   , HandshakeState
    103   , Handshake(..)
    104   , encrypt
    105   , decrypt
    106   , decrypt_frame
    107   , decrypt_frame_partial
    108   , FrameResult(..)
    109 
    110     -- * Errors
    111   , Error(..)
    112   ) where
    113 
    114 import Lightning.Protocol.BOLT8.Internal