Skip to content

Instantly share code, notes, and snippets.

Last active Oct 26, 2016
What would you like to do?
Overview of Argon2: A memory hard function for password hashing


  • Argon2 is a key derivation function that was selected as the winner of the Password Hashing Competition in July 2015. It was designed by Alex Biryukov, Daniel Dinu, and Dmitry Khovratovich from University of Luxembourg.
  • It uses the BLAKE2 hash algorithm to securely scramble input data (password and salt).


Problems with existing designs

  • Should the memory addressing (indexing functions) be input-independent or input-dependent, or hybrid?
  • Is it better to fill more memory but suffer from time-space tradeoffs, or make more passes over the memory to be more robust?
  • How should the input-independent addresses be computed? Several seemingly secure options have been attacked.
  • How large a single memory block should be?
  • If the block is large, how to choose the internal compression function? Should it be cryptographically secure or more lightweight, providing only basic mixing of the inputs?
  • How to exploit multiple cores of modern CPUs, when they are available?

Argon2 solutions

  • To defeat brute force and dictionary attacks, Argon2 can be tuned to use as much computation and memory as the application tolerates, and support multi-threading.
  • Aims at the highest memory filling rate and effective use of multiple computing units, while still providing defense against tradeoff attacks.
  • Optimized for the x86 architecture and exploits the cache and memory organization of the recent Intel and AMD processors.



  • To maximize the cost of password cracking on ASICs measured through time-area cost.


  • The memory-hard functions that we explore use the following mode of operation. The memory array B[] is filled with the compression function.

    B[0] = H(P, S);
    for j from 1 to t
      B[j] = G(B[φ1(j)], B[φ2(j)], · · · , B[φk(j)])


Argon2 has three variants: Argon2i, Argon2d, and Argon2id.

  1. Argon2d is faster and uses data-depending memory access, which makes it highly resistant against GPU cracking attacks and suitable for applications with no threats from side-channel timing attacks (eg. cryptocurrencies).
  2. Argon2i instead uses data-independent memory access, which is preferred for password hashing and password-based key derivation, but it is slower as it makes more passes over the memory to protect from tradeoff attacks.
  3. Argon2id is a hybrid of Argon2i and Argon2d, using a combination of data-depending and data-independent memory accesses, which gives some of Argon2i's resistance to side-channel cache timing attacks and much of Argon2d's resistance to GPU cracking attacks.



Argon2 has two types of inputs: Primary parameters and Secondary parameters

  • Primary parameters are always provided by the users
  • Message P may have any length from 0 to 2^32 − 1 bytes
  • Nonce S may have any length from 8 to 2^32 − 1 bytes (16 bytes is recommended for password hashing)
  • Secondary parameters have corresponding restrictions
  • Degree of parallelism p determines how many independent (but synchronizing) computational chains can be run. It may take any integer value from 1 to 2^24 − 1.
  • Tag length τ may be any integer number of bytes from 4 to 2^32 − 1.
  • Memory size m can be any integer number of kilobytes from 8p to 2^32 − 1. The actual number of blocks is m0, which is m rounded down to the nearest multiple of 4p.
  • Number of iterations t (used to tune the running time independently of the memory size) can be any integer number from 1 to 2^32 − 1;
  • Version number v is one byte 0x13;
  • Secret value K (serves as key if necessary, but we do not assume any key use by default) may have any length from 0 to 32 bytes.
  • Associated data X may have any length from 0 to 2^32 − 1 bytes.
  • Type y of Argon2: 0 for Argon2d, 1 for Argon2i.

Argon2 uses internal compression function G with two 1024-byte inputs and a 1024-byte output, and internal hash function H.

Here H is the Blake2b hash function, and G is based on its internal permutation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment