Is the seed block in Argon2 (H0) 64-bit or 64-byte? Is the H0 block in Argon2 64-bits, or 64-bytes? The RFC says bits:


  Establish H0 as the 64-bit value as shown below.


But then it attempts to generate 64-bytes using Blake2

Background

I'm trying to implement Argon2, and the original specs paper, and RFC are not a very friendly to implementors. 

I'm stuck on the first step of the Argon2 pseudo-code:


  Establish H0 as the 64-bit value as shown below.

H_0 = H^(64)(LE32(p), LE32(T), LE32(m), LE32(t), LE32(v), LE32(y), LE32(length(P)), P, LE32(length(S)), S, LE32(length(K)), K, LE32(length(X)), X)



There's a lot going on in there, but we can clean it up:


  Establish H0 as the 64-bit value as shown below.
  
  H0 = H^(64)( [stuff to hash] )


It would seem to indicate that the H^(64)(...) is going to return 64-bits (because of the phrase "...as the 64-bit value...".

But now we go hunting what H^ is, which brings us to the preamble of Section 3.2 in the RFC:


  Argon2 uses an internal hash function H^x(). Here H^x() applied to string a is the BLAKE2b [RFC7693](a,|a|,0,x) hash function


Now we know that: H^(x)(a) = Blake2b(a, |a|, 0, x).

That brings us to RFC 7693 - The BLAKE2 Cryptographic Hash and Message Authentication Code (MAC), in order to figure out what the four paramters are (especially the final paramter x):

The following procedure processes the padded data blocks into an
"nn"-byte final hash value.  See Section 2 for a description of
various variables and constants used.

   FUNCTION BLAKE2( d[0..dd-1], ll, kk, nn )
   |
   ...snip...
   |
   END FUNCTION.


That's a little hard for implementors to read; we can make it a bit more understandable:


Function Blake2(DataToHash, OriginalMessageLength, KeyLength, DigestLength)  
   Inputs:
      DataToHash:            Bytes    //array of bytes to be hashed   
      OriginalMessageLength: Integer  //length of message in bytes   
      KeyLength:             Integer  //length of secret key in bytes (0..64)  
      DigestLength:          Integer  //length of desired digest in bytes (1..64)  
   Output:   
      Digest:                Bytes    //digest that is DigestLength long   

   ...snip...   


The final parameter to Blake2 (nn in RFC's parlance) is bytes (not bits):

|             | BLAKE2b          |
|-------------|------------------|
|Bits in word | w = 64           |
|Rounds in F  | r = 12           |
|Block bytes  | bb = 128         |
|Hash bytes   | 1 &lt;= nn &lt;= 64    |
|Key bytes    | 0 &lt;= kk &lt;= 64    |
|Input bytes  | 0 &lt;= ll &lt; 2**128 |


Back to Argon

We're looking at Argon2, which says:

H^x() = BLAKE2b(a,|a|,0,x)


So in our case:


  H0 = H^(64)( [stuff to hash] )
  H0 = Blake2b([stuff to hash], |[stuff to hash]|, 0, 64)


Which means that 64 is a number of bytes (not bits), which means that the very first line of the algorithm description should be:


  Establish H0 as the 64-byte value as shown below.


Where am I going wrong? How big is H0? H1? 

Bonus

I assume it's a typo when the RFC says:


  Here H^x() applied to string a is the BLAKE2b(a,|a|,0,x) hash function


and that it should read:


  Here H^(x)(a) applied to string a is the BLAKE2b(a,|a|,0,x) hash function


Because later it uses the second syntax:


  H^(64)( [stuff to hash] )
In core.h of the Argon2 reference implementation, we can see that ARGON2_PREHASH_DIGEST_LENGTH = 64.  In core.c, we can see that ARGON2_PREHASH_DIGEST_LENGTH and ARGON2_PREHASH_SEED_LENGTH are used as numbers of bytes (to allocate a buffer in bytes and to specify the size in bytes of a BLAKE2b hash).

We can also reason that it makes no sense for the password, salt, optional secret key, and associated data to figure into the hash only via a 64-bit intermediate quantity—that would open it to preimage attacks on the intermediate quantity.

Please send email to the authors of the internet-draft identifying the incorrect ‘64-bit’ units!

Update: The November 22, 2018 revision of the Argon2 internet-draft, draft-irtf-cfrg-argon2-04, corrects the typo:


  Establish H_0 as the 64-byte value as shown below.
  
  —draft-irtf-cfrg-argon2-04, §3.2 ‘Argon2 Operation’