Use on-scheduler variants of calls when message sizes are small.

This commit is contained in:
Jesper Louis Andersen
2014-11-28 17:09:48 +01:00
parent 281c3e8fbf
commit d46ae1da16
4 changed files with 103 additions and 4 deletions
+28 -1
View File
@@ -67,6 +67,12 @@
reds/1
]).
%% Definitions of system budgets
-define(HASH_SIZE, 32 * 1024).
-define(HASH_REDUCTIONS, 2 * 200).
-define(BOX_SIZE, 32 * 1024).
-define(BOX_REDUCTIONS, 2 * 250).
%% Count reductions and number of scheduler yields for Fun. Fun is assumed
%% to be one of the above exor variants.
reds(Fun) ->
@@ -97,7 +103,12 @@ reds(Fun) ->
when Data :: binary(),
Checksum :: binary().
hash(Bin) -> enacl_nif:crypto_hash(Bin).
hash(Bin) when byte_size(Bin) =< ?HASH_SIZE ->
R = enacl_nif:crypto_hash_b(Bin),
bump(?HASH_REDUCTIONS, ?HASH_SIZE, byte_size(Bin)),
R;
hash(Bin) ->
enacl_nif:crypto_hash(Bin).
%% @doc verify_16/2 implements constant time 16-byte string verification
%% <p>A subtle problem in cryptographic software are timing attacks where an attacker exploits
@@ -138,6 +149,10 @@ box_keypair() ->
PK :: binary(),
SK :: binary(),
CipherText :: binary().
box(Msg, Nonce, PK, SK) when byte_size(Msg) =< ?BOX_SIZE ->
R = enacl_nif:crypto_box_b([p_zerobytes(), Msg], Nonce, PK, SK),
bump(?BOX_REDUCTIONS, ?BOX_SIZE, byte_size(Msg)),
R;
box(Msg, Nonce, PK, SK) ->
enacl_nif:crypto_box([p_zerobytes(), Msg], Nonce, PK, SK).
@@ -151,6 +166,13 @@ box(Msg, Nonce, PK, SK) ->
PK :: binary(),
SK :: binary(),
Msg :: binary().
box_open(CipherText, Nonce, PK, SK) when byte_size(CipherText) =< ?BOX_SIZE ->
R = case enacl_nif:crypto_box_open_b([p_box_zerobytes(), CipherText], Nonce, PK, SK) of
{error, Err} -> {error, Err};
Bin when is_binary(Bin) -> {ok, Bin}
end,
bump(?BOX_REDUCTIONS, ?BOX_SIZE, byte_size(CipherText)),
R;
box_open(CipherText, Nonce, PK, SK) ->
case enacl_nif:crypto_box_open([p_box_zerobytes(), CipherText], Nonce, PK, SK) of
{error, Err} -> {error, Err};
@@ -350,3 +372,8 @@ s_zerobytes() ->
s_box_zerobytes() ->
binary:copy(<<0>>, enacl_nif:crypto_secretbox_BOXZEROBYTES()).
bump(Budget, Max, Sz) ->
Reds = (Budget * Sz) div Max,
erlang:bump_reductions(max(1, Reds)),
ok.
-3
View File
@@ -143,6 +143,3 @@ crypto_hash(Input) when is_binary(Input) -> not_loaded().
crypto_hash_b(Input) when is_binary(Input) -> not_loaded().
crypto_verify_16(_X, _Y) -> not_loaded().
crypto_verify_32(_X, _Y) -> not_loaded().
+61
View File
@@ -0,0 +1,61 @@
%%% @doc module enacl_timing provides helpers for timing enacl toward your installation
%%% @end
-module(enacl_timing).
-export([all/0]).
all() ->
[time_hashing(),
time_box()].
-define(ROUNDS, 300).
time_box() ->
Sz = 1024 * 32,
ZB = binary:copy(<<0>>, enacl_nif:crypto_box_ZEROBYTES()),
BZB = binary:copy(<<0>>, enacl_nif:crypto_box_BOXZEROBYTES()),
Bin = binary:copy(<<0>>, Sz),
Nonce = binary:copy(<<0>>, enacl_nif:crypto_box_NONCEBYTES()),
#{ public := PK1, secret := SK1 } = enacl:box_keypair(),
#{ public := PK2, secret := SK2 } = enacl:box_keypair(),
box([ZB, Bin], Nonce, PK1, SK2, ?ROUNDS),
T = timed(fun() -> box([ZB, Bin], Nonce, PK1, SK2, ?ROUNDS) end) / ?ROUNDS,
Boxed = enacl:box([ZB, Bin], Nonce, PK1, SK2),
box_open([BZB, Boxed], Nonce, PK2, SK1, ?ROUNDS),
T2 = timed(fun() -> box_open([BZB, Boxed], Nonce, PK2, SK1, ?ROUNDS) end) / ?ROUNDS,
[
#{ size => Sz, time => T, operation => box},
#{ size => Sz, time => T2, operation => box_open}
].
%% BOX
%% --------
box_open(_Bin, _Nonce, _PK, _SK, 0) -> ok;
box_open(Bin, Nonce, PK, SK, N) ->
enacl_nif:crypto_box_open_b(Bin, Nonce, PK, SK),
box_open(Bin, Nonce, PK, SK, N-1).
box(_Bin, _Nonce, _PK, _SK, 0) -> ok;
box(Bin, Nonce, PK, SK, N) ->
enacl_nif:crypto_box_b(Bin, Nonce, PK, SK),
box(Bin, Nonce, PK, SK, N-1).
%% HASHING
%% ----------------
time_hashing() ->
Sz = 1024 * 32,
Bin = binary:copy(<<0>>, Sz),
hash(Bin, ?ROUNDS),
T = timed(fun() -> hash(Bin, ?ROUNDS) end) / ?ROUNDS,
#{ size => Sz, time => T, operation => hash}.
hash(_Bin, 0) -> ok;
hash(Bin, N) ->
enacl_nif:crypto_hash_b(Bin),
hash(Bin, N-1).
%% Helpers
timed(Fun) ->
{T, _} = timer:tc(Fun),
T.