sha512

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

commit b7fff78e638b0b09f5c2b02650047641bea91918
parent c454a32a4a39b0e18601b8139a12ae895c9b631e
Author: Jared Tobin <jared@jtobin.io>
Date:   Sun,  6 Oct 2024 20:41:42 +0400

lib: hash long keys in hmac

Diffstat:
Mlib/Crypto/Hash/SHA512.hs | 34+++++++++++++++++++++++-----------
1 file changed, 23 insertions(+), 11 deletions(-)

diff --git a/lib/Crypto/Hash/SHA512.hs b/lib/Crypto/Hash/SHA512.hs @@ -500,29 +500,41 @@ hash_lazy bl = cat (go iv (pad_lazy bl)) where -- -- The 512-bit MAC is returned as a strict bytestring. -- +-- Per RFC 2104, the key /should/ be a minimum of 64 bytes long. Keys +-- exceeding 1024 bytes in length will first be hashed (via SHA-512). +-- -- >>> hmac "strict bytestring key" "strict bytestring input" -- "<strict 512-bit MAC>" hmac :: BS.ByteString -> BS.ByteString -> BS.ByteString hmac k = hmac_lazy k . BL.fromStrict +data KeyAndLen = KeyAndLen + {-# UNPACK #-} !BS.ByteString + {-# UNPACK #-} !Int + -- | Produce a message authentication code for a lazy bytestring, based -- on the provided (strict, bytestring) key, via SHA-512. -- -- The 512-bit MAC is returned as a strict bytestring. -- +-- Per RFC 2104, the key /should/ be a minimum of 64 bytes long. Keys +-- exceeding 1024 bytes in length will first be hashed (via SHA-512). +-- -- >>> hmac_lazy "strict bytestring key" "lazy bytestring input" -- "<strict 512-bit MAC>" hmac_lazy :: BS.ByteString -> BL.ByteString -> BS.ByteString -hmac_lazy k text - | lk > 128 = error "ppad-sha512: hmac key exceeds 128 bytes" - | otherwise = - let step1 = k <> BS.replicate (128 - lk) 0x00 - step2 = BS.map (B.xor 0x36) step1 - step3 = BL.fromStrict step2 <> text - step4 = hash_lazy step3 - step5 = BS.map (B.xor 0x5C) step1 - step6 = step5 <> step4 - in hash step6 +hmac_lazy mk text = + let step1 = k <> BS.replicate (128 - lk) 0x00 + step2 = BS.map (B.xor 0x36) step1 + step3 = BL.fromStrict step2 <> text + step4 = hash_lazy step3 + step5 = BS.map (B.xor 0x5C) step1 + step6 = step5 <> step4 + in hash step6 where - lk = fi (BS.length k) + !(KeyAndLen k lk) = + let l = BS.length mk + in if l > 128 + then KeyAndLen (hash mk) 64 + else KeyAndLen mk l