diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,11 @@
 # Revision history for circe
 
+## 0.2.0.0 -- 8-14-26
+
+* CRC8 and CRC64 support
+* Additional CRC predefined configs
+* Update & generalize API
+
 ## 0.1.0.0 -- 8-12-26
 
 * First version. Released on an unsuspecting world.
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -2,15 +2,14 @@
 
 CRC cyclic redundancy check
 
-Support CRC16 & CRC32
+Support CRC8, CRC16, CRC32, and CRC64
 
 Usage
 
 ```
-crc 16 --help                  # crc options
-crc 32 --help
+crc (8|16|32|64) --help        # crc options
 echo -n "hello world" | crc 16 # stream stdin
-crc 16 100gb.bin               # stream file
+crc 32 100gb.bin               # stream file
 ```
 
 Development
diff --git a/circe.cabal b/circe.cabal
--- a/circe.cabal
+++ b/circe.cabal
@@ -1,8 +1,8 @@
 cabal-version:      3.0
 name:               circe
-version:            0.1.0.0
+version:            0.2.0.0
 synopsis:           CRC
-description:        Cyclic redundancy check CRC16 CRC32
+description:        Cyclic redundancy check CRC8 CRC16 CRC32 CRC64
 homepage:           https://github.com/dopamane/circe
 license:            MIT
 license-file:       LICENSE
@@ -24,9 +24,6 @@
   hs-source-dirs:   lib
   exposed-modules:
     Codec.Circe,
-    Codec.Circe.CRC16,
-    Codec.Circe.CRC32,
-    Codec.Circe.Cfg,
     Codec.Circe.Pretty,
     Codec.Circe.Reflect
   build-depends:
@@ -53,11 +50,7 @@
   hs-source-dirs:   test
   type:             exitcode-stdio-1.0
   main-is:          Main.hs
-  other-modules:
-    Test.Circe
-    Test.Circe.CRC16
-    Test.Circe.CRC32
-    Test.Circe.Reflect
+  other-modules:    Test.Circe
   build-depends:
     base,
     circe,
diff --git a/exe/Main.hs b/exe/Main.hs
--- a/exe/Main.hs
+++ b/exe/Main.hs
@@ -1,8 +1,6 @@
 module Main (main) where
 
-import Codec.Circe.CRC16
-import Codec.Circe.CRC32
-import Codec.Circe.Cfg
+import Codec.Circe
 import Codec.Circe.Pretty
 import qualified Data.ByteString.Lazy as BS
 import Data.Version
@@ -14,19 +12,28 @@
 main = do
   cli <- circeCLI $ showVersion version
   case cli of
+    CRC8Table  p -> putStrLn $ table $ w8  <$> crc8Table  p
     CRC16Table p -> putStrLn $ table $ w16 <$> crc16Table p
     CRC32Table p -> putStrLn $ table $ w32 <$> crc32Table p
+    CRC64Table p -> putStrLn $ table $ w64 <$> crc64Table p
+    CRC8  cfg (Just f) -> putStrLn . w8  . crc8  cfg =<< BS.readFile f
+    CRC8  cfg Nothing  -> putStrLn . w8  . crc8  cfg =<< BS.getContents
     CRC16 cfg (Just f) -> putStrLn . w16 . crc16 cfg =<< BS.readFile f
     CRC16 cfg Nothing  -> putStrLn . w16 . crc16 cfg =<< BS.getContents
     CRC32 cfg (Just f) -> putStrLn . w32 . crc32 cfg =<< BS.readFile f
     CRC32 cfg Nothing  -> putStrLn . w32 . crc32 cfg =<< BS.getContents
+    CRC64 cfg (Just f) -> putStrLn . w64 . crc64 cfg =<< BS.readFile f
+    CRC64 cfg Nothing  -> putStrLn . w64 . crc64 cfg =<< BS.getContents
 
 data CirceCLI
-  = CRC16 CRC16Cfg (Maybe String)
+  = CRC8 CRC8Cfg (Maybe String)
+  | CRC16 CRC16Cfg (Maybe String)
   | CRC32 CRC32Cfg (Maybe String)
-  | -- | poly
-    CRC16Table Word16
+  | CRC64 CRC64Cfg (Maybe String)
+  | CRC8Table  Word8
+  | CRC16Table Word16
   | CRC32Table Word32
+  | CRC64Table Word64
 
 -- | run CLI, specify version string
 circeCLI :: String -> IO CirceCLI
@@ -41,73 +48,123 @@
 
 parser :: Parser CirceCLI
 parser = hsubparser $ mconcat
