-
Notifications
You must be signed in to change notification settings - Fork 2
Getting started
Before we get down to anything, we need to discuss some of the underlying ideas behind the library and how it is to be used.
In [1] Bernstein, Lange, and Schwabe argue that simplified, opinionated cryptographic libraries avoid "cryptographic disasters" which occur with more flexible libraries like OpenSSL. The argument is solid, but NaCl is still a somewhat difficult sell since Bernstein uses somewhat less industry selected cryptographic primitives and then happily restricts you to use them. This is a somewhat scary value proposition---tie your hands and trust in NaCl because you almost certainly can't do it better and it'll simplify your life---that should be approached directly.
This library adheres to the core spirit of nacl
, and provides and
recommends using the provided setup below, matching the C
library. Nevertheless, as a cryptography library we also bring along
some extras for convenience, keeping in line with nacl
generally
being cutting-edge cryptographic work. There are a few design
principles here in accordance with these ideas:
-
We expose the names of primitives in modules by default, rather than hiding behind more innocuous names, and we do provide some choice between primitives in some APIs. We always recommend the default primitive selection, however.
-
We attempt to make the API reasonably typesafe to avoid programming error, without difficult to think about or use.
-
The module structure and API is intentionally simple with some overlap, and specifically not overloaded. In general overloading makes APIs harder to understand at a glance and sometimes doesn't mesh well with the idea of being simple to use and understand in the authors opinion.
You're encouraged to just use qualified imports to resolve naming ambiguities, like we see below.
First, import the core primitives of the nacl library. The following import specification will bring the entire library into scope:
import qualified Crypto.NaCl as NaCl
This is (basically) the same as saying:
import qualified Crypto.DH.Curve25519 as Curve25519
import qualified Crypto.Encrypt.Box as Box
import qualified Crypto.Encrypt.SecretBox as SecretBox
import qualified Crypto.Encrypt.Stream as Stream
import qualified Crypto.HMAC.SHA512 as HMACSHA512
import qualified Crypto.Hash.SHA as SHA
import qualified Crypto.MAC.Poly1305 as Poly1305
import qualified Crypto.Sign.Ed25519 as Ed25519
import qualified Crypto.Nonce as Nonce
import qualified System.Crypto.Random as Random
The above imports reflect the default primitives available in the nacl C library. You should always use these as your defaults.
NB: The APIs are intended to be imported in a qualified manner.
The above APIs may be a bit confusing. The mapping between the above modules and their equivalents in the C API is very simple:
C API |
Crypto.NaCl functions |
Haskell module |
---|---|---|
crypto_box |
box /boxOpen
|
Crypto.Encrypt.Box |
crypto_scalarmult |
curve25519 |
Crypto.DH.Curve25519 |
crypto_sign |
sign /verify
|
Crypto.Sign.Ed25519 * |
crypto_secretbox |
secretBox /secretBoxOpen
|
Crypto.Encrypt.SecretBox |
crypto_stream |
streamEncrypt /streamDecrypt
|
Crypto.Encrypt.Stream |
crypto_auth |
auth /authVerify
|
Crypto.HMAC.SHA512 |
crypto_onetimeauth |
oneTimeAuth /oneTimeAuthVerify
|
Crypto.MAC.Poly1305 |
crypto_hash |
hash |
Crypto.Hash.SHA |
Again: these Haskell APIs all reflect the default nacl C primitives.
* Note that the released version of nacl-20110221
does not use
ed25519
but an older Edwards curve. See "Signing gotchas" in the
Field Guide
Lorem ipsum...
[1] Bernstein D, Lange T, Schwabe P. The security impact of a new cryptographic library (2012).