Packages
argon2_elixir
0.8.0
4.1.3
4.1.2
4.1.1
4.1.0
4.0.0
3.2.1
3.2.0
3.1.0
3.0.0
2.4.1
2.4.0
2.3.0
2.2.1
2.2.0
2.1.2
2.1.1
2.1.0
2.0.5
2.0.4
2.0.3
2.0.2
2.0.1
2.0.0
1.3.3
1.3.1
1.3.0
1.2.14
1.2.13
1.2.12
1.2.11
1.2.10
1.2.9
1.2.8
1.2.7
1.2.6
1.2.5
1.2.4
1.2.2
1.2.1
1.2.0
1.1.0
1.0.0
0.12.0
0.11.4
0.11.3
0.11.2
0.11.0
0.10.1
0.10.0
0.9.1
0.9.0
0.8.0
Argon2 password hashing algorithm for Elixir
Current section
Files
Jump to
Current section
Files
lib/argon2.ex
defmodule Argon2 do
@moduledoc """
Elixir wrapper for the Argon2 password hashing algorithm.
"""
@compile {:autoload, false}
@on_load {:init, 0}
def init do
path = :filename.join(:code.priv_dir(:argon2_elixir), 'argon2_nif')
:erlang.load_nif(path, 0)
end
@doc """
Generate a random salt.
"""
def gen_salt(salt_len \\ 16), do: :crypto.strong_rand_bytes(salt_len)
def argon2_hash_nif(t_cost, m_cost, parallelism, password, salt, hashlen, encoded, argon2_type)
def argon2_hash_nif(_, _, _, _, _, _, _, _), do: exit(:nif_library_not_loaded)
def argon2_verify_nif(stored_hash, password, argon2_type)
def argon2_verify_nif(_, _, _), do: exit(:nif_library_not_loaded)
@doc """
Hash a password using Argon2.
"""
def hash_password(password, salt, opts \\ [])
def hash_password(_, salt, _) when byte_size(salt) < 8 do
raise ArgumentError, "The salt is too short - it should be 8 characters or longer"
end
def hash_password(password, salt, opts) do
argon2_hash_nif(Keyword.get(opts, :t_cost, 3),
Keyword.get(opts, :m_cost, 12),
Keyword.get(opts, :parallelism, 1),
password,
salt,
Keyword.get(opts, :hashlen, 32),
Keyword.get(opts, :encoded, 1),
Keyword.get(opts, :argon2_type, 1))
|> :binary.list_to_bin
end
@doc """
Generate a random salt and hash a password using Argon2.
"""
def hash_pwd_salt(password, opts \\ []) do
salt = Keyword.get(opts, :salt_len, 16) |> gen_salt
hash_password(password, salt, opts)
end
@doc """
Verify an encoded Argon2 hash.
"""
def verify_hash(stored_hash, password, opts \\ []) do
hash = :binary.bin_to_list(stored_hash)
case argon2_verify_nif(hash, password, Keyword.get(opts, :argon2_type, 1)) do
0 -> true
_ -> false
end
end
end