 ;; Key Parsing
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
-(defmulti parse-password
-  "Parse password from string to parts."
-  (fn [encryptedpassword]
-    (let [[alg, rest] (str/split encryptedpassword #"\$" 2)]
-      (keyword alg))))
-
 (defmethod parse-password :scrypt
   [encryptedpassword]
   (let [[algorithm salt cc mc pll password] (str/split encryptedpassword #"\$")

(defn check
  "Check if a unencrypted password matches
  with another encrypted password."
  [attempt encrypted]
  (when (and attempt encrypted)
    (let [pwdparams (parse-password encrypted)
          attempt (str->bytes attempt)]
      (check-password pwdparams attempt))))

  {:pbkdf2+sha1 100000
   :pbkdf2+sha256 100000
   :pbkdf2+sha3_256 100000
   :bcrypt+sha512 12
   :scrypt {:cpucost 65536
            :memcost 8}})

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Impl Interface
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(defmulti parse-password
  "Parse password from string to parts."
  (fn [encryptedpassword]
    (-> encryptedpassword
        (str/split #"\$")
        (first)
        (keyword))))

(defmulti derive-password
  "Derive key depending on algorithm."
  :algorithm)

(defmulti check-password
  "Password verification implementation."
  :algorithm)

(defmulti format-password
  "Format password depending on algorithm."
  :algorithm)

(defmulti must-update?
  "Check if the current password configuration
  is succeptible to be updatable."
  :algorithm)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Key Derivation
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(defmethod derive-password :pbkdf2+sha1
  [{:keys [algorithm password salt iterations] :as pwdparams}]
