diff --git a/changes.md b/changes.md
--- a/changes.md
+++ b/changes.md
@@ -1,3 +1,7 @@
+# 0.4.0.0
+    - Expose 'cipherBlockSize'
+    - Adjust 'Data.CryptoID.Poly' to allow for more dynamic padding
+
 # 0.3.0.0
     - Better exception type (does no longer leak private information)
     - 'Data.CryptoID.Poly' now supports padding the plaintext to a certain length before encryption
diff --git a/cryptoids.cabal b/cryptoids.cabal
--- a/cryptoids.cabal
+++ b/cryptoids.cabal
@@ -1,5 +1,5 @@
 name: cryptoids
-version: 0.3.0.0
+version: 0.4.0.0
 cabal-version: >=1.10
 build-type: Simple
 license: BSD3
diff --git a/src/Data/CryptoID/ByteString.hs b/src/Data/CryptoID/ByteString.hs
--- a/src/Data/CryptoID/ByteString.hs
+++ b/src/Data/CryptoID/ByteString.hs
@@ -20,6 +20,7 @@
   , decrypt
   , CryptoIDError(..)
   , CryptoCipher, CryptoHash
+  , cipherBlockSize
   ) where
 
 import Data.CryptoID
@@ -32,8 +33,6 @@
 import qualified Data.ByteString as ByteString
 import qualified Data.ByteString.Char8 as ByteString.Char
 
-import qualified Data.ByteString.Lazy as Lazy (ByteString)
-
 import Data.List (sortOn)
 import Data.Ord (Down(..))
 
@@ -71,6 +70,10 @@
 --
 -- Violation of this expectation causes runtime errors.
 type CryptoHash   = SHAKE128 64
+
+
+cipherBlockSize :: Int
+cipherBlockSize = blockSize (undefined :: CryptoCipher)
   
 
 -- | This newtype ensures only keys of the correct length can be created
@@ -209,4 +212,3 @@
   cipher <- cryptoFailable (cipherInit key :: CryptoFailable CryptoCipher)
   namespace <- namespace' (Proxy :: Proxy namespace)
   return $ cbcDecrypt cipher namespace ciphertext
-
diff --git a/src/Data/CryptoID/Poly.hs b/src/Data/CryptoID/Poly.hs
--- a/src/Data/CryptoID/Poly.hs
+++ b/src/Data/CryptoID/Poly.hs
@@ -54,16 +54,16 @@
            ( KnownSymbol namespace
            , MonadThrow m
            , Binary a
-           ) => Maybe Int -- ^ Ensure the resulting ciphertext is of this size (needs to be a multiple of the block size of 'CryptoCipher' in bytes, otherwise an exception will be thrown at runtime)
+           ) => (ByteString -> m (Maybe Int)) -- ^ Ensure the resulting ciphertext is of the provided length (needs to be a multiple of the block size of 'CryptoCipher' in bytes, otherwise an exception will be thrown at runtime). The computation has access to the serialized plaintext
         -> (ByteString -> m c)
         -> CryptoIDKey
         -> a
         -> m (CryptoID namespace c)
-encrypt pLength encode' key plaintext = do
-  cID <- ByteString.encrypt key <=< pad . Lazy.ByteString.toStrict $ encode plaintext
+encrypt pLength' encode' key plaintext = do
+  cID <- ByteString.encrypt key <=< (\str -> pad str =<< pLength' str) . Lazy.ByteString.toStrict $ encode plaintext
   _ciphertext encode' cID
   where
-    pad str
+    pad str pLength
       | Just l <- pLength
       , l' <= l           = return $ str <> ByteString.replicate (l - l') 0
       | Just _ <- pLength = throwM $ CiphertextConversionFailed str
