Lua implementation of the portable PHP password hashing framework
Switch branches/tags
Nothing to show
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.
spec test: returns false for malformed hashes May 13, 2015
.luacov travis, luacov May 13, 2015

lua-phpass, Lua implementation of the portable PHP password hashing framework

Travis build Coverage Status License

phpass (pronounced "pH pass") is a portable public domain password hashing framework for use in PHP applications. phpass has been integrated into WordPress 2.5+, bbPress, Vanilla, PivotX 2.1.0+, Chyrp, Textpattern 4.4.0+, and concrete5 5.6.3+.

This Lua module implements a subset of phpass (iterated MD5). It's sufficient to create and check a password hash compatible with portable phpass hash, e.g. a password from wordpress database. Blowfish-based bcrypt and BSDI-style extended DES-based hashes are not supported.


$ luarocks install phpass



The code was tested against Lua 5.1, 5.2, 5.3 and LuaJIT 2.0, 2.1. LuaCrypto for Lua 5.3 requires the following patch:

diff --git a/src/lcrypto.c b/src/lcrypto.c
index 48364d1..e5a62c4 100644
--- a/src/lcrypto.c
+++ b/src/lcrypto.c
@@ -968,7 +968,7 @@ static int verify_fverify(lua_State *L)
 static int rand_do_bytes(lua_State *L, int (*bytes)(unsigned char *, int))
-    size_t count = (size_t)luaL_checkint(L, 1);
+    size_t count = (size_t)luaL_checkinteger(L, 1);
     unsigned char tmp[256], *buf = tmp;
     if (count > sizeof tmp)
         buf = (unsigned char *)malloc(count);

I have applied this patch to my fork of LuaCrypto. There is also the modified version of rockspec for version 0.3.2, which installs modified LuaCrypto.


phpass = require 'phpass'

password = 'test12345'

hash = phpass.hashPassword(password)
--> "$P$EYyDnrNHtS2MG5vTVkvXD6wMnd0C/N/"

phpass.checkPassword(password, hash) --> true
phpass.checkPassword('other password', hash) --> false


Python-phpass, python implementation of phpass was used as a reference.

The algorithm used in phpass.hashPassword generates random salt, so this function returns different hashes for a password.

phpass.hashPassword has second argument, count_log2, which is log2 of number of iterations. The algorithm of hashing is as follows:

count = 2 ^ count_log2
salt = ...
hash = md5(salt .. password)
for i = 1, count do
    hash = md5(hash .. password)


Corresponding author: Boris Nagaev, email:

Copyright (C) 2015 Boris Nagaev

See the LICENSE file for terms of use.