Argon2 Memory-Hard Password Hashing
Argon2 is a password-hashing algorithm that makes each password guess deliberately expensive in both computation time and working memory. Instead of producing a password hash with a fast function, it forces the verifier—and anyone guessing passwords—to perform a large, memory-intensive computation.
The problem Argon2 solves
Passwords are usually low-entropy secrets: users choose from a much smaller set than the space of all possible byte strings. An attacker who obtains a database of password hashes can try likely passwords offline, without contacting your service or triggering login-rate limits.
A general-purpose hash such as SHA-256 is excellent for integrity checks, but that speed is a liability here. An attacker can run enormous numbers of SHA-256 guesses on CPUs, GPUs, or specialized hardware. Even older password-hashing schemes that increase CPU work may leave attackers able to build machines with many cheap, parallel computation units.
Password hashing does not encrypt the password. It creates a value that can be recomputed for comparison, but is intended to be impractical to reverse by trying guesses. Argon2 improves that economics by requiring substantial memory as well as computation.
What “memory-hard” means
A memory-hard function requires a large amount of working memory during each evaluation, and its computation is arranged so that reducing that memory usually requires extra computation or causes a substantial performance loss.
That matters because memory is harder to scale cheaply than arithmetic. A GPU may have thousands of arithmetic units, but those units compete for a limited amount of memory bandwidth and on-chip storage. An attacker can still run guesses in parallel, but each guess consumes a significant share of the machine’s memory system.
Memory hardness is not a magical minimum-memory lock. An attacker can sometimes configure an implementation to use less memory and compensate with more work. Argon2 is designed to make that trade-off unattractive, not impossible.
The inputs and parameters
A password hash using Argon2 normally includes four important values:
- Salt: a random, public value unique to that password record. It prevents identical passwords from having identical hashes and defeats precomputed lookup tables.
- Memory cost: the amount of working memory, commonly specified in kibibytes.
- Time cost: the number of passes through the memory structure.
- Parallelism: the number of independent lanes that can be processed in parallel within one evaluation.
The result also includes the algorithm variant and these parameters, often in a structured string beginning with a form such as $argon2id$. The salt and parameters do not need to be secret. During login, the verifier reads them, runs Argon2 on the supplied password, and compares the resulting output with the stored one using a suitable constant-time comparison.
The application chooses the costs. It should benchmark a representative production machine and select values that make a normal password verification acceptably slow without making routine logins or password changes a denial-of-service risk. The target is often a fraction of a second or more, depending on the service and threat model—not a universal fixed number.
How an evaluation uses memory
Argon2 divides its working memory into fixed-size blocks and lays those blocks out in lanes. It fills the structure by computing new blocks from earlier blocks, mixing the password, salt, and previously produced data into each result. Later blocks therefore depend on a large body of memory rather than only on a small CPU register state.
The algorithm makes multiple passes over this structure. The time-cost parameter controls how many passes it performs. Each additional pass repeats substantial memory work, increasing verification time and increasing the work required for every password guess.
The lanes provide parallel work. Synchronization points, called slices, let implementations use multiple cores while still requiring the configured total memory. Parallelism can improve throughput on the server, but it does not make a single password guess free: each lane still participates in filling and revisiting the memory structure.
Argon2 has three variants:
- Argon2d chooses some memory locations based on data derived from the password computation. This can improve resistance to some trade-offs, but data-dependent access patterns can reveal information through cache-timing observations.
- Argon2i uses data-independent memory access. That is safer for some environments, but it can require more work to resist memory-saving attacks.
- Argon2id combines the approaches: it begins with data-independent behavior and then uses data-dependent behavior. It is the usual general-purpose recommendation because it balances side-channel concerns with memory-hardness.
The exact block-mixing and indexing rules are defined by Argon2’s specification. The important operational fact is that the computation cannot be reduced to a small, fast hash without paying for the reduction elsewhere.
What the attacker must pay
Suppose an attacker steals a database containing Argon2id records. For every candidate password, the attacker must use that record’s salt and parameters and perform a complete Argon2 evaluation. A ten-million-guess attack therefore repeats the memory allocation, block filling, passes, and final comparison ten million times.
Increasing the memory cost makes each concurrent guess occupy more RAM and consume more memory bandwidth. Increasing the time cost makes each guess revisit that memory more often. Increasing parallelism can use available server cores, although the total configured memory and the implementation’s behavior still determine the actual cost.
This changes the attacker’s scaling problem. More CPU cores can provide more guesses, but the attacker must also buy enough memory capacity and bandwidth to keep those guesses moving. If they reduce memory per guess, Argon2’s design makes the computation take longer or lose efficiency. The result is a higher cost per password guess across CPUs, GPUs, and custom hardware.
Practical configuration
Argon2 does not replace other defenses. Unique salts prevent cross-user reuse of work, while login rate limits and account protections address online guessing. Operators should also plan for legitimate parameter upgrades: when a user logs in successfully, the service can detect that the stored record uses older costs and compute a new hash with stronger settings.
The parameter string you see in a password record or an error report is therefore meaningful configuration, not incidental metadata. It tells the verifier how much memory and time to spend—and tells an attacker how expensive each offline guess must be.