{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE CPP #-}
{-# LANGUAGE MultiParamTypeClasses #-}
-----------------------------------------------------------------------------
--
-- Module      : Data.Digest.Pure.MD5
-- License     : BSD3
-- Maintainer  : Thomas.DuBuisson@gmail.com
-- Stability   : experimental
-- Portability : portable
-- Tested with : GHC-7.6.3
--
-- | It is suggested you use the 'crypto-api' class-based interface to access the MD5 algorithm.
-- Either rely on type inference or provide an explicit type:
--
-- @
--   hashFileStrict = liftM hash' . B.readFile
--   hashFileLazyBS = liftM hash . B.readFile
-- @
--
-----------------------------------------------------------------------------

module Data.Digest.Pure.MD5
        (
        -- * Types
          MD5Context
        , MD5Digest
        -- * Static data
        , md5InitialContext
        -- * Functions
        , md5
        , md5Update
        , md5Finalize
        , md5DigestBytes
        -- * Crypto-API interface
        , Hash(..)
        ) where

import qualified Data.ByteString as B
import qualified Data.ByteString.Lazy as L
import Data.ByteString.Unsafe (unsafeDrop,unsafeUseAsCString)
import Data.ByteString.Internal
#if MIN_VERSION_binary(0,8,3)
import Data.ByteString.Builder.Extra as B
#endif
import Data.Bits
import Data.List
import Data.Word
import Foreign.Storable
import Foreign.Ptr (castPtr)
import Data.Binary
import Data.Binary.Get
import Data.Binary.Put
import qualified Data.Serialize.Get as G
import qualified Data.Serialize.Put as P
import qualified Data.Serialize as S
import Crypto.Classes (Hash(..), hash)
import Control.Monad (replicateM_)
import Data.Tagged
import Numeric
#ifdef FastWordExtract
import System.IO.Unsafe (unsafePerformIO)
#endif

-- | Block size in bits
md5BlockSize :: Int
md5BlockSize :: Int
md5BlockSize = Int
512

blockSizeBytes :: Int
blockSizeBytes :: Int
blockSizeBytes = Int
md5BlockSize Int -> Int -> Int
forall a. Integral a => a -> a -> a
`div` Int
8

-- | The type for intermediate results (from md5Update)
data MD5Partial = MD5Par {-# UNPACK #-} !Word32 {-# UNPACK #-} !Word32 {-# UNPACK #-} !Word32 {-# UNPACK #-} !Word32
    deriving (Eq MD5Partial
Eq MD5Partial
-> (MD5Partial -> MD5Partial -> Ordering)
-> (MD5Partial -> MD5Partial -> Bool)
-> (MD5Partial -> MD5Partial -> Bool)
-> (MD5Partial -> MD5Partial -> Bool)
-> (MD5Partial -> MD5Partial -> Bool)
-> (MD5Partial -> MD5Partial -> MD5Partial)
-> (MD5Partial -> MD5Partial -> MD5Partial)
-> Ord MD5Partial
MD5Partial -> MD5Partial -> Bool
MD5Partial -> MD5Partial -> Ordering
MD5Partial -> MD5Partial -> MD5Partial
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: MD5Partial -> MD5Partial -> MD5Partial
$cmin :: MD5Partial -> MD5Partial -> MD5Partial
max :: MD5Partial -> MD5Partial -> MD5Partial
$cmax :: MD5Partial -> MD5Partial -> MD5Partial
>= :: MD5Partial -> MD5Partial -> Bool
$c>= :: MD5Partial -> MD5Partial -> Bool
> :: MD5Partial -> MD5Partial -> Bool
$c> :: MD5Partial -> MD5Partial -> Bool
<= :: MD5Partial -> MD5Partial -> Bool
$c<= :: MD5Partial -> MD5Partial -> Bool
< :: MD5Partial -> MD5Partial -> Bool
$c< :: MD5Partial -> MD5Partial -> Bool
compare :: MD5Partial -> MD5Partial -> Ordering
$ccompare :: MD5Partial -> MD5Partial -> Ordering
$cp1Ord :: Eq MD5Partial
Ord, MD5Partial -> MD5Partial -> Bool
(MD5Partial -> MD5Partial -> Bool)
-> (MD5Partial -> MD5Partial -> Bool) -> Eq MD5Partial
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: MD5Partial -> MD5Partial -> Bool
$c/= :: MD5Partial -> MD5Partial -> Bool
== :: MD5Partial -> MD5Partial -> Bool
$c== :: MD5Partial -> MD5Partial -> Bool
Eq)

-- | The type for final results.
data MD5Context = MD5Ctx { MD5Context -> MD5Partial
mdPartial  :: {-# UNPACK #-} !MD5Partial,
                           MD5Context -> Word64
mdTotalLen :: {-# UNPACK #-} !Word64 }

-- |After finalizing a context, using md5Finalize, a new type
-- is returned to prevent 're-finalizing' the structure.
data MD5Digest = MD5Digest MD5Partial deriving (MD5Digest -> MD5Digest -> Bool
(MD5Digest -> MD5Digest -> Bool)
-> (MD5Digest -> MD5Digest -> Bool) -> Eq MD5Digest
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: MD5Digest -> MD5Digest -> Bool
$c/= :: MD5Digest -> MD5Digest -> Bool
== :: MD5Digest -> MD5Digest -> Bool
$c== :: MD5Digest -> MD5Digest -> Bool
Eq, Eq MD5Digest
Eq MD5Digest
-> (MD5Digest -> MD5Digest -> Ordering)
-> (MD5Digest -> MD5Digest -> Bool)
-> (MD5Digest -> MD5Digest -> Bool)
-> (MD5Digest -> MD5Digest -> Bool)
-> (MD5Digest -> MD5Digest -> Bool)
-> (MD5Digest -> MD5Digest -> MD5Digest)
-> (MD5Digest -> MD5Digest -> MD5Digest)
-> Ord MD5Digest
MD5Digest -> MD5Digest -> Bool
MD5Digest -> MD5Digest -> Ordering
MD5Digest -> MD5Digest -> MD5Digest
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: MD5Digest -> MD5Digest -> MD5Digest
$cmin :: MD5Digest -> MD5Digest -> MD5Digest
max :: MD5Digest -> MD5Digest -> MD5Digest
$cmax :: MD5Digest -> MD5Digest -> MD5Digest
>= :: MD5Digest -> MD5Digest -> Bool
$c>= :: MD5Digest -> MD5Digest -> Bool
> :: MD5Digest -> MD5Digest -> Bool
$c> :: MD5Digest -> MD5Digest -> Bool
<= :: MD5Digest -> MD5Digest -> Bool
$c<= :: MD5Digest -> MD5Digest -> Bool
< :: MD5Digest -> MD5Digest -> Bool
$c< :: MD5Digest -> MD5Digest -> Bool
compare :: MD5Digest -> MD5Digest -> Ordering
$ccompare :: MD5Digest -> MD5Digest -> Ordering
$cp1Ord :: Eq MD5Digest
Ord)

-- | The initial context to use when calling md5Update for the first time
md5InitialContext :: MD5Context
md5InitialContext :: MD5Context
md5InitialContext = MD5Partial -> Word64 -> MD5Context
MD5Ctx (Word32 -> Word32 -> Word32 -> Word32 -> MD5Partial
MD5Par Word32
h0 Word32
h1 Word32
h2 Word32
h3) Word64
0

h0,h1,h2,h3 :: Word32
h0 :: Word32
h0 = Word32
0x67452301
h1 :: Word32
h1 = Word32
0xEFCDAB89
h2 :: Word32
h2 = Word32
0x98BADCFE
h3 :: Word32
h3 = Word32
0x10325476

-- | Processes a lazy ByteString and returns the md5 digest.
--   This is probably what you want. You can use 'show' to produce the standard hex
-- representation.
md5 :: L.ByteString -> MD5Digest
md5 :: ByteString -> MD5Digest
md5 = ByteString -> MD5Digest
forall ctx d. (Hash ctx d, Hash ctx d) => ByteString -> d
hash

-- | Closes an MD5 context, thus producing the digest.
md5Finalize :: MD5Context -> B.ByteString -> MD5Digest
md5Finalize :: MD5Context -> ByteString -> MD5Digest
md5Finalize (MD5Ctx MD5Partial
par !Word64
totLen) ByteString
end =
        let totLen' :: Word64
totLen' = Word64
8Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
*(Word64
totLen Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
+ Int -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
l) :: Word64
            padBS :: ByteString
padBS = Put -> ByteString
P.runPut (Put -> ByteString) -> Put -> ByteString
forall a b. (a -> b) -> a -> b
$ do Putter ByteString
P.putByteString ByteString
end
                                  Putter Word8
P.putWord8 Word8
0x80
                                  Int -> Put -> Put
forall (m :: * -> *) a. Applicative m => Int -> m a -> m ()
replicateM_ Int
lenZeroPad (Putter Word8
P.putWord8 Word8
0)
                                  Putter Word64
P.putWord64le Word64
totLen'
        in MD5Partial -> MD5Digest
MD5Digest (MD5Partial -> MD5Digest) -> MD5Partial -> MD5Digest
forall a b. (a -> b) -> a -> b
$ MD5Partial -> ByteString -> MD5Partial
blockAndDo MD5Partial
par ByteString
padBS
    where
    l :: Int
l = ByteString -> Int
B.length ByteString
end
    lenZeroPad :: Int
lenZeroPad = if (Int
l Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
blockSizeBytes Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
8
                     then (Int
blockSizeBytes Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
8) Int -> Int -> Int
forall a. Num a => a -> a -> a
- (Int
l Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)
                     else (Int
2 Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
blockSizeBytes Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
8) Int -> Int -> Int
forall a. Num a => a -> a -> a
- (Int
l Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)

-- | Alters the MD5Context with a partial digest of the data.
--
-- The input bytestring MUST be a multiple of the blockSize
-- or bad things can happen (incorrect digest results)!
md5Update :: MD5Context -> B.ByteString -> MD5Context
md5Update :: MD5Context -> ByteString -> MD5Context
md5Update MD5Context
ctx ByteString
bs
  | ByteString -> Int
B.length ByteString
bs Int -> Int -> Int
forall a. Integral a => a -> a -> a
`rem` Int
blockSizeBytes Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
/= Int
0 = [Char] -> MD5Context
forall a. HasCallStack => [Char] -> a
error [Char]
"Invalid use of hash update routine (see crypto-api Hash class semantics)"
  | Bool
otherwise =
        let bs' :: ByteString
bs' = if ByteString -> Bool
isAligned ByteString
bs then ByteString
bs else ByteString -> ByteString
B.copy ByteString
bs -- copying has been measured as a net win on my x86 system
            new :: MD5Partial
new =  MD5Partial -> ByteString -> MD5Partial
blockAndDo (MD5Context -> MD5Partial
mdPartial MD5Context
ctx) ByteString
bs'
        in MD5Context
ctx { mdPartial :: MD5Partial
mdPartial = MD5Partial
new, mdTotalLen :: Word64
mdTotalLen = MD5Context -> Word64
mdTotalLen MD5Context
ctx Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
+ Int -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral (ByteString -> Int
B.length ByteString
bs) }

blockAndDo :: MD5Partial -> B.ByteString -> MD5Partial
blockAndDo :: MD5Partial -> ByteString -> MD5Partial
blockAndDo !MD5Partial
ctx ByteString
bs
  | ByteString -> Int
B.length ByteString
bs Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 = MD5Partial
ctx
  | Bool
otherwise =
        let !new :: MD5Partial
new = MD5Partial -> ByteString -> MD5Partial
performMD5Update MD5Partial
ctx ByteString
bs
        in MD5Partial -> ByteString -> MD5Partial
blockAndDo MD5Partial
new (Int -> ByteString -> ByteString
unsafeDrop Int
blockSizeBytes ByteString
bs)
{-# INLINE blockAndDo #-}

-- Assumes ByteString length == blockSizeBytes, will fold the
-- context across calls to applyMD5Rounds.
performMD5Update :: MD5Partial -> B.ByteString -> MD5Partial
performMD5Update :: MD5Partial -> ByteString -> MD5Partial
performMD5Update par :: MD5Partial
par@(MD5Par !Word32
a !Word32
b !Word32
c !Word32
d) !ByteString
bs =
        let MD5Par Word32
a' Word32
b' Word32
c' Word32
d' = MD5Partial -> ByteString -> MD5Partial
applyMD5Rounds MD5Partial
par ByteString
bs
        in Word32 -> Word32 -> Word32 -> Word32 -> MD5Partial
MD5Par (Word32
a' Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
+ Word32
a) (Word32
b' Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
+ Word32
b) (Word32
c' Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
+ Word32
c) (Word32
d' Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
+ Word32
d)
{-# INLINE performMD5Update #-}

isAligned :: ByteString -> Bool
#if !MIN_VERSION_bytestring(0,11,0)
isAligned :: ByteString -> Bool
isAligned (PS ForeignPtr Word8
_ Int
off Int
_) = Int
off Int -> Int -> Int
forall a. Integral a => a -> a -> a
`rem` Int
4 Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0
#else
isAligned = const True
-- This is semantically equivalent to the definition above, because
-- in bytestring-0.11 offset is always 0. Note that neither definition checks
-- that a pointer (the first field of 'PS') is aligned. Anyways 'isAligned'
-- is used for optimization purposes only and does not affect correctness.
#endif

applyMD5Rounds :: MD5Partial -> ByteString -> MD5Partial
applyMD5Rounds :: MD5Partial -> ByteString -> MD5Partial
applyMD5Rounds (MD5Par Word32
a Word32
b Word32
c Word32
d) ByteString
w = {-# SCC "applyMD5Rounds" #-}
        let -- Round 1
            !r0 :: Word32
r0  = Word32
-> Word32 -> Word32 -> Word32 -> Word32 -> Int -> Word32 -> Word32
forall a. (Num a, Bits a) => a -> a -> a -> a -> a -> Int -> a -> a
ff  Word32
a  Word32
b  Word32
c  Word32
d   (ByteString
wByteString -> Int -> Word32
forall a. Storable a => ByteString -> Int -> a
!!Int
0)  Int
7  Word32
3614090360
            !r1 :: Word32
r1  = Word32
-> Word32 -> Word32 -> Word32 -> Word32 -> Int -> Word32 -> Word32
forall a. (Num a, Bits a) => a -> a -> a -> a -> a -> Int -> a -> a
ff  Word32
d Word32
r0  Word32
b  Word32
c   (ByteString
wByteString -> Int -> Word32
forall a. Storable a => ByteString -> Int -> a
!!Int
1)  Int
12 Word32
3905402710
            !r2 :: Word32
r2  = Word32
-> Word32 -> Word32 -> Word32 -> Word32 -> Int -> Word32 -> Word32
forall a. (Num a, Bits a) => a -> a -> a -> a -> a -> Int -> a -> a
ff  Word32
c Word32
r1 Word32
r0  Word32
b   (ByteString
wByteString -> Int -> Word32
forall a. Storable a => ByteString -> Int -> a
!!Int
2)  Int
17 Word32
606105819
            !r3 :: Word32
r3  = Word32
-> Word32 -> Word32 -> Word32 -> Word32 -> Int -> Word32 -> Word32
forall a. (Num a, Bits a) => a -> a -> a -> a -> a -> Int -> a -> a
ff  Word32
b Word32
r2 Word32
r1 Word32
r0   (ByteString
wByteString -> Int -> Word32
forall a. Storable a => ByteString -> Int -> a
!!Int
3)  Int
22 Word32
3250441966
            !r4 :: Word32
r4  = Word32
-> Word32 -> Word32 -> Word32 -> Word32 -> Int -> Word32 -> Word32
forall a. (Num a, Bits a) => a -> a -> a -> a -> a -> Int -> a -> a
ff Word32
r0 Word32
r3 Word32
r2 Word32
r1   (ByteString
wByteString -> Int -> Word32
forall a. Storable a => ByteString -> Int -> a
!!Int
4)  Int
7  Word32
4118548399
            !r5 :: Word32
r5  = Word32
-> Word32 -> Word32 -> Word32 -> Word32 -> Int -> Word32 -> Word32
forall a. (Num a, Bits a) => a -> a -> a -> a -> a -> Int -> a -> a
ff Word32
r1 Word32
r4 Word32
r3 Word32
r2   (ByteString
wByteString -> Int -> Word32
forall a. Storable a => ByteString -> Int -> a
!!Int
5)  Int
12 Word32
1200080426
            !r6 :: Word32
r6  = Word32
-> Word32 -> Word32 -> Word32 -> Word32 -> Int -> Word32 -> Word32
forall a. (Num a, Bits a) => a -> a -> a -> a -> a -> Int -> a -> a
ff Word32
r2 Word32
r5 Word32
r4 Word32
r3   (ByteString
wByteString -> Int -> Word32
forall a. Storable a => ByteString -> Int -> a
!!Int
6)  Int
17 Word32
2821735955
            !r7 :: Word32
r7  = Word32
-> Word32 -> Word32 -> Word32 -> Word32 -> Int -> Word32 -> Word32
forall a. (Num a, Bits a) => a -> a -> a -> a -> a -> Int -> a -> a
ff Word32
r3 Word32
r6 Word32
r5 Word32
r4   (ByteString
wByteString -> Int -> Word32
forall a. Storable a => ByteString -> Int -> a
!!Int
7)  Int
22 Word32
4249261313
            !r8 :: Word32
r8  = Word32
-> Word32 -> Word32 -> Word32 -> Word32 -> Int -> Word32 -> Word32
forall a. (Num a, Bits a) => a -> a -> a -> a -> a -> Int -> a -> a
ff Word32
r4 Word32
r7 Word32
r6 Word32
r5   (ByteString
wByteString -> Int -> Word32
forall a. Storable a => ByteString -> Int -> a
!!Int
8)  Int
7  Word32
1770035416
            !r9 :: Word32
r9  = Word32
-> Word32 -> Word32 -> Word32 -> Word32 -> Int -> Word32 -> Word32
forall a. (Num a, Bits a) => a -> a -> a -> a -> a -> Int -> a -> a
ff Word32
r5 Word32
r8 Word32
r7 Word32
r6   (ByteString
wByteString -> Int -> Word32
forall a. Storable a => ByteString -> Int -> a
!!Int
9)  Int
12 Word32
2336552879
            !r10 :: Word32
r10 = Word32
-> Word32 -> Word32 -> Word32 -> Word32 -> Int -> Word32 -> Word32
forall a. (Num a, Bits a) => a -> a -> a -> a -> a -> Int -> a -> a
ff Word32
r6 Word32
r9 Word32
r8 Word32
r7  (ByteString
wByteString -> Int -> Word32
forall a. Storable a => ByteString -> Int -> a
!!Int
10) Int
17 Word32
4294925233
            !r11 :: Word32
r11 = Word32
-> Word32 -> Word32 -> Word32 -> Word32 -> Int -> Word32 -> Word32
forall a. (Num a, Bits a) => a -> a -> a -> a -> a -> Int -> a -> a
ff Word32
r7 Word32
r10 Word32
r9 Word32
r8 (ByteString
wByteString -> Int -> Word32
forall a. Storable a => ByteString -> Int -> a
!!Int
11) Int
22 Word32
2304563134
            !r12 :: Word32
r12 = Word32
-> Word32 -> Word32 -> Word32 -> Word32 -> Int -> Word32 -> Word32
forall a. (Num a, Bits a) => a -> a -> a -> a -> a -> Int -> a -> a
ff Word32
r8 Word32
r11 Word32
r10 Word32
r9 (ByteString
wByteString -> Int -> Word32
forall a. Storable a => ByteString -> Int -> a
!!Int
12) Int
7  Word32
1804603682
            !r13 :: Word32
r13 = Word32
-> Word32 -> Word32 -> Word32 -> Word32 -> Int -> Word32 -> Word32
forall a. (Num a, Bits a) => a -> a -> a -> a -> a -> Int -> a -> a
ff Word32
r9 Word32
r12 Word32
r11 Word32
r10 (ByteString
wByteString -> Int -> Word32
forall a. Storable a => ByteString -> Int -> a
!!Int
13) Int
12 Word32
4254626195
            !r14 :: Word32
r14 = Word32
-> Word32 -> Word32 -> Word32 -> Word32 -> Int -> Word32 -> Word32
forall a. (Num a, Bits a) => a -> a -> a -> a -> a -> Int -> a -> a
ff Word32
r10 Word32
r13 Word32
r12 Word32
r11 (ByteString
wByteString -> Int -> Word32
forall a. Storable a => ByteString -> Int -> a
!!Int
14) Int
17 Word32
2792965006
            !r15 :: Word32
r15 = Word32
-> Word32 -> Word32 -> Word32 -> Word32 -> Int -> Word32 -> Word32
forall a. (Num a, Bits a) => a -> a -> a -> a -> a -> Int -> a -> a
ff Word32
r11 Word32
r14 Word32
r13 Word32
r12 (ByteString
wByteString -> Int -> Word32
forall a. Storable a => ByteString -> Int -> a
!!Int
15) Int
22 Word32
1236535329
            -- Round 2
            !r16 :: Word32
r16 = Word32
-> Word32 -> Word32 -> Word32 -> Word32 -> Int -> Word32 -> Word32
forall a. (Num a, Bits a) => a -> a -> a -> a -> a -> Int -> a -> a
gg Word32
r12 Word32
r15 Word32
r14 Word32
r13 (ByteString
wByteString -> Int -> Word32
forall a. Storable a => ByteString -> Int -> a
!!Int
1)  Int
5  Word32
4129170786
            !r17 :: Word32
r17 = Word32
-> Word32 -> Word32 -> Word32 -> Word32 -> Int -> Word32 -> Word32
forall a. (Num a, Bits a) => a -> a -> a -> a -> a -> Int -> a -> a
gg Word32
r13 Word32
r16 Word32
r15 Word32
r14 (ByteString
wByteString -> Int -> Word32
forall a. Storable a => ByteString -> Int -> a
!!Int
6)  Int
9  Word32
3225465664
            !r18 :: Word32
r18 = Word32
-> Word32 -> Word32 -> Word32 -> Word32 -> Int -> Word32 -> Word32
forall a. (Num a, Bits a) => a -> a -> a -> a -> a -> Int -> a -> a
gg Word32
r14 Word32
r17 Word32
r16 Word32
r15 (ByteString
wByteString -> Int -> Word32
forall a. Storable a => ByteString -> Int -> a
!!Int
11) Int
14 Word32
643717713
            !r19 :: Word32
r19 = Word32
-> Word32 -> Word32 -> Word32 -> Word32 -> Int -> Word32 -> Word32
forall a. (Num a, Bits a) => a -> a -> a -> a -> a -> Int -> a -> a
gg Word32
r15 Word32
r18 Word32
r17 Word32
r16 (ByteString
wByteString -> Int -> Word32
forall a. Storable a => ByteString -> Int -> a
!!Int
0)  Int
20 Word32
3921069994
            !r20 :: Word32
r20 = Word32
-> Word32 -> Word32 -> Word32 -> Word32 -> Int -> Word32 -> Word32
forall a. (Num a, Bits a) => a -> a -> a -> a -> a -> Int -> a -> a
gg Word32
r16 Word32
r19 Word32
r18 Word32
r17 (ByteString
wByteString -> Int -> Word32
forall a. Storable a => ByteString -> Int -> a
!!Int
5)  Int
5  Word32
3593408605
            !r21 :: Word32
r21 = Word32
-> Word32 -> Word32 -> Word32 -> Word32 -> Int -> Word32 -> Word32
forall a. (Num a, Bits a) => a -> a -> a -> a -> a -> Int -> a -> a
gg Word32
r17 Word32
r20 Word32
r19 Word32
r18 (ByteString
wByteString -> Int -> Word32
forall a. Storable a => ByteString -> Int -> a
!!Int
10) Int
9  Word32
38016083
            !r22 :: Word32
r22 = Word32
-> Word32 -> Word32 -> Word32 -> Word32 -> Int -> Word32 -> Word32
forall a. (Num a, Bits a) => a -> a -> a -> a -> a -> Int -> a -> a
gg Word32
r18 Word32
r21 Word32
r20 Word32
r19 (ByteString
wByteString -> Int -> Word32
forall a. Storable a => ByteString -> Int -> a
!!Int
15) Int
14 Word32
3634488961
            !r23 :: Word32
r23 = Word32
-> Word32 -> Word32 -> Word32 -> Word32 -> Int -> Word32 -> Word32
forall a. (Num a, Bits a) => a -> a -> a -> a -> a -> Int -> a -> a
gg Word32
r19 Word32
r22 Word32
r21 Word32
r20 (ByteString
wByteString -> Int -> Word32
forall a. Storable a => ByteString -> Int -> a
!!Int
4)  Int
20 Word32
3889429448
            !r24 :: Word32
r24 = Word32
-> Word32 -> Word32 -> Word32 -> Word32 -> Int -> Word32 -> Word32
forall a. (Num a, Bits a) => a -> a -> a -> a -> a -> Int -> a -> a
gg Word32
r20 Word32
r23 Word32
r22 Word32
r21 (ByteString
wByteString -> Int -> Word32
forall a. Storable a => ByteString -> Int -> a
!!Int
9)  Int
5  Word32
568446438
            !r25 :: Word32
r25 = Word32
-> Word32 -> Word32 -> Word32 -> Word32 -> Int -> Word32 -> Word32
forall a. (Num a, Bits a) => a -> a -> a -> a -> a -> Int -> a -> a
gg Word32
r21 Word32
r24 Word32
r23 Word32
r22 (ByteString
wByteString -> Int -> Word32
forall a. Storable a => ByteString -> Int -> a
!!Int
14) Int
9  Word32
3275163606
            !r26 :: Word32
r26 = Word32
-> Word32 -> Word32 -> Word32 -> Word32 -> Int -> Word32 -> Word32
forall a. (Num a, Bits a) => a -> a -> a -> a -> a -> Int -> a -> a
gg Word32
r22 Word32
r25 Word32
r24 Word32
r23 (ByteString
wByteString -> Int -> Word32
forall a. Storable a => ByteString -> Int -> a
!!Int
3)  Int
14 Word32
4107603335
            !r27 :: Word32
r27 = Word32
-> Word32 -> Word32 -> Word32 -> Word32 -> Int -> Word32 -> Word32
forall a. (Num a, Bits a) => a -> a -> a -> a -> a -> Int -> a -> a
gg Word32
r23 Word32
r26 Word32
r25 Word32
r24 (ByteString
wByteString -> Int -> Word32
forall a. Storable a => ByteString -> Int -> a
!!Int
8)  Int
20 Word32
1163531501
            !r28 :: Word32
r28 = Word32
-> Word32 -> Word32 -> Word32 -> Word32 -> Int -> Word32 -> Word32
forall a. (Num a, Bits a) => a -> a -> a -> a -> a -> Int -> a -> a
gg Word32
r24 Word32
r27 Word32
r26 Word32
r25 (ByteString
wByteString -> Int -> Word32
forall a. Storable a => ByteString -> Int -> a
!!Int
13) Int
5  Word32
2850285829
            !r29 :: Word32
r29 = Word32
-> Word32 -> Word32 -> Word32 -> Word32 -> Int -> Word32 -> Word32
forall a. (Num a, Bits a) => a -> a -> a -> a -> a -> Int -> a -> a
gg Word32
r25 Word32
r28 Word32
r27 Word32
r26 (ByteString
wByteString -> Int -> Word32
forall a. Storable a => ByteString -> Int -> a
!!Int
2)  Int
9  Word32
4243563512
            !r30 :: Word32
r30 = Word32
-> Word32 -> Word32 -> Word32 -> Word32 -> Int -> Word32 -> Word32
forall a. (Num a, Bits a) => a -> a -> a -> a -> a -> Int -> a -> a
gg Word32
r26 Word32
r29 Word32
r28 Word32
r27 (ByteString
wByteString -> Int -> Word32
forall a. Storable a => ByteString -> Int -> a
!!Int
7)  Int
14 Word32
1735328473
            !r31 :: Word32
r31 = Word32
-> Word32 -> Word32 -> Word32 -> Word32 -> Int -> Word32 -> Word32
forall a. (Num a, Bits a) => a -> a -> a -> a -> a -> Int -> a -> a
gg Word32
r27 Word32
r30 Word32
r29 Word32
r28 (ByteString
wByteString -> Int -> Word32
forall a. Storable a => ByteString -> Int -> a
!!Int
12) Int
20 Word32
2368359562
            -- Round 3
            !r32 :: Word32
r32 = Word32
-> Word32 -> Word32 -> Word32 -> Word32 -> Int -> Word32 -> Word32
forall a. (Num a, Bits a) => a -> a -> a -> a -> a -> Int -> a -> a
hh Word32
r28 Word32
r31 Word32
r30 Word32
r29 (ByteString
wByteString -> Int -> Word32
forall a. Storable a => ByteString -> Int -> a
!!Int
5)  Int
4  Word32
4294588738
            !r33 :: Word32
r33 = Word32
-> Word32 -> Word32 -> Word32 -> Word32 -> Int -> Word32 -> Word32
forall a. (Num a, Bits a) => a -> a -> a -> a -> a -> Int -> a -> a
hh Word32
r29 Word32
r32 Word32
r31 Word32
r30 (ByteString
wByteString -> Int -> Word32
forall a. Storable a => ByteString -> Int -> a
!!Int
8)  Int
11 Word32
2272392833
            !r34 :: Word32
r34 = Word32
-> Word32 -> Word32 -> Word32 -> Word32 -> Int -> Word32 -> Word32
forall a. (Num a, Bits a) => a -> a -> a -> a -> a -> Int -> a -> a
hh Word32
r30 Word32
r33 Word32
r32 Word32
r31 (ByteString
wByteString -> Int -> Word32
forall a. Storable a => ByteString -> Int -> a
!!Int
11) Int
16 Word32
1839030562
            !r35 :: Word32
r35 = Word32
-> Word32 -> Word32 -> Word32 -> Word32 -> Int -> Word32 -> Word32
forall a. (Num a, Bits a) => a -> a -> a -> a -> a -> Int -> a -> a
hh Word32
r31 Word32
r34 Word32
r33 Word32
r32 (ByteString
wByteString -> Int -> Word32
forall a. Storable a => ByteString -> Int -> a
!!Int
14) Int
23 Word32
4259657740
            !r36 :: Word32
r36 = Word32
-> Word32 -> Word32 -> Word32 -> Word32 -> Int -> Word32 -> Word32
forall a. (Num a, Bits a) => a -> a -> a -> a -> a -> Int -> a -> a
hh Word32
r32 Word32
r35 Word32
r34 Word32
r33 (ByteString
wByteString -> Int -> Word32
forall a. Storable a => ByteString -> Int -> a
!!Int
1)  Int
4  Word32
2763975236
            !r37 :: Word32
r37 = Word32
-> Word32 -> Word32 -> Word32 -> Word32 -> Int -> Word32 -> Word32
forall a. (Num a, Bits a) => a -> a -> a -> a -> a -> Int -> a -> a
hh Word32
r33 Word32
r36 Word32
r35 Word32
r34 (ByteString
wByteString -> Int -> Word32
forall a. Storable a => ByteString -> Int -> a
!!Int
4)  Int
11 Word32
1272893353
            !r38 :: Word32
r38 = Word32
-> Word32 -> Word32 -> Word32 -> Word32 -> Int -> Word32 -> Word32
forall a. (Num a, Bits a) => a -> a -> a -> a -> a -> Int -> a -> a
hh Word32
r34 Word32
r37 Word32
r36 Word32
r35 (ByteString
wByteString -> Int -> Word32
forall a. Storable a => ByteString -> Int -> a
!!Int
7)  Int
16 Word32
4139469664
            !r39 :: Word32
r39 = Word32
-> Word32 -> Word32 -> Word32 -> Word32 -> Int -> Word32 -> Word32
forall a. (Num a, Bits a) => a -> a -> a -> a -> a -> Int -> a -> a
hh Word32
r35 Word32
r38 Word32
r37 Word32
r36 (ByteString
wByteString -> Int -> Word32
forall a. Storable a => ByteString -> Int -> a
!!Int
10) Int
23 Word32
3200236656
            !r40 :: Word32
r40 = Word32
-> Word32 -> Word32 -> Word32 -> Word32 -> Int -> Word32 -> Word32
forall a. (Num a, Bits a) => a -> a -> a -> a -> a -> Int -> a -> a
hh Word32
r36 Word32
r39 Word32
r38 Word32
r37 (ByteString
wByteString -> Int -> Word32
forall a. Storable a => ByteString -> Int -> a
!!Int
13) Int
4  Word32
681279174
            !r41 :: Word32
r41 = Word32
-> Word32 -> Word32 -> Word32 -> Word32 -> Int -> Word32 -> Word32
forall a. (Num a, Bits a) => a -> a -> a -> a -> a -> Int -> a -> a
hh Word32
r37 Word32
r40 Word32
r39 Word32
r38 (ByteString
wByteString -> Int -> Word32
forall a. Storable a => ByteString -> Int -> a
!!Int
0)  Int
11 Word32
3936430074
            !r42 :: Word32
r42 = Word32
-> Word32 -> Word32 -> Word32 -> Word32 -> Int -> Word32 -> Word32
forall a. (Num a, Bits a) => a -> a -> a -> a -> a -> Int -> a -> a
hh Word32
r38 Word32
r41 Word32
r40 Word32
r39 (ByteString
wByteString -> Int -> Word32
forall a. Storable a => ByteString -> Int -> a
!!Int
3)  Int
16 Word32
3572445317
            !r43 :: Word32
r43 = Word32
-> Word32 -> Word32 -> Word32 -> Word32 -> Int -> Word32 -> Word32
forall a. (Num a, Bits a) => a -> a -> a -> a -> a -> Int -> a -> a
hh Word32
r39 Word32
r42 Word32
r41 Word32
r40 (ByteString
wByteString -> Int -> Word32
forall a. Storable a => ByteString -> Int -> a
!!Int
6)  Int
23 Word32
76029189
            !r44 :: Word32
r44 = Word32
-> Word32 -> Word32 -> Word32 -> Word32 -> Int -> Word32 -> Word32
forall a. (Num a, Bits a) => a -> a -> a -> a -> a -> Int -> a -> a
hh Word32
r40 Word32
r43 Word32
r42 Word32
r41 (ByteString
wByteString -> Int -> Word32
forall a. Storable a => ByteString -> Int -> a
!!Int
9)  Int
4  Word32
3654602809
            !r45 :: Word32
r45 = Word32
-> Word32 -> Word32 -> Word32 -> Word32 -> Int -> Word32 -> Word32
forall a. (Num a, Bits a) => a -> a -> a -> a -> a -> Int -> a -> a
hh Word32
r41 Word32
r44 Word32
r43 Word32
r42 (ByteString
wByteString -> Int -> Word32
forall a. Storable a => ByteString -> Int -> a
!!Int
12) Int
11 Word32
3873151461
            !r46 :: Word32
r46 = Word32
-> Word32 -> Word32 -> Word32 -> Word32 -> Int -> Word32 -> Word32
forall a. (Num a, Bits a) => a -> a -> a -> a -> a -> Int -> a -> a
hh Word32
r42 Word32
r45 Word32
r44 Word32
r43 (ByteString
wByteString -> Int -> Word32
forall a. Storable a => ByteString -> Int -> a
!!Int
15) Int
16 Word32
530742520
            !r47 :: Word32
r47 = Word32
-> Word32 -> Word32 -> Word32 -> Word32 -> Int -> Word32 -> Word32
forall a. (Num a, Bits a) => a -> a -> a -> a -> a -> Int -> a -> a
hh Word32
r43 Word32
r46 Word32
r45 Word32
r44 (ByteString
wByteString -> Int -> Word32
forall a. Storable a => ByteString -> Int -> a
!!Int
2)  Int
23 Word32
3299628645
            -- Round 4
            !r48 :: Word32
r48 = Word32
-> Word32 -> Word32 -> Word32 -> Word32 -> Int -> Word32 -> Word32
forall a. (Num a, Bits a) => a -> a -> a -> a -> a -> Int -> a -> a
ii Word32
r44 Word32
r47 Word32
r46 Word32
r45 (ByteString
wByteString -> Int -> Word32
forall a. Storable a => ByteString -> Int -> a
!!Int
0)  Int
6  Word32
4096336452
            !r49 :: Word32
r49 = Word32
-> Word32 -> Word32 -> Word32 -> Word32 -> Int -> Word32 -> Word32
forall a. (Num a, Bits a) => a -> a -> a -> a -> a -> Int -> a -> a
ii Word32
r45 Word32
r48 Word32
r47 Word32
r46 (ByteString
wByteString -> Int -> Word32
forall a. Storable a => ByteString -> Int -> a
!!Int
7)  Int
10 Word32
1126891415
            !r50 :: Word32
r50 = Word32
-> Word32 -> Word32 -> Word32 -> Word32 -> Int -> Word32 -> Word32
forall a. (Num a, Bits a) => a -> a -> a -> a -> a -> Int -> a -> a
ii Word32
r46 Word32
r49 Word32
r48 Word32
r47 (ByteString
wByteString -> Int -> Word32
forall a. Storable a => ByteString -> Int -> a
!!Int
14) Int
15 Word32
2878612391
            !r51 :: Word32
r51 = Word32
-> Word32 -> Word32 -> Word32 -> Word32 -> Int -> Word32 -> Word32
forall a. (Num a, Bits a) => a -> a -> a -> a -> a -> Int -> a -> a
ii Word32
r47 Word32
r50 Word32
r49 Word32
r48 (ByteString
wByteString -> Int -> Word32
forall a. Storable a => ByteString -> Int -> a
!!Int
5)  Int
21 Word32
4237533241
            !r52 :: Word32
r52 = Word32
-> Word32 -> Word32 -> Word32 -> Word32 -> Int -> Word32 -> Word32
forall a. (Num a, Bits a) => a -> a -> a -> a -> a -> Int -> a -> a
ii Word32
r48 Word32
r51 Word32
r50 Word32
r49 (ByteString
wByteString -> Int -> Word32
forall a. Storable a => ByteString -> Int -> a
!!Int
12) Int
6  Word32
1700485571
            !r53 :: Word32
r53 = Word32
-> Word32 -> Word32 -> Word32 -> Word32 -> Int -> Word32 -> Word32
forall a. (Num a, Bits a) => a -> a -> a -> a -> a -> Int -> a -> a
ii Word32
r49 Word32
r52 Word32
r51 Word32
r50 (ByteString
wByteString -> Int -> Word32
forall a. Storable a => ByteString -> Int -> a
!!Int
3)  Int
10 Word32
2399980690
            !r54 :: Word32
r54 = Word32
-> Word32 -> Word32 -> Word32 -> Word32 -> Int -> Word32 -> Word32
forall a. (Num a, Bits a) => a -> a -> a -> a -> a -> Int -> a -> a
ii Word32
r50 Word32
r53 Word32
r52 Word32
r51 (ByteString
wByteString -> Int -> Word32
forall a. Storable a => ByteString -> Int -> a
!!Int
10) Int
15 Word32
4293915773
            !r55 :: Word32
r55 = Word32
-> Word32 -> Word32 -> Word32 -> Word32 -> Int -> Word32 -> Word32
forall a. (Num a, Bits a) => a -> a -> a -> a -> a -> Int -> a -> a
ii Word32
r51 Word32
r54 Word32
r53 Word32
r52 (ByteString
wByteString -> Int -> Word32
forall a. Storable a => ByteString -> Int -> a
!!Int
1)  Int
21 Word32
2240044497
            !r56 :: Word32
r56 = Word32
-> Word32 -> Word32 -> Word32 -> Word32 -> Int -> Word32 -> Word32
forall a. (Num a, Bits a) => a -> a -> a -> a -> a -> Int -> a -> a
ii Word32
r52 Word32
r55 Word32
r54 Word32
r53 (ByteString
wByteString -> Int -> Word32
forall a. Storable a => ByteString -> Int -> a
!!Int
8)  Int
6  Word32
1873313359
            !r57 :: Word32
r57 = Word32
-> Word32 -> Word32 -> Word32 -> Word32 -> Int -> Word32 -> Word32
forall a. (Num a, Bits a) => a -> a -> a -> a -> a -> Int -> a -> a
ii Word32
r53 Word32
r56 Word32
r55 Word32
r54 (ByteString
wByteString -> Int -> Word32
forall a. Storable a => ByteString -> Int -> a
!!Int
15) Int
10 Word32
4264355552
            !r58 :: Word32
r58 = Word32
-> Word32 -> Word32 -> Word32 -> Word32 -> Int -> Word32 -> Word32
forall a. (Num a, Bits a) => a -> a -> a -> a -> a -> Int -> a -> a
ii Word32
r54 Word32
r57 Word32
r56 Word32
r55 (ByteString
wByteString -> Int -> Word32
forall a. Storable a => ByteString -> Int -> a
!!Int
6)  Int
15 Word32
2734768916
            !r59 :: Word32
r59 = Word32
-> Word32 -> Word32 -> Word32 -> Word32 -> Int -> Word32 -> Word32
forall a. (Num a, Bits a) => a -> a -> a -> a -> a -> Int -> a -> a
ii Word32
r55 Word32
r58 Word32
r57 Word32
r56 (ByteString
wByteString -> Int -> Word32
forall a. Storable a => ByteString -> Int -> a
!!Int
13) Int
21 Word32
1309151649
            !r60 :: Word32
r60 = Word32
-> Word32 -> Word32 -> Word32 -> Word32 -> Int -> Word32 -> Word32
forall a. (Num a, Bits a) => a -> a -> a -> a -> a -> Int -> a -> a
ii Word32
r56 Word32
r59 Word32
r58 Word32
r57 (ByteString
wByteString -> Int -> Word32
forall a. Storable a => ByteString -> Int -> a
!!Int
4)  Int
6  Word32
4149444226
            !r61 :: Word32
r61 = Word32
-> Word32 -> Word32 -> Word32 -> Word32 -> Int -> Word32 -> Word32
forall a. (Num a, Bits a) => a -> a -> a -> a -> a -> Int -> a -> a
ii Word32
r57 Word32
r60 Word32
r59 Word32
r58 (ByteString
wByteString -> Int -> Word32
forall a. Storable a => ByteString -> Int -> a
!!Int
11) Int
10 Word32
3174756917
            !r62 :: Word32
r62 = Word32
-> Word32 -> Word32 -> Word32 -> Word32 -> Int -> Word32 -> Word32
forall a. (Num a, Bits a) => a -> a -> a -> a -> a -> Int -> a -> a
ii Word32
r58 Word32
r61 Word32
r60 Word32
r59 (ByteString
wByteString -> Int -> Word32
forall a. Storable a => ByteString -> Int -> a
!!Int
2)  Int
15 Word32
718787259
            !r63 :: Word32
r63 = Word32
-> Word32 -> Word32 -> Word32 -> Word32 -> Int -> Word32 -> Word32
forall a. (Num a, Bits a) => a -> a -> a -> a -> a -> Int -> a -> a
ii Word32
r59 Word32
r62 Word32
r61 Word32
r60 (ByteString
wByteString -> Int -> Word32
forall a. Storable a => ByteString -> Int -> a
!!Int
9)  Int
21 Word32
3951481745
        in Word32 -> Word32 -> Word32 -> Word32 -> MD5Partial
MD5Par Word32
r60 Word32
r63 Word32
r62 Word32
r61
        where
        f :: a -> a -> a -> a
f !a
x !a
y !a
z = (a
x a -> a -> a
forall a. Bits a => a -> a -> a
.&. a
y) a -> a -> a
forall a. Bits a => a -> a -> a
.|. ((a -> a
forall a. Bits a => a -> a
complement a
x) a -> a -> a
forall a. Bits a => a -> a -> a
.&. a
z)
        {-# INLINE f #-}
        g :: a -> a -> a -> a
g !a
x !a
y !a
z = (a
x a -> a -> a
forall a. Bits a => a -> a -> a
.&. a
z) a -> a -> a
forall a. Bits a => a -> a -> a
.|. (a
y a -> a -> a
forall a. Bits a => a -> a -> a
.&. (a -> a
forall a. Bits a => a -> a
complement a
z))
        {-# INLINE g #-}
        h :: a -> a -> a -> a
h !a
x !a
y !a
z = (a
x a -> a -> a
forall a. Bits a => a -> a -> a
`xor` a
y a -> a -> a
forall a. Bits a => a -> a -> a
`xor` a
z)
        {-# INLINE h #-}
        i :: a -> a -> a -> a
i !a
x !a
y !a
z = a
y a -> a -> a
forall a. Bits a => a -> a -> a
`xor` (a
x a -> a -> a
forall a. Bits a => a -> a -> a
.|. (a -> a
forall a. Bits a => a -> a
complement a
z))
        {-# INLINE i #-}
        ff :: a -> a -> a -> a -> a -> Int -> a -> a
ff a
a a
b a
c a
d !a
x Int
s a
ac = {-# SCC "ff" #-}
                let !a' :: a
a' = a -> a -> a -> a
forall a. Bits a => a -> a -> a -> a
f a
b a
c a
d a -> a -> a
forall a. Num a => a -> a -> a
+ a
x a -> a -> a
forall a. Num a => a -> a -> a
+ a
ac a -> a -> a
forall a. Num a => a -> a -> a
+ a
a
                    !a'' :: a
a'' = a -> Int -> a
forall a. Bits a => a -> Int -> a
rotateL a
a' Int
s
                in a
a'' a -> a -> a
forall a. Num a => a -> a -> a
+ a
b
        {-# INLINE ff #-}
        gg :: a -> a -> a -> a -> a -> Int -> a -> a
gg a
a a
b a
c a
d !a
x Int
s a
ac = {-# SCC "gg" #-}
                let !a' :: a
a' = a -> a -> a -> a
forall a. Bits a => a -> a -> a -> a
g a
b a
c a
d a -> a -> a
forall a. Num a => a -> a -> a
+ a
x a -> a -> a
forall a. Num a => a -> a -> a
+ a
ac a -> a -> a
forall a. Num a => a -> a -> a
+ a
a
                    !a'' :: a
a'' = a -> Int -> a
forall a. Bits a => a -> Int -> a
rotateL a
a' Int
s
                in a
a'' a -> a -> a
forall a. Num a => a -> a -> a
+ a
b
        {-# INLINE gg #-}
        hh :: a -> a -> a -> a -> a -> Int -> a -> a
hh a
a a
b a
c a
d !a
x Int
s a
ac = {-# SCC "hh" #-}
                let !a' :: a
a' = a -> a -> a -> a
forall a. Bits a => a -> a -> a -> a
h a
b a
c a
d a -> a -> a
forall a. Num a => a -> a -> a
+ a
x a -> a -> a
forall a. Num a => a -> a -> a
+ a
ac a -> a -> a
forall a. Num a => a -> a -> a
+ a
a
                    !a'' :: a
a'' = a -> Int -> a
forall a. Bits a => a -> Int -> a
rotateL a
a' Int
s
                    in a
a'' a -> a -> a
forall a. Num a => a -> a -> a
+ a
b
        {-# INLINE hh #-}
        ii :: a -> a -> a -> a -> a -> Int -> a -> a
ii a
a a
b a
c a
d  !a
x Int
s a
ac = {-# SCC "ii" #-}
                let !a' :: a
a' = a -> a -> a -> a
forall a. Bits a => a -> a -> a -> a
i a
b a
c a
d a -> a -> a
forall a. Num a => a -> a -> a
+ a
x a -> a -> a
forall a. Num a => a -> a -> a
+ a
ac a -> a -> a
forall a. Num a => a -> a -> a
+ a
a
                    !a'' :: a
a'' = a -> Int -> a
forall a. Bits a => a -> Int -> a
rotateL a
a' Int
s
                in a
a'' a -> a -> a
forall a. Num a => a -> a -> a
+ a
b
        {-# INLINE ii #-}
        !! :: ByteString -> Int -> a
(!!) ByteString
word32s Int
pos = Int -> ByteString -> a
forall a. Storable a => Int -> ByteString -> a
getNthWord Int
pos ByteString
word32s
        {-# INLINE (!!) #-}
{-# INLINE applyMD5Rounds #-}

#ifdef FastWordExtract
getNthWord :: Int -> ByteString -> a
getNthWord Int
n ByteString
b = IO a -> a
forall a. IO a -> a
unsafePerformIO (ByteString -> (CString -> IO a) -> IO a
forall a. ByteString -> (CString -> IO a) -> IO a
unsafeUseAsCString ByteString
b ((Ptr a -> Int -> IO a) -> Int -> Ptr a -> IO a
forall a b c. (a -> b -> c) -> b -> a -> c
flip Ptr a -> Int -> IO a
forall a. Storable a => Ptr a -> Int -> IO a
peekElemOff Int
n (Ptr a -> IO a) -> (CString -> Ptr a) -> CString -> IO a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CString -> Ptr a
forall a b. Ptr a -> Ptr b
castPtr))
{-# INLINE getNthWord #-}
#else
getNthWord :: Int -> B.ByteString -> Word32
getNthWord n = right . G.runGet G.getWord32le . B.drop (n * sizeOf (undefined :: Word32))
  where
  right x = case x of Right y -> y
#endif

-- | The raw bytes of an 'MD5Digest'. It is always 16 bytes long.
--
-- You can also use the 'Binary' or 'S.Serialize' instances to output the raw
-- bytes. Alternatively you can use 'show' to produce the standard hex
-- representation.
--
md5DigestBytes :: MD5Digest -> B.ByteString
md5DigestBytes :: MD5Digest -> ByteString
md5DigestBytes (MD5Digest MD5Partial
h) = MD5Partial -> ByteString
md5PartialBytes MD5Partial
h

md5PartialBytes :: MD5Partial -> B.ByteString
md5PartialBytes :: MD5Partial -> ByteString
md5PartialBytes =
    Put -> ByteString
toBs (Put -> ByteString)
-> (MD5Partial -> Put) -> MD5Partial -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (MD5Partial -> Put
forall t. Binary t => t -> Put
put :: MD5Partial -> Put)
  where
    toBs :: Put -> B.ByteString
#if MIN_VERSION_binary(0,8,3)
    -- with later binary versions we can control the buffer size precisely:
    toBs :: Put -> ByteString
toBs = ByteString -> ByteString
L.toStrict
         (ByteString -> ByteString)
-> (Put -> ByteString) -> Put -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. AllocationStrategy -> ByteString -> Builder -> ByteString
B.toLazyByteStringWith (Int -> Int -> AllocationStrategy
B.untrimmedStrategy Int
16 Int
0) ByteString
L.empty
         (Builder -> ByteString) -> (Put -> Builder) -> Put -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Put -> Builder
forall a. PutM a -> Builder
execPut
#else
    toBs = B.concat . L.toChunks . runPut
    -- note L.toStrict is only in newer bytestring versions
#endif

----- Some quick and dirty instances follow -----

instance Show MD5Digest where
    show :: MD5Digest -> [Char]
show (MD5Digest MD5Partial
h) = MD5Partial -> [Char]
forall a. Show a => a -> [Char]
show MD5Partial
h

instance Show MD5Partial where
  show :: MD5Partial -> [Char]
show MD5Partial
md5par =
    let bs :: ByteString
bs = MD5Partial -> ByteString
md5PartialBytes MD5Partial
md5par
    in ([Char] -> Word8 -> [Char]) -> [Char] -> [Word8] -> [Char]
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' (\[Char]
str Word8
w -> let cx :: [Char]
cx = Word8 -> ShowS
forall a. (Integral a, Show a) => a -> ShowS
showHex Word8
w [Char]
str
                         in if [Char] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Char]
cx Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< [Char] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Char]
str Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
2
                                 then Char
'0'Char -> ShowS
forall a. a -> [a] -> [a]
:[Char]
cx
                                else [Char]
cx) [Char]
"" (ByteString -> [Word8]
B.unpack (ByteString -> ByteString
B.reverse ByteString
bs))

instance Binary MD5Digest where
    put :: MD5Digest -> Put
put (MD5Digest MD5Partial
p) = MD5Partial -> Put
forall t. Binary t => t -> Put
put MD5Partial
p
    get :: Get MD5Digest
get = do
        MD5Partial
p <- Get MD5Partial
forall t. Binary t => Get t
get
        MD5Digest -> Get MD5Digest
forall (m :: * -> *) a. Monad m => a -> m a
return (MD5Digest -> Get MD5Digest) -> MD5Digest -> Get MD5Digest
forall a b. (a -> b) -> a -> b
$ MD5Partial -> MD5Digest
MD5Digest MD5Partial
p

instance Binary MD5Context where
        put :: MD5Context -> Put
put (MD5Ctx MD5Partial
p Word64
l) = MD5Partial -> Put
forall t. Binary t => t -> Put
put MD5Partial
p Put -> Put -> Put
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Word64 -> Put
putWord64be Word64
l
        get :: Get MD5Context
get = do MD5Partial
p <- Get MD5Partial
forall t. Binary t => Get t
get
                 Word64
l <- Get Word64
getWord64be
                 MD5Context -> Get MD5Context
forall (m :: * -> *) a. Monad m => a -> m a
return (MD5Context -> Get MD5Context) -> MD5Context -> Get MD5Context
forall a b. (a -> b) -> a -> b
$ MD5Partial -> Word64 -> MD5Context
MD5Ctx MD5Partial
p Word64
l

instance Binary MD5Partial where
        put :: MD5Partial -> Put
put (MD5Par Word32
a Word32
b Word32
c Word32
d) = Word32 -> Put
putWord32le Word32
a Put -> Put -> Put
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Word32 -> Put
putWord32le Word32
b Put -> Put -> Put
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Word32 -> Put
putWord32le Word32
c Put -> Put -> Put
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Word32 -> Put
putWord32le Word32
d
        get :: Get MD5Partial
get = do Word32
a <- Get Word32
getWord32le
                 Word32
b <- Get Word32
getWord32le
                 Word32
c <- Get Word32
getWord32le
                 Word32
d <- Get Word32
getWord32le
                 MD5Partial -> Get MD5Partial
forall (m :: * -> *) a. Monad m => a -> m a
return (MD5Partial -> Get MD5Partial) -> MD5Partial -> Get MD5Partial
forall a b. (a -> b) -> a -> b
$ Word32 -> Word32 -> Word32 -> Word32 -> MD5Partial
MD5Par Word32
a Word32
b Word32
c Word32
d

instance S.Serialize MD5Digest where
    put :: Putter MD5Digest
put (MD5Digest MD5Partial
p) = Putter MD5Partial
forall t. Serialize t => Putter t
S.put MD5Partial
p
    get :: Get MD5Digest
get = do
        MD5Partial
p <- Get MD5Partial
forall t. Serialize t => Get t
S.get
        MD5Digest -> Get MD5Digest
forall (m :: * -> *) a. Monad m => a -> m a
return (MD5Digest -> Get MD5Digest) -> MD5Digest -> Get MD5Digest
forall a b. (a -> b) -> a -> b
$ MD5Partial -> MD5Digest
MD5Digest MD5Partial
p

instance S.Serialize MD5Context where
        put :: Putter MD5Context
put (MD5Ctx MD5Partial
p Word64
l) = Putter MD5Partial
forall t. Serialize t => Putter t
S.put MD5Partial
p Put -> Put -> Put
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>>
                             Putter Word64
P.putWord64be Word64
l
        get :: Get MD5Context
get = do MD5Partial
p <- Get MD5Partial
forall t. Serialize t => Get t
S.get
                 Word64
l <- Get Word64
G.getWord64be
                 MD5Context -> Get MD5Context
forall (m :: * -> *) a. Monad m => a -> m a
return (MD5Context -> Get MD5Context) -> MD5Context -> Get MD5Context
forall a b. (a -> b) -> a -> b
$ MD5Partial -> Word64 -> MD5Context
MD5Ctx MD5Partial
p Word64
l

instance S.Serialize MD5Partial where
        put :: Putter MD5Partial
put (MD5Par Word32
a Word32
b Word32
c Word32
d) = do
            Putter Word32
P.putWord32le Word32
a
            Putter Word32
P.putWord32le Word32
b
            Putter Word32
P.putWord32le Word32
c
            Putter Word32
P.putWord32le Word32
d
        get :: Get MD5Partial
get = do
            Word32
a <- Get Word32
G.getWord32le
            Word32
b <- Get Word32
G.getWord32le
            Word32
c <- Get Word32
G.getWord32le
            Word32
d <- Get Word32
G.getWord32le
            MD5Partial -> Get MD5Partial
forall (m :: * -> *) a. Monad m => a -> m a
return (Word32 -> Word32 -> Word32 -> Word32 -> MD5Partial
MD5Par Word32
a Word32
b Word32
c Word32
d)

instance Hash MD5Context MD5Digest where
        outputLength :: Tagged MD5Digest Int
outputLength = Int -> Tagged MD5Digest Int
forall k (s :: k) b. b -> Tagged s b
Tagged Int
128
        blockLength :: Tagged MD5Digest Int
blockLength  = Int -> Tagged MD5Digest Int
forall k (s :: k) b. b -> Tagged s b
Tagged Int
512
        initialCtx :: MD5Context
initialCtx   = MD5Context
md5InitialContext
        updateCtx :: MD5Context -> ByteString -> MD5Context
updateCtx    = MD5Context -> ByteString -> MD5Context
md5Update
        finalize :: MD5Context -> ByteString -> MD5Digest
finalize     = MD5Context -> ByteString -> MD5Digest
md5Finalize