diff --git a/hw-prim.cabal b/hw-prim.cabal
--- a/hw-prim.cabal
+++ b/hw-prim.cabal
@@ -3,7 +3,7 @@
 -- see: https://github.com/sol/hpack
 
 name:           hw-prim
-version:        0.6.2.15
+version:        0.6.2.17
 synopsis:       Primitive functions and data types
 description:    Primitive functions and data types.
 category:       Data
diff --git a/src/HaskellWorks/Data/ByteString.hs b/src/HaskellWorks/Data/ByteString.hs
--- a/src/HaskellWorks/Data/ByteString.hs
+++ b/src/HaskellWorks/Data/ByteString.hs
@@ -1,12 +1,14 @@
 {-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE MultiWayIf        #-}
 
 module HaskellWorks.Data.ByteString
   ( chunkedBy
   , ToByteString(..)
   , ToByteStrings(..)
+  , rechunk
+  , rechunkPadded
   , resegment
   , resegmentPadded
-  , rechunk
   , hGetContentsChunkedBy
   ) where
 
@@ -104,61 +106,74 @@
 
 rechunk :: Int -> [BS.ByteString] -> [BS.ByteString]
 rechunk size = go
-  where go (bs:bss) = let bsLen = BS.length bs in
-          if bsLen > 0
-            then if bsLen < size
-              then case size - bsLen of
-                bsNeed -> case bss of
-                  (cs:css) -> case BS.length cs of
-                    csLen | csLen >  bsNeed -> (bs <> BS.take bsNeed cs ):go (BS.drop bsNeed cs:css)
-                    csLen | csLen == bsNeed -> (bs <> cs                ):go                    css
-                    _     | otherwise       ->                            go ((bs <> cs)       :css)
-                  [] -> [bs]
-              else if size == bsLen
-                then bs:go bss
-                else BS.take size bs:go (BS.drop size bs:bss)
-            else go bss
+  where go (bs:bss) = let bsLen = BS.length bs in if bsLen > 0
+          then if bsLen < size
+            then let bsNeed = size - bsLen in case bss of
+              (cs:css) -> case BS.length cs of
+                csLen | csLen >  bsNeed -> (bs <> BS.take bsNeed cs ):go (BS.drop bsNeed cs:css)
+                csLen | csLen == bsNeed -> (bs <> cs                ):go                    css
+                _                       ->                            go ((bs <> cs)       :css)
+              [] -> [bs]
+            else if size == bsLen
+              then bs:go bss
+              else BS.take size bs:go (BS.drop size bs:bss)
+          else go bss
         go [] = []
 
+rechunkPadded :: Int -> [BS.ByteString] -> [BS.ByteString]
+rechunkPadded size = go
+  where go (bs:bss) = let bsLen = BS.length bs in if bsLen > 0
+          then if bsLen < size
+            then let bsNeed = size - bsLen in case bss of
+              (cs:css) -> case BS.length cs of
+                csLen | csLen >  bsNeed -> (bs <> BS.take bsNeed cs ):go (BS.drop bsNeed cs:css)
+                csLen | csLen == bsNeed -> (bs <> cs                ):go                    css
+                _                       ->                            go ((bs <> cs)       :css)
+              [] -> [bs <> BS.replicate bsNeed 0]
+            else if size == bsLen
+              then bs:go bss
+              else BS.take size bs:go (BS.drop size bs:bss)
+          else go bss
+        go [] = []
+
 resegment :: Int -> [BS.ByteString] -> [BS.ByteString]
-resegment multiple = go
-  where go (bs:bss) = case BS.length bs of
-              bsLen -> if bsLen < multiple
-                then case multiple - bsLen of
-                  bsNeed -> case bss of
-                    (cs:css) -> case BS.length cs of
-                      csLen | csLen >  bsNeed -> (bs <> BS.take bsNeed cs ):go (BS.drop bsNeed cs:css)
-                      csLen | csLen == bsNeed -> (bs <> cs                ):go                    css
-                      _     | otherwise       ->                            go ((bs <> cs)       :css)
-                    [] -> [bs]
-                else case (bsLen `div` multiple) * multiple of
-                  bsCroppedLen -> if bsCroppedLen == bsLen
-                    then bs:go bss
-                    else BS.take bsCroppedLen bs:go (BS.drop bsCroppedLen bs:bss)
+resegment size = go
+  where go (bs:bss) = let bsLen = BS.length bs in if bsLen > 0
+          then if bsLen < size
+            then case bss of
+              (cs:css) -> let bsNeed = size - bsLen; csLen = BS.length cs in if
+                | csLen >  bsNeed -> (bs <> BS.take bsNeed cs ):go (BS.drop bsNeed cs:css)
+                | csLen == bsNeed -> (bs <> cs                ):go                    css
+                | otherwise       ->                            go ((bs <> cs)       :css)
+              [] -> [bs]
+            else let bsCroppedLen = (bsLen `div` size) * size in if bsCroppedLen == bsLen
+              then bs:go bss
+              else BS.take bsCroppedLen bs:go (BS.drop bsCroppedLen bs:bss)
+          else go bss
         go [] = []
 
 resegmentPadded :: Int -> [BS.ByteString] -> [BS.ByteString]
-resegmentPadded multiple = go
-  where go (bs:bss) = case BS.length bs of
-              bsLen -> if bsLen < multiple
-                then case multiple - bsLen of
-                  bsNeed -> case bss of
-                    (cs:css) -> case BS.length cs of
-                      csLen | csLen >  bsNeed -> (bs <> BS.take bsNeed cs ):go (BS.drop bsNeed cs:css)
-                      csLen | csLen == bsNeed -> (bs <> cs                ):go                    css
-                      _     | otherwise       ->                            go ((bs <> cs)       :css)
-                    [] -> [bs <> BS.replicate bsNeed 0]
-                else case (bsLen `div` multiple) * multiple of
-                  bsCroppedLen -> if bsCroppedLen == bsLen
-                    then bs:go bss
-                    else BS.take bsCroppedLen bs:go (BS.drop bsCroppedLen bs:bss)
+resegmentPadded size = go
+  where go (bs:bss) = let bsLen = BS.length bs in if bsLen > 0
+          then if bsLen < size
+            then let bsNeed = size - bsLen in case bss of
+              (cs:css) -> case BS.length cs of
+                csLen | csLen >  bsNeed -> (bs <> BS.take bsNeed cs ):go (BS.drop bsNeed cs:css)
+                csLen | csLen == bsNeed -> (bs <> cs                ):go                    css
+                _                       ->                            go ((bs <> cs)       :css)
+              [] -> [bs <> BS.replicate bsNeed 0]
+            else case (bsLen `div` size) * size of
+              bsCroppedLen -> if bsCroppedLen == bsLen
+                then bs:go bss
+                else BS.take bsCroppedLen bs:go (BS.drop bsCroppedLen bs:bss)
+          else go bss
         go [] = []
 
 hGetContentsChunkedBy :: Int -> IO.Handle -> IO [BS.ByteString]
 hGetContentsChunkedBy k h = lazyRead
   where lazyRead = IO.unsafeInterleaveIO loop
         loop = do
-            c <- BSI.createAndTrim k $ \p -> IO.hGetBuf h p k
-            if BS.null c
-              then IO.hClose h >> return []
-              else (c:) <$> lazyRead
+          c <- BSI.createAndTrim k $ \p -> IO.hGetBuf h p k
+          if BS.null c
+            then IO.hClose h >> return []
+            else (c:) <$> lazyRead
diff --git a/src/HaskellWorks/Data/ByteString/Lazy.hs b/src/HaskellWorks/Data/ByteString/Lazy.hs
--- a/src/HaskellWorks/Data/ByteString/Lazy.hs
+++ b/src/HaskellWorks/Data/ByteString/Lazy.hs
@@ -5,6 +5,8 @@
   ( ToLazyByteString(..)
   , resegment
   , resegmentPadded
+  , rechunk
+  , rechunkPadded
   , hGetContentsChunkedBy
   ) where
 
@@ -64,6 +66,12 @@
 
 resegmentPadded :: Int -> LBS.ByteString -> LBS.ByteString
 resegmentPadded multiple = LBS.fromChunks . BS.resegmentPadded multiple . LBS.toChunks
+
+rechunk :: Int -> LBS.ByteString -> LBS.ByteString
+rechunk multiple = LBS.fromChunks . BS.rechunk multiple . LBS.toChunks
+
+rechunkPadded :: Int -> LBS.ByteString -> LBS.ByteString
+rechunkPadded multiple = LBS.fromChunks . BS.rechunkPadded multiple . LBS.toChunks
 
 hGetContentsChunkedBy :: Int -> IO.Handle -> IO LBS.ByteString
 hGetContentsChunkedBy k h = lazyRead
diff --git a/test/HaskellWorks/Data/ByteStringSpec.hs b/test/HaskellWorks/Data/ByteStringSpec.hs
--- a/test/HaskellWorks/Data/ByteStringSpec.hs
+++ b/test/HaskellWorks/Data/ByteStringSpec.hs
@@ -22,8 +22,9 @@
   it "resegment creates correctly sized segments" $ requireProperty $ do
     bss       <- forAll $ (BS.pack <$>) <$> G.list (R.linear 0 8) (G.list (R.linear 0 24) (G.word8 R.constantBounded))
     chunkSize <- forAll $ G.int (R.linear 1 4)
-    forM_ (drop 1 (reverse (BS.resegment chunkSize bss))) $ \bs -> do
-      (BS.length bs) `mod` chunkSize === 0
+    let withoutLast = reverse (drop 1 (reverse (BS.resegment chunkSize bss)))
+    let disalignments = (\n -> n - (n `div` chunkSize) * chunkSize) . BS.length <$> withoutLast
+    disalignments === replicate (length disalignments) 0
   it "resegmentPadded does not modify data" $ requireProperty $ do
     bss       <- forAll $ (BS.pack <$>) <$> G.list (R.linear 0 8) (G.list (R.linear 0 24) (G.word8 R.constantBounded))
     chunkSize <- forAll $ G.int (R.linear 1 4)
