diff --git a/NaCl.cabal b/NaCl.cabal
--- a/NaCl.cabal
+++ b/NaCl.cabal
@@ -4,11 +4,11 @@
 --
 -- see: https://github.com/sol/hpack
 --
--- hash: 9b302cb2a6e7e7082c3f24456d474ba10bf82a95d7943fac58e002b7ad793a28
+-- hash: 03e840884f33f5935cba7897a47476ae30b4577c0d482ca7f4d75cdad144e7c1
 
 name:           NaCl
-version:        0.0.1.0
-synopsis:       Easy-and-safe-to-use library for cryptography
+version:        0.0.2.0
+synopsis:       Easy-and-safe-to-use high-level Haskell bindings to NaCl
 description:    This library uses <https://libsodium.org Sodium> under the hood,
                 but only exposes the primitives that are part of the “classic” NaCl
                 interface. We believe, it is better to be paranoid than sorry.
@@ -18,9 +18,23 @@
                 = Secret-key cryptography
                 .
                   * Authenticated encryption: "Crypto.Secretbox"
+                .
+                = Additional primitives
+                .
+                Sodium is more portable, but some people prefer to stick to NaCl.
+                We agree that it is better to be paranoid than sorry.
+                That is why, even though this library uses
+                Sodium under the hood, it only exposes the primitives that
+                are part of the “classic” NaCl interface.
+                .
+                Sodium provides useful algorithms, that are not part of NaCl,
+                for example key derivation or random number generation.
+                If you need them too (you probably do), you should use
+                <https://hackage.haskell.org/package/crypto-sodium crypto-sodium>
+                instead.
 category:       Cryptography
-homepage:       https://github.com/serokell/haskell-nacl#readme
-bug-reports:    https://github.com/serokell/haskell-nacl/issues
+homepage:       https://github.com/serokell/haskell-crypto#readme
+bug-reports:    https://github.com/serokell/haskell-crypto/issues
 author:         Kirill Elagin <kirelagin@serokell.io>
 maintainer:     Kirill Elagin <kirelagin@serokell.io>
 copyright:      2020 Serokell
@@ -33,14 +47,12 @@
 
 source-repository head
   type: git
-  location: https://github.com/serokell/haskell-nacl
+  location: https://github.com/serokell/haskell-crypto
 
 library
   exposed-modules:
       Crypto.Secretbox
       Crypto.Secretbox.Internal
-      Data.ByteArray.Sized
-      Data.ByteArray.Sized.Internal
   other-modules:
       Paths_NaCl
   hs-source-dirs:
@@ -52,9 +64,8 @@
     , bytestring >=0.9 && <0.11
     , gdp >=0.0.0.1 && <0.1
     , libsodium >=1.0 && <2
-    , memory >=0.1 && <0.16
+    , memory >=0.14.15 && <0.16
     , safe-exceptions >=0.1 && <0.2
-    , text >=0.7 && <1.3
   default-language: Haskell2010
 
 test-suite test
@@ -79,5 +90,4 @@
     , tasty
     , tasty-hedgehog
     , tasty-hunit
-    , text >=0.7 && <1.3
   default-language: Haskell2010
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -1,49 +1,19 @@
-# NaCl (`haskell-NaCl`)
+# NaCl
 
-Easy-and-safe-to-use library for cryptography.
+Easy-and-safe-to-use high-level Haskell bindings to NaCl.
 
 **Note: this package is experimental and WIP.**
 
-Cryptography is hard to do right and you should never try to implement it
-on your own, even if you have access to safe and secure cryptographic
-primitives. Luckily, D. J. Bernstein created [NaCl].
-
-NaCl was designed specifically to make it hard to use it incorrectly and
-thus save your from a disaster. It exposes high-level cryptographic
-algorithms with underlying implementations chosen for you, so you do not
-get flexibility, but you get security, which is more important.
-
-[Sodium] is a reimplementation of NaCl with the goal to make it more
-portable across different platforms. With time, it started providing
-not only the same interface as NaCl, the developers of Sodium decided
-to add new primitives too.
-
-Sodium is more portable, but some people are afraid of using it,
-and prefer to stick to NaCl. We agree that it is better to be
-paranoid than sorry. That is why, even though this library uses
-Sodium under the hood, it only exposes the primitives that
-are part of the “classic” NaCl interface.
-
-[NaCl]: https://nacl.cr.yp.to/
-[Sodium]: https://libsodium.org
-
-
-## Why not?
-
-
 ## Use
 
