For developers
PHP-based, no database server, no credentials file. Everything you need to evaluate, run, and harden it.
pdo_sqlite extension (bundled with most PHP builds).# 1. get the code git clone https://github.com/MohammedNasrallah/passnumber-demo.git cd passnumber-demo # 2. run it (creates the SQLite file on first request) php -S 127.0.0.1:8000 -t public # 3. open the demo # http://127.0.0.1:8000/index.php — register # http://127.0.0.1:8000/login.php — log in
On shared hosting, upload the project and point the document root at the public/ folder (or move its contents into public_html). The data/ folder must be writable by PHP so the SQLite file can be created.
A single table. Note what is not here: no plaintext passnumber, no symbol choices, no positions.
CREATE TABLE users ( id INTEGER PRIMARY KEY, username TEXT NOT NULL UNIQUE, hashed_passnumber TEXT NOT NULL, -- salted bcrypt grid_rows INTEGER, grid_cols INTEGER, neglect_count INTEGER, failed_attempts INTEGER DEFAULT 0, locked_until INTEGER DEFAULT 0 );
Registration derives one canonical token from the user's choices (each row encoded independently so the secret is collision-free), then stores only its salted hash:
$token = PassNumber::canonicalToken($positions); $hash = password_hash($token, PASSWORD_DEFAULT); // login verifies in constant time if (password_verify($rebuiltToken, $hash)) { /* ok */ }
Before you put this in front of real users:
X-Frame-Options, X-Content-Type-Options.The demo is plain PHP — there is no Laravel dependency. If your marketing or internal docs mention a framework, reconcile that with what actually ships. The demo targets PHP 8.1+ and is not tested against PHP 7. SQLite is used for zero-config portability; swapping to MySQL/Postgres is a straightforward change to the data layer but is left to the implementer.