{-# OPTIONS_HADDOCK hide #-}
{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE MagicHash #-}
{-# LANGUAGE PatternSynonyms #-}
{-# LANGUAGE UnboxedTuples #-}
module Crypto.Hash.SHA512.Arm (
sha512_arm_available
, hash
, hmac
, _hmac_rr
, _hmac_rsb
) where
import qualified Data.ByteString as BS
import qualified Data.ByteString.Internal as BI
import qualified Data.ByteString.Unsafe as BU
import Data.Word (Word8, Word64)
import Foreign.Marshal.Alloc (allocaBytes)
import Foreign.Ptr (Ptr)
import qualified GHC.Exts as Exts
import qualified GHC.IO (IO(..))
import qualified GHC.Ptr
import Crypto.Hash.SHA512.Internal hiding (update)
import System.IO.Unsafe (unsafeDupablePerformIO)
foreign import ccall unsafe "sha512_block_arm"
c_sha512_block :: Ptr Word64 -> Ptr Word64 -> IO ()
foreign import ccall unsafe "sha512_arm_available"
c_sha512_arm_available :: IO Int
fi :: (Integral a, Num b) => a -> b
fi :: forall a b. (Integral a, Num b) => a -> b
fi = a -> b
forall a b. (Integral a, Num b) => a -> b
fromIntegral
{-# INLINE fi #-}
peek_registers
:: Ptr Word64
-> Registers
peek_registers :: Ptr Word64 -> Registers
peek_registers (GHC.Ptr.Ptr Addr#
addr) = Word64#
-> Word64#
-> Word64#
-> Word64#
-> Word64#
-> Word64#
-> Word64#
-> Word64#
-> Registers
R
(Addr# -> Int# -> Word64#
Exts.indexWord64OffAddr# Addr#
addr Int#
0#)
(Addr# -> Int# -> Word64#
Exts.indexWord64OffAddr# Addr#
addr Int#
1#)
(Addr# -> Int# -> Word64#
Exts.indexWord64OffAddr# Addr#
addr Int#
2#)
(Addr# -> Int# -> Word64#
Exts.indexWord64OffAddr# Addr#
addr Int#
3#)
(Addr# -> Int# -> Word64#
Exts.indexWord64OffAddr# Addr#
addr Int#
4#)
(Addr# -> Int# -> Word64#
Exts.indexWord64OffAddr# Addr#
addr Int#
5#)
(Addr# -> Int# -> Word64#
Exts.indexWord64OffAddr# Addr#
addr Int#
6#)
(Addr# -> Int# -> Word64#
Exts.indexWord64OffAddr# Addr#
addr Int#
7#)
{-# INLINE peek_registers #-}
poke_block :: Ptr Word64 -> Block -> IO ()
poke_block :: Ptr Word64 -> Block -> IO ()
poke_block
(GHC.Ptr.Ptr Addr#
addr)
(B Word64#
w00 Word64#
w01 Word64#
w02 Word64#
w03 Word64#
w04 Word64#
w05 Word64#
w06 Word64#
w07 Word64#
w08 Word64#
w09 Word64#
w10 Word64#
w11 Word64#
w12 Word64#
w13 Word64#
w14 Word64#
w15)
= (State# RealWorld -> (# State# RealWorld, () #)) -> IO ()
forall a. (State# RealWorld -> (# State# RealWorld, a #)) -> IO a
GHC.IO.IO ((State# RealWorld -> (# State# RealWorld, () #)) -> IO ())
-> (State# RealWorld -> (# State# RealWorld, () #)) -> IO ()
forall a b. (a -> b) -> a -> b
$ \State# RealWorld
s00 ->
case Addr# -> Int# -> Word64# -> State# RealWorld -> State# RealWorld
forall d. Addr# -> Int# -> Word64# -> State# d -> State# d
Exts.writeWord64OffAddr# Addr#
addr Int#
00# Word64#
w00 State# RealWorld
s00 of { State# RealWorld
s01 ->
case Addr# -> Int# -> Word64# -> State# RealWorld -> State# RealWorld
forall d. Addr# -> Int# -> Word64# -> State# d -> State# d
Exts.writeWord64OffAddr# Addr#
addr Int#
01# Word64#
w01 State# RealWorld
s01 of { State# RealWorld
s02 ->
case Addr# -> Int# -> Word64# -> State# RealWorld -> State# RealWorld
forall d. Addr# -> Int# -> Word64# -> State# d -> State# d
Exts.writeWord64OffAddr# Addr#
addr Int#
02# Word64#
w02 State# RealWorld
s02 of { State# RealWorld
s03 ->
case Addr# -> Int# -> Word64# -> State# RealWorld -> State# RealWorld
forall d. Addr# -> Int# -> Word64# -> State# d -> State# d
Exts.writeWord64OffAddr# Addr#
addr Int#
03# Word64#
w03 State# RealWorld
s03 of { State# RealWorld
s04 ->
case Addr# -> Int# -> Word64# -> State# RealWorld -> State# RealWorld
forall d. Addr# -> Int# -> Word64# -> State# d -> State# d
Exts.writeWord64OffAddr# Addr#
addr Int#
04# Word64#
w04 State# RealWorld
s04 of { State# RealWorld
s05 ->
case Addr# -> Int# -> Word64# -> State# RealWorld -> State# RealWorld
forall d. Addr# -> Int# -> Word64# -> State# d -> State# d
Exts.writeWord64OffAddr# Addr#
addr Int#
05# Word64#
w05 State# RealWorld
s05 of { State# RealWorld
s06 ->
case Addr# -> Int# -> Word64# -> State# RealWorld -> State# RealWorld
forall d. Addr# -> Int# -> Word64# -> State# d -> State# d
Exts.writeWord64OffAddr# Addr#
addr Int#
06# Word64#
w06 State# RealWorld
s06 of { State# RealWorld
s07 ->
case Addr# -> Int# -> Word64# -> State# RealWorld -> State# RealWorld
forall d. Addr# -> Int# -> Word64# -> State# d -> State# d
Exts.writeWord64OffAddr# Addr#
addr Int#
07# Word64#
w07 State# RealWorld
s07 of { State# RealWorld
s08 ->
case Addr# -> Int# -> Word64# -> State# RealWorld -> State# RealWorld
forall d. Addr# -> Int# -> Word64# -> State# d -> State# d
Exts.writeWord64OffAddr# Addr#
addr Int#
08# Word64#
w08 State# RealWorld
s08 of { State# RealWorld
s09 ->
case Addr# -> Int# -> Word64# -> State# RealWorld -> State# RealWorld
forall d. Addr# -> Int# -> Word64# -> State# d -> State# d
Exts.writeWord64OffAddr# Addr#
addr Int#
09# Word64#
w09 State# RealWorld
s09 of { State# RealWorld
s10 ->
case Addr# -> Int# -> Word64# -> State# RealWorld -> State# RealWorld
forall d. Addr# -> Int# -> Word64# -> State# d -> State# d
Exts.writeWord64OffAddr# Addr#
addr Int#
10# Word64#
w10 State# RealWorld
s10 of { State# RealWorld
s11 ->
case Addr# -> Int# -> Word64# -> State# RealWorld -> State# RealWorld
forall d. Addr# -> Int# -> Word64# -> State# d -> State# d
Exts.writeWord64OffAddr# Addr#
addr Int#
11# Word64#
w11 State# RealWorld
s11 of { State# RealWorld
s12 ->
case Addr# -> Int# -> Word64# -> State# RealWorld -> State# RealWorld
forall d. Addr# -> Int# -> Word64# -> State# d -> State# d
Exts.writeWord64OffAddr# Addr#
addr Int#
12# Word64#
w12 State# RealWorld
s12 of { State# RealWorld
s13 ->
case Addr# -> Int# -> Word64# -> State# RealWorld -> State# RealWorld
forall d. Addr# -> Int# -> Word64# -> State# d -> State# d
Exts.writeWord64OffAddr# Addr#
addr Int#
13# Word64#
w13 State# RealWorld
s13 of { State# RealWorld
s14 ->
case Addr# -> Int# -> Word64# -> State# RealWorld -> State# RealWorld
forall d. Addr# -> Int# -> Word64# -> State# d -> State# d
Exts.writeWord64OffAddr# Addr#
addr Int#
14# Word64#
w14 State# RealWorld
s14 of { State# RealWorld
s15 ->
case Addr# -> Int# -> Word64# -> State# RealWorld -> State# RealWorld
forall d. Addr# -> Int# -> Word64# -> State# d -> State# d
Exts.writeWord64OffAddr# Addr#
addr Int#
15# Word64#
w15 State# RealWorld
s15 of { State# RealWorld
s16 ->
(# State# RealWorld
s16, () #) }}}}}}}}}}}}}}}}
{-# INLINE poke_block #-}
update :: Ptr Word64 -> Ptr Word64 -> Block -> IO ()
update :: Ptr Word64 -> Ptr Word64 -> Block -> IO ()
update Ptr Word64
rp Ptr Word64
bp Block
block = do
Ptr Word64 -> Block -> IO ()
poke_block Ptr Word64
bp Block
block
Ptr Word64 -> Ptr Word64 -> IO ()
c_sha512_block Ptr Word64
rp Ptr Word64
bp
{-# INLINE update #-}
sha512_arm_available :: Bool
sha512_arm_available :: Bool
sha512_arm_available = IO Int -> Int
forall a. IO a -> a
unsafeDupablePerformIO IO Int
c_sha512_arm_available Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
/= Int
0
{-# NOINLINE sha512_arm_available #-}
hash
:: BS.ByteString
-> BS.ByteString
hash :: ByteString -> ByteString
hash ByteString
m = IO ByteString -> ByteString
forall a. IO a -> a
unsafeDupablePerformIO (IO ByteString -> ByteString) -> IO ByteString -> ByteString
forall a b. (a -> b) -> a -> b
$
Int -> (Ptr Word64 -> IO ByteString) -> IO ByteString
forall a b. Int -> (Ptr a -> IO b) -> IO b
allocaBytes Int
64 ((Ptr Word64 -> IO ByteString) -> IO ByteString)
-> (Ptr Word64 -> IO ByteString) -> IO ByteString
forall a b. (a -> b) -> a -> b
$ \Ptr Word64
rp ->
Int -> (Ptr Word64 -> IO ByteString) -> IO ByteString
forall a b. Int -> (Ptr a -> IO b) -> IO b
allocaBytes Int
128 ((Ptr Word64 -> IO ByteString) -> IO ByteString)
-> (Ptr Word64 -> IO ByteString) -> IO ByteString
forall a b. (a -> b) -> a -> b
$ \Ptr Word64
bp -> do
Ptr Word64 -> Registers -> IO ()
poke_registers Ptr Word64
rp (() -> Registers
iv ())
Ptr Word64 -> Ptr Word64 -> Word64 -> ByteString -> IO ()
_hash Ptr Word64
rp Ptr Word64
bp Word64
0 ByteString
m
let !rs :: Registers
rs = Ptr Word64 -> Registers
peek_registers Ptr Word64
rp
ByteString -> IO ByteString
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Registers -> ByteString
cat Registers
rs)
_hash
:: Ptr Word64
-> Ptr Word64
-> Word64
-> BS.ByteString
-> IO ()
_hash :: Ptr Word64 -> Ptr Word64 -> Word64 -> ByteString -> IO ()
_hash Ptr Word64
rp Ptr Word64
bp Word64
el m :: ByteString
m@(BI.PS ForeignPtr Word8
_ Int
_ Int
l) = do
Ptr Word64 -> Ptr Word64 -> ByteString -> IO ()
hash_blocks Ptr Word64
rp Ptr Word64
bp ByteString
m
let !fin :: ByteString
fin@(BI.PS ForeignPtr Word8
_ Int
_ Int
ll) = Int -> ByteString -> ByteString
BU.unsafeDrop (Int
l Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
l Int -> Int -> Int
forall a. Integral a => a -> a -> a
`rem` Int
128) ByteString
m
!total :: Word64
total = Word64
el Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
+ Int -> Word64
forall a b. (Integral a, Num b) => a -> b
fi Int
l
if Int
ll Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
112
then do
let !ult :: Block
ult = ByteString -> Word64 -> Block
parse_pad1 ByteString
fin Word64
total
Ptr Word64 -> Ptr Word64 -> Block -> IO ()
update Ptr Word64
rp Ptr Word64
bp Block
ult
else do
let !(# Block
pen, Block
ult #) = ByteString -> Word64 -> (# Block, Block #)
parse_pad2 ByteString
fin Word64
total
Ptr Word64 -> Ptr Word64 -> Block -> IO ()
update Ptr Word64
rp Ptr Word64
bp Block
pen
Ptr Word64 -> Ptr Word64 -> Block -> IO ()
update Ptr Word64
rp Ptr Word64
bp Block
ult
{-# INLINABLE _hash #-}
hash_blocks
:: Ptr Word64
-> Ptr Word64
-> BS.ByteString
-> IO ()
hash_blocks :: Ptr Word64 -> Ptr Word64 -> ByteString -> IO ()
hash_blocks Ptr Word64
rp Ptr Word64
bp m :: ByteString
m@(BI.PS ForeignPtr Word8
_ Int
_ Int
l) = Int -> IO ()
loop Int
0 where
loop :: Int -> IO ()
loop !Int
j
| Int
j Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
128 Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
l = () -> IO ()
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
| Bool
otherwise = do
let !block :: Block
block = ByteString -> Int -> Block
parse ByteString
m Int
j
Ptr Word64 -> Ptr Word64 -> Block -> IO ()
update Ptr Word64
rp Ptr Word64
bp Block
block
Int -> IO ()
loop (Int
j Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
128)
{-# INLINE hash_blocks #-}
hmac :: BS.ByteString -> BS.ByteString -> BS.ByteString
hmac :: ByteString -> ByteString -> ByteString
hmac ByteString
k ByteString
m = IO ByteString -> ByteString
forall a. IO a -> a
unsafeDupablePerformIO (IO ByteString -> ByteString) -> IO ByteString -> ByteString
forall a b. (a -> b) -> a -> b
$
Int -> (Ptr Word64 -> IO ByteString) -> IO ByteString
forall a b. Int -> (Ptr a -> IO b) -> IO b
allocaBytes Int
64 ((Ptr Word64 -> IO ByteString) -> IO ByteString)
-> (Ptr Word64 -> IO ByteString) -> IO ByteString
forall a b. (a -> b) -> a -> b
$ \Ptr Word64
rp ->
Int -> (Ptr Word64 -> IO ByteString) -> IO ByteString
forall a b. Int -> (Ptr a -> IO b) -> IO b
allocaBytes Int
128 ((Ptr Word64 -> IO ByteString) -> IO ByteString)
-> (Ptr Word64 -> IO ByteString) -> IO ByteString
forall a b. (a -> b) -> a -> b
$ \Ptr Word64
bp -> do
Ptr Word64 -> Ptr Word64 -> Block -> ByteString -> IO ()
_hmac Ptr Word64
rp Ptr Word64
bp (ByteString -> Block
prep_key ByteString
k) ByteString
m
ByteString -> IO ByteString
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Registers -> ByteString
cat (Ptr Word64 -> Registers
peek_registers Ptr Word64
rp))
prep_key :: BS.ByteString -> Block
prep_key :: ByteString -> Block
prep_key k :: ByteString
k@(BI.PS ForeignPtr Word8
_ Int
_ Int
l)
| Int
l Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
128 = ByteString -> Block
parse_key (ByteString -> ByteString
hash ByteString
k)
| Bool
otherwise = ByteString -> Block
parse_key ByteString
k
{-# INLINABLE prep_key #-}
_hmac
:: Ptr Word64
-> Ptr Word64
-> Block
-> BS.ByteString
-> IO ()
_hmac :: Ptr Word64 -> Ptr Word64 -> Block -> ByteString -> IO ()
_hmac Ptr Word64
rp Ptr Word64
bp Block
k ByteString
m = do
Ptr Word64 -> Registers -> IO ()
poke_registers Ptr Word64
rp (() -> Registers
iv ())
Ptr Word64 -> Ptr Word64 -> Block -> IO ()
update Ptr Word64
rp Ptr Word64
bp (Block -> Word64# -> Block
xor Block
k (Word# -> Word64#
Exts.wordToWord64# Word#
0x3636363636363636##))
Ptr Word64 -> Ptr Word64 -> Word64 -> ByteString -> IO ()
_hash Ptr Word64
rp Ptr Word64
bp Word64
128 ByteString
m
let !block :: Block
block = Registers -> Block
pad_registers_with_length (Ptr Word64 -> Registers
peek_registers Ptr Word64
rp)
Ptr Word64 -> Registers -> IO ()
poke_registers Ptr Word64
rp (() -> Registers
iv ())
Ptr Word64 -> Ptr Word64 -> Block -> IO ()
update Ptr Word64
rp Ptr Word64
bp (Block -> Word64# -> Block
xor Block
k (Word# -> Word64#
Exts.wordToWord64# Word#
0x5C5C5C5C5C5C5C5C##))
Ptr Word64 -> Ptr Word64 -> Block -> IO ()
update Ptr Word64
rp Ptr Word64
bp Block
block
{-# NOINLINE _hmac #-}
_hmac_rr
:: Ptr Word64
-> Ptr Word64
-> Registers
-> Registers
-> IO ()
_hmac_rr :: Ptr Word64 -> Ptr Word64 -> Registers -> Registers -> IO ()
_hmac_rr Ptr Word64
rp Ptr Word64
bp Registers
k Registers
m = do
let !key :: Block
key = Registers -> Block
pad_registers Registers
k
!block :: Block
block = Registers -> Block
pad_registers_with_length Registers
m
Ptr Word64 -> Ptr Word64 -> Block -> Block -> IO ()
_hmac_bb Ptr Word64
rp Ptr Word64
bp Block
key Block
block
{-# INLINABLE _hmac_rr #-}
_hmac_bb
:: Ptr Word64
-> Ptr Word64
-> Block
-> Block
-> IO ()
_hmac_bb :: Ptr Word64 -> Ptr Word64 -> Block -> Block -> IO ()
_hmac_bb Ptr Word64
rp Ptr Word64
bp Block
k Block
m = do
Ptr Word64 -> Registers -> IO ()
poke_registers Ptr Word64
rp (() -> Registers
iv ())
Ptr Word64 -> Ptr Word64 -> Block -> IO ()
update Ptr Word64
rp Ptr Word64
bp (Block -> Word64# -> Block
xor Block
k (Word# -> Word64#
Exts.wordToWord64# Word#
0x3636363636363636##))
Ptr Word64 -> Ptr Word64 -> Block -> IO ()
update Ptr Word64
rp Ptr Word64
bp Block
m
let !inner :: Block
inner = Registers -> Block
pad_registers_with_length (Ptr Word64 -> Registers
peek_registers Ptr Word64
rp)
Ptr Word64 -> Registers -> IO ()
poke_registers Ptr Word64
rp (() -> Registers
iv ())
Ptr Word64 -> Ptr Word64 -> Block -> IO ()
update Ptr Word64
rp Ptr Word64
bp (Block -> Word64# -> Block
xor Block
k (Word# -> Word64#
Exts.wordToWord64# Word#
0x5C5C5C5C5C5C5C5C##))
Ptr Word64 -> Ptr Word64 -> Block -> IO ()
update Ptr Word64
rp Ptr Word64
bp Block
inner
{-# INLINABLE _hmac_bb #-}
_hmac_rsb
:: Ptr Word64
-> Ptr Word64
-> Registers
-> Registers
-> Word8
-> BS.ByteString
-> IO ()
_hmac_rsb :: Ptr Word64
-> Ptr Word64
-> Registers
-> Registers
-> Word8
-> ByteString
-> IO ()
_hmac_rsb Ptr Word64
rp Ptr Word64
bp Registers
k Registers
v Word8
sep ByteString
dat = do
Ptr Word64 -> Registers -> IO ()
poke_registers Ptr Word64
rp (() -> Registers
iv ())
let !key :: Block
key = Registers -> Block
pad_registers Registers
k
Ptr Word64 -> Ptr Word64 -> Block -> IO ()
update Ptr Word64
rp Ptr Word64
bp (Block -> Word64# -> Block
xor Block
key (Word# -> Word64#
Exts.wordToWord64# Word#
0x3636363636363636##))
Ptr Word64
-> Ptr Word64
-> Word64
-> Registers
-> Word8
-> ByteString
-> IO ()
_hash_vsb Ptr Word64
rp Ptr Word64
bp Word64
128 Registers
v Word8
sep ByteString
dat
let !inner :: Block
inner = Registers -> Block
pad_registers_with_length (Ptr Word64 -> Registers
peek_registers Ptr Word64
rp)
Ptr Word64 -> Registers -> IO ()
poke_registers Ptr Word64
rp (() -> Registers
iv ())
Ptr Word64 -> Ptr Word64 -> Block -> IO ()
update Ptr Word64
rp Ptr Word64
bp (Block -> Word64# -> Block
xor Block
key (Word# -> Word64#
Exts.wordToWord64# Word#
0x5C5C5C5C5C5C5C5C##))
Ptr Word64 -> Ptr Word64 -> Block -> IO ()
update Ptr Word64
rp Ptr Word64
bp Block
inner
{-# INLINABLE _hmac_rsb #-}
_hash_vsb
:: Ptr Word64
-> Ptr Word64
-> Word64
-> Registers
-> Word8
-> BS.ByteString
-> IO ()
_hash_vsb :: Ptr Word64
-> Ptr Word64
-> Word64
-> Registers
-> Word8
-> ByteString
-> IO ()
_hash_vsb Ptr Word64
rp Ptr Word64
bp Word64
el Registers
v Word8
sep dat :: ByteString
dat@(BI.PS ForeignPtr Word8
_ Int
_ Int
l)
| Int
l Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
63 = do
let !b0 :: Block
b0 = Registers -> Word8 -> ByteString -> Block
parse_vsb Registers
v Word8
sep ByteString
dat
Ptr Word64 -> Ptr Word64 -> Block -> IO ()
update Ptr Word64
rp Ptr Word64
bp Block
b0
let !rest :: ByteString
rest = Int -> ByteString -> ByteString
BU.unsafeDrop Int
63 ByteString
dat
!restLen :: Int
restLen = Int
l Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
63
Ptr Word64 -> Ptr Word64 -> ByteString -> IO ()
hash_blocks Ptr Word64
rp Ptr Word64
bp ByteString
rest
let !finLen :: Int
finLen = Int
restLen Int -> Int -> Int
forall a. Integral a => a -> a -> a
`rem` Int
128
!fin :: ByteString
fin = Int -> ByteString -> ByteString
BU.unsafeDrop (Int
restLen Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
finLen) ByteString
rest
!total :: Word64
total = Word64
el Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
+ Word64
65 Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
+ Int -> Word64
forall a b. (Integral a, Num b) => a -> b
fi Int
l
if Int
finLen Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
112
then Ptr Word64 -> Ptr Word64 -> Block -> IO ()
update Ptr Word64
rp Ptr Word64
bp (ByteString -> Word64 -> Block
parse_pad1 ByteString
fin Word64
total)
else do
let !(# Block
pen, Block
ult #) = ByteString -> Word64 -> (# Block, Block #)
parse_pad2 ByteString
fin Word64
total
Ptr Word64 -> Ptr Word64 -> Block -> IO ()
update Ptr Word64
rp Ptr Word64
bp Block
pen
Ptr Word64 -> Ptr Word64 -> Block -> IO ()
update Ptr Word64
rp Ptr Word64
bp Block
ult
| Bool
otherwise = do
let !total :: Word64
total = Word64
el Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
+ Word64
65 Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
+ Int -> Word64
forall a b. (Integral a, Num b) => a -> b
fi Int
l
if Int
65 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
l Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
112
then Ptr Word64 -> Ptr Word64 -> Block -> IO ()
update Ptr Word64
rp Ptr Word64
bp (Registers -> Word8 -> ByteString -> Word64 -> Block
parse_pad1_vsb Registers
v Word8
sep ByteString
dat Word64
total)
else do
let !(# Block
pen, Block
ult #) = Registers -> Word8 -> ByteString -> Word64 -> (# Block, Block #)
parse_pad2_vsb Registers
v Word8
sep ByteString
dat Word64
total
Ptr Word64 -> Ptr Word64 -> Block -> IO ()
update Ptr Word64
rp Ptr Word64
bp Block
pen
Ptr Word64 -> Ptr Word64 -> Block -> IO ()
update Ptr Word64
rp Ptr Word64
bp Block
ult
{-# INLINABLE _hash_vsb #-}