SHA2-0.2.0: Codec/Digest/SHA.hs
-- | A pure interface to SHA2
module Codec.Digest.SHA(
Length(..), hash, hmac,
showBSasHex
) where
import Codec.Digest.SHA.Monad
import qualified Data.ByteString as B
import Data.Bits(xor)
-- | Plain SHA2
hash :: Hashable a => Length -> a -> 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)]
-- | SHA2-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