Argon2
Algoritma

Function Argon2
   Inputs:
      password (P):     Bytes (0..232-1)    Password (or message) to be hashed
      salt (S):         Bytes (8..232-1)    Salt (16 bytes recommended for password hashing)
      parallelism (p):  Number (1..224-1)   Degree of parallelism (i.e. number of threads)
      tagLength (T):    Number (4..232-1)   Desired number of returned bytes
      memorySizeKB (m): Number (8p..232-1)  Amount of memory (in [./https://en.wikipedia.org/wiki/Kibibyte 30 Mart 2019 tarihinde Wayback Machine sitesinde arşivlendi. kibibytes]) to use
      iterations (t):   Number (1..232-1)   Number of iterations to perform
      version (v):      Number (0x13)      The current version is 0x13 (19 decimal)
      key (K):          Bytes (0..232-1)    Optional key (Errata: PDF says 0..32 bytes, RFC says 0..232 bytes)
      associatedData (X): Bytes (0..232-1)    Optional arbitrary extra data
      hashType (y):     Number (0=Argon2d, 1=Argon2i, 2=Argon2id)
   Output:
      tag:              Bytes (tagLength)   The resulting generated bytes, tagLength bytes long

   Generate initial 64-byte block H0.
   All the input parameters are concatenated and input as a source of additional entropy.
   Errata: RFC says H0 is 64-bits; PDF says H0 is 64-bytes.
   Errata: RFC says the Hash is H^, the PDF says it's ℋ (but doesn't document what ℋ is). It's actually Blake2b.
   Variable length items are prepended with their length as 32-bit little-endian integers.
   buffer ← parallelism ∥ tagLength ∥ memorySizeKB ∥ iterations ∥ version ∥ hashType
         ∥ Length(password)       ∥ Password
         ∥ Length(salt)           ∥ salt
         ∥ Length(key)            ∥ key
         ∥ Length(associatedData) ∥ associatedData
   H0 ← Blake2b(buffer, 64) //default hash size of Blake2b is 64-bytes

   Calculate number of 1 KB blocks by rounding down memorySizeKB to the nearest multiple of 4*parallelism [./https://en.wikipedia.org/wiki/Kibibyte 30 Mart 2019 tarihinde Wayback Machine sitesinde arşivlendi. kibibytes]
   blockCount ← Floor(memorySizeKB, 4*parallelism)

   Allocate two-dimensional array of 1 KiB blocks (parallelism rows x columnCount columns)
   columnCount ← blockCount / parallelism; //In the RFC, columnCount is referred to as q

   Compute the first and second block (i.e. column zero and one) of each lane (i.e. row)
   for i ← 0 to parallelism-1 do for each row
      Bi[0] ← Hash(H0 ∥ 0 ∥ i, 1024) //Generate a 1024-byte digest
      Bi[1] ← Hash(H0 ∥ 1 ∥ i, 1024) //Generate a 1024-byte digest

   Compute remaining columns of each lane
   for i ← 0 to parallelism-1 do //for each row
      for j ← 2 to columnCount-1 do //for each subsequent column
         //i' and j' indexes depend if it's Argon2i, Argon2d, or Argon2id (See section 3.4)
         i′, j′ ← GetBlockIndexes(i, j)  //the GetBlockIndexes function is not defined
         Bi[j] = G(Bi[j-1], Bi′[j′]) //the G hash function is not defined

   Further passes when iterations > 1
   for nIteration ← 2 to iterations do
      for i ← 0 to parallelism-1 do for each row
        for j ← 0 to columnCount-1 do //for each subsequent column
           //i' and j' indexes depend if it's Argon2i, Argon2d, or Argon2id (See section 3.4)
           i′, j′ ← GetBlockIndexes(i, j)
           if j == 0 then 
             Bi[0] = G(Bi[columnCount-1], Bi′[j′])
           else
             Bi[j] = G(Bi[j-1], Bi′[j′])

   Compute final block C as the XOR of the last column of each row
   C ← B0[columnCount-1]
   for i ← 1 to parallelism-1 do
      C ← C xor Bi[columnCount-1]

   Compute output tag
   return Hash(C, tagLength)