cryptohash 0.7.10 → 0.8.0
raw patch · 24 files changed
+703/−174 lines, 24 filesdep +ghc-primdep ~basedep ~bytestringdep ~crypto-apiPVP ok
version bump matches the API change (PVP)
Dependencies added: ghc-prim
Dependency ranges changed: base, bytestring, crypto-api
API changes (from Hackage documentation)
- Crypto.Hash.MD2: data Ctx
- Crypto.Hash.MD4: data Ctx
- Crypto.Hash.MD5: data Ctx
- Crypto.Hash.RIPEMD160: data Ctx
- Crypto.Hash.SHA1: data Ctx
- Crypto.Hash.SHA224: data Ctx
- Crypto.Hash.SHA256: data Ctx
- Crypto.Hash.SHA3: data Ctx
- Crypto.Hash.SHA384: data Ctx
- Crypto.Hash.SHA512: data Ctx
- Crypto.Hash.Skein256: data Ctx
- Crypto.Hash.Skein512: data Ctx
- Crypto.Hash.Tiger: data Ctx
- Crypto.Hash.Whirlpool: data Ctx
+ Crypto.Hash: class HashAlgorithm a
+ Crypto.Hash: data Context a
+ Crypto.Hash: data Digest a
+ Crypto.Hash: data MD2
+ Crypto.Hash: data MD4
+ Crypto.Hash: data MD5
+ Crypto.Hash: data RIPEMD160
+ Crypto.Hash: data SHA1
+ Crypto.Hash: data SHA224
+ Crypto.Hash: data SHA256
+ Crypto.Hash: data SHA384
+ Crypto.Hash: data SHA3_224
+ Crypto.Hash: data SHA3_256
+ Crypto.Hash: data SHA3_384
+ Crypto.Hash: data SHA3_512
+ Crypto.Hash: data SHA512
+ Crypto.Hash: data Skein256_224
+ Crypto.Hash: data Skein256_256
+ Crypto.Hash: data Skein512_224
+ Crypto.Hash: data Skein512_256
+ Crypto.Hash: data Skein512_384
+ Crypto.Hash: data Skein512_512
+ Crypto.Hash: data Tiger
+ Crypto.Hash: data Whirlpool
+ Crypto.Hash: digestToByteString :: Digest a -> ByteString
+ Crypto.Hash: digestToHexByteString :: Digest a -> ByteString
+ Crypto.Hash: hash :: HashAlgorithm a => ByteString -> Digest a
+ Crypto.Hash: hashFinalize :: HashAlgorithm a => Context a -> Digest a
+ Crypto.Hash: hashInit :: HashAlgorithm a => Context a
+ Crypto.Hash: hashUpdate :: HashAlgorithm a => Context a -> ByteString -> Context a
+ Crypto.Hash: hashUpdates :: HashAlgorithm a => Context a -> [ByteString] -> Context a
+ Crypto.Hash: hashlazy :: HashAlgorithm a => ByteString -> Digest a
+ Crypto.Hash: instance HashAlgorithm MD2
+ Crypto.Hash: instance HashAlgorithm MD4
+ Crypto.Hash: instance HashAlgorithm MD5
+ Crypto.Hash: instance HashAlgorithm RIPEMD160
+ Crypto.Hash: instance HashAlgorithm SHA1
+ Crypto.Hash: instance HashAlgorithm SHA224
+ Crypto.Hash: instance HashAlgorithm SHA256
+ Crypto.Hash: instance HashAlgorithm SHA384
+ Crypto.Hash: instance HashAlgorithm SHA3_224
+ Crypto.Hash: instance HashAlgorithm SHA3_256
+ Crypto.Hash: instance HashAlgorithm SHA3_384
+ Crypto.Hash: instance HashAlgorithm SHA3_512
+ Crypto.Hash: instance HashAlgorithm SHA512
+ Crypto.Hash: instance HashAlgorithm Skein256_224
+ Crypto.Hash: instance HashAlgorithm Skein256_256
+ Crypto.Hash: instance HashAlgorithm Skein512_224
+ Crypto.Hash: instance HashAlgorithm Skein512_256
+ Crypto.Hash: instance HashAlgorithm Skein512_384
+ Crypto.Hash: instance HashAlgorithm Skein512_512
+ Crypto.Hash: instance HashAlgorithm Tiger
+ Crypto.Hash: instance HashAlgorithm Whirlpool
+ Crypto.Hash.MD2: newtype Ctx
+ Crypto.Hash.MD2: updates :: Ctx -> [ByteString] -> Ctx
+ Crypto.Hash.MD4: newtype Ctx
+ Crypto.Hash.MD4: updates :: Ctx -> [ByteString] -> Ctx
+ Crypto.Hash.MD5: newtype Ctx
+ Crypto.Hash.MD5: updates :: Ctx -> [ByteString] -> Ctx
+ Crypto.Hash.RIPEMD160: newtype Ctx
+ Crypto.Hash.RIPEMD160: updates :: Ctx -> [ByteString] -> Ctx
+ Crypto.Hash.SHA1: newtype Ctx
+ Crypto.Hash.SHA1: updates :: Ctx -> [ByteString] -> Ctx
+ Crypto.Hash.SHA224: newtype Ctx
+ Crypto.Hash.SHA224: updates :: Ctx -> [ByteString] -> Ctx
+ Crypto.Hash.SHA256: newtype Ctx
+ Crypto.Hash.SHA256: updates :: Ctx -> [ByteString] -> Ctx
+ Crypto.Hash.SHA3: data SHA3
+ Crypto.Hash.SHA3: instance Eq SHA3
+ Crypto.Hash.SHA3: instance Hash Ctx SHA3
+ Crypto.Hash.SHA3: instance Ord SHA3
+ Crypto.Hash.SHA3: instance Serialize SHA3
+ Crypto.Hash.SHA3: instance Show SHA3
+ Crypto.Hash.SHA3: newtype Ctx
+ Crypto.Hash.SHA3: updates :: Ctx -> [ByteString] -> Ctx
+ Crypto.Hash.SHA384: newtype Ctx
+ Crypto.Hash.SHA384: updates :: Ctx -> [ByteString] -> Ctx
+ Crypto.Hash.SHA512: newtype Ctx
+ Crypto.Hash.SHA512: updates :: Ctx -> [ByteString] -> Ctx
+ Crypto.Hash.Skein256: newtype Ctx
+ Crypto.Hash.Skein256: updates :: Ctx -> [ByteString] -> Ctx
+ Crypto.Hash.Skein512: newtype Ctx
+ Crypto.Hash.Skein512: updates :: Ctx -> [ByteString] -> Ctx
+ Crypto.Hash.Tiger: newtype Ctx
+ Crypto.Hash.Tiger: updates :: Ctx -> [ByteString] -> Ctx
+ Crypto.Hash.Types: Context :: ByteString -> Context a
+ Crypto.Hash.Types: Digest :: ByteString -> Digest a
+ Crypto.Hash.Types: class HashAlgorithm a
+ Crypto.Hash.Types: contextToByteString :: Context a -> ByteString
+ Crypto.Hash.Types: digestToByteString :: Digest a -> ByteString
+ Crypto.Hash.Types: hashFinalize :: HashAlgorithm a => Context a -> Digest a
+ Crypto.Hash.Types: hashInit :: HashAlgorithm a => Context a
+ Crypto.Hash.Types: hashUpdates :: HashAlgorithm a => Context a -> [ByteString] -> Context a
+ Crypto.Hash.Types: instance Eq (Digest a)
+ Crypto.Hash.Types: instance Ord (Digest a)
+ Crypto.Hash.Types: instance Show (Digest a)
+ Crypto.Hash.Types: newtype Context a
+ Crypto.Hash.Types: newtype Digest a
+ Crypto.Hash.Whirlpool: newtype Ctx
+ Crypto.Hash.Whirlpool: updates :: Ctx -> [ByteString] -> Ctx
- Crypto.Hash.MD2: Ctx :: !ByteString -> Ctx
+ Crypto.Hash.MD2: Ctx :: ByteString -> Ctx
- Crypto.Hash.MD4: Ctx :: !ByteString -> Ctx
+ Crypto.Hash.MD4: Ctx :: ByteString -> Ctx
- Crypto.Hash.MD5: Ctx :: !ByteString -> Ctx
+ Crypto.Hash.MD5: Ctx :: ByteString -> Ctx
- Crypto.Hash.RIPEMD160: Ctx :: !ByteString -> Ctx
+ Crypto.Hash.RIPEMD160: Ctx :: ByteString -> Ctx
- Crypto.Hash.SHA1: Ctx :: !ByteString -> Ctx
+ Crypto.Hash.SHA1: Ctx :: ByteString -> Ctx
- Crypto.Hash.SHA224: Ctx :: !ByteString -> Ctx
+ Crypto.Hash.SHA224: Ctx :: ByteString -> Ctx
- Crypto.Hash.SHA256: Ctx :: !ByteString -> Ctx
+ Crypto.Hash.SHA256: Ctx :: ByteString -> Ctx
- Crypto.Hash.SHA3: Ctx :: !ByteString -> Ctx
+ Crypto.Hash.SHA3: Ctx :: ByteString -> Ctx
- Crypto.Hash.SHA384: Ctx :: !ByteString -> Ctx
+ Crypto.Hash.SHA384: Ctx :: ByteString -> Ctx
- Crypto.Hash.SHA512: Ctx :: !ByteString -> Ctx
+ Crypto.Hash.SHA512: Ctx :: ByteString -> Ctx
- Crypto.Hash.Skein256: Ctx :: !ByteString -> Ctx
+ Crypto.Hash.Skein256: Ctx :: ByteString -> Ctx
- Crypto.Hash.Skein512: Ctx :: !ByteString -> Ctx
+ Crypto.Hash.Skein512: Ctx :: ByteString -> Ctx
- Crypto.Hash.Tiger: Ctx :: !ByteString -> Ctx
+ Crypto.Hash.Tiger: Ctx :: ByteString -> Ctx
- Crypto.Hash.Whirlpool: Ctx :: !ByteString -> Ctx
+ Crypto.Hash.Whirlpool: Ctx :: ByteString -> Ctx
Files
- Bench/BenchAPI.hs +37/−0
- Crypto/Hash.hs +125/−0
- Crypto/Hash/MD2.hs +22/−9
- Crypto/Hash/MD4.hs +22/−9
- Crypto/Hash/MD5.hs +22/−9
- Crypto/Hash/RIPEMD160.hs +22/−9
- Crypto/Hash/SHA1.hs +22/−9
- Crypto/Hash/SHA224.hs +22/−9
- Crypto/Hash/SHA256.hs +22/−9
- Crypto/Hash/SHA3.hs +47/−9
- Crypto/Hash/SHA384.hs +22/−9
- Crypto/Hash/SHA512.hs +29/−17
- Crypto/Hash/SHA512t.hs +0/−3
- Crypto/Hash/Skein256.hs +26/−15
- Crypto/Hash/Skein512.hs +26/−15
- Crypto/Hash/Tiger.hs +22/−9
- Crypto/Hash/Types.hs +49/−0
- Crypto/Hash/Utils.hs +72/−0
- Crypto/Hash/Whirlpool.hs +22/−9
- README.md +29/−6
- cbits/skein256.c +2/−2
- cbits/skein512.c +2/−2
- cbits/skein512.h +1/−1
- cryptohash.cabal +38/−14
+ Bench/BenchAPI.hs view
@@ -0,0 +1,37 @@+{-# LANGUAGE BangPatterns #-}+import Criterion.Main+import qualified Data.ByteString as B+import qualified Data.ByteString.Lazy as L+import qualified Crypto.Hash.SHA1 as SHA1+import qualified Crypto.Hash.SHA3 as SHA3+import Crypto.Hash+import qualified Crypto.Classes as CAPI++main = do+ let !bs32 = B.replicate 32 0+ !bs256 = B.replicate 256 0+ !bs4096 = B.replicate 4096 0+ !bs1M = B.replicate (1*1024*1024) 0+ let !lbs64x256 = (map (const (B.replicate 64 0)) [0..3])+ !lbs64x4096 = (map (const (B.replicate 64 0)) [0..63])+ defaultMain+ [ bcompare+ [ bench "sha1.hash 32" $ whnf SHA1.hash bs32+ , bench "sha1.incr 32" $ whnf (SHA1.finalize . SHA1.update SHA1.init) bs32+ , bench "sha1.api 32" $ whnf (digestToByteString . hashsha1) bs32+ , bench "sha1.capi 32" $ whnf (CAPI.hash' :: B.ByteString -> SHA1.SHA1) bs32+ ]+ , bcompare+ [ bench "sha1.hash 256" $ whnf SHA1.hash bs256+ , bench "sha1.incr 256" $ whnf (SHA1.finalize . SHA1.update SHA1.init) bs256+ , bench "sha1.api 256" $ whnf (digestToByteString . hashsha1) bs256+ , bench "sha1.capi 256" $ whnf (CAPI.hash' :: B.ByteString -> SHA1.SHA1) bs256+ ]+ , bcompare+ [ bench "sha1.hash 4096" $ whnf SHA1.hash bs4096+ , bench "sha1.incr 4096" $ whnf (SHA1.finalize . SHA1.update SHA1.init) bs4096+ , bench "sha1.api 4096" $ whnf (digestToByteString . hashsha1) bs4096+ , bench "sha1.capi 4096" $ whnf (CAPI.hash' :: B.ByteString -> SHA1.SHA1) bs4096+ ]+ ]+ where hashsha1 = hash :: B.ByteString -> Digest SHA1
+ Crypto/Hash.hs view
@@ -0,0 +1,125 @@+{-# LANGUAGE EmptyDataDecls #-}+{-# LANGUAGE CPP #-}+-- |+-- Module : Crypto.Hash+-- License : BSD-style+-- Maintainer : Vincent Hanquez <vincent@snarc.org>+-- Stability : experimental+-- Portability : unknown+--+-- Crypto hash main module+--+module Crypto.Hash+ (+ -- * Types+ HashAlgorithm(..)+ , Context+ , Digest+ -- * Functions+ , digestToByteString+ , digestToHexByteString+ , hash+ , hashlazy+ , hashUpdate+ -- * 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+ )+ where++import Crypto.Hash.Types+import Crypto.Hash.Utils+import Data.ByteString (ByteString)+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++-- | run hashUpdates on one single bytestring and return the updated context.+hashUpdate :: HashAlgorithm a => Context a -> ByteString -> Context a+hashUpdate ctx b = hashUpdates ctx [b]++-- | Hash a strict bytestring into a digest.+hash :: HashAlgorithm a => ByteString -> Digest a+hash bs = hashFinalize $ hashUpdate hashInit bs++-- | Hash a lazy bytestring into a digest.+hashlazy :: HashAlgorithm a => L.ByteString -> Digest a+hashlazy lbs = hashFinalize $ hashUpdates hashInit (L.toChunks lbs)++-- | Return the hexadecimal (base16) bytestring of the digest+digestToHexByteString :: Digest a -> ByteString+digestToHexByteString = toHex . digestToByteString++#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) \+ };++#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) \+ };++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)++DEFINE_INSTANCE(RIPEMD160, RIPEMD160)+DEFINE_INSTANCE(Whirlpool, Whirlpool)+DEFINE_INSTANCE(Tiger, Tiger)++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)++DEFINE_INSTANCE_LEN(Skein256_224, Skein256, 224)+DEFINE_INSTANCE_LEN(Skein256_256, Skein256, 256)++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)
Crypto/Hash/MD2.hs view
@@ -16,6 +16,7 @@ -- * Incremental hashing Functions , init -- :: Ctx , update -- :: Ctx -> ByteString -> Ctx+ , updates -- :: Ctx -> [ByteString] -> Ctx , finalize -- :: Ctx -> ByteString -- * Single Pass hashing@@ -29,10 +30,12 @@ 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, inlinePerformIO)+import Data.ByteString.Internal (create, toForeignPtr) import Data.Word+import System.IO.Unsafe (unsafeDupablePerformIO) #ifdef HAVE_CRYPTOAPI @@ -56,7 +59,7 @@ #endif -data Ctx = Ctx !ByteString+newtype Ctx = Ctx ByteString data MD2 = Digest !ByteString deriving (Eq,Ord,Show) @@ -69,6 +72,12 @@ 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 =@@ -114,32 +123,36 @@ unsafeUseAsCStringLen d (\(cs, len) -> c_md2_update ptr (castPtr cs) (fromIntegral len)) finalizeInternalIO :: Ptr Ctx -> IO ByteString-finalizeInternalIO ptr =- create digestSize (c_md2_finalize ptr)+finalizeInternalIO ptr = create digestSize (c_md2_finalize ptr) {-# NOINLINE init #-} -- | init a context init :: Ctx-init = inlinePerformIO $ withCtxNew $ c_md2_init+init = unsafeDupablePerformIO $ withCtxNew $ c_md2_init {-# NOINLINE update #-} -- | update a context with a bytestring update :: Ctx -> ByteString -> Ctx-update ctx d = inlinePerformIO $ withCtxCopy ctx $ \ptr -> updateInternalIO ptr d+update ctx d = unsafeDupablePerformIO $ withCtxCopy ctx $ \ptr -> updateInternalIO ptr d +{-# NOINLINE updates #-}+-- | updates a context with multiples bytestring+updates :: Ctx -> [ByteString] -> Ctx+updates ctx d = unsafeDupablePerformIO $ withCtxCopy ctx $ \ptr -> mapM_ (updateInternalIO ptr) d+ {-# NOINLINE finalize #-} -- | finalize the context into a digest bytestring finalize :: Ctx -> ByteString-finalize ctx = inlinePerformIO $ withCtxThrow ctx finalizeInternalIO+finalize ctx = unsafeDupablePerformIO $ withCtxThrow ctx finalizeInternalIO {-# NOINLINE hash #-} -- | hash a strict bytestring into a digest bytestring hash :: ByteString -> ByteString-hash d = inlinePerformIO $ withCtxNewThrow $ \ptr -> do+hash d = unsafeDupablePerformIO $ withCtxNewThrow $ \ptr -> do c_md2_init ptr >> updateInternalIO ptr d >> finalizeInternalIO ptr {-# NOINLINE hashlazy #-} -- | hash a lazy bytestring into a digest bytestring hashlazy :: L.ByteString -> ByteString-hashlazy l = inlinePerformIO $ withCtxNewThrow $ \ptr -> do+hashlazy l = unsafeDupablePerformIO $ withCtxNewThrow $ \ptr -> do c_md2_init ptr >> mapM_ (updateInternalIO ptr) (L.toChunks l) >> finalizeInternalIO ptr
Crypto/Hash/MD4.hs view
@@ -16,6 +16,7 @@ -- * Incremental hashing Functions , init -- :: Ctx , update -- :: Ctx -> ByteString -> Ctx+ , updates -- :: Ctx -> [ByteString] -> Ctx , finalize -- :: Ctx -> ByteString -- * Single Pass hashing@@ -29,10 +30,12 @@ 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, inlinePerformIO)+import Data.ByteString.Internal (create, toForeignPtr) import Data.Word+import System.IO.Unsafe (unsafeDupablePerformIO) #ifdef HAVE_CRYPTOAPI @@ -56,7 +59,7 @@ #endif -data Ctx = Ctx !ByteString+newtype Ctx = Ctx ByteString data MD4 = Digest !ByteString deriving (Eq,Ord,Show) @@ -69,6 +72,12 @@ 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 =@@ -114,32 +123,36 @@ unsafeUseAsCStringLen d (\(cs, len) -> c_md4_update ptr (castPtr cs) (fromIntegral len)) finalizeInternalIO :: Ptr Ctx -> IO ByteString-finalizeInternalIO ptr =- create digestSize (c_md4_finalize ptr)+finalizeInternalIO ptr = create digestSize (c_md4_finalize ptr) {-# NOINLINE init #-} -- | init a context init :: Ctx-init = inlinePerformIO $ withCtxNew $ c_md4_init+init = unsafeDupablePerformIO $ withCtxNew $ c_md4_init {-# NOINLINE update #-} -- | update a context with a bytestring update :: Ctx -> ByteString -> Ctx-update ctx d = inlinePerformIO $ withCtxCopy ctx $ \ptr -> updateInternalIO ptr d+update ctx d = unsafeDupablePerformIO $ withCtxCopy ctx $ \ptr -> updateInternalIO ptr d +{-# NOINLINE updates #-}+-- | updates a context with multiples bytestring+updates :: Ctx -> [ByteString] -> Ctx+updates ctx d = unsafeDupablePerformIO $ withCtxCopy ctx $ \ptr -> mapM_ (updateInternalIO ptr) d+ {-# NOINLINE finalize #-} -- | finalize the context into a digest bytestring finalize :: Ctx -> ByteString-finalize ctx = inlinePerformIO $ withCtxThrow ctx finalizeInternalIO+finalize ctx = unsafeDupablePerformIO $ withCtxThrow ctx finalizeInternalIO {-# NOINLINE hash #-} -- | hash a strict bytestring into a digest bytestring hash :: ByteString -> ByteString-hash d = inlinePerformIO $ withCtxNewThrow $ \ptr -> do+hash d = unsafeDupablePerformIO $ withCtxNewThrow $ \ptr -> do c_md4_init ptr >> updateInternalIO ptr d >> finalizeInternalIO ptr {-# NOINLINE hashlazy #-} -- | hash a lazy bytestring into a digest bytestring hashlazy :: L.ByteString -> ByteString-hashlazy l = inlinePerformIO $ withCtxNewThrow $ \ptr -> do+hashlazy l = unsafeDupablePerformIO $ withCtxNewThrow $ \ptr -> do c_md4_init ptr >> mapM_ (updateInternalIO ptr) (L.toChunks l) >> finalizeInternalIO ptr
Crypto/Hash/MD5.hs view
@@ -16,6 +16,7 @@ -- * Incremental hashing Functions , init -- :: Ctx , update -- :: Ctx -> ByteString -> Ctx+ , updates -- :: Ctx -> [ByteString] -> Ctx , finalize -- :: Ctx -> ByteString -- * Single Pass hashing@@ -29,10 +30,12 @@ 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, inlinePerformIO)+import Data.ByteString.Internal (create, toForeignPtr) import Data.Word+import System.IO.Unsafe (unsafeDupablePerformIO) #ifdef HAVE_CRYPTOAPI @@ -56,7 +59,7 @@ #endif -data Ctx = Ctx !ByteString+newtype Ctx = Ctx ByteString data MD5 = Digest !ByteString deriving (Eq,Ord,Show) @@ -69,6 +72,12 @@ 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 =@@ -114,32 +123,36 @@ unsafeUseAsCStringLen d (\(cs, len) -> c_md5_update ptr (castPtr cs) (fromIntegral len)) finalizeInternalIO :: Ptr Ctx -> IO ByteString-finalizeInternalIO ptr =- create digestSize (c_md5_finalize ptr)+finalizeInternalIO ptr = create digestSize (c_md5_finalize ptr) {-# NOINLINE init #-} -- | init a context init :: Ctx-init = inlinePerformIO $ withCtxNew $ c_md5_init+init = unsafeDupablePerformIO $ withCtxNew $ c_md5_init {-# NOINLINE update #-} -- | update a context with a bytestring update :: Ctx -> ByteString -> Ctx-update ctx d = inlinePerformIO $ withCtxCopy ctx $ \ptr -> updateInternalIO ptr d+update ctx d = unsafeDupablePerformIO $ withCtxCopy ctx $ \ptr -> updateInternalIO ptr d +{-# NOINLINE updates #-}+-- | updates a context with multiples bytestring+updates :: Ctx -> [ByteString] -> Ctx+updates ctx d = unsafeDupablePerformIO $ withCtxCopy ctx $ \ptr -> mapM_ (updateInternalIO ptr) d+ {-# NOINLINE finalize #-} -- | finalize the context into a digest bytestring finalize :: Ctx -> ByteString-finalize ctx = inlinePerformIO $ withCtxThrow ctx finalizeInternalIO+finalize ctx = unsafeDupablePerformIO $ withCtxThrow ctx finalizeInternalIO {-# NOINLINE hash #-} -- | hash a strict bytestring into a digest bytestring hash :: ByteString -> ByteString-hash d = inlinePerformIO $ withCtxNewThrow $ \ptr -> do+hash d = unsafeDupablePerformIO $ withCtxNewThrow $ \ptr -> do c_md5_init ptr >> updateInternalIO ptr d >> finalizeInternalIO ptr {-# NOINLINE hashlazy #-} -- | hash a lazy bytestring into a digest bytestring hashlazy :: L.ByteString -> ByteString-hashlazy l = inlinePerformIO $ withCtxNewThrow $ \ptr -> do+hashlazy l = unsafeDupablePerformIO $ withCtxNewThrow $ \ptr -> do c_md5_init ptr >> mapM_ (updateInternalIO ptr) (L.toChunks l) >> finalizeInternalIO ptr
Crypto/Hash/RIPEMD160.hs view
@@ -16,6 +16,7 @@ -- * Incremental hashing Functions , init -- :: Ctx , update -- :: Ctx -> ByteString -> Ctx+ , updates -- :: Ctx -> [ByteString] -> Ctx , finalize -- :: Ctx -> ByteString -- * Single Pass hashing@@ -29,10 +30,12 @@ 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, inlinePerformIO)+import Data.ByteString.Internal (create, toForeignPtr) import Data.Word+import System.IO.Unsafe (unsafeDupablePerformIO) #ifdef HAVE_CRYPTOAPI @@ -56,7 +59,7 @@ #endif -data Ctx = Ctx !ByteString+newtype Ctx = Ctx ByteString data RIPEMD160 = Digest !ByteString deriving (Eq,Ord,Show) @@ -69,6 +72,12 @@ 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 =@@ -114,32 +123,36 @@ unsafeUseAsCStringLen d (\(cs, len) -> c_ripemd160_update ptr (castPtr cs) (fromIntegral len)) finalizeInternalIO :: Ptr Ctx -> IO ByteString-finalizeInternalIO ptr =- create digestSize (c_ripemd160_finalize ptr)+finalizeInternalIO ptr = create digestSize (c_ripemd160_finalize ptr) {-# NOINLINE init #-} -- | init a context init :: Ctx-init = inlinePerformIO $ withCtxNew $ c_ripemd160_init+init = unsafeDupablePerformIO $ withCtxNew $ c_ripemd160_init {-# NOINLINE update #-} -- | update a context with a bytestring update :: Ctx -> ByteString -> Ctx-update ctx d = inlinePerformIO $ withCtxCopy ctx $ \ptr -> updateInternalIO ptr d+update ctx d = unsafeDupablePerformIO $ withCtxCopy ctx $ \ptr -> updateInternalIO ptr d +{-# NOINLINE updates #-}+-- | updates a context with multiples bytestring+updates :: Ctx -> [ByteString] -> Ctx+updates ctx d = unsafeDupablePerformIO $ withCtxCopy ctx $ \ptr -> mapM_ (updateInternalIO ptr) d+ {-# NOINLINE finalize #-} -- | finalize the context into a digest bytestring finalize :: Ctx -> ByteString-finalize ctx = inlinePerformIO $ withCtxThrow ctx finalizeInternalIO+finalize ctx = unsafeDupablePerformIO $ withCtxThrow ctx finalizeInternalIO {-# NOINLINE hash #-} -- | hash a strict bytestring into a digest bytestring hash :: ByteString -> ByteString-hash d = inlinePerformIO $ withCtxNewThrow $ \ptr -> do+hash d = unsafeDupablePerformIO $ withCtxNewThrow $ \ptr -> do c_ripemd160_init ptr >> updateInternalIO ptr d >> finalizeInternalIO ptr {-# NOINLINE hashlazy #-} -- | hash a lazy bytestring into a digest bytestring hashlazy :: L.ByteString -> ByteString-hashlazy l = inlinePerformIO $ withCtxNewThrow $ \ptr -> do+hashlazy l = unsafeDupablePerformIO $ withCtxNewThrow $ \ptr -> do c_ripemd160_init ptr >> mapM_ (updateInternalIO ptr) (L.toChunks l) >> finalizeInternalIO ptr
Crypto/Hash/SHA1.hs view
@@ -16,6 +16,7 @@ -- * Incremental hashing Functions , init -- :: Ctx , update -- :: Ctx -> ByteString -> Ctx+ , updates -- :: Ctx -> [ByteString] -> Ctx , finalize -- :: Ctx -> ByteString -- * Single Pass hashing@@ -29,10 +30,12 @@ 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, inlinePerformIO)+import Data.ByteString.Internal (create, toForeignPtr) import Data.Word+import System.IO.Unsafe (unsafeDupablePerformIO) #ifdef HAVE_CRYPTOAPI @@ -56,7 +59,7 @@ #endif -data Ctx = Ctx !ByteString+newtype Ctx = Ctx ByteString data SHA1 = Digest !ByteString deriving (Eq,Ord,Show) @@ -69,6 +72,12 @@ 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 =@@ -114,32 +123,36 @@ unsafeUseAsCStringLen d (\(cs, len) -> c_sha1_update ptr (castPtr cs) (fromIntegral len)) finalizeInternalIO :: Ptr Ctx -> IO ByteString-finalizeInternalIO ptr =- create digestSize (c_sha1_finalize ptr)+finalizeInternalIO ptr = create digestSize (c_sha1_finalize ptr) {-# NOINLINE init #-} -- | init a context init :: Ctx-init = inlinePerformIO $ withCtxNew $ c_sha1_init+init = unsafeDupablePerformIO $ withCtxNew $ c_sha1_init {-# NOINLINE update #-} -- | update a context with a bytestring update :: Ctx -> ByteString -> Ctx-update ctx d = inlinePerformIO $ withCtxCopy ctx $ \ptr -> updateInternalIO ptr d+update ctx d = unsafeDupablePerformIO $ withCtxCopy ctx $ \ptr -> updateInternalIO ptr d +{-# NOINLINE updates #-}+-- | updates a context with multiples bytestring+updates :: Ctx -> [ByteString] -> Ctx+updates ctx d = unsafeDupablePerformIO $ withCtxCopy ctx $ \ptr -> mapM_ (updateInternalIO ptr) d+ {-# NOINLINE finalize #-} -- | finalize the context into a digest bytestring finalize :: Ctx -> ByteString-finalize ctx = inlinePerformIO $ withCtxThrow ctx finalizeInternalIO+finalize ctx = unsafeDupablePerformIO $ withCtxThrow ctx finalizeInternalIO {-# NOINLINE hash #-} -- | hash a strict bytestring into a digest bytestring hash :: ByteString -> ByteString-hash d = inlinePerformIO $ withCtxNewThrow $ \ptr -> do+hash d = unsafeDupablePerformIO $ withCtxNewThrow $ \ptr -> do c_sha1_init ptr >> updateInternalIO ptr d >> finalizeInternalIO ptr {-# NOINLINE hashlazy #-} -- | hash a lazy bytestring into a digest bytestring hashlazy :: L.ByteString -> ByteString-hashlazy l = inlinePerformIO $ withCtxNewThrow $ \ptr -> do+hashlazy l = unsafeDupablePerformIO $ withCtxNewThrow $ \ptr -> do c_sha1_init ptr >> mapM_ (updateInternalIO ptr) (L.toChunks l) >> finalizeInternalIO ptr
Crypto/Hash/SHA224.hs view
@@ -16,6 +16,7 @@ -- * Incremental hashing Functions , init -- :: Ctx , update -- :: Ctx -> ByteString -> Ctx+ , updates -- :: Ctx -> [ByteString] -> Ctx , finalize -- :: Ctx -> ByteString -- * Single Pass hashing@@ -29,10 +30,12 @@ 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, inlinePerformIO)+import Data.ByteString.Internal (create, toForeignPtr) import Data.Word+import System.IO.Unsafe (unsafeDupablePerformIO) #ifdef HAVE_CRYPTOAPI @@ -56,7 +59,7 @@ #endif -data Ctx = Ctx !ByteString+newtype Ctx = Ctx ByteString data SHA224 = Digest !ByteString deriving (Eq,Ord,Show) @@ -69,6 +72,12 @@ 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 =@@ -114,32 +123,36 @@ unsafeUseAsCStringLen d (\(cs, len) -> c_sha224_update ptr (castPtr cs) (fromIntegral len)) finalizeInternalIO :: Ptr Ctx -> IO ByteString-finalizeInternalIO ptr =- create digestSize (c_sha224_finalize ptr)+finalizeInternalIO ptr = create digestSize (c_sha224_finalize ptr) {-# NOINLINE init #-} -- | init a context init :: Ctx-init = inlinePerformIO $ withCtxNew $ c_sha224_init+init = unsafeDupablePerformIO $ withCtxNew $ c_sha224_init {-# NOINLINE update #-} -- | update a context with a bytestring update :: Ctx -> ByteString -> Ctx-update ctx d = inlinePerformIO $ withCtxCopy ctx $ \ptr -> updateInternalIO ptr d+update ctx d = unsafeDupablePerformIO $ withCtxCopy ctx $ \ptr -> updateInternalIO ptr d +{-# NOINLINE updates #-}+-- | updates a context with multiples bytestring+updates :: Ctx -> [ByteString] -> Ctx+updates ctx d = unsafeDupablePerformIO $ withCtxCopy ctx $ \ptr -> mapM_ (updateInternalIO ptr) d+ {-# NOINLINE finalize #-} -- | finalize the context into a digest bytestring finalize :: Ctx -> ByteString-finalize ctx = inlinePerformIO $ withCtxThrow ctx finalizeInternalIO+finalize ctx = unsafeDupablePerformIO $ withCtxThrow ctx finalizeInternalIO {-# NOINLINE hash #-} -- | hash a strict bytestring into a digest bytestring hash :: ByteString -> ByteString-hash d = inlinePerformIO $ withCtxNewThrow $ \ptr -> do+hash d = unsafeDupablePerformIO $ withCtxNewThrow $ \ptr -> do c_sha224_init ptr >> updateInternalIO ptr d >> finalizeInternalIO ptr {-# NOINLINE hashlazy #-} -- | hash a lazy bytestring into a digest bytestring hashlazy :: L.ByteString -> ByteString-hashlazy l = inlinePerformIO $ withCtxNewThrow $ \ptr -> do+hashlazy l = unsafeDupablePerformIO $ withCtxNewThrow $ \ptr -> do c_sha224_init ptr >> mapM_ (updateInternalIO ptr) (L.toChunks l) >> finalizeInternalIO ptr
Crypto/Hash/SHA256.hs view
@@ -16,6 +16,7 @@ -- * Incremental hashing Functions , init -- :: Ctx , update -- :: Ctx -> ByteString -> Ctx+ , updates -- :: Ctx -> [ByteString] -> Ctx , finalize -- :: Ctx -> ByteString -- * Single Pass hashing@@ -29,10 +30,12 @@ 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, inlinePerformIO)+import Data.ByteString.Internal (create, toForeignPtr) import Data.Word+import System.IO.Unsafe (unsafeDupablePerformIO) #ifdef HAVE_CRYPTOAPI @@ -56,7 +59,7 @@ #endif -data Ctx = Ctx !ByteString+newtype Ctx = Ctx ByteString data SHA256 = Digest !ByteString deriving (Eq,Ord,Show) @@ -69,6 +72,12 @@ 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 =@@ -114,32 +123,36 @@ unsafeUseAsCStringLen d (\(cs, len) -> c_sha256_update ptr (castPtr cs) (fromIntegral len)) finalizeInternalIO :: Ptr Ctx -> IO ByteString-finalizeInternalIO ptr =- create digestSize (c_sha256_finalize ptr)+finalizeInternalIO ptr = create digestSize (c_sha256_finalize ptr) {-# NOINLINE init #-} -- | init a context init :: Ctx-init = inlinePerformIO $ withCtxNew $ c_sha256_init+init = unsafeDupablePerformIO $ withCtxNew $ c_sha256_init {-# NOINLINE update #-} -- | update a context with a bytestring update :: Ctx -> ByteString -> Ctx-update ctx d = inlinePerformIO $ withCtxCopy ctx $ \ptr -> updateInternalIO ptr d+update ctx d = unsafeDupablePerformIO $ withCtxCopy ctx $ \ptr -> updateInternalIO ptr d +{-# NOINLINE updates #-}+-- | updates a context with multiples bytestring+updates :: Ctx -> [ByteString] -> Ctx+updates ctx d = unsafeDupablePerformIO $ withCtxCopy ctx $ \ptr -> mapM_ (updateInternalIO ptr) d+ {-# NOINLINE finalize #-} -- | finalize the context into a digest bytestring finalize :: Ctx -> ByteString-finalize ctx = inlinePerformIO $ withCtxThrow ctx finalizeInternalIO+finalize ctx = unsafeDupablePerformIO $ withCtxThrow ctx finalizeInternalIO {-# NOINLINE hash #-} -- | hash a strict bytestring into a digest bytestring hash :: ByteString -> ByteString-hash d = inlinePerformIO $ withCtxNewThrow $ \ptr -> do+hash d = unsafeDupablePerformIO $ withCtxNewThrow $ \ptr -> do c_sha256_init ptr >> updateInternalIO ptr d >> finalizeInternalIO ptr {-# NOINLINE hashlazy #-} -- | hash a lazy bytestring into a digest bytestring hashlazy :: L.ByteString -> ByteString-hashlazy l = inlinePerformIO $ withCtxNewThrow $ \ptr -> do+hashlazy l = unsafeDupablePerformIO $ withCtxNewThrow $ \ptr -> do c_sha256_init ptr >> mapM_ (updateInternalIO ptr) (L.toChunks l) >> finalizeInternalIO ptr
Crypto/Hash/SHA3.hs view
@@ -1,4 +1,4 @@-{-# LANGUAGE ForeignFunctionInterface #-}+{-# LANGUAGE ForeignFunctionInterface, CPP, MultiParamTypeClasses #-} -- | -- Module : Crypto.Hash.SHA3@@ -11,10 +11,12 @@ -- module Crypto.Hash.SHA3 ( Ctx(..)+ , SHA3 -- * Incremental hashing Functions , init -- :: Int -> Ctx , update -- :: Ctx -> ByteString -> Ctx+ , updates -- :: Ctx -> [ByteString] -> Ctx , finalize -- :: Ctx -> ByteString -- * Single Pass hashing@@ -30,11 +32,37 @@ import qualified Data.ByteString.Lazy as L import Data.ByteString (ByteString) import Data.ByteString.Unsafe (unsafeUseAsCStringLen)-import Data.ByteString.Internal (create, toForeignPtr, inlinePerformIO)+import Data.ByteString.Internal (create, toForeignPtr) import Data.Word+import System.IO.Unsafe (unsafeDupablePerformIO) -data Ctx = Ctx !ByteString+#ifdef HAVE_CRYPTOAPI +import Control.Monad (liftM)+import Data.Serialize (Serialize(..))+import Data.Serialize.Get (getByteString)+import Data.Serialize.Put (putByteString)+import Data.Tagged (Tagged(..))+import qualified Crypto.Classes as C (Hash(..))++instance C.Hash Ctx SHA3 where+ outputLength = Tagged (64 * 8)+ blockLength = Tagged (64 * 8)+ initialCtx = init (64 * 8)+ updateCtx = update+ finalize ctx bs = Digest . finalize $ update ctx bs++instance Serialize SHA3 where+ get = liftM Digest (getByteString 64)+ put (Digest d) = putByteString d++#endif++newtype Ctx = Ctx ByteString+data SHA3 = Digest !ByteString+ deriving (Eq,Ord,Show)++ {-# INLINE sizeCtx #-} sizeCtx :: Int sizeCtx = 360@@ -45,6 +73,11 @@ where iptr :: Ptr Word32 iptr = castPtr ptr +{-# RULES "hash" forall b i. finalize (update (init i) b) = hash i b #-}+{-# RULES "hash.list1" forall b i. finalize (updates (init i) [b]) = hash i b #-}+{-# RULES "hashmany" forall b i. finalize (foldl update (init i) b) = hashlazy i (L.fromChunks b) #-}+{-# RULES "hashlazy" forall b i. finalize (foldl update (init i) $ L.toChunks b) = hashlazy i b #-}+ {-# INLINE withByteStringPtr #-} withByteStringPtr :: ByteString -> (Ptr Word8 -> IO a) -> IO a withByteStringPtr b f =@@ -53,7 +86,7 @@ {-# INLINE memcopy64 #-} memcopy64 :: Ptr Word64 -> Ptr Word64 -> IO ()-memcopy64 dst src = mapM_ peekAndPoke [0..44]+memcopy64 dst src = mapM_ peekAndPoke [0..(45-1)] where peekAndPoke i = peekElemOff src i >>= pokeElemOff dst i withCtxCopy :: Ctx -> (Ptr Ctx -> IO ()) -> IO Ctx@@ -96,26 +129,31 @@ {-# NOINLINE init #-} -- | init a context init :: Int -> Ctx-init hashlen = inlinePerformIO $ withCtxNew (\ctx -> c_sha3_init ctx (fromIntegral hashlen))+init hashlen = unsafeDupablePerformIO $ withCtxNew $ \ptr -> c_sha3_init ptr (fromIntegral hashlen) {-# NOINLINE update #-} -- | update a context with a bytestring update :: Ctx -> ByteString -> Ctx-update ctx d = inlinePerformIO $ withCtxCopy ctx $ \ptr -> updateInternalIO ptr d+update ctx d = unsafeDupablePerformIO $ withCtxCopy ctx $ \ptr -> updateInternalIO ptr d +{-# NOINLINE updates #-}+-- | updates a context with multiples bytestring+updates :: Ctx -> [ByteString] -> Ctx+updates ctx d = unsafeDupablePerformIO $ withCtxCopy ctx $ \ptr -> mapM_ (updateInternalIO ptr) d+ {-# NOINLINE finalize #-} -- | finalize the context into a digest bytestring finalize :: Ctx -> ByteString-finalize ctx = inlinePerformIO $ withCtxThrow ctx finalizeInternalIO+finalize ctx = unsafeDupablePerformIO $ withCtxThrow ctx finalizeInternalIO {-# NOINLINE hash #-} -- | hash a strict bytestring into a digest bytestring hash :: Int -> ByteString -> ByteString-hash hashlen d = inlinePerformIO $ withCtxNewThrow $ \ptr -> do+hash hashlen d = unsafeDupablePerformIO $ withCtxNewThrow $ \ptr -> do c_sha3_init ptr (fromIntegral hashlen) >> updateInternalIO ptr d >> finalizeInternalIO ptr {-# NOINLINE hashlazy #-} -- | hash a lazy bytestring into a digest bytestring hashlazy :: Int -> L.ByteString -> ByteString-hashlazy hashlen l = inlinePerformIO $ withCtxNewThrow $ \ptr -> do+hashlazy hashlen l = unsafeDupablePerformIO $ withCtxNewThrow $ \ptr -> do c_sha3_init ptr (fromIntegral hashlen) >> mapM_ (updateInternalIO ptr) (L.toChunks l) >> finalizeInternalIO ptr
Crypto/Hash/SHA384.hs view
@@ -16,6 +16,7 @@ -- * Incremental hashing Functions , init -- :: Ctx , update -- :: Ctx -> ByteString -> Ctx+ , updates -- :: Ctx -> [ByteString] -> Ctx , finalize -- :: Ctx -> ByteString -- * Single Pass hashing@@ -29,10 +30,12 @@ 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, inlinePerformIO)+import Data.ByteString.Internal (create, toForeignPtr) import Data.Word+import System.IO.Unsafe (unsafeDupablePerformIO) #ifdef HAVE_CRYPTOAPI @@ -56,7 +59,7 @@ #endif -data Ctx = Ctx !ByteString+newtype Ctx = Ctx ByteString data SHA384 = Digest !ByteString deriving (Eq,Ord,Show) @@ -69,6 +72,12 @@ 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 =@@ -114,32 +123,36 @@ unsafeUseAsCStringLen d (\(cs, len) -> c_sha384_update ptr (castPtr cs) (fromIntegral len)) finalizeInternalIO :: Ptr Ctx -> IO ByteString-finalizeInternalIO ptr =- create digestSize (c_sha384_finalize ptr)+finalizeInternalIO ptr = create digestSize (c_sha384_finalize ptr) {-# NOINLINE init #-} -- | init a context init :: Ctx-init = inlinePerformIO $ withCtxNew $ c_sha384_init+init = unsafeDupablePerformIO $ withCtxNew $ c_sha384_init {-# NOINLINE update #-} -- | update a context with a bytestring update :: Ctx -> ByteString -> Ctx-update ctx d = inlinePerformIO $ withCtxCopy ctx $ \ptr -> updateInternalIO ptr d+update ctx d = unsafeDupablePerformIO $ withCtxCopy ctx $ \ptr -> updateInternalIO ptr d +{-# NOINLINE updates #-}+-- | updates a context with multiples bytestring+updates :: Ctx -> [ByteString] -> Ctx+updates ctx d = unsafeDupablePerformIO $ withCtxCopy ctx $ \ptr -> mapM_ (updateInternalIO ptr) d+ {-# NOINLINE finalize #-} -- | finalize the context into a digest bytestring finalize :: Ctx -> ByteString-finalize ctx = inlinePerformIO $ withCtxThrow ctx finalizeInternalIO+finalize ctx = unsafeDupablePerformIO $ withCtxThrow ctx finalizeInternalIO {-# NOINLINE hash #-} -- | hash a strict bytestring into a digest bytestring hash :: ByteString -> ByteString-hash d = inlinePerformIO $ withCtxNewThrow $ \ptr -> do+hash d = unsafeDupablePerformIO $ withCtxNewThrow $ \ptr -> do c_sha384_init ptr >> updateInternalIO ptr d >> finalizeInternalIO ptr {-# NOINLINE hashlazy #-} -- | hash a lazy bytestring into a digest bytestring hashlazy :: L.ByteString -> ByteString-hashlazy l = inlinePerformIO $ withCtxNewThrow $ \ptr -> do+hashlazy l = unsafeDupablePerformIO $ withCtxNewThrow $ \ptr -> do c_sha384_init ptr >> mapM_ (updateInternalIO ptr) (L.toChunks l) >> finalizeInternalIO ptr
Crypto/Hash/SHA512.hs view
@@ -17,6 +17,7 @@ , init -- :: Ctx , init_t -- :: Int -> Ctx , update -- :: Ctx -> ByteString -> Ctx+ , updates -- :: Ctx -> [ByteString] -> Ctx , finalize -- :: Ctx -> ByteString -- * Single Pass hashing@@ -25,16 +26,17 @@ ) where import Prelude hiding (init)-import System.IO.Unsafe (unsafePerformIO) 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 System.IO.Unsafe (unsafeDupablePerformIO) #ifdef HAVE_CRYPTOAPI @@ -58,7 +60,7 @@ #endif -data Ctx = Ctx !ByteString+newtype Ctx = Ctx ByteString data SHA512 = Digest !ByteString deriving (Eq,Ord,Show) @@ -71,6 +73,12 @@ 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 =@@ -105,51 +113,55 @@ foreign import ccall unsafe "sha512.h sha512_init" c_sha512_init :: Ptr Ctx -> IO () -foreign import ccall unsafe "sha512.h sha512_init_t"- c_sha512_init_t :: Ptr Ctx -> Int -> IO ()- foreign import ccall "sha512.h sha512_update" c_sha512_update :: Ptr Ctx -> Ptr Word8 -> Word32 -> IO () foreign import ccall unsafe "sha512.h sha512_finalize" c_sha512_finalize :: Ptr Ctx -> Ptr Word8 -> IO () +foreign import ccall unsafe "sha512.h sha512_init_t"+ c_sha512_init_t :: Ptr Ctx -> Int -> IO ()++{-# NOINLINE init_t #-}+-- | init a context using FIPS 180-4 for truncated SHA512+init_t :: Int -> Ctx+init_t t = unsafeDupablePerformIO $ withCtxNew $ \ptr -> c_sha512_init_t ptr t+ updateInternalIO :: Ptr Ctx -> ByteString -> IO () updateInternalIO ptr d = unsafeUseAsCStringLen d (\(cs, len) -> c_sha512_update ptr (castPtr cs) (fromIntegral len)) finalizeInternalIO :: Ptr Ctx -> IO ByteString-finalizeInternalIO ptr =- create digestSize (c_sha512_finalize ptr)+finalizeInternalIO ptr = create digestSize (c_sha512_finalize ptr) {-# NOINLINE init #-} -- | init a context init :: Ctx-init = unsafePerformIO $ withCtxNew $ c_sha512_init--{-# NOINLINE init_t #-}--- | init a context using FIPS 180-4 for truncated SHA512-init_t :: Int -> Ctx-init_t t = unsafePerformIO $ withCtxNew $ \ptr -> c_sha512_init_t ptr t+init = unsafeDupablePerformIO $ withCtxNew $ c_sha512_init {-# NOINLINE update #-} -- | update a context with a bytestring update :: Ctx -> ByteString -> Ctx-update ctx d = unsafePerformIO $ withCtxCopy ctx $ \ptr -> updateInternalIO ptr d+update ctx d = unsafeDupablePerformIO $ withCtxCopy ctx $ \ptr -> updateInternalIO ptr d +{-# NOINLINE updates #-}+-- | updates a context with multiples bytestring+updates :: Ctx -> [ByteString] -> Ctx+updates ctx d = unsafeDupablePerformIO $ withCtxCopy ctx $ \ptr -> mapM_ (updateInternalIO ptr) d+ {-# NOINLINE finalize #-} -- | finalize the context into a digest bytestring finalize :: Ctx -> ByteString-finalize ctx = unsafePerformIO $ withCtxThrow ctx finalizeInternalIO+finalize ctx = unsafeDupablePerformIO $ withCtxThrow ctx finalizeInternalIO {-# NOINLINE hash #-} -- | hash a strict bytestring into a digest bytestring hash :: ByteString -> ByteString-hash d = unsafePerformIO $ withCtxNewThrow $ \ptr -> do+hash d = unsafeDupablePerformIO $ withCtxNewThrow $ \ptr -> do c_sha512_init ptr >> updateInternalIO ptr d >> finalizeInternalIO ptr {-# NOINLINE hashlazy #-} -- | hash a lazy bytestring into a digest bytestring hashlazy :: L.ByteString -> ByteString-hashlazy l = unsafePerformIO $ withCtxNewThrow $ \ptr -> do+hashlazy l = unsafeDupablePerformIO $ withCtxNewThrow $ \ptr -> do c_sha512_init ptr >> mapM_ (updateInternalIO ptr) (L.toChunks l) >> finalizeInternalIO ptr
Crypto/Hash/SHA512t.hs view
@@ -1,5 +1,3 @@-{-# LANGUAGE MultiParamTypeClasses #-}- -- | -- Module : Crypto.Hash.SHA512t -- License : BSD-style@@ -11,7 +9,6 @@ -- module Crypto.Hash.SHA512t ( Ctx(..)- --, SHA512t -- * Incremental hashing Functions , init -- :: Ctx
Crypto/Hash/Skein256.hs view
@@ -16,6 +16,7 @@ -- * Incremental hashing Functions , init -- :: Int -> Ctx , update -- :: Ctx -> ByteString -> Ctx+ , updates -- :: Ctx -> [ByteString] -> Ctx , finalize -- :: Ctx -> ByteString -- * Single Pass hashing@@ -24,7 +25,6 @@ ) where import Prelude hiding (init)-import Foreign.C.Types import Foreign.Ptr import Foreign.ForeignPtr (withForeignPtr) import Foreign.Storable@@ -32,9 +32,9 @@ import qualified Data.ByteString.Lazy as L import Data.ByteString (ByteString) import Data.ByteString.Unsafe (unsafeUseAsCStringLen)-import Data.ByteString.Internal (create, inlinePerformIO, toForeignPtr)+import Data.ByteString.Internal (create, toForeignPtr) import Data.Word-import Data.Bits+import System.IO.Unsafe (unsafeDupablePerformIO) #ifdef HAVE_CRYPTOAPI @@ -58,19 +58,26 @@ #endif -data Ctx = Ctx !ByteString+newtype Ctx = Ctx ByteString data Skein256 = Digest !ByteString deriving (Eq,Ord,Show) ++{-# INLINE sizeCtx #-} sizeCtx :: Int-sizeCtx = 88+sizeCtx = 96 +{- return the number of bytes of output for the digest -} peekHashlen :: Ptr Ctx -> IO Int-peekHashlen ptr = do- let iptr = castPtr ptr :: Ptr CUInt- a <- peek iptr- return ((fromIntegral a + 7) `shiftR` 3)+peekHashlen ptr = peek iptr >>= \v -> return $! fromIntegral v+ where iptr :: Ptr Word32+ iptr = castPtr ptr +{-# RULES "hash" forall b i. finalize (update (init i) b) = hash i b #-}+{-# RULES "hash.list1" forall b i. finalize (updates (init i) [b]) = hash i b #-}+{-# RULES "hashmany" forall b i. finalize (foldl update (init i) b) = hashlazy i (L.fromChunks b) #-}+{-# RULES "hashlazy" forall b i. finalize (foldl update (init i) $ L.toChunks b) = hashlazy i b #-}+ {-# INLINE withByteStringPtr #-} withByteStringPtr :: ByteString -> (Ptr Word8 -> IO a) -> IO a withByteStringPtr b f =@@ -111,7 +118,6 @@ foreign import ccall unsafe "skein256.h skein256_finalize" c_skein256_finalize :: Ptr Ctx -> Ptr Word8 -> IO () - updateInternalIO :: Ptr Ctx -> ByteString -> IO () updateInternalIO ptr d = unsafeUseAsCStringLen d (\(cs, len) -> c_skein256_update ptr (castPtr cs) (fromIntegral len))@@ -123,26 +129,31 @@ {-# NOINLINE init #-} -- | init a context init :: Int -> Ctx-init hashlen = inlinePerformIO $ withCtxNew $ \ptr -> c_skein256_init ptr (fromIntegral hashlen)+init hashlen = unsafeDupablePerformIO $ withCtxNew $ \ptr -> c_skein256_init ptr (fromIntegral hashlen) {-# NOINLINE update #-} -- | update a context with a bytestring update :: Ctx -> ByteString -> Ctx-update ctx d = inlinePerformIO $ withCtxCopy ctx $ \ptr -> updateInternalIO ptr d+update ctx d = unsafeDupablePerformIO $ withCtxCopy ctx $ \ptr -> updateInternalIO ptr d +{-# NOINLINE updates #-}+-- | updates a context with multiples bytestring+updates :: Ctx -> [ByteString] -> Ctx+updates ctx d = unsafeDupablePerformIO $ withCtxCopy ctx $ \ptr -> mapM_ (updateInternalIO ptr) d+ {-# NOINLINE finalize #-} -- | finalize the context into a digest bytestring finalize :: Ctx -> ByteString-finalize ctx = inlinePerformIO $ withCtxThrow ctx finalizeInternalIO+finalize ctx = unsafeDupablePerformIO $ withCtxThrow ctx finalizeInternalIO {-# NOINLINE hash #-} -- | hash a strict bytestring into a digest bytestring hash :: Int -> ByteString -> ByteString-hash hashlen d = inlinePerformIO $ withCtxNewThrow $ \ptr -> do+hash hashlen d = unsafeDupablePerformIO $ withCtxNewThrow $ \ptr -> do c_skein256_init ptr (fromIntegral hashlen) >> updateInternalIO ptr d >> finalizeInternalIO ptr {-# NOINLINE hashlazy #-} -- | hash a lazy bytestring into a digest bytestring hashlazy :: Int -> L.ByteString -> ByteString-hashlazy hashlen l = inlinePerformIO $ withCtxNewThrow $ \ptr -> do+hashlazy hashlen l = unsafeDupablePerformIO $ withCtxNewThrow $ \ptr -> do c_skein256_init ptr (fromIntegral hashlen) >> mapM_ (updateInternalIO ptr) (L.toChunks l) >> finalizeInternalIO ptr
Crypto/Hash/Skein512.hs view
@@ -16,6 +16,7 @@ -- * Incremental hashing Functions , init -- :: Int -> Ctx , update -- :: Ctx -> ByteString -> Ctx+ , updates -- :: Ctx -> [ByteString] -> Ctx , finalize -- :: Ctx -> ByteString -- * Single Pass hashing@@ -24,7 +25,6 @@ ) where import Prelude hiding (init)-import Foreign.C.Types import Foreign.Ptr import Foreign.ForeignPtr (withForeignPtr) import Foreign.Storable@@ -32,9 +32,9 @@ import qualified Data.ByteString.Lazy as L import Data.ByteString (ByteString) import Data.ByteString.Unsafe (unsafeUseAsCStringLen)-import Data.ByteString.Internal (create, inlinePerformIO, toForeignPtr)+import Data.ByteString.Internal (create, toForeignPtr) import Data.Word-import Data.Bits+import System.IO.Unsafe (unsafeDupablePerformIO) #ifdef HAVE_CRYPTOAPI @@ -58,19 +58,26 @@ #endif -data Ctx = Ctx !ByteString+newtype Ctx = Ctx ByteString data Skein512 = Digest !ByteString deriving (Eq,Ord,Show) ++{-# INLINE sizeCtx #-} sizeCtx :: Int-sizeCtx = 152+sizeCtx = 160 +{- return the number of bytes of output for the digest -} peekHashlen :: Ptr Ctx -> IO Int-peekHashlen ptr = do- let iptr = castPtr ptr :: Ptr CUInt- a <- peek iptr- return ((fromIntegral a + 7) `shiftR` 3)+peekHashlen ptr = peek iptr >>= \v -> return $! fromIntegral v+ where iptr :: Ptr Word32+ iptr = castPtr ptr +{-# RULES "hash" forall b i. finalize (update (init i) b) = hash i b #-}+{-# RULES "hash.list1" forall b i. finalize (updates (init i) [b]) = hash i b #-}+{-# RULES "hashmany" forall b i. finalize (foldl update (init i) b) = hashlazy i (L.fromChunks b) #-}+{-# RULES "hashlazy" forall b i. finalize (foldl update (init i) $ L.toChunks b) = hashlazy i b #-}+ {-# INLINE withByteStringPtr #-} withByteStringPtr :: ByteString -> (Ptr Word8 -> IO a) -> IO a withByteStringPtr b f =@@ -111,7 +118,6 @@ foreign import ccall unsafe "skein512.h skein512_finalize" c_skein512_finalize :: Ptr Ctx -> Ptr Word8 -> IO () - updateInternalIO :: Ptr Ctx -> ByteString -> IO () updateInternalIO ptr d = unsafeUseAsCStringLen d (\(cs, len) -> c_skein512_update ptr (castPtr cs) (fromIntegral len))@@ -123,26 +129,31 @@ {-# NOINLINE init #-} -- | init a context init :: Int -> Ctx-init hashlen = inlinePerformIO $ withCtxNew $ \ptr -> c_skein512_init ptr (fromIntegral hashlen)+init hashlen = unsafeDupablePerformIO $ withCtxNew $ \ptr -> c_skein512_init ptr (fromIntegral hashlen) {-# NOINLINE update #-} -- | update a context with a bytestring update :: Ctx -> ByteString -> Ctx-update ctx d = inlinePerformIO $ withCtxCopy ctx $ \ptr -> updateInternalIO ptr d+update ctx d = unsafeDupablePerformIO $ withCtxCopy ctx $ \ptr -> updateInternalIO ptr d +{-# NOINLINE updates #-}+-- | updates a context with multiples bytestring+updates :: Ctx -> [ByteString] -> Ctx+updates ctx d = unsafeDupablePerformIO $ withCtxCopy ctx $ \ptr -> mapM_ (updateInternalIO ptr) d+ {-# NOINLINE finalize #-} -- | finalize the context into a digest bytestring finalize :: Ctx -> ByteString-finalize ctx = inlinePerformIO $ withCtxThrow ctx finalizeInternalIO+finalize ctx = unsafeDupablePerformIO $ withCtxThrow ctx finalizeInternalIO {-# NOINLINE hash #-} -- | hash a strict bytestring into a digest bytestring hash :: Int -> ByteString -> ByteString-hash hashlen d = inlinePerformIO $ withCtxNewThrow $ \ptr -> do+hash hashlen d = unsafeDupablePerformIO $ withCtxNewThrow $ \ptr -> do c_skein512_init ptr (fromIntegral hashlen) >> updateInternalIO ptr d >> finalizeInternalIO ptr {-# NOINLINE hashlazy #-} -- | hash a lazy bytestring into a digest bytestring hashlazy :: Int -> L.ByteString -> ByteString-hashlazy hashlen l = inlinePerformIO $ withCtxNewThrow $ \ptr -> do+hashlazy hashlen l = unsafeDupablePerformIO $ withCtxNewThrow $ \ptr -> do c_skein512_init ptr (fromIntegral hashlen) >> mapM_ (updateInternalIO ptr) (L.toChunks l) >> finalizeInternalIO ptr
Crypto/Hash/Tiger.hs view
@@ -16,6 +16,7 @@ -- * Incremental hashing Functions , init -- :: Ctx , update -- :: Ctx -> ByteString -> Ctx+ , updates -- :: Ctx -> [ByteString] -> Ctx , finalize -- :: Ctx -> ByteString -- * Single Pass hashing@@ -29,10 +30,12 @@ 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, inlinePerformIO)+import Data.ByteString.Internal (create, toForeignPtr) import Data.Word+import System.IO.Unsafe (unsafeDupablePerformIO) #ifdef HAVE_CRYPTOAPI @@ -56,7 +59,7 @@ #endif -data Ctx = Ctx !ByteString+newtype Ctx = Ctx ByteString data Tiger = Digest !ByteString deriving (Eq,Ord,Show) @@ -69,6 +72,12 @@ 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 =@@ -114,32 +123,36 @@ unsafeUseAsCStringLen d (\(cs, len) -> c_tiger_update ptr (castPtr cs) (fromIntegral len)) finalizeInternalIO :: Ptr Ctx -> IO ByteString-finalizeInternalIO ptr =- create digestSize (c_tiger_finalize ptr)+finalizeInternalIO ptr = create digestSize (c_tiger_finalize ptr) {-# NOINLINE init #-} -- | init a context init :: Ctx-init = inlinePerformIO $ withCtxNew $ c_tiger_init+init = unsafeDupablePerformIO $ withCtxNew $ c_tiger_init {-# NOINLINE update #-} -- | update a context with a bytestring update :: Ctx -> ByteString -> Ctx-update ctx d = inlinePerformIO $ withCtxCopy ctx $ \ptr -> updateInternalIO ptr d+update ctx d = unsafeDupablePerformIO $ withCtxCopy ctx $ \ptr -> updateInternalIO ptr d +{-# NOINLINE updates #-}+-- | updates a context with multiples bytestring+updates :: Ctx -> [ByteString] -> Ctx+updates ctx d = unsafeDupablePerformIO $ withCtxCopy ctx $ \ptr -> mapM_ (updateInternalIO ptr) d+ {-# NOINLINE finalize #-} -- | finalize the context into a digest bytestring finalize :: Ctx -> ByteString-finalize ctx = inlinePerformIO $ withCtxThrow ctx finalizeInternalIO+finalize ctx = unsafeDupablePerformIO $ withCtxThrow ctx finalizeInternalIO {-# NOINLINE hash #-} -- | hash a strict bytestring into a digest bytestring hash :: ByteString -> ByteString-hash d = inlinePerformIO $ withCtxNewThrow $ \ptr -> do+hash d = unsafeDupablePerformIO $ withCtxNewThrow $ \ptr -> do c_tiger_init ptr >> updateInternalIO ptr d >> finalizeInternalIO ptr {-# NOINLINE hashlazy #-} -- | hash a lazy bytestring into a digest bytestring hashlazy :: L.ByteString -> ByteString-hashlazy l = inlinePerformIO $ withCtxNewThrow $ \ptr -> do+hashlazy l = unsafeDupablePerformIO $ withCtxNewThrow $ \ptr -> do c_tiger_init ptr >> mapM_ (updateInternalIO ptr) (L.toChunks l) >> finalizeInternalIO ptr
+ Crypto/Hash/Types.hs view
@@ -0,0 +1,49 @@+-- |+-- Module : Crypto.Hash.Types+-- License : BSD-style+-- Maintainer : Vincent Hanquez <vincent@snarc.org>+-- Stability : experimental+-- Portability : unknown+--+-- Crypto hash types definitions+--+module Crypto.Hash.Types+ ( HashAlgorithm(..)+ , Context(..)+ , Digest(..)+ )+ where++import Data.ByteString (ByteString)+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++-- | Represent a context for a given hash algorithm.+newtype Context a = Context { contextToByteString :: ByteString }++-- | Represent a digest for a given hash algorithm.+newtype Digest a = Digest { digestToByteString :: ByteString -- ^ Return the binary digest+ }+ deriving (Eq,Ord)++instance Show (Digest a) where+ show (Digest bs) = BC.unpack $ toHex bs
+ Crypto/Hash/Utils.hs view
@@ -0,0 +1,72 @@+{-# 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)+import Foreign.Storable (poke, peek)++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 = loop db sb+ where end = sb `plusPtr` len+ loop 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)+ loop (d `plusPtr` 2) (s `plusPtr` 1)++ r :: Addr# -> Int -> Word8+ r table (I# index) = W8# (indexWord8OffAddr# table index)++ !tableLo =+ "\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x61\x62\x63\x64\x65\x66\+ \\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x61\x62\x63\x64\x65\x66\+ \\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x61\x62\x63\x64\x65\x66\+ \\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x61\x62\x63\x64\x65\x66\+ \\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x61\x62\x63\x64\x65\x66\+ \\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x61\x62\x63\x64\x65\x66\+ \\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x61\x62\x63\x64\x65\x66\+ \\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x61\x62\x63\x64\x65\x66\+ \\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x61\x62\x63\x64\x65\x66\+ \\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x61\x62\x63\x64\x65\x66\+ \\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x61\x62\x63\x64\x65\x66\+ \\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x61\x62\x63\x64\x65\x66\+ \\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x61\x62\x63\x64\x65\x66\+ \\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x61\x62\x63\x64\x65\x66\+ \\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x61\x62\x63\x64\x65\x66\+ \\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x61\x62\x63\x64\x65\x66"#+ !tableHi =+ "\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\+ \\x31\x31\x31\x31\x31\x31\x31\x31\x31\x31\x31\x31\x31\x31\x31\x31\+ \\x32\x32\x32\x32\x32\x32\x32\x32\x32\x32\x32\x32\x32\x32\x32\x32\+ \\x33\x33\x33\x33\x33\x33\x33\x33\x33\x33\x33\x33\x33\x33\x33\x33\+ \\x34\x34\x34\x34\x34\x34\x34\x34\x34\x34\x34\x34\x34\x34\x34\x34\+ \\x35\x35\x35\x35\x35\x35\x35\x35\x35\x35\x35\x35\x35\x35\x35\x35\+ \\x36\x36\x36\x36\x36\x36\x36\x36\x36\x36\x36\x36\x36\x36\x36\x36\+ \\x37\x37\x37\x37\x37\x37\x37\x37\x37\x37\x37\x37\x37\x37\x37\x37\+ \\x38\x38\x38\x38\x38\x38\x38\x38\x38\x38\x38\x38\x38\x38\x38\x38\+ \\x39\x39\x39\x39\x39\x39\x39\x39\x39\x39\x39\x39\x39\x39\x39\x39\+ \\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\+ \\x62\x62\x62\x62\x62\x62\x62\x62\x62\x62\x62\x62\x62\x62\x62\x62\+ \\x63\x63\x63\x63\x63\x63\x63\x63\x63\x63\x63\x63\x63\x63\x63\x63\+ \\x64\x64\x64\x64\x64\x64\x64\x64\x64\x64\x64\x64\x64\x64\x64\x64\+ \\x65\x65\x65\x65\x65\x65\x65\x65\x65\x65\x65\x65\x65\x65\x65\x65\+ \\x66\x66\x66\x66\x66\x66\x66\x66\x66\x66\x66\x66\x66\x66\x66\x66"#
Crypto/Hash/Whirlpool.hs view
@@ -16,6 +16,7 @@ -- * Incremental hashing Functions , init -- :: Ctx , update -- :: Ctx -> ByteString -> Ctx+ , updates -- :: Ctx -> [ByteString] -> Ctx , finalize -- :: Ctx -> ByteString -- * Single Pass hashing@@ -29,10 +30,12 @@ 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, inlinePerformIO)+import Data.ByteString.Internal (create, toForeignPtr) import Data.Word+import System.IO.Unsafe (unsafeDupablePerformIO) #ifdef HAVE_CRYPTOAPI @@ -56,7 +59,7 @@ #endif -data Ctx = Ctx !ByteString+newtype Ctx = Ctx ByteString data Whirlpool = Digest !ByteString deriving (Eq,Ord,Show) @@ -69,6 +72,12 @@ 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 =@@ -114,32 +123,36 @@ unsafeUseAsCStringLen d (\(cs, len) -> c_whirlpool_update ptr (castPtr cs) (fromIntegral len)) finalizeInternalIO :: Ptr Ctx -> IO ByteString-finalizeInternalIO ptr =- create digestSize (c_whirlpool_finalize ptr)+finalizeInternalIO ptr = create digestSize (c_whirlpool_finalize ptr) {-# NOINLINE init #-} -- | init a context init :: Ctx-init = inlinePerformIO $ withCtxNew $ c_whirlpool_init+init = unsafeDupablePerformIO $ withCtxNew $ c_whirlpool_init {-# NOINLINE update #-} -- | update a context with a bytestring update :: Ctx -> ByteString -> Ctx-update ctx d = inlinePerformIO $ withCtxCopy ctx $ \ptr -> updateInternalIO ptr d+update ctx d = unsafeDupablePerformIO $ withCtxCopy ctx $ \ptr -> updateInternalIO ptr d +{-# NOINLINE updates #-}+-- | updates a context with multiples bytestring+updates :: Ctx -> [ByteString] -> Ctx+updates ctx d = unsafeDupablePerformIO $ withCtxCopy ctx $ \ptr -> mapM_ (updateInternalIO ptr) d+ {-# NOINLINE finalize #-} -- | finalize the context into a digest bytestring finalize :: Ctx -> ByteString-finalize ctx = inlinePerformIO $ withCtxThrow ctx finalizeInternalIO+finalize ctx = unsafeDupablePerformIO $ withCtxThrow ctx finalizeInternalIO {-# NOINLINE hash #-} -- | hash a strict bytestring into a digest bytestring hash :: ByteString -> ByteString-hash d = inlinePerformIO $ withCtxNewThrow $ \ptr -> do+hash d = unsafeDupablePerformIO $ withCtxNewThrow $ \ptr -> do c_whirlpool_init ptr >> updateInternalIO ptr d >> finalizeInternalIO ptr {-# NOINLINE hashlazy #-} -- | hash a lazy bytestring into a digest bytestring hashlazy :: L.ByteString -> ByteString-hashlazy l = inlinePerformIO $ withCtxNewThrow $ \ptr -> do+hashlazy l = unsafeDupablePerformIO $ withCtxNewThrow $ \ptr -> do c_whirlpool_init ptr >> mapM_ (updateInternalIO ptr) (L.toChunks l) >> finalizeInternalIO ptr
README.md view
@@ -33,15 +33,16 @@ Incremental API --------------- -it's based on 3 different functions, similar to the lowlevel operations+it's based on 4 different functions, similar to the lowlevel operations of a typical hash: * init: create a new hash context * update: update non-destructively a new hash context with a strict bytestring+* updates: same as update, except that it takes a list of strict bytestring * 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 create a new context each time.+context as usual in others language, it re-allocate a new context each time. One Pass API ------------@@ -52,11 +53,33 @@ * hash: create a digest (init+update+finalize) from a strict bytestring * hashlazy: create a digest (init+update+finalize) from a lazy bytestring -Integration with crypto-api----------------------------+More Type safety+---------------- -cryptohash is fully integrated with crypto-api and you can use the-related function in crypto-api to use any cryptohash modules.+A more type safe API is also available from Crypto.Hash. The API provides+all the supported hashes in the same namespace, through unified functions.++It introduces 2 new types, the Context type and the Digest type.+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.++ import Crypto.Hash++ -- use the incremental API to hash the byte [1,2,3] with SHA1+ -- and print the hexadecimal digest.+ example1 = do+ let ctx = hashInit+ ctx' = hashUpdates ctx [ Data.ByteString.pack [1,2,3] ]+ dgt = hashFinalize ctx' :: Digest SHA1+ putStrLn $ show dgt++ -- use the one-pass API to hash the byte 1,2,3 with SHA3_512+ -- and print the hexadecimal digest.+ example2 = do+ let dgt = hash (Data.ByteString.pack [1,2,3]) :: Digest SHA3_512+ putStrLn $ show dgt Performance -----------
cbits/skein256.c view
@@ -108,7 +108,7 @@ uint64_t buf[4]; memset(ctx, 0, sizeof(*ctx)); - ctx->hashlen = hashlen;+ ctx->hashlen = (hashlen + 7) >> 3; SET_TYPE(ctx, FLAG_FIRST | FLAG_FINAL | FLAG_TYPE(TYPE_CFG)); memset(buf, '\0', sizeof(buf));@@ -167,7 +167,7 @@ memset(ctx->buf, '\0', 32); /* make sure we have a 8 bit rounded value */- outsize = (ctx->hashlen + 7) >> 3;+ outsize = ctx->hashlen; /* backup h[0--4] */ for (j = 0; j < 4; j++)
cbits/skein512.c view
@@ -126,7 +126,7 @@ uint64_t buf[8]; memset(ctx, 0, sizeof(*ctx)); - ctx->hashlen = hashlen;+ ctx->hashlen = (hashlen + 7) >> 3; SET_TYPE(ctx, FLAG_FIRST | FLAG_FINAL | FLAG_TYPE(TYPE_CFG)); memset(buf, '\0', sizeof(buf));@@ -185,7 +185,7 @@ memset(ctx->buf, '\0', 64); /* make sure we have a 8 bit rounded value */- outsize = (ctx->hashlen + 7) >> 3;+ outsize = ctx->hashlen; /* backup h[0--7] */ for (j = 0; j < 8; j++)
cbits/skein512.h view
@@ -28,7 +28,7 @@ struct skein512_ctx {- uint32_t hashlen; /* in bits, typically 384, 512 */+ uint32_t hashlen; /* in bytes, typically 384/8, 512/8 */ uint32_t bufindex; uint8_t buf[64]; uint64_t h[8];
cryptohash.cabal view
@@ -1,11 +1,33 @@ Name: cryptohash-Version: 0.7.10+Version: 0.8.0 Description: 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. . The implementations are made in C with a haskell FFI wrapper that hide the C implementation.-+ .+ Simple examples using the unified API:+ .+ > import Crypto.Hash+ >+ > sha1 :: ByteString -> Digest SHA1+ > sha1 = hash+ >+ > hexSha3_512 :: ByteString -> String+ > hexSha3_512 bs = show (hash bs :: Digest SHA3_512)+ .+ Simple examples using the module API:+ .+ > import qualified Crypto.Hash.SHA1 as SHA1+ >+ > main = putStrLn $ show $ SHA1.hash (Data.ByteString.pack [1..256])+ .+ > import qualified Crypto.Hash.SHA3 as SHA3+ >+ > main = putStrLn $ show $ digest+ > where digest = SHA3.finalize ctx+ > ctx = foldl' SHA3.update iCtx (map Data.ByteString.pack [ [1,2,3], [4,5,6] ]+ > iCtx = SHA3.init 224 License: BSD3 License-file: LICENSE Copyright: Vincent Hanquez <vincent@snarc.org>@@ -24,23 +46,21 @@ cbits/skein.h cbits/skein256.h cbits/skein512.h cbits/tiger.h cbits/whirlpool.h -Flag benchmark- Description: Build benchmark test- Default: False- Flag cryptoapi Description: Defines crypto-api instances Default: True Library- Build-Depends: base >= 4 && < 6, bytestring+ Build-Depends: base >= 4 && < 6, bytestring, ghc-prim if flag(cryptoapi) Build-depends: crypto-api >= 0.5, tagged >= 0.1, cereal >= 0.2 cpp-options: -DHAVE_CRYPTOAPI if impl(ghc >= 7.2.1) Extensions: Trustworthy Extensions: ForeignFunctionInterface- Exposed-modules: Crypto.Hash.SHA1+ Exposed-modules: Crypto.Hash+ Crypto.Hash.Types+ Crypto.Hash.SHA1 Crypto.Hash.SHA224 Crypto.Hash.SHA256 Crypto.Hash.SHA384@@ -56,6 +76,7 @@ Crypto.Hash.Tiger Crypto.Hash.Whirlpool Crypto.MAC.HMAC+ Other-modules: Crypto.Hash.Utils ghc-options: -Wall -O2 -optc-O3 -fno-cse -fwarn-tabs C-sources: cbits/sha1.c cbits/sha256.c@@ -84,14 +105,17 @@ , test-framework-hunit , cryptohash -Executable Bench+Benchmark bench-hashes Main-Is: Bench.hs hs-source-dirs: Bench- if flag(benchmark)- Buildable: True- Build-depends: base >= 4, bytestring, criterion, cryptohash- else- Buildable: False+ type: exitcode-stdio-1.0+ Build-depends: base >= 4, bytestring, criterion, cryptohash++Benchmark bench-api+ Main-Is: BenchAPI.hs+ hs-source-dirs: Bench+ type: exitcode-stdio-1.0+ Build-depends: base >= 4, bytestring, criterion, cryptohash, crypto-api source-repository head type: git