Streamline returns in the public key API

This commit is contained in:
Jesper Louis Andersen 2020-02-04 12:38:02 +01:00
parent 2041cec2e8
commit c791f602e9
4 changed files with 54 additions and 41 deletions

View File

@ -5,9 +5,26 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
## [TODO]
- Go through all calls and make them return {ok, _} | {error, _} if applicable.
Pretty large change, but OTOH, this ought to happen before a 1.0 release as well.
- AEAD
- enacl
- generichash
- hash
- kx
- public
- pwhash
- randombytes
- secret
- sign
## [Unreleased]
### Compatibility
- Many functions returned the type `value() | {error, term()}`. They have been
updated to return the more erlang-idiomatic `{ok, value()} | {error, term()}`.
- If you used `aead_chacha20poly1305_*` functions, please read through the changelog
carefully as we have made changes to these functions. TL;DR: look for
`aead_chacha20poly1305_ietf_*` but note it is *not* just a simple substitution

View File

@ -100,9 +100,12 @@ ERL_NIF_TERM enacl_crypto_box(ErlNifEnv *env, int argc,
goto release;
}
ret = enif_make_sub_binary(env, enif_make_binary(env, &result),
crypto_box_BOXZEROBYTES,
padded_msg.size - crypto_box_BOXZEROBYTES);
ERL_NIF_TERM ret_ok = enif_make_atom(env, ATOM_OK);
ERL_NIF_TERM ret_bin = enif_make_sub_binary(
env, enif_make_binary(env, &result), crypto_box_BOXZEROBYTES,
padded_msg.size - crypto_box_BOXZEROBYTES);
ret = enif_make_tuple2(env, ret_ok, ret_bin);
goto done;
bad_arg:
@ -143,9 +146,12 @@ ERL_NIF_TERM enacl_crypto_box_open(ErlNifEnv *env, int argc,
return enacl_error_tuple(env, "failed_verification");
}
return enif_make_sub_binary(env, enif_make_binary(env, &result),
crypto_box_ZEROBYTES,
padded_ciphertext.size - crypto_box_ZEROBYTES);
ERL_NIF_TERM ret_ok = enif_make_atom(env, ATOM_OK);
ERL_NIF_TERM ret_bin = enif_make_sub_binary(
env, enif_make_binary(env, &result), crypto_box_ZEROBYTES,
padded_ciphertext.size - crypto_box_ZEROBYTES);
return enif_make_tuple2(env, ret_ok, ret_bin);
}
/* Precomputed crypto boxes */
@ -171,7 +177,9 @@ ERL_NIF_TERM enacl_crypto_box_beforenm(ErlNifEnv *env, int argc,
return enacl_error_tuple(env, "error_gen_shared_secret");
}
return enif_make_binary(env, &k);
ERL_NIF_TERM ret_ok = enif_make_atom(env, ATOM_OK);
ERL_NIF_TERM ret_bin = enif_make_binary(env, &k);
return enif_make_tuple2(env, ret_ok, ret_bin);
}
ERL_NIF_TERM enacl_crypto_box_afternm(ErlNifEnv *env, int argc,
@ -193,9 +201,11 @@ ERL_NIF_TERM enacl_crypto_box_afternm(ErlNifEnv *env, int argc,
crypto_box_afternm(result.data, m.data, m.size, nonce.data, k.data);
return enif_make_sub_binary(env, enif_make_binary(env, &result),
crypto_box_BOXZEROBYTES,
m.size - crypto_box_BOXZEROBYTES);
ERL_NIF_TERM ret_ok = enif_make_atom(env, ATOM_OK);
ERL_NIF_TERM ret_bin = enif_make_sub_binary(
env, enif_make_binary(env, &result), crypto_box_BOXZEROBYTES,
m.size - crypto_box_BOXZEROBYTES);
return enif_make_tuple2(env, ret_ok, ret_bin);
}
ERL_NIF_TERM enacl_crypto_box_open_afternm(ErlNifEnv *env, int argc,
@ -221,9 +231,11 @@ ERL_NIF_TERM enacl_crypto_box_open_afternm(ErlNifEnv *env, int argc,
return enacl_error_tuple(env, "failed_verification");
}
return enif_make_sub_binary(env, enif_make_binary(env, &result),
crypto_box_ZEROBYTES,
m.size - crypto_box_ZEROBYTES);
ERL_NIF_TERM ret_ok = enif_make_atom(env, ATOM_OK);
ERL_NIF_TERM ret_bin =
enif_make_sub_binary(env, enif_make_binary(env, &result),
crypto_box_ZEROBYTES, m.size - crypto_box_ZEROBYTES);
return enif_make_tuple2(env, ret_ok, ret_bin);
}
/* Sealed box functions */

View File

@ -183,10 +183,10 @@ prop_box_correct() ->
begin
case v_iodata(Msg) andalso nonce_valid(Nonce) andalso keypair_valid(PK1, SK1) andalso keypair_valid(PK2, SK2) of
true ->
Key = enacl:box_beforenm(PK2, SK1),
Key = enacl:box_beforenm(PK1, SK2),
CipherText = enacl:box(Msg, Nonce, PK2, SK1),
CipherText = enacl:box_afternm(Msg, Nonce, Key),
{ok, Key} = enacl:box_beforenm(PK2, SK1),
{ok, Key} = enacl:box_beforenm(PK1, SK2),
{ok, CipherText} = enacl:box(Msg, Nonce, PK2, SK1),
{ok, CipherText} = enacl:box_afternm(Msg, Nonce, Key),
{ok, DecodedMsg} = enacl:box_open(CipherText, Nonce, PK1, SK2),
{ok, DecodedMsg} = enacl:box_open_afternm(CipherText, Nonce, Key),
equals(iolist_to_binary(Msg), DecodedMsg);
@ -210,8 +210,8 @@ prop_box_failure_integrity() ->
andalso keypair_valid(PK1, SK1)
andalso keypair_valid(PK2, SK2) of
true ->
Key = enacl:box_beforenm(PK2, SK1),
CipherText = enacl:box(Msg, Nonce, PK2, SK1),
{ok, Key} = enacl:box_beforenm(PK2, SK1),
{ok, CipherText} = enacl:box(Msg, Nonce, PK2, SK1),
Err = enacl:box_open([<<"x">>, CipherText], Nonce, PK1, SK2),
Err = enacl:box_open_afternm([<<"x">>, CipherText], Nonce, Key),
equals(Err, {error, failed_verification});

View File

@ -446,7 +446,7 @@ box_keypair() ->
%% 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
-spec box(Msg, Nonce, PK, SK) -> {ok, CipherText} | {error, term()}
when
Msg :: iodata(),
Nonce :: binary(),
@ -470,14 +470,11 @@ box(Msg, Nonce, PK, SK) ->
SK :: binary(),
Msg :: binary().
box_open(CipherText, Nonce, PK, SK) ->
case enacl_nif:crypto_box_open([?P_BOXZEROBYTES, CipherText], Nonce, PK, SK) of
{error, Err} -> {error, Err};
Bin when is_binary(Bin) -> {ok, Bin}
end.
enacl_nif:crypto_box_open([?P_BOXZEROBYTES, CipherText], Nonce, PK, SK).
%% @doc box_beforenm/2 precomputes a box shared key for a PK/SK keypair
%% @end
-spec box_beforenm(PK, SK) -> binary()
-spec box_beforenm(PK, SK) -> {ok, binary()} | {error, term()}
when
PK :: binary(),
SK :: binary().
@ -492,7 +489,7 @@ box_beforenm(PK, SK) ->
%% 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
-spec box_afternm(Msg, Nonce, K) -> {ok, CipherText} | {error, term()}
when
Msg :: iodata(),
Nonce :: binary(),
@ -522,23 +519,10 @@ box_afternm(Msg, Nonce, Key) ->
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_BOXZEROBYTES, CipherText], Nonce, Key) of
{error, Err} ->
{error, Err};
Bin when is_binary(Bin) ->
{ok, Bin}
end,
R = enacl_nif:crypto_box_open_afternm_b([?P_BOXZEROBYTES, CipherText], Nonce, Key),
bump(R, ?BOX_AFTERNM_REDUCTIONS, ?BOX_AFTERNM_SIZE, K);
_ ->
case enacl_nif:crypto_box_open_afternm(
[?P_BOXZEROBYTES, CipherText], Nonce, Key) of
{error, Err} ->
{error, Err};
Bin when is_binary(Bin) ->
{ok, Bin}
end
enacl_nif:crypto_box_open_afternm([?P_BOXZEROBYTES, CipherText], Nonce, Key)
end.
%% @doc box_nonce_size/0 return the byte-size of the nonce