module Crypto.MAC.HMAC
( hmac
) where
import Data.ByteString (ByteString)
import qualified Data.ByteString as B
import Data.Bits (xor)
hmac :: (ByteString -> ByteString)
-> Int
-> ByteString
-> ByteString
-> ByteString
hmac :: (ByteString -> ByteString)
-> Int -> ByteString -> ByteString -> ByteString
hmac ByteString -> ByteString
hashF Int
blockSize ByteString
secret ByteString
msg = ByteString -> ByteString
hashF forall a b. (a -> b) -> a -> b
$ ByteString -> ByteString -> ByteString
B.append ByteString
opad (ByteString -> ByteString
hashF forall a b. (a -> b) -> a -> b
$ ByteString -> ByteString -> ByteString
B.append ByteString
ipad ByteString
msg)
where opad :: ByteString
opad = (Word8 -> Word8) -> ByteString -> ByteString
B.map (forall a. Bits a => a -> a -> a
xor Word8
0x5c) ByteString
k'
ipad :: ByteString
ipad = (Word8 -> Word8) -> ByteString -> ByteString
B.map (forall a. Bits a => a -> a -> a
xor Word8
0x36) ByteString
k'
k' :: ByteString
k' = ByteString -> ByteString -> ByteString
B.append ByteString
kt ByteString
pad
kt :: ByteString
kt = if ByteString -> Int
B.length ByteString
secret forall a. Ord a => a -> a -> Bool
> forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
blockSize then ByteString -> ByteString
hashF ByteString
secret else ByteString
secret
pad :: ByteString
pad = Int -> Word8 -> ByteString
B.replicate (forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
blockSize forall a. Num a => a -> a -> a
- ByteString -> Int
B.length ByteString
kt) Word8
0