-- | 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