Fix box_seal/2 and box_seal_open/3.
* Call the functions `box_seal` and `box_seal_open` to match the libsodium names in module `enacl`. * Fix a bug in the C NIF: We should fail if the input is `<` SEALBYTES but not on `<=` SEALBYTES. The latter made it impossible to encode empty messages. * Add variants which run directly on the interpreter scheduler for small messages. Also: * Provide full EQC functions for the testing purposes. This generated around 13000 random test cases in a 5 minute run, all passing.# Please enter the commit message for your changes. Lines starting
This commit is contained in:
parent
4676328efa
commit
f444d1e4ac
@ -598,7 +598,7 @@ ERL_NIF_TERM enif_crypto_box_seal_open(ErlNifEnv *env, int argc, ERL_NIF_TERM co
|
||||
return enif_make_badarg(env);
|
||||
}
|
||||
|
||||
if (ciphertext.size <= crypto_box_SEALBYTES) {
|
||||
if (ciphertext.size < crypto_box_SEALBYTES) {
|
||||
return enif_make_badarg(env);
|
||||
}
|
||||
|
||||
@ -1027,7 +1027,10 @@ static ErlNifFunc nif_funcs[] = {
|
||||
{"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_seal_b", 2, enif_crypto_box_seal},
|
||||
{"crypto_box_seal", 2, enif_crypto_box_seal, ERL_NIF_DIRTY_JOB_CPU_BOUND},
|
||||
{"crypto_box_seal_open_b", 3, enif_crypto_box_seal_open},
|
||||
{"crypto_box_seal_open", 3, enif_crypto_box_seal_open, ERL_NIF_DIRTY_JOB_CPU_BOUND},
|
||||
|
||||
{"crypto_secretbox_NONCEBYTES", 0, enif_crypto_secretbox_NONCEBYTES},
|
||||
|
@ -129,6 +129,20 @@ box(Msg, Nonce , PK, SK) ->
|
||||
error:badarg -> badarg
|
||||
end.
|
||||
|
||||
box_seal(Msg, PK) ->
|
||||
try
|
||||
enacl:box_seal(Msg, PK)
|
||||
catch
|
||||
error:badarg -> badarg
|
||||
end.
|
||||
|
||||
box_seal_open(Cph, PK, SK) ->
|
||||
try
|
||||
enacl:box_seal_open(Cph, PK, SK)
|
||||
catch
|
||||
error:badarg -> badarg
|
||||
end.
|
||||
|
||||
box_open(CphText, Nonce, PK, SK) ->
|
||||
try
|
||||
enacl:box_open(CphText, Nonce, PK, SK)
|
||||
@ -137,7 +151,8 @@ box_open(CphText, Nonce, PK, SK) ->
|
||||
end.
|
||||
|
||||
failure(badarg) -> true;
|
||||
failure(_) -> false.
|
||||
failure({error, failed_verification}) -> true;
|
||||
failure(X) -> {failure, X}.
|
||||
|
||||
prop_box_correct() ->
|
||||
?FORALL({Msg, Nonce, {PK1, SK1}, {PK2, SK2}},
|
||||
@ -188,6 +203,41 @@ prop_box_failure_integrity() ->
|
||||
end
|
||||
end
|
||||
end).
|
||||
|
||||
prop_seal_box_failure_integrity() ->
|
||||
?FORALL({Msg, {PK1, SK1}}, {fault_rate(1,40,g_iodata()), fault_rate(1,40,keypair())},
|
||||
begin
|
||||
case v_iodata(Msg) andalso keypair_valid(PK1, SK1) of
|
||||
true ->
|
||||
CT = enacl:box_seal(Msg, PK1),
|
||||
Err = enacl:box_seal_open([<<"x">>, CT], PK1, SK1),
|
||||
equals(Err, {error, failed_verification});
|
||||
false ->
|
||||
case box_seal(Msg, PK1) of
|
||||
badarg -> true;
|
||||
Res ->
|
||||
failure(box_seal_open(Res, PK1, SK1))
|
||||
end
|
||||
end
|
||||
end).
|
||||
|
||||
prop_seal_box_correct() ->
|
||||
?FORALL({Msg, {PK1, SK1}},
|
||||
{fault_rate(1, 40, g_iodata()),
|
||||
fault_rate(1, 40, keypair())},
|
||||
begin
|
||||
case v_iodata(Msg) andalso keypair_valid(PK1, SK1) of
|
||||
true ->
|
||||
SealedCipherText = enacl:box_seal(Msg, PK1),
|
||||
{ok, DecodedMsg} = enacl:box_seal_open(SealedCipherText, PK1, SK1),
|
||||
equals(iolist_to_binary(Msg), DecodedMsg);
|
||||
false ->
|
||||
case box_seal(Msg, PK1) of
|
||||
badarg -> true;
|
||||
Res -> failure(box_seal_open(Res, PK1, SK1))
|
||||
end
|
||||
end
|
||||
end).
|
||||
|
||||
%% PRECOMPUTATIONS
|
||||
beforenm_key() ->
|
||||
|
@ -38,8 +38,8 @@
|
||||
sign_detached/2,
|
||||
sign_verify_detached/3,
|
||||
|
||||
seal_box/2,
|
||||
seal_box_open/3
|
||||
box_seal/2,
|
||||
box_seal_open/3
|
||||
]).
|
||||
|
||||
%% Secret key crypto
|
||||
@ -436,12 +436,17 @@ box_secret_key_bytes() ->
|
||||
%% keypair and then uses `box'. Ephemeral public key will sent to other party. Returns the
|
||||
%% enciphered message `SealedCipherText' which includes ephemeral public key at head.
|
||||
%% @end
|
||||
-spec seal_box(Msg, PK) -> SealedCipherText
|
||||
-spec box_seal(Msg, PK) -> SealedCipherText
|
||||
when Msg :: iodata(),
|
||||
PK :: binary(),
|
||||
SealedCipherText :: binary().
|
||||
seal_box(Msg, PK) ->
|
||||
enacl_nif:crypto_box_seal(Msg, PK).
|
||||
box_seal(Msg, PK) ->
|
||||
case iolist_size(Msg) of
|
||||
K when K =< ?BOX_SIZE ->
|
||||
bump(enacl_nif:crypto_box_seal_b(Msg, PK), ?BOX_REDUCTIONS, ?BOX_SIZE, K);
|
||||
_ ->
|
||||
enacl_nif:crypto_box_seal(Msg, PK)
|
||||
end.
|
||||
|
||||
%% @doc seal_box_open/3 decrypts+check message integrity from an unknown sender.
|
||||
%%
|
||||
@ -449,16 +454,25 @@ seal_box(Msg, PK) ->
|
||||
%% into a `Msg' using that key and your public and secret keys, `PK' and `SK'. Returns the
|
||||
%% plaintext message.
|
||||
%% @end
|
||||
-spec seal_box_open(SealedCipherText, PK, SK) -> {ok, Msg} | {error, failed_verification}
|
||||
-spec box_seal_open(SealedCipherText, PK, SK) -> {ok, Msg} | {error, failed_verification}
|
||||
when SealedCipherText :: iodata(),
|
||||
PK :: binary(),
|
||||
SK :: binary(),
|
||||
Msg :: binary().
|
||||
seal_box_open(SealedCipherText, PK, SK) ->
|
||||
case enacl_nif:crypto_box_seal_open(SealedCipherText, PK, SK) of
|
||||
{error, Err} -> {error, Err};
|
||||
Bin when is_binary(Bin) -> Bin
|
||||
end.
|
||||
box_seal_open(SealedCipherText, PK, SK) ->
|
||||
case iolist_size(SealedCipherText) of
|
||||
K when K =< ?BOX_SIZE ->
|
||||
R = case enacl_nif:crypto_box_seal_open_b(SealedCipherText, PK, SK) of
|
||||
{error, Err} -> {error, Err};
|
||||
Bin when is_binary(Bin) -> {ok, Bin}
|
||||
end,
|
||||
bump(R, ?BOX_REDUCTIONS, ?BOX_SIZE, K);
|
||||
_ ->
|
||||
case enacl_nif:crypto_box_seal_open(SealedCipherText, PK, SK) of
|
||||
{error, Err} -> {error, Err};
|
||||
Bin when is_binary(Bin) -> {ok, Bin}
|
||||
end
|
||||
end.
|
||||
|
||||
%% @doc secretbox/3 encrypts a message with a key
|
||||
%%
|
||||
|
@ -39,6 +39,8 @@
|
||||
crypto_sign_verify_detached_b/3,
|
||||
|
||||
crypto_box_seal/2,
|
||||
crypto_box_seal_b/2,
|
||||
crypto_box_seal_open_b/3,
|
||||
crypto_box_seal_open/3,
|
||||
crypto_box_SEALBYTES/0
|
||||
|
||||
@ -160,7 +162,9 @@ 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_b(_Msg, _PK) -> erlang:nif_error(nif_not_loaded).
|
||||
crypto_box_seal(_Msg, _PK) -> erlang:nif_error(nif_not_loaded).
|
||||
crypto_box_seal_open_b(_CipherText, _PK, _SK) -> erlang:nif_error(nif_not_loaded).
|
||||
crypto_box_seal_open(_CipherText, _PK, _SK) -> erlang:nif_error(nif_not_loaded).
|
||||
crypto_box_SEALBYTES() -> erlang:nif_error(nif_not_loaded).
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user