diff --git a/c_src/enacl_nif.c b/c_src/enacl_nif.c index b2127d9..1b154dc 100644 --- a/c_src/enacl_nif.c +++ b/c_src/enacl_nif.c @@ -661,6 +661,16 @@ ERL_NIF_TERM enif_crypto_auth_KEYBYTES(ErlNifEnv *env, int argc, ERL_NIF_TERM co return enif_make_int64(env, crypto_auth_KEYBYTES); } +static +ERL_NIF_TERM enif_crypto_shorthash_BYTES(ErlNifEnv *env, int argc, ERL_NIF_TERM const argv[]) { + return enif_make_int64(env, crypto_shorthash_BYTES); +} + +static +ERL_NIF_TERM enif_crypto_shorthash_KEYBYTES(ErlNifEnv *env, int argc, ERL_NIF_TERM const argv[]) { + return enif_make_int64(env, crypto_shorthash_KEYBYTES); +} + static ERL_NIF_TERM enif_crypto_onetimeauth_BYTES(ErlNifEnv *env, int argc, ERL_NIF_TERM const argv[]) { return enif_make_int64(env, crypto_onetimeauth_BYTES); @@ -850,6 +860,30 @@ ERL_NIF_TERM enif_crypto_auth_verify(ErlNifEnv *env, int argc, ERL_NIF_TERM cons } } +static +ERL_NIF_TERM enif_crypto_shorthash(ErlNifEnv *env, int argc, ERL_NIF_TERM const argv[]) { + ErlNifBinary a,m,k; + + if ( + (argc != 2) || + (!enif_inspect_iolist_as_binary(env, argv[0], &m)) || + (!enif_inspect_binary(env, argv[1], &k))) { + return enif_make_badarg(env); + } + + if (k.size != crypto_shorthash_KEYBYTES) { + return enif_make_badarg(env); + } + + if (!enif_alloc_binary(crypto_shorthash_BYTES, &a)) { + return nacl_error_tuple(env, "alloc_failed"); + } + + crypto_shorthash(a.data, m.data, m.size, k.data); + + return enif_make_binary(env, &a); +} + static ERL_NIF_TERM enif_crypto_onetimeauth(ErlNifEnv *env, int argc, ERL_NIF_TERM const argv[]) { ErlNifBinary a,m,k; @@ -1051,6 +1085,10 @@ static ErlNifFunc nif_funcs[] = { {"crypto_auth_verify_b", 3, enif_crypto_auth_verify}, {"crypto_auth_verify", 3, enif_crypto_auth_verify, ERL_NIF_DIRTY_JOB_CPU_BOUND}, + {"crypto_shorthash_BYTES", 0, enif_crypto_auth_BYTES}, + {"crypto_shorthash_KEYBYTES", 0, enif_crypto_shorthash_KEYBYTES}, + {"crypto_shorthash", 2, enif_crypto_shorthash}, + {"crypto_onetimeauth_BYTES", 0, enif_crypto_onetimeauth_BYTES}, {"crypto_onetimeauth_KEYBYTES", 0, enif_crypto_onetimeauth_KEYBYTES}, {"crypto_onetimeauth_b", 2, enif_crypto_onetimeauth}, diff --git a/src/enacl.erl b/src/enacl.erl index d09d7db..0244152 100644 --- a/src/enacl.erl +++ b/src/enacl.erl @@ -59,6 +59,10 @@ auth/2, auth_verify/3, + shorthash_key_size/0, + shorthash_size/0, + shorthash/2, + onetime_auth_key_size/0, onetime_auth_size/0, onetime_auth/2, @@ -601,6 +605,29 @@ auth_verify(A, M, K) -> enacl_nif:crypto_auth_verify(A, M, K) end. +%% @doc shorthash_key_size/0 returns the byte-size of the authentication key +%% @end +-spec shorthash_key_size() -> pos_integer(). +shorthash_key_size() -> enacl_nif:crypto_shorthash_KEYBYTES(). + +%% @doc shorthash_size/0 returns the byte-size of the authenticator +%% @end +-spec shorthash_size() -> pos_integer(). +shorthash_size() -> enacl_nif:crypto_shorthash_BYTES(). + +%% @doc shorthash/2 produces a short authenticator (MAC) for a message suitable for hashtables and refs +%% +%% 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 +-spec shorthash(Msg, Key) -> Authenticator + when + Msg :: iodata(), + Key :: binary(), + Authenticator :: binary(). +shorthash(Msg, Key) -> + enacl_nif:crypto_shorthash(Msg, Key). + %% @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 diff --git a/src/enacl_nif.erl b/src/enacl_nif.erl index 9640f74..d18c2c0 100644 --- a/src/enacl_nif.erl +++ b/src/enacl_nif.erl @@ -68,6 +68,11 @@ crypto_auth_verify/3, crypto_auth_verify_b/3, + crypto_shorthash_BYTES/0, + crypto_shorthash_KEYBYTES/0, + + crypto_shorthash/2, + crypto_onetimeauth_BYTES/0, crypto_onetimeauth_KEYBYTES/0, @@ -177,6 +182,10 @@ crypto_auth_b(_Msg, _Key) -> erlang:nif_error(nif_not_loaded). crypto_auth_verify(_Authenticator, _Msg, _Key) -> erlang:nif_error(nif_not_loaded). crypto_auth_verify_b(_Authenticator, _Msg, _Key) -> erlang:nif_error(nif_not_loaded). +crypto_shorthash_BYTES() -> erlang:nif_error(nif_not_loaded). +crypto_shorthash_KEYBYTES() -> erlang:nif_error(nif_not_loaded). +crypto_shorthash(_Msg, _Key) -> erlang:nif_error(nif_not_loaded). + crypto_onetimeauth_BYTES() -> erlang:nif_error(nif_not_loaded). crypto_onetimeauth_KEYBYTES() -> erlang:nif_error(nif_not_loaded). crypto_onetimeauth(_Msg, _Key) -> erlang:nif_error(nif_not_loaded).