diff options
Diffstat (limited to 'c_src/monocypher_nif.c')
-rw-r--r-- | c_src/monocypher_nif.c | 97 |
1 files changed, 96 insertions, 1 deletions
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 <erl_nif.h> #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); |