diff --git a/Bench/BenchHMAC.hs b/Bench/BenchHMAC.hs
new file mode 100644
--- /dev/null
+++ b/Bench/BenchHMAC.hs
@@ -0,0 +1,12 @@
+
+import Criterion.Main
+import Crypto.Hash
+import qualified Data.ByteString as B
+import Data.Byteable
+
+main = do
+    let b32 = B.replicate 32 0
+    defaultMain
+        [ bench "hmac-md5" $ whnf (toBytes . hmacAlg MD5 b32) b32
+        , bench "hmac-sha1" $ whnf (toBytes . hmacAlg SHA1 b32) b32
+        ]
diff --git a/Crypto/Hash.hs b/Crypto/Hash.hs
--- a/Crypto/Hash.hs
+++ b/Crypto/Hash.hs
@@ -1,5 +1,5 @@
-{-# LANGUAGE EmptyDataDecls #-}
 {-# LANGUAGE CPP #-}
+{-# LANGUAGE PackageImports #-}
 -- |
 -- Module      : Crypto.Hash
 -- License     : BSD-style
@@ -7,8 +7,17 @@
 -- Stability   : experimental
 -- Portability : unknown
 --
--- Crypto hash main module
+-- Generalized cryptographic hash interface, that you can use with cryptographic hash
+-- algorithm that belong to the HashAlgorithm type class.
 --
+-- > import Crypto.Hash
+-- >
+-- > sha1 :: ByteString -> Digest SHA1
+-- > sha1 = hash
+-- >
+-- > hexSha3_512 :: ByteString -> String
+-- > hexSha3_512 bs = show (hash bs :: Digest SHA3_512)
+--
 module Crypto.Hash
     (
     -- * Types
@@ -23,56 +32,44 @@
     , hash
     , hashlazy
     , hashUpdate
+    , hashInitAlg
     -- * hash algorithms
-    , MD2
-    , MD4
-    , MD5
-    , SHA1
-    , SHA224
-    , SHA256
-    , SHA384
-    , SHA512
-    , RIPEMD160
-    , Tiger
-    , SHA3_224
-    , SHA3_256
-    , SHA3_384
-    , SHA3_512
-    , Skein256_224
-    , Skein256_256
-    , Skein512_224
-    , Skein512_256
-    , Skein512_384
-    , Skein512_512
-    , Whirlpool
+    , H.MD2(..)
+    , H.MD4(..)
+    , H.MD5(..)
+    , H.SHA1(..)
+    , H.SHA224(..)
+    , H.SHA256(..)
+    , H.SHA384(..)
+    , H.SHA512(..)
+    , H.RIPEMD160(..)
+    , H.Tiger(..)
+    , H.SHA3_224(..)
+    , H.SHA3_256(..)
+    , H.SHA3_384(..)
+    , H.SHA3_512(..)
+    , H.Skein256_224(..)
+    , H.Skein256_256(..)
+    , H.Skein512_224(..)
+    , H.Skein512_256(..)
+    , H.Skein512_384(..)
+    , H.Skein512_512(..)
+    , H.Whirlpool(..)
     -- * MAC algorithms
     , HMAC(..)
     , hmac
-    )
-    where
+    , hmacAlg
+    ) where
 
 import Crypto.Hash.Types
-import Crypto.Hash.Utils
 import Data.ByteString (ByteString)
 import Data.Byteable
 import Data.Bits (xor)
 import qualified Data.ByteString as B
+import qualified Data.ByteArray.Encoding as B
 import qualified Data.ByteString.Lazy as L
 
-import qualified Crypto.Hash.MD2 as MD2
-import qualified Crypto.Hash.MD4 as MD4
-import qualified Crypto.Hash.MD5 as MD5
-import qualified Crypto.Hash.SHA1 as SHA1
-import qualified Crypto.Hash.SHA224 as SHA224
-import qualified Crypto.Hash.SHA256 as SHA256
-import qualified Crypto.Hash.SHA384 as SHA384
-import qualified Crypto.Hash.SHA512 as SHA512
-import qualified Crypto.Hash.SHA3 as SHA3
-import qualified Crypto.Hash.RIPEMD160 as RIPEMD160
-import qualified Crypto.Hash.Tiger as Tiger
-import qualified Crypto.Hash.Skein256 as Skein256
-import qualified Crypto.Hash.Skein512 as Skein512
-import qualified Crypto.Hash.Whirlpool as Whirlpool
+import qualified "cryptonite" Crypto.Hash as H
 
 -- | Alias to a single pass hash function that operate on a strict bytestring
 type HashFunctionBS a = ByteString -> Digest a
@@ -94,73 +91,138 @@
 
 -- | Return the hexadecimal (base16) bytestring of the digest
 digestToHexByteString :: Digest a -> ByteString
-digestToHexByteString = toHex . toBytes
+digestToHexByteString = B.convertToBase B.Base16 . toBytes
 
-#define DEFINE_INSTANCE(NAME, MODULENAME) \
-data NAME; \
-instance HashAlgorithm NAME where \
-    { hashInit = Context c where { (MODULENAME.Ctx c) = MODULENAME.init } \
-    ; hashUpdates (Context c) bs = Context nc where { (MODULENAME.Ctx nc) = MODULENAME.updates (MODULENAME.Ctx c) bs } \
-    ; hashFinalize (Context c) = Digest $ MODULENAME.finalize (MODULENAME.Ctx c) \
-    ; digestFromByteString bs = if B.length bs == len then (Just $ Digest bs) else Nothing where { len = B.length (MODULENAME.finalize MODULENAME.init) } \
+-- | Class representing hashing algorithms.
+--
+-- The hash algorithm is built over 3 primitives:
+--
+-- * init     : create a new hashing context
+--
+-- * updates  : update the hashing context with some strict bytestrings
+--              and return the new context
+--
+-- * finalize : finalize the context into a digest
+--
+class HashAlgorithm a where
+    -- | Block size in bytes the hash algorithm operates on
+    hashBlockSize :: Context a -> Int
+
+    -- | Initialize a new context for this hash algorithm
+    hashInit     :: Context a
+
+    -- | Update the context with a list of strict bytestring,
+    -- and return a new context with the updates.
+    hashUpdates  :: Context a -> [ByteString] -> Context a
+
+    -- | Finalize a context and return a digest.
+    hashFinalize :: Context a -> Digest a
+
+    -- | Try to convert a binary digest bytestring to a digest.
+    digestFromByteString :: ByteString -> Maybe (Digest a)
+
+
+#define DEFINE_INSTANCE(NAME, MODULENAME, BLOCKSIZE) \
+instance HashAlgorithm H.NAME where \
+    { hashInit = Context $ H.hashInit \
+    ; hashBlockSize ~(Context _) = BLOCKSIZE \
+    ; hashUpdates (Context c) bs = Context $ H.hashUpdates c bs \
+    ; hashFinalize (Context c) = Digest $ H.hashFinalize c \
+    ; digestFromByteString bs = Digest `fmap` H.digestFromByteString bs \
     };
 
-#define DEFINE_INSTANCE_LEN(NAME, MODULENAME, LEN) \
-data NAME; \
-instance HashAlgorithm NAME where \
-    { hashInit = Context c where { (MODULENAME.Ctx c) = MODULENAME.init LEN } \
-    ; hashUpdates (Context c) bs = Context nc where { (MODULENAME.Ctx nc) = MODULENAME.updates (MODULENAME.Ctx c) bs } \
-    ; hashFinalize (Context c) = Digest $ MODULENAME.finalize (MODULENAME.Ctx c) \
-    ; digestFromByteString bs = if B.length bs == len then (Just $ Digest bs) else Nothing where { len = B.length (MODULENAME.finalize (MODULENAME.init LEN)) } \
+#define DEFINE_INSTANCE_LEN(NAME, MODULENAME, LEN, BLOCKSIZE) \
+instance HashAlgorithm H.NAME where \
+    { hashInit = Context $ H.hashInit \
+    ; hashBlockSize ~(Context _) = BLOCKSIZE \
+    ; hashUpdates (Context c) bs = Context $ H.hashUpdates c bs \
+    ; hashFinalize (Context c) = Digest $ H.hashFinalize c \
+    ; digestFromByteString bs = Digest `fmap` H.digestFromByteString bs \
     };
 
-DEFINE_INSTANCE(MD2, MD2)
-DEFINE_INSTANCE(MD4, MD4)
-DEFINE_INSTANCE(MD5, MD5)
-DEFINE_INSTANCE(SHA1, SHA1)
-DEFINE_INSTANCE(SHA224, SHA224)
-DEFINE_INSTANCE(SHA256, SHA256)
-DEFINE_INSTANCE(SHA384, SHA384)
-DEFINE_INSTANCE(SHA512, SHA512)
+-- | MD2 cryptographic hash
+DEFINE_INSTANCE(MD2, MD2, 16)
+-- | MD4 cryptographic hash
+DEFINE_INSTANCE(MD4, MD4, 64)
+-- | MD5 cryptographic hash
+DEFINE_INSTANCE(MD5, MD5, 64)
+-- | SHA1 cryptographic hash
+DEFINE_INSTANCE(SHA1, SHA1, 64)
+-- | SHA224 cryptographic hash
+DEFINE_INSTANCE(SHA224, SHA224, 64)
+-- | SHA256 cryptographic hash
+DEFINE_INSTANCE(SHA256, SHA256, 64)
+-- | SHA384 cryptographic hash
+DEFINE_INSTANCE(SHA384, SHA384, 128)
+-- | SHA512 cryptographic hash
+DEFINE_INSTANCE(SHA512, SHA512, 128)
 
-DEFINE_INSTANCE(RIPEMD160, RIPEMD160)
-DEFINE_INSTANCE(Whirlpool, Whirlpool)
-DEFINE_INSTANCE(Tiger, Tiger)
+-- | RIPEMD160 cryptographic hash
+DEFINE_INSTANCE(RIPEMD160, RIPEMD160, 64)
+-- | Whirlpool cryptographic hash
+DEFINE_INSTANCE(Whirlpool, Whirlpool, 64)
+-- | Tiger cryptographic hash
+DEFINE_INSTANCE(Tiger, Tiger, 64)
 
-DEFINE_INSTANCE_LEN(SHA3_224, SHA3, 224)
-DEFINE_INSTANCE_LEN(SHA3_256, SHA3, 256)
-DEFINE_INSTANCE_LEN(SHA3_384, SHA3, 384)
-DEFINE_INSTANCE_LEN(SHA3_512, SHA3, 512)
+-- | SHA3 (224 bits version) cryptographic hash
+DEFINE_INSTANCE_LEN(SHA3_224, SHA3, 224, 144)
+-- | SHA3 (256 bits version) cryptographic hash
+DEFINE_INSTANCE_LEN(SHA3_256, SHA3, 256, 136)
+-- | SHA3 (384 bits version) cryptographic hash
+DEFINE_INSTANCE_LEN(SHA3_384, SHA3, 384, 104)
+-- | SHA3 (512 bits version) cryptographic hash
+DEFINE_INSTANCE_LEN(SHA3_512, SHA3, 512, 72)
 
-DEFINE_INSTANCE_LEN(Skein256_224, Skein256, 224)
-DEFINE_INSTANCE_LEN(Skein256_256, Skein256, 256)
+-- | Skein256 (224 bits version) cryptographic hash
+DEFINE_INSTANCE_LEN(Skein256_224, Skein256, 224, 32)
+-- | Skein256 (256 bits version) cryptographic hash
+DEFINE_INSTANCE_LEN(Skein256_256, Skein256, 256, 32)
 
-DEFINE_INSTANCE_LEN(Skein512_224, Skein512, 224)
-DEFINE_INSTANCE_LEN(Skein512_256, Skein512, 256)
-DEFINE_INSTANCE_LEN(Skein512_384, Skein512, 384)
-DEFINE_INSTANCE_LEN(Skein512_512, Skein512, 512)
+-- | Skein512 (224 bits version) cryptographic hash
+DEFINE_INSTANCE_LEN(Skein512_224, Skein512, 224, 64)
+-- | Skein512 (256 bits version) cryptographic hash
+DEFINE_INSTANCE_LEN(Skein512_256, Skein512, 256, 64)
+-- | Skein512 (384 bits version) cryptographic hash
+DEFINE_INSTANCE_LEN(Skein512_384, Skein512, 384, 64)
+-- | Skein512 (512 bits version) cryptographic hash
+DEFINE_INSTANCE_LEN(Skein512_512, Skein512, 512, 64)
 
+-- | Initialize a new context for a specified hash algorithm
+hashInitAlg :: HashAlgorithm alg => alg -> Context alg
+hashInitAlg _ = hashInit
+
 -- | Represent an HMAC that is a phantom type with the hash used to produce the mac.
 --
 -- The Eq instance is constant time.
-data HMAC a = HMAC ByteString
+newtype HMAC a = HMAC { hmacGetDigest :: Digest a }
 
 instance Byteable (HMAC a) where
-    toBytes (HMAC b) = b
+    toBytes (HMAC b) = toBytes b
 
 instance Eq (HMAC a) where
-    (HMAC b1) == (HMAC b2) = constEqBytes b1 b2
+    (HMAC b1) == (HMAC b2) = constEqBytes (toBytes b1) (toBytes b2)
 
 -- | compute a MAC using the supplied hashing function
-hmac :: HashFunctionBS a -- ^ Hash function to use
-     -> Int              -- ^ Block size in bytes of the hash function
-     -> ByteString       -- ^ Secret key
+hmac :: HashAlgorithm a
+     => ByteString       -- ^ Secret key
      -> ByteString       -- ^ Message to MAC
      -> HMAC a
-hmac hashF blockSize secret msg = HMAC $ toBytes $ hashF $ B.append opad (toBytes $ hashF $ B.append ipad msg)
-    where opad = B.map (xor 0x5c) k'
-          ipad = B.map (xor 0x36) k'
+hmac secret msg = doHMAC hashInit
+  where doHMAC :: HashAlgorithm a => Context a -> HMAC a
+        doHMAC ctxInit = HMAC $ hashF $ B.append opad (toBytes $ hashF $ B.append ipad msg)
+          where opad = B.map (xor 0x5c) k'
+                ipad = B.map (xor 0x36) k'
 
-          k'  = B.append kt pad
-          kt  = if B.length secret > fromIntegral blockSize then toBytes (hashF secret) else secret
-          pad = B.replicate (fromIntegral blockSize - B.length kt) 0
+                k'  = B.append kt pad
+                kt  = if B.length secret > fromIntegral blockSize then toBytes (hashF secret) else secret
+                pad = B.replicate (fromIntegral blockSize - B.length kt) 0
+                hashF = hashFinalize . hashUpdate ctxInit
+                blockSize = hashBlockSize ctxInit
+
+-- | compute a HMAC using a specified algorithm
+hmacAlg :: HashAlgorithm a
+        => a           -- ^ the hash algorithm the actual value is unused.
+        -> ByteString  -- ^ Secret key
+        -> ByteString  -- ^ Message to MAC
+        -> HMAC a
+hmacAlg _ secret msg = hmac secret msg
diff --git a/Crypto/Hash/Internal.hs b/Crypto/Hash/Internal.hs
--- a/Crypto/Hash/Internal.hs
+++ b/Crypto/Hash/Internal.hs
@@ -1,4 +1,5 @@
 {-# LANGUAGE CPP #-}
+{-# LANGUAGE PackageImports #-}
 
 -- |
 -- Module      : Crypto.Hash.Internal
@@ -6,9 +7,16 @@
 -- Maintainer  : Vincent Hanquez <vincent@snarc.org>
 -- Stability   : experimental
 -- Portability : unknown
-module Crypto.Hash.Internal where
+module Crypto.Hash.Internal
+    ( unsafeDoIO
+    , digestToByteString
+    , digestToByteStringWitness
+    ) where
 
 import System.IO.Unsafe
+import Data.ByteArray (convert)
+import "cryptonite" Crypto.Hash
+import Data.ByteString (ByteString)
 
 -- | perform io for hashes that do allocation and ffi.
 -- unsafeDupablePerformIO is used when possible as the
@@ -21,4 +29,10 @@
 #else
 unsafeDoIO = unsafePerformIO
 #endif
+
+digestToByteString :: HashAlgorithm h => Digest h -> ByteString
+digestToByteString = convert
+
+digestToByteStringWitness :: HashAlgorithm h => h -> Digest h -> ByteString
+digestToByteStringWitness _ = convert
 
diff --git a/Crypto/Hash/MD2.hs b/Crypto/Hash/MD2.hs
--- a/Crypto/Hash/MD2.hs
+++ b/Crypto/Hash/MD2.hs
@@ -1,4 +1,4 @@
-{-# LANGUAGE ForeignFunctionInterface #-}
+{-# LANGUAGE PackageImports #-}
 
 -- |
 -- Module      : Crypto.Hash.MD2
@@ -24,109 +24,36 @@
     ) where
 
 import Prelude hiding (init)
-import Foreign.Ptr
-import Foreign.ForeignPtr (withForeignPtr)
-import Foreign.Storable
-import Foreign.Marshal.Alloc
 import qualified Data.ByteString.Lazy as L
-import qualified Data.ByteString as B
 import Data.ByteString (ByteString)
-import Data.ByteString.Unsafe (unsafeUseAsCStringLen)
-import Data.ByteString.Internal (create, toForeignPtr)
-import Data.Word
-import Crypto.Hash.Internal (unsafeDoIO)
-
-newtype Ctx = Ctx ByteString
-
-{-# INLINE digestSize #-}
-digestSize :: Int
-digestSize = 16
-
-{-# INLINE sizeCtx #-}
-sizeCtx :: Int
-sizeCtx = 96
-
-{-# RULES "digestSize" B.length (finalize init) = digestSize #-}
-{-# RULES "hash" forall b. finalize (update init b) = hash b #-}
-{-# RULES "hash.list1" forall b. finalize (updates init [b]) = hash b #-}
-{-# RULES "hashmany" forall b. finalize (foldl update init b) = hashlazy (L.fromChunks b) #-}
-{-# RULES "hashlazy" forall b. finalize (foldl update init $ L.toChunks b) = hashlazy b #-}
-
-{-# INLINE withByteStringPtr #-}
-withByteStringPtr :: ByteString -> (Ptr Word8 -> IO a) -> IO a
-withByteStringPtr b f =
-    withForeignPtr fptr $ \ptr -> f (ptr `plusPtr` off)
-    where (fptr, off, _) = toForeignPtr b
-
-{-# INLINE memcopy64 #-}
-memcopy64 :: Ptr Word64 -> Ptr Word64 -> IO ()
-memcopy64 dst src = mapM_ peekAndPoke [0..(12-1)]
-    where peekAndPoke i = peekElemOff src i >>= pokeElemOff dst i
-
-withCtxCopy :: Ctx -> (Ptr Ctx -> IO ()) -> IO Ctx
-withCtxCopy (Ctx ctxB) f = Ctx `fmap` createCtx
-    where createCtx = create sizeCtx $ \dstPtr ->
-                      withByteStringPtr ctxB $ \srcPtr -> do
-                          memcopy64 (castPtr dstPtr) (castPtr srcPtr)
-                          f (castPtr dstPtr)
-
-withCtxThrow :: Ctx -> (Ptr Ctx -> IO a) -> IO a
-withCtxThrow (Ctx ctxB) f =
-    allocaBytes sizeCtx $ \dstPtr ->
-    withByteStringPtr ctxB $ \srcPtr -> do
-        memcopy64 (castPtr dstPtr) (castPtr srcPtr)
-        f (castPtr dstPtr)
-
-withCtxNew :: (Ptr Ctx -> IO ()) -> IO Ctx
-withCtxNew f = Ctx `fmap` create sizeCtx (f . castPtr)
-
-withCtxNewThrow :: (Ptr Ctx -> IO a) -> IO a
-withCtxNewThrow f = allocaBytes sizeCtx (f . castPtr)
-
-foreign import ccall unsafe "md2.h md2_init"
-    c_md2_init :: Ptr Ctx -> IO ()
-
-foreign import ccall "md2.h md2_update"
-    c_md2_update :: Ptr Ctx -> Ptr Word8 -> Word32 -> IO ()
-
-foreign import ccall unsafe "md2.h md2_finalize"
-    c_md2_finalize :: Ptr Ctx -> Ptr Word8 -> IO ()
+import Crypto.Hash.Internal (digestToByteString, digestToByteStringWitness)
 
-updateInternalIO :: Ptr Ctx -> ByteString -> IO ()
-updateInternalIO ptr d =
-    unsafeUseAsCStringLen d (\(cs, len) -> c_md2_update ptr (castPtr cs) (fromIntegral len))
+import qualified "cryptonite" Crypto.Hash as H
 
-finalizeInternalIO :: Ptr Ctx -> IO ByteString
-finalizeInternalIO ptr = create digestSize (c_md2_finalize ptr)
+-- | MD2 Context
+newtype Ctx = Ctx (H.Context H.MD2)
 
-{-# NOINLINE init #-}
 -- | init a context
 init :: Ctx
-init = unsafeDoIO $ withCtxNew $ c_md2_init
+init = Ctx H.hashInit
 
-{-# NOINLINE update #-}
 -- | update a context with a bytestring
 update :: Ctx -> ByteString -> Ctx
-update ctx d = unsafeDoIO $ withCtxCopy ctx $ \ptr -> updateInternalIO ptr d
+update (Ctx ctx) d = Ctx $ H.hashUpdate ctx d
 
-{-# NOINLINE updates #-}
 -- | updates a context with multiples bytestring
 updates :: Ctx -> [ByteString] -> Ctx
-updates ctx d = unsafeDoIO $ withCtxCopy ctx $ \ptr -> mapM_ (updateInternalIO ptr) d
+updates (Ctx ctx) d =
+    Ctx $ H.hashUpdates ctx d
 
-{-# NOINLINE finalize #-}
 -- | finalize the context into a digest bytestring
 finalize :: Ctx -> ByteString
-finalize ctx = unsafeDoIO $ withCtxThrow ctx finalizeInternalIO
+finalize (Ctx ctx) = digestToByteString $ H.hashFinalize ctx
 
-{-# NOINLINE hash #-}
 -- | hash a strict bytestring into a digest bytestring
 hash :: ByteString -> ByteString
-hash d = unsafeDoIO $ withCtxNewThrow $ \ptr -> do
-    c_md2_init ptr >> updateInternalIO ptr d >> finalizeInternalIO ptr
+hash d = digestToByteStringWitness H.MD2 $ H.hash d
 
-{-# NOINLINE hashlazy #-}
 -- | hash a lazy bytestring into a digest bytestring
 hashlazy :: L.ByteString -> ByteString
-hashlazy l = unsafeDoIO $ withCtxNewThrow $ \ptr -> do
-    c_md2_init ptr >> mapM_ (updateInternalIO ptr) (L.toChunks l) >> finalizeInternalIO ptr
+hashlazy l = digestToByteStringWitness H.MD2 $ H.hashlazy l
diff --git a/Crypto/Hash/MD4.hs b/Crypto/Hash/MD4.hs
--- a/Crypto/Hash/MD4.hs
+++ b/Crypto/Hash/MD4.hs
@@ -1,4 +1,4 @@
-{-# LANGUAGE ForeignFunctionInterface #-}
+{-# LANGUAGE PackageImports #-}
 
 -- |
 -- Module      : Crypto.Hash.MD4
@@ -24,109 +24,36 @@
     ) where
 
 import Prelude hiding (init)
-import Foreign.Ptr
-import Foreign.ForeignPtr (withForeignPtr)
-import Foreign.Storable
-import Foreign.Marshal.Alloc
 import qualified Data.ByteString.Lazy as L
-import qualified Data.ByteString as B
 import Data.ByteString (ByteString)
-import Data.ByteString.Unsafe (unsafeUseAsCStringLen)
-import Data.ByteString.Internal (create, toForeignPtr)
-import Data.Word
-import Crypto.Hash.Internal (unsafeDoIO)
-
-newtype Ctx = Ctx ByteString
-
-{-# INLINE digestSize #-}
-digestSize :: Int
-digestSize = 16
-
-{-# INLINE sizeCtx #-}
-sizeCtx :: Int
-sizeCtx = 96
-
-{-# RULES "digestSize" B.length (finalize init) = digestSize #-}
-{-# RULES "hash" forall b. finalize (update init b) = hash b #-}
-{-# RULES "hash.list1" forall b. finalize (updates init [b]) = hash b #-}
-{-# RULES "hashmany" forall b. finalize (foldl update init b) = hashlazy (L.fromChunks b) #-}
-{-# RULES "hashlazy" forall b. finalize (foldl update init $ L.toChunks b) = hashlazy b #-}
-
-{-# INLINE withByteStringPtr #-}
-withByteStringPtr :: ByteString -> (Ptr Word8 -> IO a) -> IO a
-withByteStringPtr b f =
-    withForeignPtr fptr $ \ptr -> f (ptr `plusPtr` off)
-    where (fptr, off, _) = toForeignPtr b
-
-{-# INLINE memcopy64 #-}
-memcopy64 :: Ptr Word64 -> Ptr Word64 -> IO ()
-memcopy64 dst src = mapM_ peekAndPoke [0..(12-1)]
-    where peekAndPoke i = peekElemOff src i >>= pokeElemOff dst i
-
-withCtxCopy :: Ctx -> (Ptr Ctx -> IO ()) -> IO Ctx
-withCtxCopy (Ctx ctxB) f = Ctx `fmap` createCtx
-    where createCtx = create sizeCtx $ \dstPtr ->
-                      withByteStringPtr ctxB $ \srcPtr -> do
-                          memcopy64 (castPtr dstPtr) (castPtr srcPtr)
-                          f (castPtr dstPtr)
-
-withCtxThrow :: Ctx -> (Ptr Ctx -> IO a) -> IO a
-withCtxThrow (Ctx ctxB) f =
-    allocaBytes sizeCtx $ \dstPtr ->
-    withByteStringPtr ctxB $ \srcPtr -> do
-        memcopy64 (castPtr dstPtr) (castPtr srcPtr)
-        f (castPtr dstPtr)
-
-withCtxNew :: (Ptr Ctx -> IO ()) -> IO Ctx
-withCtxNew f = Ctx `fmap` create sizeCtx (f . castPtr)
-
-withCtxNewThrow :: (Ptr Ctx -> IO a) -> IO a
-withCtxNewThrow f = allocaBytes sizeCtx (f . castPtr)
-
-foreign import ccall unsafe "md4.h md4_init"
-    c_md4_init :: Ptr Ctx -> IO ()
-
-foreign import ccall "md4.h md4_update"
-    c_md4_update :: Ptr Ctx -> Ptr Word8 -> Word32 -> IO ()
-
-foreign import ccall unsafe "md4.h md4_finalize"
-    c_md4_finalize :: Ptr Ctx -> Ptr Word8 -> IO ()
+import Crypto.Hash.Internal (digestToByteString, digestToByteStringWitness)
 
-updateInternalIO :: Ptr Ctx -> ByteString -> IO ()
-updateInternalIO ptr d =
-    unsafeUseAsCStringLen d (\(cs, len) -> c_md4_update ptr (castPtr cs) (fromIntegral len))
+import qualified "cryptonite" Crypto.Hash as H
 
-finalizeInternalIO :: Ptr Ctx -> IO ByteString
-finalizeInternalIO ptr = create digestSize (c_md4_finalize ptr)
+-- | MD4 Context
+newtype Ctx = Ctx (H.Context H.MD4)
 
-{-# NOINLINE init #-}
 -- | init a context
 init :: Ctx
-init = unsafeDoIO $ withCtxNew $ c_md4_init
+init = Ctx H.hashInit
 
-{-# NOINLINE update #-}
 -- | update a context with a bytestring
 update :: Ctx -> ByteString -> Ctx
-update ctx d = unsafeDoIO $ withCtxCopy ctx $ \ptr -> updateInternalIO ptr d
+update (Ctx ctx) d = Ctx $ H.hashUpdate ctx d
 
-{-# NOINLINE updates #-}
 -- | updates a context with multiples bytestring
 updates :: Ctx -> [ByteString] -> Ctx
-updates ctx d = unsafeDoIO $ withCtxCopy ctx $ \ptr -> mapM_ (updateInternalIO ptr) d
+updates (Ctx ctx) d =
+    Ctx $ H.hashUpdates ctx d
 
-{-# NOINLINE finalize #-}
 -- | finalize the context into a digest bytestring
 finalize :: Ctx -> ByteString
-finalize ctx = unsafeDoIO $ withCtxThrow ctx finalizeInternalIO
+finalize (Ctx ctx) = digestToByteString $ H.hashFinalize ctx
 
-{-# NOINLINE hash #-}
 -- | hash a strict bytestring into a digest bytestring
 hash :: ByteString -> ByteString
-hash d = unsafeDoIO $ withCtxNewThrow $ \ptr -> do
-    c_md4_init ptr >> updateInternalIO ptr d >> finalizeInternalIO ptr
+hash d = digestToByteStringWitness H.MD4 $ H.hash d
 
-{-# NOINLINE hashlazy #-}
 -- | hash a lazy bytestring into a digest bytestring
 hashlazy :: L.ByteString -> ByteString
-hashlazy l = unsafeDoIO $ withCtxNewThrow $ \ptr -> do
-    c_md4_init ptr >> mapM_ (updateInternalIO ptr) (L.toChunks l) >> finalizeInternalIO ptr
+hashlazy l = digestToByteStringWitness H.MD4 $ H.hashlazy l
diff --git a/Crypto/Hash/MD5.hs b/Crypto/Hash/MD5.hs
--- a/Crypto/Hash/MD5.hs
+++ b/Crypto/Hash/MD5.hs
@@ -1,4 +1,4 @@
-{-# LANGUAGE ForeignFunctionInterface #-}
+{-# LANGUAGE PackageImports #-}
 
 -- |
 -- Module      : Crypto.Hash.MD5
@@ -24,109 +24,36 @@
     ) where
 
 import Prelude hiding (init)
-import Foreign.Ptr
-import Foreign.ForeignPtr (withForeignPtr)
-import Foreign.Storable
-import Foreign.Marshal.Alloc
 import qualified Data.ByteString.Lazy as L
-import qualified Data.ByteString as B
 import Data.ByteString (ByteString)
-import Data.ByteString.Unsafe (unsafeUseAsCStringLen)
-import Data.ByteString.Internal (create, toForeignPtr)
-import Data.Word
-import Crypto.Hash.Internal (unsafeDoIO)
-
-newtype Ctx = Ctx ByteString
-
-{-# INLINE digestSize #-}
-digestSize :: Int
-digestSize = 16
-
-{-# INLINE sizeCtx #-}
-sizeCtx :: Int
-sizeCtx = 96
-
-{-# RULES "digestSize" B.length (finalize init) = digestSize #-}
-{-# RULES "hash" forall b. finalize (update init b) = hash b #-}
-{-# RULES "hash.list1" forall b. finalize (updates init [b]) = hash b #-}
-{-# RULES "hashmany" forall b. finalize (foldl update init b) = hashlazy (L.fromChunks b) #-}
-{-# RULES "hashlazy" forall b. finalize (foldl update init $ L.toChunks b) = hashlazy b #-}
-
-{-# INLINE withByteStringPtr #-}
-withByteStringPtr :: ByteString -> (Ptr Word8 -> IO a) -> IO a
-withByteStringPtr b f =
-    withForeignPtr fptr $ \ptr -> f (ptr `plusPtr` off)
-    where (fptr, off, _) = toForeignPtr b
-
-{-# INLINE memcopy64 #-}
-memcopy64 :: Ptr Word64 -> Ptr Word64 -> IO ()
-memcopy64 dst src = mapM_ peekAndPoke [0..(12-1)]
-    where peekAndPoke i = peekElemOff src i >>= pokeElemOff dst i
-
-withCtxCopy :: Ctx -> (Ptr Ctx -> IO ()) -> IO Ctx
-withCtxCopy (Ctx ctxB) f = Ctx `fmap` createCtx
-    where createCtx = create sizeCtx $ \dstPtr ->
-                      withByteStringPtr ctxB $ \srcPtr -> do
-                          memcopy64 (castPtr dstPtr) (castPtr srcPtr)
-                          f (castPtr dstPtr)
-
-withCtxThrow :: Ctx -> (Ptr Ctx -> IO a) -> IO a
-withCtxThrow (Ctx ctxB) f =
-    allocaBytes sizeCtx $ \dstPtr ->
-    withByteStringPtr ctxB $ \srcPtr -> do
-        memcopy64 (castPtr dstPtr) (castPtr srcPtr)
-        f (castPtr dstPtr)
-
-withCtxNew :: (Ptr Ctx -> IO ()) -> IO Ctx
-withCtxNew f = Ctx `fmap` create sizeCtx (f . castPtr)
-
-withCtxNewThrow :: (Ptr Ctx -> IO a) -> IO a
-withCtxNewThrow f = allocaBytes sizeCtx (f . castPtr)
-
-foreign import ccall unsafe "md5.h md5_init"
-    c_md5_init :: Ptr Ctx -> IO ()
-
-foreign import ccall "md5.h md5_update"
-    c_md5_update :: Ptr Ctx -> Ptr Word8 -> Word32 -> IO ()
-
-foreign import ccall unsafe "md5.h md5_finalize"
-    c_md5_finalize :: Ptr Ctx -> Ptr Word8 -> IO ()
+import Crypto.Hash.Internal (digestToByteString, digestToByteStringWitness)
 
-updateInternalIO :: Ptr Ctx -> ByteString -> IO ()
-updateInternalIO ptr d =
-    unsafeUseAsCStringLen d (\(cs, len) -> c_md5_update ptr (castPtr cs) (fromIntegral len))
+import qualified "cryptonite" Crypto.Hash as H
 
-finalizeInternalIO :: Ptr Ctx -> IO ByteString
-finalizeInternalIO ptr = create digestSize (c_md5_finalize ptr)
+-- | MD5 Context
+newtype Ctx = Ctx (H.Context H.MD5)
 
-{-# NOINLINE init #-}
 -- | init a context
 init :: Ctx
-init = unsafeDoIO $ withCtxNew $ c_md5_init
+init = Ctx H.hashInit
 
-{-# NOINLINE update #-}
 -- | update a context with a bytestring
 update :: Ctx -> ByteString -> Ctx
-update ctx d = unsafeDoIO $ withCtxCopy ctx $ \ptr -> updateInternalIO ptr d
+update (Ctx ctx) d = Ctx $ H.hashUpdate ctx d
 
-{-# NOINLINE updates #-}
 -- | updates a context with multiples bytestring
 updates :: Ctx -> [ByteString] -> Ctx
-updates ctx d = unsafeDoIO $ withCtxCopy ctx $ \ptr -> mapM_ (updateInternalIO ptr) d
+updates (Ctx ctx) d =
+    Ctx $ H.hashUpdates ctx d
 
-{-# NOINLINE finalize #-}
 -- | finalize the context into a digest bytestring
 finalize :: Ctx -> ByteString
-finalize ctx = unsafeDoIO $ withCtxThrow ctx finalizeInternalIO
+finalize (Ctx ctx) = digestToByteString $ H.hashFinalize ctx
 
-{-# NOINLINE hash #-}
 -- | hash a strict bytestring into a digest bytestring
 hash :: ByteString -> ByteString
-hash d = unsafeDoIO $ withCtxNewThrow $ \ptr -> do
-    c_md5_init ptr >> updateInternalIO ptr d >> finalizeInternalIO ptr
+hash d = digestToByteStringWitness H.MD5 $ H.hash d
 
-{-# NOINLINE hashlazy #-}
 -- | hash a lazy bytestring into a digest bytestring
 hashlazy :: L.ByteString -> ByteString
-hashlazy l = unsafeDoIO $ withCtxNewThrow $ \ptr -> do
-    c_md5_init ptr >> mapM_ (updateInternalIO ptr) (L.toChunks l) >> finalizeInternalIO ptr
+hashlazy l = digestToByteStringWitness H.MD5 $ H.hashlazy l
diff --git a/Crypto/Hash/RIPEMD160.hs b/Crypto/Hash/RIPEMD160.hs
--- a/Crypto/Hash/RIPEMD160.hs
+++ b/Crypto/Hash/RIPEMD160.hs
@@ -1,4 +1,4 @@
-{-# LANGUAGE ForeignFunctionInterface #-}
+{-# LANGUAGE PackageImports #-}
 
 -- |
 -- Module      : Crypto.Hash.RIPEMD160
@@ -24,109 +24,36 @@
     ) where
 
 import Prelude hiding (init)
-import Foreign.Ptr
-import Foreign.ForeignPtr (withForeignPtr)
-import Foreign.Storable
-import Foreign.Marshal.Alloc
 import qualified Data.ByteString.Lazy as L
-import qualified Data.ByteString as B
 import Data.ByteString (ByteString)
-import Data.ByteString.Unsafe (unsafeUseAsCStringLen)
-import Data.ByteString.Internal (create, toForeignPtr)
-import Data.Word
-import Crypto.Hash.Internal (unsafeDoIO)
-
-newtype Ctx = Ctx ByteString
-
-{-# INLINE digestSize #-}
-digestSize :: Int
-digestSize = 20
-
-{-# INLINE sizeCtx #-}
-sizeCtx :: Int
-sizeCtx = 128
-
-{-# RULES "digestSize" B.length (finalize init) = digestSize #-}
-{-# RULES "hash" forall b. finalize (update init b) = hash b #-}
-{-# RULES "hash.list1" forall b. finalize (updates init [b]) = hash b #-}
-{-# RULES "hashmany" forall b. finalize (foldl update init b) = hashlazy (L.fromChunks b) #-}
-{-# RULES "hashlazy" forall b. finalize (foldl update init $ L.toChunks b) = hashlazy b #-}
-
-{-# INLINE withByteStringPtr #-}
-withByteStringPtr :: ByteString -> (Ptr Word8 -> IO a) -> IO a
-withByteStringPtr b f =
-    withForeignPtr fptr $ \ptr -> f (ptr `plusPtr` off)
-    where (fptr, off, _) = toForeignPtr b
-
-{-# INLINE memcopy64 #-}
-memcopy64 :: Ptr Word64 -> Ptr Word64 -> IO ()
-memcopy64 dst src = mapM_ peekAndPoke [0..(16-1)]
-    where peekAndPoke i = peekElemOff src i >>= pokeElemOff dst i
-
-withCtxCopy :: Ctx -> (Ptr Ctx -> IO ()) -> IO Ctx
-withCtxCopy (Ctx ctxB) f = Ctx `fmap` createCtx
-    where createCtx = create sizeCtx $ \dstPtr ->
-                      withByteStringPtr ctxB $ \srcPtr -> do
-                          memcopy64 (castPtr dstPtr) (castPtr srcPtr)
-                          f (castPtr dstPtr)
-
-withCtxThrow :: Ctx -> (Ptr Ctx -> IO a) -> IO a
-withCtxThrow (Ctx ctxB) f =
-    allocaBytes sizeCtx $ \dstPtr ->
-    withByteStringPtr ctxB $ \srcPtr -> do
-        memcopy64 (castPtr dstPtr) (castPtr srcPtr)
-        f (castPtr dstPtr)
-
-withCtxNew :: (Ptr Ctx -> IO ()) -> IO Ctx
-withCtxNew f = Ctx `fmap` create sizeCtx (f . castPtr)
-
-withCtxNewThrow :: (Ptr Ctx -> IO a) -> IO a
-withCtxNewThrow f = allocaBytes sizeCtx (f . castPtr)
-
-foreign import ccall unsafe "ripemd.h ripemd160_init"
-    c_ripemd160_init :: Ptr Ctx -> IO ()
-
-foreign import ccall "ripemd.h ripemd160_update"
-    c_ripemd160_update :: Ptr Ctx -> Ptr Word8 -> Word32 -> IO ()
-
-foreign import ccall unsafe "ripemd.h ripemd160_finalize"
-    c_ripemd160_finalize :: Ptr Ctx -> Ptr Word8 -> IO ()
+import Crypto.Hash.Internal (digestToByteString, digestToByteStringWitness)
 
-updateInternalIO :: Ptr Ctx -> ByteString -> IO ()
-updateInternalIO ptr d =
-    unsafeUseAsCStringLen d (\(cs, len) -> c_ripemd160_update ptr (castPtr cs) (fromIntegral len))
+import qualified "cryptonite" Crypto.Hash as H
 
-finalizeInternalIO :: Ptr Ctx -> IO ByteString
-finalizeInternalIO ptr = create digestSize (c_ripemd160_finalize ptr)
+-- | RIPEMD160 Context
+newtype Ctx = Ctx (H.Context H.RIPEMD160)
 
-{-# NOINLINE init #-}
 -- | init a context
 init :: Ctx
-init = unsafeDoIO $ withCtxNew $ c_ripemd160_init
+init = Ctx H.hashInit
 
-{-# NOINLINE update #-}
 -- | update a context with a bytestring
 update :: Ctx -> ByteString -> Ctx
-update ctx d = unsafeDoIO $ withCtxCopy ctx $ \ptr -> updateInternalIO ptr d
+update (Ctx ctx) d = Ctx $ H.hashUpdate ctx d
 
-{-# NOINLINE updates #-}
 -- | updates a context with multiples bytestring
 updates :: Ctx -> [ByteString] -> Ctx
-updates ctx d = unsafeDoIO $ withCtxCopy ctx $ \ptr -> mapM_ (updateInternalIO ptr) d
+updates (Ctx ctx) d =
+    Ctx $ H.hashUpdates ctx d
 
-{-# NOINLINE finalize #-}
 -- | finalize the context into a digest bytestring
 finalize :: Ctx -> ByteString
-finalize ctx = unsafeDoIO $ withCtxThrow ctx finalizeInternalIO
+finalize (Ctx ctx) = digestToByteString $ H.hashFinalize ctx
 
-{-# NOINLINE hash #-}
 -- | hash a strict bytestring into a digest bytestring
 hash :: ByteString -> ByteString
-hash d = unsafeDoIO $ withCtxNewThrow $ \ptr -> do
-    c_ripemd160_init ptr >> updateInternalIO ptr d >> finalizeInternalIO ptr
+hash d = digestToByteStringWitness H.RIPEMD160 $ H.hash d
 
-{-# NOINLINE hashlazy #-}
 -- | hash a lazy bytestring into a digest bytestring
 hashlazy :: L.ByteString -> ByteString
-hashlazy l = unsafeDoIO $ withCtxNewThrow $ \ptr -> do
-    c_ripemd160_init ptr >> mapM_ (updateInternalIO ptr) (L.toChunks l) >> finalizeInternalIO ptr
+hashlazy l = digestToByteStringWitness H.RIPEMD160 $ H.hashlazy l
diff --git a/Crypto/Hash/SHA1.hs b/Crypto/Hash/SHA1.hs
--- a/Crypto/Hash/SHA1.hs
+++ b/Crypto/Hash/SHA1.hs
@@ -1,4 +1,4 @@
-{-# LANGUAGE ForeignFunctionInterface #-}
+{-# LANGUAGE PackageImports #-}
 
 -- |
 -- Module      : Crypto.Hash.SHA1
@@ -24,109 +24,36 @@
     ) where
 
 import Prelude hiding (init)
-import Foreign.Ptr
-import Foreign.ForeignPtr (withForeignPtr)
-import Foreign.Storable
-import Foreign.Marshal.Alloc
 import qualified Data.ByteString.Lazy as L
-import qualified Data.ByteString as B
 import Data.ByteString (ByteString)
-import Data.ByteString.Unsafe (unsafeUseAsCStringLen)
-import Data.ByteString.Internal (create, toForeignPtr)
-import Data.Word
-import Crypto.Hash.Internal (unsafeDoIO)
-
-newtype Ctx = Ctx ByteString
-
-{-# INLINE digestSize #-}
-digestSize :: Int
-digestSize = 20
-
-{-# INLINE sizeCtx #-}
-sizeCtx :: Int
-sizeCtx = 96
-
-{-# RULES "digestSize" B.length (finalize init) = digestSize #-}
-{-# RULES "hash" forall b. finalize (update init b) = hash b #-}
-{-# RULES "hash.list1" forall b. finalize (updates init [b]) = hash b #-}
-{-# RULES "hashmany" forall b. finalize (foldl update init b) = hashlazy (L.fromChunks b) #-}
-{-# RULES "hashlazy" forall b. finalize (foldl update init $ L.toChunks b) = hashlazy b #-}
-
-{-# INLINE withByteStringPtr #-}
-withByteStringPtr :: ByteString -> (Ptr Word8 -> IO a) -> IO a
-withByteStringPtr b f =
-    withForeignPtr fptr $ \ptr -> f (ptr `plusPtr` off)
-    where (fptr, off, _) = toForeignPtr b
-
-{-# INLINE memcopy64 #-}
-memcopy64 :: Ptr Word64 -> Ptr Word64 -> IO ()
-memcopy64 dst src = mapM_ peekAndPoke [0..(12-1)]
-    where peekAndPoke i = peekElemOff src i >>= pokeElemOff dst i
-
-withCtxCopy :: Ctx -> (Ptr Ctx -> IO ()) -> IO Ctx
-withCtxCopy (Ctx ctxB) f = Ctx `fmap` createCtx
-    where createCtx = create sizeCtx $ \dstPtr ->
-                      withByteStringPtr ctxB $ \srcPtr -> do
-                          memcopy64 (castPtr dstPtr) (castPtr srcPtr)
-                          f (castPtr dstPtr)
-
-withCtxThrow :: Ctx -> (Ptr Ctx -> IO a) -> IO a
-withCtxThrow (Ctx ctxB) f =
-    allocaBytes sizeCtx $ \dstPtr ->
-    withByteStringPtr ctxB $ \srcPtr -> do
-        memcopy64 (castPtr dstPtr) (castPtr srcPtr)
-        f (castPtr dstPtr)
-
-withCtxNew :: (Ptr Ctx -> IO ()) -> IO Ctx
-withCtxNew f = Ctx `fmap` create sizeCtx (f . castPtr)
-
-withCtxNewThrow :: (Ptr Ctx -> IO a) -> IO a
-withCtxNewThrow f = allocaBytes sizeCtx (f . castPtr)
-
-foreign import ccall unsafe "sha1.h sha1_init"
-    c_sha1_init :: Ptr Ctx -> IO ()
-
-foreign import ccall "sha1.h sha1_update"
-    c_sha1_update :: Ptr Ctx -> Ptr Word8 -> Word32 -> IO ()
-
-foreign import ccall unsafe "sha1.h sha1_finalize"
-    c_sha1_finalize :: Ptr Ctx -> Ptr Word8 -> IO ()
+import Crypto.Hash.Internal (digestToByteString, digestToByteStringWitness)
 
-updateInternalIO :: Ptr Ctx -> ByteString -> IO ()
-updateInternalIO ptr d =
-    unsafeUseAsCStringLen d (\(cs, len) -> c_sha1_update ptr (castPtr cs) (fromIntegral len))
+import qualified "cryptonite" Crypto.Hash as H
 
-finalizeInternalIO :: Ptr Ctx -> IO ByteString
-finalizeInternalIO ptr = create digestSize (c_sha1_finalize ptr)
+-- | SHA1 Context
+newtype Ctx = Ctx (H.Context H.SHA1)
 
-{-# NOINLINE init #-}
 -- | init a context
 init :: Ctx
-init = unsafeDoIO $ withCtxNew $ c_sha1_init
+init = Ctx H.hashInit
 
-{-# NOINLINE update #-}
 -- | update a context with a bytestring
 update :: Ctx -> ByteString -> Ctx
-update ctx d = unsafeDoIO $ withCtxCopy ctx $ \ptr -> updateInternalIO ptr d
+update (Ctx ctx) d = Ctx $ H.hashUpdate ctx d
 
-{-# NOINLINE updates #-}
 -- | updates a context with multiples bytestring
 updates :: Ctx -> [ByteString] -> Ctx
-updates ctx d = unsafeDoIO $ withCtxCopy ctx $ \ptr -> mapM_ (updateInternalIO ptr) d
+updates (Ctx ctx) d =
+    Ctx $ H.hashUpdates ctx d
 
-{-# NOINLINE finalize #-}
 -- | finalize the context into a digest bytestring
 finalize :: Ctx -> ByteString
-finalize ctx = unsafeDoIO $ withCtxThrow ctx finalizeInternalIO
+finalize (Ctx ctx) = digestToByteString $ H.hashFinalize ctx
 
-{-# NOINLINE hash #-}
 -- | hash a strict bytestring into a digest bytestring
 hash :: ByteString -> ByteString
-hash d = unsafeDoIO $ withCtxNewThrow $ \ptr -> do
-    c_sha1_init ptr >> updateInternalIO ptr d >> finalizeInternalIO ptr
+hash d = digestToByteStringWitness H.SHA1 $ H.hash d
 
-{-# NOINLINE hashlazy #-}
 -- | hash a lazy bytestring into a digest bytestring
 hashlazy :: L.ByteString -> ByteString
-hashlazy l = unsafeDoIO $ withCtxNewThrow $ \ptr -> do
-    c_sha1_init ptr >> mapM_ (updateInternalIO ptr) (L.toChunks l) >> finalizeInternalIO ptr
+hashlazy l = digestToByteStringWitness H.SHA1 $ H.hashlazy l
diff --git a/Crypto/Hash/SHA224.hs b/Crypto/Hash/SHA224.hs
--- a/Crypto/Hash/SHA224.hs
+++ b/Crypto/Hash/SHA224.hs
@@ -1,4 +1,4 @@
-{-# LANGUAGE ForeignFunctionInterface #-}
+{-# LANGUAGE PackageImports #-}
 
 -- |
 -- Module      : Crypto.Hash.SHA224
@@ -24,109 +24,36 @@
     ) where
 
 import Prelude hiding (init)
-import Foreign.Ptr
-import Foreign.ForeignPtr (withForeignPtr)
-import Foreign.Storable
-import Foreign.Marshal.Alloc
 import qualified Data.ByteString.Lazy as L
-import qualified Data.ByteString as B
 import Data.ByteString (ByteString)
-import Data.ByteString.Unsafe (unsafeUseAsCStringLen)
-import Data.ByteString.Internal (create, toForeignPtr)
-import Data.Word
-import Crypto.Hash.Internal (unsafeDoIO)
-
-newtype Ctx = Ctx ByteString
-
-{-# INLINE digestSize #-}
-digestSize :: Int
-digestSize = 28
-
-{-# INLINE sizeCtx #-}
-sizeCtx :: Int
-sizeCtx = 192
-
-{-# RULES "digestSize" B.length (finalize init) = digestSize #-}
-{-# RULES "hash" forall b. finalize (update init b) = hash b #-}
-{-# RULES "hash.list1" forall b. finalize (updates init [b]) = hash b #-}
-{-# RULES "hashmany" forall b. finalize (foldl update init b) = hashlazy (L.fromChunks b) #-}
-{-# RULES "hashlazy" forall b. finalize (foldl update init $ L.toChunks b) = hashlazy b #-}
-
-{-# INLINE withByteStringPtr #-}
-withByteStringPtr :: ByteString -> (Ptr Word8 -> IO a) -> IO a
-withByteStringPtr b f =
-    withForeignPtr fptr $ \ptr -> f (ptr `plusPtr` off)
-    where (fptr, off, _) = toForeignPtr b
-
-{-# INLINE memcopy64 #-}
-memcopy64 :: Ptr Word64 -> Ptr Word64 -> IO ()
-memcopy64 dst src = mapM_ peekAndPoke [0..(24-1)]
-    where peekAndPoke i = peekElemOff src i >>= pokeElemOff dst i
-
-withCtxCopy :: Ctx -> (Ptr Ctx -> IO ()) -> IO Ctx
-withCtxCopy (Ctx ctxB) f = Ctx `fmap` createCtx
-    where createCtx = create sizeCtx $ \dstPtr ->
-                      withByteStringPtr ctxB $ \srcPtr -> do
-                          memcopy64 (castPtr dstPtr) (castPtr srcPtr)
-                          f (castPtr dstPtr)
-
-withCtxThrow :: Ctx -> (Ptr Ctx -> IO a) -> IO a
-withCtxThrow (Ctx ctxB) f =
-    allocaBytes sizeCtx $ \dstPtr ->
-    withByteStringPtr ctxB $ \srcPtr -> do
-        memcopy64 (castPtr dstPtr) (castPtr srcPtr)
-        f (castPtr dstPtr)
-
-withCtxNew :: (Ptr Ctx -> IO ()) -> IO Ctx
-withCtxNew f = Ctx `fmap` create sizeCtx (f . castPtr)
-
-withCtxNewThrow :: (Ptr Ctx -> IO a) -> IO a
-withCtxNewThrow f = allocaBytes sizeCtx (f . castPtr)
-
-foreign import ccall unsafe "sha256.h sha224_init"
-    c_sha224_init :: Ptr Ctx -> IO ()
-
-foreign import ccall "sha256.h sha224_update"
-    c_sha224_update :: Ptr Ctx -> Ptr Word8 -> Word32 -> IO ()
-
-foreign import ccall unsafe "sha256.h sha224_finalize"
-    c_sha224_finalize :: Ptr Ctx -> Ptr Word8 -> IO ()
+import Crypto.Hash.Internal (digestToByteString, digestToByteStringWitness)
 
-updateInternalIO :: Ptr Ctx -> ByteString -> IO ()
-updateInternalIO ptr d =
-    unsafeUseAsCStringLen d (\(cs, len) -> c_sha224_update ptr (castPtr cs) (fromIntegral len))
+import qualified "cryptonite" Crypto.Hash as H
 
-finalizeInternalIO :: Ptr Ctx -> IO ByteString
-finalizeInternalIO ptr = create digestSize (c_sha224_finalize ptr)
+-- | SHA224 Context
+newtype Ctx = Ctx (H.Context H.SHA224)
 
-{-# NOINLINE init #-}
 -- | init a context
 init :: Ctx
-init = unsafeDoIO $ withCtxNew $ c_sha224_init
+init = Ctx H.hashInit
 
-{-# NOINLINE update #-}
 -- | update a context with a bytestring
 update :: Ctx -> ByteString -> Ctx
-update ctx d = unsafeDoIO $ withCtxCopy ctx $ \ptr -> updateInternalIO ptr d
+update (Ctx ctx) d = Ctx $ H.hashUpdate ctx d
 
-{-# NOINLINE updates #-}
 -- | updates a context with multiples bytestring
 updates :: Ctx -> [ByteString] -> Ctx
-updates ctx d = unsafeDoIO $ withCtxCopy ctx $ \ptr -> mapM_ (updateInternalIO ptr) d
+updates (Ctx ctx) d =
+    Ctx $ H.hashUpdates ctx d
 
-{-# NOINLINE finalize #-}
 -- | finalize the context into a digest bytestring
 finalize :: Ctx -> ByteString
-finalize ctx = unsafeDoIO $ withCtxThrow ctx finalizeInternalIO
+finalize (Ctx ctx) = digestToByteString $ H.hashFinalize ctx
 
-{-# NOINLINE hash #-}
 -- | hash a strict bytestring into a digest bytestring
 hash :: ByteString -> ByteString
-hash d = unsafeDoIO $ withCtxNewThrow $ \ptr -> do
-    c_sha224_init ptr >> updateInternalIO ptr d >> finalizeInternalIO ptr
+hash d = digestToByteStringWitness H.SHA224 $ H.hash d
 
-{-# NOINLINE hashlazy #-}
 -- | hash a lazy bytestring into a digest bytestring
 hashlazy :: L.ByteString -> ByteString
-hashlazy l = unsafeDoIO $ withCtxNewThrow $ \ptr -> do
-    c_sha224_init ptr >> mapM_ (updateInternalIO ptr) (L.toChunks l) >> finalizeInternalIO ptr
+hashlazy l = digestToByteStringWitness H.SHA224 $ H.hashlazy l
diff --git a/Crypto/Hash/SHA256.hs b/Crypto/Hash/SHA256.hs
--- a/Crypto/Hash/SHA256.hs
+++ b/Crypto/Hash/SHA256.hs
@@ -1,4 +1,4 @@
-{-# LANGUAGE ForeignFunctionInterface #-}
+{-# LANGUAGE PackageImports #-}
 
 -- |
 -- Module      : Crypto.Hash.SHA256
@@ -24,109 +24,36 @@
     ) where
 
 import Prelude hiding (init)
-import Foreign.Ptr
-import Foreign.ForeignPtr (withForeignPtr)
-import Foreign.Storable
-import Foreign.Marshal.Alloc
 import qualified Data.ByteString.Lazy as L
-import qualified Data.ByteString as B
 import Data.ByteString (ByteString)
-import Data.ByteString.Unsafe (unsafeUseAsCStringLen)
-import Data.ByteString.Internal (create, toForeignPtr)
-import Data.Word
-import Crypto.Hash.Internal (unsafeDoIO)
-
-newtype Ctx = Ctx ByteString
-
-{-# INLINE digestSize #-}
-digestSize :: Int
-digestSize = 32
-
-{-# INLINE sizeCtx #-}
-sizeCtx :: Int
-sizeCtx = 192
-
-{-# RULES "digestSize" B.length (finalize init) = digestSize #-}
-{-# RULES "hash" forall b. finalize (update init b) = hash b #-}
-{-# RULES "hash.list1" forall b. finalize (updates init [b]) = hash b #-}
-{-# RULES "hashmany" forall b. finalize (foldl update init b) = hashlazy (L.fromChunks b) #-}
-{-# RULES "hashlazy" forall b. finalize (foldl update init $ L.toChunks b) = hashlazy b #-}
-
-{-# INLINE withByteStringPtr #-}
-withByteStringPtr :: ByteString -> (Ptr Word8 -> IO a) -> IO a
-withByteStringPtr b f =
-    withForeignPtr fptr $ \ptr -> f (ptr `plusPtr` off)
-    where (fptr, off, _) = toForeignPtr b
-
-{-# INLINE memcopy64 #-}
-memcopy64 :: Ptr Word64 -> Ptr Word64 -> IO ()
-memcopy64 dst src = mapM_ peekAndPoke [0..(24-1)]
-    where peekAndPoke i = peekElemOff src i >>= pokeElemOff dst i
-
-withCtxCopy :: Ctx -> (Ptr Ctx -> IO ()) -> IO Ctx
-withCtxCopy (Ctx ctxB) f = Ctx `fmap` createCtx
-    where createCtx = create sizeCtx $ \dstPtr ->
-                      withByteStringPtr ctxB $ \srcPtr -> do
-                          memcopy64 (castPtr dstPtr) (castPtr srcPtr)
-                          f (castPtr dstPtr)
-
-withCtxThrow :: Ctx -> (Ptr Ctx -> IO a) -> IO a
-withCtxThrow (Ctx ctxB) f =
-    allocaBytes sizeCtx $ \dstPtr ->
-    withByteStringPtr ctxB $ \srcPtr -> do
-        memcopy64 (castPtr dstPtr) (castPtr srcPtr)
-        f (castPtr dstPtr)
-
-withCtxNew :: (Ptr Ctx -> IO ()) -> IO Ctx
-withCtxNew f = Ctx `fmap` create sizeCtx (f . castPtr)
-
-withCtxNewThrow :: (Ptr Ctx -> IO a) -> IO a
-withCtxNewThrow f = allocaBytes sizeCtx (f . castPtr)
-
-foreign import ccall unsafe "sha256.h sha256_init"
-    c_sha256_init :: Ptr Ctx -> IO ()
-
-foreign import ccall "sha256.h sha256_update"
-    c_sha256_update :: Ptr Ctx -> Ptr Word8 -> Word32 -> IO ()
-
-foreign import ccall unsafe "sha256.h sha256_finalize"
-    c_sha256_finalize :: Ptr Ctx -> Ptr Word8 -> IO ()
+import Crypto.Hash.Internal (digestToByteString, digestToByteStringWitness)
 
-updateInternalIO :: Ptr Ctx -> ByteString -> IO ()
-updateInternalIO ptr d =
-    unsafeUseAsCStringLen d (\(cs, len) -> c_sha256_update ptr (castPtr cs) (fromIntegral len))
+import qualified "cryptonite" Crypto.Hash as H
 
-finalizeInternalIO :: Ptr Ctx -> IO ByteString
-finalizeInternalIO ptr = create digestSize (c_sha256_finalize ptr)
+-- | SHA256 Context
+newtype Ctx = Ctx (H.Context H.SHA256)
 
-{-# NOINLINE init #-}
 -- | init a context
 init :: Ctx
-init = unsafeDoIO $ withCtxNew $ c_sha256_init
+init = Ctx H.hashInit
 
-{-# NOINLINE update #-}
 -- | update a context with a bytestring
 update :: Ctx -> ByteString -> Ctx
-update ctx d = unsafeDoIO $ withCtxCopy ctx $ \ptr -> updateInternalIO ptr d
+update (Ctx ctx) d = Ctx $ H.hashUpdate ctx d
 
-{-# NOINLINE updates #-}
 -- | updates a context with multiples bytestring
 updates :: Ctx -> [ByteString] -> Ctx
-updates ctx d = unsafeDoIO $ withCtxCopy ctx $ \ptr -> mapM_ (updateInternalIO ptr) d
+updates (Ctx ctx) d =
+    Ctx $ H.hashUpdates ctx d
 
-{-# NOINLINE finalize #-}
 -- | finalize the context into a digest bytestring
 finalize :: Ctx -> ByteString
-finalize ctx = unsafeDoIO $ withCtxThrow ctx finalizeInternalIO
+finalize (Ctx ctx) = digestToByteString $ H.hashFinalize ctx
 
-{-# NOINLINE hash #-}
 -- | hash a strict bytestring into a digest bytestring
 hash :: ByteString -> ByteString
-hash d = unsafeDoIO $ withCtxNewThrow $ \ptr -> do
-    c_sha256_init ptr >> updateInternalIO ptr d >> finalizeInternalIO ptr
+hash d = digestToByteStringWitness H.SHA256 $ H.hash d
 
-{-# NOINLINE hashlazy #-}
 -- | hash a lazy bytestring into a digest bytestring
 hashlazy :: L.ByteString -> ByteString
-hashlazy l = unsafeDoIO $ withCtxNewThrow $ \ptr -> do
-    c_sha256_init ptr >> mapM_ (updateInternalIO ptr) (L.toChunks l) >> finalizeInternalIO ptr
+hashlazy l = digestToByteStringWitness H.SHA256 $ H.hashlazy l
diff --git a/Crypto/Hash/SHA3.hs b/Crypto/Hash/SHA3.hs
--- a/Crypto/Hash/SHA3.hs
+++ b/Crypto/Hash/SHA3.hs
@@ -1,5 +1,4 @@
 {-# LANGUAGE ForeignFunctionInterface #-}
-
 -- |
 -- Module      : Crypto.Hash.SHA3
 -- License     : BSD-style
@@ -9,7 +8,16 @@
 --
 -- A module containing SHA3 bindings
 --
+-- WARNING: this implementation is not SHA3 as standardize, but
+-- SHA3 as submitted before standardisation. also known at the Keccak.
+--
+-- A matching implementation is available as Keccak in cryptonite
+-- for people that are using the pre-standard SHA3.
+--
+-- do not use.
+--
 module Crypto.Hash.SHA3
+{-# WARNING "this implementation is not SHA3 as standardized, but SHA3 as submitted before standardisation (Keccak)" #-}
     ( Ctx(..)
 
     -- * Incremental hashing Functions
@@ -35,6 +43,7 @@
 import Data.Word
 import Crypto.Hash.Internal (unsafeDoIO)
 
+-- | SHA3 Context
 newtype Ctx = Ctx ByteString
 
 {-# INLINE sizeCtx #-}
@@ -83,13 +92,13 @@
 withCtxNewThrow :: (Ptr Ctx -> IO a) -> IO a
 withCtxNewThrow f = allocaBytes sizeCtx (f . castPtr)
 
-foreign import ccall unsafe "sha3.h sha3_init"
+foreign import ccall unsafe "sha3.h cryptohash_sha3_init"
     c_sha3_init :: Ptr Ctx -> Word32 -> IO ()
 
-foreign import ccall "sha3.h sha3_update"
+foreign import ccall "sha3.h cryptohash_sha3_update"
     c_sha3_update :: Ptr Ctx -> Ptr Word8 -> Word32 -> IO ()
 
-foreign import ccall unsafe "sha3.h sha3_finalize"
+foreign import ccall unsafe "sha3.h cryptohash_sha3_finalize"
     c_sha3_finalize :: Ptr Ctx -> Ptr Word8 -> IO ()
 
 updateInternalIO :: Ptr Ctx -> ByteString -> IO ()
diff --git a/Crypto/Hash/SHA384.hs b/Crypto/Hash/SHA384.hs
--- a/Crypto/Hash/SHA384.hs
+++ b/Crypto/Hash/SHA384.hs
@@ -1,4 +1,4 @@
-{-# LANGUAGE ForeignFunctionInterface #-}
+{-# LANGUAGE PackageImports #-}
 
 -- |
 -- Module      : Crypto.Hash.SHA384
@@ -24,109 +24,36 @@
     ) where
 
 import Prelude hiding (init)
-import Foreign.Ptr
-import Foreign.ForeignPtr (withForeignPtr)
-import Foreign.Storable
-import Foreign.Marshal.Alloc
 import qualified Data.ByteString.Lazy as L
-import qualified Data.ByteString as B
 import Data.ByteString (ByteString)
-import Data.ByteString.Unsafe (unsafeUseAsCStringLen)
-import Data.ByteString.Internal (create, toForeignPtr)
-import Data.Word
-import Crypto.Hash.Internal (unsafeDoIO)
-
-newtype Ctx = Ctx ByteString
-
-{-# INLINE digestSize #-}
-digestSize :: Int
-digestSize = 48
-
-{-# INLINE sizeCtx #-}
-sizeCtx :: Int
-sizeCtx = 256
-
-{-# RULES "digestSize" B.length (finalize init) = digestSize #-}
-{-# RULES "hash" forall b. finalize (update init b) = hash b #-}
-{-# RULES "hash.list1" forall b. finalize (updates init [b]) = hash b #-}
-{-# RULES "hashmany" forall b. finalize (foldl update init b) = hashlazy (L.fromChunks b) #-}
-{-# RULES "hashlazy" forall b. finalize (foldl update init $ L.toChunks b) = hashlazy b #-}
-
-{-# INLINE withByteStringPtr #-}
-withByteStringPtr :: ByteString -> (Ptr Word8 -> IO a) -> IO a
-withByteStringPtr b f =
-    withForeignPtr fptr $ \ptr -> f (ptr `plusPtr` off)
-    where (fptr, off, _) = toForeignPtr b
-
-{-# INLINE memcopy64 #-}
-memcopy64 :: Ptr Word64 -> Ptr Word64 -> IO ()
-memcopy64 dst src = mapM_ peekAndPoke [0..(32-1)]
-    where peekAndPoke i = peekElemOff src i >>= pokeElemOff dst i
-
-withCtxCopy :: Ctx -> (Ptr Ctx -> IO ()) -> IO Ctx
-withCtxCopy (Ctx ctxB) f = Ctx `fmap` createCtx
-    where createCtx = create sizeCtx $ \dstPtr ->
-                      withByteStringPtr ctxB $ \srcPtr -> do
-                          memcopy64 (castPtr dstPtr) (castPtr srcPtr)
-                          f (castPtr dstPtr)
-
-withCtxThrow :: Ctx -> (Ptr Ctx -> IO a) -> IO a
-withCtxThrow (Ctx ctxB) f =
-    allocaBytes sizeCtx $ \dstPtr ->
-    withByteStringPtr ctxB $ \srcPtr -> do
-        memcopy64 (castPtr dstPtr) (castPtr srcPtr)
-        f (castPtr dstPtr)
-
-withCtxNew :: (Ptr Ctx -> IO ()) -> IO Ctx
-withCtxNew f = Ctx `fmap` create sizeCtx (f . castPtr)
-
-withCtxNewThrow :: (Ptr Ctx -> IO a) -> IO a
-withCtxNewThrow f = allocaBytes sizeCtx (f . castPtr)
-
-foreign import ccall unsafe "sha512.h sha384_init"
-    c_sha384_init :: Ptr Ctx -> IO ()
-
-foreign import ccall "sha512.h sha384_update"
-    c_sha384_update :: Ptr Ctx -> Ptr Word8 -> Word32 -> IO ()
-
-foreign import ccall unsafe "sha512.h sha384_finalize"
-    c_sha384_finalize :: Ptr Ctx -> Ptr Word8 -> IO ()
+import Crypto.Hash.Internal (digestToByteString, digestToByteStringWitness)
 
-updateInternalIO :: Ptr Ctx -> ByteString -> IO ()
-updateInternalIO ptr d =
-    unsafeUseAsCStringLen d (\(cs, len) -> c_sha384_update ptr (castPtr cs) (fromIntegral len))
+import qualified "cryptonite" Crypto.Hash as H
 
-finalizeInternalIO :: Ptr Ctx -> IO ByteString
-finalizeInternalIO ptr = create digestSize (c_sha384_finalize ptr)
+-- | SHA384 Context
+newtype Ctx = Ctx (H.Context H.SHA384)
 
-{-# NOINLINE init #-}
 -- | init a context
 init :: Ctx
-init = unsafeDoIO $ withCtxNew $ c_sha384_init
+init = Ctx H.hashInit
 
-{-# NOINLINE update #-}
 -- | update a context with a bytestring
 update :: Ctx -> ByteString -> Ctx
-update ctx d = unsafeDoIO $ withCtxCopy ctx $ \ptr -> updateInternalIO ptr d
+update (Ctx ctx) d = Ctx $ H.hashUpdate ctx d
 
-{-# NOINLINE updates #-}
 -- | updates a context with multiples bytestring
 updates :: Ctx -> [ByteString] -> Ctx
-updates ctx d = unsafeDoIO $ withCtxCopy ctx $ \ptr -> mapM_ (updateInternalIO ptr) d
+updates (Ctx ctx) d =
+    Ctx $ H.hashUpdates ctx d
 
-{-# NOINLINE finalize #-}
 -- | finalize the context into a digest bytestring
 finalize :: Ctx -> ByteString
-finalize ctx = unsafeDoIO $ withCtxThrow ctx finalizeInternalIO
+finalize (Ctx ctx) = digestToByteString $ H.hashFinalize ctx
 
-{-# NOINLINE hash #-}
 -- | hash a strict bytestring into a digest bytestring
 hash :: ByteString -> ByteString
-hash d = unsafeDoIO $ withCtxNewThrow $ \ptr -> do
-    c_sha384_init ptr >> updateInternalIO ptr d >> finalizeInternalIO ptr
+hash d = digestToByteStringWitness H.SHA384 $ H.hash d
 
-{-# NOINLINE hashlazy #-}
 -- | hash a lazy bytestring into a digest bytestring
 hashlazy :: L.ByteString -> ByteString
-hashlazy l = unsafeDoIO $ withCtxNewThrow $ \ptr -> do
-    c_sha384_init ptr >> mapM_ (updateInternalIO ptr) (L.toChunks l) >> finalizeInternalIO ptr
+hashlazy l = digestToByteStringWitness H.SHA384 $ H.hashlazy l
diff --git a/Crypto/Hash/SHA512.hs b/Crypto/Hash/SHA512.hs
--- a/Crypto/Hash/SHA512.hs
+++ b/Crypto/Hash/SHA512.hs
@@ -37,6 +37,7 @@
 import Data.Word
 import Crypto.Hash.Internal (unsafeDoIO)
 
+-- | SHA512 Context
 newtype Ctx = Ctx ByteString
 
 {-# INLINE digestSize #-}
@@ -84,16 +85,16 @@
 withCtxNewThrow :: (Ptr Ctx -> IO a) -> IO a
 withCtxNewThrow f = allocaBytes sizeCtx (f . castPtr)
 
-foreign import ccall unsafe "sha512.h sha512_init"
+foreign import ccall unsafe "sha512.h cryptohash_sha512_init"
     c_sha512_init :: Ptr Ctx -> IO ()
 
-foreign import ccall "sha512.h sha512_update"
+foreign import ccall "sha512.h cryptohash_sha512_update"
     c_sha512_update :: Ptr Ctx -> Ptr Word8 -> Word32 -> IO ()
 
-foreign import ccall unsafe "sha512.h sha512_finalize"
+foreign import ccall unsafe "sha512.h cryptohash_sha512_finalize"
     c_sha512_finalize :: Ptr Ctx -> Ptr Word8 -> IO ()
 
-foreign import ccall unsafe "sha512.h sha512_init_t"
+foreign import ccall unsafe "sha512.h cryptohash_sha512_init_t"
     c_sha512_init_t :: Ptr Ctx -> Int -> IO ()
 
 {-# NOINLINE init_t #-}
diff --git a/Crypto/Hash/SHA512t.hs b/Crypto/Hash/SHA512t.hs
--- a/Crypto/Hash/SHA512t.hs
+++ b/Crypto/Hash/SHA512t.hs
@@ -28,6 +28,7 @@
 
 import qualified Crypto.Hash.SHA512 as SHA512
 
+-- | SHA512 Context with variable size output
 data Ctx = Ctx !Int !SHA512.Ctx
 
 -- | init a context
diff --git a/Crypto/Hash/Skein256.hs b/Crypto/Hash/Skein256.hs
--- a/Crypto/Hash/Skein256.hs
+++ b/Crypto/Hash/Skein256.hs
@@ -35,6 +35,7 @@
 import Data.Word
 import Crypto.Hash.Internal (unsafeDoIO)
 
+-- | Skein256 Context
 newtype Ctx = Ctx ByteString
 
 {-# INLINE sizeCtx #-}
@@ -83,13 +84,13 @@
 withCtxNewThrow :: (Ptr Ctx -> IO a) -> IO a
 withCtxNewThrow f = allocaBytes sizeCtx (f . castPtr)
 
-foreign import ccall unsafe "skein256.h skein256_init"
+foreign import ccall unsafe "skein256.h cryptohash_skein256_init"
     c_skein256_init :: Ptr Ctx -> Word32 -> IO ()
 
-foreign import ccall "skein256.h skein256_update"
+foreign import ccall "skein256.h cryptohash_skein256_update"
     c_skein256_update :: Ptr Ctx -> Ptr Word8 -> Word32 -> IO ()
 
-foreign import ccall unsafe "skein256.h skein256_finalize"
+foreign import ccall unsafe "skein256.h cryptohash_skein256_finalize"
     c_skein256_finalize :: Ptr Ctx -> Ptr Word8 -> IO ()
 
 updateInternalIO :: Ptr Ctx -> ByteString -> IO ()
diff --git a/Crypto/Hash/Skein512.hs b/Crypto/Hash/Skein512.hs
--- a/Crypto/Hash/Skein512.hs
+++ b/Crypto/Hash/Skein512.hs
@@ -35,6 +35,7 @@
 import Data.Word
 import Crypto.Hash.Internal (unsafeDoIO)
 
+-- | Skein512 Context
 newtype Ctx = Ctx ByteString
 
 {-# INLINE sizeCtx #-}
@@ -83,13 +84,13 @@
 withCtxNewThrow :: (Ptr Ctx -> IO a) -> IO a
 withCtxNewThrow f = allocaBytes sizeCtx (f . castPtr)
 
-foreign import ccall unsafe "skein512.h skein512_init"
+foreign import ccall unsafe "skein512.h cryptohash_skein512_init"
     c_skein512_init :: Ptr Ctx -> Word32 -> IO ()
 
-foreign import ccall "skein512.h skein512_update"
+foreign import ccall "skein512.h cryptohash_skein512_update"
     c_skein512_update :: Ptr Ctx -> Ptr Word8 -> Word32 -> IO ()
 
-foreign import ccall unsafe "skein512.h skein512_finalize"
+foreign import ccall unsafe "skein512.h cryptohash_skein512_finalize"
     c_skein512_finalize :: Ptr Ctx -> Ptr Word8 -> IO ()
 
 updateInternalIO :: Ptr Ctx -> ByteString -> IO ()
diff --git a/Crypto/Hash/Tiger.hs b/Crypto/Hash/Tiger.hs
--- a/Crypto/Hash/Tiger.hs
+++ b/Crypto/Hash/Tiger.hs
@@ -1,4 +1,4 @@
-{-# LANGUAGE ForeignFunctionInterface #-}
+{-# LANGUAGE PackageImports #-}
 
 -- |
 -- Module      : Crypto.Hash.Tiger
@@ -24,109 +24,36 @@
     ) where
 
 import Prelude hiding (init)
-import Foreign.Ptr
-import Foreign.ForeignPtr (withForeignPtr)
-import Foreign.Storable
-import Foreign.Marshal.Alloc
 import qualified Data.ByteString.Lazy as L
-import qualified Data.ByteString as B
 import Data.ByteString (ByteString)
-import Data.ByteString.Unsafe (unsafeUseAsCStringLen)
-import Data.ByteString.Internal (create, toForeignPtr)
-import Data.Word
-import Crypto.Hash.Internal (unsafeDoIO)
-
-newtype Ctx = Ctx ByteString
-
-{-# INLINE digestSize #-}
-digestSize :: Int
-digestSize = 24
-
-{-# INLINE sizeCtx #-}
-sizeCtx :: Int
-sizeCtx = 96
-
-{-# RULES "digestSize" B.length (finalize init) = digestSize #-}
-{-# RULES "hash" forall b. finalize (update init b) = hash b #-}
-{-# RULES "hash.list1" forall b. finalize (updates init [b]) = hash b #-}
-{-# RULES "hashmany" forall b. finalize (foldl update init b) = hashlazy (L.fromChunks b) #-}
-{-# RULES "hashlazy" forall b. finalize (foldl update init $ L.toChunks b) = hashlazy b #-}
-
-{-# INLINE withByteStringPtr #-}
-withByteStringPtr :: ByteString -> (Ptr Word8 -> IO a) -> IO a
-withByteStringPtr b f =
-    withForeignPtr fptr $ \ptr -> f (ptr `plusPtr` off)
-    where (fptr, off, _) = toForeignPtr b
-
-{-# INLINE memcopy64 #-}
-memcopy64 :: Ptr Word64 -> Ptr Word64 -> IO ()
-memcopy64 dst src = mapM_ peekAndPoke [0..(12-1)]
-    where peekAndPoke i = peekElemOff src i >>= pokeElemOff dst i
-
-withCtxCopy :: Ctx -> (Ptr Ctx -> IO ()) -> IO Ctx
-withCtxCopy (Ctx ctxB) f = Ctx `fmap` createCtx
-    where createCtx = create sizeCtx $ \dstPtr ->
-                      withByteStringPtr ctxB $ \srcPtr -> do
-                          memcopy64 (castPtr dstPtr) (castPtr srcPtr)
-                          f (castPtr dstPtr)
-
-withCtxThrow :: Ctx -> (Ptr Ctx -> IO a) -> IO a
-withCtxThrow (Ctx ctxB) f =
-    allocaBytes sizeCtx $ \dstPtr ->
-    withByteStringPtr ctxB $ \srcPtr -> do
-        memcopy64 (castPtr dstPtr) (castPtr srcPtr)
-        f (castPtr dstPtr)
-
-withCtxNew :: (Ptr Ctx -> IO ()) -> IO Ctx
-withCtxNew f = Ctx `fmap` create sizeCtx (f . castPtr)
-
-withCtxNewThrow :: (Ptr Ctx -> IO a) -> IO a
-withCtxNewThrow f = allocaBytes sizeCtx (f . castPtr)
-
-foreign import ccall unsafe "tiger.h tiger_init"
-    c_tiger_init :: Ptr Ctx -> IO ()
-
-foreign import ccall "tiger.h tiger_update"
-    c_tiger_update :: Ptr Ctx -> Ptr Word8 -> Word32 -> IO ()
-
-foreign import ccall unsafe "tiger.h tiger_finalize"
-    c_tiger_finalize :: Ptr Ctx -> Ptr Word8 -> IO ()
+import Crypto.Hash.Internal (digestToByteString, digestToByteStringWitness)
 
-updateInternalIO :: Ptr Ctx -> ByteString -> IO ()
-updateInternalIO ptr d =
-    unsafeUseAsCStringLen d (\(cs, len) -> c_tiger_update ptr (castPtr cs) (fromIntegral len))
+import qualified "cryptonite" Crypto.Hash as H
 
-finalizeInternalIO :: Ptr Ctx -> IO ByteString
-finalizeInternalIO ptr = create digestSize (c_tiger_finalize ptr)
+-- | Tiger Context
+newtype Ctx = Ctx (H.Context H.Tiger)
 
-{-# NOINLINE init #-}
 -- | init a context
 init :: Ctx
-init = unsafeDoIO $ withCtxNew $ c_tiger_init
+init = Ctx H.hashInit
 
-{-# NOINLINE update #-}
 -- | update a context with a bytestring
 update :: Ctx -> ByteString -> Ctx
-update ctx d = unsafeDoIO $ withCtxCopy ctx $ \ptr -> updateInternalIO ptr d
+update (Ctx ctx) d = Ctx $ H.hashUpdate ctx d
 
-{-# NOINLINE updates #-}
 -- | updates a context with multiples bytestring
 updates :: Ctx -> [ByteString] -> Ctx
-updates ctx d = unsafeDoIO $ withCtxCopy ctx $ \ptr -> mapM_ (updateInternalIO ptr) d
+updates (Ctx ctx) d =
+    Ctx $ H.hashUpdates ctx d
 
-{-# NOINLINE finalize #-}
 -- | finalize the context into a digest bytestring
 finalize :: Ctx -> ByteString
-finalize ctx = unsafeDoIO $ withCtxThrow ctx finalizeInternalIO
+finalize (Ctx ctx) = digestToByteString $ H.hashFinalize ctx
 
-{-# NOINLINE hash #-}
 -- | hash a strict bytestring into a digest bytestring
 hash :: ByteString -> ByteString
-hash d = unsafeDoIO $ withCtxNewThrow $ \ptr -> do
-    c_tiger_init ptr >> updateInternalIO ptr d >> finalizeInternalIO ptr
+hash d = digestToByteStringWitness H.Tiger $ H.hash d
 
-{-# NOINLINE hashlazy #-}
 -- | hash a lazy bytestring into a digest bytestring
 hashlazy :: L.ByteString -> ByteString
-hashlazy l = unsafeDoIO $ withCtxNewThrow $ \ptr -> do
-    c_tiger_init ptr >> mapM_ (updateInternalIO ptr) (L.toChunks l) >> finalizeInternalIO ptr
+hashlazy l = digestToByteStringWitness H.Tiger $ H.hashlazy l
diff --git a/Crypto/Hash/Types.hs b/Crypto/Hash/Types.hs
--- a/Crypto/Hash/Types.hs
+++ b/Crypto/Hash/Types.hs
@@ -1,3 +1,4 @@
+{-# LANGUAGE PackageImports #-}
 -- |
 -- Module      : Crypto.Hash.Types
 -- License     : BSD-style
@@ -8,8 +9,7 @@
 -- Crypto hash types definitions
 --
 module Crypto.Hash.Types
-    ( HashAlgorithm(..)
-    , Context(..)
+    ( Context(..)
     , Digest(..)
     -- * deprecated
     , contextToByteString
@@ -19,47 +19,25 @@
 
 import Data.ByteString (ByteString)
 import Data.Byteable
-import qualified Data.ByteString.Char8 as BC
-import Crypto.Hash.Utils (toHex)
-
--- | Class representing hashing algorithms.
---
--- The hash algorithm is built over 3 primitives:
---
---   init     : create a new context
---   updates  : update the context with some strict bytestrings
---   finalize : finalize the context into a digest
---
-class HashAlgorithm a where
-    -- | Initialize a new context for this hash algorithm
-    hashInit     :: Context a
-
-    -- | Update the context with a list of strict bytestring,
-    -- and return a new context with the updates.
-    hashUpdates  :: Context a -> [ByteString] -> Context a
-
-    -- | Finalize a context and return a digest.
-    hashFinalize :: Context a -> Digest a
-
-    -- | Try to convert a binary digest bytestring to a digest.
-    digestFromByteString :: ByteString -> Maybe (Digest a)
+import qualified Data.ByteArray as B (convert)
+import qualified "cryptonite" Crypto.Hash as H
 
 -- | Represent a context for a given hash algorithm.
-newtype Context a = Context ByteString
+newtype Context a = Context (H.Context a)
 
 instance Byteable (Context a) where
-    toBytes (Context bs) = bs
+    toBytes (Context ctx) = B.convert ctx
 
--- | return the binary bytestring. deprecated use toBytes.
+--- | return the binary bytestring. deprecated use toBytes.
 contextToByteString :: Context a -> ByteString
 contextToByteString = toBytes
 
 -- | Represent a digest for a given hash algorithm.
-newtype Digest a = Digest ByteString
+newtype Digest a = Digest (H.Digest a)
     deriving (Eq,Ord)
 
 instance Byteable (Digest a) where
-    toBytes (Digest bs) = bs
+    toBytes (Digest dig) = B.convert dig
 
 -- | return the binary bytestring. deprecated use toBytes.
 {-# DEPRECATED digestToByteString "use toBytes from byteable:Data.Byteable" #-}
@@ -67,4 +45,4 @@
 digestToByteString = toBytes
 
 instance Show (Digest a) where
-    show (Digest bs) = BC.unpack $ toHex bs
+    show (Digest dig) = show dig
diff --git a/Crypto/Hash/Utils.hs b/Crypto/Hash/Utils.hs
deleted file mode 100644
--- a/Crypto/Hash/Utils.hs
+++ /dev/null
@@ -1,75 +0,0 @@
-{-# LANGUAGE MagicHash, BangPatterns #-}
--- |
--- Module      : Crypto.Hash.Utils
--- License     : BSD-style
--- Maintainer  : Vincent Hanquez <vincent@snarc.org>
--- Stability   : experimental
--- Portability : unknown
---
--- Crypto hash utility for hexadecimal
---
-module Crypto.Hash.Utils
-    ( toHex
-    ) where
-
-import Data.ByteString (ByteString)
-import qualified Data.ByteString.Internal as B
-import GHC.Prim
-import GHC.Types
-import GHC.Word
-import Foreign.ForeignPtr (withForeignPtr)
-import Foreign.Ptr (plusPtr, castPtr)
-import Foreign.Storable (poke, peek)
-import Crypto.Hash.Utils.Cpu
-import Data.Bits (testBit)
-
-toHex :: ByteString -> ByteString
-toHex (B.PS fp off len) = B.unsafeCreate (len*2) $ \d ->
-        withForeignPtr fp $ \s -> start d (s `plusPtr` off)
-    where start db sb
-            | use32Hex && (len `testBit` 0) == False = loop32 db sb
-            | otherwise                              = loop8 db sb
-                where end            = sb `plusPtr` len
-                      -- write the hex output using 32 bits write.
-                      loop32 d s
-                         | s == end  = return ()
-                         | otherwise = do b1 <- fromIntegral `fmap` (peek s :: IO Word8)
-                                          b2 <- fromIntegral `fmap` (peek (s `plusPtr` 1) :: IO Word8)
-                                          poke (castPtr d) (to32 b1 b2)
-                                          loop32 (d `plusPtr` 4) (s `plusPtr` 2)
-                      -- write the hex output 8 bits, 2 at a time
-                      loop8 d s
-                         | s == end  = return ()
-                         | otherwise = do b <- fromIntegral `fmap` (peek s :: IO Word8)
-                                          poke d               (r tableHi b)
-                                          poke (d `plusPtr` 1) (r tableLo b)
-                                          loop8 (d `plusPtr` 2) (s `plusPtr` 1)
-
-          -- little endian version
-          to32 (I# i1) (I# i2) = W32# (or# (or# (or# hi2 lo2) hi1) lo1)
-            where hi2 = uncheckedShiftL# (indexWord8OffAddr# tableLo i2) 24#
-                  lo2 = uncheckedShiftL# (indexWord8OffAddr# tableHi i2) 16#
-                  hi1 = uncheckedShiftL# (indexWord8OffAddr# tableLo i1) 8#
-                  lo1 = indexWord8OffAddr# tableHi i1
-
-          r :: Addr# -> Int -> Word8
-          r table (I# index) = W8# (indexWord8OffAddr# table index)
-
-          !tableLo =
-                "0123456789abcdef0123456789abcdef\
-                \0123456789abcdef0123456789abcdef\
-                \0123456789abcdef0123456789abcdef\
-                \0123456789abcdef0123456789abcdef\
-                \0123456789abcdef0123456789abcdef\
-                \0123456789abcdef0123456789abcdef\
-                \0123456789abcdef0123456789abcdef\
-                \0123456789abcdef0123456789abcdef"#
-          !tableHi =
-                "00000000000000001111111111111111\
-                \22222222222222223333333333333333\
-                \44444444444444445555555555555555\
-                \66666666666666667777777777777777\
-                \88888888888888889999999999999999\
-                \aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbb\
-                \ccccccccccccccccdddddddddddddddd\
-                \eeeeeeeeeeeeeeeeffffffffffffffff"#
diff --git a/Crypto/Hash/Utils/Cpu.hs b/Crypto/Hash/Utils/Cpu.hs
deleted file mode 100644
--- a/Crypto/Hash/Utils/Cpu.hs
+++ /dev/null
@@ -1,11 +0,0 @@
-{-# LANGUAGE CPP #-}
-module Crypto.Hash.Utils.Cpu
-    ( use32Hex
-    ) where
-
-use32Hex :: Bool
-#ifdef ARCH_X86
-use32Hex = True
-#else
-use32Hex = False
-#endif
diff --git a/Crypto/Hash/Whirlpool.hs b/Crypto/Hash/Whirlpool.hs
--- a/Crypto/Hash/Whirlpool.hs
+++ b/Crypto/Hash/Whirlpool.hs
@@ -1,4 +1,4 @@
-{-# LANGUAGE ForeignFunctionInterface #-}
+{-# LANGUAGE PackageImports #-}
 
 -- |
 -- Module      : Crypto.Hash.Whirlpool
@@ -24,109 +24,36 @@
     ) where
 
 import Prelude hiding (init)
-import Foreign.Ptr
-import Foreign.ForeignPtr (withForeignPtr)
-import Foreign.Storable
-import Foreign.Marshal.Alloc
 import qualified Data.ByteString.Lazy as L
-import qualified Data.ByteString as B
 import Data.ByteString (ByteString)
-import Data.ByteString.Unsafe (unsafeUseAsCStringLen)
-import Data.ByteString.Internal (create, toForeignPtr)
-import Data.Word
-import Crypto.Hash.Internal (unsafeDoIO)
-
-newtype Ctx = Ctx ByteString
-
-{-# INLINE digestSize #-}
-digestSize :: Int
-digestSize = 64
-
-{-# INLINE sizeCtx #-}
-sizeCtx :: Int
-sizeCtx = 168
-
-{-# RULES "digestSize" B.length (finalize init) = digestSize #-}
-{-# RULES "hash" forall b. finalize (update init b) = hash b #-}
-{-# RULES "hash.list1" forall b. finalize (updates init [b]) = hash b #-}
-{-# RULES "hashmany" forall b. finalize (foldl update init b) = hashlazy (L.fromChunks b) #-}
-{-# RULES "hashlazy" forall b. finalize (foldl update init $ L.toChunks b) = hashlazy b #-}
-
-{-# INLINE withByteStringPtr #-}
-withByteStringPtr :: ByteString -> (Ptr Word8 -> IO a) -> IO a
-withByteStringPtr b f =
-    withForeignPtr fptr $ \ptr -> f (ptr `plusPtr` off)
-    where (fptr, off, _) = toForeignPtr b
-
-{-# INLINE memcopy64 #-}
-memcopy64 :: Ptr Word64 -> Ptr Word64 -> IO ()
-memcopy64 dst src = mapM_ peekAndPoke [0..(21-1)]
-    where peekAndPoke i = peekElemOff src i >>= pokeElemOff dst i
-
-withCtxCopy :: Ctx -> (Ptr Ctx -> IO ()) -> IO Ctx
-withCtxCopy (Ctx ctxB) f = Ctx `fmap` createCtx
-    where createCtx = create sizeCtx $ \dstPtr ->
-                      withByteStringPtr ctxB $ \srcPtr -> do
-                          memcopy64 (castPtr dstPtr) (castPtr srcPtr)
-                          f (castPtr dstPtr)
-
-withCtxThrow :: Ctx -> (Ptr Ctx -> IO a) -> IO a
-withCtxThrow (Ctx ctxB) f =
-    allocaBytes sizeCtx $ \dstPtr ->
-    withByteStringPtr ctxB $ \srcPtr -> do
-        memcopy64 (castPtr dstPtr) (castPtr srcPtr)
-        f (castPtr dstPtr)
-
-withCtxNew :: (Ptr Ctx -> IO ()) -> IO Ctx
-withCtxNew f = Ctx `fmap` create sizeCtx (f . castPtr)
-
-withCtxNewThrow :: (Ptr Ctx -> IO a) -> IO a
-withCtxNewThrow f = allocaBytes sizeCtx (f . castPtr)
-
-foreign import ccall unsafe "whirlpool.h whirlpool_init"
-    c_whirlpool_init :: Ptr Ctx -> IO ()
-
-foreign import ccall "whirlpool.h whirlpool_update"
-    c_whirlpool_update :: Ptr Ctx -> Ptr Word8 -> Word32 -> IO ()
-
-foreign import ccall unsafe "whirlpool.h whirlpool_finalize"
-    c_whirlpool_finalize :: Ptr Ctx -> Ptr Word8 -> IO ()
+import Crypto.Hash.Internal (digestToByteString, digestToByteStringWitness)
 
-updateInternalIO :: Ptr Ctx -> ByteString -> IO ()
-updateInternalIO ptr d =
-    unsafeUseAsCStringLen d (\(cs, len) -> c_whirlpool_update ptr (castPtr cs) (fromIntegral len))
+import qualified "cryptonite" Crypto.Hash as H
 
-finalizeInternalIO :: Ptr Ctx -> IO ByteString
-finalizeInternalIO ptr = create digestSize (c_whirlpool_finalize ptr)
+-- | Whirlpool Context
+newtype Ctx = Ctx (H.Context H.Whirlpool)
 
-{-# NOINLINE init #-}
 -- | init a context
 init :: Ctx
-init = unsafeDoIO $ withCtxNew $ c_whirlpool_init
+init = Ctx H.hashInit
 
-{-# NOINLINE update #-}
 -- | update a context with a bytestring
 update :: Ctx -> ByteString -> Ctx
-update ctx d = unsafeDoIO $ withCtxCopy ctx $ \ptr -> updateInternalIO ptr d
+update (Ctx ctx) d = Ctx $ H.hashUpdate ctx d
 
-{-# NOINLINE updates #-}
 -- | updates a context with multiples bytestring
 updates :: Ctx -> [ByteString] -> Ctx
-updates ctx d = unsafeDoIO $ withCtxCopy ctx $ \ptr -> mapM_ (updateInternalIO ptr) d
+updates (Ctx ctx) d =
+    Ctx $ H.hashUpdates ctx d
 
-{-# NOINLINE finalize #-}
 -- | finalize the context into a digest bytestring
 finalize :: Ctx -> ByteString
-finalize ctx = unsafeDoIO $ withCtxThrow ctx finalizeInternalIO
+finalize (Ctx ctx) = digestToByteString $ H.hashFinalize ctx
 
-{-# NOINLINE hash #-}
 -- | hash a strict bytestring into a digest bytestring
 hash :: ByteString -> ByteString
-hash d = unsafeDoIO $ withCtxNewThrow $ \ptr -> do
-    c_whirlpool_init ptr >> updateInternalIO ptr d >> finalizeInternalIO ptr
+hash d = digestToByteStringWitness H.Whirlpool $ H.hash d
 
-{-# NOINLINE hashlazy #-}
 -- | hash a lazy bytestring into a digest bytestring
 hashlazy :: L.ByteString -> ByteString
-hashlazy l = unsafeDoIO $ withCtxNewThrow $ \ptr -> do
-    c_whirlpool_init ptr >> mapM_ (updateInternalIO ptr) (L.toChunks l) >> finalizeInternalIO ptr
+hashlazy l = digestToByteStringWitness H.Whirlpool $ H.hashlazy l
diff --git a/Crypto/MAC.hs b/Crypto/MAC.hs
new file mode 100644
--- /dev/null
+++ b/Crypto/MAC.hs
@@ -0,0 +1,75 @@
+-- |
+-- Module      : Crypto.MAC
+-- License     : BSD-style
+-- Maintainer  : Vincent Hanquez <vincent@snarc.org>
+-- Stability   : experimental
+-- Portability : unknown
+--
+-- Crypto hash generic MAC (Message Authentification Code) module
+--
+{-# LANGUAGE BangPatterns #-}
+module Crypto.MAC
+    (
+    -- * MAC algorithms
+      HMAC(..)
+    , hmac
+    , hmacAlg
+    -- ** Incremental MAC algorithms
+    , HMACContext
+    , hmacInit
+    , hmacInitAlg
+    , hmacUpdate
+    , hmacFinalize
+    ) where
+
+import Crypto.Hash
+import Data.ByteString (ByteString)
+import Data.Byteable
+import Data.Bits (xor)
+import qualified Data.ByteString as B
+
+-- -------------------------------------------------------------------------- --
+-- Incremental HMAC
+
+-- | Represent an ongoing HMAC state, that can be appended with 'hmacUpdate'
+-- and finalize to an HMAC with 'hmacFinalize'
+data HMACContext hashalg = HMACContext !(Context hashalg) !(Context hashalg)
+
+-- | Initialize a new incremental HMAC context
+hmacInit :: HashAlgorithm a
+         => ByteString -- ^ Secret key
+         -> HMACContext a
+hmacInit secret = HMACContext octx ictx
+    where ctxInit = hashInit
+          ictx = hashUpdates ctxInit [ipad]
+          octx = hashUpdates ctxInit [opad]
+          ipad = B.map (xor 0x36) k'
+          opad = B.map (xor 0x5c) k'
+
+          k'  = B.append kt pad
+          kt  = if B.length secret > fromIntegral blockSize then toBytes (hashF secret) else secret
+          pad = B.replicate (fromIntegral blockSize - B.length kt) 0
+          hashF = hashFinalize . hashUpdate ctxInit
+          blockSize = hashBlockSize ctxInit
+
+-- | Initialize a new incremental HMAC context with a given hash algorithm.
+hmacInitAlg :: HashAlgorithm a
+            => a           -- ^ the hash algorithm the actual value is unused.
+            -> ByteString  -- ^ Secret key
+            -> HMACContext a
+hmacInitAlg _ secret = hmacInit secret
+
+-- | Incrementally update a HMAC context
+hmacUpdate :: HashAlgorithm a
+           => HMACContext a
+           -> ByteString -- ^ Message to Mac
+           -> HMACContext a
+hmacUpdate (HMACContext octx ictx) msg =
+    HMACContext octx (hashUpdate ictx msg)
+
+-- | Finalize a HMAC context and return the HMAC.
+hmacFinalize :: HashAlgorithm a
+             => HMACContext a
+             -> HMAC a
+hmacFinalize (HMACContext octx ictx) =
+    HMAC $ hashFinalize $ hashUpdates octx [toBytes $ hashFinalize ictx]
diff --git a/Crypto/MAC/HMAC.hs b/Crypto/MAC/HMAC.hs
--- a/Crypto/MAC/HMAC.hs
+++ b/Crypto/MAC/HMAC.hs
@@ -6,7 +6,7 @@
 -- Portability : unknown
 --
 -- provide the HMAC (Hash based Message Authentification Code) base algorithm.
--- http://en.wikipedia.org/wiki/HMAC
+-- <http://en.wikipedia.org/wiki/HMAC>
 --
 module Crypto.MAC.HMAC
     ( hmac
@@ -17,7 +17,14 @@
 import Data.Bits (xor)
 
 -- | compute a MAC using the supplied hashing function
-hmac :: (ByteString -> ByteString) -> Int -> ByteString -> ByteString -> ByteString
+--
+-- An incremental API can be found in the module "Crypto.Hash".
+--
+hmac :: (ByteString -> ByteString) -- ^ hash function
+     -> Int -- ^ block size
+     -> ByteString -- ^ secret
+     -> ByteString -- ^ message
+     -> ByteString
 hmac hashF blockSize secret msg = hashF $ B.append opad (hashF $ B.append ipad msg)
     where opad = B.map (xor 0x5c) k'
           ipad = B.map (xor 0x36) k'
diff --git a/Crypto/MAC/SHA3.hs b/Crypto/MAC/SHA3.hs
new file mode 100644
--- /dev/null
+++ b/Crypto/MAC/SHA3.hs
@@ -0,0 +1,81 @@
+-- |
+-- Module      : Crypto.MAC.SHA3
+-- License     : BSD-style
+-- Maintainer  : Vincent Hanquez <vincent@snarc.org>
+-- Stability   : experimental
+-- Portability : unknown
+--
+-- provide a simple SHA3 MAC mechanism with
+--
+-- > mac = hash(key|message)
+--
+module Crypto.MAC.SHA3
+    ( MAC512(..)
+    , MAC384(..)
+    , MAC256(..)
+    , MAC224(..)
+    , mac512
+    , mac384
+    , mac256
+    , mac224
+    ) where
+
+import Data.Byteable
+import Data.ByteString (ByteString)
+import Crypto.Hash
+
+-- | SHA3_512 MAC
+data MAC512 = MAC512 { getDigest512 :: Digest SHA3_512 }
+
+instance Byteable MAC512 where
+    toBytes (MAC512 b) = toBytes b
+instance Eq MAC512 where
+    (MAC512 b1) == (MAC512 b2) = constEqBytes (toBytes b1) (toBytes b2)
+
+-- | SHA3_384 MAC
+data MAC384 = MAC384 { getDigest384 :: Digest SHA3_384 }
+
+instance Byteable MAC384 where
+    toBytes (MAC384 b) = toBytes b
+instance Eq MAC384 where
+    (MAC384 b1) == (MAC384 b2) = constEqBytes (toBytes b1) (toBytes b2)
+
+-- | SHA3_256 MAC
+data MAC256 = MAC256 { getDigest256 :: Digest SHA3_256 }
+
+instance Byteable MAC256 where
+    toBytes (MAC256 b) = toBytes b
+instance Eq MAC256 where
+    (MAC256 b1) == (MAC256 b2) = constEqBytes (toBytes b1) (toBytes b2)
+
+-- | SHA3_224 MAC
+data MAC224 = MAC224 { getDigest224 :: Digest SHA3_224 }
+
+instance Byteable MAC224 where
+    toBytes (MAC224 b) = toBytes b
+instance Eq MAC224 where
+    (MAC224 b1) == (MAC224 b2) = constEqBytes (toBytes b1) (toBytes b2)
+
+-- | compute a MAC using a simple SHA3_512 key|msg
+mac512 :: ByteString -- ^ secret
+       -> ByteString -- ^ message
+       -> MAC512
+mac512 secret msg = MAC512 $ hashFinalize $ hashUpdates hashInit [secret,msg]
+
+-- | compute a MAC using a simple SHA3_384 key|msg
+mac384 :: ByteString -- ^ secret
+       -> ByteString -- ^ message
+       -> MAC384
+mac384 secret msg = MAC384 $ hashFinalize $ hashUpdates hashInit [secret,msg]
+
+-- | compute a MAC using a simple SHA3_256 key|msg
+mac256 :: ByteString -- ^ secret
+       -> ByteString -- ^ message
+       -> MAC256
+mac256 secret msg = MAC256 $ hashFinalize $ hashUpdates hashInit [secret,msg]
+
+-- | compute a MAC using a simple SHA3_224 key|msg
+mac224 :: ByteString -- ^ secret
+       -> ByteString -- ^ message
+       -> MAC224
+mac224 secret msg = MAC224 $ hashFinalize $ hashUpdates hashInit [secret,msg]
diff --git a/LICENSE b/LICENSE
--- a/LICENSE
+++ b/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2010-2012 Vincent Hanquez <vincent@snarc.org>
+Copyright (c) 2010-2014 Vincent Hanquez <vincent@snarc.org>
 
 All rights reserved.
 
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -1,15 +1,27 @@
+:warning: this library is now deprecated in favor of `cryptonite`, which is
+a superset of this, and also have more functionality. For new projects,
+you should *not* use this library anymore, and preferably you should
+convert old projects to `cryptonite` too.
+
+:warning: the SHA3 implementation available in Crypto.Hash.SHA3 is
+not SHA3 as standardized by NIST, but Keccak as submitted for the SHA3 contest.
+A matching implementation is available as Keccak in `cryptonite`, although I would
+recommend not to use unless you happens to really really need your digest value
+to be compatible. On the other hand, the centralized `Crypto.Hash` export
+a proper SHA3 implementation (as standardized by NIST)
+
 CryptoHash
 ==========
 
-hs-cryptohash provides lots of different secure digest algorithms, also
-called cryptohashes. It exposes every common hashes, but also some
-more exotic hashes, provides an extensive list of hashes available
-with a consistant API.
+`hs-cryptohash` provides many different secure digest algorithms, also
+called cryptographic hash functions or, simply, cryptohashes. The package
+exports common hash functions, as well as some more exotic ones, and
+provides a single API for them all.
 
-The general performance are comparable to the most optimised hashes
+The general performance is comparable to the most optimised implementations
 available.
 
-The complete list of supported hashes:
+Here is the complete list of supported algorithms:
 
 * MD2, MD4, MD5 
 * RIPEMD160
@@ -24,11 +36,9 @@
 
     import qualified Crypto.Hash.<HASH> as <Hash>
 
-suggestion: it's easier to import qualified since there's
-a collision with the init symbol, but for only importing
-the hash or hashlazy function there's no such need.
-
-Every hashes, exposes a very similar API.
+We recommend using `import qualified` because the APIs are similar and
+many of the modules reuse the same names. However, if you are ony using
+one module, there is no need to qualify the names.
 
 Incremental API
 ---------------
@@ -42,7 +52,7 @@
 * finalize: finalize the context and returns a digest bytestring.
 
 all those operations are completely pure, and instead of changing the
-context as usual in others language, it re-allocate a new context each time.
+context as usual in others language, it re-allocates a new context each time.
 
 One Pass API
 ------------
@@ -63,7 +73,7 @@
 Both those types are parametrized with the HashAlgorithm used.
 
 The API is very similar to each single hash module, except the types are
-slightly differents.
+slightly different.
 
     import Crypto.Hash
 
@@ -84,5 +94,5 @@
 Performance
 -----------
 
-Cryptohash uses C implementations to provides maximum performance.
+Cryptohash uses C implementations to provide maximum performance.
 see the cbits directory for more information
diff --git a/Tests/KAT.hs b/Tests/KAT.hs
--- a/Tests/KAT.hs
+++ b/Tests/KAT.hs
@@ -4,6 +4,9 @@
 import Data.Bits
 import Data.Word
 import Data.ByteString (ByteString)
+import Data.Byteable
+import Data.Foldable (foldl')
+import Data.Monoid (mconcat)
 import qualified Data.ByteString as B
 import qualified Data.ByteString.Char8 as BC
 import qualified Crypto.Hash.MD2 as MD2
@@ -15,19 +18,17 @@
 import qualified Crypto.Hash.SHA384 as SHA384
 import qualified Crypto.Hash.SHA512 as SHA512
 import qualified Crypto.Hash.SHA512t as SHA512t
-import qualified Crypto.Hash.SHA3 as SHA3
 import qualified Crypto.Hash.RIPEMD160 as RIPEMD160
 import qualified Crypto.Hash.Tiger as Tiger
 import qualified Crypto.Hash.Skein256 as Skein256
 import qualified Crypto.Hash.Skein512 as Skein512
 import qualified Crypto.Hash.Whirlpool as Whirlpool
 import Crypto.Hash
-import qualified Crypto.MAC.HMAC as HMAC
+import Crypto.MAC
 
-import Test.Framework (Test, defaultMain, testGroup)
-import Test.Framework.Providers.QuickCheck2 (testProperty)
-import Test.Framework.Providers.HUnit
-import Test.HUnit ((@=?))
+import Test.Tasty
+import Test.Tasty.QuickCheck
+import Test.Tasty.HUnit
 
 v0,v1,v2 :: ByteString
 v0 = ""
@@ -35,6 +36,9 @@
 v2 = "The quick brown fox jumps over the lazy cog"
 vectors = [ v0, v1, v2 ]
 
+instance Arbitrary ByteString where
+    arbitrary = B.pack `fmap` arbitrary
+
 data HashFct = HashFct
     { fctHash   :: (B.ByteString -> B.ByteString)
     , fctInc    :: ([B.ByteString] -> B.ByteString) }
@@ -55,8 +59,6 @@
 sha512_224Hash = HashFct { fctHash = SHA512t.hash 224, fctInc = hashinc (SHA512t.init 224) SHA512t.update SHA512t.finalize }
 sha512_256Hash = HashFct { fctHash = SHA512t.hash 256, fctInc = hashinc (SHA512t.init 256) SHA512t.update SHA512t.finalize }
 
-sha3Hash i = HashFct { fctHash = SHA3.hash i, fctInc = hashinc (SHA3.init i) SHA3.update SHA3.finalize }
-
 ripemd160Hash = HashFct { fctHash = RIPEMD160.hash, fctInc = hashinc RIPEMD160.init RIPEMD160.update RIPEMD160.finalize }
 tigerHash = HashFct { fctHash = Tiger.hash, fctInc = hashinc Tiger.init Tiger.update Tiger.finalize }
 
@@ -144,22 +146,6 @@
         "19fa61d75522a4669b44e39c1d2e1726c530232130d407f89afee0964997f7a73e83be698b288febcf88e3e03c4f0757ea8964e59b63d93708b138cc42a66eb3",
         "b97de512e91e3828b40d2b0fdce9ceb3c4a71f9bea8d88e75c4fa854df36725fd2b52eb6544edcacd6f8beddfea403cb55ae31f03ad62a5ef54e42ee82c3fb35",
         "dce81fc695cfea3d7e1446509238daf89f24cc61896f2d265927daa70f2108f8902f0dfd68be085d5abb9fcd2e482c1dc24f2fabf81f40b73495cad44d7360d3"])
-    , ("SHA3-224", sha3Hash 224, [
-        "f71837502ba8e10837bdd8d365adb85591895602fc552b48b7390abd",
-        "310aee6b30c47350576ac2873fa89fd190cdc488442f3ef654cf23fe",
-        "0b27ff3b732133287f6831e2af47cf342b7ef1f3fcdee248811090cd" ])
-    , ("SHA3-256", sha3Hash 256, [
-        "c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470",
-        "4d741b6f1eb29cb2a9b9911c82f56fa8d73b04959d3d9d222895df6c0b28aa15",
-        "ed6c07f044d7573cc53bf1276f8cba3dac497919597a45b4599c8f73e22aa334" ])
-    , ("SHA3-384", sha3Hash 384, [
-        "2c23146a63a29acf99e73b88f8c24eaa7dc60aa771780ccc006afbfa8fe2479b2dd2b21362337441ac12b515911957ff",
-        "283990fa9d5fb731d786c5bbee94ea4db4910f18c62c03d173fc0a5e494422e8a0b3da7574dae7fa0baf005e504063b3",
-        "1cc515e1812491058d8b8b226fd85045e746b4937a58b0111b6b7a39dd431b6295bd6b6d05e01e225586b4dab3cbb87a" ])
-    , ("SHA3-512", sha3Hash 512, [
-        "0eab42de4c3ceb9235fc91acffe746b29c29a8c366b7c60e4e67c466f36a4304c00fa9caf9d87976ba469bcbe06713b435f091ef2769fb160cdab33d3670680e",
-        "d135bb84d0439dbac432247ee573a23ea7d3c9deb2a968eb31d47c4fb45f1ef4422d6c531b5b9bd6f449ebcc449ea94d0a8f05f62130fda612da53c79659f609",
-        "10f8caabb5b179861da5e447d34b84d604e3eb81830880e1c2135ffc94580a47cb21f6243ec0053d58b1124d13af2090033659075ee718e0f111bb3f69fb24cf" ])
     ]
 
 hexalise s = concatMap (\c -> [ hex $ c `div` 16, hex $ c `mod` 16 ]) s
@@ -205,17 +191,14 @@
             , testCase (show i ++ " inc 16") (r @=? runtestinc 16 v)
             ]
 
-katTests :: [Test]
+katTests :: [TestTree]
 katTests = map makeTestAlg results
 
-apiTests :: [Test]
+apiTests :: [TestTree]
 apiTests =
     [ testCase "sha1 api" (runhash sha1Hash B.empty @=? show (hash B.empty :: Digest SHA1))
     , testCase "sha256 api" (runhash sha256Hash B.empty @=? show (hash B.empty :: Digest SHA256))
     , testCase "sha512 api" (runhash sha512Hash B.empty @=? show (hash B.empty :: Digest SHA512))
-    , testCase "sha3-224 api" (runhash (sha3Hash 224) B.empty @=? show (hash B.empty :: Digest SHA3_224))
-    , testCase "sha3-256 api" (runhash (sha3Hash 256) B.empty @=? show (hash B.empty :: Digest SHA3_256))
-    , testCase "sha3-512 api" (runhash (sha3Hash 512) B.empty @=? show (hash B.empty :: Digest SHA3_512))
     ]
 
 
@@ -239,17 +222,43 @@
     , MACVector "key"   v1      "\xf7\xbc\x83\xf4\x30\x53\x84\x24\xb1\x32\x98\xe6\xaa\x6f\xb1\x43\xef\x4d\x59\xa1\x49\x46\x17\x59\x97\x47\x9d\xbc\x2d\x1a\x3c\xd8"
     ]
 
-macTests :: [Test]
+macTests :: [TestTree]
 macTests =
-    [ testGroup "hmac-md5" $ map (toMACTest MD5.hash 64) $ zip [0..] md5MACVectors
-    , testGroup "hmac-sha1" $ map (toMACTest SHA1.hash 64) $ zip [0..] sha1MACVectors
-    , testGroup "hmac-sha256" $ map (toMACTest SHA256.hash 64) $ zip [0..] sha256MACVectors
+    [ testGroup "hmac-md5" $ map (toMACTest MD5) $ zip [0..] md5MACVectors
+    , testGroup "hmac-sha1" $ map (toMACTest SHA1) $ zip [0..] sha1MACVectors
+    , testGroup "hmac-sha256" $ map (toMACTest SHA256) $ zip [0..] sha256MACVectors
     ]
-    where toMACTest hashF blockSize (i, macVector) =
-            testCase (show i) (macResult macVector @=? HMAC.hmac hashF blockSize (macKey macVector) (macSecret macVector))
+    where toMACTest hashAlg (i, macVector) =
+            testCase (show i) (macResult macVector @=? toBytes (hmacAlg hashAlg (macKey macVector) (macSecret macVector)))
 
-main = defaultMain
+macIncrementalTests :: [TestTree]
+macIncrementalTests =
+    [ testGroup "hmac-md5" $ map (toMACTest MD5) $ zip [0..] md5MACVectors
+    , testGroup "hmac-sha1" $ map (toMACTest SHA1) $ zip [0..] sha1MACVectors
+    , testGroup "hmac-sha256" $ map (toMACTest SHA256) $ zip [0..] sha256MACVectors
+
+    , testProperty "hmac-md5" $ prop_inc0 MD5
+    , testProperty "hmac-md5" $ prop_inc1 MD5
+    , testProperty "hmac-sha1" $ prop_inc0 SHA1
+    , testProperty "hmac-sha1" $ prop_inc1 SHA1
+    , testProperty "hmac-sha256" $ prop_inc0 SHA256
+    , testProperty "hmac-sha256" $ prop_inc1 SHA256
+    ]
+    where toMACTest hashAlg (i, macVector) =
+            testCase (show i) (macResult macVector @=? toBytes (hmacFinalize $ hmacUpdate initCtx (macSecret macVector)))
+              where initCtx = hmacInitAlg hashAlg (macKey macVector)
+
+          prop_inc0 :: HashAlgorithm a => a -> ByteString -> ByteString -> Bool
+          prop_inc0 hashAlg secret msg = hmacFinalize (hmacUpdate initCtx msg) == hmacAlg hashAlg secret msg
+              where initCtx = hmacInitAlg hashAlg secret
+
+          prop_inc1 :: HashAlgorithm a => a -> ByteString -> [ByteString] -> Bool
+          prop_inc1 hashAlg secret msgs = hmacFinalize (foldl' hmacUpdate initCtx msgs) == hmacAlg hashAlg secret (mconcat msgs)
+              where initCtx = hmacInitAlg hashAlg secret
+
+main = defaultMain $ testGroup "cryptohash"
     [ testGroup "KATs" katTests
     , testGroup "API" apiTests
     , testGroup "MACs" macTests
+    , testGroup "Incremental MACs" macIncrementalTests
     ]
diff --git a/cbits/bitfn.h b/cbits/bitfn.h
--- a/cbits/bitfn.h
+++ b/cbits/bitfn.h
@@ -169,6 +169,14 @@
   # include <machine/endian.h>
 #elif defined( BSD ) && ( BSD >= 199103 )
   # include <machine/endian.h>
+#elif defined( __QNXNTO__ ) && defined( __LITTLEENDIAN__ )
+  # define LITTLE_ENDIAN 1234
+  # define BYTE_ORDER    LITTLE_ENDIAN
+#elif defined( __QNXNTO__ ) && defined( __BIGENDIAN__ )
+  # define BIG_ENDIAN 1234
+  # define BYTE_ORDER    BIG_ENDIAN
+#elif defined( _AIX )
+  # include <sys/machine.h>
 #else
   # include <endian.h>
 #endif
diff --git a/cbits/md2.c b/cbits/md2.c
deleted file mode 100644
--- a/cbits/md2.c
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * Copyright (C) 2006-2010 Vincent Hanquez <vincent@snarc.org>
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <string.h>
-#include <stdio.h>
-#include "bitfn.h"
-#include "md2.h"
-
-void md2_init(struct md2_ctx *ctx)
-{
-	memset(ctx, 0, sizeof(*ctx));
-	ctx->sz = 0ULL;
-}
-
-static uint8_t S_table[]  = {
-	0x29, 0x2E, 0x43, 0xC9, 0xA2, 0xD8, 0x7C, 0x01, 0x3D, 0x36, 0x54, 0xA1, 0xEC, 0xF0, 0x06, 0x13, 
-	0x62, 0xA7, 0x05, 0xF3, 0xC0, 0xC7, 0x73, 0x8C, 0x98, 0x93, 0x2B, 0xD9, 0xBC, 0x4C, 0x82, 0xCA, 
-	0x1E, 0x9B, 0x57, 0x3C, 0xFD, 0xD4, 0xE0, 0x16, 0x67, 0x42, 0x6F, 0x18, 0x8A, 0x17, 0xE5, 0x12, 
-	0xBE, 0x4E, 0xC4, 0xD6, 0xDA, 0x9E, 0xDE, 0x49, 0xA0, 0xFB, 0xF5, 0x8E, 0xBB, 0x2F, 0xEE, 0x7A, 
-	0xA9, 0x68, 0x79, 0x91, 0x15, 0xB2, 0x07, 0x3F, 0x94, 0xC2, 0x10, 0x89, 0x0B, 0x22, 0x5F, 0x21,
-	0x80, 0x7F, 0x5D, 0x9A, 0x5A, 0x90, 0x32, 0x27, 0x35, 0x3E, 0xCC, 0xE7, 0xBF, 0xF7, 0x97, 0x03, 
-	0xFF, 0x19, 0x30, 0xB3, 0x48, 0xA5, 0xB5, 0xD1, 0xD7, 0x5E, 0x92, 0x2A, 0xAC, 0x56, 0xAA, 0xC6, 
-	0x4F, 0xB8, 0x38, 0xD2, 0x96, 0xA4, 0x7D, 0xB6, 0x76, 0xFC, 0x6B, 0xE2, 0x9C, 0x74, 0x04, 0xF1, 
-	0x45, 0x9D, 0x70, 0x59, 0x64, 0x71, 0x87, 0x20, 0x86, 0x5B, 0xCF, 0x65, 0xE6, 0x2D, 0xA8, 0x02, 
-	0x1B, 0x60, 0x25, 0xAD, 0xAE, 0xB0, 0xB9, 0xF6, 0x1C, 0x46, 0x61, 0x69, 0x34, 0x40, 0x7E, 0x0F, 
-	0x55, 0x47, 0xA3, 0x23, 0xDD, 0x51, 0xAF, 0x3A, 0xC3, 0x5C, 0xF9, 0xCE, 0xBA, 0xC5, 0xEA, 0x26, 
-	0x2C, 0x53, 0x0D, 0x6E, 0x85, 0x28, 0x84, 0x09, 0xD3, 0xDF, 0xCD, 0xF4, 0x41, 0x81, 0x4D, 0x52, 
-	0x6A, 0xDC, 0x37, 0xC8, 0x6C, 0xC1, 0xAB, 0xFA, 0x24, 0xE1, 0x7B, 0x08, 0x0C, 0xBD, 0xB1, 0x4A, 
-	0x78, 0x88, 0x95, 0x8B, 0xE3, 0x63, 0xE8, 0x6D, 0xE9, 0xCB, 0xD5, 0xFE, 0x3B, 0x00, 0x1D, 0x39, 
-	0xF2, 0xEF, 0xB7, 0x0E, 0x66, 0x58, 0xD0, 0xE4, 0xA6, 0x77, 0x72, 0xF8, 0xEB, 0x75, 0x4B, 0x0A, 
-	0x31, 0x44, 0x50, 0xB4, 0x8F, 0xED, 0x1F, 0x1A, 0xDB, 0x99, 0x8D, 0x33, 0x9F, 0x11, 0x83, 0x14
-};
-
-static uint8_t *padding_table[] = {
-	"",
-	"\x1",
-	"\x2\x2",
-	"\x3\x3\x3",
-	"\x4\x4\x4\x4",
-	"\x5\x5\x5\x5\x5",
-	"\x6\x6\x6\x6\x6\x6",
-	"\x7\x7\x7\x7\x7\x7\x7",
-	"\x8\x8\x8\x8\x8\x8\x8\x8",
-	"\x9\x9\x9\x9\x9\x9\x9\x9\x9",
-	"\xa\xa\xa\xa\xa\xa\xa\xa\xa\xa",
-	"\xb\xb\xb\xb\xb\xb\xb\xb\xb\xb\xb",
-	"\xc\xc\xc\xc\xc\xc\xc\xc\xc\xc\xc\xc",
-	"\xd\xd\xd\xd\xd\xd\xd\xd\xd\xd\xd\xd\xd",
-	"\xe\xe\xe\xe\xe\xe\xe\xe\xe\xe\xe\xe\xe\xe",
-	"\xf\xf\xf\xf\xf\xf\xf\xf\xf\xf\xf\xf\xf\xf\xf",
-	"\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10"
-};
-
-static void md2_do_chunk(struct md2_ctx *ctx, uint8_t *buf)
-{
-	uint8_t i, j, t;
-	uint8_t x[48];
-
-	memcpy(x, ctx->h, 16);
-	memcpy(x+16, buf, 16);
-
-	for (i = 0; i < 16; i++)
-		x[i+32] = ctx->h[i] ^ buf[i];
-
-	for (t = i = 0; i < 18; i++) {
-		for (j = 0; j < 48; j++)
-			t = x[j] ^= S_table[t];
-		t = (t + i) & 0xff;
-	}
-
-	memcpy(ctx->h, x, 16);
-
-	t = ctx->cksum[15];
-	for (i = 0; i < 16; i++)
-		t = ctx->cksum[i] ^= S_table[buf[i] ^ t];
-}
-
-void md2_update(struct md2_ctx *ctx, uint8_t *data, uint32_t len)
-{
-	uint32_t index, to_fill;
-
-	index = (uint32_t) (ctx->sz & 0xf);
-	to_fill = 16 - index;
-
-	ctx->sz += len;
-
-	if (index && len >= to_fill) {
-		memcpy(ctx->buf + index, data, to_fill);
-		md2_do_chunk(ctx, ctx->buf);
-		len -= to_fill;
-		data += to_fill;
-		index = 0;
-	}
-
-	/* process as much 16-block as possible */
-	for (; len >= 16; len -= 16, data += 16)
-		md2_do_chunk(ctx, data);
-
-	/* append data into buf */
-	if (len)
-		memcpy(ctx->buf + index, data, len);
-}
-
-void md2_finalize(struct md2_ctx *ctx, uint8_t *out)
-{
-	uint32_t index, padlen;
-
-	index = ctx->sz & 0xf;
-	padlen = 16 - index;
-
-	md2_update(ctx, padding_table[padlen], padlen);
-	md2_update(ctx, ctx->cksum, 16);
-	memcpy(out, ctx->h, 16);
-}
diff --git a/cbits/md2.h b/cbits/md2.h
deleted file mode 100644
--- a/cbits/md2.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (C) 2006-2009 Vincent Hanquez <vincent@snarc.org>
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-#ifndef CRYPTOHASH_MD2_H
-#define CRYPTOHASH_MD2_H
-
-#include <stdint.h>
-
-struct md2_ctx
-{
-	uint64_t sz;
-	uint8_t  buf[16];
-	uint8_t  h[16];
-	uint8_t  cksum[16];
-};
-
-#define MD2_DIGEST_SIZE		16
-#define MD2_CTX_SIZE		sizeof(struct md2_ctx)
-
-void md2_init(struct md2_ctx *ctx);
-void md2_update(struct md2_ctx *ctx, uint8_t *data, uint32_t len);
-void md2_finalize(struct md2_ctx *ctx, uint8_t *out);
-
-#endif
diff --git a/cbits/md4.c b/cbits/md4.c
deleted file mode 100644
--- a/cbits/md4.c
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- * Copyright (C) 2006-2009 Vincent Hanquez <vincent@snarc.org>
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <string.h>
-#include <stdio.h>
-#include "bitfn.h"
-#include "md4.h"
-
-void md4_init(struct md4_ctx *ctx)
-{
-	memset(ctx, 0, sizeof(*ctx));
-
-	ctx->sz = 0ULL;
-	ctx->h[0] = 0x67452301;
-	ctx->h[1] = 0xefcdab89;
-	ctx->h[2] = 0x98badcfe;
-	ctx->h[3] = 0x10325476;
-}
-
-#define f1(x, y, z)	((x & y) | ((~x) & z))
-#define f2(x, y, z)	((x & y) | (x & z) | (y & z))
-#define f3(x, y, z)	(x ^ y ^ z)
-
-#define K1 	0x00000000
-#define K2 	0x5A827999
-#define K3 	0x6ED9EBA1
-#define R(a,b,c,d,f,k,s,i) (a = rol32(a + f(b,c,d) + w[i] + k, s))
-
-static void md4_do_chunk(struct md4_ctx *ctx, uint32_t *buf)
-{
-	uint32_t a, b, c, d;
-#ifdef ARCH_IS_BIG_ENDIAN
-	uint32_t w[16];
-	cpu_to_le32_array(w, (uint32_t *) buf, 16);
-#else
-	uint32_t *w = buf;
-#endif
-
-	a = ctx->h[0]; b = ctx->h[1]; c = ctx->h[2]; d = ctx->h[3];
-
-	R(a, b, c, d, f1, K1, 3, 0);
-	R(d, a, b, c, f1, K1, 7, 1);
-	R(c, d, a, b, f1, K1, 11, 2);
-	R(b, c, d, a, f1, K1, 19, 3);
-	R(a, b, c, d, f1, K1, 3, 4);
-	R(d, a, b, c, f1, K1, 7, 5);
-	R(c, d, a, b, f1, K1, 11, 6);
-	R(b, c, d, a, f1, K1, 19, 7);
-	R(a, b, c, d, f1, K1, 3, 8);
-	R(d, a, b, c, f1, K1, 7, 9);
-	R(c, d, a, b, f1, K1, 11, 10);
-	R(b, c, d, a, f1, K1, 19, 11);
-	R(a, b, c, d, f1, K1, 3, 12);
-	R(d, a, b, c, f1, K1, 7, 13);
-	R(c, d, a, b, f1, K1, 11, 14);
-	R(b, c, d, a, f1, K1, 19, 15);
-
-	R(a, b, c, d, f2, K2, 3, 0);
-	R(d, a, b, c, f2, K2, 5, 4);
-	R(c, d, a, b, f2, K2, 9, 8);
-	R(b, c, d, a, f2, K2, 13, 12);
-	R(a, b, c, d, f2, K2, 3, 1);
-	R(d, a, b, c, f2, K2, 5, 5);
-	R(c, d, a, b, f2, K2, 9, 9);
-	R(b, c, d, a, f2, K2, 13, 13);
-	R(a, b, c, d, f2, K2, 3, 2);
-	R(d, a, b, c, f2, K2, 5, 6);
-	R(c, d, a, b, f2, K2, 9, 10);
-	R(b, c, d, a, f2, K2, 13, 14);
-	R(a, b, c, d, f2, K2, 3, 3);
-	R(d, a, b, c, f2, K2, 5, 7);
-	R(c, d, a, b, f2, K2, 9, 11);
-	R(b, c, d, a, f2, K2, 13, 15);
-
-	R(a, b, c, d, f3, K3, 3, 0);
-	R(d, a, b, c, f3, K3, 9, 8);
-	R(c, d, a, b, f3, K3, 11, 4);
-	R(b, c, d, a, f3, K3, 15, 12);
-	R(a, b, c, d, f3, K3, 3, 2);
-	R(d, a, b, c, f3, K3, 9, 10);
-	R(c, d, a, b, f3, K3, 11, 6);
-	R(b, c, d, a, f3, K3, 15, 14);
-	R(a, b, c, d, f3, K3, 3, 1);
-	R(d, a, b, c, f3, K3, 9, 9);
-	R(c, d, a, b, f3, K3, 11, 5);
-	R(b, c, d, a, f3, K3, 15, 13);
-	R(a, b, c, d, f3, K3, 3, 3);
-	R(d, a, b, c, f3, K3, 9, 11);
-	R(c, d, a, b, f3, K3, 11, 7);
-	R(b, c, d, a, f3, K3, 15, 15);
-
-	ctx->h[0] += a; ctx->h[1] += b; ctx->h[2] += c; ctx->h[3] += d;
-}
-
-void md4_update(struct md4_ctx *ctx, uint8_t *data, uint32_t len)
-{
-	uint32_t index, to_fill;
-
-	index = (uint32_t) (ctx->sz & 0x3f);
-	to_fill = 64 - index;
-
-	ctx->sz += len;
-
-	if (index && len >= to_fill) {
-		memcpy(ctx->buf + index, data, to_fill);
-		md4_do_chunk(ctx, (uint32_t *) ctx->buf);
-		len -= to_fill;
-		data += to_fill;
-		index = 0;
-	}
-
-	/* process as much 64-block as possible */
-	for (; len >= 64; len -= 64, data += 64)
-		md4_do_chunk(ctx, (uint32_t *) data);
-
-	/* append data into buf */
-	if (len)
-		memcpy(ctx->buf + index, data, len);
-}
-
-void md4_finalize(struct md4_ctx *ctx, uint8_t *out)
-{
-	static uint8_t padding[64] = { 0x80, };
-	uint64_t bits;
-	uint32_t index, padlen;
-
-	/* add padding and update data with it */
-	bits = cpu_to_le64(ctx->sz << 3);
-
-	/* pad out to 56 */
-	index = (uint32_t) (ctx->sz & 0x3f);
-	padlen = (index < 56) ? (56 - index) : ((64 + 56) - index);
-	md4_update(ctx, padding, padlen);
-
-	/* append length */
-	md4_update(ctx, (uint8_t *) &bits, sizeof(bits));
-
-	/* output hash */
-	le32_to_cpu_array((uint32_t *) out, ctx->h, 4);
-}
diff --git a/cbits/md4.h b/cbits/md4.h
deleted file mode 100644
--- a/cbits/md4.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2006-2009 Vincent Hanquez <vincent@snarc.org>
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-#ifndef CRYPTOHASH_MD4_H
-#define CRYPTOHASH_MD4_H
-
-#include <stdint.h>
-
-struct md4_ctx
-{
-	uint64_t sz;
-	uint8_t  buf[64];
-	uint32_t h[4];
-};
-
-#define MD4_DIGEST_SIZE		16
-#define MD4_CTX_SIZE		sizeof(struct md4_ctx)
-
-void md4_init(struct md4_ctx *ctx);
-void md4_update(struct md4_ctx *ctx, uint8_t *data, uint32_t len);
-void md4_finalize(struct md4_ctx *ctx, uint8_t *out);
-
-#endif
diff --git a/cbits/md5.c b/cbits/md5.c
deleted file mode 100644
--- a/cbits/md5.c
+++ /dev/null
@@ -1,178 +0,0 @@
-/*
- * Copyright (C) 2006-2009 Vincent Hanquez <vincent@snarc.org>
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <string.h>
-#include <stdio.h>
-#include "bitfn.h"
-#include "md5.h"
-
-void md5_init(struct md5_ctx *ctx)
-{
-	memset(ctx, 0, sizeof(*ctx));
-
-	ctx->sz = 0ULL;
-	ctx->h[0] = 0x67452301;
-	ctx->h[1] = 0xefcdab89;
-	ctx->h[2] = 0x98badcfe;
-	ctx->h[3] = 0x10325476;
-}
-
-#define f1(x, y, z)	(z ^ (x & (y ^ z)))
-#define f2(x, y, z)	f1(z, x, y)
-#define f3(x, y, z)	(x ^ y ^ z)
-#define f4(x, y, z)	(y ^ (x | ~z))
-#define R(f, a, b, c, d, i, k, s) a += f(b, c, d) + w[i] + k; a = rol32(a, s); a += b
-
-static void md5_do_chunk(struct md5_ctx *ctx, uint32_t *buf)
-{
-	uint32_t a, b, c, d;
-#ifdef ARCH_IS_BIG_ENDIAN
-	uint32_t w[16];
-	cpu_to_le32_array(w, buf, 16);
-#else
-	uint32_t *w = buf;
-#endif
-	a = ctx->h[0]; b = ctx->h[1]; c = ctx->h[2]; d = ctx->h[3];
-
-	R(f1, a, b, c, d, 0, 0xd76aa478, 7);
-	R(f1, d, a, b, c, 1, 0xe8c7b756, 12);
-	R(f1, c, d, a, b, 2, 0x242070db, 17);
-	R(f1, b, c, d, a, 3, 0xc1bdceee, 22);
-	R(f1, a, b, c, d, 4, 0xf57c0faf, 7);
-	R(f1, d, a, b, c, 5, 0x4787c62a, 12);
-	R(f1, c, d, a, b, 6, 0xa8304613, 17);
-	R(f1, b, c, d, a, 7, 0xfd469501, 22);
-	R(f1, a, b, c, d, 8, 0x698098d8, 7);
-	R(f1, d, a, b, c, 9, 0x8b44f7af, 12);
-	R(f1, c, d, a, b, 10, 0xffff5bb1, 17);
-	R(f1, b, c, d, a, 11, 0x895cd7be, 22);
-	R(f1, a, b, c, d, 12, 0x6b901122, 7);
-	R(f1, d, a, b, c, 13, 0xfd987193, 12);
-	R(f1, c, d, a, b, 14, 0xa679438e, 17);
-	R(f1, b, c, d, a, 15, 0x49b40821, 22);
-
-	R(f2, a, b, c, d, 1, 0xf61e2562, 5);
-	R(f2, d, a, b, c, 6, 0xc040b340, 9);
-	R(f2, c, d, a, b, 11, 0x265e5a51, 14);
-	R(f2, b, c, d, a, 0, 0xe9b6c7aa, 20);
-	R(f2, a, b, c, d, 5, 0xd62f105d, 5);
-	R(f2, d, a, b, c, 10, 0x02441453, 9);
-	R(f2, c, d, a, b, 15, 0xd8a1e681, 14);
-	R(f2, b, c, d, a, 4, 0xe7d3fbc8, 20);
-	R(f2, a, b, c, d, 9, 0x21e1cde6, 5);
-	R(f2, d, a, b, c, 14, 0xc33707d6, 9);
-	R(f2, c, d, a, b, 3, 0xf4d50d87, 14);
-	R(f2, b, c, d, a, 8, 0x455a14ed, 20);
-	R(f2, a, b, c, d, 13, 0xa9e3e905, 5);
-	R(f2, d, a, b, c, 2, 0xfcefa3f8, 9);
-	R(f2, c, d, a, b, 7, 0x676f02d9, 14);
-	R(f2, b, c, d, a, 12, 0x8d2a4c8a, 20);
-
-	R(f3, a, b, c, d, 5, 0xfffa3942, 4);
-	R(f3, d, a, b, c, 8, 0x8771f681, 11);
-	R(f3, c, d, a, b, 11, 0x6d9d6122, 16);
-	R(f3, b, c, d, a, 14, 0xfde5380c, 23);
-	R(f3, a, b, c, d, 1, 0xa4beea44, 4);
-	R(f3, d, a, b, c, 4, 0x4bdecfa9, 11);
-	R(f3, c, d, a, b, 7, 0xf6bb4b60, 16);
-	R(f3, b, c, d, a, 10, 0xbebfbc70, 23);
-	R(f3, a, b, c, d, 13, 0x289b7ec6, 4);
-	R(f3, d, a, b, c, 0, 0xeaa127fa, 11);
-	R(f3, c, d, a, b, 3, 0xd4ef3085, 16);
-	R(f3, b, c, d, a, 6, 0x04881d05, 23);
-	R(f3, a, b, c, d, 9, 0xd9d4d039, 4);
-	R(f3, d, a, b, c, 12, 0xe6db99e5, 11);
-	R(f3, c, d, a, b, 15, 0x1fa27cf8, 16);
-	R(f3, b, c, d, a, 2, 0xc4ac5665, 23);
-
-	R(f4, a, b, c, d, 0, 0xf4292244, 6);
-	R(f4, d, a, b, c, 7, 0x432aff97, 10);
-	R(f4, c, d, a, b, 14, 0xab9423a7, 15);
-	R(f4, b, c, d, a, 5, 0xfc93a039, 21);
-	R(f4, a, b, c, d, 12, 0x655b59c3, 6);
-	R(f4, d, a, b, c, 3, 0x8f0ccc92, 10);
-	R(f4, c, d, a, b, 10, 0xffeff47d, 15);
-	R(f4, b, c, d, a, 1, 0x85845dd1, 21);
-	R(f4, a, b, c, d, 8, 0x6fa87e4f, 6);
-	R(f4, d, a, b, c, 15, 0xfe2ce6e0, 10);
-	R(f4, c, d, a, b, 6, 0xa3014314, 15);
-	R(f4, b, c, d, a, 13, 0x4e0811a1, 21);
-	R(f4, a, b, c, d, 4, 0xf7537e82, 6);
-	R(f4, d, a, b, c, 11, 0xbd3af235, 10);
-	R(f4, c, d, a, b, 2, 0x2ad7d2bb, 15);
-	R(f4, b, c, d, a, 9, 0xeb86d391, 21);
-
-	ctx->h[0] += a; ctx->h[1] += b; ctx->h[2] += c; ctx->h[3] += d;
-}
-
-void md5_update(struct md5_ctx *ctx, uint8_t *data, uint32_t len)
-{
-	uint32_t index, to_fill;
-
-	index = (uint32_t) (ctx->sz & 0x3f);
-	to_fill = 64 - index;
-
-	ctx->sz += len;
-
-	if (index && len >= to_fill) {
-		memcpy(ctx->buf + index, data, to_fill);
-		md5_do_chunk(ctx, (uint32_t *) ctx->buf);
-		len -= to_fill;
-		data += to_fill;
-		index = 0;
-	}
-
-	/* process as much 64-block as possible */
-	for (; len >= 64; len -= 64, data += 64)
-		md5_do_chunk(ctx, (uint32_t *) data);
-
-	/* append data into buf */
-	if (len)
-		memcpy(ctx->buf + index, data, len);
-}
-
-void md5_finalize(struct md5_ctx *ctx, uint8_t *out)
-{
-	static uint8_t padding[64] = { 0x80, };
-	uint64_t bits;
-	uint32_t index, padlen;
-	uint32_t *p = (uint32_t *) out;
-
-	/* add padding and update data with it */
-	bits = cpu_to_le64(ctx->sz << 3);
-
-	/* pad out to 56 */
-	index = (uint32_t) (ctx->sz & 0x3f);
-	padlen = (index < 56) ? (56 - index) : ((64 + 56) - index);
-	md5_update(ctx, padding, padlen);
-
-	/* append length */
-	md5_update(ctx, (uint8_t *) &bits, sizeof(bits));
-
-	/* output hash */
-	p[0] = cpu_to_le32(ctx->h[0]);
-	p[1] = cpu_to_le32(ctx->h[1]);
-	p[2] = cpu_to_le32(ctx->h[2]);
-	p[3] = cpu_to_le32(ctx->h[3]);
-}
diff --git a/cbits/md5.h b/cbits/md5.h
deleted file mode 100644
--- a/cbits/md5.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2006-2009 Vincent Hanquez <vincent@snarc.org>
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-#ifndef CRYPTOHASH_MD5_H
-#define CRYPTOHASH_MD5_H
-
-#include <stdint.h>
-
-struct md5_ctx
-{
-	uint64_t sz;
-	uint8_t  buf[64];
-	uint32_t h[4];
-};
-
-#define MD5_DIGEST_SIZE		16
-#define MD5_CTX_SIZE		sizeof(struct md5_ctx)
-
-void md5_init(struct md5_ctx *ctx);
-void md5_update(struct md5_ctx *ctx, uint8_t *data, uint32_t len);
-void md5_finalize(struct md5_ctx *ctx, uint8_t *out);
-
-#endif
diff --git a/cbits/ripemd.c b/cbits/ripemd.c
deleted file mode 100644
--- a/cbits/ripemd.c
+++ /dev/null
@@ -1,299 +0,0 @@
-/*
- * Copyright (C) 2006-2009 Vincent Hanquez <vincent@snarc.org>
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "ripemd.h"
-#include "bitfn.h"
-#include <string.h>
-
-void ripemd160_init(struct ripemd160_ctx *ctx)
-{
-	memset(ctx, 0, sizeof(*ctx));
-
-	ctx->h[0] = 0x67452301;
-	ctx->h[1] = 0xefcdab89;
-	ctx->h[2] = 0x98badcfe;
-	ctx->h[3] = 0x10325476;
-	ctx->h[4] = 0xc3d2e1f0;
-}
-
-#define K1  0x00000000
-#define K2  0x5a827999
-#define K3  0x6ed9eba1
-#define K4  0x8f1bbcdc
-#define K5  0xa953fd4e
-#define K6  0x50a28be6
-#define K7  0x5c4dd124
-#define K8  0x6d703ef3
-#define K9  0x7a6d76e9
-
-#define f1(x, y, z) (x ^ y ^ z)
-#define f2(x, y, z) (z ^ (x & (y ^ z)))
-#define f3(x, y, z) ((x | ~y) ^ z)
-#define f4(x, y, z) (y ^ (z & (x ^ y)))
-#define f5(x, y, z) (x ^ (y | ~z))
-
-#define R(a, b, c, d, e, f, k, i, s)	\
-	a += f(b, c, d) + w[i] + k; a = rol32(a, s) + e; c = rol32(c, 10)
-
-static void ripemd160_do_chunk(struct ripemd160_ctx *ctx, uint32_t *buf)
-{
-	uint32_t a1, b1, c1, d1, e1, a2, b2, c2, d2, e2;
-#ifdef ARCH_IS_BIG_ENDIAN
-	uint32_t w[16];
-	cpu_to_le32_array(w, buf, 16);
-#else
-	uint32_t *w = buf;
-#endif
-
-	a1 = ctx->h[0]; b1 = ctx->h[1]; c1 = ctx->h[2]; d1 = ctx->h[3]; e1 = ctx->h[4];
-	a2 = ctx->h[0]; b2 = ctx->h[1]; c2 = ctx->h[2]; d2 = ctx->h[3]; e2 = ctx->h[4];
-
-	/* 5 passes on first state copy */
-	R(a1, b1, c1, d1, e1, f1, K1, 0, 11);
-	R(e1, a1, b1, c1, d1, f1, K1, 1, 14);
-	R(d1, e1, a1, b1, c1, f1, K1, 2, 15);
-	R(c1, d1, e1, a1, b1, f1, K1, 3, 12);
-	R(b1, c1, d1, e1, a1, f1, K1, 4, 5);
-	R(a1, b1, c1, d1, e1, f1, K1, 5, 8);
-	R(e1, a1, b1, c1, d1, f1, K1, 6, 7);
-	R(d1, e1, a1, b1, c1, f1, K1, 7, 9);
-	R(c1, d1, e1, a1, b1, f1, K1, 8, 11);
-	R(b1, c1, d1, e1, a1, f1, K1, 9, 13);
-	R(a1, b1, c1, d1, e1, f1, K1, 10, 14);
-	R(e1, a1, b1, c1, d1, f1, K1, 11, 15);
-	R(d1, e1, a1, b1, c1, f1, K1, 12, 6);
-	R(c1, d1, e1, a1, b1, f1, K1, 13, 7);
-	R(b1, c1, d1, e1, a1, f1, K1, 14, 9);
-	R(a1, b1, c1, d1, e1, f1, K1, 15, 8);
-	
-	R(e1, a1, b1, c1, d1, f2, K2, 7, 7);
-	R(d1, e1, a1, b1, c1, f2, K2, 4, 6);
-	R(c1, d1, e1, a1, b1, f2, K2, 13, 8);
-	R(b1, c1, d1, e1, a1, f2, K2, 1, 13);
-	R(a1, b1, c1, d1, e1, f2, K2, 10, 11);
-	R(e1, a1, b1, c1, d1, f2, K2, 6, 9);
-	R(d1, e1, a1, b1, c1, f2, K2, 15, 7);
-	R(c1, d1, e1, a1, b1, f2, K2, 3, 15);
-	R(b1, c1, d1, e1, a1, f2, K2, 12, 7);
-	R(a1, b1, c1, d1, e1, f2, K2, 0, 12);
-	R(e1, a1, b1, c1, d1, f2, K2, 9, 15);
-	R(d1, e1, a1, b1, c1, f2, K2, 5, 9);
-	R(c1, d1, e1, a1, b1, f2, K2, 2, 11);
-	R(b1, c1, d1, e1, a1, f2, K2, 14, 7);
-	R(a1, b1, c1, d1, e1, f2, K2, 11, 13);
-	R(e1, a1, b1, c1, d1, f2, K2, 8, 12);
-
-	R(d1, e1, a1, b1, c1, f3, K3, 3, 11);
-	R(c1, d1, e1, a1, b1, f3, K3, 10, 13);
-	R(b1, c1, d1, e1, a1, f3, K3, 14, 6);
-	R(a1, b1, c1, d1, e1, f3, K3, 4, 7);
-	R(e1, a1, b1, c1, d1, f3, K3, 9, 14);
-	R(d1, e1, a1, b1, c1, f3, K3, 15, 9);
-	R(c1, d1, e1, a1, b1, f3, K3, 8, 13);
-	R(b1, c1, d1, e1, a1, f3, K3, 1, 15);
-	R(a1, b1, c1, d1, e1, f3, K3, 2, 14);
-	R(e1, a1, b1, c1, d1, f3, K3, 7, 8);
-	R(d1, e1, a1, b1, c1, f3, K3, 0, 13);
-	R(c1, d1, e1, a1, b1, f3, K3, 6, 6);
-	R(b1, c1, d1, e1, a1, f3, K3, 13, 5);
-	R(a1, b1, c1, d1, e1, f3, K3, 11, 12);
-	R(e1, a1, b1, c1, d1, f3, K3, 5, 7);
-	R(d1, e1, a1, b1, c1, f3, K3, 12, 5);
-
-	R(c1, d1, e1, a1, b1, f4, K4, 1, 11);
-	R(b1, c1, d1, e1, a1, f4, K4, 9, 12);
-	R(a1, b1, c1, d1, e1, f4, K4, 11, 14);
-	R(e1, a1, b1, c1, d1, f4, K4, 10, 15);
-	R(d1, e1, a1, b1, c1, f4, K4, 0, 14);
-	R(c1, d1, e1, a1, b1, f4, K4, 8, 15);
-	R(b1, c1, d1, e1, a1, f4, K4, 12, 9);
-	R(a1, b1, c1, d1, e1, f4, K4, 4, 8);
-	R(e1, a1, b1, c1, d1, f4, K4, 13, 9);
-	R(d1, e1, a1, b1, c1, f4, K4, 3, 14);
-	R(c1, d1, e1, a1, b1, f4, K4, 7, 5);
-	R(b1, c1, d1, e1, a1, f4, K4, 15, 6);
-	R(a1, b1, c1, d1, e1, f4, K4, 14, 8);
-	R(e1, a1, b1, c1, d1, f4, K4, 5, 6);
-	R(d1, e1, a1, b1, c1, f4, K4, 6, 5);
-	R(c1, d1, e1, a1, b1, f4, K4, 2, 12);
-
-	R(b1, c1, d1, e1, a1, f5, K5, 4, 9);
-	R(a1, b1, c1, d1, e1, f5, K5, 0, 15);
-	R(e1, a1, b1, c1, d1, f5, K5, 5, 5);
-	R(d1, e1, a1, b1, c1, f5, K5, 9, 11);
-	R(c1, d1, e1, a1, b1, f5, K5, 7, 6);
-	R(b1, c1, d1, e1, a1, f5, K5, 12, 8);
-	R(a1, b1, c1, d1, e1, f5, K5, 2, 13);
-	R(e1, a1, b1, c1, d1, f5, K5, 10, 12);
-	R(d1, e1, a1, b1, c1, f5, K5, 14, 5);
-	R(c1, d1, e1, a1, b1, f5, K5, 1, 12);
-	R(b1, c1, d1, e1, a1, f5, K5, 3, 13);
-	R(a1, b1, c1, d1, e1, f5, K5, 8, 14);
-	R(e1, a1, b1, c1, d1, f5, K5, 11, 11);
-	R(d1, e1, a1, b1, c1, f5, K5, 6, 8);
-	R(c1, d1, e1, a1, b1, f5, K5, 15, 5);
-	R(b1, c1, d1, e1, a1, f5, K5, 13, 6);
-
-	/* 5 passes on second state copy */
-	R(a2, b2, c2, d2, e2, f5, K6, 5, 8);
-	R(e2, a2, b2, c2, d2, f5, K6, 14, 9);
-	R(d2, e2, a2, b2, c2, f5, K6, 7, 9);
-	R(c2, d2, e2, a2, b2, f5, K6, 0, 11);
-	R(b2, c2, d2, e2, a2, f5, K6, 9, 13);
-	R(a2, b2, c2, d2, e2, f5, K6, 2, 15);
-	R(e2, a2, b2, c2, d2, f5, K6, 11, 15);
-	R(d2, e2, a2, b2, c2, f5, K6, 4, 5);
-	R(c2, d2, e2, a2, b2, f5, K6, 13, 7);
-	R(b2, c2, d2, e2, a2, f5, K6, 6, 7);
-	R(a2, b2, c2, d2, e2, f5, K6, 15, 8);
-	R(e2, a2, b2, c2, d2, f5, K6, 8, 11);
-	R(d2, e2, a2, b2, c2, f5, K6, 1, 14);
-	R(c2, d2, e2, a2, b2, f5, K6, 10, 14);
-	R(b2, c2, d2, e2, a2, f5, K6, 3, 12);
-	R(a2, b2, c2, d2, e2, f5, K6, 12, 6);
-
-	R(e2, a2, b2, c2, d2, f4, K7, 6, 9);
-	R(d2, e2, a2, b2, c2, f4, K7, 11, 13);
-	R(c2, d2, e2, a2, b2, f4, K7, 3, 15);
-	R(b2, c2, d2, e2, a2, f4, K7, 7, 7);
-	R(a2, b2, c2, d2, e2, f4, K7, 0, 12);
-	R(e2, a2, b2, c2, d2, f4, K7, 13, 8);
-	R(d2, e2, a2, b2, c2, f4, K7, 5, 9);
-	R(c2, d2, e2, a2, b2, f4, K7, 10, 11);
-	R(b2, c2, d2, e2, a2, f4, K7, 14, 7);
-	R(a2, b2, c2, d2, e2, f4, K7, 15, 7);
-	R(e2, a2, b2, c2, d2, f4, K7, 8, 12);
-	R(d2, e2, a2, b2, c2, f4, K7, 12, 7);
-	R(c2, d2, e2, a2, b2, f4, K7, 4, 6);
-	R(b2, c2, d2, e2, a2, f4, K7, 9, 15);
-	R(a2, b2, c2, d2, e2, f4, K7, 1, 13);
-	R(e2, a2, b2, c2, d2, f4, K7, 2, 11);
-
-	R(d2, e2, a2, b2, c2, f3, K8, 15, 9);
-	R(c2, d2, e2, a2, b2, f3, K8, 5, 7);
-	R(b2, c2, d2, e2, a2, f3, K8, 1, 15);
-	R(a2, b2, c2, d2, e2, f3, K8, 3, 11);
-	R(e2, a2, b2, c2, d2, f3, K8, 7, 8);
-	R(d2, e2, a2, b2, c2, f3, K8, 14, 6);
-	R(c2, d2, e2, a2, b2, f3, K8, 6, 6);
-	R(b2, c2, d2, e2, a2, f3, K8, 9, 14);
-	R(a2, b2, c2, d2, e2, f3, K8, 11, 12);
-	R(e2, a2, b2, c2, d2, f3, K8, 8, 13);
-	R(d2, e2, a2, b2, c2, f3, K8, 12, 5);
-	R(c2, d2, e2, a2, b2, f3, K8, 2, 14);
-	R(b2, c2, d2, e2, a2, f3, K8, 10, 13);
-	R(a2, b2, c2, d2, e2, f3, K8, 0, 13);
-	R(e2, a2, b2, c2, d2, f3, K8, 4, 7);
-	R(d2, e2, a2, b2, c2, f3, K8, 13, 5);
-
-	R(c2, d2, e2, a2, b2, f2, K9, 8, 15);
-	R(b2, c2, d2, e2, a2, f2, K9, 6, 5);
-	R(a2, b2, c2, d2, e2, f2, K9, 4, 8);
-	R(e2, a2, b2, c2, d2, f2, K9, 1, 11);
-	R(d2, e2, a2, b2, c2, f2, K9, 3, 14);
-	R(c2, d2, e2, a2, b2, f2, K9, 11, 14);
-	R(b2, c2, d2, e2, a2, f2, K9, 15, 6);
-	R(a2, b2, c2, d2, e2, f2, K9, 0, 14);
-	R(e2, a2, b2, c2, d2, f2, K9, 5, 6);
-	R(d2, e2, a2, b2, c2, f2, K9, 12, 9);
-	R(c2, d2, e2, a2, b2, f2, K9, 2, 12);
-	R(b2, c2, d2, e2, a2, f2, K9, 13, 9);
-	R(a2, b2, c2, d2, e2, f2, K9, 9, 12);
-	R(e2, a2, b2, c2, d2, f2, K9, 7, 5);
-	R(d2, e2, a2, b2, c2, f2, K9, 10, 15);
-	R(c2, d2, e2, a2, b2, f2, K9, 14, 8);
-
-	R(b2, c2, d2, e2, a2, f1, K1, 12, 8);
-	R(a2, b2, c2, d2, e2, f1, K1, 15, 5);
-	R(e2, a2, b2, c2, d2, f1, K1, 10, 12);
-	R(d2, e2, a2, b2, c2, f1, K1, 4, 9);
-	R(c2, d2, e2, a2, b2, f1, K1, 1, 12);
-	R(b2, c2, d2, e2, a2, f1, K1, 5, 5);
-	R(a2, b2, c2, d2, e2, f1, K1, 8, 14);
-	R(e2, a2, b2, c2, d2, f1, K1, 7, 6);
-	R(d2, e2, a2, b2, c2, f1, K1, 6, 8);
-	R(c2, d2, e2, a2, b2, f1, K1, 2, 13);
-	R(b2, c2, d2, e2, a2, f1, K1, 13, 6);
-	R(a2, b2, c2, d2, e2, f1, K1, 14, 5);
-	R(e2, a2, b2, c2, d2, f1, K1, 0, 15);
-	R(d2, e2, a2, b2, c2, f1, K1, 3, 13);
-	R(c2, d2, e2, a2, b2, f1, K1, 9, 11);
-	R(b2, c2, d2, e2, a2, f1, K1, 11, 11);
-
-	d2 += c1 + ctx->h[1];
-	ctx->h[1] = ctx->h[2] + d1 + e2;
-	ctx->h[2] = ctx->h[3] + e1 + a2;
-	ctx->h[3] = ctx->h[4] + a1 + b2;
-	ctx->h[4] = ctx->h[0] + b1 + c2;
-	ctx->h[0] = d2;
-}
-
-void ripemd160_update(struct ripemd160_ctx *ctx, uint8_t *data, uint32_t len)
-{
-	uint32_t index, to_fill;
-
-	index = (uint32_t) (ctx->sz & 0x3f);
-	to_fill = 64 - index;
-
-	ctx->sz += len;
-	if (index && len >= to_fill) {
-		memcpy(ctx->buf + index, data, to_fill);
-		ripemd160_do_chunk(ctx, (uint32_t *) ctx->buf);
-		len -= to_fill;
-		data += to_fill;
-		index = 0;
-	}
-
-	for (; len >= 64; len -= 64, data += 64)
-		ripemd160_do_chunk(ctx, (uint32_t *) data);
-
-	if (len)
-		memcpy(ctx->buf + index, data, len);
-}
-
-void ripemd160_finalize(struct ripemd160_ctx *ctx, uint8_t *out)
-{
-	static uint8_t padding[64] = { 0x80, };
-	uint64_t bits;
-	uint32_t index, padlen;
-	uint32_t *p = (uint32_t *) out;
-
-	/* add padding and update data with it */
-	bits = cpu_to_le64(ctx->sz << 3);
-
-	/* pad out to 56 */
-	index = (uint32_t) (ctx->sz & 0x3f);
-	padlen = (index < 56) ? (56 - index) : ((64 + 56) - index);
-	ripemd160_update(ctx, padding, padlen);
-
-	/* append length */
-	ripemd160_update(ctx, (uint8_t *) &bits, sizeof(bits));
-
-	/* output digest */
-	p[0] = cpu_to_le32(ctx->h[0]);
-	p[1] = cpu_to_le32(ctx->h[1]);
-	p[2] = cpu_to_le32(ctx->h[2]);
-	p[3] = cpu_to_le32(ctx->h[3]);
-	p[4] = cpu_to_le32(ctx->h[4]);
-}
diff --git a/cbits/ripemd.h b/cbits/ripemd.h
deleted file mode 100644
--- a/cbits/ripemd.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2006-2009 Vincent Hanquez <vincent@snarc.org>
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-#ifndef CRYPTOHASH_RIPEMD_H
-#define CRYPTOHASH_RIPEMD_H
-
-#include <stdint.h>
-
-struct ripemd160_ctx
-{
-	uint64_t sz;
-	uint8_t  buf[64];
-	uint32_t h[5];
-};
-
-#define RIPEMD160_DIGEST_SIZE	20
-#define RIPEMD160_CTX_SIZE	sizeof(struct ripemd160_ctx)
-
-void ripemd160_init(struct ripemd160_ctx *ctx);
-void ripemd160_update(struct ripemd160_ctx *ctx, uint8_t *data, uint32_t len);
-void ripemd160_finalize(struct ripemd160_ctx *ctx, uint8_t *out);
-
-#endif
diff --git a/cbits/sha1.c b/cbits/sha1.c
deleted file mode 100644
--- a/cbits/sha1.c
+++ /dev/null
@@ -1,209 +0,0 @@
-/*
- * Copyright (C) 2006-2009 Vincent Hanquez <vincent@snarc.org>
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <string.h>
-#include "sha1.h"
-#include "bitfn.h"
-
-void sha1_init(struct sha1_ctx *ctx)
-{
-	memset(ctx, 0, sizeof(*ctx));
-
-	ctx->h[0] = 0x67452301;
-	ctx->h[1] = 0xefcdab89;
-	ctx->h[2] = 0x98badcfe;
-	ctx->h[3] = 0x10325476;
-	ctx->h[4] = 0xc3d2e1f0;
-}
-
-#define f1(x, y, z)   (z ^ (x & (y ^ z)))
-#define f2(x, y, z)   (x ^ y ^ z)
-#define f3(x, y, z)   ((x & y) + (z & (x ^ y)))
-#define f4(x, y, z)   f2(x, y, z)
-
-#define K1  0x5a827999
-#define K2  0x6ed9eba1
-#define K3  0x8f1bbcdc
-#define K4  0xca62c1d6
-
-#define R(a, b, c, d, e, f, k, w)  \
-	e += rol32(a, 5) + f(b, c, d) + k + w; b = rol32(b, 30)
-
-#define M(i)  (w[i & 0x0f] = rol32(w[i & 0x0f] ^ w[(i - 14) & 0x0f] \
-              ^ w[(i - 8) & 0x0f] ^ w[(i - 3) & 0x0f], 1))
-
-static inline void sha1_do_chunk(struct sha1_ctx *ctx, uint32_t *buf)
-{
-	uint32_t a, b, c, d, e;
-	uint32_t w[16];
-#define CPY(i)	w[i] = be32_to_cpu(buf[i])
-	CPY(0); CPY(1); CPY(2); CPY(3); CPY(4); CPY(5); CPY(6); CPY(7);
-	CPY(8); CPY(9); CPY(10); CPY(11); CPY(12); CPY(13); CPY(14); CPY(15);
-#undef CPY
-
-	a = ctx->h[0]; b = ctx->h[1]; c = ctx->h[2]; d = ctx->h[3]; e = ctx->h[4];
-
-	R(a, b, c, d, e, f1, K1, w[0]);
-	R(e, a, b, c, d, f1, K1, w[1]);
-	R(d, e, a, b, c, f1, K1, w[2]);
-	R(c, d, e, a, b, f1, K1, w[3]);
-	R(b, c, d, e, a, f1, K1, w[4]);
-	R(a, b, c, d, e, f1, K1, w[5]);
-	R(e, a, b, c, d, f1, K1, w[6]);
-	R(d, e, a, b, c, f1, K1, w[7]);
-	R(c, d, e, a, b, f1, K1, w[8]);
-	R(b, c, d, e, a, f1, K1, w[9]);
-	R(a, b, c, d, e, f1, K1, w[10]);
-	R(e, a, b, c, d, f1, K1, w[11]);
-	R(d, e, a, b, c, f1, K1, w[12]);
-	R(c, d, e, a, b, f1, K1, w[13]);
-	R(b, c, d, e, a, f1, K1, w[14]);
-	R(a, b, c, d, e, f1, K1, w[15]);
-	R(e, a, b, c, d, f1, K1, M(16));
-	R(d, e, a, b, c, f1, K1, M(17));
-	R(c, d, e, a, b, f1, K1, M(18));
-	R(b, c, d, e, a, f1, K1, M(19));
-
-	R(a, b, c, d, e, f2, K2, M(20));
-	R(e, a, b, c, d, f2, K2, M(21));
-	R(d, e, a, b, c, f2, K2, M(22));
-	R(c, d, e, a, b, f2, K2, M(23));
-	R(b, c, d, e, a, f2, K2, M(24));
-	R(a, b, c, d, e, f2, K2, M(25));
-	R(e, a, b, c, d, f2, K2, M(26));
-	R(d, e, a, b, c, f2, K2, M(27));
-	R(c, d, e, a, b, f2, K2, M(28));
-	R(b, c, d, e, a, f2, K2, M(29));
-	R(a, b, c, d, e, f2, K2, M(30));
-	R(e, a, b, c, d, f2, K2, M(31));
-	R(d, e, a, b, c, f2, K2, M(32));
-	R(c, d, e, a, b, f2, K2, M(33));
-	R(b, c, d, e, a, f2, K2, M(34));
-	R(a, b, c, d, e, f2, K2, M(35));
-	R(e, a, b, c, d, f2, K2, M(36));
-	R(d, e, a, b, c, f2, K2, M(37));
-	R(c, d, e, a, b, f2, K2, M(38));
-	R(b, c, d, e, a, f2, K2, M(39));
-
-	R(a, b, c, d, e, f3, K3, M(40));
-	R(e, a, b, c, d, f3, K3, M(41));
-	R(d, e, a, b, c, f3, K3, M(42));
-	R(c, d, e, a, b, f3, K3, M(43));
-	R(b, c, d, e, a, f3, K3, M(44));
-	R(a, b, c, d, e, f3, K3, M(45));
-	R(e, a, b, c, d, f3, K3, M(46));
-	R(d, e, a, b, c, f3, K3, M(47));
-	R(c, d, e, a, b, f3, K3, M(48));
-	R(b, c, d, e, a, f3, K3, M(49));
-	R(a, b, c, d, e, f3, K3, M(50));
-	R(e, a, b, c, d, f3, K3, M(51));
-	R(d, e, a, b, c, f3, K3, M(52));
-	R(c, d, e, a, b, f3, K3, M(53));
-	R(b, c, d, e, a, f3, K3, M(54));
-	R(a, b, c, d, e, f3, K3, M(55));
-	R(e, a, b, c, d, f3, K3, M(56));
-	R(d, e, a, b, c, f3, K3, M(57));
-	R(c, d, e, a, b, f3, K3, M(58));
-	R(b, c, d, e, a, f3, K3, M(59));
-
-	R(a, b, c, d, e, f4, K4, M(60));
-	R(e, a, b, c, d, f4, K4, M(61));
-	R(d, e, a, b, c, f4, K4, M(62));
-	R(c, d, e, a, b, f4, K4, M(63));
-	R(b, c, d, e, a, f4, K4, M(64));
-	R(a, b, c, d, e, f4, K4, M(65));
-	R(e, a, b, c, d, f4, K4, M(66));
-	R(d, e, a, b, c, f4, K4, M(67));
-	R(c, d, e, a, b, f4, K4, M(68));
-	R(b, c, d, e, a, f4, K4, M(69));
-	R(a, b, c, d, e, f4, K4, M(70));
-	R(e, a, b, c, d, f4, K4, M(71));
-	R(d, e, a, b, c, f4, K4, M(72));
-	R(c, d, e, a, b, f4, K4, M(73));
-	R(b, c, d, e, a, f4, K4, M(74));
-	R(a, b, c, d, e, f4, K4, M(75));
-	R(e, a, b, c, d, f4, K4, M(76));
-	R(d, e, a, b, c, f4, K4, M(77));
-	R(c, d, e, a, b, f4, K4, M(78));
-	R(b, c, d, e, a, f4, K4, M(79));
-
-	ctx->h[0] += a;
-	ctx->h[1] += b;
-	ctx->h[2] += c;
-	ctx->h[3] += d;
-	ctx->h[4] += e;
-}
-
-void sha1_update(struct sha1_ctx *ctx, uint8_t *data, uint32_t len)
-{
-	uint32_t index, to_fill;
-
-	index = (uint32_t) (ctx->sz & 0x3f);
-	to_fill = 64 - index;
-
-	ctx->sz += len;
-
-	/* process partial buffer if there's enough data to make a block */
-	if (index && len >= to_fill) {
-		memcpy(ctx->buf + index, data, to_fill);
-		sha1_do_chunk(ctx, (uint32_t *) ctx->buf);
-		len -= to_fill;
-		data += to_fill;
-		index = 0;
-	}
-
-	/* process as much 64-block as possible */
-	for (; len >= 64; len -= 64, data += 64)
-		sha1_do_chunk(ctx, (uint32_t *) data);
-
-	/* append data into buf */
-	if (len)
-		memcpy(ctx->buf + index, data, len);
-}
-
-void sha1_finalize(struct sha1_ctx *ctx, uint8_t *out)
-{
-	static uint8_t padding[64] = { 0x80, };
-	uint64_t bits;
-	uint32_t index, padlen;
-	uint32_t *p = (uint32_t *) out;
-
-	/* add padding and update data with it */
-	bits = cpu_to_be64(ctx->sz << 3);
-
-	/* pad out to 56 */
-	index = (uint32_t) (ctx->sz & 0x3f);
-	padlen = (index < 56) ? (56 - index) : ((64 + 56) - index);
-	sha1_update(ctx, padding, padlen);
-
-	/* append length */
-	sha1_update(ctx, (uint8_t *) &bits, sizeof(bits));
-
-	/* output hash */
-	p[0] = cpu_to_be32(ctx->h[0]);
-	p[1] = cpu_to_be32(ctx->h[1]);
-	p[2] = cpu_to_be32(ctx->h[2]);
-	p[3] = cpu_to_be32(ctx->h[3]);
-	p[4] = cpu_to_be32(ctx->h[4]);
-}
diff --git a/cbits/sha1.h b/cbits/sha1.h
deleted file mode 100644
--- a/cbits/sha1.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2006-2009 Vincent Hanquez <vincent@snarc.org>
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-#ifndef CRYPTOHASH_SHA1_H
-#define CRYPTOHASH_SHA1_H
-
-#include <stdint.h>
-
-struct sha1_ctx
-{
-	uint64_t sz;
-	uint8_t  buf[64];
-	uint32_t h[5];
-};
-
-#define SHA1_DIGEST_SIZE	20
-#define SHA1_CTX_SIZE 		(sizeof(struct sha1_ctx))
-
-void sha1_init(struct sha1_ctx *ctx);
-void sha1_update(struct sha1_ctx *ctx, uint8_t *data, uint32_t len);
-void sha1_finalize(struct sha1_ctx *ctx, uint8_t *out);
-
-#endif
diff --git a/cbits/sha256.c b/cbits/sha256.c
deleted file mode 100644
--- a/cbits/sha256.c
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * Copyright (C) 2006-2009 Vincent Hanquez <vincent@snarc.org>
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <string.h>
-#include "sha256.h"
-#include "bitfn.h"
-
-void sha224_init(struct sha224_ctx *ctx)
-{
-	memset(ctx, 0, sizeof(*ctx));
-
-	ctx->h[0] = 0xc1059ed8;
-	ctx->h[1] = 0x367cd507;
-	ctx->h[2] = 0x3070dd17;
-	ctx->h[3] = 0xf70e5939;
-	ctx->h[4] = 0xffc00b31;
-	ctx->h[5] = 0x68581511;
-	ctx->h[6] = 0x64f98fa7;
-	ctx->h[7] = 0xbefa4fa4;
-}
-
-void sha256_init(struct sha256_ctx *ctx)
-{
-	memset(ctx, 0, sizeof(*ctx));
-
-	ctx->h[0] = 0x6a09e667;
-	ctx->h[1] = 0xbb67ae85;
-	ctx->h[2] = 0x3c6ef372;
-	ctx->h[3] = 0xa54ff53a;
-	ctx->h[4] = 0x510e527f;
-	ctx->h[5] = 0x9b05688c;
-	ctx->h[6] = 0x1f83d9ab;
-	ctx->h[7] = 0x5be0cd19;
-}
-
-/* 232 times the cube root of the first 64 primes 2..311 */
-static const uint32_t k[] = {
-	0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1,
-	0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
-	0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786,
-	0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
-	0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147,
-	0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
-	0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b,
-	0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
-	0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a,
-	0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
-	0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
-};
-
-#define e0(x)       (ror32(x, 2) ^ ror32(x,13) ^ ror32(x,22))
-#define e1(x)       (ror32(x, 6) ^ ror32(x,11) ^ ror32(x,25))
-#define s0(x)       (ror32(x, 7) ^ ror32(x,18) ^ (x >> 3))
-#define s1(x)       (ror32(x,17) ^ ror32(x,19) ^ (x >> 10))
-
-static void sha256_do_chunk(struct sha256_ctx *ctx, uint32_t buf[])
-{
-	uint32_t a, b, c, d, e, f, g, h, t1, t2;
-	int i;
-	uint32_t w[64];
-
-	cpu_to_be32_array(w, buf, 16);
-	for (i = 16; i < 64; i++)
-		w[i] = s1(w[i - 2]) + w[i - 7] + s0(w[i - 15]) + w[i - 16];
-
-	a = ctx->h[0]; b = ctx->h[1]; c = ctx->h[2]; d = ctx->h[3];
-	e = ctx->h[4]; f = ctx->h[5]; g = ctx->h[6]; h = ctx->h[7];
-
-#define R(a, b, c, d, e, f, g, h, k, w)			\
-	t1 = h + e1(e) + (g ^ (e & (f ^ g))) + k + w; 	\
-	t2 = e0(a) + ((a & b) | (c & (a | b)));		\
-	d += t1;					\
-	h = t1 + t2;
-
-	for (i = 0; i < 64; i += 8) {
-		R(a, b, c, d, e, f, g, h, k[i + 0], w[i + 0]);
-		R(h, a, b, c, d, e, f, g, k[i + 1], w[i + 1]);
-		R(g, h, a, b, c, d, e, f, k[i + 2], w[i + 2]);
-		R(f, g, h, a, b, c, d, e, k[i + 3], w[i + 3]);
-		R(e, f, g, h, a, b, c, d, k[i + 4], w[i + 4]);
-		R(d, e, f, g, h, a, b, c, k[i + 5], w[i + 5]);
-		R(c, d, e, f, g, h, a, b, k[i + 6], w[i + 6]);
-		R(b, c, d, e, f, g, h, a, k[i + 7], w[i + 7]);
-	}
-
-#undef R
-
-	ctx->h[0] += a; ctx->h[1] += b; ctx->h[2] += c; ctx->h[3] += d;
-	ctx->h[4] += e; ctx->h[5] += f; ctx->h[6] += g; ctx->h[7] += h;
-}
-
-void sha224_update(struct sha224_ctx *ctx, uint8_t *data, uint32_t len)
-{
-	return sha256_update(ctx, data, len);
-}
-
-void sha256_update(struct sha256_ctx *ctx, uint8_t *data, uint32_t len)
-{
-	uint32_t index, to_fill;
-
-	/* check for partial buffer */
-	index = (uint32_t) (ctx->sz & 0x3f);
-	to_fill = 64 - index;
-
-	ctx->sz += len;
-
-	/* process partial buffer if there's enough data to make a block */
-	if (index && len >= to_fill) {
-		memcpy(ctx->buf + index, data, to_fill);
-		sha256_do_chunk(ctx, (uint32_t *) ctx->buf);
-		len -= to_fill;
-		data += to_fill;
-		index = 0;
-	}
-
-	/* process as much 64-block as possible */
-	for (; len >= 64; len -= 64, data += 64)
-		sha256_do_chunk(ctx, (uint32_t *) data);
-
-	/* append data into buf */
-	if (len)
-		memcpy(ctx->buf + index, data, len);
-}
-
-void sha224_finalize(struct sha224_ctx *ctx, uint8_t *out)
-{
-	uint8_t intermediate[SHA256_DIGEST_SIZE];
-
-	sha256_finalize(ctx, intermediate);
-	memcpy(out, intermediate, SHA224_DIGEST_SIZE);
-}
-
-void sha256_finalize(struct sha256_ctx *ctx, uint8_t *out)
-{
-	static uint8_t padding[64] = { 0x80, };
-	uint64_t bits;
-	uint32_t i, index, padlen;
-	uint32_t *p = (uint32_t *) out;
-
-	/* cpu -> big endian */
-	bits = cpu_to_be64(ctx->sz << 3);
-
-	/* pad out to 56 */
-	index = (uint32_t) (ctx->sz & 0x3f);
-	padlen = (index < 56) ? (56 - index) : ((64 + 56) - index);
-	sha256_update(ctx, padding, padlen);
-
-	/* append length */
-	sha256_update(ctx, (uint8_t *) &bits, sizeof(bits));
-
-	/* store to digest */
-	for (i = 0; i < 8; i++)
-		p[i] = cpu_to_be32(ctx->h[i]);
-}
diff --git a/cbits/sha256.h b/cbits/sha256.h
deleted file mode 100644
--- a/cbits/sha256.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (C) 2006-2009 Vincent Hanquez <vincent@snarc.org>
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef CRYPTOHASH_SHA256_H
-#define CRYPTOHASH_SHA256_H
-
-#include <stdint.h>
-
-struct sha256_ctx
-{
-	uint64_t sz;
-	uint8_t  buf[128];
-	uint32_t h[8];
-};
-
-#define sha224_ctx 		sha256_ctx
-
-#define SHA224_DIGEST_SIZE	28
-#define SHA224_CTX_SIZE		sizeof(struct sha224_ctx)
-
-#define SHA256_DIGEST_SIZE	32
-#define SHA256_CTX_SIZE		sizeof(struct sha256_ctx)
-
-void sha224_init(struct sha224_ctx *ctx);
-void sha224_update(struct sha224_ctx *ctx, uint8_t *data, uint32_t len);
-void sha224_finalize(struct sha224_ctx *ctx, uint8_t *out);
-
-void sha256_init(struct sha256_ctx *ctx);
-void sha256_update(struct sha256_ctx *ctx, uint8_t *data, uint32_t len);
-void sha256_finalize(struct sha256_ctx *ctx, uint8_t *out);
-
-#endif
diff --git a/cbits/sha3.c b/cbits/sha3.c
--- a/cbits/sha3.c
+++ b/cbits/sha3.c
@@ -97,14 +97,14 @@
 	}
 }
 
-void sha3_init(struct sha3_ctx *ctx, uint32_t hashlen)
+void cryptohash_sha3_init(struct sha3_ctx *ctx, uint32_t hashlen)
 {
 	memset(ctx, 0, sizeof(*ctx));
 	ctx->hashlen = hashlen / 8;
 	ctx->bufsz = 200 - 2 * ctx->hashlen;
 }
 
-void sha3_update(struct sha3_ctx *ctx, uint8_t *data, uint32_t len)
+void cryptohash_sha3_update(struct sha3_ctx *ctx, uint8_t *data, uint32_t len)
 {
 	uint32_t to_fill;
 
@@ -124,8 +124,8 @@
 		ctx->bufindex = 0;
 	}
 
-	/* process as much ctx->bufsz-block as possible except the last one in case we finalize */
-	for (; len > ctx->bufsz; len -= ctx->bufsz, data += ctx->bufsz)
+	/* process as much ctx->bufsz-block */
+	for (; len >= ctx->bufsz; len -= ctx->bufsz, data += ctx->bufsz)
 		sha3_do_chunk(ctx->state, (uint64_t *) data, ctx->bufsz / 8);
 
 	/* append data into buf */
@@ -135,9 +135,15 @@
 	}
 }
 
-void sha3_finalize(struct sha3_ctx *ctx, uint8_t *out)
+void cryptohash_sha3_finalize(struct sha3_ctx *ctx, uint8_t *out)
 {
 	uint64_t w[25];
+
+	/* process full buffer if needed */
+	if (ctx->bufindex == ctx->bufsz) {
+		sha3_do_chunk(ctx->state, (uint64_t *) ctx->buf, ctx->bufsz / 8);
+		ctx->bufindex = 0;
+	}
 
 	/* add the 10*1 padding */
 	ctx->buf[ctx->bufindex++] = 1;
diff --git a/cbits/sha3.h b/cbits/sha3.h
--- a/cbits/sha3.h
+++ b/cbits/sha3.h
@@ -38,8 +38,8 @@
 
 #define SHA3_CTX_SIZE		sizeof(struct sha3_ctx)
 
-void sha3_init(struct sha3_ctx *ctx, uint32_t hashlen);
-void sha3_update(struct sha3_ctx *ctx, uint8_t *data, uint32_t len);
-void sha3_finalize(struct sha3_ctx *ctx, uint8_t *out);
+void cryptohash_sha3_init(struct sha3_ctx *ctx, uint32_t hashlen);
+void cryptohash_sha3_update(struct sha3_ctx *ctx, uint8_t *data, uint32_t len);
+void cryptohash_sha3_finalize(struct sha3_ctx *ctx, uint8_t *out);
 
 #endif
diff --git a/cbits/sha512.c b/cbits/sha512.c
--- a/cbits/sha512.c
+++ b/cbits/sha512.c
@@ -26,7 +26,7 @@
 #include "bitfn.h"
 #include "sha512.h"
 
-void sha384_init(struct sha512_ctx *ctx)
+void cryptohash_sha384_init(struct sha512_ctx *ctx)
 {
 	memset(ctx, 0, sizeof(*ctx));
 
@@ -40,7 +40,7 @@
 	ctx->h[7] = 0x47b5481dbefa4fa4ULL;
 }
 
-void sha512_init(struct sha512_ctx *ctx)
+void cryptohash_sha512_init(struct sha512_ctx *ctx)
 {
 	memset(ctx, 0, sizeof(*ctx));
 
@@ -127,12 +127,12 @@
 	ctx->h[4] += e; ctx->h[5] += f; ctx->h[6] += g; ctx->h[7] += h;
 }
 
-void sha384_update(struct sha384_ctx *ctx, uint8_t *data, uint32_t len)
+void cryptohash_sha384_update(struct sha384_ctx *ctx, uint8_t *data, uint32_t len)
 {
-	return sha512_update(ctx, data, len);
+	return cryptohash_sha512_update(ctx, data, len);
 }
 
-void sha512_update(struct sha512_ctx *ctx, uint8_t *data, uint32_t len)
+void cryptohash_sha512_update(struct sha512_ctx *ctx, uint8_t *data, uint32_t len)
 {
 	unsigned int index, to_fill;
 
@@ -162,15 +162,15 @@
 		memcpy(ctx->buf + index, data, len);
 }
 
-void sha384_finalize(struct sha384_ctx *ctx, uint8_t *out)
+void cryptohash_sha384_finalize(struct sha384_ctx *ctx, uint8_t *out)
 {
 	uint8_t intermediate[SHA512_DIGEST_SIZE];
 
-	sha512_finalize(ctx, intermediate);
+	cryptohash_sha512_finalize(ctx, intermediate);
 	memcpy(out, intermediate, SHA384_DIGEST_SIZE);
 }
 
-void sha512_finalize(struct sha512_ctx *ctx, uint8_t *out)
+void cryptohash_sha512_finalize(struct sha512_ctx *ctx, uint8_t *out)
 {
 	static uint8_t padding[128] = { 0x80, };
 	uint32_t i, index, padlen;
@@ -184,10 +184,10 @@
 	/* pad out to 56 */
 	index = (unsigned int) (ctx->sz[0] & 0x7f);
 	padlen = (index < 112) ? (112 - index) : ((128 + 112) - index);
-	sha512_update(ctx, padding, padlen);
+	cryptohash_sha512_update(ctx, padding, padlen);
 
 	/* append length */
-	sha512_update(ctx, (uint8_t *) bits, sizeof(bits));
+	cryptohash_sha512_update(ctx, (uint8_t *) bits, sizeof(bits));
 
 	/* store to digest */
 	for (i = 0; i < 8; i++)
@@ -196,7 +196,7 @@
 
 #include <stdio.h>
 
-void sha512_init_t(struct sha512_ctx *ctx, int t)
+void cryptohash_sha512_init_t(struct sha512_ctx *ctx, int t)
 {
 	memset(ctx, 0, sizeof(*ctx));
 	if (t >= 512)
@@ -228,13 +228,13 @@
 		uint8_t out[64];
 		int i;
 
-		sha512_init(ctx);
+		cryptohash_sha512_init(ctx);
 		for (i = 0; i < 8; i++)
 			ctx->h[i] ^= 0xa5a5a5a5a5a5a5a5ULL;
 
 		i = sprintf(buf, "SHA-512/%d", t);
-		sha512_update(ctx, buf, i);
-		sha512_finalize(ctx, out);
+		cryptohash_sha512_update(ctx, (uint8_t *) buf, i);
+		cryptohash_sha512_finalize(ctx, out);
 
 		/* re-init the context, otherwise len is changed */
 		memset(ctx, 0, sizeof(*ctx));
diff --git a/cbits/sha512.h b/cbits/sha512.h
--- a/cbits/sha512.h
+++ b/cbits/sha512.h
@@ -35,20 +35,20 @@
 
 #define sha384_ctx sha512_ctx
 
-#define SHA384_DIGEST_SIZE	64
+#define SHA384_DIGEST_SIZE	48
 #define SHA384_CTX_SIZE		sizeof(struct sha384_ctx)
 
 #define SHA512_DIGEST_SIZE	64
 #define SHA512_CTX_SIZE		sizeof(struct sha512_ctx)
 
-void sha384_init(struct sha384_ctx *ctx);
-void sha384_update(struct sha384_ctx *ctx, uint8_t *data, uint32_t len);
-void sha384_finalize(struct sha384_ctx *ctx, uint8_t *out);
+void cryptohash_sha384_init(struct sha384_ctx *ctx);
+void cryptohash_sha384_update(struct sha384_ctx *ctx, uint8_t *data, uint32_t len);
+void cryptohash_sha384_finalize(struct sha384_ctx *ctx, uint8_t *out);
 
-void sha512_init(struct sha512_ctx *ctx);
-void sha512_update(struct sha512_ctx *ctx, uint8_t *data, uint32_t len);
-void sha512_finalize(struct sha512_ctx *ctx, uint8_t *out);
+void cryptohash_sha512_init(struct sha512_ctx *ctx);
+void cryptohash_sha512_update(struct sha512_ctx *ctx, uint8_t *data, uint32_t len);
+void cryptohash_sha512_finalize(struct sha512_ctx *ctx, uint8_t *out);
 
-void sha512_init_t(struct sha512_ctx *ctx, int t);
+void cryptohash_sha512_init_t(struct sha512_ctx *ctx, int t);
 
 #endif
diff --git a/cbits/skein256.c b/cbits/skein256.c
--- a/cbits/skein256.c
+++ b/cbits/skein256.c
@@ -103,7 +103,7 @@
         ctx->h[3] = x[3] ^ cpu_to_le64(buf[3]);
 }
 
-void skein256_init(struct skein256_ctx *ctx, uint32_t hashlen)
+void cryptohash_skein256_init(struct skein256_ctx *ctx, uint32_t hashlen)
 {
 	uint64_t buf[4];
 	memset(ctx, 0, sizeof(*ctx));
@@ -120,10 +120,13 @@
 	SET_TYPE(ctx, FLAG_FIRST | FLAG_TYPE(TYPE_MSG));
 }
 
-void skein256_update(struct skein256_ctx *ctx, uint8_t *data, uint32_t len)
+void cryptohash_skein256_update(struct skein256_ctx *ctx, uint8_t *data, uint32_t len)
 {
 	uint32_t to_fill;
 
+	if (!len)
+		return;
+
 	to_fill = 32 - ctx->bufindex;
 
 	if (ctx->bufindex == 32) {
@@ -131,8 +134,9 @@
 		ctx->bufindex = 0;
 	}
 
-	/* process partial buffer if there's enough data to make a block */
-	if (ctx->bufindex && len >= to_fill) {
+	/* process partial buffer if there's enough data to make a block
+	 * and there's without doubt further blocks */
+	if (ctx->bufindex && len > to_fill) {
 		memcpy(ctx->buf + ctx->bufindex, data, to_fill);
 		skein256_do_chunk(ctx, (uint64_t *) ctx->buf, 32);
 		len -= to_fill;
@@ -151,7 +155,7 @@
 	}
 }
 
-void skein256_finalize(struct skein256_ctx *ctx, uint8_t *out)
+void cryptohash_skein256_finalize(struct skein256_ctx *ctx, uint8_t *out)
 {
 	uint32_t outsize;
 	uint64_t *p = (uint64_t *) out;
diff --git a/cbits/skein256.h b/cbits/skein256.h
--- a/cbits/skein256.h
+++ b/cbits/skein256.h
@@ -38,8 +38,8 @@
 
 #define SKEIN256_CTX_SIZE		sizeof(struct skein256_ctx)
 
-void skein256_init(struct skein256_ctx *ctx, uint32_t hashlen);
-void skein256_update(struct skein256_ctx *ctx, uint8_t *data, uint32_t len);
-void skein256_finalize(struct skein256_ctx *ctx, uint8_t *out);
+void cryptohash_skein256_init(struct skein256_ctx *ctx, uint32_t hashlen);
+void cryptohash_skein256_update(struct skein256_ctx *ctx, uint8_t *data, uint32_t len);
+void cryptohash_skein256_finalize(struct skein256_ctx *ctx, uint8_t *out);
 
 #endif
diff --git a/cbits/skein512.c b/cbits/skein512.c
--- a/cbits/skein512.c
+++ b/cbits/skein512.c
@@ -121,7 +121,7 @@
         ctx->h[7] = x[7] ^ cpu_to_le64(buf[7]);
 }
 
-void skein512_init(struct skein512_ctx *ctx, uint32_t hashlen)
+void cryptohash_skein512_init(struct skein512_ctx *ctx, uint32_t hashlen)
 {
 	uint64_t buf[8];
 	memset(ctx, 0, sizeof(*ctx));
@@ -138,10 +138,13 @@
 	SET_TYPE(ctx, FLAG_FIRST | FLAG_TYPE(TYPE_MSG));
 }
 
-void skein512_update(struct skein512_ctx *ctx, uint8_t *data, uint32_t len)
+void cryptohash_skein512_update(struct skein512_ctx *ctx, uint8_t *data, uint32_t len)
 {
 	uint32_t to_fill;
 
+	if (!len)
+		return;
+
 	to_fill = 64 - ctx->bufindex;
 
 	if (ctx->bufindex == 64) {
@@ -149,8 +152,9 @@
 		ctx->bufindex = 0;
 	}
 
-	/* process partial buffer if there's enough data to make a block */
-	if (ctx->bufindex && len >= to_fill) {
+	/* process partial buffer if there's enough data to make a block
+	 * and there's without doubt further blocks */
+	if (ctx->bufindex && len > to_fill) {
 		memcpy(ctx->buf + ctx->bufindex, data, to_fill);
 		skein512_do_chunk(ctx, (uint64_t *) ctx->buf, 64);
 		len -= to_fill;
@@ -169,7 +173,7 @@
 	}
 }
 
-void skein512_finalize(struct skein512_ctx *ctx, uint8_t *out)
+void cryptohash_skein512_finalize(struct skein512_ctx *ctx, uint8_t *out)
 {
 	uint32_t outsize;
 	uint64_t *p = (uint64_t *) out;
diff --git a/cbits/skein512.h b/cbits/skein512.h
--- a/cbits/skein512.h
+++ b/cbits/skein512.h
@@ -38,8 +38,8 @@
 
 #define SKEIN512_CTX_SIZE		sizeof(struct skein512_ctx)
 
-void skein512_init(struct skein512_ctx *ctx, uint32_t hashlen);
-void skein512_update(struct skein512_ctx *ctx, uint8_t *data, uint32_t len);
-void skein512_finalize(struct skein512_ctx *ctx, uint8_t *out);
+void cryptohash_skein512_init(struct skein512_ctx *ctx, uint32_t hashlen);
+void cryptohash_skein512_update(struct skein512_ctx *ctx, uint8_t *data, uint32_t len);
+void cryptohash_skein512_finalize(struct skein512_ctx *ctx, uint8_t *out);
 
 #endif
diff --git a/cbits/tiger.c b/cbits/tiger.c
deleted file mode 100644
--- a/cbits/tiger.c
+++ /dev/null
@@ -1,415 +0,0 @@
-/*
- * Copyright (C) 2006-2009 Vincent Hanquez <vincent@snarc.org>
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <string.h>
-#include "tiger.h"
-#include "bitfn.h"
-
-static const uint64_t t1[256] = {
-	0x02aab17cf7e90c5eULL,0xac424b03e243a8ecULL,0x72cd5be30dd5fcd3ULL,0x6d019b93f6f97f3aULL,
-	0xcd9978ffd21f9193ULL,0x7573a1c9708029e2ULL,0xb164326b922a83c3ULL,0x46883eee04915870ULL,
-	0xeaace3057103ece6ULL,0xc54169b808a3535cULL,0x4ce754918ddec47cULL,0x0aa2f4dfdc0df40cULL,
-	0x10b76f18a74dbefaULL,0xc6ccb6235ad1ab6aULL,0x13726121572fe2ffULL,0x1a488c6f199d921eULL,
-	0x4bc9f9f4da0007caULL,0x26f5e6f6e85241c7ULL,0x859079dbea5947b6ULL,0x4f1885c5c99e8c92ULL,
-	0xd78e761ea96f864bULL,0x8e36428c52b5c17dULL,0x69cf6827373063c1ULL,0xb607c93d9bb4c56eULL,
-	0x7d820e760e76b5eaULL,0x645c9cc6f07fdc42ULL,0xbf38a078243342e0ULL,0x5f6b343c9d2e7d04ULL,
-	0xf2c28aeb600b0ec6ULL,0x6c0ed85f7254bcacULL,0x71592281a4db4fe5ULL,0x1967fa69ce0fed9fULL,
-	0xfd5293f8b96545dbULL,0xc879e9d7f2a7600bULL,0x860248920193194eULL,0xa4f9533b2d9cc0b3ULL,
-	0x9053836c15957613ULL,0xdb6dcf8afc357bf1ULL,0x18beea7a7a370f57ULL,0x037117ca50b99066ULL,
-	0x6ab30a9774424a35ULL,0xf4e92f02e325249bULL,0x7739db07061ccae1ULL,0xd8f3b49ceca42a05ULL,
-	0xbd56be3f51382f73ULL,0x45faed5843b0bb28ULL,0x1c813d5c11bf1f83ULL,0x8af0e4b6d75fa169ULL,
-	0x33ee18a487ad9999ULL,0x3c26e8eab1c94410ULL,0xb510102bc0a822f9ULL,0x141eef310ce6123bULL,
-	0xfc65b90059ddb154ULL,0xe0158640c5e0e607ULL,0x884e079826c3a3cfULL,0x930d0d9523c535fdULL,
-	0x35638d754e9a2b00ULL,0x4085fccf40469dd5ULL,0xc4b17ad28be23a4cULL,0xcab2f0fc6a3e6a2eULL,
-	0x2860971a6b943fcdULL,0x3dde6ee212e30446ULL,0x6222f32ae01765aeULL,0x5d550bb5478308feULL,
-	0xa9efa98da0eda22aULL,0xc351a71686c40da7ULL,0x1105586d9c867c84ULL,0xdcffee85fda22853ULL,
-	0xccfbd0262c5eef76ULL,0xbaf294cb8990d201ULL,0xe69464f52afad975ULL,0x94b013afdf133e14ULL,
-	0x06a7d1a32823c958ULL,0x6f95fe5130f61119ULL,0xd92ab34e462c06c0ULL,0xed7bde33887c71d2ULL,
-	0x79746d6e6518393eULL,0x5ba419385d713329ULL,0x7c1ba6b948a97564ULL,0x31987c197bfdac67ULL,
-	0xde6c23c44b053d02ULL,0x581c49fed002d64dULL,0xdd474d6338261571ULL,0xaa4546c3e473d062ULL,
-	0x928fce349455f860ULL,0x48161bbacaab94d9ULL,0x63912430770e6f68ULL,0x6ec8a5e602c6641cULL,
-	0x87282515337ddd2bULL,0x2cda6b42034b701bULL,0xb03d37c181cb096dULL,0xe108438266c71c6fULL,
-	0x2b3180c7eb51b255ULL,0xdf92b82f96c08bbcULL,0x5c68c8c0a632f3baULL,0x5504cc861c3d0556ULL,
-	0xabbfa4e55fb26b8fULL,0x41848b0ab3baceb4ULL,0xb334a273aa445d32ULL,0xbca696f0a85ad881ULL,
-	0x24f6ec65b528d56cULL,0x0ce1512e90f4524aULL,0x4e9dd79d5506d35aULL,0x258905fac6ce9779ULL,
-	0x2019295b3e109b33ULL,0xf8a9478b73a054ccULL,0x2924f2f934417eb0ULL,0x3993357d536d1bc4ULL,
-	0x38a81ac21db6ff8bULL,0x47c4fbf17d6016bfULL,0x1e0faadd7667e3f5ULL,0x7abcff62938beb96ULL,
-	0xa78dad948fc179c9ULL,0x8f1f98b72911e50dULL,0x61e48eae27121a91ULL,0x4d62f7ad31859808ULL,
-	0xeceba345ef5ceaebULL,0xf5ceb25ebc9684ceULL,0xf633e20cb7f76221ULL,0xa32cdf06ab8293e4ULL,
-	0x985a202ca5ee2ca4ULL,0xcf0b8447cc8a8fb1ULL,0x9f765244979859a3ULL,0xa8d516b1a1240017ULL,
-	0x0bd7ba3ebb5dc726ULL,0xe54bca55b86adb39ULL,0x1d7a3afd6c478063ULL,0x519ec608e7669eddULL,
-	0x0e5715a2d149aa23ULL,0x177d4571848ff194ULL,0xeeb55f3241014c22ULL,0x0f5e5ca13a6e2ec2ULL,
-	0x8029927b75f5c361ULL,0xad139fabc3d6e436ULL,0x0d5df1a94ccf402fULL,0x3e8bd948bea5dfc8ULL,
-	0xa5a0d357bd3ff77eULL,0xa2d12e251f74f645ULL,0x66fd9e525e81a082ULL,0x2e0c90ce7f687a49ULL,
-	0xc2e8bcbeba973bc5ULL,0x000001bce509745fULL,0x423777bbe6dab3d6ULL,0xd1661c7eaef06eb5ULL,
-	0xa1781f354daacfd8ULL,0x2d11284a2b16affcULL,0xf1fc4f67fa891d1fULL,0x73ecc25dcb920adaULL,
-	0xae610c22c2a12651ULL,0x96e0a810d356b78aULL,0x5a9a381f2fe7870fULL,0xd5ad62ede94e5530ULL,
-	0xd225e5e8368d1427ULL,0x65977b70c7af4631ULL,0x99f889b2de39d74fULL,0x233f30bf54e1d143ULL,
-	0x9a9675d3d9a63c97ULL,0x5470554ff334f9a8ULL,0x166acb744a4f5688ULL,0x70c74caab2e4aeadULL,
-	0xf0d091646f294d12ULL,0x57b82a89684031d1ULL,0xefd95a5a61be0b6bULL,0x2fbd12e969f2f29aULL,
-	0x9bd37013feff9fe8ULL,0x3f9b0404d6085a06ULL,0x4940c1f3166cfe15ULL,0x09542c4dcdf3defbULL,
-	0xb4c5218385cd5ce3ULL,0xc935b7dc4462a641ULL,0x3417f8a68ed3b63fULL,0xb80959295b215b40ULL,
-	0xf99cdaef3b8c8572ULL,0x018c0614f8fcb95dULL,0x1b14accd1a3acdf3ULL,0x84d471f200bb732dULL,
-	0xc1a3110e95e8da16ULL,0x430a7220bf1a82b8ULL,0xb77e090d39df210eULL,0x5ef4bd9f3cd05e9dULL,
-	0x9d4ff6da7e57a444ULL,0xda1d60e183d4a5f8ULL,0xb287c38417998e47ULL,0xfe3edc121bb31886ULL,
-	0xc7fe3ccc980ccbefULL,0xe46fb590189bfd03ULL,0x3732fd469a4c57dcULL,0x7ef700a07cf1ad65ULL,
-	0x59c64468a31d8859ULL,0x762fb0b4d45b61f6ULL,0x155baed099047718ULL,0x68755e4c3d50baa6ULL,
-	0xe9214e7f22d8b4dfULL,0x2addbf532eac95f4ULL,0x32ae3909b4bd0109ULL,0x834df537b08e3450ULL,
-	0xfa209da84220728dULL,0x9e691d9b9efe23f7ULL,0x0446d288c4ae8d7fULL,0x7b4cc524e169785bULL,
-	0x21d87f0135ca1385ULL,0xcebb400f137b8aa5ULL,0x272e2b66580796beULL,0x3612264125c2b0deULL,
-	0x057702bdad1efbb2ULL,0xd4babb8eacf84be9ULL,0x91583139641bc67bULL,0x8bdc2de08036e024ULL,
-	0x603c8156f49f68edULL,0xf7d236f7dbef5111ULL,0x9727c4598ad21e80ULL,0xa08a0896670a5fd7ULL,
-	0xcb4a8f4309eba9cbULL,0x81af564b0f7036a1ULL,0xc0b99aa778199abdULL,0x959f1ec83fc8e952ULL,
-	0x8c505077794a81b9ULL,0x3acaaf8f056338f0ULL,0x07b43f50627a6778ULL,0x4a44ab49f5eccc77ULL,
-	0x3bc3d6e4b679ee98ULL,0x9cc0d4d1cf14108cULL,0x4406c00b206bc8a0ULL,0x82a18854c8d72d89ULL,
-	0x67e366b35c3c432cULL,0xb923dd61102b37f2ULL,0x56ab2779d884271dULL,0xbe83e1b0ff1525afULL,
-	0xfb7c65d4217e49a9ULL,0x6bdbe0e76d48e7d4ULL,0x08df828745d9179eULL,0x22ea6a9add53bd34ULL,
-	0xe36e141c5622200aULL,0x7f805d1b8cb750eeULL,0xafe5c7a59f58e837ULL,0xe27f996a4fb1c23cULL,
-	0xd3867dfb0775f0d0ULL,0xd0e673de6e88891aULL,0x123aeb9eafb86c25ULL,0x30f1d5d5c145b895ULL,
-	0xbb434a2dee7269e7ULL,0x78cb67ecf931fa38ULL,0xf33b0372323bbf9cULL,0x52d66336fb279c74ULL,
-	0x505f33ac0afb4eaaULL,0xe8a5cd99a2cce187ULL,0x534974801e2d30bbULL,0x8d2d5711d5876d90ULL,
-	0x1f1a412891bc038eULL,0xd6e2e71d82e56648ULL,0x74036c3a497732b7ULL,0x89b67ed96361f5abULL,
-	0xffed95d8f1ea02a2ULL,0xe72b3bd61464d43dULL,0xa6300f170bdc4820ULL,0xebc18760ed78a77aULL,
-};
-
-static const uint64_t t2[256] =
-{
-	0xe6a6be5a05a12138ULL,0xb5a122a5b4f87c98ULL,0x563c6089140b6990ULL,0x4c46cb2e391f5dd5ULL,
-	0xd932addbc9b79434ULL,0x08ea70e42015aff5ULL,0xd765a6673e478cf1ULL,0xc4fb757eab278d99ULL,
-	0xdf11c6862d6e0692ULL,0xddeb84f10d7f3b16ULL,0x6f2ef604a665ea04ULL,0x4a8e0f0ff0e0dfb3ULL,
-	0xa5edeef83dbcba51ULL,0xfc4f0a2a0ea4371eULL,0xe83e1da85cb38429ULL,0xdc8ff882ba1b1ce2ULL,
-	0xcd45505e8353e80dULL,0x18d19a00d4db0717ULL,0x34a0cfeda5f38101ULL,0x0be77e518887caf2ULL,
-	0x1e341438b3c45136ULL,0xe05797f49089ccf9ULL,0xffd23f9df2591d14ULL,0x543dda228595c5cdULL,
-	0x661f81fd99052a33ULL,0x8736e641db0f7b76ULL,0x15227725418e5307ULL,0xe25f7f46162eb2faULL,
-	0x48a8b2126c13d9feULL,0xafdc541792e76eeaULL,0x03d912bfc6d1898fULL,0x31b1aafa1b83f51bULL,
-	0xf1ac2796e42ab7d9ULL,0x40a3a7d7fcd2ebacULL,0x1056136d0afbbcc5ULL,0x7889e1dd9a6d0c85ULL,
-	0xd33525782a7974aaULL,0xa7e25d09078ac09bULL,0xbd4138b3eac6edd0ULL,0x920abfbe71eb9e70ULL,
-	0xa2a5d0f54fc2625cULL,0xc054e36b0b1290a3ULL,0xf6dd59ff62fe932bULL,0x3537354511a8ac7dULL,
-	0xca845e9172fadcd4ULL,0x84f82b60329d20dcULL,0x79c62ce1cd672f18ULL,0x8b09a2add124642cULL,
-	0xd0c1e96a19d9e726ULL,0x5a786a9b4ba9500cULL,0x0e020336634c43f3ULL,0xc17b474aeb66d822ULL,
-	0x6a731ae3ec9baac2ULL,0x8226667ae0840258ULL,0x67d4567691caeca5ULL,0x1d94155c4875adb5ULL,
-	0x6d00fd985b813fdfULL,0x51286efcb774cd06ULL,0x5e8834471fa744afULL,0xf72ca0aee761ae2eULL,
-	0xbe40e4cdaee8e09aULL,0xe9970bbb5118f665ULL,0x726e4beb33df1964ULL,0x703b000729199762ULL,
-	0x4631d816f5ef30a7ULL,0xb880b5b51504a6beULL,0x641793c37ed84b6cULL,0x7b21ed77f6e97d96ULL,
-	0x776306312ef96b73ULL,0xae528948e86ff3f4ULL,0x53dbd7f286a3f8f8ULL,0x16cadce74cfc1063ULL,
-	0x005c19bdfa52c6ddULL,0x68868f5d64d46ad3ULL,0x3a9d512ccf1e186aULL,0x367e62c2385660aeULL,
-	0xe359e7ea77dcb1d7ULL,0x526c0773749abe6eULL,0x735ae5f9d09f734bULL,0x493fc7cc8a558ba8ULL,
-	0xb0b9c1533041ab45ULL,0x321958ba470a59bdULL,0x852db00b5f46c393ULL,0x91209b2bd336b0e5ULL,
-	0x6e604f7d659ef19fULL,0xb99a8ae2782ccb24ULL,0xccf52ab6c814c4c7ULL,0x4727d9afbe11727bULL,
-	0x7e950d0c0121b34dULL,0x756f435670ad471fULL,0xf5add442615a6849ULL,0x4e87e09980b9957aULL,
-	0x2acfa1df50aee355ULL,0xd898263afd2fd556ULL,0xc8f4924dd80c8fd6ULL,0xcf99ca3d754a173aULL,
-	0xfe477bacaf91bf3cULL,0xed5371f6d690c12dULL,0x831a5c285e687094ULL,0xc5d3c90a3708a0a4ULL,
-	0x0f7f903717d06580ULL,0x19f9bb13b8fdf27fULL,0xb1bd6f1b4d502843ULL,0x1c761ba38fff4012ULL,
-	0x0d1530c4e2e21f3bULL,0x8943ce69a7372c8aULL,0xe5184e11feb5ce66ULL,0x618bdb80bd736621ULL,
-	0x7d29bad68b574d0bULL,0x81bb613e25e6fe5bULL,0x071c9c10bc07913fULL,0xc7beeb7909ac2d97ULL,
-	0xc3e58d353bc5d757ULL,0xeb017892f38f61e8ULL,0xd4effb9c9b1cc21aULL,0x99727d26f494f7abULL,
-	0xa3e063a2956b3e03ULL,0x9d4a8b9a4aa09c30ULL,0x3f6ab7d500090fb4ULL,0x9cc0f2a057268ac0ULL,
-	0x3dee9d2dedbf42d1ULL,0x330f49c87960a972ULL,0xc6b2720287421b41ULL,0x0ac59ec07c00369cULL,
-	0xef4eac49cb353425ULL,0xf450244eef0129d8ULL,0x8acc46e5caf4deb6ULL,0x2ffeab63989263f7ULL,
-	0x8f7cb9fe5d7a4578ULL,0x5bd8f7644e634635ULL,0x427a7315bf2dc900ULL,0x17d0c4aa2125261cULL,
-	0x3992486c93518e50ULL,0xb4cbfee0a2d7d4c3ULL,0x7c75d6202c5ddd8dULL,0xdbc295d8e35b6c61ULL,
-	0x60b369d302032b19ULL,0xce42685fdce44132ULL,0x06f3ddb9ddf65610ULL,0x8ea4d21db5e148f0ULL,
-	0x20b0fce62fcd496fULL,0x2c1b912358b0ee31ULL,0xb28317b818f5a308ULL,0xa89c1e189ca6d2cfULL,
-	0x0c6b18576aaadbc8ULL,0xb65deaa91299fae3ULL,0xfb2b794b7f1027e7ULL,0x04e4317f443b5bebULL,
-	0x4b852d325939d0a6ULL,0xd5ae6beefb207ffcULL,0x309682b281c7d374ULL,0xbae309a194c3b475ULL,
-	0x8cc3f97b13b49f05ULL,0x98a9422ff8293967ULL,0x244b16b01076ff7cULL,0xf8bf571c663d67eeULL,
-	0x1f0d6758eee30da1ULL,0xc9b611d97adeb9b7ULL,0xb7afd5887b6c57a2ULL,0x6290ae846b984fe1ULL,
-	0x94df4cdeacc1a5fdULL,0x058a5bd1c5483affULL,0x63166cc142ba3c37ULL,0x8db8526eb2f76f40ULL,
-	0xe10880036f0d6d4eULL,0x9e0523c9971d311dULL,0x45ec2824cc7cd691ULL,0x575b8359e62382c9ULL,
-	0xfa9e400dc4889995ULL,0xd1823ecb45721568ULL,0xdafd983b8206082fULL,0xaa7d29082386a8cbULL,
-	0x269fcd4403b87588ULL,0x1b91f5f728bdd1e0ULL,0xe4669f39040201f6ULL,0x7a1d7c218cf04adeULL,
-	0x65623c29d79ce5ceULL,0x2368449096c00bb1ULL,0xab9bf1879da503baULL,0xbc23ecb1a458058eULL,
-	0x9a58df01bb401eccULL,0xa070e868a85f143dULL,0x4ff188307df2239eULL,0x14d565b41a641183ULL,
-	0xee13337452701602ULL,0x950e3dcf3f285e09ULL,0x59930254b9c80953ULL,0x3bf299408930da6dULL,
-	0xa955943f53691387ULL,0xa15edecaa9cb8784ULL,0x29142127352be9a0ULL,0x76f0371fff4e7afbULL,
-	0x0239f450274f2228ULL,0xbb073af01d5e868bULL,0xbfc80571c10e96c1ULL,0xd267088568222e23ULL,
-	0x9671a3d48e80b5b0ULL,0x55b5d38ae193bb81ULL,0x693ae2d0a18b04b8ULL,0x5c48b4ecadd5335fULL,
-	0xfd743b194916a1caULL,0x2577018134be98c4ULL,0xe77987e83c54a4adULL,0x28e11014da33e1b9ULL,
-	0x270cc59e226aa213ULL,0x71495f756d1a5f60ULL,0x9be853fb60afef77ULL,0xadc786a7f7443dbfULL,
-	0x0904456173b29a82ULL,0x58bc7a66c232bd5eULL,0xf306558c673ac8b2ULL,0x41f639c6b6c9772aULL,
-	0x216defe99fda35daULL,0x11640cc71c7be615ULL,0x93c43694565c5527ULL,0xea038e6246777839ULL,
-	0xf9abf3ce5a3e2469ULL,0x741e768d0fd312d2ULL,0x0144b883ced652c6ULL,0xc20b5a5ba33f8552ULL,
-	0x1ae69633c3435a9dULL,0x97a28ca4088cfdecULL,0x8824a43c1e96f420ULL,0x37612fa66eeea746ULL,
-	0x6b4cb165f9cf0e5aULL,0x43aa1c06a0abfb4aULL,0x7f4dc26ff162796bULL,0x6cbacc8e54ed9b0fULL,
-	0xa6b7ffefd2bb253eULL,0x2e25bc95b0a29d4fULL,0x86d6a58bdef1388cULL,0xded74ac576b6f054ULL,
-	0x8030bdbc2b45805dULL,0x3c81af70e94d9289ULL,0x3eff6dda9e3100dbULL,0xb38dc39fdfcc8847ULL,
-	0x123885528d17b87eULL,0xf2da0ed240b1b642ULL,0x44cefadcd54bf9a9ULL,0x1312200e433c7ee6ULL,
-	0x9ffcc84f3a78c748ULL,0xf0cd1f72248576bbULL,0xec6974053638cfe4ULL,0x2ba7b67c0cec4e4cULL,
-	0xac2f4df3e5ce32edULL,0xcb33d14326ea4c11ULL,0xa4e9044cc77e58bcULL,0x5f513293d934fcefULL,
-	0x5dc9645506e55444ULL,0x50de418f317de40aULL,0x388cb31a69dde259ULL,0x2db4a83455820a86ULL,
-	0x9010a91e84711ae9ULL,0x4df7f0b7b1498371ULL,0xd62a2eabc0977179ULL,0x22fac097aa8d5c0eULL,
-}; 
-
-static const uint64_t t3[256]= {
-	0xf49fcc2ff1daf39bULL,0x487fd5c66ff29281ULL,0xe8a30667fcdca83fULL,0x2c9b4be3d2fcce63ULL,
-	0xda3ff74b93fbbbc2ULL,0x2fa165d2fe70ba66ULL,0xa103e279970e93d4ULL,0xbecdec77b0e45e71ULL,
-	0xcfb41e723985e497ULL,0xb70aaa025ef75017ULL,0xd42309f03840b8e0ULL,0x8efc1ad035898579ULL,
-	0x96c6920be2b2abc5ULL,0x66af4163375a9172ULL,0x2174abdcca7127fbULL,0xb33ccea64a72ff41ULL,
-	0xf04a4933083066a5ULL,0x8d970acdd7289af5ULL,0x8f96e8e031c8c25eULL,0xf3fec02276875d47ULL,
-	0xec7bf310056190ddULL,0xf5adb0aebb0f1491ULL,0x9b50f8850fd58892ULL,0x4975488358b74de8ULL,
-	0xa3354ff691531c61ULL,0x0702bbe481d2c6eeULL,0x89fb24057deded98ULL,0xac3075138596e902ULL,
-	0x1d2d3580172772edULL,0xeb738fc28e6bc30dULL,0x5854ef8f63044326ULL,0x9e5c52325add3bbeULL,
-	0x90aa53cf325c4623ULL,0xc1d24d51349dd067ULL,0x2051cfeea69ea624ULL,0x13220f0a862e7e4fULL,
-	0xce39399404e04864ULL,0xd9c42ca47086fcb7ULL,0x685ad2238a03e7ccULL,0x066484b2ab2ff1dbULL,
-	0xfe9d5d70efbf79ecULL,0x5b13b9dd9c481854ULL,0x15f0d475ed1509adULL,0x0bebcd060ec79851ULL,
-	0xd58c6791183ab7f8ULL,0xd1187c5052f3eee4ULL,0xc95d1192e54e82ffULL,0x86eea14cb9ac6ca2ULL,
-	0x3485beb153677d5dULL,0xdd191d781f8c492aULL,0xf60866baa784ebf9ULL,0x518f643ba2d08c74ULL,
-	0x8852e956e1087c22ULL,0xa768cb8dc410ae8dULL,0x38047726bfec8e1aULL,0xa67738b4cd3b45aaULL,
-	0xad16691cec0dde19ULL,0xc6d4319380462e07ULL,0xc5a5876d0ba61938ULL,0x16b9fa1fa58fd840ULL,
-	0x188ab1173ca74f18ULL,0xabda2f98c99c021fULL,0x3e0580ab134ae816ULL,0x5f3b05b773645abbULL,
-	0x2501a2be5575f2f6ULL,0x1b2f74004e7e8ba9ULL,0x1cd7580371e8d953ULL,0x7f6ed89562764e30ULL,
-	0xb15926ff596f003dULL,0x9f65293da8c5d6b9ULL,0x6ecef04dd690f84cULL,0x4782275fff33af88ULL,
-	0xe41433083f820801ULL,0xfd0dfe409a1af9b5ULL,0x4325a3342cdb396bULL,0x8ae77e62b301b252ULL,
-	0xc36f9e9f6655615aULL,0x85455a2d92d32c09ULL,0xf2c7dea949477485ULL,0x63cfb4c133a39ebaULL,
-	0x83b040cc6ebc5462ULL,0x3b9454c8fdb326b0ULL,0x56f56a9e87ffd78cULL,0x2dc2940d99f42bc6ULL,
-	0x98f7df096b096e2dULL,0x19a6e01e3ad852bfULL,0x42a99ccbdbd4b40bULL,0xa59998af45e9c559ULL,
-	0x366295e807d93186ULL,0x6b48181bfaa1f773ULL,0x1fec57e2157a0a1dULL,0x4667446af6201ad5ULL,
-	0xe615ebcacfb0f075ULL,0xb8f31f4f68290778ULL,0x22713ed6ce22d11eULL,0x3057c1a72ec3c93bULL,
-	0xcb46acc37c3f1f2fULL,0xdbb893fd02aaf50eULL,0x331fd92e600b9fcfULL,0xa498f96148ea3ad6ULL,
-	0xa8d8426e8b6a83eaULL,0xa089b274b7735cdcULL,0x87f6b3731e524a11ULL,0x118808e5cbc96749ULL,
-	0x9906e4c7b19bd394ULL,0xafed7f7e9b24a20cULL,0x6509eadeeb3644a7ULL,0x6c1ef1d3e8ef0edeULL,
-	0xb9c97d43e9798fb4ULL,0xa2f2d784740c28a3ULL,0x7b8496476197566fULL,0x7a5be3e6b65f069dULL,
-	0xf96330ed78be6f10ULL,0xeee60de77a076a15ULL,0x2b4bee4aa08b9bd0ULL,0x6a56a63ec7b8894eULL,
-	0x02121359ba34fef4ULL,0x4cbf99f8283703fcULL,0x398071350caf30c8ULL,0xd0a77a89f017687aULL,
-	0xf1c1a9eb9e423569ULL,0x8c7976282dee8199ULL,0x5d1737a5dd1f7abdULL,0x4f53433c09a9fa80ULL,
-	0xfa8b0c53df7ca1d9ULL,0x3fd9dcbc886ccb77ULL,0xc040917ca91b4720ULL,0x7dd00142f9d1dcdfULL,
-	0x8476fc1d4f387b58ULL,0x23f8e7c5f3316503ULL,0x032a2244e7e37339ULL,0x5c87a5d750f5a74bULL,
-	0x082b4cc43698992eULL,0xdf917becb858f63cULL,0x3270b8fc5bf86ddaULL,0x10ae72bb29b5dd76ULL,
-	0x576ac94e7700362bULL,0x1ad112dac61efb8fULL,0x691bc30ec5faa427ULL,0xff246311cc327143ULL,
-	0x3142368e30e53206ULL,0x71380e31e02ca396ULL,0x958d5c960aad76f1ULL,0xf8d6f430c16da536ULL,
-	0xc8ffd13f1be7e1d2ULL,0x7578ae66004ddbe1ULL,0x05833f01067be646ULL,0xbb34b5ad3bfe586dULL,
-	0x095f34c9a12b97f0ULL,0x247ab64525d60ca8ULL,0xdcdbc6f3017477d1ULL,0x4a2e14d4decad24dULL,
-	0xbdb5e6d9be0a1eebULL,0x2a7e70f7794301abULL,0xdef42d8a270540fdULL,0x01078ec0a34c22c1ULL,
-	0xe5de511af4c16387ULL,0x7ebb3a52bd9a330aULL,0x77697857aa7d6435ULL,0x004e831603ae4c32ULL,
-	0xe7a21020ad78e312ULL,0x9d41a70c6ab420f2ULL,0x28e06c18ea1141e6ULL,0xd2b28cbd984f6b28ULL,
-	0x26b75f6c446e9d83ULL,0xba47568c4d418d7fULL,0xd80badbfe6183d8eULL,0x0e206d7f5f166044ULL,
-	0xe258a43911cbca3eULL,0x723a1746b21dc0bcULL,0xc7caa854f5d7cdd3ULL,0x7cac32883d261d9cULL,
-	0x7690c26423ba942cULL,0x17e55524478042b8ULL,0xe0be477656a2389fULL,0x4d289b5e67ab2da0ULL,
-	0x44862b9c8fbbfd31ULL,0xb47cc8049d141365ULL,0x822c1b362b91c793ULL,0x4eb14655fb13dfd8ULL,
-	0x1ecbba0714e2a97bULL,0x6143459d5cde5f14ULL,0x53a8fbf1d5f0ac89ULL,0x97ea04d81c5e5b00ULL,
-	0x622181a8d4fdb3f3ULL,0xe9bcd341572a1208ULL,0x1411258643cce58aULL,0x9144c5fea4c6e0a4ULL,
-	0x0d33d06565cf620fULL,0x54a48d489f219ca1ULL,0xc43e5eac6d63c821ULL,0xa9728b3a72770dafULL,
-	0xd7934e7b20df87efULL,0xe35503b61a3e86e5ULL,0xcae321fbc819d504ULL,0x129a50b3ac60bfa6ULL,
-	0xcd5e68ea7e9fb6c3ULL,0xb01c90199483b1c7ULL,0x3de93cd5c295376cULL,0xaed52edf2ab9ad13ULL,
-	0x2e60f512c0a07884ULL,0xbc3d86a3e36210c9ULL,0x35269d9b163951ceULL,0x0c7d6e2ad0cdb5faULL,
-	0x59e86297d87f5733ULL,0x298ef221898db0e7ULL,0x55000029d1a5aa7eULL,0x8bc08ae1b5061b45ULL,
-	0xc2c31c2b6c92703aULL,0x94cc596baf25ef42ULL,0x0a1d73db22540456ULL,0x04b6a0f9d9c4179aULL,
-	0xeffdafa2ae3d3c60ULL,0xf7c8075bb49496c4ULL,0x9cc5c7141d1cd4e3ULL,0x78bd1638218e5534ULL,
-	0xb2f11568f850246aULL,0xedfabcfa9502bc29ULL,0x796ce5f2da23051bULL,0xaae128b0dc93537cULL,
-	0x3a493da0ee4b29aeULL,0xb5df6b2c416895d7ULL,0xfcabbd25122d7f37ULL,0x70810b58105dc4b1ULL,
-	0xe10fdd37f7882a90ULL,0x524dcab5518a3f5cULL,0x3c9e85878451255bULL,0x4029828119bd34e2ULL,
-	0x74a05b6f5d3ceccbULL,0xb610021542e13ecaULL,0x0ff979d12f59e2acULL,0x6037da27e4f9cc50ULL,
-	0x5e92975a0df1847dULL,0xd66de190d3e623feULL,0x5032d6b87b568048ULL,0x9a36b7ce8235216eULL,
-	0x80272a7a24f64b4aULL,0x93efed8b8c6916f7ULL,0x37ddbff44cce1555ULL,0x4b95db5d4b99bd25ULL,
-	0x92d3fda169812fc0ULL,0xfb1a4a9a90660bb6ULL,0x730c196946a4b9b2ULL,0x81e289aa7f49da68ULL,
-	0x64669a0f83b1a05fULL,0x27b3ff7d9644f48bULL,0xcc6b615c8db675b3ULL,0x674f20b9bcebbe95ULL,
-	0x6f31238275655982ULL,0x5ae488713e45cf05ULL,0xbf619f9954c21157ULL,0xeabac46040a8eae9ULL,
-	0x454c6fe9f2c0c1cdULL,0x419cf6496412691cULL,0xd3dc3bef265b0f70ULL,0x6d0e60f5c3578a9eULL,
-};
-
-static const uint64_t t4[256]=
-{
-	0x5b0e608526323c55ULL,0x1a46c1a9fa1b59f5ULL, 0xa9e245a17c4c8ffaULL,0x65ca5159db2955d7ULL,
-	0x05db0a76ce35afc2ULL,0x81eac77ea9113d45ULL, 0x528ef88ab6ac0a0dULL,0xa09ea253597be3ffULL,
-	0x430ddfb3ac48cd56ULL,0xc4b3a67af45ce46fULL, 0x4ececfd8fbe2d05eULL,0x3ef56f10b39935f0ULL,
-	0x0b22d6829cd619c6ULL,0x17fd460a74df2069ULL, 0x6cf8cc8e8510ed40ULL,0xd6c824bf3a6ecaa7ULL,
-	0x61243d581a817049ULL,0x048bacb6bbc163a2ULL, 0xd9a38ac27d44cc32ULL,0x7fddff5baaf410abULL,
-	0xad6d495aa804824bULL,0xe1a6a74f2d8c9f94ULL, 0xd4f7851235dee8e3ULL,0xfd4b7f886540d893ULL,
-	0x247c20042aa4bfdaULL,0x096ea1c517d1327cULL, 0xd56966b4361a6685ULL,0x277da5c31221057dULL,
-	0x94d59893a43acff7ULL,0x64f0c51ccdc02281ULL, 0x3d33bcc4ff6189dbULL,0xe005cb184ce66af1ULL,
-	0xff5ccd1d1db99beaULL,0xb0b854a7fe42980fULL, 0x7bd46a6a718d4b9fULL,0xd10fa8cc22a5fd8cULL,
-	0xd31484952be4bd31ULL,0xc7fa975fcb243847ULL, 0x4886ed1e5846c407ULL,0x28cddb791eb70b04ULL,
-	0xc2b00be2f573417fULL,0x5c9590452180f877ULL, 0x7a6bddfff370eb00ULL,0xce509e38d6d9d6a4ULL,
-	0xebeb0f00647fa702ULL,0x1dcc06cf76606f06ULL, 0xe4d9f28ba286ff0aULL,0xd85a305dc918c262ULL,
-	0x475b1d8732225f54ULL,0x2d4fb51668ccb5feULL, 0xa679b9d9d72bba20ULL,0x53841c0d912d43a5ULL,
-	0x3b7eaa48bf12a4e8ULL,0x781e0e47f22f1ddfULL, 0xeff20ce60ab50973ULL,0x20d261d19dffb742ULL,
-	0x16a12b03062a2e39ULL,0x1960eb2239650495ULL, 0x251c16fed50eb8b8ULL,0x9ac0c330f826016eULL,
-	0xed152665953e7671ULL,0x02d63194a6369570ULL, 0x5074f08394b1c987ULL,0x70ba598c90b25ce1ULL,
-	0x794a15810b9742f6ULL,0x0d5925e9fcaf8c6cULL, 0x3067716cd868744eULL,0x910ab077e8d7731bULL,
-	0x6a61bbdb5ac42f61ULL,0x93513efbf0851567ULL, 0xf494724b9e83e9d5ULL,0xe887e1985c09648dULL,
-	0x34b1d3c675370cfdULL,0xdc35e433bc0d255dULL, 0xd0aab84234131be0ULL,0x08042a50b48b7eafULL,
-	0x9997c4ee44a3ab35ULL,0x829a7b49201799d0ULL, 0x263b8307b7c54441ULL,0x752f95f4fd6a6ca6ULL,
-	0x927217402c08c6e5ULL,0x2a8ab754a795d9eeULL, 0xa442f7552f72943dULL,0x2c31334e19781208ULL,
-	0x4fa98d7ceaee6291ULL,0x55c3862f665db309ULL, 0xbd0610175d53b1f3ULL,0x46fe6cb840413f27ULL,
-	0x3fe03792df0cfa59ULL,0xcfe700372eb85e8fULL, 0xa7be29e7adbce118ULL,0xe544ee5cde8431ddULL,
-	0x8a781b1b41f1873eULL,0xa5c94c78a0d2f0e7ULL, 0x39412e2877b60728ULL,0xa1265ef3afc9a62cULL,
-	0xbcc2770c6a2506c5ULL,0x3ab66dd5dce1ce12ULL, 0xe65499d04a675b37ULL,0x7d8f523481bfd216ULL,
-	0x0f6f64fcec15f389ULL,0x74efbe618b5b13c8ULL, 0xacdc82b714273e1dULL,0xdd40bfe003199d17ULL,
-	0x37e99257e7e061f8ULL,0xfa52626904775aaaULL, 0x8bbbf63a463d56f9ULL,0xf0013f1543a26e64ULL,
-	0xa8307e9f879ec898ULL,0xcc4c27a4150177ccULL, 0x1b432f2cca1d3348ULL,0xde1d1f8f9f6fa013ULL,
-	0x606602a047a7ddd6ULL,0xd237ab64cc1cb2c7ULL, 0x9b938e7225fcd1d3ULL,0xec4e03708e0ff476ULL,
-	0xfeb2fbda3d03c12dULL,0xae0bced2ee43889aULL, 0x22cb8923ebfb4f43ULL,0x69360d013cf7396dULL,
-	0x855e3602d2d4e022ULL,0x073805bad01f784cULL, 0x33e17a133852f546ULL,0xdf4874058ac7b638ULL,
-	0xba92b29c678aa14aULL,0x0ce89fc76cfaadcdULL, 0x5f9d4e0908339e34ULL,0xf1afe9291f5923b9ULL,
-	0x6e3480f60f4a265fULL,0xeebf3a2ab29b841cULL, 0xe21938a88f91b4adULL,0x57dfeff845c6d3c3ULL,
-	0x2f006b0bf62caaf2ULL,0x62f479ef6f75ee78ULL, 0x11a55ad41c8916a9ULL,0xf229d29084fed453ULL,
-	0x42f1c27b16b000e6ULL,0x2b1f76749823c074ULL, 0x4b76eca3c2745360ULL,0x8c98f463b91691bdULL,
-	0x14bcc93cf1ade66aULL,0x8885213e6d458397ULL, 0x8e177df0274d4711ULL,0xb49b73b5503f2951ULL,
-	0x10168168c3f96b6bULL,0x0e3d963b63cab0aeULL, 0x8dfc4b5655a1db14ULL,0xf789f1356e14de5cULL,
-	0x683e68af4e51dac1ULL,0xc9a84f9d8d4b0fd9ULL, 0x3691e03f52a0f9d1ULL,0x5ed86e46e1878e80ULL,
-	0x3c711a0e99d07150ULL,0x5a0865b20c4e9310ULL, 0x56fbfc1fe4f0682eULL,0xea8d5de3105edf9bULL,
-	0x71abfdb12379187aULL,0x2eb99de1bee77b9cULL, 0x21ecc0ea33cf4523ULL,0x59a4d7521805c7a1ULL,
-	0x3896f5eb56ae7c72ULL,0xaa638f3db18f75dcULL, 0x9f39358dabe9808eULL,0xb7defa91c00b72acULL,
-	0x6b5541fd62492d92ULL,0x6dc6dee8f92e4d5bULL, 0x353f57abc4beea7eULL,0x735769d6da5690ceULL,
-	0x0a234aa642391484ULL,0xf6f9508028f80d9dULL, 0xb8e319a27ab3f215ULL,0x31ad9c1151341a4dULL,
-	0x773c22a57bef5805ULL,0x45c7561a07968633ULL, 0xf913da9e249dbe36ULL,0xda652d9b78a64c68ULL,
-	0x4c27a97f3bc334efULL,0x76621220e66b17f4ULL, 0x967743899acd7d0bULL,0xf3ee5bcae0ed6782ULL,
-	0x409f753600c879fcULL,0x06d09a39b5926db6ULL, 0x6f83aeb0317ac588ULL,0x01e6ca4a86381f21ULL,
-	0x66ff3462d19f3025ULL,0x72207c24ddfd3bfbULL, 0x4af6b6d3e2ece2ebULL,0x9c994dbec7ea08deULL,
-	0x49ace597b09a8bc4ULL,0xb38c4766cf0797baULL, 0x131b9373c57c2a75ULL,0xb1822cce61931e58ULL,
-	0x9d7555b909ba1c0cULL,0x127fafdd937d11d2ULL, 0x29da3badc66d92e4ULL,0xa2c1d57154c2ecbcULL,
-	0x58c5134d82f6fe24ULL,0x1c3ae3515b62274fULL, 0xe907c82e01cb8126ULL,0xf8ed091913e37fcbULL,
-	0x3249d8f9c80046c9ULL,0x80cf9bede388fb63ULL, 0x1881539a116cf19eULL,0x5103f3f76bd52457ULL,
-	0x15b7e6f5ae47f7a8ULL,0xdbd7c6ded47e9ccfULL, 0x44e55c410228bb1aULL,0xb647d4255edb4e99ULL,
-	0x5d11882bb8aafc30ULL,0xf5098bbb29d3212aULL, 0x8fb5ea14e90296b3ULL,0x677b942157dd025aULL,
-	0xfb58e7c0a390acb5ULL,0x89d3674c83bd4a01ULL, 0x9e2da4df4bf3b93bULL,0xfcc41e328cab4829ULL,
-	0x03f38c96ba582c52ULL,0xcad1bdbd7fd85db2ULL, 0xbbb442c16082ae83ULL,0xb95fe86ba5da9ab0ULL,
-	0xb22e04673771a93fULL,0x845358c9493152d8ULL, 0xbe2a488697b4541eULL,0x95a2dc2dd38e6966ULL,
-	0xc02c11ac923c852bULL,0x2388b1990df2a87bULL, 0x7c8008fa1b4f37beULL,0x1f70d0c84d54e503ULL,
-	0x5490adec7ece57d4ULL,0x002b3c27d9063a3aULL, 0x7eaea3848030a2bfULL,0xc602326ded2003c0ULL,
-	0x83a7287d69a94086ULL,0xc57a5fcb30f57a8aULL, 0xb56844e479ebe779ULL,0xa373b40f05dcbce9ULL,
-	0xd71a786e88570ee2ULL,0x879cbacdbde8f6a0ULL, 0x976ad1bcc164a32fULL,0xab21e25e9666d78bULL,
-	0x901063aae5e5c33cULL,0x9818b34448698d90ULL, 0xe36487ae3e1e8abbULL,0xafbdf931893bdcb4ULL,
-	0x6345a0dc5fbbd519ULL,0x8628fe269b9465caULL, 0x1e5d01603f9c51ecULL,0x4de44006a15049b7ULL,
-	0xbf6c70e5f776cbb1ULL,0x411218f2ef552bedULL, 0xcb0c0708705a36a3ULL,0xe74d14754f986044ULL,
-	0xcd56d9430ea8280eULL,0xc12591d7535f5065ULL, 0xc83223f1720aef96ULL,0xc3a0396f7363a51fULL,
-}; 
-
-void tiger_init(struct tiger_ctx *ctx)
-{
-	memset(ctx, 0, sizeof(*ctx));
-
-	ctx->h[0] = 0x0123456789abcdefULL;
-	ctx->h[1] = 0xfedcba9876543210ULL;
-	ctx->h[2] = 0xf096a5b4c3b2e187ULL;
-}
-
-static inline void tiger_do_chunk(struct tiger_ctx *ctx, uint64_t *buf)
-{
-	uint64_t x0, x1, x2, x3, x4, x5, x6, x7;
-	uint64_t a,b,c;
-	a = ctx->h[0];
-	b = ctx->h[1];
-	c = ctx->h[2];
-
-	x0 = cpu_to_le64(buf[0]); x1 = cpu_to_le64(buf[1]); x2 = cpu_to_le64(buf[2]); x3 = cpu_to_le64(buf[3]);
-	x4 = cpu_to_le64(buf[4]); x5 = cpu_to_le64(buf[5]); x6 = cpu_to_le64(buf[6]); x7 = cpu_to_le64(buf[7]);
-
-#define BYTEOF(c, n) ((uint8_t) (c >> ((n * 8))))
-
-#define ROUND(a,b,c,x,mul)                                                          \
-	c ^= x;                                                                     \
-	a -= t1[BYTEOF(c,0)] ^ t2[BYTEOF(c,2)] ^ t3[BYTEOF(c,4)] ^ t4[BYTEOF(c,6)]; \
-	b += t4[BYTEOF(c,1)] ^ t3[BYTEOF(c,3)] ^ t2[BYTEOF(c,5)] ^ t1[BYTEOF(c,7)]; \
-	b *= mul;
-
-#define PASS(a,b,c,mul)	     \
-	ROUND(a,b,c,x0,mul); \
-	ROUND(b,c,a,x1,mul); \
-	ROUND(c,a,b,x2,mul); \
-	ROUND(a,b,c,x3,mul); \
-	ROUND(b,c,a,x4,mul); \
-	ROUND(c,a,b,x5,mul); \
-	ROUND(a,b,c,x6,mul); \
-	ROUND(b,c,a,x7,mul)
-
-#define SCHEDULE()                        \
-	x0 -= x7 ^ 0xa5a5a5a5a5a5a5a5ULL; \
-	x1 ^= x0;                         \
-	x2 += x1;                         \
-	x3 -= x2 ^ ((~x1)<<19);           \
-	x4 ^= x3;                         \
-	x5 += x4;                         \
-	x6 -= x5 ^ ((~x4)>>23);           \
-	x7 ^= x6;                         \
-	x0 += x7;                         \
-	x1 -= x0 ^ ((~x7)<<19);           \
-	x2 ^= x1;                         \
-	x3 += x2;                         \
-	x4 -= x3 ^ ((~x2)>>23);           \
-	x5 ^= x4;                         \
-	x6 += x5;                         \
-	x7 -= x6 ^ 0x0123456789abcdefULL
-
-	PASS(a,b,c,5);
-	SCHEDULE();
-	PASS(c,a,b,7);
-	SCHEDULE();
-	PASS(b,c,a,9);
-
-	ctx->h[0] ^= a;
-	ctx->h[1] = b - ctx->h[1];
-	ctx->h[2] += c;
-}
-
-void tiger_update(struct tiger_ctx *ctx, uint8_t *data, uint32_t len)
-{
-	uint32_t index, to_fill;
-
-	index = (uint32_t) (ctx->sz & 0x3f);
-	to_fill = 64 - index;
-
-	ctx->sz += len;
-
-	/* process partial buffer if there's enough data to make a block */
-	if (index && len >= to_fill) {
-		memcpy(ctx->buf + index, data, to_fill);
-		tiger_do_chunk(ctx, (uint64_t *) ctx->buf);
-		len -= to_fill;
-		data += to_fill;
-		index = 0;
-	}
-
-	/* process as much 64-block as possible */
-	for (; len >= 64; len -= 64, data += 64)
-		tiger_do_chunk(ctx, (uint64_t *) data);
-
-	/* append data into buf */
-	if (len)
-		memcpy(ctx->buf + index, data, len);
-}
-
-void tiger_finalize(struct tiger_ctx *ctx, uint8_t *out)
-{
-	static uint8_t padding[64] = { 0x01, };
-	uint64_t bits;
-	uint32_t index, padlen;
-	uint64_t *p = (uint64_t *) out;
-
-	/* add padding and update data with it */
-	bits = cpu_to_le64(ctx->sz << 3);
-
-	/* pad out to 56 */
-	index = (uint32_t) (ctx->sz & 0x3f);
-	padlen = (index < 56) ? (56 - index) : ((64 + 56) - index);
-	tiger_update(ctx, padding, padlen);
-
-	/* append length */
-	tiger_update(ctx, (uint8_t *) &bits, sizeof(bits));
-
-	/* output hash */
-	p[0] = cpu_to_le64(ctx->h[0]);
-	p[1] = cpu_to_le64(ctx->h[1]);
-	p[2] = cpu_to_le64(ctx->h[2]);
-}
diff --git a/cbits/tiger.h b/cbits/tiger.h
deleted file mode 100644
--- a/cbits/tiger.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2006-2009 Vincent Hanquez <vincent@snarc.org>
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-#ifndef CRYPTOHASH_TIGER_H
-#define CRYPTOHASH_TIGER_H
-
-#include <stdint.h>
-
-struct tiger_ctx
-{
-	uint64_t sz;
-	uint8_t  buf[64];
-	uint64_t h[3];
-};
-
-#define TIGER_DIGEST_SIZE	24
-#define TIGER_CTX_SIZE 		(sizeof(struct tiger_ctx))
-
-void tiger_init(struct tiger_ctx *ctx);
-void tiger_update(struct tiger_ctx *ctx, uint8_t *data, uint32_t len);
-void tiger_finalize(struct tiger_ctx *ctx, uint8_t *out);
-
-#endif
diff --git a/cbits/whirlpool.c b/cbits/whirlpool.c
deleted file mode 100644
--- a/cbits/whirlpool.c
+++ /dev/null
@@ -1,1027 +0,0 @@
-/**
- * The Whirlpool hashing function.
- *
- * <P>
- * <b>References</b>
- *
- * <P>
- * The Whirlpool algorithm was developed by
- * <a href="mailto:pbarreto@scopus.com.br">Paulo S. L. M. Barreto</a> and
- * <a href="mailto:vincent.rijmen@cryptomathic.com">Vincent Rijmen</a>.
- *
- * See
- *      P.S.L.M. Barreto, V. Rijmen,
- *      ``The Whirlpool hashing function,''
- *      NESSIE submission, 2000 (tweaked version, 2001),
- *      <https://www.cosic.esat.kuleuven.ac.be/nessie/workshop/submissions/whirlpool.zip>
- * 
- * @author  Paulo S.L.M. Barreto
- * @author  Vincent Rijmen.
- *
- * @version 3.0 (2003.03.12)
- *
- * =============================================================================
- *
- * Differences from version 2.1:
- *
- * - Suboptimal diffusion matrix replaced by cir(1, 1, 4, 1, 8, 5, 2, 9).
- *
- * =============================================================================
- *
- * Differences from version 2.0:
- *
- * - Generation of ISO/IEC 10118-3 test vectors.
- * - Bug fix: nonzero carry was ignored when tallying the data length
- *      (this bug apparently only manifested itself when feeding data
- *      in pieces rather than in a single chunk at once).
- * - Support for MS Visual C++ 64-bit integer arithmetic.
- *
- * Differences from version 1.0:
- *
- * - Original S-box replaced by the tweaked, hardware-efficient version.
- *
- * =============================================================================
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS
- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
- * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-/* Modified by Stijn van Drongelen for use in the cryptohash library.
-*/
-
-#include <stdlib.h>
-#include <string.h>
-
-#include "bitfn.h"
-#include "whirlpool.h"
-
-/* #define TRACE_INTERMEDIATE_VALUES */
-
-/*
- * The number of rounds of the internal dedicated block cipher.
- */
-#define R 10
-
-/*
- * Though Whirlpool is endianness-neutral, the encryption tables are listed
- * in BIG-ENDIAN format, which is adopted throughout this implementation
- * (but little-endian notation would be equally suitable if consistently
- * employed).
- */
-
-static const uint64_t C0[256] = {
-	0x18186018c07830d8ULL, 0x23238c2305af4626ULL, 0xc6c63fc67ef991b8ULL, 0xe8e887e8136fcdfbULL,
-	0x878726874ca113cbULL, 0xb8b8dab8a9626d11ULL, 0x0101040108050209ULL, 0x4f4f214f426e9e0dULL,
-	0x3636d836adee6c9bULL, 0xa6a6a2a6590451ffULL, 0xd2d26fd2debdb90cULL, 0xf5f5f3f5fb06f70eULL,
-	0x7979f979ef80f296ULL, 0x6f6fa16f5fcede30ULL, 0x91917e91fcef3f6dULL, 0x52525552aa07a4f8ULL,
-	0x60609d6027fdc047ULL, 0xbcbccabc89766535ULL, 0x9b9b569baccd2b37ULL, 0x8e8e028e048c018aULL,
-	0xa3a3b6a371155bd2ULL, 0x0c0c300c603c186cULL, 0x7b7bf17bff8af684ULL, 0x3535d435b5e16a80ULL,
-	0x1d1d741de8693af5ULL, 0xe0e0a7e05347ddb3ULL, 0xd7d77bd7f6acb321ULL, 0xc2c22fc25eed999cULL,
-	0x2e2eb82e6d965c43ULL, 0x4b4b314b627a9629ULL, 0xfefedffea321e15dULL, 0x575741578216aed5ULL,
-	0x15155415a8412abdULL, 0x7777c1779fb6eee8ULL, 0x3737dc37a5eb6e92ULL, 0xe5e5b3e57b56d79eULL,
-	0x9f9f469f8cd92313ULL, 0xf0f0e7f0d317fd23ULL, 0x4a4a354a6a7f9420ULL, 0xdada4fda9e95a944ULL,
-	0x58587d58fa25b0a2ULL, 0xc9c903c906ca8fcfULL, 0x2929a429558d527cULL, 0x0a0a280a5022145aULL,
-	0xb1b1feb1e14f7f50ULL, 0xa0a0baa0691a5dc9ULL, 0x6b6bb16b7fdad614ULL, 0x85852e855cab17d9ULL,
-	0xbdbdcebd8173673cULL, 0x5d5d695dd234ba8fULL, 0x1010401080502090ULL, 0xf4f4f7f4f303f507ULL,
-	0xcbcb0bcb16c08bddULL, 0x3e3ef83eedc67cd3ULL, 0x0505140528110a2dULL, 0x676781671fe6ce78ULL,
-	0xe4e4b7e47353d597ULL, 0x27279c2725bb4e02ULL, 0x4141194132588273ULL, 0x8b8b168b2c9d0ba7ULL,
-	0xa7a7a6a7510153f6ULL, 0x7d7de97dcf94fab2ULL, 0x95956e95dcfb3749ULL, 0xd8d847d88e9fad56ULL,
-	0xfbfbcbfb8b30eb70ULL, 0xeeee9fee2371c1cdULL, 0x7c7ced7cc791f8bbULL, 0x6666856617e3cc71ULL,
-	0xdddd53dda68ea77bULL, 0x17175c17b84b2eafULL, 0x4747014702468e45ULL, 0x9e9e429e84dc211aULL,
-	0xcaca0fca1ec589d4ULL, 0x2d2db42d75995a58ULL, 0xbfbfc6bf9179632eULL, 0x07071c07381b0e3fULL,
-	0xadad8ead012347acULL, 0x5a5a755aea2fb4b0ULL, 0x838336836cb51befULL, 0x3333cc3385ff66b6ULL,
-	0x636391633ff2c65cULL, 0x02020802100a0412ULL, 0xaaaa92aa39384993ULL, 0x7171d971afa8e2deULL,
-	0xc8c807c80ecf8dc6ULL, 0x19196419c87d32d1ULL, 0x494939497270923bULL, 0xd9d943d9869aaf5fULL,
-	0xf2f2eff2c31df931ULL, 0xe3e3abe34b48dba8ULL, 0x5b5b715be22ab6b9ULL, 0x88881a8834920dbcULL,
-	0x9a9a529aa4c8293eULL, 0x262698262dbe4c0bULL, 0x3232c8328dfa64bfULL, 0xb0b0fab0e94a7d59ULL,
-	0xe9e983e91b6acff2ULL, 0x0f0f3c0f78331e77ULL, 0xd5d573d5e6a6b733ULL, 0x80803a8074ba1df4ULL,
-	0xbebec2be997c6127ULL, 0xcdcd13cd26de87ebULL, 0x3434d034bde46889ULL, 0x48483d487a759032ULL,
-	0xffffdbffab24e354ULL, 0x7a7af57af78ff48dULL, 0x90907a90f4ea3d64ULL, 0x5f5f615fc23ebe9dULL,
-	0x202080201da0403dULL, 0x6868bd6867d5d00fULL, 0x1a1a681ad07234caULL, 0xaeae82ae192c41b7ULL,
-	0xb4b4eab4c95e757dULL, 0x54544d549a19a8ceULL, 0x93937693ece53b7fULL, 0x222288220daa442fULL,
-	0x64648d6407e9c863ULL, 0xf1f1e3f1db12ff2aULL, 0x7373d173bfa2e6ccULL, 0x12124812905a2482ULL,
-	0x40401d403a5d807aULL, 0x0808200840281048ULL, 0xc3c32bc356e89b95ULL, 0xecec97ec337bc5dfULL,
-	0xdbdb4bdb9690ab4dULL, 0xa1a1bea1611f5fc0ULL, 0x8d8d0e8d1c830791ULL, 0x3d3df43df5c97ac8ULL,
-	0x97976697ccf1335bULL, 0x0000000000000000ULL, 0xcfcf1bcf36d483f9ULL, 0x2b2bac2b4587566eULL,
-	0x7676c57697b3ece1ULL, 0x8282328264b019e6ULL, 0xd6d67fd6fea9b128ULL, 0x1b1b6c1bd87736c3ULL,
-	0xb5b5eeb5c15b7774ULL, 0xafaf86af112943beULL, 0x6a6ab56a77dfd41dULL, 0x50505d50ba0da0eaULL,
-	0x45450945124c8a57ULL, 0xf3f3ebf3cb18fb38ULL, 0x3030c0309df060adULL, 0xefef9bef2b74c3c4ULL,
-	0x3f3ffc3fe5c37edaULL, 0x55554955921caac7ULL, 0xa2a2b2a2791059dbULL, 0xeaea8fea0365c9e9ULL,
-	0x656589650fecca6aULL, 0xbabad2bab9686903ULL, 0x2f2fbc2f65935e4aULL, 0xc0c027c04ee79d8eULL,
-	0xdede5fdebe81a160ULL, 0x1c1c701ce06c38fcULL, 0xfdfdd3fdbb2ee746ULL, 0x4d4d294d52649a1fULL,
-	0x92927292e4e03976ULL, 0x7575c9758fbceafaULL, 0x06061806301e0c36ULL, 0x8a8a128a249809aeULL,
-	0xb2b2f2b2f940794bULL, 0xe6e6bfe66359d185ULL, 0x0e0e380e70361c7eULL, 0x1f1f7c1ff8633ee7ULL,
-	0x6262956237f7c455ULL, 0xd4d477d4eea3b53aULL, 0xa8a89aa829324d81ULL, 0x96966296c4f43152ULL,
-	0xf9f9c3f99b3aef62ULL, 0xc5c533c566f697a3ULL, 0x2525942535b14a10ULL, 0x59597959f220b2abULL,
-	0x84842a8454ae15d0ULL, 0x7272d572b7a7e4c5ULL, 0x3939e439d5dd72ecULL, 0x4c4c2d4c5a619816ULL,
-	0x5e5e655eca3bbc94ULL, 0x7878fd78e785f09fULL, 0x3838e038ddd870e5ULL, 0x8c8c0a8c14860598ULL,
-	0xd1d163d1c6b2bf17ULL, 0xa5a5aea5410b57e4ULL, 0xe2e2afe2434dd9a1ULL, 0x616199612ff8c24eULL,
-	0xb3b3f6b3f1457b42ULL, 0x2121842115a54234ULL, 0x9c9c4a9c94d62508ULL, 0x1e1e781ef0663ceeULL,
-	0x4343114322528661ULL, 0xc7c73bc776fc93b1ULL, 0xfcfcd7fcb32be54fULL, 0x0404100420140824ULL,
-	0x51515951b208a2e3ULL, 0x99995e99bcc72f25ULL, 0x6d6da96d4fc4da22ULL, 0x0d0d340d68391a65ULL,
-	0xfafacffa8335e979ULL, 0xdfdf5bdfb684a369ULL, 0x7e7ee57ed79bfca9ULL, 0x242490243db44819ULL,
-	0x3b3bec3bc5d776feULL, 0xabab96ab313d4b9aULL, 0xcece1fce3ed181f0ULL, 0x1111441188552299ULL,
-	0x8f8f068f0c890383ULL, 0x4e4e254e4a6b9c04ULL, 0xb7b7e6b7d1517366ULL, 0xebeb8beb0b60cbe0ULL,
-	0x3c3cf03cfdcc78c1ULL, 0x81813e817cbf1ffdULL, 0x94946a94d4fe3540ULL, 0xf7f7fbf7eb0cf31cULL,
-	0xb9b9deb9a1676f18ULL, 0x13134c13985f268bULL, 0x2c2cb02c7d9c5851ULL, 0xd3d36bd3d6b8bb05ULL,
-	0xe7e7bbe76b5cd38cULL, 0x6e6ea56e57cbdc39ULL, 0xc4c437c46ef395aaULL, 0x03030c03180f061bULL,
-	0x565645568a13acdcULL, 0x44440d441a49885eULL, 0x7f7fe17fdf9efea0ULL, 0xa9a99ea921374f88ULL,
-	0x2a2aa82a4d825467ULL, 0xbbbbd6bbb16d6b0aULL, 0xc1c123c146e29f87ULL, 0x53535153a202a6f1ULL,
-	0xdcdc57dcae8ba572ULL, 0x0b0b2c0b58271653ULL, 0x9d9d4e9d9cd32701ULL, 0x6c6cad6c47c1d82bULL,
-	0x3131c43195f562a4ULL, 0x7474cd7487b9e8f3ULL, 0xf6f6fff6e309f115ULL, 0x464605460a438c4cULL,
-	0xacac8aac092645a5ULL, 0x89891e893c970fb5ULL, 0x14145014a04428b4ULL, 0xe1e1a3e15b42dfbaULL,
-	0x16165816b04e2ca6ULL, 0x3a3ae83acdd274f7ULL, 0x6969b9696fd0d206ULL, 0x09092409482d1241ULL,
-	0x7070dd70a7ade0d7ULL, 0xb6b6e2b6d954716fULL, 0xd0d067d0ceb7bd1eULL, 0xeded93ed3b7ec7d6ULL,
-	0xcccc17cc2edb85e2ULL, 0x424215422a578468ULL, 0x98985a98b4c22d2cULL, 0xa4a4aaa4490e55edULL,
-	0x2828a0285d885075ULL, 0x5c5c6d5cda31b886ULL, 0xf8f8c7f8933fed6bULL, 0x8686228644a411c2ULL,
-};
-
-static const uint64_t C1[256] = {
-	0xd818186018c07830ULL, 0x2623238c2305af46ULL, 0xb8c6c63fc67ef991ULL, 0xfbe8e887e8136fcdULL,
-	0xcb878726874ca113ULL, 0x11b8b8dab8a9626dULL, 0x0901010401080502ULL, 0x0d4f4f214f426e9eULL,
-	0x9b3636d836adee6cULL, 0xffa6a6a2a6590451ULL, 0x0cd2d26fd2debdb9ULL, 0x0ef5f5f3f5fb06f7ULL,
-	0x967979f979ef80f2ULL, 0x306f6fa16f5fcedeULL, 0x6d91917e91fcef3fULL, 0xf852525552aa07a4ULL,
-	0x4760609d6027fdc0ULL, 0x35bcbccabc897665ULL, 0x379b9b569baccd2bULL, 0x8a8e8e028e048c01ULL,
-	0xd2a3a3b6a371155bULL, 0x6c0c0c300c603c18ULL, 0x847b7bf17bff8af6ULL, 0x803535d435b5e16aULL,
-	0xf51d1d741de8693aULL, 0xb3e0e0a7e05347ddULL, 0x21d7d77bd7f6acb3ULL, 0x9cc2c22fc25eed99ULL,
-	0x432e2eb82e6d965cULL, 0x294b4b314b627a96ULL, 0x5dfefedffea321e1ULL, 0xd5575741578216aeULL,
-	0xbd15155415a8412aULL, 0xe87777c1779fb6eeULL, 0x923737dc37a5eb6eULL, 0x9ee5e5b3e57b56d7ULL,
-	0x139f9f469f8cd923ULL, 0x23f0f0e7f0d317fdULL, 0x204a4a354a6a7f94ULL, 0x44dada4fda9e95a9ULL,
-	0xa258587d58fa25b0ULL, 0xcfc9c903c906ca8fULL, 0x7c2929a429558d52ULL, 0x5a0a0a280a502214ULL,
-	0x50b1b1feb1e14f7fULL, 0xc9a0a0baa0691a5dULL, 0x146b6bb16b7fdad6ULL, 0xd985852e855cab17ULL,
-	0x3cbdbdcebd817367ULL, 0x8f5d5d695dd234baULL, 0x9010104010805020ULL, 0x07f4f4f7f4f303f5ULL,
-	0xddcbcb0bcb16c08bULL, 0xd33e3ef83eedc67cULL, 0x2d0505140528110aULL, 0x78676781671fe6ceULL,
-	0x97e4e4b7e47353d5ULL, 0x0227279c2725bb4eULL, 0x7341411941325882ULL, 0xa78b8b168b2c9d0bULL,
-	0xf6a7a7a6a7510153ULL, 0xb27d7de97dcf94faULL, 0x4995956e95dcfb37ULL, 0x56d8d847d88e9fadULL,
-	0x70fbfbcbfb8b30ebULL, 0xcdeeee9fee2371c1ULL, 0xbb7c7ced7cc791f8ULL, 0x716666856617e3ccULL,
-	0x7bdddd53dda68ea7ULL, 0xaf17175c17b84b2eULL, 0x454747014702468eULL, 0x1a9e9e429e84dc21ULL,
-	0xd4caca0fca1ec589ULL, 0x582d2db42d75995aULL, 0x2ebfbfc6bf917963ULL, 0x3f07071c07381b0eULL,
-	0xacadad8ead012347ULL, 0xb05a5a755aea2fb4ULL, 0xef838336836cb51bULL, 0xb63333cc3385ff66ULL,
-	0x5c636391633ff2c6ULL, 0x1202020802100a04ULL, 0x93aaaa92aa393849ULL, 0xde7171d971afa8e2ULL,
-	0xc6c8c807c80ecf8dULL, 0xd119196419c87d32ULL, 0x3b49493949727092ULL, 0x5fd9d943d9869aafULL,
-	0x31f2f2eff2c31df9ULL, 0xa8e3e3abe34b48dbULL, 0xb95b5b715be22ab6ULL, 0xbc88881a8834920dULL,
-	0x3e9a9a529aa4c829ULL, 0x0b262698262dbe4cULL, 0xbf3232c8328dfa64ULL, 0x59b0b0fab0e94a7dULL,
-	0xf2e9e983e91b6acfULL, 0x770f0f3c0f78331eULL, 0x33d5d573d5e6a6b7ULL, 0xf480803a8074ba1dULL,
-	0x27bebec2be997c61ULL, 0xebcdcd13cd26de87ULL, 0x893434d034bde468ULL, 0x3248483d487a7590ULL,
-	0x54ffffdbffab24e3ULL, 0x8d7a7af57af78ff4ULL, 0x6490907a90f4ea3dULL, 0x9d5f5f615fc23ebeULL,
-	0x3d202080201da040ULL, 0x0f6868bd6867d5d0ULL, 0xca1a1a681ad07234ULL, 0xb7aeae82ae192c41ULL,
-	0x7db4b4eab4c95e75ULL, 0xce54544d549a19a8ULL, 0x7f93937693ece53bULL, 0x2f222288220daa44ULL,
-	0x6364648d6407e9c8ULL, 0x2af1f1e3f1db12ffULL, 0xcc7373d173bfa2e6ULL, 0x8212124812905a24ULL,
-	0x7a40401d403a5d80ULL, 0x4808082008402810ULL, 0x95c3c32bc356e89bULL, 0xdfecec97ec337bc5ULL,
-	0x4ddbdb4bdb9690abULL, 0xc0a1a1bea1611f5fULL, 0x918d8d0e8d1c8307ULL, 0xc83d3df43df5c97aULL,
-	0x5b97976697ccf133ULL, 0x0000000000000000ULL, 0xf9cfcf1bcf36d483ULL, 0x6e2b2bac2b458756ULL,
-	0xe17676c57697b3ecULL, 0xe68282328264b019ULL, 0x28d6d67fd6fea9b1ULL, 0xc31b1b6c1bd87736ULL,
-	0x74b5b5eeb5c15b77ULL, 0xbeafaf86af112943ULL, 0x1d6a6ab56a77dfd4ULL, 0xea50505d50ba0da0ULL,
-	0x5745450945124c8aULL, 0x38f3f3ebf3cb18fbULL, 0xad3030c0309df060ULL, 0xc4efef9bef2b74c3ULL,
-	0xda3f3ffc3fe5c37eULL, 0xc755554955921caaULL, 0xdba2a2b2a2791059ULL, 0xe9eaea8fea0365c9ULL,
-	0x6a656589650feccaULL, 0x03babad2bab96869ULL, 0x4a2f2fbc2f65935eULL, 0x8ec0c027c04ee79dULL,
-	0x60dede5fdebe81a1ULL, 0xfc1c1c701ce06c38ULL, 0x46fdfdd3fdbb2ee7ULL, 0x1f4d4d294d52649aULL,
-	0x7692927292e4e039ULL, 0xfa7575c9758fbceaULL, 0x3606061806301e0cULL, 0xae8a8a128a249809ULL,
-	0x4bb2b2f2b2f94079ULL, 0x85e6e6bfe66359d1ULL, 0x7e0e0e380e70361cULL, 0xe71f1f7c1ff8633eULL,
-	0x556262956237f7c4ULL, 0x3ad4d477d4eea3b5ULL, 0x81a8a89aa829324dULL, 0x5296966296c4f431ULL,
-	0x62f9f9c3f99b3aefULL, 0xa3c5c533c566f697ULL, 0x102525942535b14aULL, 0xab59597959f220b2ULL,
-	0xd084842a8454ae15ULL, 0xc57272d572b7a7e4ULL, 0xec3939e439d5dd72ULL, 0x164c4c2d4c5a6198ULL,
-	0x945e5e655eca3bbcULL, 0x9f7878fd78e785f0ULL, 0xe53838e038ddd870ULL, 0x988c8c0a8c148605ULL,
-	0x17d1d163d1c6b2bfULL, 0xe4a5a5aea5410b57ULL, 0xa1e2e2afe2434dd9ULL, 0x4e616199612ff8c2ULL,
-	0x42b3b3f6b3f1457bULL, 0x342121842115a542ULL, 0x089c9c4a9c94d625ULL, 0xee1e1e781ef0663cULL,
-	0x6143431143225286ULL, 0xb1c7c73bc776fc93ULL, 0x4ffcfcd7fcb32be5ULL, 0x2404041004201408ULL,
-	0xe351515951b208a2ULL, 0x2599995e99bcc72fULL, 0x226d6da96d4fc4daULL, 0x650d0d340d68391aULL,
-	0x79fafacffa8335e9ULL, 0x69dfdf5bdfb684a3ULL, 0xa97e7ee57ed79bfcULL, 0x19242490243db448ULL,
-	0xfe3b3bec3bc5d776ULL, 0x9aabab96ab313d4bULL, 0xf0cece1fce3ed181ULL, 0x9911114411885522ULL,
-	0x838f8f068f0c8903ULL, 0x044e4e254e4a6b9cULL, 0x66b7b7e6b7d15173ULL, 0xe0ebeb8beb0b60cbULL,
-	0xc13c3cf03cfdcc78ULL, 0xfd81813e817cbf1fULL, 0x4094946a94d4fe35ULL, 0x1cf7f7fbf7eb0cf3ULL,
-	0x18b9b9deb9a1676fULL, 0x8b13134c13985f26ULL, 0x512c2cb02c7d9c58ULL, 0x05d3d36bd3d6b8bbULL,
-	0x8ce7e7bbe76b5cd3ULL, 0x396e6ea56e57cbdcULL, 0xaac4c437c46ef395ULL, 0x1b03030c03180f06ULL,
-	0xdc565645568a13acULL, 0x5e44440d441a4988ULL, 0xa07f7fe17fdf9efeULL, 0x88a9a99ea921374fULL,
-	0x672a2aa82a4d8254ULL, 0x0abbbbd6bbb16d6bULL, 0x87c1c123c146e29fULL, 0xf153535153a202a6ULL,
-	0x72dcdc57dcae8ba5ULL, 0x530b0b2c0b582716ULL, 0x019d9d4e9d9cd327ULL, 0x2b6c6cad6c47c1d8ULL,
-	0xa43131c43195f562ULL, 0xf37474cd7487b9e8ULL, 0x15f6f6fff6e309f1ULL, 0x4c464605460a438cULL,
-	0xa5acac8aac092645ULL, 0xb589891e893c970fULL, 0xb414145014a04428ULL, 0xbae1e1a3e15b42dfULL,
-	0xa616165816b04e2cULL, 0xf73a3ae83acdd274ULL, 0x066969b9696fd0d2ULL, 0x4109092409482d12ULL,
-	0xd77070dd70a7ade0ULL, 0x6fb6b6e2b6d95471ULL, 0x1ed0d067d0ceb7bdULL, 0xd6eded93ed3b7ec7ULL,
-	0xe2cccc17cc2edb85ULL, 0x68424215422a5784ULL, 0x2c98985a98b4c22dULL, 0xeda4a4aaa4490e55ULL,
-	0x752828a0285d8850ULL, 0x865c5c6d5cda31b8ULL, 0x6bf8f8c7f8933fedULL, 0xc28686228644a411ULL,
-};
-
-static const uint64_t C2[256] = {
-	0x30d818186018c078ULL, 0x462623238c2305afULL, 0x91b8c6c63fc67ef9ULL, 0xcdfbe8e887e8136fULL,
-	0x13cb878726874ca1ULL, 0x6d11b8b8dab8a962ULL, 0x0209010104010805ULL, 0x9e0d4f4f214f426eULL,
-	0x6c9b3636d836adeeULL, 0x51ffa6a6a2a65904ULL, 0xb90cd2d26fd2debdULL, 0xf70ef5f5f3f5fb06ULL,
-	0xf2967979f979ef80ULL, 0xde306f6fa16f5fceULL, 0x3f6d91917e91fcefULL, 0xa4f852525552aa07ULL,
-	0xc04760609d6027fdULL, 0x6535bcbccabc8976ULL, 0x2b379b9b569baccdULL, 0x018a8e8e028e048cULL,
-	0x5bd2a3a3b6a37115ULL, 0x186c0c0c300c603cULL, 0xf6847b7bf17bff8aULL, 0x6a803535d435b5e1ULL,
-	0x3af51d1d741de869ULL, 0xddb3e0e0a7e05347ULL, 0xb321d7d77bd7f6acULL, 0x999cc2c22fc25eedULL,
-	0x5c432e2eb82e6d96ULL, 0x96294b4b314b627aULL, 0xe15dfefedffea321ULL, 0xaed5575741578216ULL,
-	0x2abd15155415a841ULL, 0xeee87777c1779fb6ULL, 0x6e923737dc37a5ebULL, 0xd79ee5e5b3e57b56ULL,
-	0x23139f9f469f8cd9ULL, 0xfd23f0f0e7f0d317ULL, 0x94204a4a354a6a7fULL, 0xa944dada4fda9e95ULL,
-	0xb0a258587d58fa25ULL, 0x8fcfc9c903c906caULL, 0x527c2929a429558dULL, 0x145a0a0a280a5022ULL,
-	0x7f50b1b1feb1e14fULL, 0x5dc9a0a0baa0691aULL, 0xd6146b6bb16b7fdaULL, 0x17d985852e855cabULL,
-	0x673cbdbdcebd8173ULL, 0xba8f5d5d695dd234ULL, 0x2090101040108050ULL, 0xf507f4f4f7f4f303ULL,
-	0x8bddcbcb0bcb16c0ULL, 0x7cd33e3ef83eedc6ULL, 0x0a2d050514052811ULL, 0xce78676781671fe6ULL,
-	0xd597e4e4b7e47353ULL, 0x4e0227279c2725bbULL, 0x8273414119413258ULL, 0x0ba78b8b168b2c9dULL,
-	0x53f6a7a7a6a75101ULL, 0xfab27d7de97dcf94ULL, 0x374995956e95dcfbULL, 0xad56d8d847d88e9fULL,
-	0xeb70fbfbcbfb8b30ULL, 0xc1cdeeee9fee2371ULL, 0xf8bb7c7ced7cc791ULL, 0xcc716666856617e3ULL,
-	0xa77bdddd53dda68eULL, 0x2eaf17175c17b84bULL, 0x8e45474701470246ULL, 0x211a9e9e429e84dcULL,
-	0x89d4caca0fca1ec5ULL, 0x5a582d2db42d7599ULL, 0x632ebfbfc6bf9179ULL, 0x0e3f07071c07381bULL,
-	0x47acadad8ead0123ULL, 0xb4b05a5a755aea2fULL, 0x1bef838336836cb5ULL, 0x66b63333cc3385ffULL,
-	0xc65c636391633ff2ULL, 0x041202020802100aULL, 0x4993aaaa92aa3938ULL, 0xe2de7171d971afa8ULL,
-	0x8dc6c8c807c80ecfULL, 0x32d119196419c87dULL, 0x923b494939497270ULL, 0xaf5fd9d943d9869aULL,
-	0xf931f2f2eff2c31dULL, 0xdba8e3e3abe34b48ULL, 0xb6b95b5b715be22aULL, 0x0dbc88881a883492ULL,
-	0x293e9a9a529aa4c8ULL, 0x4c0b262698262dbeULL, 0x64bf3232c8328dfaULL, 0x7d59b0b0fab0e94aULL,
-	0xcff2e9e983e91b6aULL, 0x1e770f0f3c0f7833ULL, 0xb733d5d573d5e6a6ULL, 0x1df480803a8074baULL,
-	0x6127bebec2be997cULL, 0x87ebcdcd13cd26deULL, 0x68893434d034bde4ULL, 0x903248483d487a75ULL,
-	0xe354ffffdbffab24ULL, 0xf48d7a7af57af78fULL, 0x3d6490907a90f4eaULL, 0xbe9d5f5f615fc23eULL,
-	0x403d202080201da0ULL, 0xd00f6868bd6867d5ULL, 0x34ca1a1a681ad072ULL, 0x41b7aeae82ae192cULL,
-	0x757db4b4eab4c95eULL, 0xa8ce54544d549a19ULL, 0x3b7f93937693ece5ULL, 0x442f222288220daaULL,
-	0xc86364648d6407e9ULL, 0xff2af1f1e3f1db12ULL, 0xe6cc7373d173bfa2ULL, 0x248212124812905aULL,
-	0x807a40401d403a5dULL, 0x1048080820084028ULL, 0x9b95c3c32bc356e8ULL, 0xc5dfecec97ec337bULL,
-	0xab4ddbdb4bdb9690ULL, 0x5fc0a1a1bea1611fULL, 0x07918d8d0e8d1c83ULL, 0x7ac83d3df43df5c9ULL,
-	0x335b97976697ccf1ULL, 0x0000000000000000ULL, 0x83f9cfcf1bcf36d4ULL, 0x566e2b2bac2b4587ULL,
-	0xece17676c57697b3ULL, 0x19e68282328264b0ULL, 0xb128d6d67fd6fea9ULL, 0x36c31b1b6c1bd877ULL,
-	0x7774b5b5eeb5c15bULL, 0x43beafaf86af1129ULL, 0xd41d6a6ab56a77dfULL, 0xa0ea50505d50ba0dULL,
-	0x8a5745450945124cULL, 0xfb38f3f3ebf3cb18ULL, 0x60ad3030c0309df0ULL, 0xc3c4efef9bef2b74ULL,
-	0x7eda3f3ffc3fe5c3ULL, 0xaac755554955921cULL, 0x59dba2a2b2a27910ULL, 0xc9e9eaea8fea0365ULL,
-	0xca6a656589650fecULL, 0x6903babad2bab968ULL, 0x5e4a2f2fbc2f6593ULL, 0x9d8ec0c027c04ee7ULL,
-	0xa160dede5fdebe81ULL, 0x38fc1c1c701ce06cULL, 0xe746fdfdd3fdbb2eULL, 0x9a1f4d4d294d5264ULL,
-	0x397692927292e4e0ULL, 0xeafa7575c9758fbcULL, 0x0c3606061806301eULL, 0x09ae8a8a128a2498ULL,
-	0x794bb2b2f2b2f940ULL, 0xd185e6e6bfe66359ULL, 0x1c7e0e0e380e7036ULL, 0x3ee71f1f7c1ff863ULL,
-	0xc4556262956237f7ULL, 0xb53ad4d477d4eea3ULL, 0x4d81a8a89aa82932ULL, 0x315296966296c4f4ULL,
-	0xef62f9f9c3f99b3aULL, 0x97a3c5c533c566f6ULL, 0x4a102525942535b1ULL, 0xb2ab59597959f220ULL,
-	0x15d084842a8454aeULL, 0xe4c57272d572b7a7ULL, 0x72ec3939e439d5ddULL, 0x98164c4c2d4c5a61ULL,
-	0xbc945e5e655eca3bULL, 0xf09f7878fd78e785ULL, 0x70e53838e038ddd8ULL, 0x05988c8c0a8c1486ULL,
-	0xbf17d1d163d1c6b2ULL, 0x57e4a5a5aea5410bULL, 0xd9a1e2e2afe2434dULL, 0xc24e616199612ff8ULL,
-	0x7b42b3b3f6b3f145ULL, 0x42342121842115a5ULL, 0x25089c9c4a9c94d6ULL, 0x3cee1e1e781ef066ULL,
-	0x8661434311432252ULL, 0x93b1c7c73bc776fcULL, 0xe54ffcfcd7fcb32bULL, 0x0824040410042014ULL,
-	0xa2e351515951b208ULL, 0x2f2599995e99bcc7ULL, 0xda226d6da96d4fc4ULL, 0x1a650d0d340d6839ULL,
-	0xe979fafacffa8335ULL, 0xa369dfdf5bdfb684ULL, 0xfca97e7ee57ed79bULL, 0x4819242490243db4ULL,
-	0x76fe3b3bec3bc5d7ULL, 0x4b9aabab96ab313dULL, 0x81f0cece1fce3ed1ULL, 0x2299111144118855ULL,
-	0x03838f8f068f0c89ULL, 0x9c044e4e254e4a6bULL, 0x7366b7b7e6b7d151ULL, 0xcbe0ebeb8beb0b60ULL,
-	0x78c13c3cf03cfdccULL, 0x1ffd81813e817cbfULL, 0x354094946a94d4feULL, 0xf31cf7f7fbf7eb0cULL,
-	0x6f18b9b9deb9a167ULL, 0x268b13134c13985fULL, 0x58512c2cb02c7d9cULL, 0xbb05d3d36bd3d6b8ULL,
-	0xd38ce7e7bbe76b5cULL, 0xdc396e6ea56e57cbULL, 0x95aac4c437c46ef3ULL, 0x061b03030c03180fULL,
-	0xacdc565645568a13ULL, 0x885e44440d441a49ULL, 0xfea07f7fe17fdf9eULL, 0x4f88a9a99ea92137ULL,
-	0x54672a2aa82a4d82ULL, 0x6b0abbbbd6bbb16dULL, 0x9f87c1c123c146e2ULL, 0xa6f153535153a202ULL,
-	0xa572dcdc57dcae8bULL, 0x16530b0b2c0b5827ULL, 0x27019d9d4e9d9cd3ULL, 0xd82b6c6cad6c47c1ULL,
-	0x62a43131c43195f5ULL, 0xe8f37474cd7487b9ULL, 0xf115f6f6fff6e309ULL, 0x8c4c464605460a43ULL,
-	0x45a5acac8aac0926ULL, 0x0fb589891e893c97ULL, 0x28b414145014a044ULL, 0xdfbae1e1a3e15b42ULL,
-	0x2ca616165816b04eULL, 0x74f73a3ae83acdd2ULL, 0xd2066969b9696fd0ULL, 0x124109092409482dULL,
-	0xe0d77070dd70a7adULL, 0x716fb6b6e2b6d954ULL, 0xbd1ed0d067d0ceb7ULL, 0xc7d6eded93ed3b7eULL,
-	0x85e2cccc17cc2edbULL, 0x8468424215422a57ULL, 0x2d2c98985a98b4c2ULL, 0x55eda4a4aaa4490eULL,
-	0x50752828a0285d88ULL, 0xb8865c5c6d5cda31ULL, 0xed6bf8f8c7f8933fULL, 0x11c28686228644a4ULL,
-};
-
-static const uint64_t C3[256] = {
-	0x7830d818186018c0ULL, 0xaf462623238c2305ULL, 0xf991b8c6c63fc67eULL, 0x6fcdfbe8e887e813ULL,
-	0xa113cb878726874cULL, 0x626d11b8b8dab8a9ULL, 0x0502090101040108ULL, 0x6e9e0d4f4f214f42ULL,
-	0xee6c9b3636d836adULL, 0x0451ffa6a6a2a659ULL, 0xbdb90cd2d26fd2deULL, 0x06f70ef5f5f3f5fbULL,
-	0x80f2967979f979efULL, 0xcede306f6fa16f5fULL, 0xef3f6d91917e91fcULL, 0x07a4f852525552aaULL,
-	0xfdc04760609d6027ULL, 0x766535bcbccabc89ULL, 0xcd2b379b9b569bacULL, 0x8c018a8e8e028e04ULL,
-	0x155bd2a3a3b6a371ULL, 0x3c186c0c0c300c60ULL, 0x8af6847b7bf17bffULL, 0xe16a803535d435b5ULL,
-	0x693af51d1d741de8ULL, 0x47ddb3e0e0a7e053ULL, 0xacb321d7d77bd7f6ULL, 0xed999cc2c22fc25eULL,
-	0x965c432e2eb82e6dULL, 0x7a96294b4b314b62ULL, 0x21e15dfefedffea3ULL, 0x16aed55757415782ULL,
-	0x412abd15155415a8ULL, 0xb6eee87777c1779fULL, 0xeb6e923737dc37a5ULL, 0x56d79ee5e5b3e57bULL,
-	0xd923139f9f469f8cULL, 0x17fd23f0f0e7f0d3ULL, 0x7f94204a4a354a6aULL, 0x95a944dada4fda9eULL,
-	0x25b0a258587d58faULL, 0xca8fcfc9c903c906ULL, 0x8d527c2929a42955ULL, 0x22145a0a0a280a50ULL,
-	0x4f7f50b1b1feb1e1ULL, 0x1a5dc9a0a0baa069ULL, 0xdad6146b6bb16b7fULL, 0xab17d985852e855cULL,
-	0x73673cbdbdcebd81ULL, 0x34ba8f5d5d695dd2ULL, 0x5020901010401080ULL, 0x03f507f4f4f7f4f3ULL,
-	0xc08bddcbcb0bcb16ULL, 0xc67cd33e3ef83eedULL, 0x110a2d0505140528ULL, 0xe6ce78676781671fULL,
-	0x53d597e4e4b7e473ULL, 0xbb4e0227279c2725ULL, 0x5882734141194132ULL, 0x9d0ba78b8b168b2cULL,
-	0x0153f6a7a7a6a751ULL, 0x94fab27d7de97dcfULL, 0xfb374995956e95dcULL, 0x9fad56d8d847d88eULL,
-	0x30eb70fbfbcbfb8bULL, 0x71c1cdeeee9fee23ULL, 0x91f8bb7c7ced7cc7ULL, 0xe3cc716666856617ULL,
-	0x8ea77bdddd53dda6ULL, 0x4b2eaf17175c17b8ULL, 0x468e454747014702ULL, 0xdc211a9e9e429e84ULL,
-	0xc589d4caca0fca1eULL, 0x995a582d2db42d75ULL, 0x79632ebfbfc6bf91ULL, 0x1b0e3f07071c0738ULL,
-	0x2347acadad8ead01ULL, 0x2fb4b05a5a755aeaULL, 0xb51bef838336836cULL, 0xff66b63333cc3385ULL,
-	0xf2c65c636391633fULL, 0x0a04120202080210ULL, 0x384993aaaa92aa39ULL, 0xa8e2de7171d971afULL,
-	0xcf8dc6c8c807c80eULL, 0x7d32d119196419c8ULL, 0x70923b4949394972ULL, 0x9aaf5fd9d943d986ULL,
-	0x1df931f2f2eff2c3ULL, 0x48dba8e3e3abe34bULL, 0x2ab6b95b5b715be2ULL, 0x920dbc88881a8834ULL,
-	0xc8293e9a9a529aa4ULL, 0xbe4c0b262698262dULL, 0xfa64bf3232c8328dULL, 0x4a7d59b0b0fab0e9ULL,
-	0x6acff2e9e983e91bULL, 0x331e770f0f3c0f78ULL, 0xa6b733d5d573d5e6ULL, 0xba1df480803a8074ULL,
-	0x7c6127bebec2be99ULL, 0xde87ebcdcd13cd26ULL, 0xe468893434d034bdULL, 0x75903248483d487aULL,
-	0x24e354ffffdbffabULL, 0x8ff48d7a7af57af7ULL, 0xea3d6490907a90f4ULL, 0x3ebe9d5f5f615fc2ULL,
-	0xa0403d202080201dULL, 0xd5d00f6868bd6867ULL, 0x7234ca1a1a681ad0ULL, 0x2c41b7aeae82ae19ULL,
-	0x5e757db4b4eab4c9ULL, 0x19a8ce54544d549aULL, 0xe53b7f93937693ecULL, 0xaa442f222288220dULL,
-	0xe9c86364648d6407ULL, 0x12ff2af1f1e3f1dbULL, 0xa2e6cc7373d173bfULL, 0x5a24821212481290ULL,
-	0x5d807a40401d403aULL, 0x2810480808200840ULL, 0xe89b95c3c32bc356ULL, 0x7bc5dfecec97ec33ULL,
-	0x90ab4ddbdb4bdb96ULL, 0x1f5fc0a1a1bea161ULL, 0x8307918d8d0e8d1cULL, 0xc97ac83d3df43df5ULL,
-	0xf1335b97976697ccULL, 0x0000000000000000ULL, 0xd483f9cfcf1bcf36ULL, 0x87566e2b2bac2b45ULL,
-	0xb3ece17676c57697ULL, 0xb019e68282328264ULL, 0xa9b128d6d67fd6feULL, 0x7736c31b1b6c1bd8ULL,
-	0x5b7774b5b5eeb5c1ULL, 0x2943beafaf86af11ULL, 0xdfd41d6a6ab56a77ULL, 0x0da0ea50505d50baULL,
-	0x4c8a574545094512ULL, 0x18fb38f3f3ebf3cbULL, 0xf060ad3030c0309dULL, 0x74c3c4efef9bef2bULL,
-	0xc37eda3f3ffc3fe5ULL, 0x1caac75555495592ULL, 0x1059dba2a2b2a279ULL, 0x65c9e9eaea8fea03ULL,
-	0xecca6a656589650fULL, 0x686903babad2bab9ULL, 0x935e4a2f2fbc2f65ULL, 0xe79d8ec0c027c04eULL,
-	0x81a160dede5fdebeULL, 0x6c38fc1c1c701ce0ULL, 0x2ee746fdfdd3fdbbULL, 0x649a1f4d4d294d52ULL,
-	0xe0397692927292e4ULL, 0xbceafa7575c9758fULL, 0x1e0c360606180630ULL, 0x9809ae8a8a128a24ULL,
-	0x40794bb2b2f2b2f9ULL, 0x59d185e6e6bfe663ULL, 0x361c7e0e0e380e70ULL, 0x633ee71f1f7c1ff8ULL,
-	0xf7c4556262956237ULL, 0xa3b53ad4d477d4eeULL, 0x324d81a8a89aa829ULL, 0xf4315296966296c4ULL,
-	0x3aef62f9f9c3f99bULL, 0xf697a3c5c533c566ULL, 0xb14a102525942535ULL, 0x20b2ab59597959f2ULL,
-	0xae15d084842a8454ULL, 0xa7e4c57272d572b7ULL, 0xdd72ec3939e439d5ULL, 0x6198164c4c2d4c5aULL,
-	0x3bbc945e5e655ecaULL, 0x85f09f7878fd78e7ULL, 0xd870e53838e038ddULL, 0x8605988c8c0a8c14ULL,
-	0xb2bf17d1d163d1c6ULL, 0x0b57e4a5a5aea541ULL, 0x4dd9a1e2e2afe243ULL, 0xf8c24e616199612fULL,
-	0x457b42b3b3f6b3f1ULL, 0xa542342121842115ULL, 0xd625089c9c4a9c94ULL, 0x663cee1e1e781ef0ULL,
-	0x5286614343114322ULL, 0xfc93b1c7c73bc776ULL, 0x2be54ffcfcd7fcb3ULL, 0x1408240404100420ULL,
-	0x08a2e351515951b2ULL, 0xc72f2599995e99bcULL, 0xc4da226d6da96d4fULL, 0x391a650d0d340d68ULL,
-	0x35e979fafacffa83ULL, 0x84a369dfdf5bdfb6ULL, 0x9bfca97e7ee57ed7ULL, 0xb44819242490243dULL,
-	0xd776fe3b3bec3bc5ULL, 0x3d4b9aabab96ab31ULL, 0xd181f0cece1fce3eULL, 0x5522991111441188ULL,
-	0x8903838f8f068f0cULL, 0x6b9c044e4e254e4aULL, 0x517366b7b7e6b7d1ULL, 0x60cbe0ebeb8beb0bULL,
-	0xcc78c13c3cf03cfdULL, 0xbf1ffd81813e817cULL, 0xfe354094946a94d4ULL, 0x0cf31cf7f7fbf7ebULL,
-	0x676f18b9b9deb9a1ULL, 0x5f268b13134c1398ULL, 0x9c58512c2cb02c7dULL, 0xb8bb05d3d36bd3d6ULL,
-	0x5cd38ce7e7bbe76bULL, 0xcbdc396e6ea56e57ULL, 0xf395aac4c437c46eULL, 0x0f061b03030c0318ULL,
-	0x13acdc565645568aULL, 0x49885e44440d441aULL, 0x9efea07f7fe17fdfULL, 0x374f88a9a99ea921ULL,
-	0x8254672a2aa82a4dULL, 0x6d6b0abbbbd6bbb1ULL, 0xe29f87c1c123c146ULL, 0x02a6f153535153a2ULL,
-	0x8ba572dcdc57dcaeULL, 0x2716530b0b2c0b58ULL, 0xd327019d9d4e9d9cULL, 0xc1d82b6c6cad6c47ULL,
-	0xf562a43131c43195ULL, 0xb9e8f37474cd7487ULL, 0x09f115f6f6fff6e3ULL, 0x438c4c464605460aULL,
-	0x2645a5acac8aac09ULL, 0x970fb589891e893cULL, 0x4428b414145014a0ULL, 0x42dfbae1e1a3e15bULL,
-	0x4e2ca616165816b0ULL, 0xd274f73a3ae83acdULL, 0xd0d2066969b9696fULL, 0x2d12410909240948ULL,
-	0xade0d77070dd70a7ULL, 0x54716fb6b6e2b6d9ULL, 0xb7bd1ed0d067d0ceULL, 0x7ec7d6eded93ed3bULL,
-	0xdb85e2cccc17cc2eULL, 0x578468424215422aULL, 0xc22d2c98985a98b4ULL, 0x0e55eda4a4aaa449ULL,
-	0x8850752828a0285dULL, 0x31b8865c5c6d5cdaULL, 0x3fed6bf8f8c7f893ULL, 0xa411c28686228644ULL,
-};
-
-static const uint64_t C4[256] = {
-	0xc07830d818186018ULL, 0x05af462623238c23ULL, 0x7ef991b8c6c63fc6ULL, 0x136fcdfbe8e887e8ULL,
-	0x4ca113cb87872687ULL, 0xa9626d11b8b8dab8ULL, 0x0805020901010401ULL, 0x426e9e0d4f4f214fULL,
-	0xadee6c9b3636d836ULL, 0x590451ffa6a6a2a6ULL, 0xdebdb90cd2d26fd2ULL, 0xfb06f70ef5f5f3f5ULL,
-	0xef80f2967979f979ULL, 0x5fcede306f6fa16fULL, 0xfcef3f6d91917e91ULL, 0xaa07a4f852525552ULL,
-	0x27fdc04760609d60ULL, 0x89766535bcbccabcULL, 0xaccd2b379b9b569bULL, 0x048c018a8e8e028eULL,
-	0x71155bd2a3a3b6a3ULL, 0x603c186c0c0c300cULL, 0xff8af6847b7bf17bULL, 0xb5e16a803535d435ULL,
-	0xe8693af51d1d741dULL, 0x5347ddb3e0e0a7e0ULL, 0xf6acb321d7d77bd7ULL, 0x5eed999cc2c22fc2ULL,
-	0x6d965c432e2eb82eULL, 0x627a96294b4b314bULL, 0xa321e15dfefedffeULL, 0x8216aed557574157ULL,
-	0xa8412abd15155415ULL, 0x9fb6eee87777c177ULL, 0xa5eb6e923737dc37ULL, 0x7b56d79ee5e5b3e5ULL,
-	0x8cd923139f9f469fULL, 0xd317fd23f0f0e7f0ULL, 0x6a7f94204a4a354aULL, 0x9e95a944dada4fdaULL,
-	0xfa25b0a258587d58ULL, 0x06ca8fcfc9c903c9ULL, 0x558d527c2929a429ULL, 0x5022145a0a0a280aULL,
-	0xe14f7f50b1b1feb1ULL, 0x691a5dc9a0a0baa0ULL, 0x7fdad6146b6bb16bULL, 0x5cab17d985852e85ULL,
-	0x8173673cbdbdcebdULL, 0xd234ba8f5d5d695dULL, 0x8050209010104010ULL, 0xf303f507f4f4f7f4ULL,
-	0x16c08bddcbcb0bcbULL, 0xedc67cd33e3ef83eULL, 0x28110a2d05051405ULL, 0x1fe6ce7867678167ULL,
-	0x7353d597e4e4b7e4ULL, 0x25bb4e0227279c27ULL, 0x3258827341411941ULL, 0x2c9d0ba78b8b168bULL,
-	0x510153f6a7a7a6a7ULL, 0xcf94fab27d7de97dULL, 0xdcfb374995956e95ULL, 0x8e9fad56d8d847d8ULL,
-	0x8b30eb70fbfbcbfbULL, 0x2371c1cdeeee9feeULL, 0xc791f8bb7c7ced7cULL, 0x17e3cc7166668566ULL,
-	0xa68ea77bdddd53ddULL, 0xb84b2eaf17175c17ULL, 0x02468e4547470147ULL, 0x84dc211a9e9e429eULL,
-	0x1ec589d4caca0fcaULL, 0x75995a582d2db42dULL, 0x9179632ebfbfc6bfULL, 0x381b0e3f07071c07ULL,
-	0x012347acadad8eadULL, 0xea2fb4b05a5a755aULL, 0x6cb51bef83833683ULL, 0x85ff66b63333cc33ULL,
-	0x3ff2c65c63639163ULL, 0x100a041202020802ULL, 0x39384993aaaa92aaULL, 0xafa8e2de7171d971ULL,
-	0x0ecf8dc6c8c807c8ULL, 0xc87d32d119196419ULL, 0x7270923b49493949ULL, 0x869aaf5fd9d943d9ULL,
-	0xc31df931f2f2eff2ULL, 0x4b48dba8e3e3abe3ULL, 0xe22ab6b95b5b715bULL, 0x34920dbc88881a88ULL,
-	0xa4c8293e9a9a529aULL, 0x2dbe4c0b26269826ULL, 0x8dfa64bf3232c832ULL, 0xe94a7d59b0b0fab0ULL,
-	0x1b6acff2e9e983e9ULL, 0x78331e770f0f3c0fULL, 0xe6a6b733d5d573d5ULL, 0x74ba1df480803a80ULL,
-	0x997c6127bebec2beULL, 0x26de87ebcdcd13cdULL, 0xbde468893434d034ULL, 0x7a75903248483d48ULL,
-	0xab24e354ffffdbffULL, 0xf78ff48d7a7af57aULL, 0xf4ea3d6490907a90ULL, 0xc23ebe9d5f5f615fULL,
-	0x1da0403d20208020ULL, 0x67d5d00f6868bd68ULL, 0xd07234ca1a1a681aULL, 0x192c41b7aeae82aeULL,
-	0xc95e757db4b4eab4ULL, 0x9a19a8ce54544d54ULL, 0xece53b7f93937693ULL, 0x0daa442f22228822ULL,
-	0x07e9c86364648d64ULL, 0xdb12ff2af1f1e3f1ULL, 0xbfa2e6cc7373d173ULL, 0x905a248212124812ULL,
-	0x3a5d807a40401d40ULL, 0x4028104808082008ULL, 0x56e89b95c3c32bc3ULL, 0x337bc5dfecec97ecULL,
-	0x9690ab4ddbdb4bdbULL, 0x611f5fc0a1a1bea1ULL, 0x1c8307918d8d0e8dULL, 0xf5c97ac83d3df43dULL,
-	0xccf1335b97976697ULL, 0x0000000000000000ULL, 0x36d483f9cfcf1bcfULL, 0x4587566e2b2bac2bULL,
-	0x97b3ece17676c576ULL, 0x64b019e682823282ULL, 0xfea9b128d6d67fd6ULL, 0xd87736c31b1b6c1bULL,
-	0xc15b7774b5b5eeb5ULL, 0x112943beafaf86afULL, 0x77dfd41d6a6ab56aULL, 0xba0da0ea50505d50ULL,
-	0x124c8a5745450945ULL, 0xcb18fb38f3f3ebf3ULL, 0x9df060ad3030c030ULL, 0x2b74c3c4efef9befULL,
-	0xe5c37eda3f3ffc3fULL, 0x921caac755554955ULL, 0x791059dba2a2b2a2ULL, 0x0365c9e9eaea8feaULL,
-	0x0fecca6a65658965ULL, 0xb9686903babad2baULL, 0x65935e4a2f2fbc2fULL, 0x4ee79d8ec0c027c0ULL,
-	0xbe81a160dede5fdeULL, 0xe06c38fc1c1c701cULL, 0xbb2ee746fdfdd3fdULL, 0x52649a1f4d4d294dULL,
-	0xe4e0397692927292ULL, 0x8fbceafa7575c975ULL, 0x301e0c3606061806ULL, 0x249809ae8a8a128aULL,
-	0xf940794bb2b2f2b2ULL, 0x6359d185e6e6bfe6ULL, 0x70361c7e0e0e380eULL, 0xf8633ee71f1f7c1fULL,
-	0x37f7c45562629562ULL, 0xeea3b53ad4d477d4ULL, 0x29324d81a8a89aa8ULL, 0xc4f4315296966296ULL,
-	0x9b3aef62f9f9c3f9ULL, 0x66f697a3c5c533c5ULL, 0x35b14a1025259425ULL, 0xf220b2ab59597959ULL,
-	0x54ae15d084842a84ULL, 0xb7a7e4c57272d572ULL, 0xd5dd72ec3939e439ULL, 0x5a6198164c4c2d4cULL,
-	0xca3bbc945e5e655eULL, 0xe785f09f7878fd78ULL, 0xddd870e53838e038ULL, 0x148605988c8c0a8cULL,
-	0xc6b2bf17d1d163d1ULL, 0x410b57e4a5a5aea5ULL, 0x434dd9a1e2e2afe2ULL, 0x2ff8c24e61619961ULL,
-	0xf1457b42b3b3f6b3ULL, 0x15a5423421218421ULL, 0x94d625089c9c4a9cULL, 0xf0663cee1e1e781eULL,
-	0x2252866143431143ULL, 0x76fc93b1c7c73bc7ULL, 0xb32be54ffcfcd7fcULL, 0x2014082404041004ULL,
-	0xb208a2e351515951ULL, 0xbcc72f2599995e99ULL, 0x4fc4da226d6da96dULL, 0x68391a650d0d340dULL,
-	0x8335e979fafacffaULL, 0xb684a369dfdf5bdfULL, 0xd79bfca97e7ee57eULL, 0x3db4481924249024ULL,
-	0xc5d776fe3b3bec3bULL, 0x313d4b9aabab96abULL, 0x3ed181f0cece1fceULL, 0x8855229911114411ULL,
-	0x0c8903838f8f068fULL, 0x4a6b9c044e4e254eULL, 0xd1517366b7b7e6b7ULL, 0x0b60cbe0ebeb8bebULL,
-	0xfdcc78c13c3cf03cULL, 0x7cbf1ffd81813e81ULL, 0xd4fe354094946a94ULL, 0xeb0cf31cf7f7fbf7ULL,
-	0xa1676f18b9b9deb9ULL, 0x985f268b13134c13ULL, 0x7d9c58512c2cb02cULL, 0xd6b8bb05d3d36bd3ULL,
-	0x6b5cd38ce7e7bbe7ULL, 0x57cbdc396e6ea56eULL, 0x6ef395aac4c437c4ULL, 0x180f061b03030c03ULL,
-	0x8a13acdc56564556ULL, 0x1a49885e44440d44ULL, 0xdf9efea07f7fe17fULL, 0x21374f88a9a99ea9ULL,
-	0x4d8254672a2aa82aULL, 0xb16d6b0abbbbd6bbULL, 0x46e29f87c1c123c1ULL, 0xa202a6f153535153ULL,
-	0xae8ba572dcdc57dcULL, 0x582716530b0b2c0bULL, 0x9cd327019d9d4e9dULL, 0x47c1d82b6c6cad6cULL,
-	0x95f562a43131c431ULL, 0x87b9e8f37474cd74ULL, 0xe309f115f6f6fff6ULL, 0x0a438c4c46460546ULL,
-	0x092645a5acac8aacULL, 0x3c970fb589891e89ULL, 0xa04428b414145014ULL, 0x5b42dfbae1e1a3e1ULL,
-	0xb04e2ca616165816ULL, 0xcdd274f73a3ae83aULL, 0x6fd0d2066969b969ULL, 0x482d124109092409ULL,
-	0xa7ade0d77070dd70ULL, 0xd954716fb6b6e2b6ULL, 0xceb7bd1ed0d067d0ULL, 0x3b7ec7d6eded93edULL,
-	0x2edb85e2cccc17ccULL, 0x2a57846842421542ULL, 0xb4c22d2c98985a98ULL, 0x490e55eda4a4aaa4ULL,
-	0x5d8850752828a028ULL, 0xda31b8865c5c6d5cULL, 0x933fed6bf8f8c7f8ULL, 0x44a411c286862286ULL,
-};
-
-static const uint64_t C5[256] = {
-	0x18c07830d8181860ULL, 0x2305af462623238cULL, 0xc67ef991b8c6c63fULL, 0xe8136fcdfbe8e887ULL,
-	0x874ca113cb878726ULL, 0xb8a9626d11b8b8daULL, 0x0108050209010104ULL, 0x4f426e9e0d4f4f21ULL,
-	0x36adee6c9b3636d8ULL, 0xa6590451ffa6a6a2ULL, 0xd2debdb90cd2d26fULL, 0xf5fb06f70ef5f5f3ULL,
-	0x79ef80f2967979f9ULL, 0x6f5fcede306f6fa1ULL, 0x91fcef3f6d91917eULL, 0x52aa07a4f8525255ULL,
-	0x6027fdc04760609dULL, 0xbc89766535bcbccaULL, 0x9baccd2b379b9b56ULL, 0x8e048c018a8e8e02ULL,
-	0xa371155bd2a3a3b6ULL, 0x0c603c186c0c0c30ULL, 0x7bff8af6847b7bf1ULL, 0x35b5e16a803535d4ULL,
-	0x1de8693af51d1d74ULL, 0xe05347ddb3e0e0a7ULL, 0xd7f6acb321d7d77bULL, 0xc25eed999cc2c22fULL,
-	0x2e6d965c432e2eb8ULL, 0x4b627a96294b4b31ULL, 0xfea321e15dfefedfULL, 0x578216aed5575741ULL,
-	0x15a8412abd151554ULL, 0x779fb6eee87777c1ULL, 0x37a5eb6e923737dcULL, 0xe57b56d79ee5e5b3ULL,
-	0x9f8cd923139f9f46ULL, 0xf0d317fd23f0f0e7ULL, 0x4a6a7f94204a4a35ULL, 0xda9e95a944dada4fULL,
-	0x58fa25b0a258587dULL, 0xc906ca8fcfc9c903ULL, 0x29558d527c2929a4ULL, 0x0a5022145a0a0a28ULL,
-	0xb1e14f7f50b1b1feULL, 0xa0691a5dc9a0a0baULL, 0x6b7fdad6146b6bb1ULL, 0x855cab17d985852eULL,
-	0xbd8173673cbdbdceULL, 0x5dd234ba8f5d5d69ULL, 0x1080502090101040ULL, 0xf4f303f507f4f4f7ULL,
-	0xcb16c08bddcbcb0bULL, 0x3eedc67cd33e3ef8ULL, 0x0528110a2d050514ULL, 0x671fe6ce78676781ULL,
-	0xe47353d597e4e4b7ULL, 0x2725bb4e0227279cULL, 0x4132588273414119ULL, 0x8b2c9d0ba78b8b16ULL,
-	0xa7510153f6a7a7a6ULL, 0x7dcf94fab27d7de9ULL, 0x95dcfb374995956eULL, 0xd88e9fad56d8d847ULL,
-	0xfb8b30eb70fbfbcbULL, 0xee2371c1cdeeee9fULL, 0x7cc791f8bb7c7cedULL, 0x6617e3cc71666685ULL,
-	0xdda68ea77bdddd53ULL, 0x17b84b2eaf17175cULL, 0x4702468e45474701ULL, 0x9e84dc211a9e9e42ULL,
-	0xca1ec589d4caca0fULL, 0x2d75995a582d2db4ULL, 0xbf9179632ebfbfc6ULL, 0x07381b0e3f07071cULL,
-	0xad012347acadad8eULL, 0x5aea2fb4b05a5a75ULL, 0x836cb51bef838336ULL, 0x3385ff66b63333ccULL,
-	0x633ff2c65c636391ULL, 0x02100a0412020208ULL, 0xaa39384993aaaa92ULL, 0x71afa8e2de7171d9ULL,
-	0xc80ecf8dc6c8c807ULL, 0x19c87d32d1191964ULL, 0x497270923b494939ULL, 0xd9869aaf5fd9d943ULL,
-	0xf2c31df931f2f2efULL, 0xe34b48dba8e3e3abULL, 0x5be22ab6b95b5b71ULL, 0x8834920dbc88881aULL,
-	0x9aa4c8293e9a9a52ULL, 0x262dbe4c0b262698ULL, 0x328dfa64bf3232c8ULL, 0xb0e94a7d59b0b0faULL,
-	0xe91b6acff2e9e983ULL, 0x0f78331e770f0f3cULL, 0xd5e6a6b733d5d573ULL, 0x8074ba1df480803aULL,
-	0xbe997c6127bebec2ULL, 0xcd26de87ebcdcd13ULL, 0x34bde468893434d0ULL, 0x487a75903248483dULL,
-	0xffab24e354ffffdbULL, 0x7af78ff48d7a7af5ULL, 0x90f4ea3d6490907aULL, 0x5fc23ebe9d5f5f61ULL,
-	0x201da0403d202080ULL, 0x6867d5d00f6868bdULL, 0x1ad07234ca1a1a68ULL, 0xae192c41b7aeae82ULL,
-	0xb4c95e757db4b4eaULL, 0x549a19a8ce54544dULL, 0x93ece53b7f939376ULL, 0x220daa442f222288ULL,
-	0x6407e9c86364648dULL, 0xf1db12ff2af1f1e3ULL, 0x73bfa2e6cc7373d1ULL, 0x12905a2482121248ULL,
-	0x403a5d807a40401dULL, 0x0840281048080820ULL, 0xc356e89b95c3c32bULL, 0xec337bc5dfecec97ULL,
-	0xdb9690ab4ddbdb4bULL, 0xa1611f5fc0a1a1beULL, 0x8d1c8307918d8d0eULL, 0x3df5c97ac83d3df4ULL,
-	0x97ccf1335b979766ULL, 0x0000000000000000ULL, 0xcf36d483f9cfcf1bULL, 0x2b4587566e2b2bacULL,
-	0x7697b3ece17676c5ULL, 0x8264b019e6828232ULL, 0xd6fea9b128d6d67fULL, 0x1bd87736c31b1b6cULL,
-	0xb5c15b7774b5b5eeULL, 0xaf112943beafaf86ULL, 0x6a77dfd41d6a6ab5ULL, 0x50ba0da0ea50505dULL,
-	0x45124c8a57454509ULL, 0xf3cb18fb38f3f3ebULL, 0x309df060ad3030c0ULL, 0xef2b74c3c4efef9bULL,
-	0x3fe5c37eda3f3ffcULL, 0x55921caac7555549ULL, 0xa2791059dba2a2b2ULL, 0xea0365c9e9eaea8fULL,
-	0x650fecca6a656589ULL, 0xbab9686903babad2ULL, 0x2f65935e4a2f2fbcULL, 0xc04ee79d8ec0c027ULL,
-	0xdebe81a160dede5fULL, 0x1ce06c38fc1c1c70ULL, 0xfdbb2ee746fdfdd3ULL, 0x4d52649a1f4d4d29ULL,
-	0x92e4e03976929272ULL, 0x758fbceafa7575c9ULL, 0x06301e0c36060618ULL, 0x8a249809ae8a8a12ULL,
-	0xb2f940794bb2b2f2ULL, 0xe66359d185e6e6bfULL, 0x0e70361c7e0e0e38ULL, 0x1ff8633ee71f1f7cULL,
-	0x6237f7c455626295ULL, 0xd4eea3b53ad4d477ULL, 0xa829324d81a8a89aULL, 0x96c4f43152969662ULL,
-	0xf99b3aef62f9f9c3ULL, 0xc566f697a3c5c533ULL, 0x2535b14a10252594ULL, 0x59f220b2ab595979ULL,
-	0x8454ae15d084842aULL, 0x72b7a7e4c57272d5ULL, 0x39d5dd72ec3939e4ULL, 0x4c5a6198164c4c2dULL,
-	0x5eca3bbc945e5e65ULL, 0x78e785f09f7878fdULL, 0x38ddd870e53838e0ULL, 0x8c148605988c8c0aULL,
-	0xd1c6b2bf17d1d163ULL, 0xa5410b57e4a5a5aeULL, 0xe2434dd9a1e2e2afULL, 0x612ff8c24e616199ULL,
-	0xb3f1457b42b3b3f6ULL, 0x2115a54234212184ULL, 0x9c94d625089c9c4aULL, 0x1ef0663cee1e1e78ULL,
-	0x4322528661434311ULL, 0xc776fc93b1c7c73bULL, 0xfcb32be54ffcfcd7ULL, 0x0420140824040410ULL,
-	0x51b208a2e3515159ULL, 0x99bcc72f2599995eULL, 0x6d4fc4da226d6da9ULL, 0x0d68391a650d0d34ULL,
-	0xfa8335e979fafacfULL, 0xdfb684a369dfdf5bULL, 0x7ed79bfca97e7ee5ULL, 0x243db44819242490ULL,
-	0x3bc5d776fe3b3becULL, 0xab313d4b9aabab96ULL, 0xce3ed181f0cece1fULL, 0x1188552299111144ULL,
-	0x8f0c8903838f8f06ULL, 0x4e4a6b9c044e4e25ULL, 0xb7d1517366b7b7e6ULL, 0xeb0b60cbe0ebeb8bULL,
-	0x3cfdcc78c13c3cf0ULL, 0x817cbf1ffd81813eULL, 0x94d4fe354094946aULL, 0xf7eb0cf31cf7f7fbULL,
-	0xb9a1676f18b9b9deULL, 0x13985f268b13134cULL, 0x2c7d9c58512c2cb0ULL, 0xd3d6b8bb05d3d36bULL,
-	0xe76b5cd38ce7e7bbULL, 0x6e57cbdc396e6ea5ULL, 0xc46ef395aac4c437ULL, 0x03180f061b03030cULL,
-	0x568a13acdc565645ULL, 0x441a49885e44440dULL, 0x7fdf9efea07f7fe1ULL, 0xa921374f88a9a99eULL,
-	0x2a4d8254672a2aa8ULL, 0xbbb16d6b0abbbbd6ULL, 0xc146e29f87c1c123ULL, 0x53a202a6f1535351ULL,
-	0xdcae8ba572dcdc57ULL, 0x0b582716530b0b2cULL, 0x9d9cd327019d9d4eULL, 0x6c47c1d82b6c6cadULL,
-	0x3195f562a43131c4ULL, 0x7487b9e8f37474cdULL, 0xf6e309f115f6f6ffULL, 0x460a438c4c464605ULL,
-	0xac092645a5acac8aULL, 0x893c970fb589891eULL, 0x14a04428b4141450ULL, 0xe15b42dfbae1e1a3ULL,
-	0x16b04e2ca6161658ULL, 0x3acdd274f73a3ae8ULL, 0x696fd0d2066969b9ULL, 0x09482d1241090924ULL,
-	0x70a7ade0d77070ddULL, 0xb6d954716fb6b6e2ULL, 0xd0ceb7bd1ed0d067ULL, 0xed3b7ec7d6eded93ULL,
-	0xcc2edb85e2cccc17ULL, 0x422a578468424215ULL, 0x98b4c22d2c98985aULL, 0xa4490e55eda4a4aaULL,
-	0x285d8850752828a0ULL, 0x5cda31b8865c5c6dULL, 0xf8933fed6bf8f8c7ULL, 0x8644a411c2868622ULL,
-};
-
-static const uint64_t C6[256] = {
-	0x6018c07830d81818ULL, 0x8c2305af46262323ULL, 0x3fc67ef991b8c6c6ULL, 0x87e8136fcdfbe8e8ULL,
-	0x26874ca113cb8787ULL, 0xdab8a9626d11b8b8ULL, 0x0401080502090101ULL, 0x214f426e9e0d4f4fULL,
-	0xd836adee6c9b3636ULL, 0xa2a6590451ffa6a6ULL, 0x6fd2debdb90cd2d2ULL, 0xf3f5fb06f70ef5f5ULL,
-	0xf979ef80f2967979ULL, 0xa16f5fcede306f6fULL, 0x7e91fcef3f6d9191ULL, 0x5552aa07a4f85252ULL,
-	0x9d6027fdc0476060ULL, 0xcabc89766535bcbcULL, 0x569baccd2b379b9bULL, 0x028e048c018a8e8eULL,
-	0xb6a371155bd2a3a3ULL, 0x300c603c186c0c0cULL, 0xf17bff8af6847b7bULL, 0xd435b5e16a803535ULL,
-	0x741de8693af51d1dULL, 0xa7e05347ddb3e0e0ULL, 0x7bd7f6acb321d7d7ULL, 0x2fc25eed999cc2c2ULL,
-	0xb82e6d965c432e2eULL, 0x314b627a96294b4bULL, 0xdffea321e15dfefeULL, 0x41578216aed55757ULL,
-	0x5415a8412abd1515ULL, 0xc1779fb6eee87777ULL, 0xdc37a5eb6e923737ULL, 0xb3e57b56d79ee5e5ULL,
-	0x469f8cd923139f9fULL, 0xe7f0d317fd23f0f0ULL, 0x354a6a7f94204a4aULL, 0x4fda9e95a944dadaULL,
-	0x7d58fa25b0a25858ULL, 0x03c906ca8fcfc9c9ULL, 0xa429558d527c2929ULL, 0x280a5022145a0a0aULL,
-	0xfeb1e14f7f50b1b1ULL, 0xbaa0691a5dc9a0a0ULL, 0xb16b7fdad6146b6bULL, 0x2e855cab17d98585ULL,
-	0xcebd8173673cbdbdULL, 0x695dd234ba8f5d5dULL, 0x4010805020901010ULL, 0xf7f4f303f507f4f4ULL,
-	0x0bcb16c08bddcbcbULL, 0xf83eedc67cd33e3eULL, 0x140528110a2d0505ULL, 0x81671fe6ce786767ULL,
-	0xb7e47353d597e4e4ULL, 0x9c2725bb4e022727ULL, 0x1941325882734141ULL, 0x168b2c9d0ba78b8bULL,
-	0xa6a7510153f6a7a7ULL, 0xe97dcf94fab27d7dULL, 0x6e95dcfb37499595ULL, 0x47d88e9fad56d8d8ULL,
-	0xcbfb8b30eb70fbfbULL, 0x9fee2371c1cdeeeeULL, 0xed7cc791f8bb7c7cULL, 0x856617e3cc716666ULL,
-	0x53dda68ea77bddddULL, 0x5c17b84b2eaf1717ULL, 0x014702468e454747ULL, 0x429e84dc211a9e9eULL,
-	0x0fca1ec589d4cacaULL, 0xb42d75995a582d2dULL, 0xc6bf9179632ebfbfULL, 0x1c07381b0e3f0707ULL,
-	0x8ead012347acadadULL, 0x755aea2fb4b05a5aULL, 0x36836cb51bef8383ULL, 0xcc3385ff66b63333ULL,
-	0x91633ff2c65c6363ULL, 0x0802100a04120202ULL, 0x92aa39384993aaaaULL, 0xd971afa8e2de7171ULL,
-	0x07c80ecf8dc6c8c8ULL, 0x6419c87d32d11919ULL, 0x39497270923b4949ULL, 0x43d9869aaf5fd9d9ULL,
-	0xeff2c31df931f2f2ULL, 0xabe34b48dba8e3e3ULL, 0x715be22ab6b95b5bULL, 0x1a8834920dbc8888ULL,
-	0x529aa4c8293e9a9aULL, 0x98262dbe4c0b2626ULL, 0xc8328dfa64bf3232ULL, 0xfab0e94a7d59b0b0ULL,
-	0x83e91b6acff2e9e9ULL, 0x3c0f78331e770f0fULL, 0x73d5e6a6b733d5d5ULL, 0x3a8074ba1df48080ULL,
-	0xc2be997c6127bebeULL, 0x13cd26de87ebcdcdULL, 0xd034bde468893434ULL, 0x3d487a7590324848ULL,
-	0xdbffab24e354ffffULL, 0xf57af78ff48d7a7aULL, 0x7a90f4ea3d649090ULL, 0x615fc23ebe9d5f5fULL,
-	0x80201da0403d2020ULL, 0xbd6867d5d00f6868ULL, 0x681ad07234ca1a1aULL, 0x82ae192c41b7aeaeULL,
-	0xeab4c95e757db4b4ULL, 0x4d549a19a8ce5454ULL, 0x7693ece53b7f9393ULL, 0x88220daa442f2222ULL,
-	0x8d6407e9c8636464ULL, 0xe3f1db12ff2af1f1ULL, 0xd173bfa2e6cc7373ULL, 0x4812905a24821212ULL,
-	0x1d403a5d807a4040ULL, 0x2008402810480808ULL, 0x2bc356e89b95c3c3ULL, 0x97ec337bc5dfececULL,
-	0x4bdb9690ab4ddbdbULL, 0xbea1611f5fc0a1a1ULL, 0x0e8d1c8307918d8dULL, 0xf43df5c97ac83d3dULL,
-	0x6697ccf1335b9797ULL, 0x0000000000000000ULL, 0x1bcf36d483f9cfcfULL, 0xac2b4587566e2b2bULL,
-	0xc57697b3ece17676ULL, 0x328264b019e68282ULL, 0x7fd6fea9b128d6d6ULL, 0x6c1bd87736c31b1bULL,
-	0xeeb5c15b7774b5b5ULL, 0x86af112943beafafULL, 0xb56a77dfd41d6a6aULL, 0x5d50ba0da0ea5050ULL,
-	0x0945124c8a574545ULL, 0xebf3cb18fb38f3f3ULL, 0xc0309df060ad3030ULL, 0x9bef2b74c3c4efefULL,
-	0xfc3fe5c37eda3f3fULL, 0x4955921caac75555ULL, 0xb2a2791059dba2a2ULL, 0x8fea0365c9e9eaeaULL,
-	0x89650fecca6a6565ULL, 0xd2bab9686903babaULL, 0xbc2f65935e4a2f2fULL, 0x27c04ee79d8ec0c0ULL,
-	0x5fdebe81a160dedeULL, 0x701ce06c38fc1c1cULL, 0xd3fdbb2ee746fdfdULL, 0x294d52649a1f4d4dULL,
-	0x7292e4e039769292ULL, 0xc9758fbceafa7575ULL, 0x1806301e0c360606ULL, 0x128a249809ae8a8aULL,
-	0xf2b2f940794bb2b2ULL, 0xbfe66359d185e6e6ULL, 0x380e70361c7e0e0eULL, 0x7c1ff8633ee71f1fULL,
-	0x956237f7c4556262ULL, 0x77d4eea3b53ad4d4ULL, 0x9aa829324d81a8a8ULL, 0x6296c4f431529696ULL,
-	0xc3f99b3aef62f9f9ULL, 0x33c566f697a3c5c5ULL, 0x942535b14a102525ULL, 0x7959f220b2ab5959ULL,
-	0x2a8454ae15d08484ULL, 0xd572b7a7e4c57272ULL, 0xe439d5dd72ec3939ULL, 0x2d4c5a6198164c4cULL,
-	0x655eca3bbc945e5eULL, 0xfd78e785f09f7878ULL, 0xe038ddd870e53838ULL, 0x0a8c148605988c8cULL,
-	0x63d1c6b2bf17d1d1ULL, 0xaea5410b57e4a5a5ULL, 0xafe2434dd9a1e2e2ULL, 0x99612ff8c24e6161ULL,
-	0xf6b3f1457b42b3b3ULL, 0x842115a542342121ULL, 0x4a9c94d625089c9cULL, 0x781ef0663cee1e1eULL,
-	0x1143225286614343ULL, 0x3bc776fc93b1c7c7ULL, 0xd7fcb32be54ffcfcULL, 0x1004201408240404ULL,
-	0x5951b208a2e35151ULL, 0x5e99bcc72f259999ULL, 0xa96d4fc4da226d6dULL, 0x340d68391a650d0dULL,
-	0xcffa8335e979fafaULL, 0x5bdfb684a369dfdfULL, 0xe57ed79bfca97e7eULL, 0x90243db448192424ULL,
-	0xec3bc5d776fe3b3bULL, 0x96ab313d4b9aababULL, 0x1fce3ed181f0ceceULL, 0x4411885522991111ULL,
-	0x068f0c8903838f8fULL, 0x254e4a6b9c044e4eULL, 0xe6b7d1517366b7b7ULL, 0x8beb0b60cbe0ebebULL,
-	0xf03cfdcc78c13c3cULL, 0x3e817cbf1ffd8181ULL, 0x6a94d4fe35409494ULL, 0xfbf7eb0cf31cf7f7ULL,
-	0xdeb9a1676f18b9b9ULL, 0x4c13985f268b1313ULL, 0xb02c7d9c58512c2cULL, 0x6bd3d6b8bb05d3d3ULL,
-	0xbbe76b5cd38ce7e7ULL, 0xa56e57cbdc396e6eULL, 0x37c46ef395aac4c4ULL, 0x0c03180f061b0303ULL,
-	0x45568a13acdc5656ULL, 0x0d441a49885e4444ULL, 0xe17fdf9efea07f7fULL, 0x9ea921374f88a9a9ULL,
-	0xa82a4d8254672a2aULL, 0xd6bbb16d6b0abbbbULL, 0x23c146e29f87c1c1ULL, 0x5153a202a6f15353ULL,
-	0x57dcae8ba572dcdcULL, 0x2c0b582716530b0bULL, 0x4e9d9cd327019d9dULL, 0xad6c47c1d82b6c6cULL,
-	0xc43195f562a43131ULL, 0xcd7487b9e8f37474ULL, 0xfff6e309f115f6f6ULL, 0x05460a438c4c4646ULL,
-	0x8aac092645a5acacULL, 0x1e893c970fb58989ULL, 0x5014a04428b41414ULL, 0xa3e15b42dfbae1e1ULL,
-	0x5816b04e2ca61616ULL, 0xe83acdd274f73a3aULL, 0xb9696fd0d2066969ULL, 0x2409482d12410909ULL,
-	0xdd70a7ade0d77070ULL, 0xe2b6d954716fb6b6ULL, 0x67d0ceb7bd1ed0d0ULL, 0x93ed3b7ec7d6ededULL,
-	0x17cc2edb85e2ccccULL, 0x15422a5784684242ULL, 0x5a98b4c22d2c9898ULL, 0xaaa4490e55eda4a4ULL,
-	0xa0285d8850752828ULL, 0x6d5cda31b8865c5cULL, 0xc7f8933fed6bf8f8ULL, 0x228644a411c28686ULL,
-};
-
-static const uint64_t C7[256] = {
-	0x186018c07830d818ULL, 0x238c2305af462623ULL, 0xc63fc67ef991b8c6ULL, 0xe887e8136fcdfbe8ULL,
-	0x8726874ca113cb87ULL, 0xb8dab8a9626d11b8ULL, 0x0104010805020901ULL, 0x4f214f426e9e0d4fULL,
-	0x36d836adee6c9b36ULL, 0xa6a2a6590451ffa6ULL, 0xd26fd2debdb90cd2ULL, 0xf5f3f5fb06f70ef5ULL,
-	0x79f979ef80f29679ULL, 0x6fa16f5fcede306fULL, 0x917e91fcef3f6d91ULL, 0x525552aa07a4f852ULL,
-	0x609d6027fdc04760ULL, 0xbccabc89766535bcULL, 0x9b569baccd2b379bULL, 0x8e028e048c018a8eULL,
-	0xa3b6a371155bd2a3ULL, 0x0c300c603c186c0cULL, 0x7bf17bff8af6847bULL, 0x35d435b5e16a8035ULL,
-	0x1d741de8693af51dULL, 0xe0a7e05347ddb3e0ULL, 0xd77bd7f6acb321d7ULL, 0xc22fc25eed999cc2ULL,
-	0x2eb82e6d965c432eULL, 0x4b314b627a96294bULL, 0xfedffea321e15dfeULL, 0x5741578216aed557ULL,
-	0x155415a8412abd15ULL, 0x77c1779fb6eee877ULL, 0x37dc37a5eb6e9237ULL, 0xe5b3e57b56d79ee5ULL,
-	0x9f469f8cd923139fULL, 0xf0e7f0d317fd23f0ULL, 0x4a354a6a7f94204aULL, 0xda4fda9e95a944daULL,
-	0x587d58fa25b0a258ULL, 0xc903c906ca8fcfc9ULL, 0x29a429558d527c29ULL, 0x0a280a5022145a0aULL,
-	0xb1feb1e14f7f50b1ULL, 0xa0baa0691a5dc9a0ULL, 0x6bb16b7fdad6146bULL, 0x852e855cab17d985ULL,
-	0xbdcebd8173673cbdULL, 0x5d695dd234ba8f5dULL, 0x1040108050209010ULL, 0xf4f7f4f303f507f4ULL,
-	0xcb0bcb16c08bddcbULL, 0x3ef83eedc67cd33eULL, 0x05140528110a2d05ULL, 0x6781671fe6ce7867ULL,
-	0xe4b7e47353d597e4ULL, 0x279c2725bb4e0227ULL, 0x4119413258827341ULL, 0x8b168b2c9d0ba78bULL,
-	0xa7a6a7510153f6a7ULL, 0x7de97dcf94fab27dULL, 0x956e95dcfb374995ULL, 0xd847d88e9fad56d8ULL,
-	0xfbcbfb8b30eb70fbULL, 0xee9fee2371c1cdeeULL, 0x7ced7cc791f8bb7cULL, 0x66856617e3cc7166ULL,
-	0xdd53dda68ea77bddULL, 0x175c17b84b2eaf17ULL, 0x47014702468e4547ULL, 0x9e429e84dc211a9eULL,
-	0xca0fca1ec589d4caULL, 0x2db42d75995a582dULL, 0xbfc6bf9179632ebfULL, 0x071c07381b0e3f07ULL,
-	0xad8ead012347acadULL, 0x5a755aea2fb4b05aULL, 0x8336836cb51bef83ULL, 0x33cc3385ff66b633ULL,
-	0x6391633ff2c65c63ULL, 0x020802100a041202ULL, 0xaa92aa39384993aaULL, 0x71d971afa8e2de71ULL,
-	0xc807c80ecf8dc6c8ULL, 0x196419c87d32d119ULL, 0x4939497270923b49ULL, 0xd943d9869aaf5fd9ULL,
-	0xf2eff2c31df931f2ULL, 0xe3abe34b48dba8e3ULL, 0x5b715be22ab6b95bULL, 0x881a8834920dbc88ULL,
-	0x9a529aa4c8293e9aULL, 0x2698262dbe4c0b26ULL, 0x32c8328dfa64bf32ULL, 0xb0fab0e94a7d59b0ULL,
-	0xe983e91b6acff2e9ULL, 0x0f3c0f78331e770fULL, 0xd573d5e6a6b733d5ULL, 0x803a8074ba1df480ULL,
-	0xbec2be997c6127beULL, 0xcd13cd26de87ebcdULL, 0x34d034bde4688934ULL, 0x483d487a75903248ULL,
-	0xffdbffab24e354ffULL, 0x7af57af78ff48d7aULL, 0x907a90f4ea3d6490ULL, 0x5f615fc23ebe9d5fULL,
-	0x2080201da0403d20ULL, 0x68bd6867d5d00f68ULL, 0x1a681ad07234ca1aULL, 0xae82ae192c41b7aeULL,
-	0xb4eab4c95e757db4ULL, 0x544d549a19a8ce54ULL, 0x937693ece53b7f93ULL, 0x2288220daa442f22ULL,
-	0x648d6407e9c86364ULL, 0xf1e3f1db12ff2af1ULL, 0x73d173bfa2e6cc73ULL, 0x124812905a248212ULL,
-	0x401d403a5d807a40ULL, 0x0820084028104808ULL, 0xc32bc356e89b95c3ULL, 0xec97ec337bc5dfecULL,
-	0xdb4bdb9690ab4ddbULL, 0xa1bea1611f5fc0a1ULL, 0x8d0e8d1c8307918dULL, 0x3df43df5c97ac83dULL,
-	0x976697ccf1335b97ULL, 0x0000000000000000ULL, 0xcf1bcf36d483f9cfULL, 0x2bac2b4587566e2bULL,
-	0x76c57697b3ece176ULL, 0x82328264b019e682ULL, 0xd67fd6fea9b128d6ULL, 0x1b6c1bd87736c31bULL,
-	0xb5eeb5c15b7774b5ULL, 0xaf86af112943beafULL, 0x6ab56a77dfd41d6aULL, 0x505d50ba0da0ea50ULL,
-	0x450945124c8a5745ULL, 0xf3ebf3cb18fb38f3ULL, 0x30c0309df060ad30ULL, 0xef9bef2b74c3c4efULL,
-	0x3ffc3fe5c37eda3fULL, 0x554955921caac755ULL, 0xa2b2a2791059dba2ULL, 0xea8fea0365c9e9eaULL,
-	0x6589650fecca6a65ULL, 0xbad2bab9686903baULL, 0x2fbc2f65935e4a2fULL, 0xc027c04ee79d8ec0ULL,
-	0xde5fdebe81a160deULL, 0x1c701ce06c38fc1cULL, 0xfdd3fdbb2ee746fdULL, 0x4d294d52649a1f4dULL,
-	0x927292e4e0397692ULL, 0x75c9758fbceafa75ULL, 0x061806301e0c3606ULL, 0x8a128a249809ae8aULL,
-	0xb2f2b2f940794bb2ULL, 0xe6bfe66359d185e6ULL, 0x0e380e70361c7e0eULL, 0x1f7c1ff8633ee71fULL,
-	0x62956237f7c45562ULL, 0xd477d4eea3b53ad4ULL, 0xa89aa829324d81a8ULL, 0x966296c4f4315296ULL,
-	0xf9c3f99b3aef62f9ULL, 0xc533c566f697a3c5ULL, 0x25942535b14a1025ULL, 0x597959f220b2ab59ULL,
-	0x842a8454ae15d084ULL, 0x72d572b7a7e4c572ULL, 0x39e439d5dd72ec39ULL, 0x4c2d4c5a6198164cULL,
-	0x5e655eca3bbc945eULL, 0x78fd78e785f09f78ULL, 0x38e038ddd870e538ULL, 0x8c0a8c148605988cULL,
-	0xd163d1c6b2bf17d1ULL, 0xa5aea5410b57e4a5ULL, 0xe2afe2434dd9a1e2ULL, 0x6199612ff8c24e61ULL,
-	0xb3f6b3f1457b42b3ULL, 0x21842115a5423421ULL, 0x9c4a9c94d625089cULL, 0x1e781ef0663cee1eULL,
-	0x4311432252866143ULL, 0xc73bc776fc93b1c7ULL, 0xfcd7fcb32be54ffcULL, 0x0410042014082404ULL,
-	0x515951b208a2e351ULL, 0x995e99bcc72f2599ULL, 0x6da96d4fc4da226dULL, 0x0d340d68391a650dULL,
-	0xfacffa8335e979faULL, 0xdf5bdfb684a369dfULL, 0x7ee57ed79bfca97eULL, 0x2490243db4481924ULL,
-	0x3bec3bc5d776fe3bULL, 0xab96ab313d4b9aabULL, 0xce1fce3ed181f0ceULL, 0x1144118855229911ULL,
-	0x8f068f0c8903838fULL, 0x4e254e4a6b9c044eULL, 0xb7e6b7d1517366b7ULL, 0xeb8beb0b60cbe0ebULL,
-	0x3cf03cfdcc78c13cULL, 0x813e817cbf1ffd81ULL, 0x946a94d4fe354094ULL, 0xf7fbf7eb0cf31cf7ULL,
-	0xb9deb9a1676f18b9ULL, 0x134c13985f268b13ULL, 0x2cb02c7d9c58512cULL, 0xd36bd3d6b8bb05d3ULL,
-	0xe7bbe76b5cd38ce7ULL, 0x6ea56e57cbdc396eULL, 0xc437c46ef395aac4ULL, 0x030c03180f061b03ULL,
-	0x5645568a13acdc56ULL, 0x440d441a49885e44ULL, 0x7fe17fdf9efea07fULL, 0xa99ea921374f88a9ULL,
-	0x2aa82a4d8254672aULL, 0xbbd6bbb16d6b0abbULL, 0xc123c146e29f87c1ULL, 0x535153a202a6f153ULL,
-	0xdc57dcae8ba572dcULL, 0x0b2c0b582716530bULL, 0x9d4e9d9cd327019dULL, 0x6cad6c47c1d82b6cULL,
-	0x31c43195f562a431ULL, 0x74cd7487b9e8f374ULL, 0xf6fff6e309f115f6ULL, 0x4605460a438c4c46ULL,
-	0xac8aac092645a5acULL, 0x891e893c970fb589ULL, 0x145014a04428b414ULL, 0xe1a3e15b42dfbae1ULL,
-	0x165816b04e2ca616ULL, 0x3ae83acdd274f73aULL, 0x69b9696fd0d20669ULL, 0x092409482d124109ULL,
-	0x70dd70a7ade0d770ULL, 0xb6e2b6d954716fb6ULL, 0xd067d0ceb7bd1ed0ULL, 0xed93ed3b7ec7d6edULL,
-	0xcc17cc2edb85e2ccULL, 0x4215422a57846842ULL, 0x985a98b4c22d2c98ULL, 0xa4aaa4490e55eda4ULL,
-	0x28a0285d88507528ULL, 0x5c6d5cda31b8865cULL, 0xf8c7f8933fed6bf8ULL, 0x86228644a411c286ULL,
-};
-
-static const uint64_t rc[R + 1] = {
-	0x0000000000000000ULL,
-	0x1823c6e887b8014fULL,
-	0x36a6d2f5796f9152ULL,
-	0x60bc9b8ea30c7b35ULL,
-	0x1de0d7c22e4bfe57ULL,
-	0x157737e59ff04adaULL,
-	0x58c9290ab1a06b85ULL,
-	0xbd5d10f4cb3e0567ULL,
-	0xe427418ba77d95d8ULL,
-	0xfbee7c66dd17479eULL,
-	0xca2dbf07ad5a8333ULL,
-};
-
-/* This might not be true for all platforms and compilers. */
-#define SANE_ARRAY_PACKING 1
-
-#if defined(SANE_ARRAY_PACKING) && (defined(ARCH_IS_LITTLE_ENDIAN) || defined(ARCH_IS_BIG_ENDIAN))
-
-#if defined(ARCH_IS_LITTLE_ENDIAN)
-#define LB(n)  do { L[n] = C0[mu[((n+0)%8) * 8 + 7]] \
-	^ C1[mu[((n+7)%8) * 8 + 6]] \
-	^ C2[mu[((n+6)%8) * 8 + 5]] \
-	^ C3[mu[((n+5)%8) * 8 + 4]] \
-	^ C4[mu[((n+4)%8) * 8 + 3]] \
-	^ C5[mu[((n+3)%8) * 8 + 2]] \
-	^ C6[mu[((n+2)%8) * 8 + 1]] \
-	^ C7[mu[((n+1)%8) * 8 + 0]] \
-	; } while (0)
-#else
-#define LB(n)  do { L[n] = C0[mu[((n+0)%8) * 8 + 0]] \
-	^ C1[mu[((n+7)%8) * 8 + 1]] \
-	^ C2[mu[((n+6)%8) * 8 + 2]] \
-	^ C3[mu[((n+5)%8) * 8 + 3]] \
-	^ C4[mu[((n+4)%8) * 8 + 4]] \
-	^ C5[mu[((n+3)%8) * 8 + 5]] \
-	^ C6[mu[((n+2)%8) * 8 + 6]] \
-	^ C7[mu[((n+1)%8) * 8 + 7]] \
-	; } while (0)
-#endif
-
-static void transformMatrix(uint64_t m[8])
-{
-	uint64_t L[8];
-	uint8_t *mu = (uint8_t*)m;
-
-	LB(0);
-	LB(1);
-	LB(2);
-	LB(3);
-	LB(4);
-	LB(5);
-	LB(6);
-	LB(7);
-
-	array_copy64(m, L, 8);
-}
-
-#else
-
-static void transformMatrix(uint64_t m[8])
-{
-	uint64_t L[8];
-
-	L[0] =
-		C0[(int)(m[0] >> 56)       ] ^
-		C1[(int)(m[7] >> 48) & 0xff] ^
-		C2[(int)(m[6] >> 40) & 0xff] ^
-		C3[(int)(m[5] >> 32) & 0xff] ^
-		C4[(int)(m[4] >> 24) & 0xff] ^
-		C5[(int)(m[3] >> 16) & 0xff] ^
-		C6[(int)(m[2] >>  8) & 0xff] ^
-		C7[(int)(m[1]      ) & 0xff];
-	L[1] =
-		C0[(int)(m[1] >> 56)       ] ^
-		C1[(int)(m[0] >> 48) & 0xff] ^
-		C2[(int)(m[7] >> 40) & 0xff] ^
-		C3[(int)(m[6] >> 32) & 0xff] ^
-		C4[(int)(m[5] >> 24) & 0xff] ^
-		C5[(int)(m[4] >> 16) & 0xff] ^
-		C6[(int)(m[3] >>  8) & 0xff] ^
-		C7[(int)(m[2]      ) & 0xff];
-	L[2] =
-		C0[(int)(m[2] >> 56)       ] ^
-		C1[(int)(m[1] >> 48) & 0xff] ^
-		C2[(int)(m[0] >> 40) & 0xff] ^
-		C3[(int)(m[7] >> 32) & 0xff] ^
-		C4[(int)(m[6] >> 24) & 0xff] ^
-		C5[(int)(m[5] >> 16) & 0xff] ^
-		C6[(int)(m[4] >>  8) & 0xff] ^
-		C7[(int)(m[3]      ) & 0xff];
-	L[3] =
-		C0[(int)(m[3] >> 56)       ] ^
-		C1[(int)(m[2] >> 48) & 0xff] ^
-		C2[(int)(m[1] >> 40) & 0xff] ^
-		C3[(int)(m[0] >> 32) & 0xff] ^
-		C4[(int)(m[7] >> 24) & 0xff] ^
-		C5[(int)(m[6] >> 16) & 0xff] ^
-		C6[(int)(m[5] >>  8) & 0xff] ^
-		C7[(int)(m[4]      ) & 0xff];
-	L[4] =
-		C0[(int)(m[4] >> 56)       ] ^
-		C1[(int)(m[3] >> 48) & 0xff] ^
-		C2[(int)(m[2] >> 40) & 0xff] ^
-		C3[(int)(m[1] >> 32) & 0xff] ^
-		C4[(int)(m[0] >> 24) & 0xff] ^
-		C5[(int)(m[7] >> 16) & 0xff] ^
-		C6[(int)(m[6] >>  8) & 0xff] ^
-		C7[(int)(m[5]      ) & 0xff];
-	L[5] =
-		C0[(int)(m[5] >> 56)       ] ^
-		C1[(int)(m[4] >> 48) & 0xff] ^
-		C2[(int)(m[3] >> 40) & 0xff] ^
-		C3[(int)(m[2] >> 32) & 0xff] ^
-		C4[(int)(m[1] >> 24) & 0xff] ^
-		C5[(int)(m[0] >> 16) & 0xff] ^
-		C6[(int)(m[7] >>  8) & 0xff] ^
-		C7[(int)(m[6]      ) & 0xff];
-	L[6] =
-		C0[(int)(m[6] >> 56)       ] ^
-		C1[(int)(m[5] >> 48) & 0xff] ^
-		C2[(int)(m[4] >> 40) & 0xff] ^
-		C3[(int)(m[3] >> 32) & 0xff] ^
-		C4[(int)(m[2] >> 24) & 0xff] ^
-		C5[(int)(m[1] >> 16) & 0xff] ^
-		C6[(int)(m[0] >>  8) & 0xff] ^
-		C7[(int)(m[7]      ) & 0xff];
-	L[7] =
-		C0[(int)(m[7] >> 56)       ] ^
-		C1[(int)(m[6] >> 48) & 0xff] ^
-		C2[(int)(m[5] >> 40) & 0xff] ^
-		C3[(int)(m[4] >> 32) & 0xff] ^
-		C4[(int)(m[3] >> 24) & 0xff] ^
-		C5[(int)(m[2] >> 16) & 0xff] ^
-		C6[(int)(m[1] >>  8) & 0xff] ^
-		C7[(int)(m[0]      ) & 0xff];
-
-	array_copy64(m, L, 8);
-}
-
-#endif
-
-static void inplaceXor(uint64_t dst[8], uint64_t src[8])
-{
-	dst[0] ^= src[0];
-	dst[1] ^= src[1];
-	dst[2] ^= src[2];
-	dst[3] ^= src[3];
-	dst[4] ^= src[4];
-	dst[5] ^= src[5];
-	dst[6] ^= src[6];
-	dst[7] ^= src[7];
-}
-
-/**
- * The core Whirlpool transform.
- */
-static void processBuffer(whirlpool_ctx * const ctx)
-{
-	int i, r;
-	uint64_t K[8];        /* the round key */
-	uint64_t block[8];    /* mu(buffer) */
-	uint64_t state[8];    /* the cipher state */
-	uint64_t L[8];
-	uint8_t *buffer = ctx->buffer;
-
-	/*
-	 * map the buffer to a block:
-	 */
-	for (i = 0; i < 8; i++, buffer += 8) {
-		block[i] =
-			(((uint64_t)buffer[0]        ) << 56) ^
-			(((uint64_t)buffer[1] & 0xffL) << 48) ^
-			(((uint64_t)buffer[2] & 0xffL) << 40) ^
-			(((uint64_t)buffer[3] & 0xffL) << 32) ^
-			(((uint64_t)buffer[4] & 0xffL) << 24) ^
-			(((uint64_t)buffer[5] & 0xffL) << 16) ^
-			(((uint64_t)buffer[6] & 0xffL) <<  8) ^
-			(((uint64_t)buffer[7] & 0xffL)      );
-	}
-
-	/*
-	 * compute and apply K^0 to the cipher state:
-	 */
-	array_copy64(K, ctx->hash, 8);
-	array_copy64(state, block, 8);
-	inplaceXor(state, K);
-
-	/*
-	 * iterate over all rounds:
-	 */
-	for (r = 1; r <= R; r++) {
-		/*
-		 * compute K^r from K^{r-1}:
-		 */
-		transformMatrix(K);
-		K[0] ^= rc[r];
-
-		/*
-		 * apply the r-th round transformation:
-		 */
-		transformMatrix(state);
-		inplaceXor(state, K);
-	}
-	/*
-	 * apply the Miyaguchi-Preneel compression function:
-	 */
-	inplaceXor(ctx->hash, state);
-	inplaceXor(ctx->hash, block);
-}
-
-/**
- * Initialize the hashing state.
- */
-void whirlpool_init(struct whirlpool_ctx * const ctx)
-{
-	int i;
-
-	memset(ctx->bitLength, 0, 32);
-	ctx->bufferBits = ctx->bufferPos = 0;
-	ctx->buffer[0] = 0; /* it's only necessary to cleanup buffer[bufferPos] */
-	for (i = 0; i < 8; i++) {
-		ctx->hash[i] = 0L; /* initial value */
-	}
-}
-
-/**
- * Delivers input data to the hashing algorithm.
- *
- * @param    source        plaintext data to hash.
- * @param    sourceBits    how many bits of plaintext to process.
- *
- * This method maintains the invariant: bufferBits < DIGESTBITS
- */
-void whirlpool_update(struct whirlpool_ctx * const ctx, const uint8_t * const source, uint32_t sourceBytes)
-{
-	/*
-	   sourcePos
-	   |
-	   +-------+-------+-------
-	   ||||||||||||||||||||| source
-	   +-------+-------+-------
-	   +-------+-------+-------+-------+-------+-------
-	   ||||||||||||||||||||||                           buffer
-	   +-------+-------+-------+-------+-------+-------
-	   |
-	   bufferPos
-	   */
-	int sourceBits   = sourceBytes * 8;
-	int sourcePos    = 0; /* index of leftmost source uint8_t containing data (1 to 8 bits). */
-	int sourceGap    = (8 - ((int)sourceBits & 7)) & 7; /* space on source[sourcePos]. */
-	int bufferRem    = ctx->bufferBits & 7; /* occupied bits on buffer[bufferPos]. */
-	int i;
-	uint32_t b, carry;
-	uint8_t *buffer       = ctx->buffer;
-	uint8_t *bitLength    = ctx->bitLength;
-	int bufferBits   = ctx->bufferBits;
-	int bufferPos    = ctx->bufferPos;
-
-	/*
-	 * tally the length of the added data:
-	 */
-	uint64_t value = sourceBits;
-	for (i = 31, carry = 0; i >= 0 && (carry != 0 || value != 0ULL); i--) {
-		carry += bitLength[i] + ((uint32_t)value & 0xff);
-		bitLength[i] = (uint8_t)carry;
-		carry >>= 8;
-		value >>= 8;
-	}
-	/*
-	 * process data in chunks of 8 bits (a more efficient approach would be to take whole-word chunks):
-	 */
-	while (sourceBits > 8) {
-		/* N.B. at least source[sourcePos] and source[sourcePos+1] contain data. */
-		/*
-		 * take a byte from the source:
-		 */
-		b = ((source[sourcePos] << sourceGap) & 0xff) |
-			((source[sourcePos + 1] & 0xff) >> (8 - sourceGap));
-		/*
-		 * process this byte:
-		 */
-		buffer[bufferPos++] |= (uint8_t)(b >> bufferRem);
-		bufferBits += 8 - bufferRem; /* bufferBits = 8*bufferPos; */
-		if (bufferBits == DIGESTBITS) {
-			/*
-			 * process data block:
-			 */
-			processBuffer(ctx);
-			/*
-			 * reset buffer:
-			 */
-			bufferBits = bufferPos = 0;
-		}
-		buffer[bufferPos] = b << (8 - bufferRem);
-		bufferBits += bufferRem;
-		/*
-		 * proceed to remaining data:
-		 */
-		sourceBits -= 8;
-		sourcePos++;
-	}
-	/* now 0 <= sourceBits <= 8;
-	 * furthermore, all data (if any is left) is in source[sourcePos].
-	 */
-	if (sourceBits > 0) {
-		b = (source[sourcePos] << sourceGap) & 0xff; /* bits are left-justified on b. */
-		/*
-		 * process the remaining bits:
-		 */
-		buffer[bufferPos] |= b >> bufferRem;
-	} else {
-		b = 0;
-	}
-	if (bufferRem + sourceBits < 8) {
-		/*
-		 * all remaining data fits on buffer[bufferPos],
-		 * and there still remains some space.
-		 */
-		bufferBits += sourceBits;
-	} else {
-		/*
-		 * buffer[bufferPos] is full:
-		 */
-		bufferPos++;
-		bufferBits += 8 - bufferRem; /* bufferBits = 8*bufferPos; */
-		sourceBits -= 8 - bufferRem;
-		/* now 0 <= sourceBits < 8;
-		 * furthermore, all data (if any is left) is in source[sourcePos].
-		 */
-		if (bufferBits == DIGESTBITS) {
-			/*
-			 * process data block:
-			 */
-			processBuffer(ctx);
-			/*
-			 * reset buffer:
-			 */
-			bufferBits = bufferPos = 0;
-		}
-		buffer[bufferPos] = b << (8 - bufferRem);
-		bufferBits += (int)sourceBits;
-	}
-	ctx->bufferBits   = bufferBits;
-	ctx->bufferPos    = bufferPos;
-}
-
-/**
- * Get the hash value from the hashing state.
- * 
- * This method uses the invariant: bufferBits < DIGESTBITS
- */
-void whirlpool_finalize(struct whirlpool_ctx * const ctx, uint8_t * const result)
-{
-	int i;
-	uint8_t *buffer    = ctx->buffer;
-	uint8_t *bitLength = ctx->bitLength;
-	int bufferBits     = ctx->bufferBits;
-	int bufferPos      = ctx->bufferPos;
-	uint8_t *digest    = result;
-
-	/*
-	 * append a '1'-bit:
-	 */
-	buffer[bufferPos] |= 0x80U >> (bufferBits & 7);
-	bufferPos++; /* all remaining bits on the current uint8_t are set to zero. */
-	/*
-	 * pad with zero bits to complete (N*WBLOCKBITS - LENGTHBITS) bits:
-	 */
-	if (bufferPos > WBLOCKBYTES - LENGTHBYTES) {
-		if (bufferPos < WBLOCKBYTES) {
-			memset(&buffer[bufferPos], 0, WBLOCKBYTES - bufferPos);
-		}
-		/*
-		 * process data block:
-		 */
-		processBuffer(ctx);
-		/*
-		 * reset buffer:
-		 */
-		bufferPos = 0;
-	}
-	if (bufferPos < WBLOCKBYTES - LENGTHBYTES) {
-		memset(&buffer[bufferPos], 0, (WBLOCKBYTES - LENGTHBYTES) - bufferPos);
-	}
-	bufferPos = WBLOCKBYTES - LENGTHBYTES;
-	/*
-	 * append bit length of hashed data:
-	 */
-	memcpy(&buffer[WBLOCKBYTES - LENGTHBYTES], bitLength, LENGTHBYTES);
-	/*
-	 * process data block:
-	 */
-	processBuffer(ctx);
-	/*
-	 * return the completed message digest:
-	 */
-	for (i = 0; i < DIGESTBYTES/8; i++) {
-		digest[0] = (uint8_t)(ctx->hash[i] >> 56);
-		digest[1] = (uint8_t)(ctx->hash[i] >> 48);
-		digest[2] = (uint8_t)(ctx->hash[i] >> 40);
-		digest[3] = (uint8_t)(ctx->hash[i] >> 32);
-		digest[4] = (uint8_t)(ctx->hash[i] >> 24);
-		digest[5] = (uint8_t)(ctx->hash[i] >> 16);
-		digest[6] = (uint8_t)(ctx->hash[i] >>  8);
-		digest[7] = (uint8_t)(ctx->hash[i]      );
-		digest += 8;
-	}
-	ctx->bufferBits   = bufferBits;
-	ctx->bufferPos    = bufferPos;
-}
diff --git a/cbits/whirlpool.h b/cbits/whirlpool.h
deleted file mode 100644
--- a/cbits/whirlpool.h
+++ /dev/null
@@ -1,31 +0,0 @@
-#ifndef CRYPTOHASH_WHIRLPOOL_H
-#define CRYPTOHASH_WHIRLPOOL_H
-
-#include <stdint.h>
-
-/*
- * Whirlpool-specific definitions.
- */
-
-#define DIGESTBYTES 64
-#define DIGESTBITS  (8*DIGESTBYTES) /* 512 */
-
-#define WBLOCKBYTES 64
-#define WBLOCKBITS  (8*WBLOCKBYTES) /* 512 */
-
-#define LENGTHBYTES 32
-#define LENGTHBITS  (8*LENGTHBYTES) /* 256 */
-
-typedef struct whirlpool_ctx {
-	uint8_t  bitLength[LENGTHBYTES]; /* global number of hashed bits (256-bit counter) */
-	uint8_t  buffer[WBLOCKBYTES];    /* buffer of data to hash */
-	uint32_t bufferBits;             /* current number of bits on the buffer */
-	uint32_t bufferPos;              /* current (possibly incomplete) byte slot on the buffer */
-	uint64_t hash[DIGESTBYTES/8];    /* the hashing state */
-} whirlpool_ctx;
-
-void whirlpool_init(struct whirlpool_ctx * const ctx);
-void whirlpool_update(struct whirlpool_ctx * const ctx, const uint8_t * const source, uint32_t len);
-void whirlpool_finalize(struct whirlpool_ctx * const ctx, uint8_t * const result);
-
-#endif
diff --git a/cryptohash.cabal b/cryptohash.cabal
--- a/cryptohash.cabal
+++ b/cryptohash.cabal
@@ -1,8 +1,11 @@
 Name:                cryptohash
-Version:             0.10.0
+Version:             0.11.9
 Description:
+    DEPRECATED: this library is still fully functional, but please use cryptonite for new projects
+    and convert old one to use cryptonite. This is where things are at nowadays.
+    .
     A collection of crypto hashes, with a practical incremental and one-pass, pure APIs,
-    with performance close to the fastest implementations available in others languages.
+    with performance close to the fastest implementations available in other languages.
     .
     The implementations are made in C with a haskell FFI wrapper that hide the C implementation.
     .
@@ -20,7 +23,7 @@
     .
     > import qualified Crypto.Hash.SHA1 as SHA1
     >
-    > main = putStrLn $ show $ SHA1.hash (Data.ByteString.pack [1..256])
+    > main = putStrLn $ show $ SHA1.hash (Data.ByteString.pack [0..255])
     .
     > import qualified Crypto.Hash.SHA3 as SHA3
     >
@@ -38,21 +41,20 @@
 Build-Type:          Simple
 Cabal-Version:       >=1.8
 Homepage:            http://github.com/vincenthz/hs-cryptohash
-data-files:          README.md
 
 extra-source-files:
-  cbits/bitfn.h cbits/md2.h cbits/md4.h cbits/md5.h
-  cbits/ripemd.h cbits/sha1.h cbits/sha256.h cbits/sha512.h cbits/sha3.h
+  cbits/bitfn.h cbits/sha512.h cbits/sha3.h
   cbits/skein.h cbits/skein256.h cbits/skein512.h
-  cbits/tiger.h cbits/whirlpool.h
+  README.md
 
 Library
-  Build-Depends:     base >= 4 && < 6, bytestring, byteable, ghc-prim
+  Build-Depends:     base >= 4 && < 6, bytestring, byteable, cryptonite >= 0.13, memory, ghc-prim
   if impl(ghc >= 7.2.1)
     Extensions:      Trustworthy
   Extensions:        ForeignFunctionInterface
   Exposed-modules:   Crypto.Hash
                      Crypto.Hash.Types
+                     Crypto.MAC
                      Crypto.Hash.SHA1
                      Crypto.Hash.SHA224
                      Crypto.Hash.SHA256
@@ -69,22 +71,13 @@
                      Crypto.Hash.Tiger
                      Crypto.Hash.Whirlpool
                      Crypto.MAC.HMAC
-  Other-modules:     Crypto.Hash.Utils
-                     Crypto.Hash.Utils.Cpu
-                     Crypto.Hash.Internal
-  ghc-options:       -Wall -O2 -optc-O3 -fno-cse -fwarn-tabs
-  C-sources:         cbits/sha1.c
-                     cbits/sha256.c
-                     cbits/sha512.c
+                     Crypto.MAC.SHA3
+  Other-modules:     Crypto.Hash.Internal
+  ghc-options:       -Wall -optc-O3 -fno-cse -fwarn-tabs
+  C-sources:         cbits/sha512.c
                      cbits/sha3.c
-                     cbits/md2.c
-                     cbits/md4.c
-                     cbits/md5.c
-                     cbits/ripemd.c
                      cbits/skein256.c
                      cbits/skein512.c
-                     cbits/tiger.c
-                     cbits/whirlpool.c
   Include-Dirs:      cbits
   if (arch(i386) || arch(x86_64))
     cpp-options: -DARCH_X86
@@ -95,11 +88,12 @@
   Main-Is:           KAT.hs
   Build-depends:     base >= 4 && < 5
                    , bytestring
+                   , byteable
                    , HUnit
                    , QuickCheck >= 2
-                   , test-framework >= 0.3.3
-                   , test-framework-quickcheck2 >= 0.2.9
-                   , test-framework-hunit
+                   , tasty
+                   , tasty-quickcheck
+                   , tasty-hunit
                    , cryptohash
 
 Benchmark bench-hashes
@@ -107,6 +101,12 @@
   hs-source-dirs:    Bench
   type:              exitcode-stdio-1.0
   Build-depends:     base >= 4, bytestring, criterion, cryptohash
+
+Benchmark bench-hmac
+  Main-Is:           BenchHMAC.hs
+  hs-source-dirs:    Bench
+  type:              exitcode-stdio-1.0
+  Build-depends:     base >= 4, bytestring, criterion, cryptohash, byteable
 
 Benchmark bench-api
   Main-Is:           BenchAPI.hs
