From 41045fed85270d3a620bae830e07ee4b559aa3ba Mon Sep 17 00:00:00 2001 From: Jesper Louis Andersen Date: Wed, 5 Feb 2020 13:16:35 +0100 Subject: [PATCH] Partially stream kx Also while here, implement some EQC tests for it. --- CHANGELOG.md | 3 ++- c_src/enacl.c | 2 +- c_src/kx.c | 14 +++++++------- eqc_test/enacl_eqc.erl | 29 +++++++++++++++++++++++++++++ 4 files changed, 39 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f8794ff..39211d8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,15 +10,16 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - Go through all calls and make them return streamlined exceptions if applicable. Pretty large change, but OTOH, this ought to happen before a 1.0 release as well. - kx + - Rename the key sizes so they follow libsodium. - secret - sign - - enacl_nif - Implement missing EQC tests - Generichash - Multi-part generic hash - pwhash - Extend with limit for ops and memory as well. + - kx ## [Unreleased] diff --git a/c_src/enacl.c b/c_src/enacl.c index fa8a71b..5497180 100644 --- a/c_src/enacl.c +++ b/c_src/enacl.c @@ -8,5 +8,5 @@ ERL_NIF_TERM enacl_error_tuple(ErlNifEnv *env, char *error_atom) { } ERL_NIF_TERM enacl_internal_error(ErlNifEnv *env) { - return enif_raise_exception(env, enif_make_atom(env, "internal_error")); + return enif_raise_exception(env, enif_make_atom(env, "enacl_internal_error")); } \ No newline at end of file diff --git a/c_src/kx.c b/c_src/kx.c index 6d5b39b..6020e6f 100644 --- a/c_src/kx.c +++ b/c_src/kx.c @@ -31,12 +31,12 @@ ERL_NIF_TERM enacl_crypto_kx_keypair(ErlNifEnv *env, int argc, } if (!enif_alloc_binary(crypto_kx_PUBLICKEYBYTES, &pk)) { - return enacl_error_tuple(env, "alloc_failed"); + return enacl_internal_error(env); } if (!enif_alloc_binary(crypto_kx_SECRETKEYBYTES, &sk)) { enif_release_binary(&pk); - return enacl_error_tuple(env, "alloc_failed"); + return enacl_internal_error(env); } crypto_kx_keypair(pk.data, sk.data); @@ -68,12 +68,12 @@ enacl_crypto_kx_server_session_keys(ErlNifEnv *env, int argc, goto bad_arg; if (!enif_alloc_binary(crypto_kx_SESSIONKEYBYTES, &rx)) { - ret = enacl_error_tuple(env, "alloc_failed"); + ret = enacl_internal_error(env); goto done; } if (!enif_alloc_binary(crypto_kx_SESSIONKEYBYTES, &tx)) { - ret = enacl_error_tuple(env, "alloc_failed"); + ret = enacl_internal_error(env); goto release_rx; } @@ -121,12 +121,12 @@ enacl_crypto_kx_client_session_keys(ErlNifEnv *env, int argc, goto bad_arg; if (!enif_alloc_binary(crypto_kx_SESSIONKEYBYTES, &rx)) { - ret = enacl_error_tuple(env, "alloc_failed"); + ret = enacl_internal_error(env); goto done; } if (!enif_alloc_binary(crypto_kx_SESSIONKEYBYTES, &tx)) { - ret = enacl_error_tuple(env, "alloc_failed"); + ret = enacl_internal_error(env); goto release_rx; } @@ -148,4 +148,4 @@ release_rx: enif_release_binary(&rx); done: return ret; -} \ No newline at end of file +} diff --git a/eqc_test/enacl_eqc.erl b/eqc_test/enacl_eqc.erl index 7eb1486..4b6f4ac 100644 --- a/eqc_test/enacl_eqc.erl +++ b/eqc_test/enacl_eqc.erl @@ -122,6 +122,24 @@ keypair_bad() -> keypair() -> ?FAULT(keypair_bad(), keypair_good()). +kx_keypair_good() -> + #{ public := PK, secret := SK} = enacl:kx_keypair(), + {PK, SK}. + +kx_keypair_bad() -> + ?LET(X, elements([pk, sk]), + begin + #{ public := PK, secret := SK} = enacl:box_keypair(), + case X of + pk -> + PKBytes = enacl:kx_public_key_size(), + {oneof([return(a), nat(), ?SUCHTHAT(B, binary(), byte_size(B) /= PKBytes)]), SK}; + sk -> + SKBytes = enacl:kx_secret_key_size(), + {PK, oneof([return(a), nat(), ?SUCHTHAT(B, binary(), byte_size(B) /= SKBytes)])} + end + end). + %% CRYPTO BOX %% --------------------------- %% * box/4 @@ -880,6 +898,17 @@ prop_randombytes_uint32() -> is_integer(V) end). +%% KX +%% --------------------------- +prop_kx() -> + ?FORALL({{CPK, CSK}, {SPK, SSK}}, {kx_keypair_good(), kx_keypair_good()}, + begin + #{ client_tx := CTX, client_rx := CRX} = enacl:kx_client_session_keys(CPK, CSK, SPK), + #{ server_tx := STX, server_rx := SRX} = enacl:kx_server_session_keys(SPK, SSK, CPK), + %% This keypair must be shared in both directions + conjunction([{ctx_srx, equals(CTX, SRX)}, {stx_crx, equals(STX, CRX)}]) + end). + %% SCRAMBLING prop_scramble_block() -> ?FORALL({Block, Key}, {binary(16), eqc_gen:largebinary(32)},