{-# LANGUAGE OverloadedStrings #-}
module Botan.Low.Hash (
Hash(..)
, HashName
, HashDigest
, withHash
, hashInit
, hashDestroy
, hashName
, hashBlockSize
, hashOutputLength
, hashCopyState
, hashUpdate
, hashFinal
, hashUpdateFinalize
, hashUpdateFinalizeClear
, hashClear
, pattern BLAKE2b
, blake2b
, pattern Keccak1600
, keccak1600
, pattern GOST_34_11
, pattern MD4
, pattern MD5
, pattern RIPEMD160
, pattern SHA1
, pattern SHA224
, pattern SHA256
, pattern SHA384
, pattern SHA512
, pattern SHA512_256
, pattern SHA3
, sha3
, pattern SHAKE128
, shake128
, pattern SHAKE256
, shake256
, pattern SM3
, pattern Skein512
, skein512
, pattern Streebog256
, pattern Streebog512
, pattern Whirlpool
, pattern Parallel
, pattern Comb4P
, pattern Adler32
, pattern CRC24
, pattern CRC32
, cryptohashes
, checksums
, allHashes
) where
import Botan.Bindings.Hash
import Botan.Low.Error.Internal
import Botan.Low.Internal.ByteString
import Botan.Low.Internal.String
import Botan.Low.Make
import Botan.Low.Remake
import Data.ByteString (ByteString)
import Foreign.C.Types
import Foreign.ForeignPtr
import Foreign.Ptr
newtype Hash = MkHash { Hash -> ForeignPtr BotanHashStruct
foreignPtr :: ForeignPtr BotanHashStruct }
withHash :: Hash -> (BotanHash -> IO a) -> IO a
hashDestroy :: Hash -> IO ()
createHash :: (Ptr BotanHash -> IO CInt) -> IO Hash
(Hash -> (BotanHash -> IO a) -> IO a
withHash, Hash -> IO ()
hashDestroy, (Ptr BotanHash -> IO CInt) -> IO Hash
createHash)
= (Ptr BotanHashStruct -> BotanHash)
-> (BotanHash -> Ptr BotanHashStruct)
-> (ForeignPtr BotanHashStruct -> Hash)
-> (Hash -> ForeignPtr BotanHashStruct)
-> FinalizerPtr BotanHashStruct
-> (Hash -> (BotanHash -> IO a) -> IO a, Hash -> IO (),
(Ptr BotanHash -> IO CInt) -> IO Hash)
forall botan struct object a.
Storable botan =>
(Ptr struct -> botan)
-> (botan -> Ptr struct)
-> (ForeignPtr struct -> object)
-> (object -> ForeignPtr struct)
-> FinalizerPtr struct
-> (object -> (botan -> IO a) -> IO a, object -> IO (),
(Ptr botan -> IO CInt) -> IO object)
mkBindings
Ptr BotanHashStruct -> BotanHash
MkBotanHash (.ptr)
ForeignPtr BotanHashStruct -> Hash
MkHash (.foreignPtr)
FinalizerPtr BotanHashStruct
botan_hash_destroy
type HashName = ByteString
pattern BLAKE2b
, Keccak1600
, GOST_34_11
, MD4
, MD5
, RIPEMD160
, SHA1
, SHA224
, SHA256
, SHA384
, SHA512
, SHA512_256
, SHA3
, SHAKE128
, SHAKE256
, SM3
, Skein512
, Streebog256
, Streebog512
, Whirlpool
, Parallel
, Comb4P
, Adler32
, CRC24
, CRC32
:: HashName
pattern $bBLAKE2b :: HashName
$mBLAKE2b :: forall {r}. HashName -> ((# #) -> r) -> ((# #) -> r) -> r
BLAKE2b = BOTAN_HASH_BLAKE2B
blake2b :: (Ord a, Num a, Show a) => a -> HashName
blake2b :: forall a. (Ord a, Num a, Show a) => a -> HashName
blake2b a
sz | a
sz a -> a -> Bool
forall a. Ord a => a -> a -> Bool
<= a
512 = HashName
BLAKE2b HashName -> HashName -> HashName
forall a. (IsString a, Semigroup a) => a -> a -> a
/$ a -> HashName
forall a. Show a => a -> HashName
showBytes a
sz
blake2b a
_ = [Char] -> HashName
forall a. HasCallStack => [Char] -> a
error [Char]
"Invalid BLAKE2b variant"
pattern $bKeccak1600 :: HashName
$mKeccak1600 :: forall {r}. HashName -> ((# #) -> r) -> ((# #) -> r) -> r
Keccak1600 = BOTAN_HASH_KECCAK_1600
keccak1600 :: (Eq a, Num a, Show a) => a -> HashName
keccak1600 :: forall a. (Eq a, Num a, Show a) => a -> HashName
keccak1600 a
n | a
n a -> [a] -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [a
224, a
256, a
384, a
512] = HashName
Keccak1600 HashName -> HashName -> HashName
forall a. (IsString a, Semigroup a) => a -> a -> a
/$ a -> HashName
forall a. Show a => a -> HashName
showBytes a
n
keccak1600 a
_ = [Char] -> HashName
forall a. HasCallStack => [Char] -> a
error [Char]
"Invalid Keccak-1600 variant"
pattern $bGOST_34_11 :: HashName
$mGOST_34_11 :: forall {r}. HashName -> ((# #) -> r) -> ((# #) -> r) -> r
GOST_34_11 = BOTAN_HASH_GOST_34_11
pattern $bMD4 :: HashName
$mMD4 :: forall {r}. HashName -> ((# #) -> r) -> ((# #) -> r) -> r
MD4 = BOTAN_HASH_MD4
pattern $bMD5 :: HashName
$mMD5 :: forall {r}. HashName -> ((# #) -> r) -> ((# #) -> r) -> r
MD5 = BOTAN_HASH_MD5
pattern $bRIPEMD160 :: HashName
$mRIPEMD160 :: forall {r}. HashName -> ((# #) -> r) -> ((# #) -> r) -> r
RIPEMD160 = BOTAN_HASH_RIPEMD_160
pattern $bSHA1 :: HashName
$mSHA1 :: forall {r}. HashName -> ((# #) -> r) -> ((# #) -> r) -> r
SHA1 = BOTAN_HASH_SHA1
pattern $bSHA224 :: HashName
$mSHA224 :: forall {r}. HashName -> ((# #) -> r) -> ((# #) -> r) -> r
SHA224 = BOTAN_HASH_SHA_224
pattern $bSHA256 :: HashName
$mSHA256 :: forall {r}. HashName -> ((# #) -> r) -> ((# #) -> r) -> r
SHA256 = BOTAN_HASH_SHA_256
pattern $bSHA384 :: HashName
$mSHA384 :: forall {r}. HashName -> ((# #) -> r) -> ((# #) -> r) -> r
SHA384 = BOTAN_HASH_SHA_384
pattern $bSHA512 :: HashName
$mSHA512 :: forall {r}. HashName -> ((# #) -> r) -> ((# #) -> r) -> r
SHA512 = BOTAN_HASH_SHA_512
pattern $bSHA512_256 :: HashName
$mSHA512_256 :: forall {r}. HashName -> ((# #) -> r) -> ((# #) -> r) -> r
SHA512_256 = BOTAN_HASH_SHA_512_256
pattern $bSHA3 :: HashName
$mSHA3 :: forall {r}. HashName -> ((# #) -> r) -> ((# #) -> r) -> r
SHA3 = BOTAN_HASH_SHA_3
sha3 :: (Eq a, Num a, Show a) => a -> HashName
sha3 :: forall a. (Eq a, Num a, Show a) => a -> HashName
sha3 a
n | a
n a -> [a] -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [a
224, a
256, a
384, a
512] = HashName
SHA3 HashName -> HashName -> HashName
forall a. (IsString a, Semigroup a) => a -> a -> a
/$ a -> HashName
forall a. Show a => a -> HashName
showBytes a
n
sha3 a
_ = [Char] -> HashName
forall a. HasCallStack => [Char] -> a
error [Char]
"Invalid SHA-3 variant"
pattern $bSHAKE128 :: HashName
$mSHAKE128 :: forall {r}. HashName -> ((# #) -> r) -> ((# #) -> r) -> r
SHAKE128 = BOTAN_HASH_SHAKE_128
shake128 :: Show a => a -> HashName
shake128 :: forall a. Show a => a -> HashName
shake128 a
sz = HashName
SHAKE128 HashName -> HashName -> HashName
forall a. (IsString a, Semigroup a) => a -> a -> a
/$ a -> HashName
forall a. Show a => a -> HashName
showBytes a
sz
pattern $bSHAKE256 :: HashName
$mSHAKE256 :: forall {r}. HashName -> ((# #) -> r) -> ((# #) -> r) -> r
SHAKE256 = BOTAN_HASH_SHAKE_256
shake256 :: Show a => a -> HashName
shake256 :: forall a. Show a => a -> HashName
shake256 a
sz = HashName
SHAKE256 HashName -> HashName -> HashName
forall a. (IsString a, Semigroup a) => a -> a -> a
/$ a -> HashName
forall a. Show a => a -> HashName
showBytes a
sz
pattern $bSM3 :: HashName
$mSM3 :: forall {r}. HashName -> ((# #) -> r) -> ((# #) -> r) -> r
SM3 = BOTAN_HASH_SM3
pattern $bSkein512 :: HashName
$mSkein512 :: forall {r}. HashName -> ((# #) -> r) -> ((# #) -> r) -> r
Skein512 = BOTAN_HASH_SKEIN_512
skein512 :: Show a => a -> HashName -> HashName
skein512 :: forall a. Show a => a -> HashName -> HashName
skein512 a
sz HashName
salt = HashName
Skein512 HashName -> HashName -> HashName
forall a. (IsString a, Semigroup a) => a -> a -> a
/$ a -> HashName
forall a. Show a => a -> HashName
showBytes a
sz HashName -> HashName -> HashName
forall a. Semigroup a => a -> a -> a
<> HashName
"," HashName -> HashName -> HashName
forall a. Semigroup a => a -> a -> a
<> HashName
salt
pattern $bStreebog256 :: HashName
$mStreebog256 :: forall {r}. HashName -> ((# #) -> r) -> ((# #) -> r) -> r
Streebog256 = BOTAN_HASH_STREEBOG_256
pattern $bStreebog512 :: HashName
$mStreebog512 :: forall {r}. HashName -> ((# #) -> r) -> ((# #) -> r) -> r
Streebog512 = BOTAN_HASH_STREEBOG_512
pattern $bWhirlpool :: HashName
$mWhirlpool :: forall {r}. HashName -> ((# #) -> r) -> ((# #) -> r) -> r
Whirlpool = BOTAN_HASH_WHIRLPOOL
pattern $bParallel :: HashName
$mParallel :: forall {r}. HashName -> ((# #) -> r) -> ((# #) -> r) -> r
Parallel = BOTAN_HASH_STRAT_PARALLEL
pattern $bComb4P :: HashName
$mComb4P :: forall {r}. HashName -> ((# #) -> r) -> ((# #) -> r) -> r
Comb4P = BOTAN_HASH_STRAT_COMB4P
pattern $bAdler32 :: HashName
$mAdler32 :: forall {r}. HashName -> ((# #) -> r) -> ((# #) -> r) -> r
Adler32 = BOTAN_CHECKSUM_ADLER32
pattern $bCRC24 :: HashName
$mCRC24 :: forall {r}. HashName -> ((# #) -> r) -> ((# #) -> r) -> r
CRC24 = BOTAN_CHECKSUM_CRC24
pattern $bCRC32 :: HashName
$mCRC32 :: forall {r}. HashName -> ((# #) -> r) -> ((# #) -> r) -> r
CRC32 = BOTAN_CHECKSUM_CRC32
cryptohashes :: [HashName]
cryptohashes :: [HashName]
cryptohashes =
[ HashName
BLAKE2b
, HashName
GOST_34_11
, HashName
Keccak1600
, HashName
MD4
, HashName
MD5
, HashName
RIPEMD160
, HashName
SHA1
, HashName
SHA224
, HashName
SHA256
, HashName
SHA384
, HashName
SHA512
, HashName
SHA512_256
, HashName
SHA3
, forall a. Show a => a -> HashName
shake128 @Int Int
128
, forall a. Show a => a -> HashName
shake256 @Int Int
128
, HashName
SM3
, HashName
Skein512
, HashName
Streebog256
, HashName
Streebog512
, HashName
Whirlpool
]
checksums :: [HashName]
checksums :: [HashName]
checksums =
[ HashName
Adler32
, HashName
CRC24
, HashName
CRC32
]
allHashes :: [HashName]
allHashes :: [HashName]
allHashes = [HashName]
cryptohashes [HashName] -> [HashName] -> [HashName]
forall a. [a] -> [a] -> [a]
++ [HashName]
checksums
type HashDigest = ByteString
hashInit
:: HashName
-> IO Hash
hashInit :: HashName -> IO Hash
hashInit = ((Ptr BotanHash -> IO CInt) -> IO Hash)
-> (Ptr BotanHash -> ConstPtr CChar -> IO CInt)
-> HashName
-> IO Hash
forall botan object.
((Ptr botan -> IO CInt) -> IO object)
-> (Ptr botan -> ConstPtr CChar -> IO CInt)
-> HashName
-> IO object
mkCreateObjectCString (Ptr BotanHash -> IO CInt) -> IO Hash
createHash (\ Ptr BotanHash
out ConstPtr CChar
name -> Ptr BotanHash -> ConstPtr CChar -> Word32 -> IO CInt
botan_hash_init Ptr BotanHash
out ConstPtr CChar
name Word32
0)
hashName
:: Hash
-> IO HashDigest
hashName :: Hash -> IO HashName
hashName = WithPtr Hash BotanHash
-> GetCString BotanHash CChar -> Hash -> IO HashName
forall typ ptr byte.
WithPtr typ ptr -> GetCString ptr byte -> typ -> IO HashName
mkGetCString Hash -> (BotanHash -> IO a) -> IO a
WithPtr Hash BotanHash
withHash GetCString BotanHash CChar
botan_hash_name
hashCopyState
:: Hash
-> IO Hash
hashCopyState :: Hash -> IO Hash
hashCopyState Hash
source = Hash -> (BotanHash -> IO Hash) -> IO Hash
WithPtr Hash BotanHash
withHash Hash
source ((BotanHash -> IO Hash) -> IO Hash)
-> (BotanHash -> IO Hash) -> IO Hash
forall a b. (a -> b) -> a -> b
$ \ BotanHash
sourcePtr -> do
(Ptr BotanHash -> IO CInt) -> IO Hash
createHash ((Ptr BotanHash -> IO CInt) -> IO Hash)
-> (Ptr BotanHash -> IO CInt) -> IO Hash
forall a b. (a -> b) -> a -> b
$ \ Ptr BotanHash
dest -> Ptr BotanHash -> BotanHash -> IO CInt
botan_hash_copy_state Ptr BotanHash
dest BotanHash
sourcePtr
hashClear
:: Hash
-> IO ()
hashClear :: Hash -> IO ()
hashClear = WithPtr Hash BotanHash -> (BotanHash -> IO CInt) -> Hash -> IO ()
forall typ ptr. WithPtr typ ptr -> Action ptr -> typ -> IO ()
mkAction Hash -> (BotanHash -> IO a) -> IO a
WithPtr Hash BotanHash
withHash BotanHash -> IO CInt
botan_hash_clear
hashBlockSize
:: Hash
-> IO Int
hashBlockSize :: Hash -> IO Int
hashBlockSize = WithPtr Hash BotanHash -> GetSize BotanHash -> Hash -> IO Int
forall typ ptr. WithPtr typ ptr -> GetSize ptr -> typ -> IO Int
mkGetSize Hash -> (BotanHash -> IO a) -> IO a
WithPtr Hash BotanHash
withHash GetSize BotanHash
botan_hash_block_size
hashOutputLength
:: Hash
-> IO Int
hashOutputLength :: Hash -> IO Int
hashOutputLength = WithPtr Hash BotanHash -> GetSize BotanHash -> Hash -> IO Int
forall typ ptr. WithPtr typ ptr -> GetSize ptr -> typ -> IO Int
mkGetSize Hash -> (BotanHash -> IO a) -> IO a
WithPtr Hash BotanHash
withHash GetSize BotanHash
botan_hash_output_length
hashUpdate
:: Hash
-> ByteString
-> IO ()
hashUpdate :: Hash -> HashName -> IO ()
hashUpdate = WithPtr Hash BotanHash
-> (BotanHash -> ConstPtr Word8 -> CSize -> IO CInt)
-> Hash
-> HashName
-> IO ()
forall object botan.
(forall a. object -> (botan -> IO a) -> IO a)
-> (botan -> ConstPtr Word8 -> CSize -> IO CInt)
-> object
-> HashName
-> IO ()
mkWithObjectSetterCBytesLen Hash -> (BotanHash -> IO a) -> IO a
WithPtr Hash BotanHash
withHash BotanHash -> ConstPtr Word8 -> CSize -> IO CInt
botan_hash_update
hashFinal
:: Hash
-> IO HashDigest
hashFinal :: Hash -> IO HashName
hashFinal Hash
hash = Hash -> (BotanHash -> IO HashName) -> IO HashName
WithPtr Hash BotanHash
withHash Hash
hash ((BotanHash -> IO HashName) -> IO HashName)
-> (BotanHash -> IO HashName) -> IO HashName
forall a b. (a -> b) -> a -> b
$ \ BotanHash
hashPtr -> do
Int
sz <- Hash -> IO Int
hashOutputLength Hash
hash
Int -> (Ptr Word8 -> IO ()) -> IO HashName
forall byte. Int -> (Ptr byte -> IO ()) -> IO HashName
allocBytes Int
sz ((Ptr Word8 -> IO ()) -> IO HashName)
-> (Ptr Word8 -> IO ()) -> IO HashName
forall a b. (a -> b) -> a -> b
$ \ Ptr Word8
digestPtr -> do
HasCallStack => IO CInt -> IO ()
IO CInt -> IO ()
throwBotanIfNegative_ (IO CInt -> IO ()) -> IO CInt -> IO ()
forall a b. (a -> b) -> a -> b
$ BotanHash -> Ptr Word8 -> IO CInt
botan_hash_final BotanHash
hashPtr Ptr Word8
digestPtr
hashUpdateFinalize :: Hash -> ByteString -> IO HashDigest
hashUpdateFinalize :: Hash -> HashName -> IO HashName
hashUpdateFinalize Hash
ctx HashName
bytes = do
Hash -> HashName -> IO ()
hashUpdate Hash
ctx HashName
bytes
Hash -> IO HashName
hashFinal Hash
ctx
hashUpdateFinalizeClear :: Hash -> ByteString -> IO HashDigest
hashUpdateFinalizeClear :: Hash -> HashName -> IO HashName
hashUpdateFinalizeClear Hash
ctx HashName
bytes = do
HashName
dg <- Hash -> HashName -> IO HashName
hashUpdateFinalize Hash
ctx HashName
bytes
Hash -> IO ()
hashClear Hash
ctx
HashName -> IO HashName
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return HashName
dg