diff --git a/src/Tahoe/CHK/Encrypt.hs b/src/Tahoe/CHK/Encrypt.hs
index bb8374288e679dc312db3e54d796b091858640ee..ce76a7db0a45269d4d132e691bb335b4e8e48c16 100644
--- a/src/Tahoe/CHK/Encrypt.hs
+++ b/src/Tahoe/CHK/Encrypt.hs
@@ -1,7 +1,10 @@
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeApplications #-}
+
 -- | Support the encryption requirements of CHK.
 module Tahoe.CHK.Encrypt (encrypt, encryptLazy, decrypt, decryptLazy) where
 
-import Crypto.Cipher.Types (BlockCipher (ctrCombine), ivAdd, nullIV)
+import Crypto.Cipher.Types (BlockCipher (blockSize, ctrCombine), ivAdd, nullIV)
 import Data.ByteArray (ByteArray)
 import qualified Data.ByteString.Lazy as LBS
 import Data.List (unfoldr)
@@ -18,19 +21,23 @@ encrypt :: (BlockCipher cipher, ByteArray ba) => cipher -> ba -> ba
 encrypt key = ctrCombine key nullIV
 
 -- | Like encrypt but operate on lazy bytestrings.
-encryptLazy :: BlockCipher cipher => cipher -> LBS.ByteString -> LBS.ByteString
+encryptLazy :: forall cipher. BlockCipher cipher => cipher -> LBS.ByteString -> LBS.ByteString
 encryptLazy cipher lbs = LBS.concat . (LBS.fromStrict <$>) $ zipWith (ctrCombine cipher) ivs blocks
   where
     -- The underlying encryption function works on strict bytes.  Here's the
-    -- number of bytes to feed to it (that is, to make strict) at a time.
-    workingBlockSize :: Int
-    workingBlockSize = 1024 * 64
+    -- number of *blocks* to feed to it (that is, to make strict) at a time.
+    -- This value here is a magic number that is meant to represent a good
+    -- compromise between performance and number of bytes forced at one time.
+    workingBlocks = 1024 * 16
+
+    -- The size of a block is determined by the cipher.
+    workingBytes = workingBlocks * blockSize @cipher undefined
 
-    ivs = iterate (`ivAdd` (workingBlockSize `div` 16)) nullIV
+    ivs = iterate (`ivAdd` workingBlocks) nullIV
     blocks = LBS.toStrict <$> unfoldr takeChunk lbs
 
     takeChunk "" = Nothing
-    takeChunk xs = Just . LBS.splitAt (fromIntegral workingBlockSize) $ xs
+    takeChunk xs = Just . LBS.splitAt (fromIntegral workingBytes) $ xs
 
 -- | AES128-CTR decrypt a byte string in the manner used by CHK.
 decrypt :: (BlockCipher cipher, ByteArray ba) => cipher -> ba -> ba