Argon2 Reference Implementation
repository·master·Indexed 26 days ago
https://github.com/p-h-c/phc-winner-argon2The reference C implementation of the Argon2 password-hashing function, winner of the Password Hashing Competition (PHC). Designed to be memory-hard and resistant to GPU cracking and side-channel attacks, it provides a command-line utility and both high-level and low-level C APIs for Argon2i, Argon2d, and Argon2id variants.
What's inside Argon2
- Argon2 is available via various third-party bindings for multiple programming languages. When using a binding, ensure you consult its specific documentation for implementation details and configuration.
Build and install Argon2
masterTo build the Argon2 executable, static library (
libargon2.a), and shared library (libargon2.soorlibargon2.dylib), usemake. It is recommended to specify an installation prefix during compilation and run tests to verify the build.- Build the project:
make - Verify the build:
make test - Install to the system:
sudo make install PREFIX=/usr
make make test sudo make install PREFIX=/usr- Build the project:
Run the Argon2 test suite
masterThe repository includes two sets of test suites: a low-level test for the hash function and a high-level test for the API. To build and execute both test suites, use themake testcommand.make testGenerate Argon2 hashes via CLI
masterUse theargon2command-line utility to generate Argon2 hashes. The command requires a salt as the first argument (minimum 8 octets) and expects the password to be provided via standard input (stdin). By default, the tool uses the Argon2i variant.Use the Argon2 low-level C API
masterThe low-level API uses an
argon2_contextstructure to provide fine-grained control over the hashing process. This allows for advanced features like keyed hashing and secure memory erasure.Key Features:
secretparameter: Used for keyed hashing (HMAC-like). Provides a secret key to be folded into the hash.ad(associated data) parameter: Folds additional data into the hash value.flagsparameter: Controls secure memory erasure. UseARGON2_FLAG_CLEAR_PASSWORDorARGON2_FLAG_CLEAR_SECRETto wipe sensitive buffers after use.
Implementation Pattern:
- Initialize an
argon2_contextstruct. - Call the variant-specific context function (e.g.,
argon2i_ctx(&context)). - Check the return code against
ARGON2_OK.
Example:
argon2_context context = { hash2, /* output array */ HASHLEN, /* digest length */ pwd, /* password array */ pwdlen, /* password length */ salt, /* salt array */ SALTLEN, /* salt length */ NULL, 0, /* optional secret data */ NULL, 0, /* optional associated data */ t_cost, m_cost, parallelism, parallelism, ARGON2_VERSION_13, /* algorithm version */ NULL, NULL, /* custom memory functions */ ARGON2_DEFAULT_FLAGS }; int rc = argon2i_ctx(&context);#include "argon2.h" #include <stdio.h> #include <string.h> #include <stdlib.h> #define HASHLEN 32 #define SALTLEN 16 #define PWD "password" int main(void) { uint8_t hash1[HASHLEN]; uint8_t hash2[HASHLEN]; uint8_t salt[SALTLEN]; memset( salt, 0x00, SALTLEN ); uint8_t *pwd = (uint8_t *)strdup(PWD); uint32_t pwdlen = strlen((char *)pwd); uint32_t t_cost = 2; // 2-pass computation uint32_t m_cost = (1<<16); // 64 mebibytes memory usage uint32_t parallelism = 1; // number of threads and lanes // high-level API argon2i_hash_raw(t_cost, m_cost, parallelism, pwd, pwdlen, salt, SALTLEN, hash1, HASHLEN); // low-level API argon2_context context = { hash2, /* output array, at least HASHLEN in size */ HASHLEN, /* digest length */ pwd, /* password array */ pwdlen, /* password length */ salt, /* salt array */ SALTLEN, /* salt length */ NULL, 0, /* optional secret data */ NULL, 0, /* optional associated data */ t_cost, m_cost, parallelism, parallelism, ARGON2_VERSION_13, /* algorithm version */ NULL, NULL, /* custom memory allocation / deallocation functions */ /* by default only internal memory is cleared (pwd is not wiped) */ ARGON2_DEFAULT_FLAGS }; int rc = argon2i_ctx( &context ); if(ARGON2_OK != rc) { printf("Error: %s\n", argon2_error_message(rc)); exit(1); } free(pwd); for( int i=0; i<HASHLEN; ++i ) printf( "%02x", hash1[i] ); printf( "\n" ); if (memcmp(hash1, hash2, HASHLEN)) { for( int i=0; i<HASHLEN; ++i ) { printf( "%02x", hash2[i] ); } printf( "\nfail\n" ); } else printf( "ok\n" ); return 0; }Use the Argon2 high-level C API
masterThe high-level API provides simple functions for hashing. Functions are named based on the variant and whether they return raw bytes or encoded strings:
- Argon2i:
argon2i_hash_raw(...)orargon2i_hash_encoded(...) - Argon2d:
argon2d_hash_raw(...)orargon2d_hash_encoded(...) - Argon2id:
argon2id_hash_raw(...)orargon2id_hash_encoded(...)
Parameters:
t_cost: Number of iterations.m_cost: Memory usage in kibibytes.parallelism: Number of threads/lanes.pwd: Password input buffer.pwdlen: Password length.salt: Salt input buffer.saltlen: Salt length.hash: Output buffer.hashlen: Desired hash length.
- Argon2i:
Use the Argon2 command-line utility
masterThe
argon2CLI tool allows you to test specific Argon2 instances. The password is read fromstdin.Usage:
./argon2 [-h] salt [-i|-d|-id] [-t iterations] [-m memory] [-p parallelism] [-l hash length] [-e|-r] [-v (10|13)]Parameters:
salt: The salt to use (at least 8 characters).-i: Use Argon2i (default).-d: Use Argon2d.-id: Use Argon2id.-t N: Sets iterations to N (default 3).-m N: Sets memory usage to $2^N$ KiB (default 12).-p N: Sets parallelism to N threads (default 1).-l N: Sets hash output length to N bytes (default 32).-e: Output only encoded hash.-r: Output only the raw bytes of the hash.-v (10|13): Argon2 version (defaults to 13).-h: Print usage.
Example: To hash "password" using "somesalt" with 2 iterations, 64 MiB memory ($2^{16}$ KiB), 4 threads, and a 24-byte hash:
echo -n "password" | ./argon2 somesalt -t 2 -m 16 -p 4 -l 24Configure Argon2 CLI options
masterThe
argon2command supports several options to tune the hashing parameters and output format:Variants
-d: Use Argon2d instead of the default Argon2i.-id: Use Argon2id instead of the default Argon2i.
Tuning Parameters
-t " N": Sets the number of iterations toN(default = 3).-m " N": Sets the memory usage to $2^N$ KiB (default = 12).-p " N": Sets parallelism toNthreads (default = 1).-l " N": Sets hash output length toNbytes (default = 32).-v (10|13): Specifies the Argon2 version (defaults to the most recent, currently 13).
Output Formats
-e: Output only the encoded hash.-r: Output only the raw bytes of the hash.-h: Display tool usage.