sha512

Pure Haskell SHA-512, HMAC-SHA512 (docs.ppad.tech/sha512).
git clone git://git.ppad.tech/sha512.git
Log | Files | Refs | README | LICENSE

SHA512.hs (3532B)


      1 {-# OPTIONS_HADDOCK prune #-}
      2 
      3 -- |
      4 -- Module: Crypto.Hash.SHA512
      5 -- Copyright: (c) 2024 Jared Tobin
      6 -- License: MIT
      7 -- Maintainer: Jared Tobin <jared@ppad.tech>
      8 --
      9 -- SHA-512 and HMAC-SHA512 implementations for
     10 -- strict and lazy ByteStrings, as specified by RFC's
     11 -- [6234](https://datatracker.ietf.org/doc/html/rfc6234) and
     12 -- [2104](https://datatracker.ietf.org/doc/html/rfc2104).
     13 --
     14 -- The 'hash' and 'hmac' functions will use primitive instructions from
     15 -- the ARM or x86 SHA512 extensions via FFI if they're available, and
     16 -- will otherwise use a pure Haskell implementation.
     17 
     18 module Crypto.Hash.SHA512 (
     19   -- * SHA-512 message digest functions
     20     hash
     21   , Lazy.hash_lazy
     22 
     23   -- * SHA512-based MAC functions
     24   , MAC(..)
     25   , hmac
     26   , Lazy.hmac_lazy
     27 
     28   -- low-level specialized HMAC primitives
     29   , _hmac_rr
     30   , _hmac_rsb
     31   ) where
     32 
     33 import qualified Data.ByteString as BS
     34 import Data.Word (Word8, Word64)
     35 import Foreign.Ptr (Ptr)
     36 import qualified Crypto.Hash.SHA512.Native as Native
     37 import Crypto.Hash.SHA512.Internal (MAC(..), Registers)
     38 import qualified Crypto.Hash.SHA512.Lazy as Lazy
     39 import qualified Crypto.Hash.SHA512.Pure as Pure
     40 
     41 -- hash -----------------------------------------------------------------------
     42 
     43 -- | Compute a condensed representation of a strict bytestring via
     44 --   SHA-512.
     45 --
     46 --   The 512-bit output digest is returned as a strict bytestring.
     47 --
     48 --   >>> hash "strict bytestring input"
     49 --   "<strict 512-bit message digest>"
     50 hash :: BS.ByteString -> BS.ByteString
     51 hash m
     52   | Native.sha512_native_available = Native.hash m
     53   | otherwise = Pure.hash m
     54 {-# INLINABLE hash #-}
     55 
     56 -- hmac ----------------------------------------------------------------------
     57 
     58 -- | Produce a message authentication code for a strict bytestring,
     59 --   based on the provided (strict, bytestring) key, via SHA-512.
     60 --
     61 --   The 512-bit MAC is returned as a strict bytestring.
     62 --
     63 --   Per RFC 2104, the key /should/ be a minimum of 64 bytes long. Keys
     64 --   exceeding 128 bytes in length will first be hashed (via SHA-512).
     65 --
     66 --   >>> hmac "strict bytestring key" "strict bytestring input"
     67 --   "<strict 512-bit MAC>"
     68 hmac :: BS.ByteString -> BS.ByteString -> MAC
     69 hmac k m
     70   | Native.sha512_native_available = MAC (Native.hmac k m)
     71   | otherwise = MAC (Pure.hmac k m)
     72 {-# INLINABLE hmac #-}
     73 
     74 -- the following functions are useful when we want to avoid allocating certain
     75 -- components of the HMAC key and message on the heap.
     76 
     77 -- Computes hmac(k, v) when k and v are Registers.
     78 --
     79 -- The 64-byte result is written to the destination pointer.
     80 _hmac_rr
     81   :: Ptr Word64    -- ^ destination (8 Word64s)
     82   -> Ptr Word64    -- ^ scratch block buffer (16 Word64s)
     83   -> Registers     -- ^ key
     84   -> Registers     -- ^ message
     85   -> IO ()
     86 _hmac_rr rp bp k m
     87   | Native.sha512_native_available = Native._hmac_rr rp bp k m
     88   | otherwise = Pure._hmac_rr rp bp k m
     89 {-# INLINABLE _hmac_rr #-}
     90 
     91 -- Calculate hmac(k, m) where m is the concatenation of v (registers), a
     92 -- separator byte, and a ByteString. This avoids allocating 'v' on the
     93 -- heap.
     94 --
     95 -- The 64-byte result is written to the destination pointer.
     96 _hmac_rsb
     97   :: Ptr Word64    -- ^ destination pointer (8 x Word64)
     98   -> Ptr Word64    -- ^ scratch block pointer (16 x Word64)
     99   -> Registers     -- ^ k
    100   -> Registers     -- ^ v
    101   -> Word8         -- ^ separator byte
    102   -> BS.ByteString -- ^ data
    103   -> IO ()
    104 _hmac_rsb rp bp k v sep dat
    105   | Native.sha512_native_available = Native._hmac_rsb rp bp k v sep dat
    106   | otherwise = Pure._hmac_rsb rp bp k v sep dat
    107 {-# INLINABLE _hmac_rsb #-}