diff --git a/Raaz.hs b/Raaz.hs
--- a/Raaz.hs
+++ b/Raaz.hs
@@ -2,18 +2,18 @@
 -- By importing this module you get a rather high-level access to the
 -- primitives provided by the library.
 module Raaz
-       ( version
-       , module Raaz.Cipher
+       ( module Raaz.Cipher
        , module Raaz.Core
        , module Raaz.Hash
+       , version
        ) where
 
 import           Data.Version  (Version)
 import qualified Paths_raaz as P
 
-import Raaz.Core
-import Raaz.Hash
-import Raaz.Cipher
+import           Raaz.Core
+import           Raaz.Hash
+import           Raaz.Cipher
 
 
 -- | Raaz library version number.
diff --git a/Raaz/Cipher/AES/CBC/Implementation/CPortable.hs b/Raaz/Cipher/AES/CBC/Implementation/CPortable.hs
--- a/Raaz/Cipher/AES/CBC/Implementation/CPortable.hs
+++ b/Raaz/Cipher/AES/CBC/Implementation/CPortable.hs
@@ -70,11 +70,11 @@
 ------------------- 128-bit CBC Implementation ----------------
 
 -- | Implementation of 128-bit AES in CBC mode using Portable C.
-aes128cbcI :: Implementation (AES 128 CBC)
+aes128cbcI :: Implementation (AES 128 'CBC)
 aes128cbcI = SomeCipherI cbc128CPortable
 
 -- | 128-bit AES in CBC mode using Portable C.
-cbc128CPortable :: CipherI (AES 128 CBC) M128 M128
+cbc128CPortable :: CipherI (AES 128 'CBC) M128 M128
 cbc128CPortable =
   CipherI { cipherIName = "aes128cbc-cportable"
           , cipherIDescription =
@@ -84,14 +84,14 @@
           }
 
 -- | The encryption action.
-cbc128Encrypt :: Pointer -> BLOCKS (AES 128 CBC) -> MT M128 ()
+cbc128Encrypt :: Pointer -> BLOCKS (AES 128 'CBC) -> MT M128 ()
 cbc128Encrypt buf nBlocks =
   do eKeyPtr <- liftSubMT m128ekey getMemoryPointer
      ivPtr   <- liftSubMT m128iv   getMemoryPointer
      liftIO $ c_aes_cbc_e buf (fromEnum nBlocks) 10 eKeyPtr ivPtr
 
 -- | The decryption action.
-cbc128Decrypt :: Pointer -> BLOCKS (AES 128 CBC) -> MT M128 ()
+cbc128Decrypt :: Pointer -> BLOCKS (AES 128 'CBC) -> MT M128 ()
 cbc128Decrypt buf nBlocks =
   do eKeyPtr <- liftSubMT m128ekey getMemoryPointer
      ivPtr   <- liftSubMT m128iv   getMemoryPointer
@@ -102,11 +102,11 @@
 ------------------- 192-bit CBC Implementation ----------------
 
 -- | Implementation of 192-bit AES in CBC mode using Portable C.
-aes192cbcI :: Implementation (AES 192 CBC)
+aes192cbcI :: Implementation (AES 192 'CBC)
 aes192cbcI = SomeCipherI cbc192CPortable
 
 -- | 192-bit AES in CBC mode using Portable C.
-cbc192CPortable :: CipherI (AES 192 CBC) M192 M192
+cbc192CPortable :: CipherI (AES 192 'CBC) M192 M192
 cbc192CPortable =
   CipherI { cipherIName = "aes192cbc-cportable"
           , cipherIDescription =
@@ -116,14 +116,14 @@
           }
 
 -- | The encryption action.
-cbc192Encrypt :: Pointer -> BLOCKS (AES 192 CBC) -> MT M192 ()
+cbc192Encrypt :: Pointer -> BLOCKS (AES 192 'CBC) -> MT M192 ()
 cbc192Encrypt buf nBlocks =
   do eKeyPtr <- liftSubMT m192ekey getMemoryPointer
      ivPtr   <- liftSubMT m192iv   getMemoryPointer
      liftIO $ c_aes_cbc_e buf (fromEnum nBlocks) 12 eKeyPtr ivPtr
 
 -- | The decryption action.
-cbc192Decrypt :: Pointer -> BLOCKS (AES 192 CBC) -> MT M192 ()
+cbc192Decrypt :: Pointer -> BLOCKS (AES 192 'CBC) -> MT M192 ()
 cbc192Decrypt buf nBlocks =
   do eKeyPtr <- liftSubMT m192ekey getMemoryPointer
      ivPtr   <- liftSubMT m192iv   getMemoryPointer
@@ -132,11 +132,11 @@
 ------------------- 256-bit CBC Implementation ----------------
 
 -- | Implementation of 256-bit AES in CBC mode using Portable C.
-aes256cbcI :: Implementation (AES 256 CBC)
+aes256cbcI :: Implementation (AES 256 'CBC)
 aes256cbcI = SomeCipherI cbc256CPortable
 
 -- | 256-bit AES in CBC mode using Portable C.
-cbc256CPortable :: CipherI (AES 256 CBC) M256 M256
+cbc256CPortable :: CipherI (AES 256 'CBC) M256 M256
 cbc256CPortable =
   CipherI { cipherIName = "aes256cbc-cportable"
           , cipherIDescription =
@@ -146,14 +146,14 @@
           }
 
 -- | The encryption action.
-cbc256Encrypt :: Pointer -> BLOCKS (AES 256 CBC) -> MT M256 ()
+cbc256Encrypt :: Pointer -> BLOCKS (AES 256 'CBC) -> MT M256 ()
 cbc256Encrypt buf nBlocks =
   do eKeyPtr <- liftSubMT m256ekey getMemoryPointer
      ivPtr   <- liftSubMT m256iv   getMemoryPointer
      liftIO $ c_aes_cbc_e buf (fromEnum nBlocks) 14 eKeyPtr ivPtr
 
 -- | The decryption action.
-cbc256Decrypt :: Pointer -> BLOCKS (AES 256 CBC) -> MT M256 ()
+cbc256Decrypt :: Pointer -> BLOCKS (AES 256 'CBC) -> MT M256 ()
 cbc256Decrypt buf nBlocks =
   do eKeyPtr <- liftSubMT m256ekey getMemoryPointer
      ivPtr   <- liftSubMT m256iv   getMemoryPointer
diff --git a/Raaz/Cipher/AES/Internal.hs b/Raaz/Cipher/AES/Internal.hs
--- a/Raaz/Cipher/AES/Internal.hs
+++ b/Raaz/Cipher/AES/Internal.hs
@@ -102,59 +102,59 @@
 ----------------- AES 128 CBC ------------------------------
 
 -- | 128-bit aes cipher in `CBC` mode.
-aes128cbc :: AES 128 CBC
+aes128cbc :: AES 128 'CBC
 aes128cbc = AES
 
 -- | The 128-bit aes cipher in cbc mode.
-instance Primitive (AES 128 CBC) where
+instance Primitive (AES 128 'CBC) where
   blockSize _ = BYTES 16
-  type Implementation (AES 128 CBC) = SomeCipherI (AES 128 CBC)
+  type Implementation (AES 128 'CBC) = SomeCipherI (AES 128 'CBC)
 
 -- | Key is @(`KEY128`,`IV`)@ pair.
-instance Symmetric (AES 128 CBC) where
-  type Key (AES 128 CBC) = (KEY128,IV)
+instance Symmetric (AES 128 'CBC) where
+  type Key (AES 128 'CBC) = (KEY128,IV)
 
-instance Cipher (AES 128 CBC)
+instance Cipher (AES 128 'CBC)
 
 ----------------- AES 192 CBC --------------------------------
 
 -- | 128-bit aes cipher in `CBC` mode.
-aes192cbc :: AES 192 CBC
+aes192cbc :: AES 192 'CBC
 aes192cbc = AES
 
 -- | The 192-bit aes cipher in cbc mode.
-instance Primitive (AES 192 CBC) where
+instance Primitive (AES 192 'CBC) where
   blockSize _ = BYTES 16
-  type Implementation (AES 192 CBC) = SomeCipherI (AES 192 CBC)
+  type Implementation (AES 192 'CBC) = SomeCipherI (AES 192 'CBC)
 
 -- | Key is @(`KEY192`,`IV`)@ pair.
-instance Symmetric (AES 192 CBC) where
-  type Key (AES 192 CBC) = (KEY192,IV)
+instance Symmetric (AES 192 'CBC) where
+  type Key (AES 192 'CBC) = (KEY192,IV)
 
-instance Cipher (AES 192 CBC)
+instance Cipher (AES 192 'CBC)
 
 ------------------- AES 256 CBC -----------------------------
 
 -- | 128-bit aes cipher in `CBC` mode.
-aes256cbc :: AES 256 CBC
+aes256cbc :: AES 256 'CBC
 aes256cbc = AES
 
 -- | The 256-bit aes cipher in cbc mode.
-instance Primitive (AES 256 CBC) where
+instance Primitive (AES 256 'CBC) where
   blockSize _ = BYTES 16
-  type Implementation (AES 256 CBC) = SomeCipherI (AES 256 CBC)
+  type Implementation (AES 256 'CBC) = SomeCipherI (AES 256 'CBC)
 
 -- | Key is @(`KEY256`,`IV`)@ pair.
-instance Symmetric (AES 256 CBC) where
-  type Key (AES 256 CBC) = (KEY256,IV)
+instance Symmetric (AES 256 'CBC) where
+  type Key (AES 256 'CBC) = (KEY256,IV)
 
-instance Cipher (AES 256 CBC)
+instance Cipher (AES 256 'CBC)
 
 
 ------------------- AES CTR mode ---------------------------
 
 -- | Smart constructors for AES 128 ctr.
-aes128ctr :: AES 128 CTR
+aes128ctr :: AES 128 'CTR
 aes128ctr = AES
 
 --------------  Memory for storing extended keys ---------
diff --git a/Raaz/Core/ByteSource.hs b/Raaz/Core/ByteSource.hs
--- a/Raaz/Core/ByteSource.hs
+++ b/Raaz/Core/ByteSource.hs
@@ -2,10 +2,12 @@
 {-# LANGUAGE DefaultSignatures #-}
 -- | Module define byte sources.
 module Raaz.Core.ByteSource
-       ( ByteSource(..), fill, processChunks
-       , InfiniteSource(..), slurp
-       , PureByteSource
+       ( -- * Byte sources.
+         -- $bytesource$
+         InfiniteSource(..)
+       , ByteSource(..), PureByteSource
        , FillResult(..)
+       , fill, slurp, processChunks
        , withFillResult
        ) where
 
@@ -26,6 +28,23 @@
                                           )
 import           Raaz.Core.Types.Pointer  (hFillBuf)
 
+-- $bytesource$
+--
+-- Cryptographic input come from various sources; they can come from
+-- network sockets or might be just a string in the Haskell. To give a
+-- uniform interfaces for all such inputs, we define the abstract
+-- concept of a /byte source/. Essentially a byte source is one from
+-- which we can fill a buffer with bytes. Depending on the nature of
+-- the source we have two classes: `ByteSource` which captures bounded
+-- sources and `InfiniteSource` that captures never ending source of
+-- bytes.
+--
+-- Among instances of `ByteSource`, some like for example
+-- `B.ByteString` are /pure/ in the sense filling a buffer with bytes
+-- from such a source has no other side-effects. This is in contrast
+-- to a source like a sockets. The type class `PureByteSource`
+-- captures such byte sources.
+--
 
 -- | This type captures the result of a fill operation.
 data FillResult a = Remaining a           -- ^ the buffer is filled completely
@@ -77,6 +96,7 @@
 fill = fillBytes . inBytes
 {-# INLINE fill #-}
 
+-- | A version of slurp that takes type safe lengths as input.
 slurp :: ( LengthUnit len
          , InfiniteSource src
          )
diff --git a/Raaz/Core/Encode.hs b/Raaz/Core/Encode.hs
--- a/Raaz/Core/Encode.hs
+++ b/Raaz/Core/Encode.hs
@@ -1,40 +1,55 @@
---
 module Raaz.Core.Encode
-       ( -- * The encodable type
+       ( -- * Encoding of binary data.
          -- $encodable$
          Encodable(..)
-       -- * Encoding formats
-       -- $encodingformat$
        , Format(..)
-       , encode, decode, unsafeDecode
-       -- ** The base 16 encoding fromat
-       , Base16, fromBase16, showBase16
+       , encode, decode, translate, unsafeDecode
+       -- ** The base 16 encoding format
+       , Base16
+       , fromBase16, showBase16
+       -- ** Other binary formats.
+       , Base64
        ) where
 
 import Raaz.Core.Encode.Internal
 import Raaz.Core.Encode.Base16
+import Raaz.Core.Encode.Base64
 
 -- $encodable$
 --
--- Many types like cryptographic hashes, secret keys etc can be
--- encoded into bytes. This module gives an interface to such objects
--- using the `Encodable` type class. To ease their printing most types
--- of this class have a `Show` instances. Similarly, to make it easy
--- to defines constants of these types in source code, they often are
--- instances of `Data.String.IsString`. Typically for cryptographic
--- types like hashes, secret keys etc the `Show` and
--- `Data.String.IsString` instances correspond to the base-16 encoding
--- of these types.
+-- Often one wants to represent cryptographic hashes, secret keys or
+-- just binary data into various enocoding formats like base64,
+-- hexadecimal etc. This module gives a generic interface for all such
+-- operations. There are two main classes that capture the essence of
+-- encoding.
+--
+-- [`Format`] Each encoding supported by this module is an instance of
+--     this class. For printing and for easy inclusion in source code
+--     appropriate instances of `Show` and `Data.String.IsString` is
+--     provided for these types.
+--
+-- [`Encodable`] Instances of this class are those that can be encoded
+--    into any of the available formats. Actual encoding and decoding
+--    of elements of this class can be done by the combinators
+--    `encode` and `decode`
+--
+-- The raaz library exposes many instances of `Format` which are all
+-- some form of encoding of binary data.
+--
 
+-- | Encode in a given format.
+encode :: (Encodable a, Format fmt) => a -> fmt
+encode = encodeByteString . toByteString
 
+-- | Decode from a given format. It results in Nothing if there is a
+-- parse error.
+decode :: (Format fmt, Encodable a) => fmt -> Maybe a
+decode = fromByteString . decodeFormat
 
+-- | The unsafe version of `decode`.
+unsafeDecode :: (Format fmt, Encodable a) => fmt -> a
+unsafeDecode = unsafeFromByteString . decodeFormat
 
--- $encodingformat$
---
--- We also give facilities to encode any instance of `Encodable` into
--- multiple formats. For type safety, encoding formats are
--- distinguished by their types. All such formats have to be members
--- of the `Format` type class and this allows encoding and decoding
--- any type that is an instance of `Encodable` into any of the desired
--- format.
---
+-- | Translate from one format to another.
+translate :: (Format fmt1, Format fmt2) => fmt1 -> fmt2
+translate = encodeByteString . decodeFormat
diff --git a/Raaz/Core/Encode/Base16.hs b/Raaz/Core/Encode/Base16.hs
--- a/Raaz/Core/Encode/Base16.hs
+++ b/Raaz/Core/Encode/Base16.hs
@@ -1,6 +1,9 @@
 -- | Base 16 or hexadecimal encoding of objects.
 {-# LANGUAGE GeneralizedNewtypeDeriving #-}
-module Raaz.Core.Encode.Base16( Base16, fromBase16, showBase16 ) where
+module Raaz.Core.Encode.Base16
+       ( Base16
+       , fromBase16, showBase16
+       ) where
 
 import Data.Char
 import Data.Bits
@@ -15,7 +18,12 @@
 import Data.Word
 import Raaz.Core.Encode.Internal
 
--- | The base16 type.
+-- | The type corresponding to base-16 or hexadecimal encoding. The
+-- `Base16` encoding has a special place in this library: most
+-- cryptographic types use `Base16` encoding for their `Show` and
+-- `IsString` instance. The combinators `fromBase16` and `showBase16`
+-- are exposed mainly to make these definitions easy.
+--
 newtype Base16 = Base16 {unBase16 :: ByteString} deriving (Eq, Monoid)
 
 -- Developers note: Internally base16 just stores the bytestring as
@@ -29,7 +37,7 @@
     | odd (B.length bs) = Nothing
     | badCharacter bs   = Nothing
     | otherwise         = Just $ Base16 $ unsafeFromHex bs
-    where badCharacter  = C8.all (not . isHexDigit)
+    where badCharacter  = C8.any (not . isHexDigit)
 
   unsafeFromByteString  = Base16 . unsafeFromHex
 
@@ -66,8 +74,9 @@
 
 
 unsafeFromHex :: ByteString -> ByteString
-unsafeFromHex bs | odd (B.length bs) = error "base16 encoding is always of even size"
-                 | otherwise         = fst $ B.unfoldrN len gen 0
+unsafeFromHex bs
+  | odd (B.length bs) = error "base16 encoding is always of even size"
+  | otherwise         = fst $ B.unfoldrN len gen 0
   where len   = B.length bs `quot` 2
         gen i = Just (shiftL w0 4 .|. w1, i + 1)
           where w0 = fromHexWord $ unsafeIndex bs (2 * i)
@@ -83,8 +92,8 @@
 -- `IsString` instances as well as in cases where the default
 -- `IsString` instance does not parse from a base16 encoding.
 fromBase16 :: Encodable a => String -> a
-fromBase16 str = unsafeDecode (fromString str :: Base16)
+fromBase16 = unsafeFromByteString . unBase16 . fromString
 
 -- | Base16 variant of `show`.
 showBase16 :: Encodable a => a -> String
-showBase16 a = show (encode a :: Base16)
+showBase16 = show . Base16 . toByteString
diff --git a/Raaz/Core/Encode/Base64.hs b/Raaz/Core/Encode/Base64.hs
new file mode 100644
--- /dev/null
+++ b/Raaz/Core/Encode/Base64.hs
@@ -0,0 +1,171 @@
+-- | Base 64 encoding of objects.
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+module Raaz.Core.Encode.Base64( Base64 ) where
+
+import Data.Char
+import Data.Bits
+import Data.String
+
+import Data.ByteString as B
+import Data.ByteString.Char8 as C8
+import Data.ByteString.Internal (c2w, w2c)
+
+import Data.ByteString.Unsafe(unsafeIndex)
+import Data.Monoid
+import Data.Word
+import Raaz.Core.Encode.Internal
+
+
+-- | The type corresponding to the standard padded base-64 binary
+-- encoding.
+newtype Base64 = Base64 {unBase64 :: ByteString} deriving (Eq, Monoid)
+
+-- Developers note: Internally base16 just stores the bytestring as
+-- is. The conversion happens when we do an encode and decode of
+-- actual base16.
+
+instance Encodable Base64 where
+  toByteString          = toB64 . unBase64
+
+  fromByteString bs
+    | B.null bs                = Just $ Base64 B.empty
+    | B.length bs `rem` 4 /= 0 = Nothing
+    | badCharacter bs'         = Nothing
+    | not (isB64OrPad pl)      = Nothing
+    | not (isB64OrPad pf)      = Nothing
+    | otherwise                = Just $ Base64 $ unsafeFromB64 bs
+    where pl           = C8.last bs
+          pf           = C8.last $ C8.init bs
+          bs'          = C8.init $ C8.init bs
+          badCharacter = C8.any (not . isB64Char)
+          isB64Char c  = isAlpha c || isDigit c || c == '+' || c == '/'
+          isB64OrPad c = isB64Char c || c == '='
+
+  unsafeFromByteString bs | B.null bs = Base64 B.empty
+                          | otherwise = Base64 $ unsafeFromB64 bs
+
+
+instance Show Base64 where
+  show = C8.unpack . toByteString
+
+instance IsString Base64 where
+  fromString = unsafeFromByteString . fromString
+
+
+instance Format Base64 where
+  encodeByteString = Base64
+  {-# INLINE encodeByteString #-}
+
+  decodeFormat     = unBase64
+  {-# INLINE decodeFormat #-}
+
+
+
+------------- Base 64 encoding -------------------------
+
+-- NOTE: The topN functions ensure that the top N bits of a word are present
+-- in the least N significant bits. The botN ensures that there
+
+top6 :: Word8 -> Word8; bot2 :: Word8 -> Word8
+top4 :: Word8 -> Word8; bot4 :: Word8 -> Word8
+top2 :: Word8 -> Word8; bot6 :: Word8 -> Word8
+
+top6 w = w `shiftR` 2; bot2 w = w .&. 0x03
+top4 w = w `shiftR` 4; bot4 w = w .&. 0x0F
+top2 w = w `shiftR` 6; bot6 w = w .&. 0x3F
+
+--------------- Combining bytes -----------------------------------
+
+byte0 :: Word8 -> Word8
+byte1 :: Word8 -> Word8 -> Word8
+byte2 :: Word8 -> Word8 -> Word8
+byte3 :: Word8 -> Word8
+pad   :: Word8
+
+
+byte0     = b64 . top6
+byte1 t p = b64 $ shiftL (bot2 p) 4 .|. top4 t
+byte2 t p = b64 $ shiftL (bot4 p) 2 .|. top2 t
+byte3     = b64 . bot6
+pad       = c2w '='
+
+-- | Encoding word.
+b64 :: Word8 -> Word8
+b64 w | 0  <= w  && w <= 25 = c2w 'A' + w
+      | 26 <= w  && w <= 51 = c2w 'a' + w - 26
+      | 52 <= w  && w <= 61 = c2w '0' + w - 52
+      | w == 62             = c2w '+'
+      | w == 63             = c2w '/'
+      | otherwise           = error "oops: b64"
+
+
+unB64 :: Word8 -> Word8
+unB64 w | c2w 'A' <= w && w <= c2w 'Z' = w - c2w 'A'
+        | c2w 'a' <= w && w <= c2w 'z' = w - c2w 'a' + 26
+        | c2w '0' <= w && w <= c2w '9' = w - c2w '0' + 52
+        | w == c2w '+'                 = 62
+        | w == c2w '/'                 = 63
+        | otherwise                    = error $ "oops unB64:" ++ [w2c w]
+
+
+-- TODO: Since the encoding to base16 is usually used for user interaction
+-- we can afford to be slower here.
+toB64 :: ByteString -> ByteString
+toB64 bs = fst (B.unfoldrN (4*n) gen 0) <> padding
+    where gen i    = Just (byte i, i + 1)
+          at blk i = unsafeIndex bs $ 3 * blk + i
+
+          byte i = case r of
+            0 -> byte0          $ at q 0
+            1 -> byte1 (at q 1) $ at q 0
+            2 -> byte2 (at q 2) $ at q 1
+            3 -> byte3          $ at q 2
+            _ -> error "base64 bad index"
+            where (q, r) = quotRem i 4
+
+          (n,p) = B.length bs `quotRem` 3
+
+          padding = case p of
+            0 -> mempty
+            1 -> B.pack [ byte0   $ at n 0
+                        , byte1 0 $ at n 0
+                        , pad, pad
+                        ]
+            2 -> B.pack [ byte0          $ at n 0
+                        , byte1 (at n 1) $ at n 0
+                        , byte2 0        $ at n 1
+                        , pad
+                        ]
+            _ -> error "base64 pad bad index"
+
+-- Notes: Merge is used to convert from base64 digits, which are
+-- words of 6-bits.
+merg0 :: Word8 -> Word8 -> Word8
+merg1 :: Word8 -> Word8 -> Word8
+merg2 :: Word8 -> Word8 -> Word8
+merg0 a b = (unB64 a `shiftL` 2) .|. top4 (unB64 b)
+merg1 a b = (unB64 a `shiftL` 4) .|. top6 (unB64 b)
+merg2 a b = (unB64 a `shiftL` 6) .|. unB64 b
+
+unsafeFromB64 :: ByteString -> ByteString
+unsafeFromB64 bs = fst (B.unfoldrN (3*n) gen 0) <> unPad
+  where n         = B.length bs `quot` 4 - 1
+        gen i     = Just (byte i, i + 1)
+        at blk i  = unsafeIndex bs $ 4 * blk + i
+
+        byte i    = case r of
+          0 -> merg0 (at q 0) $ at q 1
+          1 -> merg1 (at q 1) $ at q 2
+          2 -> merg2 (at q 2) $ at q 3
+          _ -> error "base64 bad index"
+          where (q, r) = quotRem i 3
+
+        unPad
+          | at n 2 == c2w '=' = B.singleton $ merg0 (at n 0) $ at n 1
+          | at n 3 == c2w '=' = B.pack [ merg0 (at n 0) $ at n 1
+                                       , merg1 (at n 1) $ at n 2
+                                       ]
+          | otherwise         = B.pack [ merg0 (at n 0) $ at n 1
+                                       , merg1 (at n 1) $ at n 2
+                                       , merg2 (at n 2) $ at n 3
+                                       ]
diff --git a/Raaz/Core/Encode/Internal.hs b/Raaz/Core/Encode/Internal.hs
--- a/Raaz/Core/Encode/Internal.hs
+++ b/Raaz/Core/Encode/Internal.hs
@@ -5,10 +5,8 @@
 -- | Internal module that has the encode class and some utility functions.
 module Raaz.Core.Encode.Internal
        ( Encodable(..), Format(..)
-       , encode, decode, unsafeDecode
        ) where
 
-
 import Data.Maybe
 
 import Data.ByteString              (ByteString)
@@ -25,7 +23,21 @@
 import Raaz.Core.Util.ByteString(length, withByteString)
 
 
--- | The type class `Encodable` captures all the types can be encoding into `ByteString`.
+-- | The type class `Encodable` captures all the types that can be
+-- encoded into a stream of bytes. By making a type say @Foo@ an
+-- instance of the `Encodable` class, we get for free methods to
+-- encode it in any of the supported formats (i.e. instances of the
+-- class `Format`).
+--
+-- Minimum complete definition for this class is `toByteString` and
+-- `fromByteString`. Instances of `EndianStore` have default
+-- definitions for both these functions and hence a trivial instance
+-- declaration is sufficient for such types.
+--
+-- >
+-- > instance Encodable Foo
+-- >
+--
 class Encodable a where
   -- | Convert stuff to bytestring
   toByteString          :: a           -> ByteString
@@ -75,12 +87,39 @@
   unsafeFromByteString  = BYTES      . unsafeFromByteString
 
 
--- | A binary encoding format is something for which there is a 1:1
--- correspondence with bytestrings. We also insist that it is an
--- instance of `IsString`, so that it can be easily included in source
--- code, and `Show`, so that it can be easily printed out.
+
+-- | A binary format is a representation of binary data often in
+-- printable form. We distinguish between various binary formats at
+-- the type level and each supported format corresponds to an instance
+-- of the the class `Format`. The `encodeByteString` and
+-- `decodeFormat` are required to satisfy the laws
+--
+-- > decodeFormat . encodeByteString = id
+--
+-- For type safety, the formats themselves are opaque types and hence
+-- it is not possible to obtain the underlying binary data directly.
+-- We require binary formats to be instances of the class `Encodable`,
+-- with the combinators `toByteString` and `fromByteString` of the
+-- `Encodable` class performing the actual encoding and decoding.
+--
+-- Instances of `Format` are required to be instances of `Show` and so
+-- that the encoded format can be easily printed. They are also
+-- required to be instances of `IsString` so that they can be easily
+-- represented in Haskell source using the @OverloadedStrings@
+-- extension.  However, be careful when using this due to the fact
+-- that invalid encodings can lead to runtime errors.
+--
 class (IsString fmt, Show fmt, Encodable fmt) => Format fmt where
+
+  -- | Encode binary data into the format. The return type gurantees
+  -- that any binary data can indeed be encoded into a format.
   encodeByteString :: ByteString -> fmt
+
+  -- | Decode the format to its associated binary
+  -- representation. Notice that this function always succeeds: we
+  -- assume that elements of the type `fmt` are valid encodings and
+  -- hence the return type is `ByteString` instead of @`Maybe`
+  -- ByteString@.
   decodeFormat     :: fmt        -> ByteString
 
 -- | Bytestring itself is an encoding format (namely binary format).
@@ -89,17 +128,3 @@
   {-# INLINE encodeByteString #-}
   decodeFormat     = id
   {-# INLINE decodeFormat     #-}
-
-
--- | Encode in a given format.
-encode :: (Encodable a, Format fmt) => a -> fmt
-encode = encodeByteString . toByteString
-
--- | Decode from a given format. It results in Nothing if there is a
--- parse error.
-decode :: (Format fmt, Encodable a) => fmt -> Maybe a
-decode = fromByteString . decodeFormat
-
--- | The unsafe version of `decode`.
-unsafeDecode :: (Format fmt, Encodable a) => fmt -> a
-unsafeDecode = unsafeFromByteString . decodeFormat
diff --git a/Raaz/Core/Memory.hs b/Raaz/Core/Memory.hs
--- a/Raaz/Core/Memory.hs
+++ b/Raaz/Core/Memory.hs
@@ -13,21 +13,22 @@
 
 module Raaz.Core.Memory
        (
-       -- * The Memory subsystem
+       -- * The Memory subsystem.
        -- $memorysubsystem$
-
-       -- ** Memory monads
-         MonadMemory(..)
-       , MT, execute, getMemory, liftSubMT
-       , MemoryM, runMT
-       -- *** Some low level functions.
+       -- ** Memory elements
+         Memory(..), copyMemory
+       -- *** A basic memory cell.
+       , MemoryCell
+       -- *** Initialising and extracting.
+       , Initialisable(..), Extractable(..)
+       -- *** Actions on memory elements.
+       , MT,  execute, getMemory, liftSubMT, modify
+       -- **** Some low level `MT` actions.
        , getMemoryPointer, withPointer
        , allocate
-       -- ** Memory elements.
-       , Memory(..), copyMemory
-       , Initialisable(..), Extractable(..), modify
-       -- *** Some basic memory elements.
-       , MemoryCell
+       -- ** Generic memory monads.
+       , MonadMemory(..)
+       , MemoryM, runMT
        -- ** Memory allocation
        ,  Alloc, pointerAlloc
        ) where
@@ -44,10 +45,33 @@
 --
 -- The memory subsystem consists of two main components.
 --
--- 1. Abstract elements captured by the `Memory` type class.
+-- [The `Memory` type class] A memory element is some type that holds
+-- an internal buffer inside it. The operations that are allowed on
+-- the element is controlled by the associated type. Certain memory
+-- element have a default way in which it can be initialised by values
+-- of type @a@. An instance declaration @`Initialisable` mem a@ for
+-- the memory type @mem@ is done in such case. Similary, if values of
+-- type @b@ can be extracted out of a memory element @mem@, we can
+-- indicate it with an instance of @`Extractable` mem a@.
 --
--- 2. Abstract memory actions captured by the type class `MonadMemory`.
+-- [The `Alloc` type and memory allocation] The most important and
+-- often error prone operation while using low level memory buffers is
+-- its allocation. The `Alloc` types gives the allocation strategy for
+-- a memory element keeping track of the necessary book keeping
+-- involved in it.  The `Alloc` type is an instance of `Applicative`
+-- which helps build the allocation strategy for a compound memory
+-- type from its components in a modular fashion without any explicit
+-- size calculation or offset computation.
 --
+-- [The `MonadMemory` class] Instances of these classes are actions
+-- that use some kind of memory elements, i.e. instances of the class
+-- `Memory`, inside it. Any such monad can either be run using the
+-- combinator `securely` or the combinator `insecurely`. If one use
+-- the combinator `securely`, then all allocations done during the run
+-- is from a locked memory pool which is wiped clean before
+-- de-allocation. The types `MT` and `MemoryM` are two instances that
+-- we expose from this library.
+--
 
 -- | A class that captures monads that use an internal memory element.
 --
@@ -338,7 +362,7 @@
 -- essentially a limitation of the bracket which is used internally.
 withSecureMemory :: Memory m => (m -> IO a) -> IO a
 withSecureMemory = withSM memoryAlloc
-  where withSM :: Memory m => Alloc m -> (m -> IO a) -> IO a
+  where -- withSM :: Memory m => Alloc m -> (m -> IO a) -> IO a
         withSM alctr action = allocaSecure sz $ action . getM
           where sz     = getSum $ twistMonoidValue alctr
                 getM   = computeField $ twistFunctorValue alctr
@@ -356,7 +380,14 @@
 withCell fp  = execute $ fp . unMemoryCell
 {-# INLINE withCell #-}
 
--- | Apply the given function to the value in the cell.
+-- | Apply the given function to the value in the cell. For a function @f :: b -> a@,
+-- the action @modify f@ first extracts a value of type @b@ from the
+-- memory element, applies @f@ to it and puts the result back into the
+-- memory.
+--
+-- > modify f = do b          <- extract
+-- >               initialise $  f b
+--
 modify :: (Initialisable m a, Extractable m b) =>  (b -> a) -> MT m ()
 modify f = extract >>= initialise . f
 
diff --git a/Raaz/Core/Primitives.hs b/Raaz/Core/Primitives.hs
--- a/Raaz/Core/Primitives.hs
+++ b/Raaz/Core/Primitives.hs
@@ -91,5 +91,5 @@
 -- | The expression @n `blocksOf` p@ specifies the message lengths in
 -- units of the block length of the primitive @p@. This expression is
 -- sometimes required to make the type checker happy.
-blocksOf :: Primitive p =>  Int -> p -> BLOCKS p
+blocksOf :: Int -> p -> BLOCKS p
 blocksOf n _ = BLOCKS n
diff --git a/Raaz/Core/Types.hs b/Raaz/Core/Types.hs
--- a/Raaz/Core/Types.hs
+++ b/Raaz/Core/Types.hs
@@ -3,38 +3,16 @@
 -- use the type safety of Haskell to catch some common bugs at compile
 -- time. As of now we address three kinds of errors
 --
--- [Timing safe equality:] We need a consistent way to build timing
---     safe equality comparisons. The type class `Equality` plays the
---     role of `Eq` for us. The comparison result is of type `Result`
---     and not `Bool` so as to avoid timing attacks due to
---     short-circuting of the AND-operation. Instance for basic word
---     types are given here and users are expected to build the
---     `Equality` instances of compound types by combine the results
---     of comparisons using the monoid instance of `Result`. We also
---     give timing safe equality comparisons for `Vector` types using
---     the `eqVector` and `oftenCorrectEqVector` functions.  Once an
---     instance for `Equality` is defined for a cryptographically
---     sensitive data type, we define the `Eq` for it indirectly using
---     the `Equality` instance and the operation `===`.
---
--- [Endianness aware types:] When serialising data, we need to be
---     careful about the endianness of the machine. Instance of the
---     `EndianStore` type class correctly stores and loads data from
---     memory, irrespective of the endianness of the machine. We
---     define endian aware variants of `Word32` and `Word64` here and
---     expect other cryptographic types to use such endian explicit
---     types in their definition.
---
--- [Pointer and Length units:] We have the generic pointer type
---     `Pointer` and distinguish between different length units at the
---     type level. This helps in to avoid a lot of length conversion
---     errors.
+
 module Raaz.Core.Types
        ( -- * Timing safe equality checking.
+         -- $timingSafeEquality$
          module Raaz.Core.Types.Equality
          -- * Endianess aware types.
+         -- $endianness$
        , module Raaz.Core.Types.Endian
          -- * The pointer type and Length offsets.
+         -- $typesafeLength$
        , module Raaz.Core.Types.Pointer
          -- * Tuples with length encoded in their types.
        , module Raaz.Core.Types.Tuple
@@ -46,5 +24,54 @@
 import Raaz.Core.Types.Endian
 import Raaz.Core.Types.Pointer
 import Raaz.Core.Types.Tuple
+
+-- $timingSafeEquality$
+--
+-- We need a consistent way to build timing safe equality
+-- comparisons. The type class `Equality` plays the role of `Eq` for
+-- us. The comparison result is of type `Result` and not `Bool` so as
+-- to avoid timing attacks due to short-circuting of the
+-- AND-operation.
+--
+-- The `Result` type is an opaque type to avoid the user from
+-- compromising the equality comparisons by pattern matching on it. To
+-- combine the results of two comparisons one can use the monoid
+-- instance of `Result`, i.e. if @r1@ and @r2@ are the results of two
+-- comparisons then @r1 `mappend` r2@ essentially takes the AND of
+-- these results but this and is not short-circuited and is timing
+-- independent.
+--
+-- Instance for basic word types are provided by the library and users
+-- are expected to build the `Equality` instances of compound types by
+-- combine the results of comparisons using the monoid instance of
+-- `Result`. We also give timing safe equality comparisons for
+-- `Vector` types using the `eqVector` and `oftenCorrectEqVector`
+-- functions.  Once an instance for `Equality` is defined for a
+-- cryptographically sensitive data type, we define the `Eq` for it
+-- indirectly using the `Equality` instance and the operation `===`.
+
+
+-- $endianness$
+--
+-- Cryptographic primitives often consider their input as an array of
+-- words of a particular endianness. Endianness is only relevant when
+-- the data is being read or written to. It makes sense therefore to
+-- keep track of the endianness in the type and perform necessary
+-- transformations depending on the endianness of the
+-- machine. Such types are captured by the type class `EndianStore`. They
+-- support the `load` and `store` combinators that automatically compensates
+-- for the endianness of the machine.
+--
+-- This libraray exposes endian aware variants of `Word32` and
+-- `Word64` here and expect other cryptographic types to use such
+-- endian explicit types in their definition.
+
+
+-- $typesafeLength$
+--
+-- We have the generic pointer type `Pointer` and distinguish between
+-- different length units at the type level. This helps in to avoid a
+-- lot of length conversion errors.
+
 
 {-# ANN module "HLint: ignore Use import/export shortcut" #-}
diff --git a/Raaz/Core/Types/Endian.hs b/Raaz/Core/Types/Endian.hs
--- a/Raaz/Core/Types/Endian.hs
+++ b/Raaz/Core/Types/Endian.hs
@@ -86,7 +86,7 @@
               -> IO w
 {-# INLINE loadFromIndex #-}
 loadFromIndex cptr index = loadP undefined
-   where loadP ::  (EndianStore w, Storable w) => w -> IO w
+   where loadP ::  EndianStore w => w -> IO w
          loadP w = loadFrom cptr offset
            where offset = toEnum index * byteSize w
 
diff --git a/Raaz/Core/Types/Equality.hs b/Raaz/Core/Types/Equality.hs
--- a/Raaz/Core/Types/Equality.hs
+++ b/Raaz/Core/Types/Equality.hs
@@ -5,7 +5,7 @@
 module Raaz.Core.Types.Equality
        ( Equality(..), (===)
        -- ** The result of comparion.
-       , Result, isSuccessful
+       , Result
        -- ** Comparing vectors.
        , oftenCorrectEqVector, eqVector
        ) where
@@ -22,17 +22,13 @@
 import           Data.Vector.Unboxed         ( MVector(..), Vector, Unbox )
 import           Data.Word
 
--- | An opaque type that captures the result of a comparison. The monoid
--- instances allows us to combine the results of two equality comparisons
--- in a timing independent manner. We have the following properties.
---
--- > isSuccessful mempty            = True
--- > isSuccessful (r `mappend` s)   = isSuccessful r && isSuccessful s
---
+-- | The result of a comparison. This is an opaque type and the monoid instance essentially takes
+-- AND of two comparisons in a timing safe way.
 newtype Result =  Result { unResult :: Word }
 
 -- | Checks whether a given equality comparison is successful.
 isSuccessful :: Result -> Bool
+{-# INLINE isSuccessful #-}
 isSuccessful = (==0) . unResult
 
 instance Monoid Result where
@@ -99,7 +95,7 @@
 
 
 
--- | In a cryptographic setting, naive equality checking
+-- | In a cryptographic setting, naive equality checking is
 -- dangerous. This class is the timing safe way of doing equality
 -- checking. The recommended method of defining equality checking for
 -- cryptographically sensitive data is as follows.
@@ -155,6 +151,76 @@
 #else
   eq w1 w2 = Result $ fromIntegral $ xor w1 w2
 #endif
+
+-- Now comes the boring instances for tuples.
+
+instance ( Equality a
+         , Equality b
+         ) => Equality (a , b) where
+  eq (a1,a2) (b1,b2) = eq a1 b1 `mappend` eq a2 b2
+
+
+instance ( Equality a
+         , Equality b
+         , Equality c
+         ) => Equality (a , b, c) where
+  eq (a1,a2,a3) (b1,b2,b3) = eq a1 b1 `mappend`
+                             eq a2 b2 `mappend`
+                             eq a3 b3
+
+
+instance ( Equality a
+         , Equality b
+         , Equality c
+         , Equality d
+         ) => Equality (a , b, c, d) where
+  eq (a1,a2,a3,a4) (b1,b2,b3,b4) = eq a1 b1 `mappend`
+                                   eq a2 b2 `mappend`
+                                   eq a3 b3 `mappend`
+                                   eq a4 b4
+
+instance ( Equality a
+         , Equality b
+         , Equality c
+         , Equality d
+         , Equality e
+         ) => Equality (a , b, c, d, e) where
+  eq (a1,a2,a3,a4,a5) (b1,b2,b3,b4,b5) = eq a1 b1 `mappend`
+                                         eq a2 b2 `mappend`
+                                         eq a3 b3 `mappend`
+                                         eq a4 b4 `mappend`
+                                         eq a5 b5
+
+
+instance ( Equality a
+         , Equality b
+         , Equality c
+         , Equality d
+         , Equality e
+         , Equality f
+         ) => Equality (a , b, c, d, e, f) where
+  eq (a1,a2,a3,a4,a5,a6) (b1,b2,b3,b4,b5,b6) = eq a1 b1 `mappend`
+                                               eq a2 b2 `mappend`
+                                               eq a3 b3 `mappend`
+                                               eq a4 b4 `mappend`
+                                               eq a5 b5 `mappend`
+                                               eq a6 b6
+
+instance ( Equality a
+         , Equality b
+         , Equality c
+         , Equality d
+         , Equality e
+         , Equality f
+         , Equality g
+         ) => Equality (a , b, c, d, e, f, g) where
+  eq (a1,a2,a3,a4,a5,a6,a7) (b1,b2,b3,b4,b5,b6,b7) = eq a1 b1 `mappend`
+                                                     eq a2 b2 `mappend`
+                                                     eq a3 b3 `mappend`
+                                                     eq a4 b4 `mappend`
+                                                     eq a5 b5 `mappend`
+                                                     eq a6 b6 `mappend`
+                                                     eq a7 b7
 
 
 -- | Timing independent equality checks for vector of values. /Do not/
diff --git a/Raaz/Hash/Internal/HMAC.hs b/Raaz/Hash/Internal/HMAC.hs
--- a/Raaz/Hash/Internal/HMAC.hs
+++ b/Raaz/Hash/Internal/HMAC.hs
@@ -80,13 +80,13 @@
         theHash     :: HMACKey h -> h
         theHash  _  = undefined
 
-instance (Hash h, Recommendation h, Encodable h) => EndianStore (HMACKey h) where
+instance (Hash h, Recommendation h) => EndianStore (HMACKey h) where
   store = poke . castPtr
   load  = peek . castPtr
 
-instance (Hash h, Recommendation h, Encodable h) => Random (HMACKey h)
+instance (Hash h, Recommendation h) => Random (HMACKey h)
 
-instance (Hash h, Recommendation h, Encodable h) => Encodable (HMACKey h)
+instance (Hash h, Recommendation h) => Encodable (HMACKey h)
 
 -- | Base16 representation of the string.
 instance IsString (HMACKey h) where
diff --git a/raaz.cabal b/raaz.cabal
--- a/raaz.cabal
+++ b/raaz.cabal
@@ -1,5 +1,5 @@
 name:    raaz
-version: 0.0.1
+version: 0.0.2
 
 synopsis: The raaz cryptographic library.
 
@@ -103,6 +103,7 @@
   other-modules: Raaz.Core.Constants
                , Raaz.Core.Encode.Internal
                , Raaz.Core.Encode.Base16
+               , Raaz.Core.Encode.Base64
                , Raaz.Core.Util.ByteString
                , Raaz.Core.Types.Pointer
                , Raaz.Core.Types.Tuple
@@ -173,7 +174,7 @@
   hs-source-dirs: bin
   main-is: checksum.lhs
   build-depends: base     >= 4.5 && < 5.0
-               , raaz     == 0.0.1
+               , raaz     == 0.0.2
 
 test-Suite spec
   type: exitcode-stdio-1.0
@@ -183,11 +184,13 @@
   other-modules: Common
                , Common.Cipher
                , Common.Hash
+               , Common.Imports
                , Common.Instances
                , Common.Utils
                , Raaz.Cipher.AESSpec
-               , Raaz.Core.Encode.Base16Spec
+               , Raaz.Core.EncodeSpec
                , Raaz.Core.MemorySpec
+               , Raaz.Core.SystemPRGSpec
                , Raaz.Core.Types.WordSpec
                , Raaz.Core.Util.ByteStringSpec
                , Raaz.Hash.Sha1Spec
@@ -204,7 +207,7 @@
                , QuickCheck                     >= 2.4
                , hspec
                , transformers
-               , raaz                           == 0.0.1
+               , raaz                           == 0.0.2
                , vector
 
 benchmark blaze-vs-write
diff --git a/spec/Common/Imports.hs b/spec/Common/Imports.hs
new file mode 100644
--- /dev/null
+++ b/spec/Common/Imports.hs
@@ -0,0 +1,19 @@
+-- Common imports.
+module Common.Imports( module E ) where
+import Control.Applicative     as E
+import Data.ByteString         as E (ByteString, pack)
+import Data.ByteString.Char8        () -- import IsString instance for
+                                       -- byte string.
+import Data.String             as E
+import Data.Monoid             as E
+import Data.Word               as E
+import Foreign.Storable        as E (Storable(..))
+import Test.Hspec              as E
+import Test.Hspec.QuickCheck   as E
+import Test.QuickCheck         as E
+import Test.QuickCheck.Monadic as E
+
+import Raaz.Core               as E hiding ((===), Result)
+import Raaz.Hash               as E
+import Raaz.Cipher             as E
+import Raaz.Cipher.Internal    as E ( Cipher, unsafeEncrypt, unsafeDecrypt )
diff --git a/spec/Common/Instances.hs b/spec/Common/Instances.hs
--- a/spec/Common/Instances.hs
+++ b/spec/Common/Instances.hs
@@ -51,6 +51,9 @@
 instance Arbitrary Base16 where
   arbitrary =  (encodeByteString . pack) <$> listOf arbitrary
 
+instance Arbitrary Base64 where
+  arbitrary =  (encodeByteString . pack) <$> listOf arbitrary
+
 ------------------ Arbitrary instances for Keys ---------------
 
 instance Arbitrary AES.KEY128 where
diff --git a/spec/Raaz/Core/Encode/Base16Spec.hs b/spec/Raaz/Core/Encode/Base16Spec.hs
deleted file mode 100644
--- a/spec/Raaz/Core/Encode/Base16Spec.hs
+++ /dev/null
@@ -1,13 +0,0 @@
-{-# OPTIONS_GHC -fno-warn-orphans #-}
-{-# LANGUAGE ScopedTypeVariables #-}
-{-# LANGUAGE OverloadedStrings   #-}
-module Raaz.Core.Encode.Base16Spec where
-
-import Common
-
-spec :: Spec
-spec = do
-  prop "unsafeFromByteString . toByteString = id" $ \ (x :: Base16) ->
-    unsafeFromByteString (toByteString x) `shouldBe` x
-  prop "correctly encodes a 64-bit big endian word." $ \ (w :: Word64) ->
-    (read $ "0x" ++ showBase16 (bigEndian w))  == w
diff --git a/spec/Raaz/Core/EncodeSpec.hs b/spec/Raaz/Core/EncodeSpec.hs
new file mode 100644
--- /dev/null
+++ b/spec/Raaz/Core/EncodeSpec.hs
@@ -0,0 +1,41 @@
+{-# OPTIONS_GHC -fno-warn-orphans #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE OverloadedStrings   #-}
+module Raaz.Core.EncodeSpec where
+
+import           Common
+import qualified Data.ByteString as B
+
+shouldBeAMultipleOf :: Int -> Int -> Bool
+shouldBeAMultipleOf m x = m `rem` x == 0
+
+shouldEncodeTo :: (Format fmt, Eq fmt) => ByteString -> fmt -> Spec
+shouldEncodeTo bs e = it msg $ encodeByteString bs `shouldBe` e
+  where msg = show bs ++ " should encode to " ++ show e
+
+spec :: Spec
+spec = do
+  describe "Base16" $ do
+    prop "encoded string is always of even length" $ \ (x :: Base16) ->
+      B.length (toByteString x) `shouldBeAMultipleOf` 2
+
+    prop "unsafeFromByteString . toByteString = id" $ \ (x :: Base16) ->
+      unsafeFromByteString (toByteString x) `shouldBe` x
+
+    prop "correctly encodes a 64-bit big endian word." $ \ (w :: Word64) ->
+      (read $ "0x" ++ showBase16 (bigEndian w))  == w
+
+
+  describe "Base64" $ do
+    prop "encoded string is always divisible by 4" $ \ (x :: Base64) ->
+      B.length (toByteString x) `shouldBeAMultipleOf` 4
+
+    prop "unsafeFromByteString . toByteString = id" $ \ (x :: Base16) ->
+      unsafeFromByteString (toByteString x) `shouldBe` x
+
+    describe "examples" $ do
+      "pleasure." `shouldEncodeTo` ("cGxlYXN1cmUu" :: Base64)
+      "leasure."  `shouldEncodeTo` ("bGVhc3VyZS4=" :: Base64)
+      "easure."   `shouldEncodeTo` ("ZWFzdXJlLg==" :: Base64)
+      "asure." 	  `shouldEncodeTo` ("YXN1cmUu"     :: Base64)
+      "sure." 	  `shouldEncodeTo` ("c3VyZS4="     :: Base64)
diff --git a/spec/Raaz/Core/SystemPRGSpec.hs b/spec/Raaz/Core/SystemPRGSpec.hs
new file mode 100644
--- /dev/null
+++ b/spec/Raaz/Core/SystemPRGSpec.hs
@@ -0,0 +1,12 @@
+module Raaz.Core.SystemPRGSpec where
+
+import Common
+
+spec :: Spec
+spec = it "system prg should return different words on distinct calls"
+       $ compareWords `shouldReturn` False
+  where randomWord :: SystemPRG -> IO Word
+        randomWord  = random
+        compareWords = do systemPRG <- newPRG ()
+                          (==) <$> randomWord systemPRG
+                               <*> randomWord systemPRG
