-module(argus). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]). -export([hasher/0, hasher_argon2i/0, algorithm/2, time_cost/2, memory_cost/2, parallelism/2, hash_length/2, gen_salt/0, hash/3, verify/2]). -export_type([argon2_algorithm/0, hasher/0, hashes/0, hash_error/0]). -type argon2_algorithm() :: argon2d | argon2i | argon2id. -opaque hasher() :: {hasher, argon2_algorithm(), integer(), integer(), integer(), integer()}. -type hashes() :: {hashes, bitstring(), binary()}. -type hash_error() :: output_pointer_is_null | output_too_short | output_too_long | password_too_short | password_too_long | salt_too_short | salt_too_long | associated_data_too_short | associated_data_too_long | secret_too_short | secret_too_long | time_cost_too_small | time_cost_too_large | memory_cost_too_small | memory_cost_too_large | too_few_lanes | too_many_lanes | password_pointer_mismatch | salt_pointer_mismatch | secret_pointer_mismatch | associated_data_pointer_mismatch | memory_allocation_error | free_memory_callback_null | allocate_memory_callback_null | incorrect_parameter | incorrect_type | invalid_algorithm | output_pointer_mismatch | too_few_threads | too_many_threads | not_enough_memory | encoding_failed | decoding_failed | thread_failure | decoding_length_failure | verification_failure | unknown_error_code. -spec hasher() -> hasher(). hasher() -> {hasher, argon2id, 2, 19456, 1, 32}. -spec hasher_argon2i() -> hasher(). hasher_argon2i() -> {hasher, argon2i, 3, 12228, 1, 32}. -spec algorithm(hasher(), argon2_algorithm()) -> hasher(). algorithm(Hasher, Algorithm) -> erlang:setelement(2, Hasher, Algorithm). -spec time_cost(hasher(), integer()) -> hasher(). time_cost(Hasher, Time_cost) -> erlang:setelement(3, Hasher, Time_cost). -spec memory_cost(hasher(), integer()) -> hasher(). memory_cost(Hasher, Memory_cost) -> erlang:setelement(4, Hasher, Memory_cost). -spec parallelism(hasher(), integer()) -> hasher(). parallelism(Hasher, Parallelism) -> erlang:setelement(5, Hasher, Parallelism). -spec hash_length(hasher(), integer()) -> hasher(). hash_length(Hasher, Hash_length) -> erlang:setelement(6, Hasher, Hash_length). -spec gen_salt() -> binary(). gen_salt() -> argus_nif:gen_salt(). -spec hash(hasher(), binary(), binary()) -> {ok, hashes()} | {error, hash_error()}. hash(Hasher, Password, Salt) -> Result = argus_nif:hash( Password, Salt, erlang:element(2, Hasher), erlang:element(3, Hasher), erlang:element(4, Hasher), erlang:element(5, Hasher), erlang:element(6, Hasher) ), case Result of {ok, {Raw_hash, Encoded_hash}} -> {ok, {hashes, Raw_hash, Encoded_hash}}; {error, Error} -> {error, Error} end. -spec verify(binary(), binary()) -> {ok, boolean()} | {error, hash_error()}. verify(Encoded_hash, Password) -> jargon:verify(Encoded_hash, Password).