{-# LANGUAGE TypeApplications #-}
{-# OPTIONS_HADDOCK not-home #-}

-- | Implementation to be used when compiled with GHC
module Bitcoin.Hash.GHC
  ( hash160
  , hash256
  , ripemd160
  , sha256
  , hmacSHA512
  ) where

import qualified Crypto.Hash as Hash
import qualified Crypto.MAC.HMAC as HMAC
import qualified Data.ByteArray as BA
import qualified Data.ByteString as B

--------------------------------------------------------------------------------

-- | @'hash160' == 'ripemd160' . 'sha256'@
hash160
  :: B.ByteString  -- ^ Data to hash.
  -> B.ByteString  -- ^ 160-bit long digest.
{-# INLINE hash160 #-}
hash160 :: ByteString -> ByteString
hash160 = Digest RIPEMD160 -> ByteString
forall bin bout.
(ByteArrayAccess bin, ByteArray bout) =>
bin -> bout
BA.convert
        (Digest RIPEMD160 -> ByteString)
-> (ByteString -> Digest RIPEMD160) -> ByteString -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ByteArrayAccess (Digest SHA256), HashAlgorithm RIPEMD160) =>
Digest SHA256 -> Digest RIPEMD160
forall ba a.
(ByteArrayAccess ba, HashAlgorithm a) =>
ba -> Digest a
Hash.hash @(Hash.Digest Hash.SHA256) @Hash.RIPEMD160
        (Digest SHA256 -> Digest RIPEMD160)
-> (ByteString -> Digest SHA256) -> ByteString -> Digest RIPEMD160
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ByteArrayAccess ByteString, HashAlgorithm SHA256) =>
ByteString -> Digest SHA256
forall ba a.
(ByteArrayAccess ba, HashAlgorithm a) =>
ba -> Digest a
Hash.hash @B.ByteString @Hash.SHA256

--------------------------------------------------------------------------------

-- | @'hash256' == 'sha256' . 'sha256'@
hash256
  :: B.ByteString  -- ^ Data to hash.
  -> B.ByteString  -- ^ 256-bit long digest.
{-# INLINE hash256 #-}
hash256 :: ByteString -> ByteString
hash256 = Digest SHA256 -> ByteString
forall bin bout.
(ByteArrayAccess bin, ByteArray bout) =>
bin -> bout
BA.convert
        (Digest SHA256 -> ByteString)
-> (ByteString -> Digest SHA256) -> ByteString -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ByteArrayAccess (Digest SHA256), HashAlgorithm SHA256) =>
Digest SHA256 -> Digest SHA256
forall ba a.
(ByteArrayAccess ba, HashAlgorithm a) =>
ba -> Digest a
Hash.hash @(Hash.Digest Hash.SHA256) @Hash.SHA256
        (Digest SHA256 -> Digest SHA256)
-> (ByteString -> Digest SHA256) -> ByteString -> Digest SHA256
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ByteArrayAccess ByteString, HashAlgorithm SHA256) =>
ByteString -> Digest SHA256
forall ba a.
(ByteArrayAccess ba, HashAlgorithm a) =>
ba -> Digest a
Hash.hash @B.ByteString @Hash.SHA256

--------------------------------------------------------------------------------

ripemd160
  :: B.ByteString  -- ^ Data to hash.
  -> B.ByteString  -- ^ 20-byte long digest.
{-# INLINE ripemd160 #-}
ripemd160 :: ByteString -> ByteString
ripemd160 = Digest RIPEMD160 -> ByteString
forall bin bout.
(ByteArrayAccess bin, ByteArray bout) =>
bin -> bout
BA.convert
          (Digest RIPEMD160 -> ByteString)
-> (ByteString -> Digest RIPEMD160) -> ByteString -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ByteArrayAccess ByteString, HashAlgorithm RIPEMD160) =>
ByteString -> Digest RIPEMD160
forall ba a.
(ByteArrayAccess ba, HashAlgorithm a) =>
ba -> Digest a
Hash.hash @B.ByteString @Hash.RIPEMD160

--------------------------------------------------------------------------------

sha256
  :: B.ByteString  -- ^ Data to hash.
  -> B.ByteString  -- ^ 32-byte long digest.
{-# INLINE sha256 #-}
sha256 :: ByteString -> ByteString
sha256 = Digest SHA256 -> ByteString
forall bin bout.
(ByteArrayAccess bin, ByteArray bout) =>
bin -> bout
BA.convert
       (Digest SHA256 -> ByteString)
-> (ByteString -> Digest SHA256) -> ByteString -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ByteArrayAccess ByteString, HashAlgorithm SHA256) =>
ByteString -> Digest SHA256
forall ba a.
(ByteArrayAccess ba, HashAlgorithm a) =>
ba -> Digest a
Hash.hash @B.ByteString @Hash.SHA256

--------------------------------------------------------------------------------

hmacSHA512
  :: B.ByteString  -- ^ Key.
  -> B.ByteString  -- ^ Data to hash.
  -> B.ByteString  -- ^ 64-byte long digest.
{-# INLINE hmacSHA512 #-}
hmacSHA512 :: ByteString -> ByteString -> ByteString
hmacSHA512 k :: ByteString
k d :: ByteString
d = HMAC SHA512 -> ByteString
forall bin bout.
(ByteArrayAccess bin, ByteArray bout) =>
bin -> bout
BA.convert (ByteString -> ByteString -> HMAC SHA512
forall key message a.
(ByteArrayAccess key, ByteArrayAccess message, HashAlgorithm a) =>
key -> message -> HMAC a
HMAC.hmac ByteString
k ByteString
d :: HMAC.HMAC Hash.SHA512)