diff --git a/Crypto/Classes.hs b/Crypto/Classes.hs
--- a/Crypto/Classes.hs
+++ b/Crypto/Classes.hs
@@ -320,7 +320,7 @@
                         | otherwise             -> Left (GenErrorOther "Generator failed to provide requested number of bytes")
 {-# INLINEABLE getIV #-}
 
--- | Obtain an 'IV' using the system entropy (see 'System.Crypto.Random')
+-- | Obtain an 'IV' using the system entropy (see 'System.Entropy')
 getIVIO :: (BlockCipher k) => IO (IV k)
 getIVIO = do
         let p = Proxy
@@ -459,7 +459,7 @@
 keyLengthBytes :: (BlockCipher k) => Tagged k ByteLength
 keyLengthBytes = fmap (`div` 8) keyLength
 
--- |Build a symmetric key using the system entropy (see 'System.Crypto.Random')
+-- |Build a symmetric key using the system entropy (see 'System.Entropy')
 buildKeyIO :: (BlockCipher k) => IO k
 buildKeyIO = buildKeyM getEntropy fail
 
@@ -490,6 +490,7 @@
   privateKeyLength :: v -> BitLength
 
 -- |Build a pair of asymmetric keys using the system random generator.
+--   WARNING: This function opens a file handle which will never be closed!
 buildKeyPairIO :: AsymCipher p v => BitLength -> IO (Either GenError (p,v))
 buildKeyPairIO bl = do
         g <- newGenIO :: IO SystemRandom
@@ -542,6 +543,7 @@
   verifyingKeyLength :: p -> BitLength
 
 -- |Build a signing key using the system random generator
+--   WARNING: This function opens a file handle which will never be closed!
 buildSigningKeyPairIO :: (Signing p v) => BitLength -> IO (Either GenError (p,v))
 buildSigningKeyPairIO bl = do
         g <- newGenIO :: IO SystemRandom
diff --git a/Crypto/Classes.hs-boot b/Crypto/Classes.hs-boot
--- a/Crypto/Classes.hs-boot
+++ b/Crypto/Classes.hs-boot
@@ -1,4 +1,133 @@
+{-|
+ Maintainer: Thomas.DuBuisson@gmail.com
+ Stability: beta
+ Portability: portable 
+ Authors: Thomas DuBuisson
+
+This is the heart of the crypto-api package.  By making (or having) an instance
+of Hash, AsymCipher, BlockCipher or StreamCipher you provide (or obtain) access
+to any infrastructure built on these primitives include block cipher modes of
+operation, hashing, hmac, signing, etc.  These classes allow users to build
+routines that are agnostic to the algorithm used so changing algorithms is as
+simple as changing a type signature.
+-}
 module Crypto.Classes where
-    import Crypto.Types
-    class BlockCipher k
-    zeroIV :: (BlockCipher k) => IV k
+
+  import Data.ByteString as B
+  import Data.ByteString.Lazy as L
+  import Crypto.Types
+  import Data.Serialize
+  import Data.Tagged
+
+  class ( Serialize k) => BlockCipher k where
+    blockSize     :: Tagged k BitLength                   -- ^ The size of a single block; the smallest unit on which the cipher operates.
+    encryptBlock  :: k -> B.ByteString -> B.ByteString    -- ^ encrypt data of size @n*blockSize@ where @n `elem` [0..]@  (ecb encryption)
+    decryptBlock  :: k -> B.ByteString -> B.ByteString    -- ^ decrypt data of size @n*blockSize@ where @n `elem` [0..]@  (ecb decryption)
+    buildKey      :: B.ByteString -> Maybe k              -- ^ smart constructor for keys from a bytestring.
+    keyLength     :: Tagged k BitLength                   -- ^ length of the cryptographic key
+
+    -- * Modes of operation over strict bytestrings
+    -- | Electronic Cookbook (encryption)
+    ecb           :: k -> B.ByteString -> B.ByteString
+    ecb = modeEcb'
+    -- | Electronic Cookbook (decryption)
+    unEcb         :: k -> B.ByteString -> B.ByteString
+    unEcb = modeUnEcb'
+    -- | Cipherblock Chaining (encryption)
+    cbc           :: k -> IV k -> B.ByteString -> (B.ByteString, IV k)
+    cbc = modeCbc'
+    -- | Cipherblock Chaining (decryption)
+    unCbc         :: k -> IV k -> B.ByteString -> (B.ByteString, IV k)
+    unCbc = modeUnCbc'
+
+    -- | Counter (encryption)
+    ctr           :: k -> IV k -> B.ByteString -> (B.ByteString, IV k)
+    ctr = modeCtr' incIV
+
+    -- | Counter (decryption)
+    unCtr         :: k -> IV k -> B.ByteString -> (B.ByteString, IV k)
+    unCtr = modeUnCtr' incIV
+
+    -- | Counter (encryption)
+    ctrLazy           :: k -> IV k -> L.ByteString -> (L.ByteString, IV k)
+    ctrLazy = modeCtr incIV
+
+    -- | Counter (decryption)
+    unCtrLazy         :: k -> IV k -> L.ByteString -> (L.ByteString, IV k)
+    unCtrLazy = modeUnCtr incIV
+
+    -- | Ciphertext feedback (encryption)
+    cfb           :: k -> IV k -> B.ByteString -> (B.ByteString, IV k)
+    cfb = modeCfb'
+    -- | Ciphertext feedback (decryption)
+    unCfb         :: k -> IV k -> B.ByteString -> (B.ByteString, IV k)
+    unCfb = modeUnCfb'
+    -- | Output feedback (encryption)
+    ofb           :: k -> IV k -> B.ByteString -> (B.ByteString, IV k)
+    ofb = modeOfb'
+
+    -- | Output feedback (decryption)
+    unOfb         :: k -> IV k -> B.ByteString -> (B.ByteString, IV k)
+    unOfb = modeUnOfb'
+
+    -- |Cipher block chaining encryption for lazy bytestrings
+    cbcLazy       :: k -> IV k -> L.ByteString -> (L.ByteString, IV k)
+    cbcLazy = modeCbc
+
+    -- |Cipher block chaining decryption for lazy bytestrings
+    unCbcLazy     :: k -> IV k -> L.ByteString -> (L.ByteString, IV k)
+    unCbcLazy = modeUnCbc
+
+    -- |SIV (Synthetic IV) mode for lazy bytestrings. The third argument is
+    -- the optional list of bytestrings to be authenticated but not
+    -- encrypted As required by the specification this algorithm may
+    -- return nothing when certain constraints aren't met.
+    sivLazy :: k -> k -> [L.ByteString] -> L.ByteString -> Maybe L.ByteString
+    sivLazy = modeSiv
+
+    -- |SIV (Synthetic IV) for lazy bytestrings.  The third argument is the
+    -- optional list of bytestrings to be authenticated but not encrypted.
+    -- As required by the specification this algorithm may return nothing
+    -- when authentication fails.
+    unSivLazy :: k -> k -> [L.ByteString] -> L.ByteString -> Maybe L.ByteString
+    unSivLazy = modeUnSiv
+
+    -- |SIV (Synthetic IV) mode for strict bytestrings.  First argument is
+    -- the optional list of bytestrings to be authenticated but not
+    -- encrypted.  As required by the specification this algorithm may
+    -- return nothing when certain constraints aren't met.
+    siv :: k -> k -> [B.ByteString] -> B.ByteString -> Maybe B.ByteString
+    siv = modeSiv'
+
+    -- |SIV (Synthetic IV) for strict bytestrings First argument is the
+    -- optional list of bytestrings to be authenticated but not encrypted
+    -- As required by the specification this algorithm may return nothing
+    -- when authentication fails.
+    unSiv :: k -> k -> [B.ByteString] -> B.ByteString -> Maybe B.ByteString
+    unSiv = modeUnSiv'
+
+    -- |Cook book mode - not really a mode at all.  If you don't know what you're doing, don't use this mode^H^H^H^H library.
+    ecbLazy :: k -> L.ByteString -> L.ByteString
+    ecbLazy = modeEcb
+
+    -- |ECB decrypt, complementary to `ecb`.
+    unEcbLazy :: k -> L.ByteString -> L.ByteString
+    unEcbLazy = modeUnEcb
+
+    -- |Ciphertext feed-back encryption mode for lazy bytestrings (with s
+    -- == blockSize)
+    cfbLazy :: k -> IV k -> L.ByteString -> (L.ByteString, IV k)
+    cfbLazy = modeCfb
+
+    -- |Ciphertext feed-back decryption mode for lazy bytestrings (with s
+    -- == blockSize)
+    unCfbLazy :: k -> IV k -> L.ByteString -> (L.ByteString, IV k)
+    unCfbLazy = modeUnCfb
+
+    -- |Output feedback mode for lazy bytestrings
+    ofbLazy  :: k -> IV k -> L.ByteString -> (L.ByteString, IV k)
+    ofbLazy = modeOfb
+
+    -- |Output feedback mode for lazy bytestrings
+    unOfbLazy :: k -> IV k -> L.ByteString -> (L.ByteString, IV k)
+    unOfbLazy = modeUnOfb
diff --git a/Crypto/Classes/Exceptions.hs b/Crypto/Classes/Exceptions.hs
--- a/Crypto/Classes/Exceptions.hs
+++ b/Crypto/Classes/Exceptions.hs
@@ -1,29 +1,38 @@
--- |The module mirrors 'Crypto.Classes' except that errors are thrown as
+-- |The module mirrors "Crypto.Classes" except that errors are thrown as
 -- exceptions instead of having returning types of @Either error result@
 -- or @Maybe result@.
 --
 -- NB This module is experimental and might go away or be re-arranged.
 {-# LANGUAGE DeriveDataTypeable #-}
 module Crypto.Classes.Exceptions 
-    ( C.Hash(..)
+    ( -- * Classes
+      C.Hash(..), C.AsymCipher, R.CryptoRandomGen, C.BlockCipher
+      -- * Hashing Operations
     , C.hashFunc', C.hashFunc
-    , C.BlockCipher, C.blockSize, C.encryptBlock, C.decryptBlock
-    , C.keyLength
-    , C.getIVIO, C.blockSizeBytes, C.keyLengthBytes, C.buildKeyIO
-    , C.AsymCipher, C.publicKeyLength, C.privateKeyLength, C.buildKeyPairIO
-    , C.Signing, C.signingKeyLength, C.verifyingKeyLength, C.verify
-    , C.incIV, C.zeroIV, R.CryptoRandomGen, R.genSeedLength, R.reseedInfo, R.reseedPeriod, R.newGenIO
-    --  Types
-    , R.GenError(..), R.ReseedInfo(..), CipherError(..)
-    -- Modes
+      -- * Symmetric Cryptographic Operations
+      -- ** Helpers
+    , C.blockSize, C.blockSizeBytes
+    , C.keyLength, C.keyLengthBytes
+    , C.incIV
+      -- ** Primitives
+    , C.encryptBlock, C.decryptBlock
+    -- * Key and IV construction
+    , buildKey, C.buildKeyIO, buildKeyGen
+    , getIV ,C.getIVIO, C.zeroIV
+    -- ** Block Cipher Modes of Operation
     , C.ecb, C.unEcb, C.cbc, C.unCbc, C.ctr, C.unCtr, C.ctrLazy, C.unCtrLazy
     , C.cfb, C.unCfb, C.ofb, C.unOfb, C.cbcLazy, C.unCbcLazy, C.sivLazy, C.unSivLazy
     , C.siv, C.unSiv, C.ecbLazy, C.unEcbLazy, C.cfbLazy, C.unCfbLazy, C.ofbLazy
     , C.unOfbLazy
-    -- Wrapped functions
-    , buildKey, getIV, buildKeyGen
-    , buildKeyPair, encryptAsym, decryptAsym
+    -- * RNG Operations
     , newGen, genBytes, genBytesWithEntropy, reseed, splitGen
+    , R.genSeedLength, R.reseedInfo, R.reseedPeriod, R.newGenIO
+    --  * Info Types
+    , R.GenError(..), R.ReseedInfo(..), CipherError(..)
+    -- * Asymmetric cryptographic operations
+    , buildKeyPair, encryptAsym, decryptAsym
+    , C.Signing, C.signingKeyLength, C.verifyingKeyLength, C.verify
+    , C.publicKeyLength, C.privateKeyLength, C.buildKeyPairIO
     ) where
 
 import qualified Crypto.Random     as R
diff --git a/Crypto/Modes.hs b/Crypto/Modes.hs
--- a/Crypto/Modes.hs
+++ b/Crypto/Modes.hs
@@ -2,13 +2,7 @@
 {-|
  Maintainer: Thomas.DuBuisson@gmail.com
  Stability: beta
- Portability: portable 
- Authors: Thomas DuBuisson
-
-
- Generic mode implementations useable by any correct BlockCipher
- instance Be aware there are no tests for CFB mode yet.  See
- 'Test.Crypto'.
+ Portability: portable
 -}
 module Crypto.Modes (
         -- * Initialization Vector Type, Modifiers (for all ciphers, all modes that use IVs)
diff --git a/Crypto/Random.hs b/Crypto/Random.hs
--- a/Crypto/Random.hs
+++ b/Crypto/Random.hs
@@ -9,7 +9,7 @@
  This module is for instantiating cryptographicly strong
 determinitic random bit generators (DRBGs, aka PRNGs) For the simple
 use case of using the system random number generator
-('System.Crypto.Random') to seed the DRBG:
+('System.Entropy') to seed the DRBG:
 
 @   g <- newGenIO
 @
@@ -160,8 +160,9 @@
         -- (`NotEnoughEntropy`).
         reseed          :: B.ByteString -> g -> Either GenError g
 
-        -- |By default this uses "System.Crypto.Random" to obtain
+        -- |By default this uses "System.Entropy" to obtain
         -- entropy for `newGen`.
+        -- WARNING: The default implementation opens a file handle which will never be closed!
         newGenIO :: IO g
         newGenIO = go 0
           where
@@ -178,7 +179,8 @@
                         Left _ -> go (i+1)
                         Right g -> return (g `asProxyTypeOf` p)
 
--- |Get a random number generator based on the standard system entropy source
+-- | Get a random number generator based on the standard system entropy source
+--   WARNING: This function opens a file handle which will never be closed!
 getSystemGen :: IO SystemRandom
 getSystemGen = do
         ch <- openHandle
diff --git a/crypto-api.cabal b/crypto-api.cabal
--- a/crypto-api.cabal
+++ b/crypto-api.cabal
@@ -1,5 +1,5 @@
 name:           crypto-api
-version:        0.13
+version:        0.13.3
 license:        BSD3
 license-file:   LICENSE
 copyright:      Thomas DuBuisson <thomas.dubuisson@gmail.com>
