diff --git a/CHANGELOG b/CHANGELOG
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,5 +1,8 @@
 # Changelog
 
+- 0.2.2 (2025-01-07)
+  * Minor bytestring-handling optimisations.
+
 - 0.2.1 (2024-10-13)
   * Adds an INLINE pragma to an internal step function.
   * 'hmac' no longer calls 'hmac_lazy', which has no practical effect
diff --git a/lib/Crypto/Hash/SHA256.hs b/lib/Crypto/Hash/SHA256.hs
--- a/lib/Crypto/Hash/SHA256.hs
+++ b/lib/Crypto/Hash/SHA256.hs
@@ -79,14 +79,14 @@
 splitAt64 :: BL.ByteString -> SLPair
 splitAt64 = splitAt' (64 :: Int) where
   splitAt' _ BLI.Empty        = SLPair mempty BLI.Empty
-  splitAt' n (BLI.Chunk c cs) =
-    if    n < BS.length c
+  splitAt' n (BLI.Chunk c@(BI.PS _ _ l) cs) =
+    if    n < l
     then
       -- n < BS.length c, so unsafe_splitAt is safe
       let !(SSPair c0 c1) = unsafe_splitAt n c
       in  SLPair c0 (BLI.Chunk c1 cs)
     else
-      let SLPair cs' cs'' = splitAt' (n - BS.length c) cs
+      let SLPair cs' cs'' = splitAt' (n - l) cs
       in  SLPair (c <> cs') cs''
 
 -- variant of Data.ByteString.splitAt that behaves like an incremental
@@ -110,10 +110,8 @@
 
 -- RFC 6234 4.1 (strict)
 pad :: BS.ByteString -> BS.ByteString
-pad m = BL.toStrict . BSB.toLazyByteString $ padded where
-  l = fi (BS.length m)
+pad m@(BI.PS _ _ (fi -> l)) = BL.toStrict . BSB.toLazyByteString $ padded where
   padded = BSB.byteString m <> fill (sol l) (BSB.word8 0x80)
-
   fill j !acc
     | j == 0 = acc <> BSB.word64BE (l * 8)
     | otherwise = fill (pred j) (acc <> BSB.word8 0x00)
@@ -358,13 +356,16 @@
 -- register concatenation
 cat :: Registers -> BS.ByteString
 cat Registers {..} =
-    BL.toStrict
-    -- more efficient for small builder
-  . BE.toLazyByteStringWith (BE.safeStrategy 128 BE.smallChunkSize) mempty
-  $ mconcat [
-        BSB.word32BE h0, BSB.word32BE h1, BSB.word32BE h2, BSB.word32BE h3
-      , BSB.word32BE h4, BSB.word32BE h5, BSB.word32BE h6, BSB.word32BE h7
-      ]
+      BL.toStrict
+      -- more efficient for small builder
+    . BE.toLazyByteStringWith (BE.safeStrategy 128 BE.smallChunkSize) mempty
+    $     BSB.word64BE w64_0 <> BSB.word64BE w64_1
+       <> BSB.word64BE w64_2 <> BSB.word64BE w64_3
+  where
+    !w64_0 = fi h0 `B.unsafeShiftL` 32 .|. fi h1
+    !w64_1 = fi h2 `B.unsafeShiftL` 32 .|. fi h3
+    !w64_2 = fi h4 `B.unsafeShiftL` 32 .|. fi h5
+    !w64_3 = fi h6 `B.unsafeShiftL` 32 .|. fi h7
 
 -- | Compute a condensed representation of a strict bytestring via
 --   SHA-256.
@@ -439,7 +440,7 @@
   :: BS.ByteString -- ^ key
   -> BS.ByteString -- ^ text
   -> BS.ByteString
-hmac mk text =
+hmac mk@(BI.PS _ _ l) text =
     let step1 = k <> BS.replicate (64 - lk) 0x00
         step2 = BS.map (B.xor 0x36) step1
         step3 = step2 <> text
@@ -448,11 +449,9 @@
         step6 = step5 <> step4
     in  hash step6
   where
-    !(KeyAndLen k lk) =
-      let l = BS.length mk
-      in  if   l > 64
-          then KeyAndLen (hash mk) 32
-          else KeyAndLen mk l
+    !(KeyAndLen k lk)
+      | l > 64    = KeyAndLen (hash mk) 32
+      | otherwise = KeyAndLen mk l
 
 -- | Produce a message authentication code for a lazy bytestring, based
 --   on the provided (strict, bytestring) key, via SHA-256.
@@ -468,7 +467,7 @@
   :: BS.ByteString -- ^ key
   -> BL.ByteString -- ^ text
   -> BS.ByteString
-hmac_lazy mk text =
+hmac_lazy mk@(BI.PS _ _ l) text =
     let step1 = k <> BS.replicate (64 - lk) 0x00
         step2 = BS.map (B.xor 0x36) step1
         step3 = BL.fromStrict step2 <> text
@@ -477,9 +476,7 @@
         step6 = step5 <> step4
     in  hash step6
   where
-    !(KeyAndLen k lk) =
-      let l = BS.length mk
-      in  if   l > 64
-          then KeyAndLen (hash mk) 32
-          else KeyAndLen mk l
+    !(KeyAndLen k lk)
+      | l > 64    = KeyAndLen (hash mk) 32
+      | otherwise = KeyAndLen mk l
 
diff --git a/ppad-sha256.cabal b/ppad-sha256.cabal
--- a/ppad-sha256.cabal
+++ b/ppad-sha256.cabal
@@ -1,6 +1,6 @@
 cabal-version:      3.0
 name:               ppad-sha256
-version:            0.2.1
+version:            0.2.2
 synopsis:           The SHA-256 and HMAC-SHA256 algorithms
 license:            MIT
 license-file:       LICENSE
