diff --git a/Crypto/Pbkdf2.hs b/Crypto/Pbkdf2.hs
--- a/Crypto/Pbkdf2.hs
+++ b/Crypto/Pbkdf2.hs
@@ -1,12 +1,12 @@
-module Crypto.Pbkdf2 (pbkdf2, hmacSha512Pbkdf2) where
+module Crypto.Pbkdf2 (pbkdf2, pbkdf2_iterative) where
 
-import Data.Digest.Pure.SHA (hmacSha512, bytestringDigest)
 import Data.Bits (shiftR)
-import Data.ByteString.Lazy as B
-import Data.Binary as Bin
 import Data.Bits(xor)
 
-octetsBE :: Word32 -> [Word8]
+import qualified Data.ByteString.Lazy as B
+import qualified Data.Binary as Bin
+
+octetsBE :: Bin.Word32 -> [Bin.Word8]
 octetsBE w = 
     [ fromIntegral (w `shiftR` 24)
     , fromIntegral (w `shiftR` 16)
@@ -18,17 +18,55 @@
   | B.length x == B.length y = B.pack $ B.zipWith xor x y
   | otherwise = error "xor bytestrings are not of equal length"
 
-pbkdf2 :: (ByteString -> ByteString -> ByteString)
+-- | This is a non standard variation of PBKDF2 which recursively uses the
+-- last generated value to improve the salt. In difference to pbkdf2 the
+-- salt can not be precalculated for every iteration (with a simple append
+-- of 4 bytes), but has to be calculated for every single iteration. This
+-- also creates a function where you cannot jump in the stream without
+-- calculating everything before it.  Compared to the standard this
+-- function only changes the salt for the initial PBKDF2 value of each
+-- iteration to include a salt iterated from earlier parts of the PBKDF2
+-- stream. This can be verified by removing the i from (hash' $ B.concat
+-- [i, salt, B.pack $ octetsBE c]).
+--
+-- The added salt for the first iteration will be "", and all following
+-- will be calculated as (PRF output input), where output is the output of
+-- the previous block and input is the added salt for the previous block.
+-- Notice that the output from the previous block is put in the password
+-- filed of the PRF.
+pbkdf2_iterative :: (B.ByteString -> B.ByteString -> B.ByteString)
+                     -- ^ @PRF@, the PRF function to be used for the
+                     -- iterative PBKDF2. The first argument is secret, the
+                     -- second argument is not.
+                 -> B.ByteString -- ^ @Password@, the secret to use in the PBKDF2 computations.
+                 -> B.ByteString -- ^ @Salt@, the not neccesarily secret data to use in the PBKDF2 computations.
+                 -> Integer -- ^ @c@, number of iterations for the the PBKDF2 computations.
+                 -> B.ByteString -- ^ @DK@, the output data in the format of an unlimited lazy ByteString.
+pbkdf2_iterative prf password salt iterations = B.concat $ pbkdf2' (B.pack []) 1
+  where
+    hash' = prf password
+    pbkdf2' :: B.ByteString -> Bin.Word32 -> [B.ByteString]
+    pbkdf2' i c = let prev = (pbkdf2'' (hash' $ B.concat [i, salt, B.pack $ octetsBE c])) in prev:(pbkdf2' (prf prev i) (c + 1))
+    pbkdf2'' hash = pbkdf2''' hash hash 1
+    pbkdf2''' prev_hash prev_result i
+      | i == iterations = prev_result
+      | i > iterations = error "Count must be at least 1"
+      | otherwise = pbkdf2''' current_hash result (i + 1)
+        where
+          current_hash = (hash' prev_hash)
+          result = xorByteStrings current_hash prev_result
+
+pbkdf2 :: (B.ByteString -> B.ByteString -> B.ByteString)
            -- ^ @PRF@, the PRF function to be used for PBKDF2. The first
            -- argument is secret, the second argument is not.
-       -> ByteString -- ^ @Password@, the secret to use in the PBKDF2 computations.
-       -> ByteString -- ^ @Salt@, the not neccesarily secret data to use in the PBKDF2 computations.
+       -> B.ByteString -- ^ @Password@, the secret to use in the PBKDF2 computations.
+       -> B.ByteString -- ^ @Salt@, the not neccesarily secret data to use in the PBKDF2 computations.
        -> Integer -- ^ @c@, number of iterations for the the PBKDF2 computations.
-       -> ByteString -- ^ @DK@, the output data in the format of an unlimited lazy ByteString.
+       -> B.ByteString -- ^ @DK@, the output data in the format of an unlimited lazy ByteString.
 pbkdf2 prf password salt iterations = B.concat $ pbkdf2' 1 True
   where
     hash' = prf password
-    pbkdf2' :: Word32 -> Bool -> [ByteString]
+    pbkdf2' :: Bin.Word32 -> Bool -> [B.ByteString]
     pbkdf2' 1 False = error "Hashing algorithm looped, stopping to maintain security of data" -- Paranoia, but that's useful when doing crypto
     pbkdf2' i _ = (pbkdf2'' (hash' $ B.concat [salt, B.pack $ octetsBE i])):(pbkdf2' (i + 1) False)
     pbkdf2'' hash = pbkdf2''' hash hash 1
@@ -39,12 +77,3 @@
         where
           current_hash = (hash' prev_hash)
           result = xorByteStrings current_hash prev_result
-
--- |Example of the pbkdf2 function using SHA512. See `pbkdf2` for usage.
-hmacSha512Pbkdf2 :: ByteString -- ^ @Password@
-                 -> ByteString -- ^ @Salt@
-                 -> Integer -- ^ @c@
-                 -> ByteString -- ^ @DK@
-hmacSha512Pbkdf2 = pbkdf2 hash
-  where
-    hash password salt = bytestringDigest $ hmacSha512 password salt
diff --git a/Lazy-Pbkdf2.cabal b/Lazy-Pbkdf2.cabal
--- a/Lazy-Pbkdf2.cabal
+++ b/Lazy-Pbkdf2.cabal
@@ -1,5 +1,5 @@
 Name:           Lazy-Pbkdf2
-Version:        1.0.2
+Version:        2.1.0
 Author:         Marcus Ofenhed <marcus@conditionraise.se>
 Maintainer:     Marcus Ofenhed <marcus@conditionraise.se>
 License:        MIT
@@ -15,7 +15,6 @@
   Exposed-Modules:   Crypto.Pbkdf2
   Default-Language:  Haskell2010
   Build-Depends:     base>= 4 && <5,
-                     SHA,
                      bytestring,
                      binary
                    
@@ -25,10 +24,11 @@
   Main-Is:           Pbkdf2-test.hs
   Default-Language:  Haskell2010
   Build-Depends:     base>= 4 && <5,
-                     SHA,
+                     cryptonite,
                      bytestring,
                      base16-bytestring,
-                     binary
+                     binary,
+                     memory
 
 Source-Repository head
   Type:       git
diff --git a/Pbkdf2-test.hs b/Pbkdf2-test.hs
--- a/Pbkdf2-test.hs
+++ b/Pbkdf2-test.hs
@@ -1,10 +1,14 @@
 import Data.ByteString.Lazy.Char8 as C8
-import Crypto.Pbkdf2 (hmacSha512Pbkdf2)
+import qualified Data.ByteString.Lazy as BS
+import Crypto.Pbkdf2 (pbkdf2)
 import Data.Binary as B
+import Data.ByteArray as BA
 import Data.ByteString.Base16.Lazy as B16
 import Data.Int (Int64)
 import System.IO (hSetBuffering, stdout, BufferMode (NoBuffering) )
 import System.Exit (exitFailure, exitSuccess)
+import Crypto.MAC.HMAC (initialize, update, finalize, Context(), hmacGetDigest)
+import Crypto.Hash.Algorithms (SHA512)
 
 -- Inofficial test suite fetched from http://stackoverflow.com/a/19898265
 test_vectors :: [(ByteString, ByteString, Integer, Int64, ByteString)]
@@ -84,6 +88,7 @@
   where
     generated = B16.encode $ C8.take len $ hmacSha512Pbkdf2 pass salt iter
     (pass, salt, iter, len, result) = test
+    hmacSha512Pbkdf2 = pbkdf2 (\key d -> let h = (initialize $ C8.toStrict key :: Context SHA512) ; h' = update h $ C8.toStrict d in BS.pack $ BA.unpack $ hmacGetDigest $ finalize h')
 
 countIf :: (a -> Bool) -> [a] -> Int
 countIf cond = Prelude.length . Prelude.filter cond
