SHA2-0.1.0: Codec/Digest/SHA.hs
-- | A pure interface to SHA
module Codec.Digest.SHA(
Length(..), hash, hash', hmac,
showBSasHex
) where
import Codec.Digest.SHA.Monad
import qualified Data.ByteString as B
import qualified Data.ByteString.Lazy as BL
import Data.Bits(xor)
-- | Hashing lazy bytestrings
hash :: Length -> BL.ByteString -> B.ByteString
hash len bs = snd $ runSHA len (update bs)
-- | Hashing strict bytestrings
hash' :: Length -> B.ByteString -> B.ByteString
hash' len bs = snd $ runSHA len (update bs)
lenBytes :: Num a => Length -> a
lenBytes SHA256 = 32
lenBytes SHA384 = 48
lenBytes SHA512 = 64
fixkey :: B.ByteString -> Length -> B.ByteString
fixkey k (lenBytes -> len) = if B.length k >= len
then B.take len k
else B.concat [k,(B.replicate (len - B.length k) 0)]
-- | SHA-based HMAC, see http://en.wikipedia.org/wiki/HMAC
--
-- If you're doing encryption and want to prevent attackers from
-- changing your messages, you probably want this.
hmac :: Hashable a
=> Length -- ^ Desired size of the HMAC
-> B.ByteString -- ^ The shared secret key to use
-> a -- ^ Message to hash
-> B.ByteString
hmac len key' msg = hash' len $ B.concat [opad,ihash]
where
ihash = snd $ runSHA len $ update ipad >> update msg
opad = B.map (xor 0x5c) key
ipad = B.map (xor 0x36) key
key = fixkey key' len