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 #-}