CRYPTO_ARGON2I(3MONOCYPHER)
π CRYPTO_ARGON2I π
okay bestie, settle in, because this is the 3monocypher page for crypto_argon2i and it's literally the password-hashing baddie of your dreams β¨ (it lives in the LOCAL section of the manual, iykyk)
β¨ NAME β¨
crypto_argon2i β password key derivation π
πΈ SYNOPSIS πΈ
#include <monocypher.h>
void
crypto_argon2i(uint8_t *hash, uint32_t hash_size, void *work_area,
uint32_t nb_blocks, uint32_t nb_iterations, const uint8_t *password,
uint32_t password_size, const uint8_t *salt, uint32_t salt_size);
void
crypto_argon2i_general(uint8_t *hash, uint32_t hash_size,
void *work_area, uint32_t nb_blocks, uint32_t nb_iterations,
const uint8_t *password, uint32_t password_size,
const uint8_t *salt, uint32_t salt_size, const uint8_t *key,
uint32_t key_size, const uint8_t *ad, uint32_t ad_size);
π¦ DESCRIPTION π¦
Argon2i is a resource intensive password key derivation scheme, optimised for your typical x86-like processor. It runs in constant time with respect to the contents of the password. no leaking, periodt π
Typical applications are password checking (for online services) and key derivation (for encryption). Derived keys can be used to encrypt, for example, private keys or password databases. iconic behaviour honestly.
The version Monocypher gives you has no threading support, so the degree of parallelism is limited to 1. That's considered good enough for most purposes, fr fr.
π the arguments to crypto_argon2i() π
hashβ the output hash. The way this works: if all parameters tocrypto_argon2i()orcrypto_argon2i_general()are identical between two calls, then the output hash is also identical. In other words, every single input parameter passed to the function influences the output value. no sneaky hidden inputs, we love consistency β¨hash_sizeβ length ofhash, in bytes. You should set this to32or64for compatibility with thecrypto_verify*()constant time comparison functions.work_areaβ temporary buffer for the algorithm, allocated by the caller. It must benb_blocksΓ 1024 bytes big, and suitably aligned for 64-bit integers. If you're not sure how to allocate that buffer, just usemalloc(). It's giving "trust the process".
The work area is automatically wiped by crypto_argon2i(). we love a self-cleaning queen π§
nb_blocksβ the number of blocks for the work area. Must be at least8. A value of100000(one hundred megabytes) is a good starting point. If the computation takes too long, reduce this number. If it's too fast, increase this number. If it's still too fast with all available memory, increasenb_iterations. tuning era πnb_iterationsβ the number of iterations. It must be at least1. A value of3is strongly recommended; any value lower than3enables significantly more efficient attacks. so like, don't. just don't πpasswordβ the password to hash. It should be wiped withcrypto_wipe(3monocypher)after being hashed.password_sizeβ length ofpassword, in bytes.saltβ a password salt. This should be filled with random bytes, generated separately for each password to be hashed. Seeintro(3monocypher)for advice about generating random bytes (use the operating system's random number generator). every password gets its own, no sharing πsalt_sizeβ length ofsalt, in bytes. Must be at least8.16is recommended.
The arguments may overlap or point at the same buffer. go off, memory layout π
Use crypto_verify16(3monocypher), crypto_verify32(3monocypher) or crypto_verify64(3monocypher) to compare password hashes to prevent timing attacks. seriously, this one matters.
To select the nb_blocks and nb_iterations parameters, it should first be decided how long the computation should take. For user authentication, values somewhere between half a second (convenient) and several seconds (paranoid) are recommended. The computation should use as much memory as can be spared.
Since parameter selection depends on your hardware, some trial and error will be required in order to determine the ideal settings. Three iterations and 100000 blocks (that is, one hundred megabytes of memory) is a good starting point. Adjust nb_blocks first. If using all available memory is not slow enough, increase nb_iterations. basically: dial it in, bestie π
π crypto_argon2i_general() β the deluxe version π
crypto_argon2i_general() is a variant of crypto_argon2i() that supports keyed hashing and hashing of additional data. The additional arguments are:
keyβ a key to use in the hash. Can beNULLifkey_sizeis zero. The key is generally not needed, but it does have some uses. In the context of password derivation, it would be stored separately from the password database, and would remain secret even if an attacker were to steal the database. Note that changing the key requires rehashing the user's password, which is only possible upon user login. plot twist πkey_sizeβ length ofkey, in bytes. Must be zero if there is no key.adβ additional data. This is additional data that goes into the hash, similar to the authenticated encryption with authenticated data (AEAD) construction incrypto_lock_aead(3monocypher). This most likely has no practical application but is exposed for the sake of completeness. This parameter may beNULLifad_sizeis zero.ad_sizeβ length ofad, in bytes. Must be zero if there is no additional data.
β RETURN VALUES β
These functions return nothing. that's it, that's the section π
π EXAMPLES π
The following example assumes the existence of arc4random_buf(), which fills the given buffer with cryptographically secure random bytes. If arc4random_buf() does not exist on your system, see intro(3monocypher) for advice about how to generate cryptographically secure random bytes.
This example shows how to hash a password with the recommended baseline parameters:
uint8_t hash[32]; /* Output hash */
char *password = "Okay Password!"; /* User's password */
uint32_t password_size = 14; /* Password length */
uint8_t salt[16]; /* Random salt */
const uint32_t nb_blocks = 100000; /* 100 megabytes */
const uint32_t nb_iterations = 3; /* 3 iterations */
void *work_area = malloc(nb_blocks * 1024); /* Work area */
if (work_area == NULL) {
/* Handle malloc() failure */
/* Wipe secrets if they are no longer needed */
crypto_wipe(password, password_size);
} else {
arc4random_buf(salt, 16);
crypto_argon2i(hash, 32,
work_area, nb_blocks, nb_iterations,
(uint8_t *)password, password_size,
salt, 16);
/* Wipe secrets if they are no longer needed */
crypto_wipe(password, password_size);
free(work_area);
}
π SEE ALSO π
crypto_lock(3monocypher), crypto_verify16(3monocypher), crypto_wipe(3monocypher), intro(3monocypher)
π STANDARDS π
These functions implement Argon2i. An RFC draft is being maintained.
π§ HISTORY π§
The crypto_argon2i_general() function first appeared in Monocypher 0.1 but was called crypto_argon2i(); it was renamed to its current name in Monocypher 1.1.0. The current crypto_argon2i() first appeared in Monocypher 1.1.0. glow-up confirmed β¨
π₯ CAVEATS π₯
Any deviation from the specified input and output length ranges results in undefined behaviour. Make sure your inputs are correct. no cap, check your sizes before you ship π
and that's the whole page, bestie π«Ά β this manual page came out of the Debian crew on September 26, 2020, filed under CRYPTO_ARGON2I(3MONOCYPHER). go hash something responsibly π
π
π¦ where this page comes from
- fedora 43: monocypher-devel 3.1.2-12.fc43 Β· LicenseRef-Callaway-BSD OR CC0-1.0
- fedora 43: monocypher-devel 3.1.2-12.fc43 Β· LicenseRef-Callaway-BSD OR CC0-1.0
- fedora 44: monocypher-devel 3.1.2-13.fc44 Β· LicenseRef-Callaway-BSD OR CC0-1.0
- fedora 44: monocypher-devel 3.1.2-13.fc44 Β· LicenseRef-Callaway-BSD OR CC0-1.0
- π the page's license: BSD-2-Clause OR CC0-1.0
- Copyright (c) 2017-2019 Loup Vaillant
- Copyright (c) 2018 Michael Savage
- Copyright (c) 2017, 2019-2020 Fabio Scotoni
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms