Argon2: Memory-Hard Password Hashing
Argon2 won the 2015 Password Hashing Competition by making brute-force attacks expensive in RAM, not just CPU time — closing off the GPU and ASIC cracking farms that broke older schemes. Here's how memory-hardness works.
Interactive Argon2-Style Visualizer
🔐 Argon2-Style Memory-Hard Hashing
Argon2: Memory-Hard Password Hashing
Introduction
Hashing a password once with a fast function like SHA-256 is actively dangerous: an attacker with a stolen password database can try billions of guesses per second on modern GPUs. PBKDF2 fixed part of this by adding deliberate iteration count, but GPUs and custom ASICs are extremely good at brute-forcing simple repeated-hash constructions in parallel, since they need almost no memory per guess. Argon2, the winner of the 2015 Password Hashing Competition, closes that loophole with memory-hardness: its algorithm requires filling a large block of memory that depends on the password itself, and that memory requirement doesn’t shrink even if an attacker has enormous parallel compute — RAM is expensive and hard to parallelize cheaply, unlike raw hashing throughput.
Table of Contents
- Why Memory-Hardness Matters
- How Argon2 Works
- The Three Argon2 Variants
- Tuning Parameters
- FAQ
- References
Why Memory-Hardness Matters
A custom ASIC or GPU farm can compute billions of SHA-256 hashes per second because the algorithm needs almost no memory — just a small, fast register set repeated in massive parallel. Memory, on the other hand, is expensive to replicate at scale: a chip with a thousand parallel hashing cores still needs a thousand times the RAM to run Argon2 at the same parallelism, and RAM doesn’t get dramatically cheaper or faster the way pure arithmetic throughput does. This asymmetry is the entire point: legitimate logins pay a small, fixed memory and time cost once, while attackers trying billions of guesses pay that same cost billions of times over, with none of the GPU/ASIC shortcuts available to older schemes.
How Argon2 Works
- An initial hash is derived from the password, salt, and configuration parameters.
- That initial value seeds a large memory array, filled block by block, where each new block is derived from the password-dependent seed and one or more previously computed blocks — making every block genuinely dependent on real memory contents that must actually be held (or expensively recomputed) to proceed.
- Depending on the variant (see below), later blocks may also depend on data computed earlier in the same pass, chosen based on the contents of already-filled memory — this data-dependent addressing is what makes trade-off attacks (recomputing instead of storing) prohibitively expensive.
- The process runs for a configurable number of passes over the memory array, further increasing the time and memory-access cost.
- The final derived key is produced by hashing the last blocks of memory together.
Interactive Visualizer
Real Argon2 uses the BLAKE2b hash function internally with a specific, highly-optimized compression function and addressing scheme, and its typical memory requirement (megabytes and up) is far beyond what’s practical to run inside a browser lesson. The visualizer above demonstrates the same structural idea — a memory array filled block by block, each depending on prior blocks and the password, followed by multiple mixing passes — using SHA-256 instead of BLAKE2b and a tiny handful of blocks, so you can watch the dependency chain build visibly rather than running the real, production-scale algorithm.
The Three Argon2 Variants
- Argon2d: memory access patterns depend entirely on the data being processed, maximizing resistance to the “time-memory trade-off” attacks that let an attacker use less memory at the cost of more computation. Its data-dependent addressing, however, makes it theoretically vulnerable to side-channel timing attacks, so it’s recommended mainly for contexts without an attacker capable of observing memory access patterns (like isolated cryptocurrency mining or proof-of-work applications).
- Argon2i: memory access patterns are independent of the data, specifically to resist side-channel timing attacks — the trade-off is somewhat weaker resistance to the trade-off attacks Argon2d defends against best.
- Argon2id (the recommended default, and what most modern systems mean when they say “Argon2”): a hybrid, using data-independent addressing for the first half of the first pass (protecting against timing side-channels during the most vulnerable early phase) and data-dependent addressing afterward (gaining Argon2d’s stronger trade-off resistance for the rest of the computation).
Tuning Parameters
Argon2 exposes three independent knobs, letting operators tune the cost to their specific threat model and hardware:
- Memory cost (m): how much RAM (typically tens of megabytes) the algorithm must allocate — the primary lever against GPU/ASIC parallelism.
- Time cost (t): how many passes to make over the memory array — increases computation time independent of memory size.
- Parallelism (p): how many independent lanes can be computed in parallel on a legitimate multi-core machine, without weakening the memory requirement per lane.
OWASP and other security guidance publish concrete recommended parameter combinations (e.g., specific memory/time/parallelism triples) balancing security against acceptable login latency for real users.
FAQ
Should I use Argon2 instead of bcrypt or PBKDF2 for new systems?
Yes — Argon2id is the current best-practice recommendation from OWASP and the broader security community for new password-hashing systems, specifically because of its memory-hardness. bcrypt and PBKDF2 remain acceptable when Argon2 isn’t available in your platform’s libraries, but neither offers memory-hardness against modern parallel hardware.
What does “memory-hard” actually mean?
It means the algorithm’s time cost is tightly coupled to a required memory footprint — you can’t meaningfully speed up the computation by throwing more parallel compute at it without also multiplying your memory requirement by the same factor, which is expensive and hard to scale the way raw arithmetic throughput is.
Which Argon2 variant should I use?
Argon2id, for nearly all password-hashing use cases — it’s the variant recommended by the Argon2 designers themselves and by OWASP as the general-purpose default, balancing resistance to both timing side-channels and time-memory trade-off attacks.
Why did Argon2 win the Password Hashing Competition?
The 2013-2015 competition specifically sought a successor to bcrypt and PBKDF2 that addressed their vulnerability to cheap, massively parallel GPU and ASIC cracking. Argon2’s tunable memory-hardness directly targeted that weakness, and its design withstood the competition’s public cryptanalysis process better than the other finalists.
Is Argon2 only used for passwords?
Its primary and most common use is password hashing and password-based key derivation, though its underlying memory-hard construction has also influenced designs for other applications needing deliberately expensive, hard-to-parallelize computation, like certain proof-of-work schemes.
References
-
Biryukov, A., Dinu, D., and Khovratovich, D. “Argon2: New Generation of Memory-Hard Functions for Password Hashing and Other Applications.” IEEE EuroS&P 2016 — the original paper, from the Password Hashing Competition winners.
-
RFC 9106. “Argon2 Memory-Hard Function for Password Hashing and Proof-of-Work Applications.” IETF, 2021.
-
OWASP. “Password Storage Cheat Sheet.” Available at: https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html
-
Password Hashing Competition. Available at: https://www.password-hashing.net/