A behaviour providing password hashing.
Summary
Callbacks
Whether the same input always produces the same hash output.
Given some user input as a string, convert it into it's hashed form.
Hash with action context.
The minimum bits of input entropy required for this hash provider to be safe.
Attempt to defeat timing attacks by simulating a password hash check.
Check if the user input matches the hash.
Functions
Calls hash/2 if the provider implements it, otherwise falls back to hash/1.
Callbacks
@callback deterministic?() :: boolean()
Whether the same input always produces the same hash output.
Deterministic providers (e.g. SHA-256) allow atomic database-level verification by hashing the input and matching directly against stored values. Non-deterministic providers (e.g. bcrypt, argon2) use random salts, so verification requires loading stored hashes and comparing individually.
Given some user input as a string, convert it into it's hashed form.
Hash with action context.
An optional variant of hash/1 that receives the Ash context from the
current action (changeset or action input). This enables hash providers
that need external state — for example, a shared-salt provider can read
a pre-generated salt from the context.
When implemented, this callback is preferred over hash/1 by the
recovery code strategy's hashing change and verify action.
@callback minimum_entropy() :: non_neg_integer()
The minimum bits of input entropy required for this hash provider to be safe.
Slow hash providers like bcrypt and argon2 return 0 because their
computational cost makes brute-force attacks impractical regardless of input
entropy. Fast deterministic hash providers like SHA-256 require high-entropy
inputs (e.g. 60+ bits) because their speed makes low-entropy inputs
vulnerable to offline brute-force attacks.
@callback simulate() :: false
Attempt to defeat timing attacks by simulating a password hash check.
See Bcrypt.no_user_verify/1 for more information.
Check if the user input matches the hash.