-- |
-- 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
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
showList :: [SipHash] -> ShowS
$cshowList :: [SipHash] -> ShowS
show :: SipHash -> String
$cshow :: SipHash -> String
showsPrec :: Int -> SipHash -> ShowS
$cshowsPrec :: Int -> SipHash -> ShowS
Show,SipHash -> SipHash -> Bool
(SipHash -> SipHash -> Bool)
-> (SipHash -> SipHash -> Bool) -> Eq SipHash
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: SipHash -> SipHash -> Bool
$c/= :: SipHash -> SipHash -> Bool
== :: SipHash -> SipHash -> Bool
$c== :: 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
min :: SipHash -> SipHash -> SipHash
$cmin :: SipHash -> SipHash -> SipHash
max :: SipHash -> SipHash -> SipHash
$cmax :: SipHash -> SipHash -> SipHash
>= :: SipHash -> SipHash -> Bool
$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
compare :: SipHash -> SipHash -> Ordering
$ccompare :: SipHash -> SipHash -> Ordering
$cp1Ord :: Eq 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 :: 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 :: 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 :: 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
            Difference (CountOf Word8)
Nothing -> InternalState
-> SipIncremental -> Offset Word8 -> CountOf Word8 -> Sip
loop1 InternalState
st SipIncremental
SipIncremental0 Offset Word8
ofs CountOf Word8
l
            Just 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
            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 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 :: Ptr Word8 -> Offset Word8 -> ST s Sip
goAddr (Ptr Addr#
ptr) Offset Word8
start = Sip -> ST s Sip
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
            Difference (CountOf Word8)
Nothing -> InternalState
-> SipIncremental -> Offset Word8 -> CountOf Word8 -> Sip
loop1 InternalState
st SipIncremental
SipIncremental0 Offset Word8
ofs CountOf Word8
l
            Just 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
          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 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 #-}