packages feed

cryptohash 0.10.0 → 0.11.0

raw patch · 23 files changed

+180/−74 lines, 23 filesdep ~base

Dependency ranges changed: base

Files

+ Bench/BenchHMAC.hs view
@@ -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 . hmac MD5 b32) b32+        , bench "hmac-sha1" $ whnf (toBytes . hmac SHA1 b32) b32+        ]
Crypto/Hash.hs view
@@ -1,4 +1,3 @@-{-# LANGUAGE EmptyDataDecls #-} {-# LANGUAGE CPP #-} -- | -- Module      : Crypto.Hash@@ -23,33 +22,34 @@     , 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+    , 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(..)     -- * MAC algorithms     , HMAC(..)     , hmac-    )-    where+    , hmacAlg+    ) where  import Crypto.Hash.Types import Crypto.Hash.Utils@@ -96,71 +96,109 @@ digestToHexByteString :: Digest a -> ByteString digestToHexByteString = toHex . toBytes -#define DEFINE_INSTANCE(NAME, MODULENAME) \-data NAME; \+#define DEFINE_INSTANCE(NAME, MODULENAME, BLOCKSIZE) \+data NAME = NAME deriving Show; \ instance HashAlgorithm NAME where \     { hashInit = Context c where { (MODULENAME.Ctx c) = MODULENAME.init } \+    ; hashBlockSize ~(Context _) = BLOCKSIZE \     ; 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) } \     }; -#define DEFINE_INSTANCE_LEN(NAME, MODULENAME, LEN) \-data NAME; \+#define DEFINE_INSTANCE_LEN(NAME, MODULENAME, LEN, BLOCKSIZE) \+data NAME = NAME deriving Show; \ instance HashAlgorithm NAME where \     { hashInit = Context c where { (MODULENAME.Ctx c) = MODULENAME.init LEN } \+    ; hashBlockSize ~(Context _) = BLOCKSIZE \     ; 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_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
Crypto/Hash/MD2.hs view
@@ -36,6 +36,7 @@ import Data.Word import Crypto.Hash.Internal (unsafeDoIO) +-- | MD2 Context newtype Ctx = Ctx ByteString  {-# INLINE digestSize #-}
Crypto/Hash/MD4.hs view
@@ -36,6 +36,7 @@ import Data.Word import Crypto.Hash.Internal (unsafeDoIO) +-- | MD4 Context newtype Ctx = Ctx ByteString  {-# INLINE digestSize #-}
Crypto/Hash/MD5.hs view
@@ -36,6 +36,7 @@ import Data.Word import Crypto.Hash.Internal (unsafeDoIO) +-- | MD5 Context newtype Ctx = Ctx ByteString  {-# INLINE digestSize #-}
Crypto/Hash/RIPEMD160.hs view
@@ -36,6 +36,7 @@ import Data.Word import Crypto.Hash.Internal (unsafeDoIO) +-- | RIPEMD160 Context newtype Ctx = Ctx ByteString  {-# INLINE digestSize #-}
Crypto/Hash/SHA1.hs view
@@ -36,6 +36,7 @@ import Data.Word import Crypto.Hash.Internal (unsafeDoIO) +-- | SHA1 Context newtype Ctx = Ctx ByteString  {-# INLINE digestSize #-}
Crypto/Hash/SHA224.hs view
@@ -36,6 +36,7 @@ import Data.Word import Crypto.Hash.Internal (unsafeDoIO) +-- | SHA224 Context newtype Ctx = Ctx ByteString  {-# INLINE digestSize #-}
Crypto/Hash/SHA256.hs view
@@ -36,6 +36,7 @@ import Data.Word import Crypto.Hash.Internal (unsafeDoIO) +-- | SHA256 Context newtype Ctx = Ctx ByteString  {-# INLINE digestSize #-}
Crypto/Hash/SHA3.hs view
@@ -35,6 +35,7 @@ import Data.Word import Crypto.Hash.Internal (unsafeDoIO) +-- | SHA3 Context newtype Ctx = Ctx ByteString  {-# INLINE sizeCtx #-}
Crypto/Hash/SHA384.hs view
@@ -36,6 +36,7 @@ import Data.Word import Crypto.Hash.Internal (unsafeDoIO) +-- | SHA384 Context newtype Ctx = Ctx ByteString  {-# INLINE digestSize #-}
Crypto/Hash/SHA512.hs view
@@ -37,6 +37,7 @@ import Data.Word import Crypto.Hash.Internal (unsafeDoIO) +-- | SHA512 Context newtype Ctx = Ctx ByteString  {-# INLINE digestSize #-}
Crypto/Hash/SHA512t.hs view
@@ -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
Crypto/Hash/Skein256.hs view
@@ -35,6 +35,7 @@ import Data.Word import Crypto.Hash.Internal (unsafeDoIO) +-- | Skein256 Context newtype Ctx = Ctx ByteString  {-# INLINE sizeCtx #-}
Crypto/Hash/Skein512.hs view
@@ -35,6 +35,7 @@ import Data.Word import Crypto.Hash.Internal (unsafeDoIO) +-- | Skein512 Context newtype Ctx = Ctx ByteString  {-# INLINE sizeCtx #-}
Crypto/Hash/Tiger.hs view
@@ -36,6 +36,7 @@ import Data.Word import Crypto.Hash.Internal (unsafeDoIO) +-- | Tiger Context newtype Ctx = Ctx ByteString  {-# INLINE digestSize #-}
Crypto/Hash/Types.hs view
@@ -31,6 +31,9 @@ --   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 
Crypto/Hash/Utils.hs view
@@ -23,6 +23,8 @@ import Crypto.Hash.Utils.Cpu import Data.Bits (testBit) +-- | Convert a bytestring to the hexadecimal equivalent+-- using 0123456789abcdef as digit toHex :: ByteString -> ByteString toHex (B.PS fp off len) = B.unsafeCreate (len*2) $ \d ->         withForeignPtr fp $ \s -> start d (s `plusPtr` off)
Crypto/Hash/Whirlpool.hs view
@@ -36,6 +36,7 @@ import Data.Word import Crypto.Hash.Internal (unsafeDoIO) +-- | Whirlpool Context newtype Ctx = Ctx ByteString  {-# INLINE digestSize #-}
README.md view
@@ -42,7 +42,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 +63,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 +84,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
Tests/KAT.hs view
@@ -4,6 +4,7 @@ import Data.Bits import Data.Word import Data.ByteString (ByteString)+import Data.Byteable import qualified Data.ByteString as B import qualified Data.ByteString.Char8 as BC import qualified Crypto.Hash.MD2 as MD2@@ -22,7 +23,6 @@ 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 Test.Framework (Test, defaultMain, testGroup) import Test.Framework.Providers.QuickCheck2 (testProperty)@@ -239,14 +239,37 @@     , 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"     ] +sha3_key1 = "\x4a\x65\x66\x65"+sha3_data1 = "\x77\x68\x61\x74\x20\x64\x6f\x20\x79\x61\x20\x77\x61\x6e\x74\x20\x66\x6f\x72\x20\x6e\x6f\x74\x68\x69\x6e\x67\x3f"++sha3_224_MAC_Vectors =+    [ MACVector sha3_key1 sha3_data1 "\xe8\x24\xfe\xc9\x6c\x07\x4f\x22\xf9\x92\x35\xbb\x94\x2d\xa1\x98\x26\x64\xab\x69\x2c\xa8\x50\x10\x53\xcb\xd4\x14"+    ]++sha3_256_MAC_Vectors =+    [  MACVector sha3_key1 sha3_data1 "\xaa\x9a\xed\x44\x8c\x7a\xbc\x8b\x5e\x32\x6f\xfa\x6a\x01\xcd\xed\xf7\xb4\xb8\x31\x88\x14\x68\xc0\x44\xba\x8d\xd4\x56\x63\x69\xa1"+    ]++sha3_384_MAC_Vectors =+    [ MACVector sha3_key1 sha3_data1 "\x5a\xf5\xc9\xa7\x7a\x23\xa6\xa9\x3d\x80\x64\x9e\x56\x2a\xb7\x7f\x4f\x35\x52\xe3\xc5\xca\xff\xd9\x3b\xdf\x8b\x3c\xfc\x69\x20\xe3\x02\x3f\xc2\x67\x75\xd9\xdf\x1f\x3c\x94\x61\x31\x46\xad\x2c\x9d"+    ]++sha3_512_MAC_Vectors =+    [ MACVector sha3_key1 sha3_data1 "\xc2\x96\x2e\x5b\xbe\x12\x38\x00\x78\x52\xf7\x9d\x81\x4d\xbb\xec\xd4\x68\x2e\x6f\x09\x7d\x37\xa3\x63\x58\x7c\x03\xbf\xa2\xeb\x08\x59\xd8\xd9\xc7\x01\xe0\x4c\xec\xec\xfd\x3d\xd7\xbf\xd4\x38\xf2\x0b\x8b\x64\x8e\x01\xbf\x8c\x11\xd2\x68\x24\xb9\x6c\xeb\xbd\xcb"+    ]+ macTests :: [Test] 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+    , testGroup "hmac-sha3-224" $ map (toMACTest SHA3_224) $ zip [0..] sha3_224_MAC_Vectors+    , testGroup "hmac-sha3-256" $ map (toMACTest SHA3_256) $ zip [0..] sha3_256_MAC_Vectors+    , testGroup "hmac-sha3-384" $ map (toMACTest SHA3_384) $ zip [0..] sha3_384_MAC_Vectors+    , testGroup "hmac-sha3-512" $ map (toMACTest SHA3_512) $ zip [0..] sha3_512_MAC_Vectors     ]-    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 (hmac hashAlg (macKey macVector) (macSecret macVector)))  main = defaultMain     [ testGroup "KATs" katTests
cbits/bitfn.h view
@@ -169,6 +169,12 @@   # 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 #else   # include <endian.h> #endif
cryptohash.cabal view
@@ -1,8 +1,8 @@ Name:                cryptohash-Version:             0.10.0+Version:             0.11.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.+    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 +20,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,13 +38,13 @@ 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/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@@ -95,6 +95,7 @@   Main-Is:           KAT.hs   Build-depends:     base >= 4 && < 5                    , bytestring+                   , byteable                    , HUnit                    , QuickCheck >= 2                    , test-framework >= 0.3.3@@ -107,6 +108,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