Commit 159e8f67 authored by Jesper Louis Andersen's avatar Jesper Louis Andersen
Browse files

Introduce precomputed keys API.

This patch implements beforenm/afternm calls from NaCl for `box` style
crypto. It's main advantage is way faster computations, since it avoids
recomputing in the elliptic curve for every message.

While here, bump the version to v0.11.0 as new functionality was added.
parent f2da7b01
......@@ -17,7 +17,7 @@ or
### Features:
* Complete library for every NaCl call, save `beforenm/afternm` invocations
* Complete NaCl library, implementing all default functionality.
* Implements a small set of additional functionality from libsodium. Most notably access to a proper CSPRNG random source
* Tests created by aggressive use of Erlang QuickCheck.
......@@ -31,9 +31,12 @@ In addition, I would like to thank Steve Vinoski, Rickard Green, and Sverker Eri
# Versions
## Upcoming release:
## v0.11.x
### v0.11.0
* Introduce NIF layer beforenm/afternm calls.
* Introduce the API for precomputed keys (beforenm/afternm calls).
* Use test cases which tries to inject `iodata()` rather than binaries in all places where `iodata()` tend to be accepted.
* Fix type for `enacl:box_open/4`. The specification was wrong which results in errors in other applications using enacl.
......
{application, enacl,
[
{description, "Erlang NaCl bindings"},
{vsn, "0.10.2"},
{vsn, "0.11.0"},
{registered, []},
{applications, [kernel, stdlib]},
{env, []}
......
......@@ -21,9 +21,14 @@
box_keypair/0,
box/4,
box_open/4,
box_beforenm/2,
box_afternm/3,
box_open_afternm/3,
box_nonce_size/0,
box_public_key_bytes/0,
box_secret_key_bytes/0,
box_beforenm_bytes/0,
sign_keypair_public_size/0,
sign_keypair_secret_size/0,
......@@ -210,6 +215,64 @@ box_open(CipherText, Nonce, PK, SK) ->
end
end.
%% @doc box_beforenm/2 precomputes a box shared key for a PK/SK keypair
%% @end
-spec box_beforenm(PK, SK) -> binary()
when
PK :: binary(),
SK :: binary().
box_beforenm(PK, SK) ->
R = enacl_nif:crypto_box_beforenm(PK, SK),
erlang:bump_reductions(?BOX_BEFORENM_REDUCTIONS),
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.
%% @end
-spec box_afternm(Msg, Nonce, K) -> CipherText
when
Msg :: iodata(),
Nonce :: binary(),
K :: binary(),
CipherText :: binary().
box_afternm(Msg, Nonce, Key) ->
case iolist_size(Msg) of
K when K =< ?BOX_AFTERNM_SIZE ->
bump(enacl_nif:crypto_box_afternm_b([p_zerobytes(), Msg], Nonce, Key),
?BOX_AFTERNM_REDUCTIONS, ?BOX_AFTERNM_SIZE, K);
_ ->
enacl_nif:crypto_box_afternm([p_zerobytes(), 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.
%% @end
-spec box_open_afternm(CT, Nonce, K) -> {ok, Msg} | {error, failed_verification}
when
CT :: binary(),
Nonce :: binary(),
K :: binary(),
Msg :: binary().
box_open_afternm(CipherText, Nonce, Key) ->
case iolist_size(CipherText) of
K when K =< ?BOX_AFTERNM_SIZE ->
R =
case enacl_nif:crypto_box_open_afternm_b([p_box_zerobytes(), CipherText], Nonce, Key) of
{error, Err} -> {error, Err};
Bin when is_binary(Bin) -> {ok, Bin}
end,
bump(R, ?BOX_AFTERNM_REDUCTIONS, ?BOX_AFTERNM_SIZE, K);
_ ->
case enacl_nif:crypto_box_open_afternm([p_box_zerobytes(), CipherText], Nonce, Key) of
{error, Err} -> {error, Err};
Bin when is_binary(Bin) -> {ok, Bin}
end
end.
%% @doc box_nonce_size/0 return the byte-size of the nonce
%% Used to obtain the size of the nonce.
%% @end.
......@@ -222,6 +285,10 @@ box_nonce_size() ->
box_public_key_bytes() ->
enacl_nif:crypto_box_PUBLICKEYBYTES().
%% @private
box_beforenm_bytes() ->
enacl_nif:crypto_box_BEFORENMBYTES().
%% Signatures
%% @private
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment