(** The password-hashing port. An adapter supplies a concrete algorithm, so the use case and the {!Trainee} entity never name one. The stored form is an opaque verifier string, wrapped by {!Trainee.credential_of_hash}. *) module type S = sig val hash : string -> string (** Salt and hash a new password into a stored verifier. *) val verify : hash:string -> string -> bool (** Check a candidate password against a stored verifier. The adapter supplies the comparison, so it decides the timing guarantee. *) end