diff options
Diffstat (limited to 'doc/rfc/rfc9106.txt')
-rw-r--r-- | doc/rfc/rfc9106.txt | 975 |
1 files changed, 975 insertions, 0 deletions
diff --git a/doc/rfc/rfc9106.txt b/doc/rfc/rfc9106.txt new file mode 100644 index 0000000..f950898 --- /dev/null +++ b/doc/rfc/rfc9106.txt @@ -0,0 +1,975 @@ + + + + +Internet Research Task Force (IRTF) A. Biryukov +Request for Comments: 9106 D. Dinu +Category: Informational University of Luxembourg +ISSN: 2070-1721 D. Khovratovich + ABDK Consulting + S. Josefsson + SJD AB + September 2021 + + + Argon2 Memory-Hard Function for Password Hashing and Proof-of-Work + Applications + +Abstract + + This document describes the Argon2 memory-hard function for password + hashing and proof-of-work applications. We provide an implementer- + oriented description with test vectors. The purpose is to simplify + adoption of Argon2 for Internet protocols. This document is a + product of the Crypto Forum Research Group (CFRG) in the IRTF. + +Status of This Memo + + This document is not an Internet Standards Track specification; it is + published for informational purposes. + + This document is a product of the Internet Research Task Force + (IRTF). The IRTF publishes the results of Internet-related research + and development activities. These results might not be suitable for + deployment. This RFC represents the consensus of the Crypto Forum + Research Group of the Internet Research Task Force (IRTF). Documents + approved for publication by the IRSG are not candidates for any level + of Internet Standard; see Section 2 of RFC 7841. + + Information about the current status of this document, any errata, + and how to provide feedback on it may be obtained at + https://www.rfc-editor.org/info/rfc9106. + +Copyright Notice + + Copyright (c) 2021 IETF Trust and the persons identified as the + document authors. All rights reserved. + + This document is subject to BCP 78 and the IETF Trust's Legal + Provisions Relating to IETF Documents + (https://trustee.ietf.org/license-info) in effect on the date of + publication of this document. Please review these documents + carefully, as they describe your rights and restrictions with respect + to this document. + +Table of Contents + + 1. Introduction + 1.1. Requirements Language + 2. Notation and Conventions + 3. Argon2 Algorithm + 3.1. Argon2 Inputs and Outputs + 3.2. Argon2 Operation + 3.3. Variable-Length Hash Function H' + 3.4. Indexing + 3.4.1. Computing the 32-Bit Values J_1 and J_2 + 3.4.2. Mapping J_1 and J_2 to Reference Block Index [l][z] + 3.5. Compression Function G + 3.6. Permutation P + 4. Parameter Choice + 5. Test Vectors + 5.1. Argon2d Test Vectors + 5.2. Argon2i Test Vectors + 5.3. Argon2id Test Vectors + 6. IANA Considerations + 7. Security Considerations + 7.1. Security as a Hash Function and KDF + 7.2. Security against Time-Space Trade-off Attacks + 7.3. Security for Time-Bounded Defenders + 7.4. Recommendations + 8. References + 8.1. Normative References + 8.2. Informative References + Acknowledgements + Authors' Addresses + +1. Introduction + + This document describes the Argon2 [ARGON2ESP] memory-hard function + for password hashing and proof-of-work applications. We provide an + implementer-oriented description with test vectors. The purpose is + to simplify adoption of Argon2 for Internet protocols. This document + corresponds to version 1.3 of the Argon2 hash function. + + Argon2 is a memory-hard function [HARD]. It is a streamlined design. + It aims at the highest memory-filling rate and effective use of + multiple computing units, while still providing defense against + trade-off attacks. Argon2 is optimized for the x86 architecture and + exploits the cache and memory organization of the recent Intel and + AMD processors. Argon2 has one primary variant, Argon2id, and two + supplementary variants, Argon2d and Argon2i. Argon2d uses data- + dependent memory access, which makes it suitable for cryptocurrencies + and proof-of-work applications with no threats from side-channel + timing attacks. Argon2i uses data-independent memory access, which + is preferred for password hashing and password-based key derivation. + Argon2id works as Argon2i for the first half of the first pass over + the memory and as Argon2d for the rest, thus providing both side- + channel attack protection and brute-force cost savings due to time- + memory trade-offs. Argon2i makes more passes over the memory to + protect from trade-off attacks [AB15]. + + Argon2id MUST be supported by any implementation of this document, + whereas Argon2d and Argon2i MAY be supported. + + Argon2 is also a mode of operation over a fixed-input-length + compression function G and a variable-input-length hash function H. + Even though Argon2 can be potentially used with an arbitrary function + H, as long as it provides outputs up to 64 bytes, the BLAKE2b + function [BLAKE2] is used in this document. + + For further background and discussion, see the Argon2 paper [ARGON2]. + + This document represents the consensus of the Crypto Forum Research + Group (CFRG). + +1.1. Requirements Language + + The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", + "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and + "OPTIONAL" in this document are to be interpreted as described in + BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all + capitals, as shown here. + +2. Notation and Conventions + + x^y integer x multiplied by itself integer y times + + a*b multiplication of integer a and integer b + + c-d subtraction of integer d from integer c + + E_f variable E with subscript index f + + g / h integer g divided by integer h. The result is a + rational number. + + I(j) function I evaluated at j + + K || L string K concatenated with string L + + a XOR b bitwise exclusive-or between bitstrings a and b + + a mod b remainder of integer a modulo integer b, always in + range [0, b-1] + + a >>> n rotation of 64-bit string a to the right by n bits + + trunc(a) the 64-bit value, truncated to the 32 least + significant bits + + floor(a) the largest integer not bigger than a + + ceil(a) the smallest integer not smaller than a + + extract(a, i) the i-th set of 32 bits from bitstring a, starting + from 0-th + + |A| the number of elements in set A + + LE32(a) 32-bit integer a converted to a byte string in little + endian (for example, 123456 (decimal) is 40 E2 01 00) + + LE64(a) 64-bit integer a converted to a byte string in little + endian (for example, 123456 (decimal) is 40 E2 01 00 + 00 00 00 00) + + int32(s) 32-bit string s is converted to a non-negative integer + in little endian + + int64(s) 64-bit string s is converted to a non-negative integer + in little endian + + length(P) the byte length of string P expressed as 32-bit + integer + + ZERO(P) the P-byte zero string + +3. Argon2 Algorithm + +3.1. Argon2 Inputs and Outputs + + Argon2 has the following input parameters: + + * Message string P, which is a password for password hashing + applications. It MUST have a length not greater than 2^(32)-1 + bytes. + + * Nonce S, which is a salt for password hashing applications. It + MUST have a length not greater than 2^(32)-1 bytes. 16 bytes is + RECOMMENDED for password hashing. The salt SHOULD be unique for + each password. + + * Degree of parallelism p determines how many independent (but + synchronizing) computational chains (lanes) can be run. It MUST + be an integer value from 1 to 2^(24)-1. + + * Tag length T MUST be an integer number of bytes from 4 to 2^(32)- + 1. + + * Memory size m MUST be an integer number of kibibytes from 8*p to + 2^(32)-1. The actual number of blocks is m', which is m rounded + down to the nearest multiple of 4*p. + + * Number of passes t (used to tune the running time independently of + the memory size) MUST be an integer number from 1 to 2^(32)-1. + + * Version number v MUST be one byte 0x13. + + * Secret value K is OPTIONAL. If used, it MUST have a length not + greater than 2^(32)-1 bytes. + + * Associated data X is OPTIONAL. If used, it MUST have a length not + greater than 2^(32)-1 bytes. + + * Type y MUST be 0 for Argon2d, 1 for Argon2i, or 2 for Argon2id. + + The Argon2 output, or "tag", is a string T bytes long. + +3.2. Argon2 Operation + + Argon2 uses an internal compression function G with two 1024-byte + inputs, a 1024-byte output, and an internal hash function H^x(), with + x being its output length in bytes. Here, H^x() applied to string A + is the BLAKE2b ([BLAKE2], Section 3.3) function, which takes + (d,ll,kk=0,nn=x) as parameters, where d is A padded to a multiple of + 128 bytes and ll is the length of d in bytes. The compression + function G is based on its internal permutation. A variable-length + hash function H' built upon H is also used. G is described in + Section 3.5, and H' is described in Section 3.3. + + The Argon2 operation is as follows. + + 1. Establish H_0 as the 64-byte value as shown below. If K, X, or S + has zero length, it is just absent, but its length field remains. + + 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) + + Figure 1: H_0 Generation + + 2. Allocate the memory as m' 1024-byte blocks, where m' is derived + as: + + m' = 4 * p * floor (m / 4p) + + Figure 2: Memory Allocation + + For p lanes, the memory is organized in a matrix B[i][j] of + blocks with p rows (lanes) and q = m' / p columns. + + 3. Compute B[i][0] for all i ranging from (and including) 0 to (not + including) p. + + B[i][0] = H'^(1024)(H_0 || LE32(0) || LE32(i)) + + Figure 3: Lane Starting Blocks + + 4. Compute B[i][1] for all i ranging from (and including) 0 to (not + including) p. + + B[i][1] = H'^(1024)(H_0 || LE32(1) || LE32(i)) + + Figure 4: Second Lane Blocks + + 5. Compute B[i][j] for all i ranging from (and including) 0 to (not + including) p and for all j ranging from (and including) 2 to (not + including) q. The computation MUST proceed slicewise + (Section 3.4): first, blocks from slice 0 are computed for all + lanes (in an arbitrary order of lanes), then blocks from slice 1 + are computed, etc. The block indices l and z are determined for + each i, j differently for Argon2d, Argon2i, and Argon2id. + + B[i][j] = G(B[i][j-1], B[l][z]) + + Figure 5: Further Block Generation + + 6. If the number of passes t is larger than 1, we repeat step 5. We + compute B[i][0] and B[i][j] for all i raging from (and including) + 0 to (not including) p and for all j ranging from (and including) + 1 to (not including) q. However, blocks are computed differently + as the old value is XORed with the new one: + + B[i][0] = G(B[i][q-1], B[l][z]) XOR B[i][0]; + B[i][j] = G(B[i][j-1], B[l][z]) XOR B[i][j]. + + Figure 6: Further Passes + + 7. After t steps have been iterated, the final block C is computed + as the XOR of the last column: + + C = B[0][q-1] XOR B[1][q-1] XOR ... XOR B[p-1][q-1] + + Figure 7: Final Block + + 8. The output tag is computed as H'^T(C). + +3.3. Variable-Length Hash Function H' + + Let V_i be a 64-byte block and W_i be its first 32 bytes. Then we + define function H' as follows: + + if T <= 64 + H'^T(A) = H^T(LE32(T)||A) + else + r = ceil(T/32)-2 + V_1 = H^(64)(LE32(T)||A) + V_2 = H^(64)(V_1) + ... + V_r = H^(64)(V_{r-1}) + V_{r+1} = H^(T-32*r)(V_{r}) + H'^T(X) = W_1 || W_2 || ... || W_r || V_{r+1} + + Figure 8: Function H' for Tag and Initial Block Computations + +3.4. Indexing + + To enable parallel block computation, we further partition the memory + matrix into SL = 4 vertical slices. The intersection of a slice and + a lane is called a segment, which has a length of q/SL. Segments of + the same slice can be computed in parallel and do not reference + blocks from each other. All other blocks can be referenced. + + slice 0 slice 1 slice 2 slice 3 + ___/\___ ___/\___ ___/\___ ___/\___ + / \ / \ / \ / \ + +----------+----------+----------+----------+ + | | | | | > lane 0 + +----------+----------+----------+----------+ + | | | | | > lane 1 + +----------+----------+----------+----------+ + | | | | | > lane 2 + +----------+----------+----------+----------+ + | ... ... ... | ... + +----------+----------+----------+----------+ + | | | | | > lane p - 1 + +----------+----------+----------+----------+ + + Figure 9: Single-Pass Argon2 with p Lanes and 4 Slices + +3.4.1. Computing the 32-Bit Values J_1 and J_2 + +3.4.1.1. Argon2d + + J_1 is given by the first 32 bits of block B[i][j-1], while J_2 is + given by the next 32 bits of block B[i][j-1]: + + J_1 = int32(extract(B[i][j-1], 0)) + J_2 = int32(extract(B[i][j-1], 1)) + + Figure 10: Deriving J1,J2 in Argon2d + +3.4.1.2. Argon2i + + For each segment, we do the following. First, we compute the value Z + as: + + Z= ( LE64(r) || LE64(l) || LE64(sl) || LE64(m') || + LE64(t) || LE64(y) ) + + Figure 11: Input to Compute J1,J2 in Argon2i + + where + + r: the pass number + l: the lane number + sl: the slice number + m': the total number of memory blocks + t: the total number of passes + y: the Argon2 type (0 for Argon2d, 1 for Argon2i, 2 for Argon2id) + + Then we compute: + + q/(128*SL) 1024-byte values + G(ZERO(1024),G(ZERO(1024), + Z || LE64(1) || ZERO(968) )), + G(ZERO(1024),G(ZERO(1024), + Z || LE64(2) || ZERO(968) )),... , + G(ZERO(1024),G(ZERO(1024), + Z || LE64(q/(128*SL)) || ZERO(968) )), + + which are partitioned into q/(SL) 8-byte values X, which are viewed + as X1||X2 and converted to J_1=int32(X1) and J_2=int32(X2). + + The values r, l, sl, m', t, y, and i are represented as 8 bytes in + little endian. + +3.4.1.3. Argon2id + + If the pass number is 0 and the slice number is 0 or 1, then compute + J_1 and J_2 as for Argon2i, else compute J_1 and J_2 as for Argon2d. + +3.4.2. Mapping J_1 and J_2 to Reference Block Index [l][z] + + The value of l = J_2 mod p gives the index of the lane from which the + block will be taken. For the first pass (r=0) and the first slice + (sl=0), the block is taken from the current lane. + + The set W contains the indices that are referenced according to the + following rules: + + 1. If l is the current lane, then W includes the indices of all + blocks in the last SL - 1 = 3 segments computed and finished, as + well as the blocks computed in the current segment in the current + pass excluding B[i][j-1]. + + 2. If l is not the current lane, then W includes the indices of all + blocks in the last SL - 1 = 3 segments computed and finished in + lane l. If B[i][j] is the first block of a segment, then the + very last index from W is excluded. + + Then take a block from W with a nonuniform distribution over [0, |W|) + using the following mapping: + + J_1 -> |W|(1 - J_1^2 / 2^(64)) + + Figure 12: Computing J1 + + To avoid floating point computation, the following approximation is + used: + + x = J_1^2 / 2^(32) + y = (|W| * x) / 2^(32) + zz = |W| - 1 - y + + Figure 13: Computing J1, Part 2 + + Then take the zz-th index from W; it will be the z value for the + reference block index [l][z]. + +3.5. Compression Function G + + The compression function G is built upon the BLAKE2b-based + transformation P. P operates on the 128-byte input, which can be + viewed as eight 16-byte registers: + + P(A_0, A_1, ... ,A_7) = (B_0, B_1, ... ,B_7) + + Figure 14: Blake Round Function P + + The compression function G(X, Y) operates on two 1024-byte blocks X + and Y. It first computes R = X XOR Y. Then R is viewed as an 8x8 + matrix of 16-byte registers R_0, R_1, ... , R_63. Then P is first + applied to each row, and then to each column to get Z: + + ( Q_0, Q_1, Q_2, ... , Q_7) <- P( R_0, R_1, R_2, ... , R_7) + ( Q_8, Q_9, Q_10, ... , Q_15) <- P( R_8, R_9, R_10, ... , R_15) + ... + (Q_56, Q_57, Q_58, ... , Q_63) <- P(R_56, R_57, R_58, ... , R_63) + ( Z_0, Z_8, Z_16, ... , Z_56) <- P( Q_0, Q_8, Q_16, ... , Q_56) + ( Z_1, Z_9, Z_17, ... , Z_57) <- P( Q_1, Q_9, Q_17, ... , Q_57) + ... + ( Z_7, Z_15, Z 23, ... , Z_63) <- P( Q_7, Q_15, Q_23, ... , Q_63) + + Figure 15: Core of Compression Function G + + Finally, G outputs Z XOR R: + + G: (X, Y) -> R -> Q -> Z -> Z XOR R + + +---+ +---+ + | X | | Y | + +---+ +---+ + | | + ---->XOR<---- + --------| + | \ / + | +---+ + | | R | + | +---+ + | | + | \ / + | P rowwise + | | + | \ / + | +---+ + | | Q | + | +---+ + | | + | \ / + | P columnwise + | | + | \ / + | +---+ + | | Z | + | +---+ + | | + | \ / + ------>XOR + | + \ / + + Figure 16: Argon2 Compression Function G + +3.6. Permutation P + + Permutation P is based on the round function of BLAKE2b. The eight + 16-byte inputs S_0, S_1, ... , S_7 are viewed as a 4x4 matrix of + 64-bit words, where S_i = (v_{2*i+1} || v_{2*i}): + + v_0 v_1 v_2 v_3 + v_4 v_5 v_6 v_7 + v_8 v_9 v_10 v_11 + v_12 v_13 v_14 v_15 + + Figure 17: Matrix Element Labeling + + It works as follows: + + GB(v_0, v_4, v_8, v_12) + GB(v_1, v_5, v_9, v_13) + GB(v_2, v_6, v_10, v_14) + GB(v_3, v_7, v_11, v_15) + + GB(v_0, v_5, v_10, v_15) + GB(v_1, v_6, v_11, v_12) + GB(v_2, v_7, v_8, v_13) + GB(v_3, v_4, v_9, v_14) + + Figure 18: Feeding Matrix Elements to GB + + GB(a, b, c, d) is defined as follows: + + a = (a + b + 2 * trunc(a) * trunc(b)) mod 2^(64) + d = (d XOR a) >>> 32 + c = (c + d + 2 * trunc(c) * trunc(d)) mod 2^(64) + b = (b XOR c) >>> 24 + + a = (a + b + 2 * trunc(a) * trunc(b)) mod 2^(64) + d = (d XOR a) >>> 16 + c = (c + d + 2 * trunc(c) * trunc(d)) mod 2^(64) + b = (b XOR c) >>> 63 + + Figure 19: Details of GB + + The modular additions in GB are combined with 64-bit multiplications. + Multiplications are the only difference from the original BLAKE2b + design. This choice is done to increase the circuit depth and thus + the running time of ASIC implementations, while having roughly the + same running time on CPUs thanks to parallelism and pipelining. + +4. Parameter Choice + + Argon2d is optimized for settings where the adversary does not get + regular access to system memory or CPU, i.e., they cannot run side- + channel attacks based on the timing information, nor can they recover + the password much faster using garbage collection. These settings + are more typical for backend servers and cryptocurrency minings. For + practice, we suggest the following settings: + + * Cryptocurrency mining, which takes 0.1 seconds on a 2 GHz CPU + using 1 core -- Argon2d with 2 lanes and 250 MB of RAM. + + Argon2id is optimized for more realistic settings, where the + adversary can possibly access the same machine, use its CPU, or mount + cold-boot attacks. We suggest the following settings: + + * Backend server authentication, which takes 0.5 seconds on a 2 GHz + CPU using 4 cores -- Argon2id with 8 lanes and 4 GiB of RAM. + + * Key derivation for hard-drive encryption, which takes 3 seconds on + a 2 GHz CPU using 2 cores -- Argon2id with 4 lanes and 6 GiB of + RAM. + + * Frontend server authentication, which takes 0.5 seconds on a 2 GHz + CPU using 2 cores -- Argon2id with 4 lanes and 1 GiB of RAM. + + We recommend the following procedure to select the type and the + parameters for practical use of Argon2. + + 1. If a uniformly safe option that is not tailored to your + application or hardware is acceptable, select Argon2id with t=1 + iteration, p=4 lanes, m=2^(21) (2 GiB of RAM), 128-bit salt, and + 256-bit tag size. This is the FIRST RECOMMENDED option. + + 2. If much less memory is available, a uniformly safe option is + Argon2id with t=3 iterations, p=4 lanes, m=2^(16) (64 MiB of + RAM), 128-bit salt, and 256-bit tag size. This is the SECOND + RECOMMENDED option. + + 3. Otherwise, start with selecting the type y. If you do not know + the difference between the types or you consider side-channel + attacks to be a viable threat, choose Argon2id. + + 4. Select p=4 lanes. + + 5. Figure out the maximum amount of memory that each call can + afford and translate it to the parameter m. + + 6. Figure out the maximum amount of time (in seconds) that each + call can afford. + + 7. Select the salt length. A length of 128 bits is sufficient for + all applications but can be reduced to 64 bits in the case of + space constraints. + + 8. Select the tag length. A length of 128 bits is sufficient for + most applications, including key derivation. If longer keys are + needed, select longer tags. + + 9. If side-channel attacks are a viable threat or if you're + uncertain, enable the memory-wiping option in the library call. + + 10. Run the scheme of type y, memory m, and p lanes using a + different number of passes t. Figure out the maximum t such + that the running time does not exceed the affordable time. If + it even exceeds for t = 1, reduce m accordingly. + + 11. Use Argon2 with determined values m, p, and t. + +5. Test Vectors + + This section contains test vectors for Argon2. + +5.1. Argon2d Test Vectors + + We provide test vectors with complete outputs (tags). For the + convenience of developers, we also provide some interim variables -- + concretely, the first and last memory blocks of each pass. + + ======================================= + Argon2d version number 19 + ======================================= + Memory: 32 KiB + Passes: 3 + Parallelism: 4 lanes + Tag length: 32 bytes + Password[32]: 01 01 01 01 01 01 01 01 + 01 01 01 01 01 01 01 01 + 01 01 01 01 01 01 01 01 + 01 01 01 01 01 01 01 01 + Salt[16]: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 + Secret[8]: 03 03 03 03 03 03 03 03 + Associated data[12]: 04 04 04 04 04 04 04 04 04 04 04 04 + Pre-hashing digest: b8 81 97 91 a0 35 96 60 + bb 77 09 c8 5f a4 8f 04 + d5 d8 2c 05 c5 f2 15 cc + db 88 54 91 71 7c f7 57 + 08 2c 28 b9 51 be 38 14 + 10 b5 fc 2e b7 27 40 33 + b9 fd c7 ae 67 2b ca ac + 5d 17 90 97 a4 af 31 09 + + After pass 0: + Block 0000 [ 0]: db2fea6b2c6f5c8a + Block 0000 [ 1]: 719413be00f82634 + Block 0000 [ 2]: a1e3f6dd42aa25cc + Block 0000 [ 3]: 3ea8efd4d55ac0d1 + ... + Block 0031 [124]: 28d17914aea9734c + Block 0031 [125]: 6a4622176522e398 + Block 0031 [126]: 951aa08aeecb2c05 + Block 0031 [127]: 6a6c49d2cb75d5b6 + + After pass 1: + Block 0000 [ 0]: d3801200410f8c0d + Block 0000 [ 1]: 0bf9e8a6e442ba6d + Block 0000 [ 2]: e2ca92fe9c541fcc + Block 0000 [ 3]: 6269fe6db177a388 + ... + Block 0031 [124]: 9eacfcfbdb3ce0fc + Block 0031 [125]: 07dedaeb0aee71ac + Block 0031 [126]: 074435fad91548f4 + Block 0031 [127]: 2dbfff23f31b5883 + + After pass 2: + Block 0000 [ 0]: 5f047b575c5ff4d2 + Block 0000 [ 1]: f06985dbf11c91a8 + Block 0000 [ 2]: 89efb2759f9a8964 + Block 0000 [ 3]: 7486a73f62f9b142 + ... + Block 0031 [124]: 57cfb9d20479da49 + Block 0031 [125]: 4099654bc6607f69 + Block 0031 [126]: f142a1126075a5c8 + Block 0031 [127]: c341b3ca45c10da5 + Tag: 51 2b 39 1b 6f 11 62 97 + 53 71 d3 09 19 73 42 94 + f8 68 e3 be 39 84 f3 c1 + a1 3a 4d b9 fa be 4a cb + +5.2. Argon2i Test Vectors + + ======================================= + Argon2i version number 19 + ======================================= + Memory: 32 KiB + Passes: 3 + Parallelism: 4 lanes + Tag length: 32 bytes + Password[32]: 01 01 01 01 01 01 01 01 + 01 01 01 01 01 01 01 01 + 01 01 01 01 01 01 01 01 + 01 01 01 01 01 01 01 01 + Salt[16]: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 + Secret[8]: 03 03 03 03 03 03 03 03 + Associated data[12]: 04 04 04 04 04 04 04 04 04 04 04 04 + Pre-hashing digest: c4 60 65 81 52 76 a0 b3 + e7 31 73 1c 90 2f 1f d8 + 0c f7 76 90 7f bb 7b 6a + 5c a7 2e 7b 56 01 1f ee + ca 44 6c 86 dd 75 b9 46 + 9a 5e 68 79 de c4 b7 2d + 08 63 fb 93 9b 98 2e 5f + 39 7c c7 d1 64 fd da a9 + + After pass 0: + Block 0000 [ 0]: f8f9e84545db08f6 + Block 0000 [ 1]: 9b073a5c87aa2d97 + Block 0000 [ 2]: d1e868d75ca8d8e4 + Block 0000 [ 3]: 349634174e1aebcc + ... + Block 0031 [124]: 975f596583745e30 + Block 0031 [125]: e349bdd7edeb3092 + Block 0031 [126]: b751a689b7a83659 + Block 0031 [127]: c570f2ab2a86cf00 + + After pass 1: + Block 0000 [ 0]: b2e4ddfcf76dc85a + Block 0000 [ 1]: 4ffd0626c89a2327 + Block 0000 [ 2]: 4af1440fff212980 + Block 0000 [ 3]: 1e77299c7408505b + ... + Block 0031 [124]: e4274fd675d1e1d6 + Block 0031 [125]: 903fffb7c4a14c98 + Block 0031 [126]: 7e5db55def471966 + Block 0031 [127]: 421b3c6e9555b79d + + After pass 2: + Block 0000 [ 0]: af2a8bd8482c2f11 + Block 0000 [ 1]: 785442294fa55e6d + Block 0000 [ 2]: 9256a768529a7f96 + Block 0000 [ 3]: 25a1c1f5bb953766 + ... + Block 0031 [124]: 68cf72fccc7112b9 + Block 0031 [125]: 91e8c6f8bb0ad70d + Block 0031 [126]: 4f59c8bd65cbb765 + Block 0031 [127]: 71e436f035f30ed0 + Tag: c8 14 d9 d1 dc 7f 37 aa + 13 f0 d7 7f 24 94 bd a1 + c8 de 6b 01 6d d3 88 d2 + 99 52 a4 c4 67 2b 6c e8 + +5.3. Argon2id Test Vectors + + ======================================= + Argon2id version number 19 + ======================================= + Memory: 32 KiB, Passes: 3, + Parallelism: 4 lanes, Tag length: 32 bytes + Password[32]: 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 + 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 + Salt[16]: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 + Secret[8]: 03 03 03 03 03 03 03 03 + Associated data[12]: 04 04 04 04 04 04 04 04 04 04 04 04 + Pre-hashing digest: 28 89 de 48 7e b4 2a e5 00 c0 00 7e d9 25 2f + 10 69 ea de c4 0d 57 65 b4 85 de 6d c2 43 7a 67 b8 54 6a 2f 0a + cc 1a 08 82 db 8f cf 74 71 4b 47 2e 94 df 42 1a 5d a1 11 2f fa + 11 43 43 70 a1 e9 97 + + After pass 0: + Block 0000 [ 0]: 6b2e09f10671bd43 + Block 0000 [ 1]: f69f5c27918a21be + Block 0000 [ 2]: dea7810ea41290e1 + Block 0000 [ 3]: 6787f7171870f893 + ... + Block 0031 [124]: 377fa81666dc7f2b + Block 0031 [125]: 50e586398a9c39c8 + Block 0031 [126]: 6f732732a550924a + Block 0031 [127]: 81f88b28683ea8e5 + + After pass 1: + Block 0000 [ 0]: 3653ec9d01583df9 + Block 0000 [ 1]: 69ef53a72d1e1fd3 + Block 0000 [ 2]: 35635631744ab54f + Block 0000 [ 3]: 599512e96a37ab6e + ... + Block 0031 [124]: 4d4b435cea35caa6 + Block 0031 [125]: c582210d99ad1359 + Block 0031 [126]: d087971b36fd6d77 + Block 0031 [127]: a55222a93754c692 + + After pass 2: + Block 0000 [ 0]: 942363968ce597a4 + Block 0000 [ 1]: a22448c0bdad5760 + Block 0000 [ 2]: a5f80662b6fa8748 + Block 0000 [ 3]: a0f9b9ce392f719f + ... + Block 0031 [124]: d723359b485f509b + Block 0031 [125]: cb78824f42375111 + Block 0031 [126]: 35bc8cc6e83b1875 + Block 0031 [127]: 0b012846a40f346a + Tag: 0d 64 0d f5 8d 78 76 6c 08 c0 37 a3 4a 8b 53 c9 d0 + 1e f0 45 2d 75 b6 5e b5 25 20 e9 6b 01 e6 59 + +6. IANA Considerations + + This document has no IANA actions. + +7. Security Considerations + +7.1. Security as a Hash Function and KDF + + The collision and preimage resistance levels of Argon2 are equivalent + to those of the underlying BLAKE2b hash function. To produce a + collision, 2^(256) inputs are needed. To find a preimage, 2^(512) + inputs must be tried. + + The KDF security is determined by the key length and the size of the + internal state of hash function H'. To distinguish the output of the + keyed Argon2 from random, a minimum of (2^(128),2^length(K)) calls to + BLAKE2b are needed. + +7.2. Security against Time-Space Trade-off Attacks + + Time-space trade-offs allow computing a memory-hard function storing + fewer memory blocks at the cost of more calls to the internal + compression function. The advantage of trade-off attacks is measured + in the reduction factor to the time-area product, where memory and + extra compression function cores contribute to the area and time is + increased to accommodate the recomputation of missed blocks. A high + reduction factor may potentially speed up the preimage search. + + The best-known attack on the 1-pass and 2-pass Argon2i is the low- + storage attack described in [CBS16], which reduces the time-area + product (using the peak memory value) by the factor of 5. The best + attack on Argon2i with 3 passes or more is described in [AB16], with + the reduction factor being a function of memory size and the number + of passes (e.g., for 1 gibibyte of memory, a reduction factor of 3 + for 3 passes, 2.5 for 4 passes, 2 for 6 passes). The reduction + factor grows by about 0.5 with every doubling of the memory size. To + completely prevent time-space trade-offs from [AB16], the number of + passes MUST exceed the binary logarithm of memory minus 26. + Asymptotically, the best attack on 1-pass Argon2i is given in [BZ17], + with maximal advantage of the adversary upper bounded by + O(m^(0.233)), where m is the number of blocks. This attack is also + asymptotically optimal as [BZ17] also proves the upper bound on any + attack is O(m^(0.25)). + + The best trade-off attack on t-pass Argon2d is the ranking trade-off + attack, which reduces the time-area product by the factor of 1.33. + + The best attack on Argon2id can be obtained by complementing the best + attack on the 1-pass Argon2i with the best attack on a multi-pass + Argon2d. Thus, the best trade-off attack on 1-pass Argon2id is the + combined low-storage attack (for the first half of the memory) and + the ranking attack (for the second half), which generate the factor + of about 2.1. The best trade-off attack on t-pass Argon2id is the + ranking trade-off attack, which reduces the time-area product by the + factor of 1.33. + +7.3. Security for Time-Bounded Defenders + + A bottleneck in a system employing the password hashing function is + often the function latency rather than memory costs. A rational + defender would then maximize the brute-force costs for the attacker + equipped with a list of hashes, salts, and timing information for + fixed computing time on the defender's machine. The attack cost + estimates from [AB16] imply that for Argon2i, 3 passes is almost + optimal for most reasonable memory sizes; for Argon2d and Argon2id, 1 + pass maximizes the attack costs for the constant defender time. + +7.4. Recommendations + + The Argon2id variant with t=1 and 2 GiB memory is the FIRST + RECOMMENDED option and is suggested as a default setting for all + environments. This setting is secure against side-channel attacks + and maximizes adversarial costs on dedicated brute-force hardware. + The Argon2id variant with t=3 and 64 MiB memory is the SECOND + RECOMMENDED option and is suggested as a default setting for memory- + constrained environments. + +8. References + +8.1. Normative References + + [BLAKE2] Saarinen, M-J., Ed. and J-P. Aumasson, "The BLAKE2 + Cryptographic Hash and Message Authentication Code (MAC)", + RFC 7693, DOI 10.17487/RFC7693, November 2015, + <https://www.rfc-editor.org/info/rfc7693>. + + [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate + Requirement Levels", BCP 14, RFC 2119, + DOI 10.17487/RFC2119, March 1997, + <https://www.rfc-editor.org/info/rfc2119>. + + [RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC + 2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, + May 2017, <https://www.rfc-editor.org/info/rfc8174>. + +8.2. Informative References + + [AB15] Biryukov, A. and D. Khovratovich, "Tradeoff Cryptanalysis + of Memory-Hard Functions", ASIACRYPT 2015, + DOI 10.1007/978-3-662-48800-3_26, December 2015, + <https://eprint.iacr.org/2015/227.pdf>. + + [AB16] Alwen, J. and J. Blocki, "Efficiently Computing Data- + Independent Memory-Hard Functions", CRYPTO 2016, + DOI 10.1007/978-3-662-53008-5_9, March 2016, + <https://eprint.iacr.org/2016/115.pdf>. + + [ARGON2] Biryukov, A., Dinu, D., and D. Khovratovich, "Argon2: the + memory-hard function for password hashing and other + applications", March 2017, + <https://www.cryptolux.org/images/0/0d/Argon2.pdf>. + + [ARGON2ESP] + Biryukov, A., Dinu, D., and D. Khovratovich, "Argon2: New + Generation of Memory-Hard Functions for Password Hashing + and Other Applications", Euro SnP 2016, + DOI 10.1109/EuroSP.2016.31, March 2016, + <https://www.cryptolux.org/images/d/d0/Argon2ESP.pdf>. + + [BZ17] Blocki, J. and S. Zhou, "On the Depth-Robustness and + Cumulative Pebbling Cost of Argon2i", TCC 2017, + DOI 10.1007/978-3-319-70500-2_15, May 2017, + <https://eprint.iacr.org/2017/442.pdf>. + + [CBS16] Boneh, D., Corrigan-Gibbs, H., and S. Schechter, "Balloon + Hashing: A Memory-Hard Function Providing Provable + Protection Against Sequential Attacks", ASIACRYPT 2016, + DOI 10.1007/978-3-662-53887-6_8, May 2017, + <https://eprint.iacr.org/2016/027.pdf>. + + [HARD] Alwen, J. and V. Serbinenko, "High Parallel Complexity + Graphs and Memory-Hard Functions", STOC '15, + DOI 10.1145/2746539.2746622, June 2015, + <https://eprint.iacr.org/2014/238.pdf>. + +Acknowledgements + + We greatly thank the following individuals who helped in preparing + and reviewing this document: Jean-Philippe Aumasson, Samuel Neves, + Joel Alwen, Jeremiah Blocki, Bill Cox, Arnold Reinhold, Solar + Designer, Russ Housley, Stanislav Smyshlyaev, Kenny Paterson, Alexey + Melnikov, and Gwynne Raskind. + + The work described in this document was done before Daniel Dinu + joined Intel, while he was at the University of Luxembourg. + +Authors' Addresses + + Alex Biryukov + University of Luxembourg + + Email: alex.biryukov@uni.lu + + + Daniel Dinu + University of Luxembourg + + Email: daniel.dinu@intel.com + + + Dmitry Khovratovich + ABDK Consulting + + Email: khovratovich@gmail.com + + + Simon Josefsson + SJD AB + + Email: simon@josefsson.org + URI: http://josefsson.org/ |