Improve the documentation of the project.

Go over the README file, and improve its contents. Add a Usage/hints section
with some helpful hints on how to use the library in turn. Also while here, make
sure that `rebar doc` works as expected and fix every documentation bug in
the EDoc sections, so it compiles and works. Verify the documentation output
is nice-looking while at it.
This commit is contained in:
Jesper Louis Andersen
2014-12-18 09:28:00 +01:00
parent 2a23a16ed3
commit 50b0058335
4 changed files with 73 additions and 10 deletions
+41 -6
View File
@@ -11,7 +11,7 @@
%%% <p><b>Warning:</b> The cryptographic strength of your implementation is no stronger than
%%% plaintext cryptography unless you take care in using these primitives correctly. Hence,
%%% implementors should use these primitives with that in mind.</p>
%%% <p><b>Note:</b>All functions will fail with a `badarg' error if given incorrect
%%% <p><b>Note:</b> All functions will fail with a `badarg' error if given incorrect
%%% parameters.</p>
%%% @end.
-module(enacl).
@@ -101,8 +101,12 @@
-define(RANDOMBYTES_SIZE, 1024).
-define(RANDOMBYTES_REDUCTIONS, 200).
%% @doc reds/1 counts the number of reductions and scheduler yields for a thunk
%%
%% Count reductions and number of scheduler yields for Fun. Fun is assumed
%% to be one of the above exor variants.
%% @end
-spec reds(fun (() -> any())) -> #{ atom() => any() }.
reds(Fun) ->
Parent = self(),
Pid = spawn(fun() ->
@@ -112,7 +116,8 @@ reds(Fun) ->
Fun(),
R1 = process_info(Self, reductions),
T = timer:now_diff(os:timestamp(), Start),
Parent ! {Self,{T, R1, R0}} end),
Parent ! {Self,#{ time_diff => T, after_reductions => R1, before_reductions => R0}}
end),
receive
{Pid,Result} ->
Result
@@ -122,6 +127,7 @@ reds(Fun) ->
%% -----------------
%% @doc hash/1 hashes data into a cryptographically secure checksum.
%%
%% <p>Given an iodata(), `Data' of any size, run a cryptographically secure hash algorithm to
%% produce a checksum of the data. This can be used to verify the integrity of a data block
%% since the checksum have the properties of cryptographic hashes in general.</p>
@@ -140,6 +146,7 @@ hash(Bin) ->
end.
%% @doc verify_16/2 implements constant time 16-byte binary() verification
%%
%% <p>A subtle problem in cryptographic software are timing attacks where an attacker exploits
%% early exist in string verification if the strings happen to mismatch. This allows the
%% attacker to time how long verification took and thus learn the structure of the desired
@@ -154,6 +161,7 @@ verify_16(X, Y) when is_binary(X), is_binary(Y) -> enacl_nif:crypto_verify_16(X,
verify_16(_, _) -> error(badarg).
%% @doc verify_32/2 implements constant time 32-byte iolist() verification
%%
%% This function works as {@link verify_16/2} but does so on 32 byte strings. Same caveats apply.
%% @end
-spec verify_32(binary(), binary()) -> boolean().
@@ -163,6 +171,7 @@ verify_32(_, _) -> error(badarg).
%% Public Key Crypto
%% ---------------------
%% @doc box_keypair/0 creates a new Public/Secret keypair.
%%
%% Generates and returns a new key pair for the Box encryption scheme. The return value is a
%% map in order to avoid using the public key as a secret key and vice versa.
%% @end.
@@ -172,8 +181,9 @@ box_keypair() ->
#{ public => PK, secret => SK}.
%% @doc box/4 encrypts+authenticates a message to another party.
%% Encrypt a `Msg` to the party identified by public key `PK` using your own secret key `SK` to
%% authenticate yourself. Requires a `Nonce` in addition. Returns the ciphered message.
%%
%% Encrypt a `Msg' to the party identified by public key `PK' using your own secret key `SK' to
%% authenticate yourself. Requires a `Nonce' in addition. Returns the ciphered message.
%% @end
-spec box(Msg, Nonce, PK, SK) -> CipherText
when Msg :: iodata(),
@@ -190,9 +200,11 @@ box(Msg, Nonce, PK, SK) ->
end.
%% @doc box_open/4 decrypts+verifies a message from another party.
%% Decrypt a `CipherText` into a `Msg` given the other partys public key `PK` and your secret
%% key `SK`. Also requires the same nonce as was used by the other party. Returns the plaintext
%%
%% Decrypt a `CipherText' into a `Msg' given the other partys public key `PK' and your secret
%% key `SK'. Also requires the same nonce as was used by the other party. Returns the plaintext
%% message.
%% @end
-spec box_open(CipherText, Nonce, PK, SK) -> {ok, Msg} | {error, failed_verification}
when CipherText :: iodata(),
Nonce :: binary(),
@@ -227,6 +239,7 @@ box_beforenm(PK, SK) ->
R.
%% @doc box_afternm/3 works like `box/4' but uses a precomputed key
%%
%% Calling `box_afternm(M, Nonce, K)' for a precomputed key `K = box_beforenm(PK, SK)' works exactly as
%% if you had called `box(M, Nonce, PK, SK)'. Except that it avoids computations in the elliptic curve Curve25519,
%% and thus is a much faster operation.
@@ -247,6 +260,7 @@ box_afternm(Msg, Nonce, Key) ->
end.
%% @doc box_open_afternm/3 works like `box_open/4` but uses a precomputed key
%%
%% Calling `box_open_afternm(M, Nonce, K)' for a precomputed key `K = box_beforenm(PK, SK)' works exactly as
%% if you had called `box_open(M, Nonce, PK, SK)'. Except the operation is much faster as it avoids costly
%% computations in the elliptic curve Curve25519.
@@ -274,6 +288,7 @@ box_open_afternm(CipherText, Nonce, Key) ->
end.
%% @doc box_nonce_size/0 return the byte-size of the nonce
%%
%% Used to obtain the size of the nonce.
%% @end.
-spec box_nonce_size() -> pos_integer().
@@ -300,6 +315,7 @@ sign_keypair_secret_size() ->
enacl_nif:crypto_sign_SECRETKEYBYTES().
%% @doc sign_keypair/0 returns a signature keypair for signing
%%
%% The returned value is a map in order to make it harder to misuse keys.
%% @end
-spec sign_keypair() -> #{ atom() => binary() }.
@@ -308,6 +324,7 @@ sign_keypair() ->
#{ public => PK, secret => SK}.
%% @doc sign/2 signs a message with a digital signature identified by a secret key.
%%
%% Given a message `M' and a secret key `SK' the function will sign the message and return a signed message `SM'.
%% @end
-spec sign(M, SK) -> SM
@@ -324,6 +341,7 @@ sign(M, SK) ->
end.
%% @doc sign_open/2 opens a digital signature
%%
%% Given a signed message `SM' and a public key `PK', verify that the message has the
%% right signature. Returns either `{ok, M}' or `{error, failed_verification}' depending
%% on the correctness of the signature.
@@ -354,6 +372,7 @@ box_secret_key_bytes() ->
enacl_nif:crypto_box_SECRETKEYBYTES().
%% @doc secretbox/3 encrypts a message with a key
%%
%% Given a `Msg', a `Nonce' and a `Key' encrypt the message with the Key while taking the
%% nonce into consideration. The function returns the Box obtained from the encryption.
%% @end
@@ -375,6 +394,7 @@ secretbox(Msg, Nonce, Key) ->
enacl_nif:crypto_secretbox([s_zerobytes(), Msg], Nonce, Key)
end.
%% @doc secretbox_open/3 opens a sealed box.
%%
%% Given a boxed `CipherText' and given we know the used `Nonce' and `Key' we can open the box
%% to obtain the `Msg` within. Returns either `{ok, Msg}' or `{error, failed_verification}'.
%% @end
@@ -400,9 +420,17 @@ secretbox_open(CipherText, Nonce, Key) ->
end
end.
%% @doc secretbox_nonce_size/0 returns the size of the secretbox nonce
%%
%% When encrypting with a secretbox, the nonce must have this size
%% @end
secretbox_nonce_size() ->
enacl_nif:crypto_secretbox_NONCEBYTES().
%% @doc secretbox_key_size/0 returns the size of the secretbox key
%%
%% When encrypting with a secretbox, the key must have this size
%% @end
secretbox_key_size() ->
enacl_nif:crypto_secretbox_KEYBYTES().
@@ -417,6 +445,7 @@ stream_nonce_size() -> enacl_nif:crypto_stream_NONCEBYTES().
stream_key_size() -> enacl_nif:crypto_stream_KEYBYTES().
%% @doc stream/3 produces a cryptographic stream suitable for secret-key encryption
%%
%% <p>Given a positive `Len' a `Nonce' and a `Key', the stream/3 function will return an unpredictable cryptographic stream of bytes
%% based on this output. In other words, the produced stream is indistinguishable from a random stream. Using this stream one
%% can XOR it with a message in order to produce a encrypted message.</p>
@@ -439,6 +468,7 @@ stream(Len, Nonce, Key) when is_integer(Len), Len >= 0 ->
stream(_, _, _) -> error(badarg).
%% @doc stream_xor/3 encrypts a plaintext message into ciphertext
%%
%% The stream_xor/3 function works by using the {@link stream/3} api to XOR a message with the cryptographic stream. The same
%% caveat applies: the nonce must be new for each sent message or the system fails to work.
%% @end
@@ -470,6 +500,7 @@ auth_key_size() -> enacl_nif:crypto_auth_KEYBYTES().
auth_size() -> enacl_nif:crypto_auth_BYTES().
%% @doc auth/2 produces an authenticator (MAC) for a message
%%
%% Given a `Msg' and a `Key' produce a MAC/Authenticator for that message. The key can be reused for several such Msg/Authenticator pairs.
%% An eavesdropper will not learn anything extra about the message structure.
%% @end
@@ -487,6 +518,7 @@ auth(Msg, Key) ->
end.
%% @doc auth_verify/3 verifies an authenticator for a message
%%
%% Given an `Authenticator', a `Msg' and a `Key'; verify that the MAC for the pair `{Msg, Key}' is really `Authenticator'. Returns
%% the value `true' if the verfication passes. Upon failure, the function returns `false'.
%% @end
@@ -507,6 +539,7 @@ auth_verify(A, M, K) ->
end.
%% @doc onetime_auth/2 produces a ONE-TIME authenticator for a message
%%
%% This function works like {@link auth/2} except that the key must not be used again for subsequent messages. That is, the pair
%% `{Msg, Key}' is unique and only to be used once. The advantage is noticably faster execution.
%% @end
@@ -527,6 +560,7 @@ onetime_auth(Msg, Key) ->
end.
%% @doc onetime_auth_verify/3 verifies an ONE-TIME authenticator for a message
%%
%% Given an `Authenticator', a `Msg' and a `Key'; verify that the MAC for the pair `{Msg, Key}' is really `Authenticator'. Returns
%% the value `true' if the verification passes. Upon failure, the function returns `false'. Note the caveat from {@link onetime_auth/2}
%% applies: you are not allowed to ever use the same key again for another message.
@@ -560,6 +594,7 @@ onetime_auth_key_size() -> enacl_nif:crypto_onetimeauth_KEYBYTES().
%% Obtaining random bytes
%% @doc randombytes/1 produces a stream of random bytes of the given size
%%
%% The security properties of the random stream are that of the libsodium library. Specifically,
%% we use:
%%
+1 -1
View File
@@ -1,6 +1,6 @@
%%% @doc module enacl_ext implements various enacl extensions.
%%% <p>None of the extensions listed here are part of the official NaCl library.
%%% Things may be removed without further notice if it suddenly ends up being
%%% Functions may be removed without further notice if it suddenly ends up being
%%% better to do something differently than the solution given here.
%%% </p>
-module(enacl_ext).
+6 -1
View File
@@ -1,9 +1,14 @@
%%% @doc module enacl_timing provides helpers for timing enacl toward your installation
%%% @doc module enacl_timing provides helpers for timing enacl toward your installation.
%%% <p>To use this module, make sure you disable CPU frequency scaling to obtain better numbers for your system.</p>
%%% @end
-module(enacl_timing).
-export([all/0]).
%% @doc all/0 runs all timing code and reports the timings of different enacl primitives
%% <p>Returns a nested list structure containing maps which explains the runtimes of different primitives</p>
%% <p>The structure is subject to change without notice, so don't rely on it in code.</p>
%% @end
all() ->
[time_hashing(),
time_box(),