    -- |
    -- Module      : Foundation.Hashing.SipHash
    -- License     : BSD-style
    -- Maintainer  : Vincent Hanquez <vincent@snarc.org>
    -- Stability   : experimental
    -- Portability : good
    --
    -- provide the SipHash algorithm.
    -- reference: <http://131002.net/siphash/siphash.pdf>
    --
    {-# LANGUAGE BangPatterns #-}
    {-# LANGUAGE MagicHash #-}
    module Foundation.Hashing.SipHash
        ( SipKey(..)
        , SipHash(..)
        , Sip1_3
        , Sip2_4
        ) where

    import           Data.Bits hiding ((.<<.), (.>>.))
    import           Basement.Compat.Base
    import           Basement.Types.OffsetSize
    import           Basement.PrimType
    import           Basement.Cast (cast)
    import           Basement.IntegralConv
    import           Foundation.Hashing.Hasher
    import           Basement.Block (Block(..))
    import qualified Basement.UArray as A
    import           Foundation.Array
    import           Foundation.Numerical
    import           Foundation.Bits
    import qualified Prelude
    import           GHC.ST

    -- | SigHash Key
    data SipKey = SipKey {-# UNPACK #-} !Word64
                         {-# UNPACK #-} !Word64

    -- | Siphash Hash value
    newtype SipHash = SipHash Word64
        deriving (Int -> SipHash -> ShowS
    [SipHash] -> ShowS
    SipHash -> String
    (Int -> SipHash -> ShowS)
    -> (SipHash -> String) -> ([SipHash] -> ShowS) -> Show SipHash
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> SipHash -> ShowS
    showsPrec :: Int -> SipHash -> ShowS
    $cshow :: SipHash -> String
    show :: SipHash -> String
    $cshowList :: [SipHash] -> ShowS
    showList :: [SipHash] -> ShowS
    Show,SipHash -> SipHash -> Bool
    (SipHash -> SipHash -> Bool)
    -> (SipHash -> SipHash -> Bool) -> Eq SipHash
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: SipHash -> SipHash -> Bool
    == :: SipHash -> SipHash -> Bool
    $c/= :: SipHash -> SipHash -> Bool
    /= :: SipHash -> SipHash -> Bool
    Eq,Eq SipHash
    Eq SipHash =>
    (SipHash -> SipHash -> Ordering)
    -> (SipHash -> SipHash -> Bool)
    -> (SipHash -> SipHash -> Bool)
    -> (SipHash -> SipHash -> Bool)
    -> (SipHash -> SipHash -> Bool)
    -> (SipHash -> SipHash -> SipHash)
    -> (SipHash -> SipHash -> SipHash)
    -> Ord SipHash
    SipHash -> SipHash -> Bool
    SipHash -> SipHash -> Ordering
    SipHash -> SipHash -> SipHash
    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
    $ccompare :: SipHash -> SipHash -> Ordering
    compare :: SipHash -> SipHash -> Ordering
    $c< :: SipHash -> SipHash -> Bool
    < :: SipHash -> SipHash -> Bool
    $c<= :: SipHash -> SipHash -> Bool
    <= :: SipHash -> SipHash -> Bool
    $c> :: SipHash -> SipHash -> Bool
    > :: SipHash -> SipHash -> Bool
    $c>= :: SipHash -> SipHash -> Bool
    >= :: SipHash -> SipHash -> Bool
    $cmax :: SipHash -> SipHash -> SipHash
    max :: SipHash -> SipHash -> SipHash
    $cmin :: SipHash -> SipHash -> SipHash
    min :: SipHash -> SipHash -> SipHash
    Ord)

    -- | Sip State 2-4 (2 compression rounds, 4 digest rounds)
    newtype Sip2_4 = Sip2_4 Sip

    -- | Sip State 1-3 (1 compression rounds, 3 digest rounds)
    newtype Sip1_3 = Sip1_3 Sip

    instance Hasher Sip2_4 where
        type HashResult Sip2_4      = SipHash
        type HashInitParam Sip2_4   = SipKey
        hashNew :: Sip2_4
    hashNew                     = Sip -> Sip2_4
    Sip2_4 (Sip -> Sip2_4) -> Sip -> Sip2_4
    forall a b. (a -> b) -> a -> b
    $ SipKey -> Sip
    newSipState (Word64 -> Word64 -> SipKey
    SipKey Word64
    0 Word64
    0)
        hashNewParam :: HashInitParam Sip2_4 -> Sip2_4
    hashNewParam HashInitParam Sip2_4
    key            = Sip -> Sip2_4
    Sip2_4 (Sip -> Sip2_4) -> Sip -> Sip2_4
    forall a b. (a -> b) -> a -> b
    $ SipKey -> Sip
    newSipState HashInitParam Sip2_4
    SipKey
    key
        hashEnd :: Sip2_4 -> HashResult Sip2_4
    hashEnd (Sip2_4 Sip
    st)         = Int -> Int -> Sip -> SipHash
    finish Int
    2 Int
    4 Sip
    st
        hashMix8 :: Word8 -> Sip2_4 -> Sip2_4
    hashMix8 Word8
    w (Sip2_4 Sip
    st)      = Sip -> Sip2_4
    Sip2_4 (Sip -> Sip2_4) -> Sip -> Sip2_4
    forall a b. (a -> b) -> a -> b
    $ Int -> Word8 -> Sip -> Sip
    mix8 Int
    2 Word8
    w Sip
    st
        hashMix32 :: Word32 -> Sip2_4 -> Sip2_4
    hashMix32 Word32
    w (Sip2_4 Sip
    st)     = Sip -> Sip2_4
    Sip2_4 (Sip -> Sip2_4) -> Sip -> Sip2_4
    forall a b. (a -> b) -> a -> b
    $ Int -> Word32 -> Sip -> Sip
    mix32 Int
    2 Word32
    w Sip
    st
        hashMix64 :: Word64 -> Sip2_4 -> Sip2_4
    hashMix64 Word64
    w (Sip2_4 Sip
    st)     = Sip -> Sip2_4
    Sip2_4 (Sip -> Sip2_4) -> Sip -> Sip2_4
    forall a b. (a -> b) -> a -> b
    $ Int -> Word64 -> Sip -> Sip
    mix64 Int
    2 Word64
    w Sip
    st
        hashMixBytes :: forall e. PrimType e => UArray e -> Sip2_4 -> Sip2_4
    hashMixBytes UArray e
    ba (Sip2_4 Sip
    st) = Sip -> Sip2_4
    Sip2_4 (Sip -> Sip2_4) -> Sip -> Sip2_4
    forall a b. (a -> b) -> a -> b
    $ Int -> UArray e -> Sip -> Sip
    forall a. PrimType a => Int -> UArray a -> Sip -> Sip
    mixBa Int
    2 UArray e
    ba Sip
    st

    instance Hasher Sip1_3 where
        type HashResult Sip1_3      = SipHash
        type HashInitParam Sip1_3   = SipKey
        hashNew :: Sip1_3
    hashNew                     = Sip -> Sip1_3
    Sip1_3 (Sip -> Sip1_3) -> Sip -> Sip1_3
    forall a b. (a -> b) -> a -> b
    $ SipKey -> Sip
    newSipState (Word64 -> Word64 -> SipKey
    SipKey Word64
    0 Word64
    0)
        hashNewParam :: HashInitParam Sip1_3 -> Sip1_3
    hashNewParam HashInitParam Sip1_3
    key            = Sip -> Sip1_3
    Sip1_3 (Sip -> Sip1_3) -> Sip -> Sip1_3
    forall a b. (a -> b) -> a -> b
    $ SipKey -> Sip
    newSipState HashInitParam Sip1_3
    SipKey
    key
        hashEnd :: Sip1_3 -> HashResult Sip1_3
    hashEnd (Sip1_3 Sip
    st)         = Int -> Int -> Sip -> SipHash
    finish Int
    1 Int
    3 Sip
    st
        hashMix8 :: Word8 -> Sip1_3 -> Sip1_3
    hashMix8 Word8
    w (Sip1_3 Sip
    st)      = Sip -> Sip1_3
    Sip1_3 (Sip -> Sip1_3) -> Sip -> Sip1_3
    forall a b. (a -> b) -> a -> b
    $ Int -> Word8 -> Sip -> Sip
    mix8 Int
    1 Word8
    w Sip
    st
        hashMix32 :: Word32 -> Sip1_3 -> Sip1_3
    hashMix32 Word32
    w (Sip1_3 Sip
    st)     = Sip -> Sip1_3
    Sip1_3 (Sip -> Sip1_3) -> Sip -> Sip1_3
    forall a b. (a -> b) -> a -> b
    $ Int -> Word32 -> Sip -> Sip
    mix32 Int
    1 Word32
    w Sip
    st
        hashMix64 :: Word64 -> Sip1_3 -> Sip1_3
    hashMix64 Word64
    w (Sip1_3 Sip
    st)     = Sip -> Sip1_3
    Sip1_3 (Sip -> Sip1_3) -> Sip -> Sip1_3
    forall a b. (a -> b) -> a -> b
    $ Int -> Word64 -> Sip -> Sip
    mix64 Int
    1 Word64
    w Sip
    st
        hashMixBytes :: forall e. PrimType e => UArray e -> Sip1_3 -> Sip1_3
    hashMixBytes UArray e
    ba (Sip1_3 Sip
    st) = Sip -> Sip1_3
    Sip1_3 (Sip -> Sip1_3) -> Sip -> Sip1_3
    forall a b. (a -> b) -> a -> b
    $ Int -> UArray e -> Sip -> Sip
    forall a. PrimType a => Int -> UArray a -> Sip -> Sip
    mixBa Int
    1 UArray e
    ba Sip
    st

    data Sip = Sip !InternalState !SipIncremental !(CountOf Word8)

    data InternalState = InternalState {-# UNPACK #-} !Word64
                                       {-# UNPACK #-} !Word64
                                       {-# UNPACK #-} !Word64
                                       {-# UNPACK #-} !Word64

    data SipIncremental =
          SipIncremental0
        | SipIncremental1 {-# UNPACK #-} !Word64
        | SipIncremental2 {-# UNPACK #-} !Word64
        | SipIncremental3 {-# UNPACK #-} !Word64
        | SipIncremental4 {-# UNPACK #-} !Word64
        | SipIncremental5 {-# UNPACK #-} !Word64
        | SipIncremental6 {-# UNPACK #-} !Word64
        | SipIncremental7 {-# UNPACK #-} !Word64

    newSipState :: SipKey -> Sip
    newSipState :: SipKey -> Sip
    newSipState (SipKey Word64
    k0 Word64
    k1) = InternalState -> SipIncremental -> CountOf Word8 -> Sip
    Sip InternalState
    st SipIncremental
    SipIncremental0 CountOf Word8
    0
      where
        st :: InternalState
    st = Word64 -> Word64 -> Word64 -> Word64 -> InternalState
    InternalState (Word64
    k0 Word64 -> Word64 -> Word64
    forall a. Bits a => a -> a -> a
    `xor` Word64
    0x736f6d6570736575)
                           (Word64
    k1 Word64 -> Word64 -> Word64
    forall a. Bits a => a -> a -> a
    `xor` Word64
    0x646f72616e646f6d)
                           (Word64
    k0 Word64 -> Word64 -> Word64
    forall a. Bits a => a -> a -> a
    `xor` Word64
    0x6c7967656e657261)
                           (Word64
    k1 Word64 -> Word64 -> Word64
    forall a. Bits a => a -> a -> a
    `xor` Word64
    0x7465646279746573)

    mix8Prim :: Int -> Word8 -> InternalState -> SipIncremental -> (InternalState, SipIncremental)
    mix8Prim :: Int
    -> Word8
    -> InternalState
    -> SipIncremental
    -> (InternalState, SipIncremental)
    mix8Prim !Int
    c !Word8
    w !InternalState
    ist !SipIncremental
    incremental =
        case SipIncremental
    incremental of
            SipIncremental7 Word64
    acc -> (Int -> InternalState -> Word64 -> InternalState
    process Int
    c InternalState
    ist ((Word64
    acc Word64 -> Int -> Word64
    forall a. Bits a => a -> Int -> a
    `unsafeShiftL` Int
    8) Word64 -> Word64 -> Word64
    forall a. Bits a => a -> a -> a
    .|. Word8 -> Word64
    forall a b. (Integral a, Num b) => a -> b
    Prelude.fromIntegral Word8
    w), SipIncremental
    SipIncremental0)
            SipIncremental6 Word64
    acc -> (Word64 -> SipIncremental)
    -> Word64 -> (InternalState, SipIncremental)
    doAcc Word64 -> SipIncremental
    SipIncremental7 Word64
    acc
            SipIncremental5 Word64
    acc -> (Word64 -> SipIncremental)
    -> Word64 -> (InternalState, SipIncremental)
    doAcc Word64 -> SipIncremental
    SipIncremental6 Word64
    acc
            SipIncremental4 Word64
    acc -> (Word64 -> SipIncremental)
    -> Word64 -> (InternalState, SipIncremental)
    doAcc Word64 -> SipIncremental
    SipIncremental5 Word64
    acc
            SipIncremental3 Word64
    acc -> (Word64 -> SipIncremental)
    -> Word64 -> (InternalState, SipIncremental)
    doAcc Word64 -> SipIncremental
    SipIncremental4 Word64
    acc
            SipIncremental2 Word64
    acc -> (Word64 -> SipIncremental)
    -> Word64 -> (InternalState, SipIncremental)
    doAcc Word64 -> SipIncremental
    SipIncremental3 Word64
    acc
            SipIncremental1 Word64
    acc -> (Word64 -> SipIncremental)
    -> Word64 -> (InternalState, SipIncremental)
    doAcc Word64 -> SipIncremental
    SipIncremental2 Word64
    acc
            SipIncremental
    SipIncremental0     -> (InternalState
    ist, Word64 -> SipIncremental
    SipIncremental1 (Word64 -> SipIncremental) -> Word64 -> SipIncremental
    forall a b. (a -> b) -> a -> b
    $ Word8 -> Word64
    forall a b. (Integral a, Num b) => a -> b
    Prelude.fromIntegral Word8
    w)
      where
        doAcc :: (Word64 -> SipIncremental)
    -> Word64 -> (InternalState, SipIncremental)
    doAcc Word64 -> SipIncremental
    constr Word64
    acc =
            (InternalState
    ist , Word64 -> SipIncremental
    constr ((Word64
    acc Word64 -> Int -> Word64
    forall a. Bits a => a -> Int -> a
    .<<. Int
    8) Word64 -> Word64 -> Word64
    forall a. Bits a => a -> a -> a
    .|. Word8 -> Word64
    forall a b. (Integral a, Num b) => a -> b
    Prelude.fromIntegral Word8
    w))

    mix8 :: Int -> Word8 -> Sip -> Sip
    mix8 :: Int -> Word8 -> Sip -> Sip
    mix8 !Int
    c !Word8
    w (Sip InternalState
    ist SipIncremental
    incremental CountOf Word8
    len) =
        case SipIncremental
    incremental of
            SipIncremental7 Word64
    acc -> InternalState -> SipIncremental -> CountOf Word8 -> Sip
    Sip (Int -> InternalState -> Word64 -> InternalState
    process Int
    c InternalState
    ist ((Word64
    acc Word64 -> Int -> Word64
    forall a. Bits a => a -> Int -> a
    .<<. Int
    8) Word64 -> Word64 -> Word64
    forall a. Bits a => a -> a -> a
    .|. Word8 -> Word64
    forall a b. (Integral a, Num b) => a -> b
    Prelude.fromIntegral Word8
    w))
                                       SipIncremental
    SipIncremental0 (CountOf Word8
    lenCountOf Word8 -> CountOf Word8 -> CountOf Word8
    forall a. Additive a => a -> a -> a
    +CountOf Word8
    1)
            SipIncremental6 Word64
    acc -> (Word64 -> SipIncremental) -> Word64 -> Sip
    doAcc Word64 -> SipIncremental
    SipIncremental7 Word64
    acc
            SipIncremental5 Word64
    acc -> (Word64 -> SipIncremental) -> Word64 -> Sip
    doAcc Word64 -> SipIncremental
    SipIncremental6 Word64
    acc
            SipIncremental4 Word64
    acc -> (Word64 -> SipIncremental) -> Word64 -> Sip
    doAcc Word64 -> SipIncremental
    SipIncremental5 Word64
    acc
            SipIncremental3 Word64
    acc -> (Word64 -> SipIncremental) -> Word64 -> Sip
    doAcc Word64 -> SipIncremental
    SipIncremental4 Word64
    acc
            SipIncremental2 Word64
    acc -> (Word64 -> SipIncremental) -> Word64 -> Sip
    doAcc Word64 -> SipIncremental
    SipIncremental3 Word64
    acc
            SipIncremental1 Word64
    acc -> (Word64 -> SipIncremental) -> Word64 -> Sip
    doAcc Word64 -> SipIncremental
    SipIncremental2 Word64
    acc
            SipIncremental
    SipIncremental0     -> InternalState -> SipIncremental -> CountOf Word8 -> Sip
    Sip InternalState
    ist (Word64 -> SipIncremental
    SipIncremental1 (Word64 -> SipIncremental) -> Word64 -> SipIncremental
    forall a b. (a -> b) -> a -> b
    $ Word8 -> Word64
    forall a b. (Integral a, Num b) => a -> b
    Prelude.fromIntegral Word8
    w) (CountOf Word8
    lenCountOf Word8 -> CountOf Word8 -> CountOf Word8
    forall a. Additive a => a -> a -> a
    +CountOf Word8
    1)
      where
        doAcc :: (Word64 -> SipIncremental) -> Word64 -> Sip
    doAcc Word64 -> SipIncremental
    constr Word64
    acc =
            InternalState -> SipIncremental -> CountOf Word8 -> Sip
    Sip InternalState
    ist (Word64 -> SipIncremental
    constr ((Word64
    acc Word64 -> Int -> Word64
    forall a. Bits a => a -> Int -> a
    .<<. Int
    8) Word64 -> Word64 -> Word64
    forall a. Bits a => a -> a -> a
    .|. Word8 -> Word64
    forall a b. (Integral a, Num b) => a -> b
    Prelude.fromIntegral Word8
    w)) (CountOf Word8
    lenCountOf Word8 -> CountOf Word8 -> CountOf Word8
    forall a. Additive a => a -> a -> a
    +CountOf Word8
    1)

    mix32 :: Int -> Word32 -> Sip -> Sip
    mix32 :: Int -> Word32 -> Sip -> Sip
    mix32 !Int
    c !Word32
    w (Sip InternalState
    ist SipIncremental
    incremental CountOf Word8
    len) =
        case SipIncremental
    incremental of
            SipIncremental
    SipIncremental0     -> InternalState -> SipIncremental -> CountOf Word8 -> Sip
    Sip InternalState
    ist (Word64 -> SipIncremental
    SipIncremental4 (Word64 -> SipIncremental) -> Word64 -> SipIncremental
    forall a b. (a -> b) -> a -> b
    $ Word32 -> Word64
    forall a b. (Integral a, Num b) => a -> b
    Prelude.fromIntegral Word32
    w) (CountOf Word8
    lenCountOf Word8 -> CountOf Word8 -> CountOf Word8
    forall a. Additive a => a -> a -> a
    +CountOf Word8
    4)
            SipIncremental1 Word64
    acc -> Word64 -> Int -> (Word64 -> SipIncremental) -> Sip
    consume Word64
    acc Int
    32 Word64 -> SipIncremental
    SipIncremental5
            SipIncremental2 Word64
    acc -> Word64 -> Int -> (Word64 -> SipIncremental) -> Sip
    consume Word64
    acc Int
    32 Word64 -> SipIncremental
    SipIncremental6
            SipIncremental3 Word64
    acc -> Word64 -> Int -> (Word64 -> SipIncremental) -> Sip
    consume Word64
    acc Int
    32 Word64 -> SipIncremental
    SipIncremental7
            SipIncremental4 Word64
    acc -> InternalState -> SipIncremental -> CountOf Word8 -> Sip
    Sip (Int -> InternalState -> Word64 -> InternalState
    process Int
    c InternalState
    ist ((Word64
    acc Word64 -> Int -> Word64
    forall a. Bits a => a -> Int -> a
    .<<. Int
    32) Word64 -> Word64 -> Word64
    forall a. Bits a => a -> a -> a
    .|. Word32 -> Word64
    forall a b. (Integral a, Num b) => a -> b
    Prelude.fromIntegral Word32
    w)) SipIncremental
    SipIncremental0 (CountOf Word8
    lenCountOf Word8 -> CountOf Word8 -> CountOf Word8
    forall a. Additive a => a -> a -> a
    +CountOf Word8
    4)
            SipIncremental5 Word64
    acc -> Word64 -> Int -> Int -> (Word64 -> SipIncremental) -> Sip
    consumeProcess Word64
    acc Int
    24 Int
    8 Word64 -> SipIncremental
    SipIncremental1
            SipIncremental6 Word64
    acc -> Word64 -> Int -> Int -> (Word64 -> SipIncremental) -> Sip
    consumeProcess Word64
    acc Int
    16 Int
    16 Word64 -> SipIncremental
    SipIncremental2
            SipIncremental7 Word64
    acc -> Word64 -> Int -> Int -> (Word64 -> SipIncremental) -> Sip
    consumeProcess Word64
    acc  Int
    8 Int
    24 Word64 -> SipIncremental
    SipIncremental3
      where
        consume :: Word64 -> Int -> (Word64 -> SipIncremental) -> Sip
    consume Word64
    acc Int
    n Word64 -> SipIncremental
    constr =
            InternalState -> SipIncremental -> CountOf Word8 -> Sip
    Sip InternalState
    ist (Word64 -> SipIncremental
    constr ((Word64
    acc Word64 -> Int -> Word64
    forall a. Bits a => a -> Int -> a
    .<<. Int
    n) Word64 -> Word64 -> Word64
    forall a. Bits a => a -> a -> a
    .&. Word32 -> Word64
    forall a b. (Integral a, Num b) => a -> b
    Prelude.fromIntegral Word32
    w)) (CountOf Word8
    lenCountOf Word8 -> CountOf Word8 -> CountOf Word8
    forall a. Additive a => a -> a -> a
    +CountOf Word8
    4)
        {-# INLINE consume #-}
        consumeProcess :: Word64 -> Int -> Int -> (Word64 -> SipIncremental) -> Sip
    consumeProcess Word64
    acc Int
    n Int
    x Word64 -> SipIncremental
    constr =
            InternalState -> SipIncremental -> CountOf Word8 -> Sip
    Sip (Int -> InternalState -> Word64 -> InternalState
    process Int
    c InternalState
    ist ((Word64
    acc Word64 -> Int -> Word64
    forall a. Bits a => a -> Int -> a
    .<<. Int
    n) Word64 -> Word64 -> Word64
    forall a. Bits a => a -> a -> a
    .|. (Word32 -> Word64
    forall a b. (Integral a, Num b) => a -> b
    Prelude.fromIntegral Word32
    w Word64 -> Int -> Word64
    forall a. Bits a => a -> Int -> a
    .>>. Int
    x)))
                (Word64 -> SipIncremental
    constr (Word32 -> Word64
    forall a b. (Integral a, Num b) => a -> b
    Prelude.fromIntegral Word32
    w Word64 -> Word64 -> Word64
    forall a. Bits a => a -> a -> a
    .&. Int -> Word64
    andMask64 Int
    n))
                (CountOf Word8
    lenCountOf Word8 -> CountOf Word8 -> CountOf Word8
    forall a. Additive a => a -> a -> a
    +CountOf Word8
    4)
        {-# INLINE consumeProcess #-}

    mix64 :: Int -> Word64 -> Sip -> Sip
    mix64 :: Int -> Word64 -> Sip -> Sip
    mix64 !Int
    c !Word64
    w (Sip InternalState
    ist SipIncremental
    incremental CountOf Word8
    len) =
        case SipIncremental
    incremental of
            SipIncremental
    SipIncremental0     -> InternalState -> SipIncremental -> CountOf Word8 -> Sip
    Sip (Int -> InternalState -> Word64 -> InternalState
    process Int
    c InternalState
    ist Word64
    w) SipIncremental
    SipIncremental0 (CountOf Word8
    lenCountOf Word8 -> CountOf Word8 -> CountOf Word8
    forall a. Additive a => a -> a -> a
    +CountOf Word8
    8)
            SipIncremental1 Word64
    acc -> Word64 -> Int -> Int -> (Word64 -> SipIncremental) -> Sip
    consume Word64
    acc Int
    56 Int
    8 Word64 -> SipIncremental
    SipIncremental1
            SipIncremental2 Word64
    acc -> Word64 -> Int -> Int -> (Word64 -> SipIncremental) -> Sip
    consume Word64
    acc Int
    48 Int
    16 Word64 -> SipIncremental
    SipIncremental2
            SipIncremental3 Word64
    acc -> Word64 -> Int -> Int -> (Word64 -> SipIncremental) -> Sip
    consume Word64
    acc Int
    40 Int
    24 Word64 -> SipIncremental
    SipIncremental3
            SipIncremental4 Word64
    acc -> Word64 -> Int -> Int -> (Word64 -> SipIncremental) -> Sip
    consume Word64
    acc Int
    32 Int
    32 Word64 -> SipIncremental
    SipIncremental4
            SipIncremental5 Word64
    acc -> Word64 -> Int -> Int -> (Word64 -> SipIncremental) -> Sip
    consume Word64
    acc Int
    24 Int
    40 Word64 -> SipIncremental
    SipIncremental5
            SipIncremental6 Word64
    acc -> Word64 -> Int -> Int -> (Word64 -> SipIncremental) -> Sip
    consume Word64
    acc Int
    16 Int
    48 Word64 -> SipIncremental
    SipIncremental6
            SipIncremental7 Word64
    acc -> Word64 -> Int -> Int -> (Word64 -> SipIncremental) -> Sip
    consume Word64
    acc  Int
    8 Int
    56 Word64 -> SipIncremental
    SipIncremental7
      where
        consume :: Word64 -> Int -> Int -> (Word64 -> SipIncremental) -> Sip
    consume Word64
    acc Int
    n Int
    x Word64 -> SipIncremental
    constr =
            InternalState -> SipIncremental -> CountOf Word8 -> Sip
    Sip (Int -> InternalState -> Word64 -> InternalState
    process Int
    c InternalState
    ist ((Word64
    acc Word64 -> Int -> Word64
    forall a. Bits a => a -> Int -> a
    .<<. Int
    n) Word64 -> Word64 -> Word64
    forall a. Bits a => a -> a -> a
    .|. ((Word64
    w Word64 -> Int -> Word64
    forall a. Bits a => a -> Int -> a
    .>>. Int
    x) Word64 -> Word64 -> Word64
    forall a. Bits a => a -> a -> a
    .&. Int -> Word64
    andMask64 Int
    n)))
                (Word64 -> SipIncremental
    constr (Word64 -> SipIncremental) -> Word64 -> SipIncremental
    forall a b. (a -> b) -> a -> b
    $ Word64
    acc Word64 -> Word64 -> Word64
    forall a. Bits a => a -> a -> a
    .&. Int -> Word64
    andMask64 Int
    x)
                (CountOf Word8
    lenCountOf Word8 -> CountOf Word8 -> CountOf Word8
    forall a. Additive a => a -> a -> a
    +CountOf Word8
    8)
        {-# INLINE consume #-}

    finish :: Int -> Int -> Sip -> SipHash
    finish :: Int -> Int -> Sip -> SipHash
    finish !Int
    c !Int
    d (Sip InternalState
    ist SipIncremental
    incremental (CountOf Int
    len)) = Int -> InternalState -> SipHash
    finalize Int
    d (InternalState -> SipHash) -> InternalState -> SipHash
    forall a b. (a -> b) -> a -> b
    $
        case SipIncremental
    incremental of
            SipIncremental
    SipIncremental0     -> Int -> InternalState -> Word64 -> InternalState
    process Int
    c InternalState
    ist Word64
    lenMask
            SipIncremental1 Word64
    acc -> Int -> InternalState -> Word64 -> InternalState
    process Int
    c InternalState
    ist (Word64
    lenMask Word64 -> Word64 -> Word64
    forall a. Bits a => a -> a -> a
    .|. Word64
    acc)
            SipIncremental2 Word64
    acc -> Int -> InternalState -> Word64 -> InternalState
    process Int
    c InternalState
    ist (Word64
    lenMask Word64 -> Word64 -> Word64
    forall a. Bits a => a -> a -> a
    .|. Word64
    acc)
            SipIncremental3 Word64
    acc -> Int -> InternalState -> Word64 -> InternalState
    process Int
    c InternalState
    ist (Word64
    lenMask Word64 -> Word64 -> Word64
    forall a. Bits a => a -> a -> a
    .|. Word64
    acc)
            SipIncremental4 Word64
    acc -> Int -> InternalState -> Word64 -> InternalState
    process Int
    c InternalState
    ist (Word64
    lenMask Word64 -> Word64 -> Word64
    forall a. Bits a => a -> a -> a
    .|. Word64
    acc)
            SipIncremental5 Word64
    acc -> Int -> InternalState -> Word64 -> InternalState
    process Int
    c InternalState
    ist (Word64
    lenMask Word64 -> Word64 -> Word64
    forall a. Bits a => a -> a -> a
    .|. Word64
    acc)
            SipIncremental6 Word64
    acc -> Int -> InternalState -> Word64 -> InternalState
    process Int
    c InternalState
    ist (Word64
    lenMask Word64 -> Word64 -> Word64
    forall a. Bits a => a -> a -> a
    .|. Word64
    acc)
            SipIncremental7 Word64
    acc -> Int -> InternalState -> Word64 -> InternalState
    process Int
    c InternalState
    ist (Word64
    lenMask Word64 -> Word64 -> Word64
    forall a. Bits a => a -> a -> a
    .|. Word64
    acc)
      where
        lenMask :: Word64
    lenMask = (Word64
    wlen Word64 -> Word64 -> Word64
    forall a. Bits a => a -> a -> a
    .&. Word64
    0xff) Word64 -> Int -> Word64
    forall a. Bits a => a -> Int -> a
    .<<. Int
    56
        wlen :: Word64
    wlen = Int64 -> Word64
    forall source destination.
    Cast source destination =>
    source -> destination
    cast (Int -> Int64
    forall a b. IntegralUpsize a b => a -> b
    integralUpsize Int
    len :: Int64) :: Word64

    -- | same as 'hash', except also specifies the number of sipround iterations for compression (C) and digest (D).
    mixBa :: PrimType a => Int -> UArray a -> Sip -> Sip
    mixBa :: forall a. PrimType a => Int -> UArray a -> Sip -> Sip
    mixBa !Int
    c !UArray a
    array (Sip InternalState
    initSt SipIncremental
    initIncr CountOf Word8
    currentLen) =
        (Block Word8 -> Offset Word8 -> Sip)
    -> (Ptr Word8 -> Offset Word8 -> ST Any Sip) -> UArray Word8 -> Sip
    forall ty a s.
    (Block ty -> Offset ty -> a)
    -> (Ptr ty -> Offset ty -> ST s a) -> UArray ty -> a
    A.unsafeDewrap Block Word8 -> Offset Word8 -> Sip
    goVec Ptr Word8 -> Offset Word8 -> ST Any Sip
    forall s. Ptr Word8 -> Offset Word8 -> ST s Sip
    goAddr UArray Word8
    array8
      where
        totalLen :: CountOf Word8
    totalLen = UArray Word8 -> CountOf Word8
    forall ty. UArray ty -> CountOf ty
    A.length UArray Word8
    array8
        array8 :: UArray Word8
    array8 = UArray a -> UArray Word8
    forall a b. (PrimType a, PrimType b) => UArray a -> UArray b
    A.unsafeRecast UArray a
    array

        goVec :: Block Word8 -> Offset Word8 -> Sip
        goVec :: Block Word8 -> Offset Word8 -> Sip
    goVec (Block ByteArray#
    ba) Offset Word8
    start = InternalState
    -> SipIncremental -> Offset Word8 -> CountOf Word8 -> Sip
    loop8 InternalState
    initSt SipIncremental
    initIncr Offset Word8
    start CountOf Word8
    totalLen
          where
            loop8 :: InternalState
    -> SipIncremental -> Offset Word8 -> CountOf Word8 -> Sip
    loop8 !InternalState
    st !SipIncremental
    incr            Offset Word8
    _     CountOf Word8
    0 = InternalState -> SipIncremental -> CountOf Word8 -> Sip
    Sip InternalState
    st SipIncremental
    incr (CountOf Word8
    currentLen CountOf Word8 -> CountOf Word8 -> CountOf Word8
    forall a. Additive a => a -> a -> a
    + CountOf Word8
    totalLen)
            loop8 !InternalState
    st SipIncremental
    SipIncremental0 !Offset Word8
    ofs !CountOf Word8
    l = case CountOf Word8
    l CountOf Word8 -> CountOf Word8 -> Difference (CountOf Word8)
    forall a. Subtractive a => a -> a -> Difference a
    - CountOf Word8
    8 of
                Maybe (CountOf Word8)
    Difference (CountOf Word8)
    Nothing -> InternalState
    -> SipIncremental -> Offset Word8 -> CountOf Word8 -> Sip
    loop1 InternalState
    st SipIncremental
    SipIncremental0 Offset Word8
    ofs CountOf Word8
    l
                Just CountOf Word8
    l8 ->
                    let v :: Word64
    v =     Int -> Word8 -> Word64
    to64 Int
    56 (ByteArray# -> Offset Word8 -> Word8
    forall ty. PrimType ty => ByteArray# -> Offset ty -> ty
    primBaIndex ByteArray#
    ba Offset Word8
    ofs)
                            Word64 -> Word64 -> Word64
    forall a. Bits a => a -> a -> a
    .|. Int -> Word8 -> Word64
    to64 Int
    48 (ByteArray# -> Offset Word8 -> Word8
    forall ty. PrimType ty => ByteArray# -> Offset ty -> ty
    primBaIndex ByteArray#
    ba (Offset Word8
    ofs Offset Word8 -> Offset Word8 -> Offset Word8
    forall a. Additive a => a -> a -> a
    + Int -> Offset Word8
    forall ty. Int -> Offset ty
    Offset Int
    1))
                            Word64 -> Word64 -> Word64
    forall a. Bits a => a -> a -> a
    .|. Int -> Word8 -> Word64
    to64 Int
    40 (ByteArray# -> Offset Word8 -> Word8
    forall ty. PrimType ty => ByteArray# -> Offset ty -> ty
    primBaIndex ByteArray#
    ba (Offset Word8
    ofs Offset Word8 -> Offset Word8 -> Offset Word8
    forall a. Additive a => a -> a -> a
    + Int -> Offset Word8
    forall ty. Int -> Offset ty
    Offset Int
    2))
                            Word64 -> Word64 -> Word64
    forall a. Bits a => a -> a -> a
    .|. Int -> Word8 -> Word64
    to64 Int
    32 (ByteArray# -> Offset Word8 -> Word8
    forall ty. PrimType ty => ByteArray# -> Offset ty -> ty
    primBaIndex ByteArray#
    ba (Offset Word8
    ofs Offset Word8 -> Offset Word8 -> Offset Word8
    forall a. Additive a => a -> a -> a
    + Int -> Offset Word8
    forall ty. Int -> Offset ty
    Offset Int
    3))
                            Word64 -> Word64 -> Word64
    forall a. Bits a => a -> a -> a
    .|. Int -> Word8 -> Word64
    to64 Int
    24 (ByteArray# -> Offset Word8 -> Word8
    forall ty. PrimType ty => ByteArray# -> Offset ty -> ty
    primBaIndex ByteArray#
    ba (Offset Word8
    ofs Offset Word8 -> Offset Word8 -> Offset Word8
    forall a. Additive a => a -> a -> a
    + Int -> Offset Word8
    forall ty. Int -> Offset ty
    Offset Int
    4))
                            Word64 -> Word64 -> Word64
    forall a. Bits a => a -> a -> a
    .|. Int -> Word8 -> Word64
    to64 Int
    16 (ByteArray# -> Offset Word8 -> Word8
    forall ty. PrimType ty => ByteArray# -> Offset ty -> ty
    primBaIndex ByteArray#
    ba (Offset Word8
    ofs Offset Word8 -> Offset Word8 -> Offset Word8
    forall a. Additive a => a -> a -> a
    + Int -> Offset Word8
    forall ty. Int -> Offset ty
    Offset Int
    5))
                            Word64 -> Word64 -> Word64
    forall a. Bits a => a -> a -> a
    .|. Int -> Word8 -> Word64
    to64 Int
    8  (ByteArray# -> Offset Word8 -> Word8
    forall ty. PrimType ty => ByteArray# -> Offset ty -> ty
    primBaIndex ByteArray#
    ba (Offset Word8
    ofs Offset Word8 -> Offset Word8 -> Offset Word8
    forall a. Additive a => a -> a -> a
    + Int -> Offset Word8
    forall ty. Int -> Offset ty
    Offset Int
    6))
                            Word64 -> Word64 -> Word64
    forall a. Bits a => a -> a -> a
    .|. Int -> Word8 -> Word64
    to64 Int
    0  (ByteArray# -> Offset Word8 -> Word8
    forall ty. PrimType ty => ByteArray# -> Offset ty -> ty
    primBaIndex ByteArray#
    ba (Offset Word8
    ofs Offset Word8 -> Offset Word8 -> Offset Word8
    forall a. Additive a => a -> a -> a
    + Int -> Offset Word8
    forall ty. Int -> Offset ty
    Offset Int
    7))
                    in InternalState
    -> SipIncremental -> Offset Word8 -> CountOf Word8 -> Sip
    loop8 (Int -> InternalState -> Word64 -> InternalState
    process Int
    c InternalState
    st Word64
    v) SipIncremental
    SipIncremental0 (Offset Word8
    start Offset Word8 -> Offset Word8 -> Offset Word8
    forall a. Additive a => a -> a -> a
    + Int -> Offset Word8
    forall ty. Int -> Offset ty
    Offset Int
    8) CountOf Word8
    l8
            loop8 !InternalState
    st !SipIncremental
    incr !Offset Word8
    ofs !CountOf Word8
    l = InternalState
    -> SipIncremental -> Offset Word8 -> CountOf Word8 -> Sip
    loop1 InternalState
    st SipIncremental
    incr Offset Word8
    ofs CountOf Word8
    l
            loop1 :: InternalState
    -> SipIncremental -> Offset Word8 -> CountOf Word8 -> Sip
    loop1 !InternalState
    st !SipIncremental
    incr !Offset Word8
    ofs !CountOf Word8
    l = case CountOf Word8
    l CountOf Word8 -> CountOf Word8 -> Difference (CountOf Word8)
    forall a. Subtractive a => a -> a -> Difference a
    - CountOf Word8
    1 of
                Maybe (CountOf Word8)
    Difference (CountOf Word8)
    Nothing -> InternalState -> SipIncremental -> CountOf Word8 -> Sip
    Sip InternalState
    st SipIncremental
    incr (CountOf Word8
    currentLen CountOf Word8 -> CountOf Word8 -> CountOf Word8
    forall a. Additive a => a -> a -> a
    + CountOf Word8
    totalLen)
                Just CountOf Word8
    l1 -> let (!InternalState
    st', !SipIncremental
    incr') = Int
    -> Word8
    -> InternalState
    -> SipIncremental
    -> (InternalState, SipIncremental)
    mix8Prim Int
    c (ByteArray# -> Offset Word8 -> Word8
    forall ty. PrimType ty => ByteArray# -> Offset ty -> ty
    primBaIndex ByteArray#
    ba Offset Word8
    ofs) InternalState
    st SipIncremental
    incr
                            in InternalState
    -> SipIncremental -> Offset Word8 -> CountOf Word8 -> Sip
    loop1 InternalState
    st' SipIncremental
    incr' (Offset Word8
    ofs Offset Word8 -> Offset Word8 -> Offset Word8
    forall a. Additive a => a -> a -> a
    + Int -> Offset Word8
    forall ty. Int -> Offset ty
    Offset Int
    1) CountOf Word8
    l1

        to64 :: Int -> Word8 -> Word64
        to64 :: Int -> Word8 -> Word64
    to64 Int
    0  !Word8
    v = Word8 -> Word64
    forall a b. (Integral a, Num b) => a -> b
    Prelude.fromIntegral Word8
    v
        to64 !Int
    s !Word8
    v = Word8 -> Word64
    forall a b. (Integral a, Num b) => a -> b
    Prelude.fromIntegral Word8
    v Word64 -> Int -> Word64
    forall a. Bits a => a -> Int -> a
    .<<. Int
    s

        goAddr :: Ptr Word8 -> Offset Word8 -> ST s Sip
        goAddr :: forall s. Ptr Word8 -> Offset Word8 -> ST s Sip
    goAddr (Ptr Addr#
    ptr) Offset Word8
    start = Sip -> ST s Sip
    forall a. a -> ST s a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Sip -> ST s Sip) -> Sip -> ST s Sip
    forall a b. (a -> b) -> a -> b
    $ InternalState
    -> SipIncremental -> Offset Word8 -> CountOf Word8 -> Sip
    loop8 InternalState
    initSt SipIncremental
    initIncr Offset Word8
    start CountOf Word8
    totalLen
          where
            loop8 :: InternalState
    -> SipIncremental -> Offset Word8 -> CountOf Word8 -> Sip
    loop8 !InternalState
    st !SipIncremental
    incr            Offset Word8
    _     CountOf Word8
    0 = InternalState -> SipIncremental -> CountOf Word8 -> Sip
    Sip InternalState
    st SipIncremental
    incr (CountOf Word8
    currentLen CountOf Word8 -> CountOf Word8 -> CountOf Word8
    forall a. Additive a => a -> a -> a
    + CountOf Word8
    totalLen)
            loop8 !InternalState
    st SipIncremental
    SipIncremental0 !Offset Word8
    ofs !CountOf Word8
    l = case CountOf Word8
    l CountOf Word8 -> CountOf Word8 -> Difference (CountOf Word8)
    forall a. Subtractive a => a -> a -> Difference a
    - CountOf Word8
    8 of
                Maybe (CountOf Word8)
    Difference (CountOf Word8)
    Nothing -> InternalState
    -> SipIncremental -> Offset Word8 -> CountOf Word8 -> Sip
    loop1 InternalState
    st SipIncremental
    SipIncremental0 Offset Word8
    ofs CountOf Word8
    l
                Just CountOf Word8
    l8 ->
                    let v :: Word64
    v =     Int -> Word8 -> Word64
    to64 Int
    56 (Addr# -> Offset Word8 -> Word8
    forall ty. PrimType ty => Addr# -> Offset ty -> ty
    primAddrIndex Addr#
    ptr Offset Word8
    ofs)
                            Word64 -> Word64 -> Word64
    forall a. Bits a => a -> a -> a
    .|. Int -> Word8 -> Word64
    to64 Int
    48 (Addr# -> Offset Word8 -> Word8
    forall ty. PrimType ty => Addr# -> Offset ty -> ty
    primAddrIndex Addr#
    ptr (Offset Word8
    ofs Offset Word8 -> Offset Word8 -> Offset Word8
    forall a. Additive a => a -> a -> a
    + Int -> Offset Word8
    forall ty. Int -> Offset ty
    Offset Int
    1))
                            Word64 -> Word64 -> Word64
    forall a. Bits a => a -> a -> a
    .|. Int -> Word8 -> Word64
    to64 Int
    40 (Addr# -> Offset Word8 -> Word8
    forall ty. PrimType ty => Addr# -> Offset ty -> ty
    primAddrIndex Addr#
    ptr (Offset Word8
    ofs Offset Word8 -> Offset Word8 -> Offset Word8
    forall a. Additive a => a -> a -> a
    + Int -> Offset Word8
    forall ty. Int -> Offset ty
    Offset Int
    2))
                            Word64 -> Word64 -> Word64
    forall a. Bits a => a -> a -> a
    .|. Int -> Word8 -> Word64
    to64 Int
    32 (Addr# -> Offset Word8 -> Word8
    forall ty. PrimType ty => Addr# -> Offset ty -> ty
    primAddrIndex Addr#
    ptr (Offset Word8
    ofs Offset Word8 -> Offset Word8 -> Offset Word8
    forall a. Additive a => a -> a -> a
    + Int -> Offset Word8
    forall ty. Int -> Offset ty
    Offset Int
    3))
                            Word64 -> Word64 -> Word64
    forall a. Bits a => a -> a -> a
    .|. Int -> Word8 -> Word64
    to64 Int
    24 (Addr# -> Offset Word8 -> Word8
    forall ty. PrimType ty => Addr# -> Offset ty -> ty
    primAddrIndex Addr#
    ptr (Offset Word8
    ofs Offset Word8 -> Offset Word8 -> Offset Word8
    forall a. Additive a => a -> a -> a
    + Int -> Offset Word8
    forall ty. Int -> Offset ty
    Offset Int
    4))
                            Word64 -> Word64 -> Word64
    forall a. Bits a => a -> a -> a
    .|. Int -> Word8 -> Word64
    to64 Int
    16 (Addr# -> Offset Word8 -> Word8
    forall ty. PrimType ty => Addr# -> Offset ty -> ty
    primAddrIndex Addr#
    ptr (Offset Word8
    ofs Offset Word8 -> Offset Word8 -> Offset Word8
    forall a. Additive a => a -> a -> a
    + Int -> Offset Word8
    forall ty. Int -> Offset ty
    Offset Int
    5))
                            Word64 -> Word64 -> Word64
    forall a. Bits a => a -> a -> a
    .|. Int -> Word8 -> Word64
    to64 Int
    8  (Addr# -> Offset Word8 -> Word8
    forall ty. PrimType ty => Addr# -> Offset ty -> ty
    primAddrIndex Addr#
    ptr (Offset Word8
    ofs Offset Word8 -> Offset Word8 -> Offset Word8
    forall a. Additive a => a -> a -> a
    + Int -> Offset Word8
    forall ty. Int -> Offset ty
    Offset Int
    6))
                            Word64 -> Word64 -> Word64
    forall a. Bits a => a -> a -> a
    .|. Int -> Word8 -> Word64
    to64 Int
    0  (Addr# -> Offset Word8 -> Word8
    forall ty. PrimType ty => Addr# -> Offset ty -> ty
    primAddrIndex Addr#
    ptr (Offset Word8
    ofs Offset Word8 -> Offset Word8 -> Offset Word8
    forall a. Additive a => a -> a -> a
    + Int -> Offset Word8
    forall ty. Int -> Offset ty
    Offset Int
    7))
                    in InternalState
    -> SipIncremental -> Offset Word8 -> CountOf Word8 -> Sip
    loop8 (Int -> InternalState -> Word64 -> InternalState
    process Int
    c InternalState
    st Word64
    v) SipIncremental
    SipIncremental0 (Offset Word8
    start Offset Word8 -> Offset Word8 -> Offset Word8
    forall a. Additive a => a -> a -> a
    + Int -> Offset Word8
    forall ty. Int -> Offset ty
    Offset Int
    8) CountOf Word8
    l8 -- (l - 8)
            loop8 !InternalState
    st !SipIncremental
    incr !Offset Word8
    ofs !CountOf Word8
    l = InternalState
    -> SipIncremental -> Offset Word8 -> CountOf Word8 -> Sip
    loop1 InternalState
    st SipIncremental
    incr Offset Word8
    ofs CountOf Word8
    l
            loop1 :: InternalState
    -> SipIncremental -> Offset Word8 -> CountOf Word8 -> Sip
    loop1 !InternalState
    st !SipIncremental
    incr !Offset Word8
    ofs !CountOf Word8
    l = case CountOf Word8
    l CountOf Word8 -> CountOf Word8 -> Difference (CountOf Word8)
    forall a. Subtractive a => a -> a -> Difference a
    - CountOf Word8
    1 of
              Maybe (CountOf Word8)
    Difference (CountOf Word8)
    Nothing -> InternalState -> SipIncremental -> CountOf Word8 -> Sip
    Sip InternalState
    st SipIncremental
    incr (CountOf Word8
    currentLen CountOf Word8 -> CountOf Word8 -> CountOf Word8
    forall a. Additive a => a -> a -> a
    + CountOf Word8
    totalLen)
              Just CountOf Word8
    l1 -> let (!InternalState
    st', !SipIncremental
    incr') = Int
    -> Word8
    -> InternalState
    -> SipIncremental
    -> (InternalState, SipIncremental)
    mix8Prim Int
    c (Addr# -> Offset Word8 -> Word8
    forall ty. PrimType ty => Addr# -> Offset ty -> ty
    primAddrIndex Addr#
    ptr Offset Word8
    ofs) InternalState
    st SipIncremental
    incr
                          in InternalState
    -> SipIncremental -> Offset Word8 -> CountOf Word8 -> Sip
    loop1 InternalState
    st' SipIncremental
    incr' (Offset Word8
    ofs Offset Word8 -> Offset Word8 -> Offset Word8
    forall a. Additive a => a -> a -> a
    + Int -> Offset Word8
    forall ty. Int -> Offset ty
    Offset Int
    1) CountOf Word8
    l1

    doRound :: InternalState -> InternalState
    doRound :: InternalState -> InternalState
    doRound (InternalState !Word64
    v0 !Word64
    v1 !Word64
    v2 !Word64
    v3) =
          let !v0' :: Word64
    v0'    = Word64
    v0 Word64 -> Word64 -> Word64
    forall a. Additive a => a -> a -> a
    + Word64
    v1
              !v2' :: Word64
    v2'    = Word64
    v2 Word64 -> Word64 -> Word64
    forall a. Additive a => a -> a -> a
    + Word64
    v3
              !v1' :: Word64
    v1'    = Word64
    v1 Word64 -> Int -> Word64
    forall a. Bits a => a -> Int -> a
    `rotateL` Int
    13
              !v3' :: Word64
    v3'    = Word64
    v3 Word64 -> Int -> Word64
    forall a. Bits a => a -> Int -> a
    `rotateL` Int
    16
              !v1'' :: Word64
    v1''   = Word64
    v1' Word64 -> Word64 -> Word64
    forall a. Bits a => a -> a -> a
    `xor` Word64
    v0'
              !v3'' :: Word64
    v3''   = Word64
    v3' Word64 -> Word64 -> Word64
    forall a. Bits a => a -> a -> a
    `xor` Word64
    v2'
              !v0'' :: Word64
    v0''   = Word64
    v0' Word64 -> Int -> Word64
    forall a. Bits a => a -> Int -> a
    `rotateL` Int
    32
              !v2'' :: Word64
    v2''   = Word64
    v2' Word64 -> Word64 -> Word64
    forall a. Additive a => a -> a -> a
    + Word64
    v1''
              !v0''' :: Word64
    v0'''  = Word64
    v0'' Word64 -> Word64 -> Word64
    forall a. Additive a => a -> a -> a
    + Word64
    v3''
              !v1''' :: Word64
    v1'''  = Word64
    v1'' Word64 -> Int -> Word64
    forall a. Bits a => a -> Int -> a
    `rotateL` Int
    17
              !v3''' :: Word64
    v3'''  = Word64
    v3'' Word64 -> Int -> Word64
    forall a. Bits a => a -> Int -> a
    `rotateL` Int
    21
              !v1'''' :: Word64
    v1'''' = Word64
    v1''' Word64 -> Word64 -> Word64
    forall a. Bits a => a -> a -> a
    `xor` Word64
    v2''
              !v3'''' :: Word64
    v3'''' = Word64
    v3''' Word64 -> Word64 -> Word64
    forall a. Bits a => a -> a -> a
    `xor` Word64
    v0'''
              !v2''' :: Word64
    v2'''  = Word64
    v2'' Word64 -> Int -> Word64
    forall a. Bits a => a -> Int -> a
    `rotateL` Int
    32
           in Word64 -> Word64 -> Word64 -> Word64 -> InternalState
    InternalState Word64
    v0''' Word64
    v1'''' Word64
    v2''' Word64
    v3''''
    {-# INLINE doRound #-}

    process :: Int -> InternalState -> Word64 -> InternalState
    process :: Int -> InternalState -> Word64 -> InternalState
    process !Int
    c !InternalState
    istate !Word64
    m = InternalState -> InternalState
    postInject (InternalState -> InternalState) -> InternalState -> InternalState
    forall a b. (a -> b) -> a -> b
    $! InternalState -> InternalState
    runRoundsCompression (InternalState -> InternalState) -> InternalState -> InternalState
    forall a b. (a -> b) -> a -> b
    $! InternalState -> InternalState
    preInject InternalState
    istate
      where
        preInject :: InternalState -> InternalState
    preInject  (InternalState Word64
    v0 Word64
    v1 Word64
    v2 Word64
    v3) = Word64 -> Word64 -> Word64 -> Word64 -> InternalState
    InternalState Word64
    v0 Word64
    v1 Word64
    v2 (Word64
    v3 Word64 -> Word64 -> Word64
    forall a. Bits a => a -> a -> a
    `xor` Word64
    m)
        postInject :: InternalState -> InternalState
    postInject (InternalState Word64
    v0 Word64
    v1 Word64
    v2 Word64
    v3) = Word64 -> Word64 -> Word64 -> Word64 -> InternalState
    InternalState (Word64
    v0 Word64 -> Word64 -> Word64
    forall a. Bits a => a -> a -> a
    `xor` Word64
    m) Word64
    v1 Word64
    v2 Word64
    v3

        runRoundsCompression :: InternalState -> InternalState
    runRoundsCompression InternalState
    st
            | Int
    c Int -> Int -> Bool
    forall a. Eq a => a -> a -> Bool
    == Int
    2    = InternalState -> InternalState
    doRound (InternalState -> InternalState) -> InternalState -> InternalState
    forall a b. (a -> b) -> a -> b
    $! InternalState -> InternalState
    doRound InternalState
    st
            | Bool
    otherwise = Int -> InternalState -> InternalState
    loopRounds Int
    c InternalState
    st
    {-# INLINE process #-}

    finalize :: Int -> InternalState -> SipHash
    finalize :: Int -> InternalState -> SipHash
    finalize !Int
    d !InternalState
    istate = InternalState -> SipHash
    getDigest (InternalState -> SipHash) -> InternalState -> SipHash
    forall a b. (a -> b) -> a -> b
    $! InternalState -> InternalState
    runRoundsDigest (InternalState -> InternalState) -> InternalState -> InternalState
    forall a b. (a -> b) -> a -> b
    $! InternalState -> InternalState
    preInject InternalState
    istate
      where
        getDigest :: InternalState -> SipHash
    getDigest (InternalState Word64
    v0 Word64
    v1 Word64
    v2 Word64
    v3) = Word64 -> SipHash
    SipHash (Word64
    v0 Word64 -> Word64 -> Word64
    forall a. Bits a => a -> a -> a
    `xor` Word64
    v1 Word64 -> Word64 -> Word64
    forall a. Bits a => a -> a -> a
    `xor` Word64
    v2 Word64 -> Word64 -> Word64
    forall a. Bits a => a -> a -> a
    `xor` Word64
    v3)
        preInject :: InternalState -> InternalState
    preInject (InternalState Word64
    v0 Word64
    v1 Word64
    v2 Word64
    v3) = Word64 -> Word64 -> Word64 -> Word64 -> InternalState
    InternalState Word64
    v0 Word64
    v1 (Word64
    v2 Word64 -> Word64 -> Word64
    forall a. Bits a => a -> a -> a
    `xor` Word64
    0xff) Word64
    v3
        runRoundsDigest :: InternalState -> InternalState
    runRoundsDigest InternalState
    st
            | Int
    d Int -> Int -> Bool
    forall a. Eq a => a -> a -> Bool
    == Int
    4    = InternalState -> InternalState
    doRound (InternalState -> InternalState) -> InternalState -> InternalState
    forall a b. (a -> b) -> a -> b
    $! InternalState -> InternalState
    doRound (InternalState -> InternalState) -> InternalState -> InternalState
    forall a b. (a -> b) -> a -> b
    $! InternalState -> InternalState
    doRound (InternalState -> InternalState) -> InternalState -> InternalState
    forall a b. (a -> b) -> a -> b
    $! InternalState -> InternalState
    doRound InternalState
    st
            | Bool
    otherwise = Int -> InternalState -> InternalState
    loopRounds Int
    d InternalState
    st
    {-# INLINE finalize #-}

    loopRounds :: Int -> InternalState -> InternalState
    loopRounds :: Int -> InternalState -> InternalState
    loopRounds Int
    1 !InternalState
    v = InternalState -> InternalState
    doRound InternalState
    v
    loopRounds Int
    n !InternalState
    v = Int -> InternalState -> InternalState
    loopRounds (Int
    nInt -> Int -> Difference Int
    forall a. Subtractive a => a -> a -> Difference a
    -Int
    1) (InternalState -> InternalState
    doRound InternalState
    v)
    {-# INLINE loopRounds #-}

    andMask64 :: Int -> Word64
    andMask64 :: Int -> Word64
    andMask64 Int
    64 = Word64
    0xffffffffffffffff
    andMask64 Int
    56 = Word64
    0x00ffffffffffffff
    andMask64 Int
    48 = Word64
    0x0000ffffffffffff
    andMask64 Int
    40 = Word64
    0x000000ffffffffff
    andMask64 Int
    32 = Word64
    0x00000000ffffffff
    andMask64 Int
    24 = Word64
    0x0000000000ffffff
    andMask64 Int
    16 = Word64
    0x000000000000ffff
    andMask64 Int
    8  = Word64
    0x00000000000000ff
    andMask64 Int
    n  = (Word64
    1 Word64 -> Int -> Word64
    forall a. Bits a => a -> Int -> a
    .<<. Int
    n) Word64 -> Word64 -> Difference Word64
    forall a. Subtractive a => a -> a -> Difference a
    - (Word64
    1 :: Word64)
    {-# INLINE andMask64 #-}