summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpukkamustard <pukkamustard@posteo.net>2020-12-03 17:09:58 +0100
committerpukkamustard <pukkamustard@posteo.net>2020-12-03 17:09:58 +0100
commitb46391bbb8d0ea750d9a0b3129b9a6f5c7973b79 (patch)
tree17615fd0bf8e0498c8d9341ae7c3b8c36f8b24e4
parent414e4eb55750090ccae9001797a89351bf2722fd (diff)
monocypher: add crypto_ed25519_* functions.
-rw-r--r--README.md6
-rw-r--r--c_src/monocypher_nif.c97
-rw-r--r--src/monocypher.erl23
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 <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);
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} ->