initial import
This commit is contained in:
@@ -0,0 +1,144 @@
|
||||
#include "erl_nif.h"
|
||||
#include "KeccakNISTInterface.h"
|
||||
|
||||
typedef struct nif_hash_context nif_hash_context;
|
||||
|
||||
struct nif_hash_context {
|
||||
int bitlen;
|
||||
hashState state;
|
||||
};
|
||||
|
||||
static void sha3_resource_cleanup(ErlNifEnv* env, void* arg);
|
||||
static ERL_NIF_TERM nif_hash_init(ErlNifEnv* env, int argc,
|
||||
const ERL_NIF_TERM argv[]);
|
||||
static ERL_NIF_TERM nif_hash_update(ErlNifEnv* env, int argc,
|
||||
const ERL_NIF_TERM argv[]);
|
||||
static ERL_NIF_TERM nif_hash_final(ErlNifEnv* env, int argc,
|
||||
const ERL_NIF_TERM argv[]);
|
||||
static ERL_NIF_TERM nif_hash(ErlNifEnv* env, int argc,
|
||||
const ERL_NIF_TERM argv[]);
|
||||
|
||||
static ErlNifFunc nif_funcs[] =
|
||||
{
|
||||
{"hash_init", 1, nif_hash_init},
|
||||
{"hash_update", 2, nif_hash_update},
|
||||
{"hash_final", 1, nif_hash_final},
|
||||
{"hash", 2, nif_hash}
|
||||
};
|
||||
|
||||
static ErlNifResourceType *sha3_resource_type;
|
||||
|
||||
static void
|
||||
sha3_resource_cleanup(ErlNifEnv* env, void* arg)
|
||||
{
|
||||
/* do nothing */
|
||||
}
|
||||
|
||||
static ERL_NIF_TERM
|
||||
nif_hash_init(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
|
||||
{
|
||||
ERL_NIF_TERM ctxt_term;
|
||||
nif_hash_context *ctxt;
|
||||
int bitlen;
|
||||
|
||||
if (!enif_get_int(env, argv[0], &bitlen))
|
||||
return 0;
|
||||
|
||||
if (bitlen != 224 && bitlen != 256 && bitlen != 384 && bitlen != 512)
|
||||
return 0;
|
||||
|
||||
ctxt = enif_alloc_resource(sha3_resource_type, sizeof(nif_hash_context));
|
||||
ctxt->bitlen = bitlen;
|
||||
Init(&ctxt->state, bitlen);
|
||||
ctxt_term = enif_make_resource(env, ctxt);
|
||||
enif_release_resource(ctxt);
|
||||
|
||||
return ctxt_term;
|
||||
}
|
||||
|
||||
static ERL_NIF_TERM
|
||||
nif_hash_update(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
|
||||
{
|
||||
ERL_NIF_TERM ctxt_term;
|
||||
ErlNifBinary src_bin;
|
||||
nif_hash_context *ctxt, *new;
|
||||
hashState state;
|
||||
|
||||
if (!enif_get_resource(env, argv[0], sha3_resource_type, (void **)&ctxt) ||
|
||||
!enif_inspect_binary(env, argv[1], &src_bin))
|
||||
return 0;
|
||||
|
||||
state = ctxt->state;
|
||||
Update(&state, src_bin.data, src_bin.size * 8);
|
||||
new = enif_alloc_resource(sha3_resource_type, sizeof(nif_hash_context));
|
||||
new->bitlen = ctxt->bitlen;
|
||||
new->state = state;
|
||||
ctxt_term = enif_make_resource(env, new);
|
||||
enif_release_resource(new);
|
||||
|
||||
return ctxt_term;
|
||||
}
|
||||
|
||||
static ERL_NIF_TERM
|
||||
nif_hash_final(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
|
||||
{
|
||||
ERL_NIF_TERM digest_term;
|
||||
ErlNifBinary digest_bin;
|
||||
nif_hash_context *ctxt;
|
||||
hashState state;
|
||||
|
||||
if (!enif_get_resource(env, argv[0], sha3_resource_type, (void **)&ctxt))
|
||||
return 0;
|
||||
|
||||
state = ctxt->state;
|
||||
enif_alloc_binary(ctxt->bitlen / 8, &digest_bin);
|
||||
Final(&state, digest_bin.data);
|
||||
digest_term = enif_make_binary(env, &digest_bin);
|
||||
enif_release_binary(&digest_bin);
|
||||
|
||||
return digest_term;
|
||||
}
|
||||
|
||||
static ERL_NIF_TERM
|
||||
nif_hash(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
|
||||
{
|
||||
ERL_NIF_TERM digest_term;
|
||||
ErlNifBinary src_bin, digest_bin;
|
||||
int bitlen;
|
||||
|
||||
if (!enif_get_int(env, argv[0], &bitlen) ||
|
||||
!enif_inspect_binary(env, argv[1], &src_bin))
|
||||
return 0;
|
||||
|
||||
if (bitlen != 224 && bitlen != 256 && bitlen != 384 && bitlen != 512)
|
||||
return 0;
|
||||
|
||||
enif_alloc_binary(bitlen / 8, &digest_bin);
|
||||
Hash(bitlen, src_bin.data, src_bin.size * 8, digest_bin.data);
|
||||
digest_term = enif_make_binary(env, &digest_bin);
|
||||
enif_release_binary(&digest_bin);
|
||||
|
||||
return digest_term;
|
||||
}
|
||||
|
||||
static int
|
||||
on_load(ErlNifEnv* env, void** priv_data, ERL_NIF_TERM load_info)
|
||||
{
|
||||
ErlNifResourceFlags flags = ERL_NIF_RT_CREATE | ERL_NIF_RT_TAKEOVER;
|
||||
|
||||
sha3_resource_type = enif_open_resource_type(env, NULL, "sha3_resource",
|
||||
&sha3_resource_cleanup, flags, NULL);
|
||||
if (sha3_resource_type == NULL)
|
||||
return -1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
on_unload(ErlNifEnv* env, void* priv_data)
|
||||
{
|
||||
/* do nothing */
|
||||
}
|
||||
|
||||
ERL_NIF_INIT(sha3, nif_funcs, &on_load, NULL, NULL, &on_unload);
|
||||
|
||||
Reference in New Issue
Block a user