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 #-}