diff -urp password_policy.old/constraints/constraint_history.inc password_policy/constraints/constraint_history.inc
--- password_policy.old/constraints/constraint_history.inc	Fri May  8 15:19:02 2009
+++ password_policy/constraints/constraint_history.inc	Tue Nov  3 13:19:30 2009
@@ -26,28 +26,81 @@ function password_policy_constraint_hist
  * Password validation.
  */
 function password_policy_constraint_history_validate($password, $constraint, $uid) {
-  return !in_array(md5($password), _password_policy_constraint_history_old_passwords($constraint, $uid));
+  $old_hashes = _password_policy_constraint_history_old_passwords($constraint, $uid);
+  foreach ($old_hashes as $hash) {
+    if (_password_policy_check_hash($password, $hash)) {
+      return FALSE;
+    }
+  }
+
+  return TRUE;
+}
+
+function password_policy_constraint_history_validate_js($account) {
+  if (drupal_valid_token($_GET['token'], $account->uid)) {
+    $password = $_POST['password'];
+    $constraint = intval($_POST['constraint']);
+    print drupal_to_js(password_policy_constraint_history_validate($password, $constraint, $account->uid));
+  }
+  session_save_session(FALSE);
+  exit();
 }
 
 /**
  * Javascript portion.
  */
 function password_policy_constraint_history_js($constraint, $uid) {
-  drupal_add_js(drupal_get_path('module', 'password_policy') .'/constraints/scripts/webtoolkit.md5.js');
-  $pass = _password_policy_constraint_history_old_passwords($constraint, $uid);
+  $token = drupal_get_token($uid);
   $s = '';
-  $s .= "  var num=0;\n";
-  $s .= "  var pass=new Array(\"". implode('","', $pass) ."\");\n";
-  $s .= "  var i;\n";
-  $s .= "  for (i=0;i<pass.length;i++) {\n";
-  $s .= "    if (pass[i] == MD5(value)) {\n";
-  $s .= "      num=1;\n";
+  $s .= "  var outerItemElement = $(context).parent().parent().get(0);\n";
+  $s .= "  if (outerItemElement.cache[value]) {\n";
+  $s .= "    if (!outerItemElement.cache[value].valid) {\n";
+  $s .= "      strength = outerItemElement.cache[value].strength;\n";
+  $s .= "      msg.push(outerItemElement.cache[value].message)\n";
   $s .= "    }\n";
   $s .= "  }\n";
-  $s .= "  if (num>0) {\n";
-  $s .= "    strength=\"low\";\n";
-  $s .= "    msg.push(translate.constraint_history);\n";
+  $s .= "  else {\n";
+  $s .= "    outerItemElement.toBeChecked = value;\n";
+  $s .= "    $(context).addClass('throbbing');\n";
+  $s .= "    $.post(\n";
+  $s .= "      Drupal.settings.basePath + '?q=password_policy/history/$uid&token=$token',\n";
+  $s .= "      { password: value, constraint: $constraint },\n";
+  $s .= "      function (data) {\n";
+  $s .= "        if (!data) {\n";
+  $s .= "          var strength = \"low\";\n";
+  $s .= "          var msg = translate.constraint_history;\n";
+  $s .= "          if (outerItemElement.toBeChecked == value) {\n";
+  $s .= "            var classMap = { low: \"error\", medium: \"warning\", high: \"ok\" };\n";
+  $s .= "            var newClass = classMap[strength] || \"\";\n";
+  $s .= "            var parent = $(outerItemElement).find(\"div.password-parent\");\n";
+  $s .= "            var passwordStrength = $(\"span.password-strength\", parent);\n";
+  $s .= "            var passwordResult = $(\"span.password-result\", passwordStrength).html(translate[strength +\"Strength\"]);\n";
+  $s .= "            var passwordDescription = $(\"div.password-description\", $(context).parent().parent()).hide();\n";
+  $s .= "            if (context.passwordClass) {\n";
+  $s .= "              passwordResult.removeClass(context.passwordClass);\n";
+  $s .= "              passwordDescription.removeClass(context.passwordClass);\n";
+  $s .= "            }\n";
+  $s .= "            var passwordDescriptionList = passwordDescription.find(\"ul\");\n";
+  $s .= "            if (!passwordDescriptionList.size()) {\n";
+  $s .= "              passwordDescriptionList = passwordDescription.html(translate.needsMoreVariation +\"<ul></ul>\").find(\"ul\");\n";
+  $s .= "            }\n";
+  $s .= "            passwordDescriptionList.append(\"<li>\"+msg+\"</li>\");\n";
+  $s .= "            passwordResult.addClass(newClass);\n";
+  $s .= "            passwordDescription.show();\n";
+  $s .= "            passwordDescription.addClass(newClass);\n";
+  $s .= "            context.passwordClass = newClass;\n";
+  $s .= "          }\n";
+  $s .= "          outerItemElement.cache[value] = { valid: false, strength: strength, message: msg };\n";
+  $s .= "        }\n";
+  $s .= "        else {\n";
+  $s .= "          outerItemElement.cache[value] = { valid: true };\n";
+  $s .= "        }\n";
+  $s .= "        $(context).removeClass('throbbing');\n";
+  $s .= "      },\n";
+  $s .= "      \"json\"\n";
+  $s .= "    );\n";
   $s .= "  }\n";
+
   return $s;
 }
 
