Merge branch 'multi-part-signatures' of github.com:hazy/enacl

This commit is contained in:
Jesper Louis Andersen
2020-01-16 15:38:48 +01:00
3 changed files with 204 additions and 1 deletions
+148 -1
View File
@@ -10,6 +10,7 @@
#define ATOM_FALSE "false"
#define CRYPTO_GENERICHASH_STATE_RESOURCE "crypto_generichash_state"
#define CRYPTO_SIGN_STATE_RESOURCE "crypto_sign_state"
#ifdef ERL_NIF_DIRTY_JOB_CPU_BOUND
#define erl_nif_dirty_job_cpu_bound_macro(a, b, c) \
@@ -23,8 +24,9 @@
// ERL_NIF_DIRTY_JOB_CPU_BOUND}
/* Errors */
/* This is a global variable for resource type */
/* These are global variables for resource types */
static ErlNifResourceType *generichash_state_type = NULL;
static ErlNifResourceType *sign_state_type = NULL;
static ERL_NIF_TERM nacl_error_tuple(ErlNifEnv *env, char *error_atom) {
return enif_make_tuple2(env, enif_make_atom(env, "error"),
@@ -40,6 +42,12 @@ static int enif_crypto_load(ErlNifEnv *env, void **priv_data,
ERL_NIF_RT_CREATE, NULL))) {
return -1;
}
// Create a new resource type for crypto_sign_state
if (!(sign_state_type =
enif_open_resource_type(env, NULL, CRYPTO_SIGN_STATE_RESOURCE, NULL,
ERL_NIF_RT_CREATE, NULL))) {
return -1;
}
return sodium_init();
}
@@ -660,6 +668,138 @@ enif_crypto_sign_verify_detached(ErlNifEnv *env, int argc,
}
}
/*
int crypto_sign_init(crypto_sign_state *state)
*/
static ERL_NIF_TERM enif_crypto_sign_init(ErlNifEnv *env, int argc,
ERL_NIF_TERM const argv[]) {
if ((argc != 0)) {
return enif_make_badarg(env);
}
void *state = enif_alloc_resource(sign_state_type, crypto_sign_statebytes());
if (!state) {
return nacl_error_tuple(env, "alloc_failed");
}
if (0 != crypto_sign_init(state)) {
return nacl_error_tuple(env, "sign_init_error");
}
// Create return values
ERL_NIF_TERM e1 = enif_make_atom(env, "signstate");
ERL_NIF_TERM e2 = enif_make_resource(env, state);
// release dynamically allocated memory to erlang to mange
enif_release_resource(state);
// return a tuple
return enif_make_tuple2(env, e1, e2);
}
/*
int crypto_sign_update(crypto_sign_state *state,
const unsigned char *m,
unsigned long long mlen);
*/
static ERL_NIF_TERM enif_crypto_sign_update(ErlNifEnv *env, int argc,
ERL_NIF_TERM const argv[]) {
ErlNifBinary data;
void *state;
// Validate the arguments
if ((argc != 2) ||
(!enif_get_resource(env, argv[0], sign_state_type, (void **)&state)) ||
(!enif_inspect_binary(env, argv[1], &data))) {
return enif_make_badarg(env);
}
if (0 != crypto_sign_update(state, data.data, data.size)) {
return nacl_error_tuple(env, "sign_update_error");
}
// Generate return value
ERL_NIF_TERM e1 = enif_make_atom(env, "signstate");
ERL_NIF_TERM e2 = enif_make_resource(env, state);
// return a tuple
return enif_make_tuple2(env, e1, e2);
}
/*
int crypto_sign_final_create(crypto_sign_state *state,
unsigned char *sig,
unsigned long long *siglen_p,
const unsigned char *sk);
*/
static ERL_NIF_TERM enif_crypto_sign_final_create(ErlNifEnv *env, int argc,
ERL_NIF_TERM const argv[]) {
ErlNifBinary sk, sig;
void *state;
unsigned long long siglen;
if ((argc != 2) ||
(!enif_get_resource(env, argv[0], sign_state_type, (void **)&state)) ||
(!enif_inspect_binary(env, argv[1], &sk))) {
return enif_make_badarg(env);
}
if (sk.size != crypto_sign_SECRETKEYBYTES) {
return enif_make_badarg(env);
}
if (!enif_alloc_binary(crypto_sign_BYTES, &sig)) {
return nacl_error_tuple(env, "alloc_failed");
}
if (0 != crypto_sign_final_create(state, sig.data, &siglen, sk.data)) {
enif_release_binary(&sig);
return nacl_error_tuple(env, "sign_error");
}
ERL_NIF_TERM ok = enif_make_atom(env, ATOM_OK);
ERL_NIF_TERM ret = enif_make_binary(env, &sig);
return enif_make_tuple2(env, ok, ret);
}
/*
int crypto_sign_final_verify(crypto_sign_state *state,
unsigned char *sig,
const unsigned char *pk);
*/
static ERL_NIF_TERM enif_crypto_sign_final_verify(ErlNifEnv *env, int argc,
ERL_NIF_TERM const argv[]) {
ErlNifBinary pk, sig;
void *state;
if ((argc != 3) ||
(!enif_get_resource(env, argv[0], sign_state_type, (void **)&state)) ||
(!enif_inspect_binary(env, argv[1], &sig)) ||
(!enif_inspect_binary(env, argv[2], &pk))) {
return enif_make_badarg(env);
}
if (pk.size != crypto_sign_PUBLICKEYBYTES) {
return enif_make_badarg(env);
}
if (0 == crypto_sign_final_verify(state, sig.data, pk.data)) {
return enif_make_atom(env, ATOM_OK);
}
return nacl_error_tuple(env, "failed_verification");
}
/* Sealed box functions */
static ERL_NIF_TERM enif_crypto_box_SEALBYTES(ErlNifEnv *env, int argc,
@@ -1882,6 +2022,13 @@ static ErlNifFunc nif_funcs[] = {
enif_crypto_sign_detached),
erl_nif_dirty_job_cpu_bound_macro("crypto_sign_verify_detached", 3,
enif_crypto_sign_verify_detached),
{"crypto_sign_init", 0, enif_crypto_sign_init},
{"crypto_sign_update", 2, enif_crypto_sign_update},
erl_nif_dirty_job_cpu_bound_macro("crypto_sign_final_create", 2,
enif_crypto_sign_final_create),
erl_nif_dirty_job_cpu_bound_macro("crypto_sign_final_verify", 3,
enif_crypto_sign_final_verify),
{"crypto_sign_ed25519_sk_to_pk", 1, enif_crypto_sign_ed25519_sk_to_pk},
{"crypto_box_SEALBYTES", 0, enif_crypto_box_SEALBYTES},