Initial checkin.

This commit is contained in:
Jesper Louis Andersen 2014-11-18 23:16:49 +01:00
commit 9a7f4c8d4e
11 changed files with 178 additions and 0 deletions

13
Makefile Normal file
View File

@ -0,0 +1,13 @@
REBAR=rebar
.PHONY: compile
compile: deps
$(REBAR) compile
.PHONY: deps
deps:
$(REBAR) get-deps
.PHONY: clean
clean:
$(REBAR) clean

10
README.md Normal file
View File

@ -0,0 +1,10 @@
# Erlang bindings for NaCl
This library provides bindings for the NaCl cryptographic library for Erlang. Several such libraries exist, but this one is a re-write with a number of different requirements, and foci:
* Erlang/OTP 17.3. This library *needs* the newest dirty scheduler implementation.
* Uses the original NaCl sources over something like libsodium. This is a deliberate choice.
* Tests created by aggressive use of Erlang QuickCheck.
* provides gen_nacl, a gen_tcp wrapper for sending/receiving messages over a tcp socket.
This package draws heavy inspiration from "erlang-nacl" by Tony Garnock-Jones.

54
c_src/enacl_nif.c Normal file
View File

@ -0,0 +1,54 @@
#include "erl_nif.h"
#include <sodium.h>
static
ERL_NIF_TERM nacl_error_tuple(ErlNifEnv *env, char *error_atom) {
return enif_make_tuple2(env, enif_make_atom(env, "error"), enif_make_atom(env, error_atom));
}
static
ERL_NIF_TERM enif_crypto_hash(ErlNifEnv *env, int argc, ERL_NIF_TERM const argv[]) {
ErlNifBinary input;
ErlNifBinary result;
if ((argc != 1) || (!enif_inspect_iolist_as_binary(env, argv[0], &input))) {
return enif_make_badarg(env);
}
if (!enif_alloc_binary(crypto_hash_BYTES, &result)) {
return nacl_error_tuple(env, "alloc_failed");
}
crypto_hash(result.data, input.data, input.size);
return enif_make_binary(env, &result);
}
static
ERL_NIF_TERM enif_crypto_box_keypair(ErlNifEnv *env, int argc, ERL_NIF_TERM const argv[]) {
ErlNifBinary pk, sk;
if (argc != 0) {
return enif_make_badarg(env);
}
if (!enif_alloc_binary(crypto_box_PUBLICKEYBYTES, &pk)) {
return nacl_error_tuple(env, "alloc_failed");
}
if (!enif_alloc_binary(crypto_box_SECRETKEYBYTES, &sk)) {
return nacl_error_tuple(env, "alloc_failed");
}
crypto_box_keypair(pk.data, sk.data);
return enif_make_tuple3(env, enif_make_atom(env, "ok"), enif_make_binary(env, &pk), enif_make_binary(env, &sk));
}
static ErlNifFunc nif_funcs[] = {
{"crypto_box_keypair", 0, enif_crypto_box_keypair},
{"crypto_hash", 1, enif_crypto_hash, ERL_NIF_DIRTY_JOB_CPU_BOUND}
};
ERL_NIF_INIT(enacl_nif, nif_funcs, NULL, NULL, NULL, NULL);

5
eqc_test/Makefile Normal file
View File

@ -0,0 +1,5 @@
console:
erl -pa ../ebin ../deps/*/ebin
clean:
rm *.beam

33
eqc_test/enacl_eqc.erl Normal file
View File

@ -0,0 +1,33 @@
-module(enacl_eqc).
-include_lib("eqc/include/eqc.hrl").
-compile(export_all).
%% CRYPTO BOX
%% ---------------------------
prop_box_keypair() ->
?FORALL(_X, return(dummy),
ok_box(enacl:box_keypair())).
ok_box({ok, _PK, _SK}) -> true;
ok_box(_) -> false.
%% HASHING
%% ---------------------------
diff_pair(Sz) ->
?SUCHTHAT({X, Y}, {binary(Sz), binary(Sz)},
X /= Y).
prop_crypto_hash_eq() ->
?FORALL(Sz, oneof([1, 128, 1024, 1024*4]),
?FORALL(X, binary(Sz),
equals(enacl:hash(X), enacl:hash(X))
)).
prop_crypto_hash_neq() ->
?FORALL(Sz, oneof([1, 128, 1024, 1024*4]),
?FORALL({X, Y}, diff_pair(Sz),
enacl:hash(X) /= enacl:hash(Y)
)).

8
rebar.config Normal file
View File

@ -0,0 +1,8 @@
{erl_opts, [debug_info]}.
{port_env, [
{"CFLAGS", "$CFLAGS $LIBSODIUM_CFLAGS"},
{"LDFLAGS", "$LDFLAGS $LIBSODIUM_LDFLAGS -lsodium"}
]}.
{port_specs, [{"priv/enacl_nif.so", ["c_src/*.c"]}]}.

2
src/Makefile Normal file
View File

@ -0,0 +1,2 @@
all:
$(MAKE) -C .. compile

9
src/enacl.app.src Normal file
View File

@ -0,0 +1,9 @@
{application, enacl,
[
{description, "Erlang NaCl bindings"},
{vsn, "0.0.1"},
{registered, []},
{applications, [kernel, stdlib]},
{mod, {enacl_app, []}},
{env, []}
]}.

13
src/enacl.erl Normal file
View File

@ -0,0 +1,13 @@
-module(enacl).
-export([
hash/1,
box_keypair/0
]).
hash(Bin) ->
enacl_nif:crypto_hash(Bin).
box_keypair() ->
enacl_nif:crypto_box_keypair().

10
src/enacl_app.erl Normal file
View File

@ -0,0 +1,10 @@
-module(enacl_app).
-behaviour(application).
-export([start/2, stop/1]).
start(_StartType, _StartArgs) ->
enacl_sup:start_link().
stop(_State) ->
ok.

21
src/enacl_nif.erl Normal file
View File

@ -0,0 +1,21 @@
-module(enacl_nif).
-export([
crypto_hash/1,
crypto_box_keypair/0
]).
-on_load(init/0).
init() ->
SoName = filename:join(
case code:priv_dir(enacl) of
{error, bad_name} ->
filename:join(filename:dirname(filename:dirname(code:which(?MODULE))), "priv");
Dir ->
Dir
end, atom_to_list(?MODULE)),
erlang:load_nif(SoName, 0).
crypto_hash(Input) when is_binary(Input) -> error({nif_not_loaded, ?MODULE}).
crypto_box_keypair() -> error({nif_not_loaded, ?MODULE}).