aboutsummaryrefslogtreecommitdiffstats
path: root/lib/crypto/src/crypto.erl
diff options
context:
space:
mode:
authorGuilherme Andrade <[email protected]>2017-03-12 17:20:00 +0000
committerGuilherme Andrade <[email protected]>2017-03-14 23:53:39 +0000
commitd07008a0562d1f83dcab144fdec9fd920deb2b96 (patch)
tree1e2aa60f891b6f2c47e85ded243d94d918bef9f4 /lib/crypto/src/crypto.erl
parent27df945c35aa541330700d75b6844de9886361b2 (diff)
downloadotp-d07008a0562d1f83dcab144fdec9fd920deb2b96.tar.gz
otp-d07008a0562d1f83dcab144fdec9fd920deb2b96.tar.bz2
otp-d07008a0562d1f83dcab144fdec9fd920deb2b96.zip
Support generation of strong random numbers
Diffstat (limited to 'lib/crypto/src/crypto.erl')
-rw-r--r--lib/crypto/src/crypto.erl39
1 files changed, 38 insertions, 1 deletions
diff --git a/lib/crypto/src/crypto.erl b/lib/crypto/src/crypto.erl
index 631af62615..4b386924cb 100644
--- a/lib/crypto/src/crypto.erl
+++ b/lib/crypto/src/crypto.erl
@@ -30,6 +30,8 @@
-export([hmac/3, hmac/4, hmac_init/2, hmac_update/2, hmac_final/1, hmac_final_n/2]).
-export([cmac/3, cmac/4]).
-export([exor/2, strong_rand_bytes/1, mod_pow/3]).
+-export([strong_rand_uniform/0]).
+-export([strong_rand_uniform/1]).
-export([rand_uniform/2]).
-export([block_encrypt/3, block_decrypt/3, block_encrypt/4, block_decrypt/4]).
-export([next_iv/2, next_iv/3]).
@@ -283,9 +285,11 @@ stream_decrypt(State, Data0) ->
stream_crypt(fun do_stream_decrypt/2, State, Data, erlang:byte_size(Data), MaxByts, []).
%%
-%% RAND - pseudo random numbers using RN_ functions in crypto lib
+%% RAND - pseudo random numbers using RN_ and BN_ functions in crypto lib
%%
-spec strong_rand_bytes(non_neg_integer()) -> binary().
+-spec strong_rand_uniform() -> float().
+-spec strong_rand_uniform(pos_integer()) -> pos_integer().
-spec rand_uniform(crypto_integer(), crypto_integer()) ->
crypto_integer().
@@ -297,6 +301,38 @@ strong_rand_bytes(Bytes) ->
strong_rand_bytes_nif(_Bytes) -> ?nif_stub.
+strong_rand_uniform() ->
+ Sign = 0, % positive
+ Exponent = 1023, % on the interval [1.0, 2.0[
+ Fraction = strong_rand_uniform(1, 1 bsl 52), % the whole interval above (except 1.0)
+ <<Value:64/big-float>> = <<Sign:1, Exponent:11, Fraction:52>>,
+ Value - 1.0.
+
+strong_rand_uniform(N) when is_integer(N), N >= 1 ->
+ 1 + strong_rand_uniform(0, N).
+
+strong_rand_uniform(From, To) when is_binary(From), is_binary(To) ->
+ case strong_rand_uniform_nif(From,To) of
+ false ->
+ erlang:error(low_entropy);
+ <<Len:32/integer, MSB, Rest/binary>> when MSB > 127 ->
+ <<(Len + 1):32/integer, 0, MSB, Rest/binary>>;
+ Whatever ->
+ Whatever
+ end;
+strong_rand_uniform(From, To) when is_integer(From), is_integer(To), From < To ->
+ BinFrom = mpint(From),
+ BinTo = mpint(To),
+ case strong_rand_uniform(BinFrom, BinTo) of
+ Result when is_binary(Result) ->
+ erlint(Result);
+ Other ->
+ Other
+ end.
+
+strong_rand_uniform_nif(_From, _To) -> ?nif_stub.
+
+
rand_uniform(From,To) when is_binary(From), is_binary(To) ->
case rand_uniform_nif(From,To) of
<<Len:32/integer, MSB, Rest/binary>> when MSB > 127 ->
@@ -325,6 +361,7 @@ rand_uniform_pos(_,_) ->
rand_uniform_nif(_From,_To) -> ?nif_stub.
+
-spec rand_seed(binary()) -> ok.
rand_seed(Seed) ->
rand_seed_nif(Seed).