cryptohash 0.11.4 → 0.11.5
raw patch · 7 files changed
+151/−17 lines, 7 filesdep +tastydep +tasty-hunitdep +tasty-quickcheckdep −test-frameworkdep −test-framework-hunitdep −test-framework-quickcheck2
Dependencies added: tasty, tasty-hunit, tasty-quickcheck
Dependencies removed: test-framework, test-framework-hunit, test-framework-quickcheck2
Files
- Crypto/Hash.hs +10/−1
- Crypto/Hash/Types.hs +6/−3
- Crypto/MAC.hs +75/−0
- Crypto/MAC/HMAC.hs +3/−0
- LICENSE +1/−1
- Tests/KAT.hs +51/−8
- cryptohash.cabal +5/−4
Crypto/Hash.hs view
@@ -6,7 +6,16 @@ -- 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 (
Crypto/Hash/Types.hs view
@@ -26,9 +26,12 @@ -- -- 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+-- * 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
+ Crypto/MAC.hs view
@@ -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]
Crypto/MAC/HMAC.hs view
@@ -17,6 +17,9 @@ import Data.Bits (xor) -- | compute a MAC using the supplied hashing function+--+-- An incremental API can be found in the module "Crypto.Hash".+-- hmac :: (ByteString -> ByteString) -- ^ hash function -> Int -- ^ block size -> ByteString -- ^ secret
LICENSE view
@@ -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.
Tests/KAT.hs view
@@ -5,6 +5,8 @@ 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@@ -23,11 +25,11 @@ import qualified Crypto.Hash.Skein512 as Skein512 import qualified Crypto.Hash.Whirlpool as Whirlpool import Crypto.Hash+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 +37,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) }@@ -205,10 +210,10 @@ , 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))@@ -258,7 +263,7 @@ [ 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 :: [TestTree] macTests = [ testGroup "hmac-md5" $ map (toMACTest MD5) $ zip [0..] md5MACVectors , testGroup "hmac-sha1" $ map (toMACTest SHA1) $ zip [0..] sha1MACVectors@@ -271,8 +276,46 @@ 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+ , 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++ , 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+ , testProperty "hmac-sha3-224" $ prop_inc0 SHA3_224+ , testProperty "hmac-sha3-224" $ prop_inc1 SHA3_224+ , testProperty "hmac-sha3-256" $ prop_inc0 SHA3_256+ , testProperty "hmac-sha3-256" $ prop_inc1 SHA3_256+ , testProperty "hmac-sha3-384" $ prop_inc0 SHA3_384+ , testProperty "hmac-sha3-384" $ prop_inc1 SHA3_384+ , testProperty "hmac-sha3-512" $ prop_inc0 SHA3_512+ , testProperty "hmac-sha3-512" $ prop_inc1 SHA3_512+ ]+ 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 ]
cryptohash.cabal view
@@ -1,5 +1,5 @@ Name: cryptohash-Version: 0.11.4+Version: 0.11.5 Description: A collection of crypto hashes, with a practical incremental and one-pass, pure APIs, with performance close to the fastest implementations available in other languages.@@ -53,6 +53,7 @@ Extensions: ForeignFunctionInterface Exposed-modules: Crypto.Hash Crypto.Hash.Types+ Crypto.MAC Crypto.Hash.SHA1 Crypto.Hash.SHA224 Crypto.Hash.SHA256@@ -98,9 +99,9 @@ , 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