Improve and verify sign_*_detached functions.
Provide non-dirty-scheduler variants for small strings, accurately bump reductions for these strings. While here, provide EQC test cases for the two functions.
This commit is contained in:
parent
7b64f3e52b
commit
92109eb354
@ -1020,7 +1020,10 @@ static ErlNifFunc nif_funcs[] = {
|
|||||||
{"crypto_sign_open_b", 2, enif_crypto_sign_open},
|
{"crypto_sign_open_b", 2, enif_crypto_sign_open},
|
||||||
{"crypto_sign_open", 2, enif_crypto_sign_open, ERL_NIF_DIRTY_JOB_CPU_BOUND},
|
{"crypto_sign_open", 2, enif_crypto_sign_open, ERL_NIF_DIRTY_JOB_CPU_BOUND},
|
||||||
|
|
||||||
|
|
||||||
|
{"crypto_sign_detached_b", 2, enif_crypto_sign_detached},
|
||||||
{"crypto_sign_detached", 2, enif_crypto_sign_detached, ERL_NIF_DIRTY_JOB_CPU_BOUND},
|
{"crypto_sign_detached", 2, enif_crypto_sign_detached, ERL_NIF_DIRTY_JOB_CPU_BOUND},
|
||||||
|
{"crypto_sign_verify_detached_b", 3, enif_crypto_sign_verify_detached},
|
||||||
{"crypto_sign_verify_detached", 3, enif_crypto_sign_verify_detached, ERL_NIF_DIRTY_JOB_CPU_BOUND},
|
{"crypto_sign_verify_detached", 3, enif_crypto_sign_verify_detached, ERL_NIF_DIRTY_JOB_CPU_BOUND},
|
||||||
|
|
||||||
{"crypto_box_SEALBYTES", 0, enif_crypto_box_SEALBYTES},
|
{"crypto_box_SEALBYTES", 0, enif_crypto_box_SEALBYTES},
|
||||||
|
@ -2,13 +2,6 @@
|
|||||||
-include_lib("eqc/include/eqc.hrl").
|
-include_lib("eqc/include/eqc.hrl").
|
||||||
-compile(export_all).
|
-compile(export_all).
|
||||||
|
|
||||||
%% dummy test property
|
|
||||||
prop_append() ->
|
|
||||||
?FORALL({Xs,Ys},{list(int()),list(int())},
|
|
||||||
lists:reverse(Xs++Ys)
|
|
||||||
==
|
|
||||||
lists:reverse(Ys) ++ lists:reverse(Xs)).
|
|
||||||
|
|
||||||
non_byte_int() ->
|
non_byte_int() ->
|
||||||
oneof([
|
oneof([
|
||||||
?LET(N, nat(), -(N+1)),
|
?LET(N, nat(), -(N+1)),
|
||||||
@ -295,6 +288,22 @@ sign_keypair_secret_valid(_) -> false.
|
|||||||
sign_keypair_valid(KP) ->
|
sign_keypair_valid(KP) ->
|
||||||
sign_keypair_public_valid(KP) andalso sign_keypair_secret_valid(KP).
|
sign_keypair_public_valid(KP) andalso sign_keypair_secret_valid(KP).
|
||||||
|
|
||||||
|
prop_sign_detached() ->
|
||||||
|
?FORALL({Msg, KeyPair},
|
||||||
|
{fault_rate(1, 40, g_iodata()),
|
||||||
|
fault_rate(1, 40, sign_keypair())},
|
||||||
|
begin
|
||||||
|
case v_iodata(Msg) andalso sign_keypair_secret_valid(KeyPair) of
|
||||||
|
true ->
|
||||||
|
#{ secret := Secret } = KeyPair,
|
||||||
|
enacl:sign_detached(Msg, Secret),
|
||||||
|
true;
|
||||||
|
false ->
|
||||||
|
#{ secret := Secret } = KeyPair,
|
||||||
|
badargs(fun() -> enacl:sign_detached(Msg, Secret) end)
|
||||||
|
end
|
||||||
|
end).
|
||||||
|
|
||||||
prop_sign() ->
|
prop_sign() ->
|
||||||
?FORALL({Msg, KeyPair},
|
?FORALL({Msg, KeyPair},
|
||||||
{fault_rate(1, 40, g_iodata()),
|
{fault_rate(1, 40, g_iodata()),
|
||||||
@ -322,17 +331,50 @@ signed_message_good(M) ->
|
|||||||
pk -> {{invalid, SM}, binary(byte_size(PK))}
|
pk -> {{invalid, SM}, binary(byte_size(PK))}
|
||||||
end)}]).
|
end)}]).
|
||||||
|
|
||||||
|
signed_message_good_d(M) ->
|
||||||
|
#{ public := PK, secret := SK} = enacl:sign_keypair(),
|
||||||
|
Sig = enacl:sign_detached(M, SK),
|
||||||
|
frequency([
|
||||||
|
{3, return({{valid, Sig}, PK})},
|
||||||
|
{1, ?LET(X, elements([sm, pk]),
|
||||||
|
case X of
|
||||||
|
sm -> {{invalid, binary(byte_size(Sig))}, PK};
|
||||||
|
pk -> {{invalid, Sig}, binary(byte_size(PK))}
|
||||||
|
end)}]).
|
||||||
|
|
||||||
signed_message_bad() ->
|
signed_message_bad() ->
|
||||||
Sz = enacl:sign_keypair_public_size(),
|
Sz = enacl:sign_keypair_public_size(),
|
||||||
{binary(), oneof([a, int(), ?SUCHTHAT(B, binary(Sz), byte_size(B) /= Sz)])}.
|
{binary(), oneof([a, int(), ?SUCHTHAT(B, binary(Sz), byte_size(B) /= Sz)])}.
|
||||||
|
|
||||||
|
signed_message_bad_d() ->
|
||||||
|
Sz = enacl:sign_keypair_public_size(),
|
||||||
|
{binary(), oneof([a, int(), ?SUCHTHAT(B, binary(Sz), byte_size(B) /= Sz)])}.
|
||||||
|
|
||||||
signed_message(M) ->
|
signed_message(M) ->
|
||||||
fault(signed_message_bad(), signed_message_good(M)).
|
fault(signed_message_bad(), signed_message_good(M)).
|
||||||
|
|
||||||
|
signed_message_d(M) ->
|
||||||
|
fault(signed_message_bad(), signed_message_good(M)).
|
||||||
|
|
||||||
signed_message_valid({valid, _}, _) -> true;
|
signed_message_valid({valid, _}, _) -> true;
|
||||||
signed_message_valid({invalid, _}, _) -> true;
|
signed_message_valid({invalid, _}, _) -> true;
|
||||||
signed_message_valid(_, _) -> false.
|
signed_message_valid(_, _) -> false.
|
||||||
|
|
||||||
|
prop_sign_detached_open() ->
|
||||||
|
?FORALL(Msg, g_iodata(),
|
||||||
|
?FORALL({SignMsg, PK}, signed_message_d(Msg),
|
||||||
|
case v_iodata(Msg) andalso signed_message_valid(SignMsg, PK) of
|
||||||
|
true ->
|
||||||
|
case SignMsg of
|
||||||
|
{valid, Sig} ->
|
||||||
|
equals({ok, Msg}, enacl:sign_verify_detached(Sig, Msg, PK));
|
||||||
|
{invalid, Sig} ->
|
||||||
|
equals({error, failed_verification}, enacl:sign_verify_detached(Sig, Msg, PK))
|
||||||
|
end;
|
||||||
|
false ->
|
||||||
|
badargs(fun() -> enacl:sign_verify_detached(SignMsg, Msg, PK) end)
|
||||||
|
end)).
|
||||||
|
|
||||||
prop_sign_open() ->
|
prop_sign_open() ->
|
||||||
?FORALL(Msg, g_iodata(),
|
?FORALL(Msg, g_iodata(),
|
||||||
?FORALL({SignMsg, PK}, signed_message(Msg),
|
?FORALL({SignMsg, PK}, signed_message(Msg),
|
||||||
|
@ -395,7 +395,13 @@ sign_open(SM, PK) ->
|
|||||||
M :: iodata(),
|
M :: iodata(),
|
||||||
SK :: binary(),
|
SK :: binary(),
|
||||||
DS :: binary().
|
DS :: binary().
|
||||||
sign_detached(M, SK) -> enacl_nif:crypto_sign_detached(M, SK).
|
sign_detached(M, SK) ->
|
||||||
|
case iolist_size(M) of
|
||||||
|
K when K =< ?SIGN_SIZE ->
|
||||||
|
bump(enacl_nif:crypto_sign_detached_b(M, SK), ?SIGN_REDUCTIONS, ?SIGN_SIZE, K);
|
||||||
|
_ ->
|
||||||
|
enacl_nif:crypto_sign_detached(M, SK)
|
||||||
|
end.
|
||||||
|
|
||||||
%% @doc sign_verify_detached/3 verifies the given signature against the given
|
%% @doc sign_verify_detached/3 verifies the given signature against the given
|
||||||
%% message for the given public key.
|
%% message for the given public key.
|
||||||
@ -408,7 +414,13 @@ sign_detached(M, SK) -> enacl_nif:crypto_sign_detached(M, SK).
|
|||||||
M :: iodata(),
|
M :: iodata(),
|
||||||
PK :: binary().
|
PK :: binary().
|
||||||
sign_verify_detached(SIG, M, PK) ->
|
sign_verify_detached(SIG, M, PK) ->
|
||||||
case enacl_nif:crypto_sign_verify_detached(SIG, M, PK) of
|
SignRes = case iolist_size(M) of
|
||||||
|
K when K =< ?SIGN_SIZE ->
|
||||||
|
bump(enacl_nif:crypto_sign_verify_detached_b(SIG, M, PK), ?SIGN_REDUCTIONS, ?SIGN_SIZE, K);
|
||||||
|
_ ->
|
||||||
|
enacl_nif:crypto_sign_detached(SIG, M, PK)
|
||||||
|
end,
|
||||||
|
case SignRes of
|
||||||
true -> {ok, M};
|
true -> {ok, M};
|
||||||
false -> {error, failed_verification}
|
false -> {error, failed_verification}
|
||||||
end.
|
end.
|
||||||
|
@ -34,7 +34,9 @@
|
|||||||
crypto_sign_open_b/2,
|
crypto_sign_open_b/2,
|
||||||
|
|
||||||
crypto_sign_detached/2,
|
crypto_sign_detached/2,
|
||||||
|
crypto_sign_detached_b/2,
|
||||||
crypto_sign_verify_detached/3,
|
crypto_sign_verify_detached/3,
|
||||||
|
crypto_sign_verify_detached_b/3,
|
||||||
|
|
||||||
crypto_box_seal/2,
|
crypto_box_seal/2,
|
||||||
crypto_box_seal_open/3,
|
crypto_box_seal_open/3,
|
||||||
@ -153,7 +155,10 @@ crypto_sign_open(_SignedMessage, _PK) -> erlang:nif_error(nif_not_loaded).
|
|||||||
crypto_sign_open_b(_SignedMessage, _PK) -> erlang:nif_error(nif_not_loaded).
|
crypto_sign_open_b(_SignedMessage, _PK) -> erlang:nif_error(nif_not_loaded).
|
||||||
|
|
||||||
crypto_sign_detached(_M, _SK) -> erlang:nif_error(nif_not_loaded).
|
crypto_sign_detached(_M, _SK) -> erlang:nif_error(nif_not_loaded).
|
||||||
crypto_sign_verify_detached(_SIG, _M, _PK) -> erlang:nif_error(nif_not_loaded).
|
crypto_sign_detached_b(_M, _SK) -> erlang:nif_error(nif_not_loaded).
|
||||||
|
|
||||||
|
crypto_sign_verify_detached(_Sig, _M, _PK) -> erlang:nif_error(nif_not_loaded).
|
||||||
|
crypto_sign_verify_detached_b(_Sig, _M, _PK) -> erlang:nif_error(nif_not_loaded).
|
||||||
|
|
||||||
crypto_box_seal(_Msg, _PK) -> erlang:nif_error(nif_not_loaded).
|
crypto_box_seal(_Msg, _PK) -> erlang:nif_error(nif_not_loaded).
|
||||||
crypto_box_seal_open(_CipherText, _PK, _SK) -> erlang:nif_error(nif_not_loaded).
|
crypto_box_seal_open(_CipherText, _PK, _SK) -> erlang:nif_error(nif_not_loaded).
|
||||||
|
Loading…
x
Reference in New Issue
Block a user