Implement missing random functions* enacl:randombytes_int32/0* enacl:randombytes_uniform/1
This commit is contained in:
parent
bc1af327e5
commit
f9d6034e84
@ -6,6 +6,14 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
|
|||||||
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
|
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
|
||||||
|
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
- Implement enacl:randombytes_int32/0. Returns a random 32bit unsigned
|
||||||
|
integer, by means of the underlying random source.
|
||||||
|
- Implement enacl:randombytes_uniform/1. Takes up to a 32bit unsigned
|
||||||
|
integer and produces a uniform integer in the range [0..N). Note
|
||||||
|
that the implementation avoids the typical non-uniformness which
|
||||||
|
would be present on a modulus operation on the nearest power-of-two
|
||||||
|
integer.
|
||||||
|
- Added a nix shell for easier development
|
||||||
|
|
||||||
## [0.17.2]
|
## [0.17.2]
|
||||||
|
|
||||||
|
@ -1029,6 +1029,31 @@ static ERL_NIF_TERM enif_randombytes(ErlNifEnv *env, int argc,
|
|||||||
return enif_make_binary(env, &result);
|
return enif_make_binary(env, &result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static ERL_NIF_TERM enif_randombytes_int32(ErlNifEnv *env, int argc,
|
||||||
|
ERL_NIF_TERM const argv[]) {
|
||||||
|
ErlNifUInt64 result;
|
||||||
|
|
||||||
|
if (argc != 0) {
|
||||||
|
return enif_make_badarg(env);
|
||||||
|
}
|
||||||
|
|
||||||
|
result = randombytes_random();
|
||||||
|
return enif_make_uint64(env, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ERL_NIF_TERM enif_randombytes_uniform(ErlNifEnv *env, int argc,
|
||||||
|
ERL_NIF_TERM const argv[]) {
|
||||||
|
unsigned upper_bound;
|
||||||
|
ErlNifUInt64 result;
|
||||||
|
|
||||||
|
if ((argc != 1) || (!enif_get_uint(env, argv[0], &upper_bound))) {
|
||||||
|
return enif_make_badarg(env);
|
||||||
|
}
|
||||||
|
|
||||||
|
result = randombytes_uniform(upper_bound);
|
||||||
|
return enif_make_uint64(env, result);
|
||||||
|
}
|
||||||
|
|
||||||
/* Key exchange */
|
/* Key exchange */
|
||||||
|
|
||||||
static ERL_NIF_TERM enif_crypto_kx_SECRETKEYBYTES(ErlNifEnv *env, int argc,
|
static ERL_NIF_TERM enif_crypto_kx_SECRETKEYBYTES(ErlNifEnv *env, int argc,
|
||||||
@ -1741,7 +1766,14 @@ static ErlNifFunc nif_funcs[] = {
|
|||||||
{"crypto_sign_ed25519_SECRETKEYBYTES", 0,
|
{"crypto_sign_ed25519_SECRETKEYBYTES", 0,
|
||||||
enif_crypto_sign_ed25519_SECRETKEYBYTES},
|
enif_crypto_sign_ed25519_SECRETKEYBYTES},
|
||||||
|
|
||||||
|
// Linux might block here if early in the boot sequence, so get it off the
|
||||||
|
// main scheduler. Otherwise, it it would probably be fine to run on the
|
||||||
|
// main scheduler. This plays it safe, albeit with a performance hit.
|
||||||
erl_nif_dirty_job_cpu_bound_macro("randombytes", 1, enif_randombytes),
|
erl_nif_dirty_job_cpu_bound_macro("randombytes", 1, enif_randombytes),
|
||||||
|
erl_nif_dirty_job_cpu_bound_macro("randombytes_int32", 0,
|
||||||
|
enif_randombytes_int32),
|
||||||
|
erl_nif_dirty_job_cpu_bound_macro("randombytes_uniform", 1,
|
||||||
|
enif_randombytes_uniform),
|
||||||
|
|
||||||
erl_nif_dirty_job_cpu_bound_macro("crypto_kx_keypair", 0,
|
erl_nif_dirty_job_cpu_bound_macro("crypto_kx_keypair", 0,
|
||||||
enif_crypto_kx_keypair),
|
enif_crypto_kx_keypair),
|
||||||
|
@ -114,7 +114,7 @@
|
|||||||
hash/1,
|
hash/1,
|
||||||
verify_16/2,
|
verify_16/2,
|
||||||
verify_32/2,
|
verify_32/2,
|
||||||
|
|
||||||
%% No Tests!
|
%% No Tests!
|
||||||
unsafe_memzero/1
|
unsafe_memzero/1
|
||||||
]).
|
]).
|
||||||
@ -122,7 +122,9 @@
|
|||||||
%% Randomness
|
%% Randomness
|
||||||
-export([
|
-export([
|
||||||
%% EQC
|
%% EQC
|
||||||
randombytes/1
|
randombytes/1,
|
||||||
|
randombytes_int32/0,
|
||||||
|
randombytes_uniform/1
|
||||||
]).
|
]).
|
||||||
|
|
||||||
%%% Specific primitives
|
%%% Specific primitives
|
||||||
@ -204,6 +206,9 @@
|
|||||||
-define(CRYPTO_GENERICHASH_KEYBYTES_MAX, 64).
|
-define(CRYPTO_GENERICHASH_KEYBYTES_MAX, 64).
|
||||||
-define(CRYPTO_GENERICHASH_KEYBYTES, 32).
|
-define(CRYPTO_GENERICHASH_KEYBYTES, 32).
|
||||||
|
|
||||||
|
%% Size limits
|
||||||
|
-define(MAX_32BIT_INT, 1 bsl 32).
|
||||||
|
|
||||||
%% @doc Verify makes sure the constants defined in libsodium matches ours
|
%% @doc Verify makes sure the constants defined in libsodium matches ours
|
||||||
verify() ->
|
verify() ->
|
||||||
true = equals(binary:copy(<<0>>, enacl_nif:crypto_box_ZEROBYTES()), ?P_ZEROBYTES),
|
true = equals(binary:copy(<<0>>, enacl_nif:crypto_box_ZEROBYTES()), ?P_ZEROBYTES),
|
||||||
@ -1119,6 +1124,18 @@ aead_chacha20poly1305_MESSAGEBYTES_MAX() ->
|
|||||||
randombytes(N) ->
|
randombytes(N) ->
|
||||||
enacl_nif:randombytes(N).
|
enacl_nif:randombytes(N).
|
||||||
|
|
||||||
|
%% @doc randombytes_int32/0 produces an integer in the 32bit range
|
||||||
|
%% @end
|
||||||
|
-spec randombytes_int32() -> integer().
|
||||||
|
randombytes_int32() ->
|
||||||
|
enacl_nif:randombytes_int32().
|
||||||
|
|
||||||
|
%% @doc randombytes_uniform/1 produces a random integer in the space [0..N)
|
||||||
|
%% That is with the upper bound excluded. Fails for integers above 32bit size
|
||||||
|
%% @end
|
||||||
|
randombytes_uniform(N) when N < ?MAX_32BIT_INT ->
|
||||||
|
enacl_nif:randombytes_uniform(N).
|
||||||
|
|
||||||
%% Helpers
|
%% Helpers
|
||||||
|
|
||||||
%% @doc bump/4 bumps a reduction budget linearly before returning the result
|
%% @doc bump/4 bumps a reduction budget linearly before returning the result
|
||||||
|
@ -153,7 +153,9 @@
|
|||||||
|
|
||||||
%% Access to the RNG
|
%% Access to the RNG
|
||||||
-export([
|
-export([
|
||||||
randombytes/1
|
randombytes/1,
|
||||||
|
randombytes_int32/0,
|
||||||
|
randombytes_uniform/1
|
||||||
]).
|
]).
|
||||||
|
|
||||||
%% Undocumented features :>
|
%% Undocumented features :>
|
||||||
@ -296,5 +298,7 @@ crypto_kx_PUBLICKEYBYTES() -> erlang:nif_error(nif_not_loaded).
|
|||||||
crypto_kx_SECRETKEYBYTES() -> erlang:nif_error(nif_not_loaded).
|
crypto_kx_SECRETKEYBYTES() -> erlang:nif_error(nif_not_loaded).
|
||||||
|
|
||||||
randombytes(_RequestedSize) -> erlang:nif_error(nif_not_loaded).
|
randombytes(_RequestedSize) -> erlang:nif_error(nif_not_loaded).
|
||||||
|
randombytes_int32() -> erlang:nif_error(nif_not_loaded).
|
||||||
|
randombytes_uniform(_UpperBound) -> erlang:nif_error(nif_not_loaded).
|
||||||
|
|
||||||
scramble_block_16(_Block, _Key) -> erlang:nif_error(nif_not_loaded).
|
scramble_block_16(_Block, _Key) -> erlang:nif_error(nif_not_loaded).
|
||||||
|
Loading…
x
Reference in New Issue
Block a user