+### Get it
 
-## Contributing
+Add [`NaCl`][hackage:NaCl] to the dependencies of your package.
 
-If you encounter any issues when using this library or have improvement ideas,
-please open report in issue on GitHub. You are also very welcome to submit
-pull request, if you feel like doing so.
+### Documentation
 
+All documentation exists is in the form of Haddock comments, you can
+find them in the source code or [browse on Hackage][hackage:NaCl].
 
-## License
 
-[MPL-2.0] © [Serokell]
-
-[MPL-2.0]: https://spdx.org/licenses/MPL-2.0.html
-[Serokell]: https://serokell.io/
+[hackage:NaCl]: https://hackage.haskell.org/package/NaCl
diff --git a/lib/Crypto/Secretbox.hs b/lib/Crypto/Secretbox.hs
--- a/lib/Crypto/Secretbox.hs
+++ b/lib/Crypto/Secretbox.hs
@@ -2,6 +2,18 @@
 --
 -- SPDX-License-Identifier: MPL-2.0
 
+-- | Symmetric authenticated encryption.
+--
+-- It is best to import this module qualified:
+--
+-- @
+-- import qualified Crypto.Secretbox as Secretbox
+--
+-- encrypted = Secretbox.'create' key nonce message
+-- decrypted = Secretbox.'open' key nonce encrypted
+-- @
+--
+-- This is @crypto_secretbox_*@ from NaCl.
 module Crypto.Secretbox
   ( Key
   , toKey
@@ -23,31 +35,78 @@
 
 -- | Encrypt a message.
 --
--- Note: This function is similar to the C++ API of NaCl.
--- That is, unlike @crypto_secretbox@ from the C API of NaCl,
--- it does not require any special padding.
+-- @
+-- encrypted = Secretbox.create key nonce message
+-- @
+--
+-- *   @key@ is the secret key used for encryption. There are two typical ways
+--     of creating it:
+--
+--     1. /Derive from a password/. If you want to protect a message with a password,
+--     you must use a
+--     <https://en.wikipedia.org/wiki/Key_derivation_function key derivation function>
+--     to turn this password into an encryption key.
+--     NaCl does not provide a key derivation function, however
+--     <https://hackage.haskell.org/package/crypto-sodium crypto-sodium> does.
+--
+--     2. /Generate a random one/. This can be useful in certain situations when
+--     you want to have an intermediate key that you will encrypt and share
+--     later. NaCl does not provide a cryptographically secure pseudo random
+--     generator, however
+--     <https://hackage.haskell.org/package/crypto-sodium crypto-sodium> does.
+--
+-- *   @nonce@ is an extra noise that ensures that if you encrypt the same
+--     message with the same key multiple times, you will get different ciphertexts,
+--     which is required for
+--     <https://en.wikipedia.org/wiki/Semantic_security semantic security>.
+--     There are two standard ways of getting it:
+--
+--     1. /Use a counter/. In this case you keep a counter of encrypted messages,
+--     which means that the nonce will be new for each new message.
+--
+--     2. /Random/. You generate a random nonce every time you encrypt a message.
+--     Since the nonce is large enough, the chances of you using the same
+--     nonce twice are negligible.
+--
+--     <https://hackage.haskell.org/package/crypto-sodium crypto-sodium> has
+--     useful helpers for both options.
+--
+-- *   @message@ is the data you are encrypting.
+--
+-- This function adds authentication data, so if anyone modifies the cyphertext,
+-- @open@ will refuse to decrypt it.
 create
-  ::  ( ByteArrayAccess key, ByteArrayAccess nonce
-      , ByteArrayAccess pt, ByteArray ct
+  ::  ( ByteArrayAccess keyBytes, ByteArrayAccess nonceBytes
+      , ByteArrayAccess ptBytes, ByteArray ctBytes
       )
-  => Key key  -- ^ Secret key
-  -> Nonce nonce  -- ^ Nonce
-  -> pt -- ^ Plaintext message
-  -> ct
-create key nonce msg = unsafeDupablePerformIO $ I.create key nonce msg
+  => Key keyBytes  -- ^ Secret key
+  -> Nonce nonceBytes  -- ^ Nonce
+  -> ptBytes -- ^ Plaintext message
+  -> ctBytes
+create key nonce msg =
+  -- This IO is safe, because it is pure.
+  unsafeDupablePerformIO $ I.create key nonce msg
 
 
 -- | Decrypt a message.
 --
--- Note: This function is similar to the C++ API of NaCl.
--- That is, unlike @crypto_secretbox_open@ from the C API of NaCl,
--- it does not require any special padding.
+-- @
+-- decrypted = Secretbox.open key nonce encrypted
+-- @
+--
+-- * @key@ and @nonce@ are the same that were used for encryption.
+-- * @encrypted@ is the output of 'create'.
+--
+-- This function will return @Nothing@ if the encrypted message was tampered
+-- with after it was encrypted.
 open
-  ::  ( ByteArrayAccess key, ByteArrayAccess nonce
-      , ByteArray pt, ByteArrayAccess ct
+  ::  ( ByteArrayAccess keyBytes, ByteArrayAccess nonceBytes
+      , ByteArray ptBytes, ByteArrayAccess ctBytes
       )
-  => Key key  -- ^ Secret key
-  -> Nonce nonce  -- ^ Nonce
-  -> ct -- ^ Cyphertext
-  -> Maybe pt
-open key nonce ct = unsafeDupablePerformIO $ I.open key nonce ct
+  => Key keyBytes  -- ^ Secret key
+  -> Nonce nonceBytes  -- ^ Nonce
+  -> ctBytes -- ^ Encrypted message (cyphertext)
+  -> Maybe ptBytes
+open key nonce ct =
+  -- This IO is safe, because it is pure.
+  unsafeDupablePerformIO $ I.open key nonce ct
diff --git a/lib/Crypto/Secretbox/Internal.hs b/lib/Crypto/Secretbox/Internal.hs
--- a/lib/Crypto/Secretbox/Internal.hs
+++ b/lib/Crypto/Secretbox/Internal.hs
@@ -2,6 +2,7 @@
 --
 -- SPDX-License-Identifier: MPL-2.0
 
+-- | Internals of @crypto_secretbox@.
 module Crypto.Secretbox.Internal
   ( Key
   , toKey
@@ -19,7 +20,7 @@
 
 import qualified Libsodium as Na
 
-import Data.ByteArray.Sized (OfLength, hasRightLength)
+import Data.ByteArray.Sized (SizedByteArray, sizedByteArray)
 
 
 -- | Encryption key that can be used for Secretbox.
@@ -27,28 +28,28 @@
 -- This type is parametrised by the actual data type that contains
 -- bytes. This can be, for example, a @ByteString@, but, since this
 -- is a secret key, it is better to use @ScrubbedBytes@.
-type Key a = OfLength Na.CRYPTO_SECRETBOX_KEYBYTES a
+type Key a = SizedByteArray Na.CRYPTO_SECRETBOX_KEYBYTES a
 
 -- | Make a 'Key' from an arbitrary byte array.
 --
 -- This function returns @Just@ if and only if the byte array has
 -- the right length to be used as a key with a Secretbox.
 toKey :: ByteArrayAccess ba => ba -> Maybe (Key ba)
-toKey = hasRightLength
+toKey = sizedByteArray
 
 
 -- | Nonce that can be used for Secretbox.
 --
 -- This type is parametrised by the actual data type that contains
 -- bytes. This can be, for example, a @ByteString@.
-type Nonce a = OfLength Na.CRYPTO_SECRETBOX_NONCEBYTES a
+type Nonce a = SizedByteArray Na.CRYPTO_SECRETBOX_NONCEBYTES a
 
 -- | Make a 'Nonce' from an arbitrary byte array.
 --
 -- This function returns @Just@ if and only if the byte array has
 -- the right length to be used as a nonce with a Secretbox.
 toNonce :: ByteArrayAccess ba => ba -> Maybe (Nonce ba)
-toNonce = hasRightLength
+toNonce = sizedByteArray
 
 
 -- | Encrypt a message.
diff --git a/lib/Data/ByteArray/Sized.hs b/lib/Data/ByteArray/Sized.hs
deleted file mode 100644
--- a/lib/Data/ByteArray/Sized.hs
+++ /dev/null
@@ -1,10 +0,0 @@
--- SPDX-FileCopyrightText: 2020 Serokell
---
--- SPDX-License-Identifier: MPL-2.0
-
--- | 'ByteArray' with length known at compile time.
-module Data.ByteArray.Sized
-  ( module M
-  ) where
-
-import Data.ByteArray.Sized.Internal as M (OfLength, hasRightLength)
diff --git a/lib/Data/ByteArray/Sized/Internal.hs b/lib/Data/ByteArray/Sized/Internal.hs
deleted file mode 100644
--- a/lib/Data/ByteArray/Sized/Internal.hs
+++ /dev/null
@@ -1,63 +0,0 @@
--- SPDX-FileCopyrightText: 2020 Serokell
---
--- SPDX-License-Identifier: MPL-2.0
-
--- | 'ByteArray' with length known at compile time. Internal module.
-module Data.ByteArray.Sized.Internal
-  ( OfLength (..)
-  , hasRightLength
-
-  , allocRet
-  , alloc
-  ) where
-
-import Prelude hiding (length)
-
-import Data.Bifunctor (second)
-import Data.Proxy (Proxy (Proxy))
-import Data.The (The)
-import Foreign.Ptr (Ptr)
-import GHC.TypeLits (KnownNat, Nat, natVal)
-
-import Data.ByteArray (ByteArray, ByteArrayAccess, length)
-
-import qualified Data.ByteArray
-
-
--- Type of byte arrays that have length @l@.
-newtype OfLength (l :: Nat) ba = OfLength ba
-  deriving (ByteArrayAccess, Eq, Monoid, Ord, Semigroup)
-
-instance The (OfLength l ba) ba
-
-
--- | Check that the byte array has the given length.
-hasRightLength
-  :: forall ba n. (ByteArrayAccess ba, KnownNat n)
-  => ba
-  -> Maybe (OfLength n ba)
-hasRightLength ba
-  | fromIntegral (length ba) == natVal (Proxy :: Proxy n) = Just $ OfLength ba
-  | otherwise = Nothing
-
--- | Allocate a new byte array of the given length, and perform the given operation.
---
--- This is the same as 'Data.ByteArray.allocRet'.
-allocRet
-  :: forall ba n p a. (ByteArray ba, KnownNat n)
-  => (Ptr p -> IO a)
-  -> IO (a, OfLength n ba)
-allocRet
-  = fmap (second OfLength)
-  . Data.ByteArray.allocRet (fromIntegral $ natVal (Proxy :: Proxy n))
-
--- | Allocate a new byte array of the given length, and run the initialiser.
---
--- This is the same as 'Data.ByteArray.alloc'.
-alloc
-  :: forall ba n p. (ByteArray ba, KnownNat n)
-  => (Ptr p -> IO ())
-  -> IO (OfLength n ba)
-alloc
-  = fmap OfLength
-  . Data.ByteArray.alloc (fromIntegral $ natVal (Proxy :: Proxy n))
diff --git a/test/Test.hs b/test/Test.hs
--- a/test/Test.hs
+++ b/test/Test.hs
diff --git a/test/Test/Crypto/Secretbox.hs b/test/Test/Crypto/Secretbox.hs
--- a/test/Test/Crypto/Secretbox.hs
+++ b/test/Test/Crypto/Secretbox.hs