diff -urp password_policy.old/password_policy.install password_policy/password_policy.install
--- password_policy.old/password_policy.install	Sun Oct 26 11:21:06 2008
+++ password_policy/password_policy.install	Tue Nov  3 13:13:56 2009
@@ -109,9 +109,9 @@ function password_policy_schema() {
           'not null' => TRUE,
         ),
         'pass' => array(
-          'description' => t("User's password (md5 hash)."),
+          'description' => t("User's password hash."),
           'type' => 'varchar',
-          'length' => 32,
+          'length' => 60,
           'not null' => TRUE,
         ),
         'created' => array(
@@ -154,5 +154,14 @@ function password_policy_schema() {
       'indexes' => array('uid' => array('uid')),
     ),
   );
+}
+
+/**
+ * Alter table password_policy_history to accommodate phpass hash
+ */
+function password_policy_update_6001() {
+  $ret = array();
+  $ret[] = update_sql("ALTER TABLE {password_policy_history} CHANGE pass pass varchar(60) NOT NULL");
+  return $ret;
 }
 
diff -urp password_policy.old/password_policy.js password_policy/password_policy.js
--- password_policy.old/password_policy.js	Sun Feb 10 16:35:40 2008
+++ password_policy/password_policy.js	Tue Nov  3 13:17:30 2009
@@ -44,8 +44,7 @@ Drupal.behaviors.password = function(con
       }
 
       // Evaluate password strength.
-
-      var result = Drupal.evaluatePasswordStrength(passwordInput.val());
+      var result = Drupal.evaluatePasswordStrength(passwordInput.val(), this);
       passwordResult.html(result.strength == "" ? "" : translate[result.strength +"Strength"]);
 
       // Map the password strength to the relevant drupal CSS class.
@@ -104,11 +103,17 @@ Drupal.behaviors.password = function(con
       }
 
       // Schedule the actual check.
-      this.timer = setTimeout(passwordCheck, monitorDelay);
+      var that = this;
+      this.timer = setTimeout(function () { passwordCheck.apply(that); }, monitorDelay);
     };
+
+    var outerItemElement = outerItem.get(0);
+    outerItemElement.toBeChecked = '';
+    outerItemElement.cache = {};
+
     // Monitor keyup and blur events.
     // Blur must be used because a mouse paste does not trigger keyup.
-    passwordInput.keyup(passwordDelayedCheck).blur(passwordCheck);
+    passwordInput.addClass('form-autocomplete').keyup(passwordDelayedCheck).blur(passwordCheck);
     confirmInput.keyup(passwordDelayedCheck).blur(passwordCheck);
   });
 };
diff -urp password_policy.old/password_policy.module password_policy/password_policy.module
--- password_policy.old/password_policy.module	Mon Oct 19 16:31:50 2009
+++ password_policy/password_policy.module	Tue Nov  3 13:13:56 2009
@@ -143,6 +143,13 @@ function password_policy_menu() {
     'page arguments' => array(4),
     'access arguments' => array('unblock expired accounts'),
   );
+  $items['password_policy/history/%user_uid_optional'] = array(
+    'page callback' => 'password_policy_constraint_history_validate_js',
+    'page arguments' => array(2),
+    'access callback' => user_edit_access,
+    'access arguments' => array(2),
+    'type' => MENU_CALLBACK,
+  );
   return $items;
 }
 
@@ -702,7 +709,58 @@ function _password_policy_start($expirat
  *   Clear text password.
  */
 function _password_policy_store_password($uid, $pass) {
-  db_query("INSERT INTO {password_policy_history} (uid, pass, created) VALUES (%d, '%s', %d)", $uid, md5($pass), time());
+  $hash = _password_policy_hash_password($pass);
+  db_query("INSERT INTO {password_policy_history} (uid, pass, created) VALUES (%d, '%s', %d)", $uid, $hash, time());
+}
+
+/**
+ * Generate a password hash.
+ *  IF   phpass module is enabled, generates using phpass,
+ *  ELSE regular md5
+ *
+ * @param $pass
+ *   Clear text password.
+ */
+function _password_policy_hash_password($pass) {
+  if (_password_policy_phpass_enabled()) {
+    return _password_policy_phpass_hash($pass);
+  }
+  return md5($pass);
+}
+
+/**
+ * Check a password against a known hash
+ * @return
+ *   TRUE if hashes match
+ */
+function _password_policy_check_hash($pass, $known_hash) {
+  if (_password_policy_phpass_enabled()) {
+    $phpass = _password_policy_new_phpass();
+    return $phpass->CheckPassword($pass, $known_hash);
+  }
+
+  return md5($pass) == $known_hash;
+}
+
+// -----------------------------------------------------------------------
+// phpass helpers
+
+function _password_policy_phpass_enabled() {
+  return module_exists('phpass') && variable_get('user_hash_method', 'phpass') == 'phpass';
+}
+
+function _password_policy_new_phpass() {
+  // initialize phpass
+  require_once(drupal_get_path('module', 'phpass') .'/PasswordHash.php');
+  $phpass = new PasswordHash(variable_get('user_hash_strength', 8), variable_get('user_hash_portable', TRUE));
+  return $phpass;
+}
+
+function _password_policy_phpass_hash($pass) {
+  $phpass = _password_policy_new_phpass();
+
+  // get a new secure hash
+  return $phpass->HashPassword($pass);
 }
 
 /**
@@ -741,7 +799,7 @@ function password_policy_add_policy_js($
   $s .= " *\n";
   $s .= " * Returns the estimated strength and the relevant output message.\n";
   $s .= " */\n";
-  $s .= "Drupal.evaluatePasswordStrength = function(value) {\n";
+  $s .= "Drupal.evaluatePasswordStrength = function(value, context) {\n";
   $s .= "  var strength = \"high\", msg = [], translate = Drupal.settings.password_policy;\n";
   // Print out each constraint's javascript password strength evaluation.
   foreach ($policy['policy'] as $key => $value) {
