      :salt (hex->bytes salt)
      :password (hex->bytes password)
      :iterations (Integer/parseInt iterations)}))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Update Algorithm
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defmethod must-update? :default
+  [{:keys [algorithm iterations]}]
+  (let [desired-iterations (get *default-iterations* algorithm)]
+    (and desired-iterations (> desired-iterations iterations))))
+
+(defmethod must-update? :scrypt
+  [{:keys [algorithm memcost cpucost]}]
+  (let [desired-memcost (get-in *default-iterations* [:scrypt :memcost])
+        desired-cpucost (get-in *default-iterations* [:scrypt :cpucost])]
+    (and desired-cpucost
+         desired-memcost
+         (or (> desired-memcost memcost)
+             (> desired-cpucost cpucost)))))
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; Public Api

(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))))

;; Key Parsing
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(defmethod parse-password :scrypt
  [encryptedpassword]
  (let [[algorithm salt cc mc pll password] (str/split encryptedpassword #"\$")
