From 6f4a0c2521a2f20dec9b2db76e8bb77dbbfb743b Mon Sep 17 00:00:00 2001 From: Ole Andre Birkedal Date: Sat, 8 Jun 2019 18:19:44 +0200 Subject: [PATCH] Added bindings for crypto_sign_seed_keypair in libsodium --- c_src/enacl_nif.c | 30 ++++++++++++++++++++++++++++++ src/enacl.erl | 17 +++++++++++++++++ src/enacl_nif.erl | 4 ++++ 3 files changed, 51 insertions(+) diff --git a/c_src/enacl_nif.c b/c_src/enacl_nif.c index 1497215..dbc3393 100644 --- a/c_src/enacl_nif.c +++ b/c_src/enacl_nif.c @@ -477,6 +477,11 @@ ERL_NIF_TERM enif_crypto_sign_SECRETKEYBYTES(ErlNifEnv *env, int argc, ERL_NIF_T return enif_make_int64(env, crypto_sign_SECRETKEYBYTES); } +static +ERL_NIF_TERM enif_crypto_sign_SEEDBYTES(ErlNifEnv *env, int argc, ERL_NIF_TERM const argv[]) { + return enif_make_int64(env, crypto_sign_SEEDBYTES); +} + static ERL_NIF_TERM enif_crypto_sign_keypair(ErlNifEnv *env, int argc, ERL_NIF_TERM const argv[]) { ErlNifBinary pk, sk; @@ -498,6 +503,29 @@ ERL_NIF_TERM enif_crypto_sign_keypair(ErlNifEnv *env, int argc, ERL_NIF_TERM con return enif_make_tuple2(env, enif_make_binary(env, &pk), enif_make_binary(env, &sk)); } +static +ERL_NIF_TERM enif_crypto_sign_seed_keypair(ErlNifEnv *env, int argc, ERL_NIF_TERM const argv[]) { + ErlNifBinary pk, sk, seed; + + if ( + (argc != 1) || + (!enif_inspect_binary(env, argv[0], &seed))) { + return enif_make_badarg(env); + } + + if (!enif_alloc_binary(crypto_sign_PUBLICKEYBYTES, &pk)) { + return nacl_error_tuple(env, "alloc_failed"); + } + + if (!enif_alloc_binary(crypto_sign_SECRETKEYBYTES, &sk)) { + return nacl_error_tuple(env, "alloc_failed"); + } + + crypto_sign_seed_keypair(pk.data, sk.data, seed.data); + + return enif_make_tuple2(env, enif_make_binary(env, &pk), enif_make_binary(env, &sk)); +} + /* int crypto_sign(unsigned char *sm, unsigned long long *smlen, const unsigned char *m, unsigned long long mlen, @@ -1667,7 +1695,9 @@ static ErlNifFunc nif_funcs[] = { {"crypto_sign_PUBLICKEYBYTES", 0, enif_crypto_sign_PUBLICKEYBYTES}, {"crypto_sign_SECRETKEYBYTES", 0, enif_crypto_sign_SECRETKEYBYTES}, + {"crypto_sign_SEEDBYTES", 0, enif_crypto_sign_SEEDBYTES}, erl_nif_dirty_job_cpu_bound_macro("crypto_sign_keypair", 0, enif_crypto_sign_keypair), + erl_nif_dirty_job_cpu_bound_macro("crypto_sign_seed_keypair", 1, enif_crypto_sign_seed_keypair), erl_nif_dirty_job_cpu_bound_macro("crypto_sign", 2, enif_crypto_sign), erl_nif_dirty_job_cpu_bound_macro("crypto_sign_open", 2, enif_crypto_sign_open), diff --git a/src/enacl.erl b/src/enacl.erl index 15ea2c2..d6e811d 100644 --- a/src/enacl.erl +++ b/src/enacl.erl @@ -33,7 +33,9 @@ %% EQC sign_keypair_public_size/0, sign_keypair_secret_size/0, + sign_keypair_seed_size/0, sign_keypair/0, + sign_seed_keypair/1, sign/2, sign_open/2, sign_detached/2, @@ -513,6 +515,10 @@ sign_keypair_public_size() -> sign_keypair_secret_size() -> enacl_nif:crypto_sign_SECRETKEYBYTES(). +%% @private +sign_keypair_seed_size() -> + enacl_nif:crypto_sign_SEEDBYTES(). + %% @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. @@ -522,6 +528,17 @@ sign_keypair() -> {PK, SK} = enacl_nif:crypto_sign_keypair(), #{ public => PK, secret => SK}. +%% @doc sign_seed_keypair/1 returns a signature keypair based on seed for signing +%% +%% The returned value is a map in order to make it harder to misuse keys. +%% @end +-spec sign_seed_keypair(S) -> #{ atom() => binary() } + when + S :: binary(). +sign_seed_keypair(S) -> + {PK, SK} = enacl_nif:crypto_sign_seed_keypair(S), + #{ 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'. diff --git a/src/enacl_nif.erl b/src/enacl_nif.erl index 798ef53..0675615 100644 --- a/src/enacl_nif.erl +++ b/src/enacl_nif.erl @@ -25,8 +25,10 @@ crypto_sign_PUBLICKEYBYTES/0, crypto_sign_SECRETKEYBYTES/0, + crypto_sign_SEEDBYTES/0, crypto_sign_keypair/0, + crypto_sign_seed_keypair/1, crypto_sign/2, crypto_sign_open/2, @@ -211,8 +213,10 @@ crypto_box_open_afternm_b(_CipherText, _Nonce, _K) -> erlang:nif_error(nif_not_l crypto_sign_PUBLICKEYBYTES() -> erlang:nif_error(nif_not_loaded). crypto_sign_SECRETKEYBYTES() -> erlang:nif_error(nif_not_loaded). +crypto_sign_SEEDBYTES() -> erlang:nif_error(nif_not_loaded). crypto_sign_keypair() -> erlang:nif_error(nif_not_loaded). +crypto_sign_seed_keypair(_S) -> erlang:nif_error(nif_not_loaded). crypto_sign(_M, _SK) -> erlang:nif_error(nif_not_loaded). crypto_sign_open(_SignedMessage, _PK) -> erlang:nif_error(nif_not_loaded).