-  [ command "16" $ info crc16Parser $ progDesc "CRC16"
+  [ command "8"  $ info crc8Parser  $ progDesc "CRC8"
+  , command "16" $ info crc16Parser $ progDesc "CRC16"
   , command "32" $ info crc32Parser $ progDesc "CRC32"
+  , command "64" $ info crc64Parser $ progDesc "CRC64"
   ]
 
+crc8Parser :: Parser CirceCLI
+crc8Parser = asum
+  [ CRC8 <$> crc8CfgParser <*> optional fileArg
+  , CRC8Table <$> tableOpt 8
+  ]
+
 crc16Parser :: Parser CirceCLI
 crc16Parser = asum
-  [ CRC16Table <$> tableOpt 16
-  , CRC16 <$> crc16CfgParser <*> optional fileArg
+  [ CRC16 <$> crc16CfgParser <*> optional fileArg
+  , CRC16Table <$> tableOpt 16
   ]
 
 crc32Parser :: Parser CirceCLI
 crc32Parser = asum
-  [ CRC32Table <$> tableOpt 32
-  , CRC32 <$> crc32CfgParser <*> optional fileArg
+  [ CRC32 <$> crc32CfgParser <*> optional fileArg
+  , CRC32Table <$> tableOpt 32
   ]
 
+crc64Parser :: Parser CirceCLI
+crc64Parser = asum
+  [ CRC64 <$> crc64CfgParser <*> optional fileArg
+  , CRC64Table <$> tableOpt 64
+  ]
+
 tableOpt :: (Num a, Read a) => Int -> Parser a
 tableOpt n = option auto $ mconcat
   [ short 't' <> long "table" <> metavar "POLY"
   , help $ "Generate CRC" <> show n <> " lookup table with polynomial"
   ]
 
+crc8CfgParser :: Parser CRC8Cfg
+crc8CfgParser = asum
+  [ flag' crc8Cfg $ long "crc8" <> help ("DEFAULT " ++ showCRC8Cfg crc8Cfg)
+  , flag' crc88H2F $ long "8h2f" <> help (showCRC8Cfg crc88H2F)
+  , flag' crc8CDMA2k $ long "cdma2k" <> help (showCRC8Cfg crc8CDMA2k)
+  , flag' crc8DARC $ long "darc" <> help (showCRC8Cfg crc8DARC)
+  , flag' crc8DVBS2 $ long "dvbs2" <> help (showCRC8Cfg crc8DVBS2)
+  , flag' crc8EBU $ long "ebu" <> help (showCRC8Cfg crc8EBU)
+  , flag' crc8ICode $ long "icode" <> help (showCRC8Cfg crc8ICode)
+  , flag' crc8ITU $ long "itu" <> help (showCRC8Cfg crc8ITU)
+  , flag' crc8Maxim $ long "maxim" <> help (showCRC8Cfg crc8Maxim)
+  , flag' crc8ROHC $ long "rohc" <> help (showCRC8Cfg crc8ROHC)
+  , flag' crc8WCDMA $ long "wcdma" <> help (showCRC8Cfg crc8WCDMA)
+  , crcCfgParser
+  , pure crc8Cfg
+  ]
+
 crc16CfgParser :: Parser CRC16Cfg
 crc16CfgParser = asum
-  [ flag' crc16CCITZero $ long "ccit-zero"
-  , flag' crc16Modbus $ long "modbus"
-  , CRCCfg
-      <$> polyOpt
-      <*> initOpt
-      <*> refinSwitch
-      <*> refoutSwitch
-      <*> finXorOpt
+  [ flag' crc16CCITZero $ long "ccit-zero" <> help ("DEFAULT " ++ showCRC16Cfg crc16CCITZero)
+  , flag' crc16Arc $ long "arc" <> help (showCRC16Cfg crc16Arc)
+  , flag' crc16AugCCITT $ long "aug-ccit" <> help (showCRC16Cfg crc16AugCCITT)
+  , flag' crc16Buypass $ long "buypass" <> help (showCRC16Cfg crc16Buypass)
+  , flag' crc16CCITTFalse $ long "ccitt-false" <> help (showCRC16Cfg crc16CCITTFalse)
+  , flag' crc16CDMA2k $ long "cdma2k" <> help (showCRC16Cfg crc16CDMA2k)
+  , flag' crc16DDS110 $ long "dds110" <> help (showCRC16Cfg crc16DDS110)
+  , flag' crc16DECTR $ long "dectr" <> help (showCRC16Cfg crc16DECTR)
+  , flag' crc16DECTX $ long "dectx" <> help (showCRC16Cfg crc16DECTX)
+  , flag' crc16DNP $ long "dnp" <> help (showCRC16Cfg crc16DNP)
+  , flag' crc16EN13757 $ long "en13757" <> help (showCRC16Cfg crc16EN13757)
+  , flag' crc16Genibus $ long "genibus" <> help (showCRC16Cfg crc16Genibus)
+  , flag' crc16Maxim $ long "maxim" <> help (showCRC16Cfg crc16Maxim)
+  , flag' crc16MCRF4XX $ long "mcrf4xx" <> help (showCRC16Cfg crc16MCRF4XX)
+  , flag' crc16Riello $ long "riello" <> help (showCRC16Cfg crc16Riello)
+  , flag' crc16T10DIF $ long "t10dif" <> help (showCRC16Cfg crc16T10DIF)
+  , flag' crc16Teledisk $ long "teledisk" <> help (showCRC16Cfg crc16Teledisk)
+  , flag' crc16TMS37157 $ long "tms37157" <> help (showCRC16Cfg crc16TMS37157)
+  , flag' crc16USB $ long "usb" <> help (showCRC16Cfg crc16USB)
+  , flag' crc16CRCA $ long "crca" <> help (showCRC16Cfg crc16CRCA)
+  , flag' crc16Kermit $ long "kermit" <> help (showCRC16Cfg crc16Kermit)
+  , flag' crc16Modbus $ long "modbus" <> help (showCRC16Cfg crc16Modbus)
+  , flag' crc16X25 $ long "x25" <> help (showCRC16Cfg crc16X25)
+  , flag' crc16XModem $ long "xmodem" <> help (showCRC16Cfg crc16XModem)
+  , crcCfgParser
+  , pure crc16CCITZero
   ]
 
 crc32CfgParser :: Parser CRC32Cfg
 crc32CfgParser = asum
-  [ CRCCfg
-      <$> option auto (short 'p' <> long "poly" <> metavar "WORD32" <> help "polynomial")
-      <*> option auto (short 'i' <> long "init" <> metavar "WORD32" <> help "initial value")
-      <*> refinSwitch
-      <*> refoutSwitch
-      <*> option auto (short 'x' <> long "xor" <> metavar "WORD32" <> help "final xor")
-  , flag crc32IEEE crc32IEEE $ long "ieee"
-      <> help ("Default CRC32 config "
-                 <> "POLY=0x4C11DB7 INIT=0xFFFFFFFF REFL-IN REFL-OUT FIN-XOR=0xFFFFFFFF")
+  [ flag' crc32IEEE $ long "ieee" <> help ("DEFAULT " ++ showCRC32Cfg crc32IEEE)
+  , flag' crc32BZIP2 $ long "bzip2" <> help (showCRC32Cfg crc32BZIP2)
+  , flag' crc32MPEG2 $ long "mpeg2" <> help (showCRC32Cfg crc32MPEG2)
+  , flag' crc32POSIX $ long "posix" <> help (showCRC32Cfg crc32POSIX)
+  , crcCfgParser
+  , pure crc32IEEE
   ]
 
-polyOpt :: Parser Word16
-polyOpt = option auto $
-  short 'p' <> long "poly" <> metavar "WORD16" <> help "polynomial"
-    <> value 0x1021 <> showDefaultWith w16
+crc64CfgParser :: Parser CRC64Cfg
+crc64CfgParser = asum
+  [ flag' crc64ECMA182 $ long "ecma-182" <> help ("DEFAULT " ++ showCRC64Cfg crc64ECMA182)
+  , flag' crc64GoISO $ long "go-iso" <> help (showCRC64Cfg crc64GoISO)
+  , flag' crc64WE $ long "we" <> help (showCRC64Cfg crc64WE)
+  , flag' crc64XZ $ long "xz" <> help (showCRC64Cfg crc64XZ)
+  , crcCfgParser
+  , pure crc64ECMA182
+  ]
 
-initOpt :: Parser Word16
-initOpt = option auto $
-  short 'i' <> long "init" <> metavar "WORD16" <> help "inital value"
-    <> value 0 <> showDefaultWith w16
+crcCfgParser :: Read a => Parser (CRCCfg a)
+crcCfgParser =
+  CRCCfg
+    <$> option auto (short 'p' <> long "poly" <> help "polynomial")
+    <*> option auto (short 'i' <> long "init" <> help "initial value")
+    <*> refinSwitch
+    <*> refoutSwitch
+    <*> option auto (short 'x' <> long "xor" <> help "final xor")
 
 refinSwitch :: Parser Bool
 refinSwitch = switch $ long "ri" <> long "refin" <> help "reflect input"
 
 refoutSwitch :: Parser Bool
 refoutSwitch = switch $ long "ro" <> long "refout" <> help "reflect output"
-
-finXorOpt :: Parser Word16
-finXorOpt = option auto $
-  short 'x' <> long "xor" <> metavar "WORD16"
-    <> value 0 <> showDefaultWith w16 <> help "final xor"
 
 fileArg :: Parser String
 fileArg = strArgument $
diff --git a/lib/Codec/Circe.hs b/lib/Codec/Circe.hs
--- a/lib/Codec/Circe.hs
+++ b/lib/Codec/Circe.hs
@@ -1,20 +1,295 @@
--- | CRC high-level utilities.
--- See "Codec.Circe.CRC16" and "Codec.Circe.CRC32" for low-level functions.
+-- | CRC utilities.
 module Codec.Circe
-  ( -- ** CRC
-    crc16
-  , crc32
-  , -- ** CONFIG
+  ( -- ** CRC8
+    crc8, crc8WithTable, crc8Table
+  , CRC8Cfg, showCRC8Cfg
+  , crc8Cfg, crc88H2F, crc8CDMA2k, crc8DARC, crc8DVBS2, crc8EBU, crc8ICode
+  , crc8ITU, crc8Maxim, crc8ROHC, crc8WCDMA
+  , -- ** CRC16
+    crc16, crc16WithTable, crc16Table
+  , CRC16Cfg, showCRC16Cfg
+  , crc16CCITZero, crc16Arc, crc16AugCCITT, crc16Buypass, crc16CCITTFalse
+  , crc16CDMA2k, crc16DDS110, crc16DECTR, crc16DECTX, crc16DNP, crc16EN13757
+  , crc16Genibus, crc16Maxim, crc16MCRF4XX, crc16Riello, crc16T10DIF
+  , crc16Teledisk, crc16TMS37157, crc16USB, crc16CRCA, crc16Kermit
+  , crc16Modbus, crc16X25, crc16XModem
+  , -- ** CRC32
+    crc32, crc32WithTable, crc32Table
+  , CRC32Cfg, showCRC32Cfg
+  , crc32IEEE, crc32BZIP2, crc32MPEG2, crc32POSIX
+  , -- ** CRC64
+    crc64, crc64WithTable, crc64Table
+  , CRC64Cfg, showCRC64Cfg
+  , crc64ECMA182, crc64GoISO, crc64WE, crc64XZ
+  , -- ** CRCCfg
     CRCCfg(..)
-  , -- **** CRC16
-    CRC16Cfg
-  , crc16CCITZero
-  , crc16Modbus
-  , -- **** CRC32
-    CRC32Cfg
-  , crc32IEEE
+  , -- ** Unsafe
+    crc, crcWithTable, crcUnsafe, crcTable
   ) where
 
-import Codec.Circe.CRC16
-import Codec.Circe.CRC32
-import Codec.Circe.Cfg
+import Codec.Circe.Pretty
+import Codec.Circe.Reflect
+import Data.Bits
+import Data.ByteString.Lazy (ByteString)
+import qualified Data.ByteString.Lazy as BS
+import Data.Vector.Storable (Vector)
+import qualified Data.Vector.Storable as V
+import Data.Function
+import Data.Word
+
+-- | calculate CRC8 using lookup table generated from config
+crc8 :: CRC8Cfg -> ByteString -> Word8
+crc8 = crc ref8
+-- | calculate CRC16 using lookup table generated from config
+crc16 :: CRC16Cfg -> ByteString -> Word16
+crc16 = crc ref16
+-- | calculate CRC32 using lookup table generated from config
+crc32 :: CRC32Cfg -> ByteString -> Word32
+crc32 = crc ref32
+-- | calculate CRC64 using lookup table generated from config
+crc64 :: CRC64Cfg -> ByteString -> Word64
+crc64 = crc ref64
+
+-- | calculate CRC8 with precalculated poly table
+crc8WithTable :: Vector Word8 -> CRC8Cfg -> ByteString -> Word8
+crc8WithTable = crcWithTable ref8
+-- | calculate CRC16 with precalculated poly table
+crc16WithTable :: Vector Word16 -> CRC16Cfg -> ByteString -> Word16
+crc16WithTable = crcWithTable ref16
+-- | calculate CRC32 with precalculated poly table
+crc32WithTable :: Vector Word32 -> CRC32Cfg -> ByteString -> Word32
+crc32WithTable = crcWithTable ref32
+-- | calculate CRC64 with precalculated poly table
+crc64WithTable :: Vector Word64 -> CRC64Cfg -> ByteString -> Word64
+crc64WithTable = crcWithTable ref64
+
+-- | generate CRC8 lookup table using polynomial
+crc8Table :: Word8 -> [Word8]
+crc8Table = crcTable
+-- | generate CRC16 lookup table using polynomial
+crc16Table :: Word16 -> [Word16]
+crc16Table = crcTable
+-- | generate CRC32 lookup table using polynomial
+crc32Table :: Word32 -> [Word32]
+crc32Table = crcTable
+-- | generate CRC64 lookup table using polynomial
+crc64Table :: Word64 -> [Word64]
+crc64Table = crcTable
+
+-- | calculate CRC using lookup table generated from config
+crc :: (FiniteBits a, Integral a, Num a, V.Storable a) => (a -> a) -> CRCCfg a -> ByteString -> a
+crc ref cfg = crcWithTable ref t cfg
+  where
+    t = V.fromList $ crcTable $ crcPoly cfg
+
+-- | calculate CRC with reflection & precalculated poly table.
+crcWithTable
+  :: (FiniteBits a, Integral a, Num a, V.Storable a)
+  => (a -> a)
+  -> Vector a -> CRCCfg a -> ByteString -> a
+crcWithTable ref t cfg =
+  xor (crcFinXor cfg) . applyWhen (crcRefOut cfg) ref . crcUnsafe t (crcRefIn cfg) (crcInit cfg)
+
+-- | calculate CRC using width, efficient lookup table, input reflection, and init value
+crcUnsafe :: (FiniteBits a, Integral a, Num a, V.Storable a) => Vector a -> Bool -> a -> ByteString -> a
+crcUnsafe t refIn i = BS.foldl' go i
+  where
+    go crc' b = crc' `shiftL` 8 `xor` t `V.unsafeIndex` fromIntegral pos
+      where
+        pos = fromIntegral ((crc' `xor` fromIntegral b' `shiftL` w') `shiftR` w') :: Word8
+          where
+            b' = applyWhen refIn ref8 b
+            w' = finiteBitSize i - 8
+
+-- | Generate CRC table using width and poly
+crcTable :: (FiniteBits a, Enum a, Num a) => a -> [a]
+crcTable poly = calc <$> [0..255]
+  where
+    l    = fromIntegral (finiteBitSize poly) :: Int
+    calc = (!! 8) . iterate step . (`shiftL` (l - 8))
+      where
+        step curByte = applyWhen (testBit curByte $ l - 1) (`xor` poly) $ curByte `shiftL` 1
+
+-- | CRC configuration parameters
+data CRCCfg a = CRCCfg
+  { crcPoly :: a
+    -- ^ polynomial
+  , crcInit :: a
+    -- ^ initial value
+  , crcRefIn :: Bool
+    -- ^ reflect input
+  , crcRefOut :: Bool
+    -- ^ reflect output
+  , crcFinXor :: a
+    -- ^ final xor
+  }
+  deriving (Eq, Read, Show)
+
+instance Functor CRCCfg where
+  fmap f (CRCCfg p i ri ro x) = CRCCfg (f p) (f i) ri ro (f x)
+
+showCRCCfg :: CRCCfg String -> String
+showCRCCfg (CRCCfg p i ri ro x) = unwords ["POLY", p, "INIT", i, showRefl (ri, ro), "XOR", x]
+
+-- | display reflection config
+showRefl :: (Bool, Bool) -> String
+showRefl (ri, ro) = case (ri, ro) of
+  (False, False) -> "NOREFL"
+  (False, True)  -> "REFLOUT"
+  (True,  False) -> "REFLIN"
+  (True,  True)  -> "REFLINOUT"
+
+-- | specialized CRC for 'Word8'
+type CRC8Cfg = CRCCfg Word8
+-- | specialized CRC for 'Word16'
+type CRC16Cfg = CRCCfg Word16
+-- | specialized CRC for 'Word32'
+type CRC32Cfg = CRCCfg Word32
+-- | specialized CRC for 'Word64'
+type CRC64Cfg = CRCCfg Word64
+
+-- | display CRC8 config
+showCRC8Cfg :: CRC8Cfg -> String
+showCRC8Cfg = showCRCCfg . fmap w8
+-- | display CRC16 config
+showCRC16Cfg :: CRC16Cfg -> String
+showCRC16Cfg = showCRCCfg . fmap w16
+-- | display CRC32 config
+showCRC32Cfg :: CRC32Cfg -> String
+showCRC32Cfg = showCRCCfg . fmap w32
+-- | display CRC64 config
+showCRC64Cfg :: CRC64Cfg -> String
+showCRC64Cfg = showCRCCfg . fmap w64
+
+-- | POLY 0x7 INIT 0 NOREFL NOXOR
+crc8Cfg :: CRC8Cfg
+crc8Cfg = CRCCfg 0x7 0x0 False False 0x0
+-- | POLY 0x2F INIT 0xFF NOREFL XOR 0xFF
+crc88H2F :: CRC8Cfg
+crc88H2F = CRCCfg 0x2f 0xff False False 0xff
+-- | POLY 0x9b INIT 0xFF NOREFL NOXOR
+crc8CDMA2k :: CRC8Cfg
+crc8CDMA2k = CRCCfg 0x9b 0xFF False False 0
+-- | POLY 0x39 INIT 0 REFLINOUT NOXOR
+crc8DARC :: CRC8Cfg
+crc8DARC = CRCCfg 0x39 0 True True 0
+-- | POLY 0xD5 INIT 0 NOREFL XOR 0
+crc8DVBS2 :: CRC8Cfg
+crc8DVBS2 = CRCCfg 0xD5 0 False False 0
+-- | POLY 0x1D INIT 0xFF REFLINOUT XOR 0
+crc8EBU :: CRC8Cfg
+crc8EBU = CRCCfg 0x1D 0xFF True True 0
+-- | POLY 0x1D INIT 0xFD NOREFL XOR 0
+crc8ICode :: CRC8Cfg
+crc8ICode = CRCCfg 0x1D 0xFD False False 0
+-- | POLY 0x07 INIT 0x00 NOREFL XOR 0x55
+crc8ITU :: CRC8Cfg
+crc8ITU = CRCCfg 0x07 0x00 False False 0x55
+-- | POLY 0x31 INIT 0 REFLINOUT XOR 0
+crc8Maxim :: CRC8Cfg
+crc8Maxim = CRCCfg 0x31 0 True True 0
+-- | POLY 0x07 INIT 0xFF REFLINOUT XOR 0
+crc8ROHC :: CRC8Cfg
+crc8ROHC = CRCCfg 0x07 0xFF True True 0
+-- | POLY 0x9b INIT 0 REFLINOUT NOXOR
+crc8WCDMA :: CRC8Cfg
+crc8WCDMA = CRCCfg 0x9b 0 True True 0
+
+-- | POLY 0x1021 INIT 0x0000 NOREFL NOXOR
+crc16CCITZero :: CRC16Cfg
+crc16CCITZero = CRCCfg 0x1021 0x0000 False False 0x0000
+-- | POLY 0x8005 INIT 0 REFLINOUT XOR 0
+crc16Arc :: CRC16Cfg
+crc16Arc = CRCCfg 0x8005 0 True True 0
+-- | POLY 0x1021 INIT 0x1D0F NOREFL XOR 0
+crc16AugCCITT :: CRC16Cfg
+crc16AugCCITT = CRCCfg 0x1021 0x1D0F False False 0
+-- | POLY 0x8005 INIT 0 NOREFL XOR 0
+crc16Buypass :: CRC16Cfg
+crc16Buypass = CRCCfg 0x8005 0 False False 0
+-- | POLY 0x1021 INIT 0xFFFF NOREFL XOR 0
+crc16CCITTFalse :: CRC16Cfg
+crc16CCITTFalse = CRCCfg 0x1021 0xFFFF False False 0
+-- | POLY 0xC867 INIT 0xFFFF NOREFL XOR 0
+crc16CDMA2k :: CRC16Cfg
+crc16CDMA2k = CRCCfg 0xC867 0xFFFF False False 0
+-- | POLY 0x8005 INIT 0x800D NOREFL XOR 0
+crc16DDS110 :: CRC16Cfg
+crc16DDS110 = CRCCfg 0x8005 0x800D False False 0
+-- | POLY 0x0589 INIT 0 NOREFL XOR 1
+crc16DECTR :: CRC16Cfg
+crc16DECTR = CRCCfg 0x0589 0 False False 1
+-- | POLY 0x0589 INIT 0 NOREFL XOR 0
+crc16DECTX :: CRC16Cfg
+crc16DECTX = CRCCfg 0x0589 0 False False 0
+-- | POLY 0x3D65 INIT 0 REFLINOUT XOR 0xFFFF
+crc16DNP :: CRC16Cfg
+crc16DNP = CRCCfg 0x3D65 0 True True 0xFFFF
+-- | POLY 0x3D65 INIT 0 NOREFL XOR 0xFFFF
+crc16EN13757 :: CRC16Cfg
+crc16EN13757 = CRCCfg 0x3D65 0 False False 0xFFFF
+-- | POLY 0x1021 INIT 0xFFFF NOREFL XOR 0xFFFF
+crc16Genibus :: CRC16Cfg
+crc16Genibus = CRCCfg 0x1021 0xFFFF False False 0xFFFF
+-- | POLY 0x8005 INIT 0 REFLINOUT XOR 0xFFFF
+crc16Maxim :: CRC16Cfg
+crc16Maxim = CRCCfg 0x8005 0 True True 0xFFFF
+-- | POLY 0x1021 INIT 0xFFFF REFLINOUT XOR 0
+crc16MCRF4XX :: CRC16Cfg
+crc16MCRF4XX = CRCCfg 0x1021 0xFFFF True True 0
+-- | POLY 0x1021 INIT 0xB2AA REFLINOUT XOR 0
+crc16Riello :: CRC16Cfg
+crc16Riello = CRCCfg 0x1021 0xB2AA True True 0
+-- | POLY 0x8BB7 INIT 0 NOREFL XOR 0
+crc16T10DIF :: CRC16Cfg
+crc16T10DIF = CRCCfg 0x8BB7 0 False False 0
+-- | POLY 0xA097 INIT 0 NOREFL XOR 0
+crc16Teledisk :: CRC16Cfg
+crc16Teledisk = CRCCfg 0xA097 0 False False 0
+-- | POLY 0x1021 INIT 0x89EC REFLINOUT XOR 0
+crc16TMS37157 :: CRC16Cfg
+crc16TMS37157 = CRCCfg 0x1021 0x89EC True True 0
+-- | POLY 0x8005 INIT 0xFFFF REFLINOUT XOR 0xFFFF
+crc16USB :: CRC16Cfg
+crc16USB = CRCCfg 0x8005 0xFFFF True True 0xFFFF
+-- | POLY 0x1021 INIT 0xC6C6 REFLINOUT XOR 0
+crc16CRCA :: CRC16Cfg
+crc16CRCA = CRCCfg 0x1021 0xC6C6 True True 0
+-- | POLY 0x1021 INIT 0 REFLINOUT XOR 0
+crc16Kermit :: CRC16Cfg
+crc16Kermit = CRCCfg 0x1021 0 True True 0
+-- | POLY 0x8005 INIT 0XFFFF REFLINOUT NOXOR
+crc16Modbus :: CRC16Cfg
+crc16Modbus = CRCCfg 0x8005 0xFFFF True True 0x0000
+-- | POLY 0x1021 INIT 0xFFFF REFLINOUT XOR 0xFFFF
+crc16X25 :: CRC16Cfg
+crc16X25 = CRCCfg 0x1021 0xFFFF True True 0xFFFF
+-- | POLY 0x1021 INIT 0 NOREFL XOR 0
+crc16XModem :: CRC16Cfg
+crc16XModem = CRCCfg 0x1021 0 False False 0
+
+-- | POLY 0x4C11DB7 INIT 0xFFFFFFFF REFLINOUT XOR 0xFFFFFFFF
+crc32IEEE :: CRC32Cfg
+crc32IEEE = CRCCfg 0x4C11DB7 0xFFFFFFFF True True 0xFFFFFFFF
+-- | POLY 0x4C11DB7 INIT 0xFFFFFFFF NOREFL XOR 0xFFFFFFFF
+crc32BZIP2 :: CRC32Cfg
+crc32BZIP2 = CRCCfg 0x4C11DB7 0xFFFFFFFF False False 0xFFFFFFFF
+-- | POLY 0x4C11DB7 INIT 0xFFFFFFFF NOREFL XOR 0
+crc32MPEG2 :: CRC32Cfg
+crc32MPEG2 = CRCCfg 0x4C11DB7 0xFFFFFFFF False False 0
+-- | POLY 0x4C11DB7 INIT 0 NOREFL XOR 0xFFFFFFFF
+crc32POSIX :: CRC32Cfg
+crc32POSIX = CRCCfg 0x4C11DB7 0 False False 0xFFFFFFFF
+
+-- | POLY 0x42F0E1EBA9EA3693 INIT 0 NOREFL XOR 0
+crc64ECMA182 :: CRC64Cfg
+crc64ECMA182 = CRCCfg 0x42F0E1EBA9EA3693 0 False False 0
+-- | POLY 0x000000000000001B INIT 0xFFFFFFFFFFFFFFFF REFLINOUT XOR 0xFFFFFFFFFFFFFFFF
+crc64GoISO :: CRC64Cfg
+crc64GoISO = CRCCfg 0x000000000000001B 0xFFFFFFFFFFFFFFFF True True 0xFFFFFFFFFFFFFFFF
+-- | POLY 0x42F0E1EBA9EA3693 INIT 0xFFFFFFFFFFFFFFFF NOREFL XOR 0xFFFFFFFFFFFFFFFF
+crc64WE :: CRC64Cfg
+crc64WE = CRCCfg 0x42F0E1EBA9EA3693 0xFFFFFFFFFFFFFFFF False False 0xFFFFFFFFFFFFFFFF
+-- | POLY 0x42F0E1EBA9EA3693 INIT 0xFFFFFFFFFFFFFFFF REFLINOUT XOR 0xFFFFFFFFFFFFFFFF
+crc64XZ :: CRC64Cfg
+crc64XZ = CRCCfg 0x42F0E1EBA9EA3693 0xFFFFFFFFFFFFFFFF True True 0xFFFFFFFFFFFFFFFF
diff --git a/lib/Codec/Circe/CRC16.hs b/lib/Codec/Circe/CRC16.hs
deleted file mode 100644
--- a/lib/Codec/Circe/CRC16.hs
+++ /dev/null
@@ -1,48 +0,0 @@
--- | CRC16 utilities
-module Codec.Circe.CRC16
-  ( crc16
-  , crc16WithTable
-  , crc16Unsafe
-  , crc16Table
-  ) where
-
-import Codec.Circe.Cfg
-import Codec.Circe.Reflect
-import Data.Bits
-import Data.ByteString.Lazy (ByteString)
-import qualified Data.ByteString.Lazy as BS
-import Data.Vector.Storable (Vector)
-import qualified Data.Vector.Storable as V
-import Data.Function
-import Data.Monoid
-import Data.Semigroup
-import Data.Word
-
--- | calculate CRC16 using lookup table generated from config
-crc16 :: CRC16Cfg -> ByteString -> Word16
-crc16 cfg = crc16WithTable t cfg
-  where
-    t = V.fromList $ crc16Table $ crcPoly cfg
-
--- | calculate CRC16 with precalculated poly table
-crc16WithTable :: Vector Word16 -> CRC16Cfg -> ByteString -> Word16
-crc16WithTable t cfg =
-  xor (crcFinXor cfg)
-    . applyWhen (crcRefOut cfg) ref16
-    . crc16Unsafe t (crcRefIn cfg) (crcInit cfg)
-
--- | calculate CRC16 using an efficient lookup table and init value
-crc16Unsafe :: Vector Word16 -> Bool -> Word16 -> ByteString -> Word16
-crc16Unsafe t refIn = BS.foldl' go
-  where
-    go crc b = crc `shiftL` 8 `xor` t `V.unsafeIndex` fromIntegral pos
-      where
-        pos = fromIntegral (crc `shiftR` 8) `xor` applyWhen refIn ref8 b
-
--- | generate lookup table using polynomial
-crc16Table :: Word16 -> [Word16]
-crc16Table poly = calc <$> [0..255]
-  where
-    calc = appEndo (stimes (8 :: Int) $ Endo step) . (`shiftL` 8)
-      where
-        step curByte = applyWhen (testBit curByte 15) (`xor` poly) $ curByte `shiftL` 1
diff --git a/lib/Codec/Circe/CRC32.hs b/lib/Codec/Circe/CRC32.hs
deleted file mode 100644
--- a/lib/Codec/Circe/CRC32.hs
+++ /dev/null
@@ -1,50 +0,0 @@
--- | CRC32 utilities
-module Codec.Circe.CRC32
-  ( crc32
-  , crc32WithTable
-  , crc32Unsafe
-  , crc32Table
-  ) where
-
-import Codec.Circe.Cfg
-import Codec.Circe.Reflect
-import Data.Bits
-import Data.ByteString.Lazy (ByteString)
-import qualified Data.ByteString.Lazy as BS
-import Data.Vector.Storable (Vector)
-import qualified Data.Vector.Storable as V
-import Data.Function
-import Data.Monoid
-import Data.Semigroup
-import Data.Word
-
--- | calculate CRC32 using lookup table generated from config
-crc32 :: CRC32Cfg -> ByteString -> Word32
-crc32 cfg = crc32WithTable t cfg
-  where
-    t = V.fromList $ crc32Table $ crcPoly cfg
-
--- | calculate CRC32 with precalculated poly table.
-crc32WithTable :: Vector Word32 -> CRC32Cfg -> ByteString -> Word32
-crc32WithTable t cfg =
-  xor (crcFinXor cfg)
-    . applyWhen (crcRefOut cfg) ref32
-    . crc32Unsafe t (crcRefIn cfg) (crcInit cfg)
-
--- | calculate CRC32 using an efficient lookup table and init value
-crc32Unsafe :: Vector Word32 -> Bool -> Word32 -> ByteString -> Word32
-crc32Unsafe t refIn = BS.foldl' go
-  where
-    go crc b = crc `shiftL` 8 `xor` t `V.unsafeIndex` fromIntegral pos
-      where
-        pos = fromIntegral ((crc `xor` (fromIntegral b' `shiftL` 24)) `shiftR` 24) :: Word8
-          where
-            b' = applyWhen refIn ref8 b
-
--- | generate lookup table using polynomial
-crc32Table :: Word32 -> [Word32]
-crc32Table poly = calc <$> [0..255]
-  where
-    calc = appEndo (stimes (8 :: Int) $ Endo step) . (`shiftL` 24)
-      where
-        step curByte = applyWhen (testBit curByte 31) (`xor` poly) $ curByte `shiftL` 1
diff --git a/lib/Codec/Circe/Cfg.hs b/lib/Codec/Circe/Cfg.hs
deleted file mode 100644
--- a/lib/Codec/Circe/Cfg.hs
+++ /dev/null
@@ -1,43 +0,0 @@
--- | CRC configurations
-module Codec.Circe.Cfg
-  ( CRCCfg(..)
-  , CRC16Cfg
-  , crc16CCITZero
-  , crc16Modbus
-  , CRC32Cfg
-  , crc32IEEE
-  ) where
-
-import Data.Word
-
--- | CRC configuration parameters
-data CRCCfg a = CRCCfg
-  { crcPoly :: a
-    -- ^ polynomial
-  , crcInit :: a
-    -- ^ initial value
-  , crcRefIn :: Bool
-    -- ^ reflect input
-  , crcRefOut :: Bool
-    -- ^ reflect output
-  , crcFinXor :: a
-    -- ^ final xor
-  }
-  deriving (Eq, Read, Show)
-
--- | specialized CRC for 'Word16'
-type CRC16Cfg = CRCCfg Word16
--- | specialized CRC for 'Word32'
-type CRC32Cfg = CRCCfg Word32
-
--- | POLY 0x1021 INIT 0x0000 NOREFL NOXOR
-crc16CCITZero :: CRC16Cfg
-crc16CCITZero = CRCCfg 0x1021 0x0000 False False 0x0000
-
--- | POLY 0x8005 INIT 0XFFFF REFLINOUT NOXOR
-crc16Modbus :: CRC16Cfg
-crc16Modbus = CRCCfg 0x8005 0xFFFF True True 0x0000
-
--- | POLY 0x4C11DB7 INIT 0xFFFFFFFF REFLINOUT XOR 0xFFFFFFFF
-crc32IEEE :: CRC32Cfg
-crc32IEEE = CRCCfg 0x4C11DB7 0xFFFFFFFF True True 0xFFFFFFFF
diff --git a/lib/Codec/Circe/Pretty.hs b/lib/Codec/Circe/Pretty.hs
--- a/lib/Codec/Circe/Pretty.hs
+++ b/lib/Codec/Circe/Pretty.hs
@@ -1,7 +1,9 @@
 -- | prettyprinting utilities
 module Codec.Circe.Pretty
-  ( w16
+  ( w8
+  , w16
   , w32
+  , w64
   , table
   ) where
 
@@ -9,24 +11,41 @@
 import Data.Word
 import Numeric
 
+-- | @0x0a@
+w8 :: Word8 -> String
+w8 w = "0x" ++ w8' w
+
+-- | pretty word8 without 0x prefix
+w8' :: Word8 -> String
+w8' w = showHex (w `shiftR` 4) "" ++ showHex (w .&. 0xF) ""
+
 -- | @0x01ab@
 w16 :: Word16 -> String
 w16 w = "0x" ++ w16' w
 
 -- | pretty word16 without 0x prefix
 w16' :: Word16 -> String
-w16' w = w3 ++ w2 ++ w1 ++ w0
+w16' w = w8' h ++ w8' l
   where
-    w3 = showHex (w `shiftR` 12) ""
-    w2 = showHex (w `shiftR` 8 .&. 0xF) ""
-    w1 = showHex (w `shiftR` 4 .&. 0xF) ""
-    w0 = showHex (w .&. 0xF) ""
+    h = fromIntegral $ w `shiftR` 8
+    l = fromIntegral w
 
 -- | @0x0123abcd@
 w32 :: Word32 -> String
-w32 w = "0x" ++ w16' h ++ w16' l
+w32 w = "0x" ++ w32' w
+
+-- | pretty word32 without 0x prefix
+w32' :: Word32 -> String
+w32' w = w16' h ++ w16' l
   where
     h = fromIntegral $ w `shiftR` 16
+    l = fromIntegral w
+
+-- | @0x01234567abcdefff@
+w64 :: Word64 -> String
+w64 w = "0x" ++ w32' h ++ w32' l
+  where
+    h = fromIntegral $ w `shiftR` 32
     l = fromIntegral w
 
 -- | prettyprint 8 cols across
diff --git a/lib/Codec/Circe/Reflect.hs b/lib/Codec/Circe/Reflect.hs
--- a/lib/Codec/Circe/Reflect.hs
+++ b/lib/Codec/Circe/Reflect.hs
@@ -1,17 +1,30 @@
 -- | Reflect bits
-module Codec.Circe.Reflect (ref32, ref16, ref8) where
+module Codec.Circe.Reflect (ref64, ref32, ref16, ref8) where
 
 import Data.Bits
+import Data.Vector.Storable (Vector)
+import qualified Data.Vector.Storable as V
 import Data.Word
 
+-- | Reflect 'Word64'
+ref64 :: Word64 -> Word64
+ref64 = s1 . s2 . s4 . s8 . s16 . s32
+  where
+    s1  n = ((n .&. 0xAAAAAAAAAAAAAAAA) `shiftR` 1)  .|. ((n .&. 0x5555555555555555) `shiftL` 1)
+    s2  n = ((n .&. 0xCCCCCCCCCCCCCCCC) `shiftR` 2)  .|. ((n .&. 0x3333333333333333) `shiftL` 2)
+    s4  n = ((n .&. 0xF0F0F0F0F0F0F0F0) `shiftR` 4)  .|. ((n .&. 0x0F0F0F0F0F0F0F0F) `shiftL` 4)
+    s8  n = ((n .&. 0xFF00FF00FF00FF00) `shiftR` 8)  .|. ((n .&. 0x00FF00FF00FF00FF) `shiftL` 8)
+    s16 n = ((n .&. 0xFFFF0000FFFF0000) `shiftR` 16) .|. ((n .&. 0x0000FFFF0000FFFF) `shiftL` 16)
+    s32 n = (n `shiftR` 32) .|. (n `shiftL` 32)
+
 -- | Reflect 'Word32'
 ref32 :: Word32 -> Word32
 ref32 = s1 . s2 . s4 . s8 . s16
   where
-    s1 n = ((n .&. 0xAAAAAAAA) `shiftR` 1) .|. ((n .&. 0x55555555) `shiftL` 1)
-    s2 n = ((n .&. 0xCCCCCCCC) `shiftR` 2) .|. ((n .&. 0x33333333) `shiftL` 2)
-    s4 n = ((n .&. 0xF0F0F0F0) `shiftR` 4) .|. ((n .&. 0x0F0F0F0F) `shiftL` 4)
-    s8 n = ((n .&. 0xFF00FF00) `shiftR` 8) .|. ((n .&. 0x00FF00FF) `shiftL` 8)
+    s1  n = ((n .&. 0xAAAAAAAA) `shiftR` 1) .|. ((n .&. 0x55555555) `shiftL` 1)
+    s2  n = ((n .&. 0xCCCCCCCC) `shiftR` 2) .|. ((n .&. 0x33333333) `shiftL` 2)
+    s4  n = ((n .&. 0xF0F0F0F0) `shiftR` 4) .|. ((n .&. 0x0F0F0F0F) `shiftL` 4)
+    s8  n = ((n .&. 0xFF00FF00) `shiftR` 8) .|. ((n .&. 0x00FF00FF) `shiftL` 8)
     s16 n = (n `shiftR` 16) .|. (n `shiftL` 16)
 
 -- | Reflect 'Word16'
@@ -25,8 +38,40 @@
 
 -- | Reflect 'Word8'
 ref8 :: Word8 -> Word8
-ref8 = s1 . s2 . s4
-  where
-    s1 n = ((n .&. 0xAA) `shiftR` 1) .|. ((n .&. 0x55) `shiftL` 1)
-    s2 n = ((n .&. 0xCC) `shiftR` 2) .|. ((n .&. 0x33) `shiftL` 2)
-    s4 n = (n `shiftR` 4) .|. (n `shiftL` 4)
+ref8 = V.unsafeIndex ref8Table . fromIntegral
+
+ref8Table :: Vector Word8
+ref8Table = V.fromList
+  [ 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0
+  , 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0
+  , 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8
+  , 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8
+  , 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4
+  , 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4
+  , 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec
+  , 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc
+  , 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2
+  , 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2
+  , 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea
+  , 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa
+  , 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6
+  , 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6
+  , 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee
+  , 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe
+  , 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1
+  , 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1
+  , 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9
+  , 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9
+  , 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5
+  , 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5
+  , 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed
+  , 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd
+  , 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3
+  , 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3
+  , 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb
+  , 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb
+  , 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7
+  , 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7
+  , 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef
+  , 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff
+  ]
diff --git a/test/Test/Circe.hs b/test/Test/Circe.hs
--- a/test/Test/Circe.hs
+++ b/test/Test/Circe.hs
@@ -1,16 +1,99 @@
+{-# LANGUAGE BinaryLiterals     #-}
+{-# LANGUAGE NumericUnderscores #-}
+{-# LANGUAGE OverloadedStrings  #-}
 module Test.Circe (testCirce) where
 
-import qualified Test.Circe.CRC16 as CRC16
-import qualified Test.Circe.CRC32 as CRC32
-import qualified Test.Circe.Reflect as Reflect
+import Codec.Circe
+import Codec.Circe.Reflect
+import qualified Data.Vector.Storable as V
 import Test.Tasty
+import Test.Tasty.HUnit
 
 testCirce :: IO ()
 testCirce = defaultMain tests
 
 tests :: TestTree
 tests = testGroup "Test.Circe"
-  [ CRC16.tests
-  , CRC32.tests
-  , Reflect.tests
+  [ testGroup "CRC8"
+    [ crc8Test
+    ]
+  , testGroup "CRC16"
+    [ crc16UnsafeTest
+    , crc16Test
+    ]
+  , testGroup "CRC32"
+    [ crc32UnsafeTest
+    , crc32Test
+    ]
+  , testGroup "CRC64"
+    [ crc64Test
+    ]
+  , testGroup "Reflect"
+    [ ref8Test
+    , ref16Test
+    , ref32Test
+    ]
   ]
+
+crc8Test :: TestTree
+crc8Test = testCaseSteps "crc8" $ \step -> do
+  step "crc8"
+  crc8 crc8Cfg "alpha and omega" @?= 0x6f
+  crc8 crc8Cfg "black and yellow" @?= 0x67
+  step "crc88H2F"
+  crc8 crc88H2F "yamborghini high" @?= 0x02
+  step "crc8CDMA2k"
+  crc8 crc8CDMA2k "asdfgh" @?= 0x79
+  step "crc8DARC"
+  crc8 crc8DARC "i am god" @?= 0x5a
+  step "crc8ITU"
+  crc8 crc8ITU "OMG itz GODZILLA!" @?= 0xf9
+  step "crc8WCDMA"
+  crc8 crc8WCDMA "city of angels" @?= 0x5d
+
+crc16UnsafeTest :: TestTree
+crc16UnsafeTest = testCase "crc16Unsafe" $
+  crcUnsafe (V.fromList t) False 0 "bosscoxwuzhere" @?= 0xbe42
+  where
+    t = crc16Table 0x1021
+
+crc16Test :: TestTree
+crc16Test = testCaseSteps "crc16" $ \step -> do
+  step "modbus"
+  crc16 crc16Modbus "hello world" @?= 0xddc7
+  step "X25"
+  crc16 crc16X25 "city of angels" @?= 0x5386
+
+crc32UnsafeTest :: TestTree
+crc32UnsafeTest = testCase "crc32Unsafe" $
+  crcUnsafe (V.fromList t) False 0 "hello world" @?= 0x737af2ae
+  where
+    t = crc32Table 0x4c11db7
+
+crc32Test :: TestTree
+crc32Test = testCase "crc32" $ do
+  crc32 crc32IEEE "bo$$ cox rulez" @?= 0x75ce60a3
+  crc32 crc32IEEE "hello world"    @?= 0x0d4a1185
+  crc32 crc32IEEE "YOLO DOLO"      @?= 0xa13ee2ed
+
+crc64Test :: TestTree
+crc64Test = testCaseSteps "crc64" $ \step -> do
+  step "ECMA182"
+  crc64 crc64ECMA182 "fast cars" @?= 0x5c991e3b22f9bd5f
+  step "XZ"
+  crc64 crc64XZ "goodbye" @?= 0x8F627A49FD449B48
+
+ref8Test :: TestTree
+ref8Test = testCase "ref8" $
+  ref8 0b1011_1110
+   @?= 0b0111_1101
+
+ref16Test :: TestTree
+ref16Test = testCase "ref16" $
+  ref16 0b1010_1111_0000_0011
+    @?= 0b1100_0000_1111_0101
+
+ref32Test :: TestTree
+ref32Test = testCase "ref32" $
+  ref32 0b1110_0111_0000_0000_1111_1111_1010_1010
+    @?= 0b0101_0101_1111_1111_0000_0000_1110_0111
diff --git a/test/Test/Circe/CRC16.hs b/test/Test/Circe/CRC16.hs
deleted file mode 100644
--- a/test/Test/Circe/CRC16.hs
+++ /dev/null
@@ -1,27 +0,0 @@
-{-# LANGUAGE OverloadedStrings #-}
-
-module Test.Circe.CRC16 (tests) where
-
-import Codec.Circe.CRC16
-import Codec.Circe.Cfg
---import Data.Vector.Storable (Vector)
-import qualified Data.Vector.Storable as V
-import Test.Tasty
-import Test.Tasty.HUnit
-
-tests :: TestTree
-tests = testGroup "CRC16"
-  [ crc16UnsafeTest
-  , crc16Test
-  ]
-
-crc16UnsafeTest :: TestTree
-crc16UnsafeTest = testCase "crc16Unsafe" $
-  crc16Unsafe (V.fromList t) False 0 "bosscoxwuzhere" @?= 0xbe42
-  where
-    t = crc16Table 0x1021
-
-crc16Test :: TestTree
-crc16Test = testCaseSteps "crc16" $ \step -> do
-  step "modbus"
-  crc16 crc16Modbus "hello world" @?= 0xddc7
diff --git a/test/Test/Circe/CRC32.hs b/test/Test/Circe/CRC32.hs
deleted file mode 100644
--- a/test/Test/Circe/CRC32.hs
+++ /dev/null
@@ -1,27 +0,0 @@
-{-# LANGUAGE OverloadedStrings #-}
-
-module Test.Circe.CRC32 (tests) where
-
-import Codec.Circe.CRC32
-import Codec.Circe.Cfg
-import qualified Data.Vector.Storable as V
-import Test.Tasty
-import Test.Tasty.HUnit
-
-tests :: TestTree
-tests = testGroup "CRC32"
-  [ crc32UnsafeTest
-  , crc32Test
-  ]
-
-crc32UnsafeTest :: TestTree
-crc32UnsafeTest = testCase "crc32Unsafe" $
-  crc32Unsafe (V.fromList t) False 0 "hello world" @?= 0x737af2ae
-  where
-    t = crc32Table 0x4c11db7
-
-crc32Test :: TestTree
-crc32Test = testCase "crc32" $ do
-  crc32 crc32IEEE "bo$$ cox rulez" @?= 0x75ce60a3
-  crc32 crc32IEEE "hello world"    @?= 0x0d4a1185
-  crc32 crc32IEEE "YOLO DOLO"      @?= 0xa13ee2ed
diff --git a/test/Test/Circe/Reflect.hs b/test/Test/Circe/Reflect.hs
deleted file mode 100644
--- a/test/Test/Circe/Reflect.hs
+++ /dev/null
@@ -1,30 +0,0 @@
-{-# LANGUAGE BinaryLiterals     #-}
-{-# LANGUAGE NumericUnderscores #-}
-
-module Test.Circe.Reflect (tests) where
-
-import Codec.Circe.Reflect
-import Test.Tasty
-import Test.Tasty.HUnit
-
-tests :: TestTree
-tests = testGroup "Reflect"
-  [ ref8Test
-  , ref16Test
-  , ref32Test
-  ]
-
-ref8Test :: TestTree
-ref8Test = testCase "ref8" $
-  ref8 0b1011_1110
-   @?= 0b0111_1101
-
-ref16Test :: TestTree
-ref16Test = testCase "ref16" $
-  ref16 0b1010_1111_0000_0011
-    @?= 0b1100_0000_1111_0101
-
-ref32Test :: TestTree
-ref32Test = testCase "ref32" $
-  ref32 0b1110_0111_0000_0000_1111_1111_1010_1010
-    @?= 0b0101_0101_1111_1111_0000_0000_1110_0111
