Try it live!
Finabel is a relatively simple password hashing algorithm based on cyclic abelian groups (finite fields). The primary motivation here was to implement something which is (hopefully) easier to analyze and verify than some of the more typical functions in common use.
const finabel = require("./finabel"); let argv = process.argv.slice(1); let argc = argv.length; if (argc <= 1) console.log("Usage:", argv, "[KEY] [SALT] [ROUNDS] [DIGITS] [COST]"); let key = ""; if (argc > 1) key = argv; let salt = ""; if (argc > 2) salt = argv; let rounds = 0; if (argc > 3) rounds = Number(argv); let digits = 0; if (argc > 4) digits = Number(argv); let cost = 0; if (argc > 5) cost = Number(argv); console.log(finabel(key, salt, rounds, digits, cost));
NOTE: If rounds is zero or unspecified, a default of 1024 rounds is used. If cost is zero or unspecified, a default of 256 (kilobytes) is used.
A bird's-eye view looks something like this. We start by defining three large (public) prime numbers, A, B, and C. Next we define the function E(X) which "stretches" some X by repeated concatenation until the result contains at least as many bits as the largest prime. Let V represent our password and salt merged together and then reinterpreted as a large integer. We now apply the following transform to calculate our hash, H(V):
Q = E(V) R = (Q * A) mod B S = E(R) H(V) = (Q * S) mod C
The finabel algorithm demonstrates some very useful properties:
(2) Non-malleability (primary and secondary preimage resistance).
(3) Strong collision resistance.
(4) Satisfies the strict avalanche and bit independence criteria.
(5) Not susceptible to length extension attacks.
This reference implementation currently supports the following languages (UTF-8 fully supported unless otherwise indicated):
In the future I may include other languages as well. Until then, developers are encouraged to create their own implementations based on the straightforward examples given here.
I would also like to thank the folks at crypto.stackexchange.com for their invaluable input.