From b46391bbb8d0ea750d9a0b3129b9a6f5c7973b79 Mon Sep 17 00:00:00 2001 From: pukkamustard Date: Thu, 3 Dec 2020 17:09:58 +0100 Subject: monocypher: add crypto_ed25519_* functions. --- README.md | 6 ++-- c_src/monocypher_nif.c | 97 +++++++++++++++++++++++++++++++++++++++++++++++++- src/monocypher.erl | 23 ++++++++++++ 3 files changed, 122 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 040af28..fff1c2b 100644 --- a/README.md +++ b/README.md @@ -43,9 +43,9 @@ See also the [Monocypher documentation](https://monocypher.org/manual/). #### Ed25519 -- [ ] `crypto_ed25519_public_key` -- [ ] `crypto_ed25519_sign` -- [ ] `crypto_ed25519_check` +- [X] `crypto_ed25519_public_key` +- [X] `crypto_ed25519_sign` +- [X] `crypto_ed25519_check` ## Acknowledgments diff --git a/c_src/monocypher_nif.c b/c_src/monocypher_nif.c index 209dd66..7e25d90 100644 --- a/c_src/monocypher_nif.c +++ b/c_src/monocypher_nif.c @@ -4,6 +4,7 @@ #include #include "monocypher.h" +#include "monocypher-ed25519.h" /* Authenticated Encryption */ @@ -237,6 +238,97 @@ static ERL_NIF_TERM crypto_ietf_chacha20_ctr_nif(ErlNifEnv* env, int argc, const } +/* Public Key Signature (Ed25519) */ + +static ERL_NIF_TERM crypto_ed25519_public_key_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) +{ + + ErlNifBinary secret_key; + if(!enif_inspect_binary(env, argv[0], &secret_key)) { + return enif_make_badarg(env); + } + + if(secret_key.size != 32) { + return enif_make_badarg(env); + } + + ERL_NIF_TERM public_key_term; + unsigned char* public_key = enif_make_new_binary(env, 32, &public_key_term); + + crypto_ed25519_public_key(public_key, secret_key.data); + + return public_key_term; +} + +static ERL_NIF_TERM crypto_ed25519_sign_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) +{ + + ErlNifBinary secret_key; + if(!enif_inspect_binary(env, argv[0], &secret_key)) { + return enif_make_badarg(env); + } + + if(secret_key.size != 32) { + return enif_make_badarg(env); + } + + ErlNifBinary public_key; + if(!enif_inspect_binary(env, argv[1], &public_key)) { + return enif_make_badarg(env); + } + + if(public_key.size != 32) { + return enif_make_badarg(env); + } + + ErlNifBinary message; + if(!enif_inspect_binary(env, argv[2], &message)) { + return enif_make_badarg(env); + } + + ERL_NIF_TERM signature_term; + unsigned char* signature = enif_make_new_binary(env, 64, &signature_term); + + crypto_ed25519_sign(signature, secret_key.data, public_key.data, message.data, message.size); + + return signature_term; +} + +static ERL_NIF_TERM crypto_ed25519_check_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) +{ + ErlNifBinary signature; + if(!enif_inspect_binary(env, argv[0], &signature)) { + return enif_make_badarg(env); + } + + if(signature.size != 64) { + return enif_make_badarg(env); + } + + ErlNifBinary public_key; + if(!enif_inspect_binary(env, argv[1], &public_key)) { + return enif_make_badarg(env); + } + + if(public_key.size != 32) { + return enif_make_badarg(env); + } + + ErlNifBinary message; + if(!enif_inspect_binary(env, argv[2], &message)) { + return enif_make_badarg(env); + } + + int check_return_value = crypto_ed25519_check(signature.data, public_key.data, message.data, message.size); + + if (check_return_value == 0) { + return enif_make_atom_len(env, "ok", 2); + } else { + return enif_make_atom_len(env, "forgery", 7); + } +} + + static ErlNifFunc nif_funs[] = { {"crypto_lock", 4, crypto_lock_nif}, @@ -244,7 +336,10 @@ static ErlNifFunc nif_funs[] = {"crypto_blake2b", 1, crypto_blake2b_nif}, {"crypto_blake2b_general", 3, crypto_blake2b_general_nif}, {"crypto_ietf_chacha20", 3, crypto_ietf_chacha20_nif}, - {"crypto_ietf_chacha20_ctr", 4, crypto_ietf_chacha20_ctr_nif} + {"crypto_ietf_chacha20_ctr", 4, crypto_ietf_chacha20_ctr_nif}, + {"crypto_ed25519_public_key", 1, crypto_ed25519_public_key_nif}, + {"crypto_ed25519_sign", 3, crypto_ed25519_sign_nif}, + {"crypto_ed25519_check", 3, crypto_ed25519_check_nif} }; ERL_NIF_INIT(monocypher, nif_funs, NULL, NULL, NULL, NULL); diff --git a/src/monocypher.erl b/src/monocypher.erl index 41c5c24..eca8fc4 100644 --- a/src/monocypher.erl +++ b/src/monocypher.erl @@ -9,6 +9,9 @@ crypto_blake2b_general/3]). -export([crypto_ietf_chacha20/3, crypto_ietf_chacha20_ctr/4]). +-export([crypto_ed25519_public_key/1, + crypto_ed25519_sign/3, + crypto_ed25519_check/3]). -on_load(init/0). -define(APPNAME, monocypher). @@ -52,6 +55,26 @@ crypto_ietf_chacha20(_,_,_) -> crypto_ietf_chacha20_ctr(_,_,_,_) -> not_loaded(?LINE). +%% Public Key Signature (Ed25519) + +-type crypto_ed25519_secret_key() :: <<_:256>>. +-type crypto_ed25519_public_key() :: <<_:256>>. +-type crypto_ed25519_signature() :: <<_:512>>. +-type crypto_ed25519_message() :: <<_:_*8>>. + +-spec crypto_ed25519_public_key(crypto_ed25519_secret_key()) -> crypto_ed25519_public_key(). +crypto_ed25519_public_key(_) -> + not_loaded(?LINE). + +-spec crypto_ed25519_sign(crypto_ed25519_secret_key(), crypto_ed25519_public_key(), crypto_ed25519_message()) -> crypto_ed25519_signature(). +crypto_ed25519_sign(_,_,_) -> + not_loaded(?LINE). + +-spec crypto_ed25519_check(crypto_ed25519_signature(), crypto_ed25519_public_key(), crypto_ed25519_message()) -> 'ok' | 'forgery'. +crypto_ed25519_check(_,_,_) -> + not_loaded(?LINE). + + init() -> SoName = case code:priv_dir(?APPNAME) of {error, bad_name} -> -- cgit v1.2.3