bolt7

Routing gossip protocol, per BOLT #7 (docs.ppad.tech/bolt7).
git clone git://git.ppad.tech/bolt7.git
Log | Files | Refs | README | LICENSE

CRC32C.hs (1325B)


      1 {-# LANGUAGE BangPatterns #-}
      2 
      3 -- |
      4 -- Module: Lightning.Protocol.BOLT7.CRC32C
      5 -- Copyright: (c) 2025 Jared Tobin
      6 -- License: MIT
      7 -- Maintainer: Jared Tobin <jared@ppad.tech>
      8 --
      9 -- CRC-32C (Castagnoli) implementation for BOLT #7 checksums.
     10 --
     11 -- This is an internal helper module implementing CRC-32C as specified
     12 -- in RFC 3720. CRC-32C uses the Castagnoli polynomial 0x1EDC6F41.
     13 
     14 module Lightning.Protocol.BOLT7.CRC32C (
     15     crc32c
     16   ) where
     17 
     18 import Data.Bits (shiftR, xor, (.&.))
     19 import Data.ByteString (ByteString)
     20 import qualified Data.ByteString as BS
     21 import Data.Word (Word8, Word32)
     22 
     23 -- | CRC-32C polynomial (Castagnoli): 0x1EDC6F41 reflected = 0x82F63B78
     24 crc32cPoly :: Word32
     25 crc32cPoly = 0x82F63B78
     26 {-# INLINE crc32cPoly #-}
     27 
     28 -- | Compute CRC-32C of a bytestring.
     29 --
     30 -- >>> crc32c "123456789"
     31 -- 0xe3069283
     32 crc32c :: ByteString -> Word32
     33 crc32c = xor 0xFFFFFFFF . BS.foldl' updateByte 0xFFFFFFFF
     34 {-# INLINE crc32c #-}
     35 
     36 -- | Update CRC with a single byte.
     37 updateByte :: Word32 -> Word8 -> Word32
     38 updateByte !crc !byte =
     39   let crc' = crc `xor` fromIntegral byte
     40   in  go 8 crc'
     41   where
     42     go :: Int -> Word32 -> Word32
     43     go 0 !c = c
     44     go !n !c =
     45       let c' = if c .&. 1 /= 0
     46                then (c `shiftR` 1) `xor` crc32cPoly
     47                else c `shiftR` 1
     48       in  go (n - 1) c'
     49 {-# INLINE updateByte #-}