- Gleam 96.4%
- JavaScript 1.9%
- Shell 0.9%
- Erlang 0.8%
| priv | ||
| src | ||
| test | ||
| .gitignore | ||
| gleam.toml | ||
| manifest.toml | ||
| README.md | ||
Portomir
Password hashing and verification for Gleam using external programs instead of native code building.
The only supported algorithm right now is argon2. See its page for further installation instructions.
Supports both Erlang and JavaScript targets.
gleam add portomir@1
import portomir/argon2
pub fn main() -> Nil {
let hasher = argon2.init()
let settings =
argon2.Settings(
version: 19,
variant: argon2.Id,
iterations: 15,
memory_cost: 2048,
parallelism: 4,
)
let salt = argon2.gen_salt()
let password = "..."
// Hashing
echo argon2.hash(hasher, password, salt, settings)
// Outputs something like
// $argon2id$v=19$m=2048,t=15,p=4$c29tZXN1cGVybG9uZ3NhbHQ$O3hAW5NET9B1mj0pK2S+rqOJeeAP4gSgSLWJhpjp5K8
// Parsing existing hashes to get the settings used to create them
echo argon2.parse("$argon2id$v=19$m=4096,t=10,p=2$MTIzNDU2Nzg5MHNhbHRpbmVjcmFja2Vycw$iA+BvAMNqAKjV/qIbmbcbEkBC0rho9xTtI1IJwrAf08")
// Outputs something like
// Ok(Settings("1234567890saltinecrackers", 19, Id, 10, 4096, 2))
// Verifying passwords against existing hashes
echo argon2.verify(hasher, password, "$argon2id$v=19$m=2048,t=15,p=4$...")
// Results in Ok(Nil) for a successful verification
}
Justification
There are already several libraries for password hashing in Gleam, for both Argon2 and bcrypt, so why this library?
The existing libraries rely on building Native Implemented Functions (NIFs) to do the actual hashing operations. This allows running such performance intensive code, which Erlang itself would not be suited for. However, it comes with some downsides:
- Such a built release is no longer portable across systems, as it depends on the CPU architecture and possibly dynamically linked system libraries.
- Building the release requires the installation of various build tooling.
- If a NIF crashes, it takes down the whole Erlang VM. Although this is unlikely with well tested and widely used packages.
- Due to the usage of NIFs, the current libraries only support the Erlang target.
Since Argon2 is also available as a command line program, instead of building native code, we can use that. It allows us to avoid the downsides listed above, but it does come with some of its own tradeoffs:
- Running a command line program is going to be slower and probably use more memory. It has not been measured yet at which point this will become an issue.
- A one-liner shell script is needed between Gleam and the program, since Erlang is unable to send EOF to the called program.
If the downsides of the NIF approach listed above are not issues for you, then you should probably look at those libraries.
Etymology
One of the Argon2 libraries is called Aragorn2, so Globerto suggested the name Portomir as a pun on Boromir.