rfc9106.original   rfc9106.txt 
CFRG A. Biryukov Internet Research Task Force (IRTF) A. Biryukov
Internet-Draft D. Dinu Request for Comments: 9106 D. Dinu
Intended status: Informational University of Luxembourg Category: Informational University of Luxembourg
Expires: September 12, 2021 D. Khovratovich ISSN: 2070-1721 D. Khovratovich
ABDK Consulting ABDK Consulting
S. Josefsson S. Josefsson
SJD AB SJD AB
March 11, 2021 August 2021
The memory-hard Argon2 password hash and proof-of-work function Argon2 Memory-Hard Function for Password Hashing and Proof-of-Work
draft-irtf-cfrg-argon2-13 Applications
Abstract Abstract
This document describes the Argon2 memory-hard function for password This document describes the Argon2 memory-hard function for password
hashing and proof-of-work applications. We provide an implementer- hashing and proof-of-work applications. We provide an implementer-
oriented description with test vectors. The purpose is to simplify oriented description with test vectors. The purpose is to simplify
adoption of Argon2 for Internet protocols. This document is a adoption of Argon2 for Internet protocols. This document is a
product of the Crypto Forum Research Group (CFRG) in the IRTF. product of the Crypto Forum Research Group (CFRG) in the IRTF.
Status of This Memo Status of This Memo
This Internet-Draft is submitted in full conformance with the This document is not an Internet Standards Track specification; it is
provisions of BCP 78 and BCP 79. published for informational purposes.
Internet-Drafts are working documents of the Internet Engineering
Task Force (IETF). Note that other groups may also distribute
working documents as Internet-Drafts. The list of current Internet-
Drafts is at https://datatracker.ietf.org/drafts/current/.
Internet-Drafts are draft documents valid for a maximum of six months This document is a product of the Internet Research Task Force
and may be updated, replaced, or obsoleted by other documents at any (IRTF). The IRTF publishes the results of Internet-related research
time. It is inappropriate to use Internet-Drafts as reference and development activities. These results might not be suitable for
material or to cite them other than as "work in progress." 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.
This Internet-Draft will expire on September 12, 2021. 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 Notice
Copyright (c) 2021 IETF Trust and the persons identified as the Copyright (c) 2021 IETF Trust and the persons identified as the
document authors. All rights reserved. document authors. All rights reserved.
This document is subject to BCP 78 and the IETF Trust's Legal This document is subject to BCP 78 and the IETF Trust's Legal
Provisions Relating to IETF Documents Provisions Relating to IETF Documents
(https://trustee.ietf.org/license-info) in effect on the date of (https://trustee.ietf.org/license-info) in effect on the date of
publication of this document. Please review these documents publication of this document. Please review these documents
carefully, as they describe your rights and restrictions with respect carefully, as they describe your rights and restrictions with respect
to this document. Code Components extracted from this document must to this document.
include Simplified BSD License text as described in Section 4.e of
the Trust Legal Provisions and are provided without warranty as
described in the Simplified BSD License.
Table of Contents Table of Contents
1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 2 1. Introduction
2. Notation and Conventions . . . . . . . . . . . . . . . . . . 3 1.1. Requirements Language
3. Argon2 Algorithm . . . . . . . . . . . . . . . . . . . . . . 4 2. Notation and Conventions
3.1. Argon2 Inputs and Outputs . . . . . . . . . . . . . . . . 4 3. Argon2 Algorithm
3.2. Argon2 Operation . . . . . . . . . . . . . . . . . . . . 5 3.1. Argon2 Inputs and Outputs
3.3. Variable-length hash function H' . . . . . . . . . . . . 7 3.2. Argon2 Operation
3.4. Indexing . . . . . . . . . . . . . . . . . . . . . . . . 7 3.3. Variable-Length Hash Function H'
3.4.1. Computing the 32-bit values J_1 and J_2 . . . . . . . 8 3.4. Indexing
3.4.2. Mapping J_1 and J_2 to reference block index [l][z] . 9 3.4.1. Computing the 32-Bit Values J_1 and J_2
3.5. Compression function G . . . . . . . . . . . . . . . . . 10 3.4.2. Mapping J_1 and J_2 to Reference Block Index [l][z]
3.6. Permutation P . . . . . . . . . . . . . . . . . . . . . . 11 3.5. Compression Function G
4. Parameter Choice . . . . . . . . . . . . . . . . . . . . . . 12 3.6. Permutation P
5. Test Vectors . . . . . . . . . . . . . . . . . . . . . . . . 14 4. Parameter Choice
5.1. Argon2d Test Vectors . . . . . . . . . . . . . . . . . . 14 5. Test Vectors
5.2. Argon2i Test Vectors . . . . . . . . . . . . . . . . . . 15 5.1. Argon2d Test Vectors
5.3. Argon2id Test Vectors . . . . . . . . . . . . . . . . . . 16 5.2. Argon2i Test Vectors
6. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 18 5.3. Argon2id Test Vectors
7. Security Considerations . . . . . . . . . . . . . . . . . . . 18 6. IANA Considerations
7.1. Security as hash function and KDF . . . . . . . . . . . . 18 7. Security Considerations
7.2. Security against time-space tradeoff attacks . . . . . . 18 7.1. Security as a Hash Function and KDF
7.3. Security for time-bounded defenders . . . . . . . . . . . 19 7.2. Security against Time-Space Trade-off Attacks
7.4. Recommendations . . . . . . . . . . . . . . . . . . . . . 19 7.3. Security for Time-Bounded Defenders
8. Acknowledgements . . . . . . . . . . . . . . . . . . . . . . 19 7.4. Recommendations
9. References . . . . . . . . . . . . . . . . . . . . . . . . . 19 8. References
9.1. Normative References . . . . . . . . . . . . . . . . . . 19 8.1. Normative References
9.2. Informative References . . . . . . . . . . . . . . . . . 20 8.2. Informative References
Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 20 Acknowledgements
Authors' Addresses
1. Introduction 1. Introduction
This document describes the Argon2 [ARGON2ESP] memory-hard function This document describes the Argon2 [ARGON2ESP] memory-hard function
for password hashing and proof-of-work applications. We provide an for password hashing and proof-of-work applications. We provide an
implementer oriented description with test vectors. The purpose is implementer-oriented description with test vectors. The purpose is
to simplify adoption of Argon2 for Internet protocols. This document to simplify adoption of Argon2 for Internet protocols. This document
corresponds to version 1.3 of the Argon2 hash function. corresponds to version 1.3 of the Argon2 hash function.
Argon2 is a traditional memory-hard function [HARD]. It is a Argon2 is a memory-hard function [HARD]. It is a streamlined design.
streamlined design. It aims at the highest memory filling rate and It aims at the highest memory-filling rate and effective use of
effective use of multiple computing units, while still providing multiple computing units, while still providing defense against
defense against tradeoff attacks. Argon2 is optimized for the x86 trade-off attacks. Argon2 is optimized for the x86 architecture and
architecture and exploits the cache and memory organization of the exploits the cache and memory organization of the recent Intel and
recent Intel and AMD processors. Argon2 has one primary variant: AMD processors. Argon2 has one primary variant, Argon2id, and two
Argon2id and two supplementary variants: Argon2d and Argon2i. supplementary variants, Argon2d and Argon2i. Argon2d uses data-
Argon2d uses data-dependent memory access, which makes it suitable dependent memory access, which makes it suitable for cryptocurrencies
for cryptocurrencies and proof-of-work applications with no threats and proof-of-work applications with no threats from side-channel
from side-channel timing attacks. Argon2i uses data-independent timing attacks. Argon2i uses data-independent memory access, which
memory access, which is preferred for password hashing and password- is preferred for password hashing and password-based key derivation.
based key derivation. Argon2id works as Argon2i for the first half Argon2id works as Argon2i for the first half of the first pass over
of the first pass over the memory, and as Argon2d for the rest, thus the memory and as Argon2d for the rest, thus providing both side-
providing both side-channel attack protection and brute-force cost channel attack protection and brute-force cost savings due to time-
savings due to time-memory tradeoffs. Argon2i makes more passes over memory trade-offs. Argon2i makes more passes over the memory to
the memory to protect from tradeoff attacks [AB15]. protect from trade-off attacks [AB15].
Argon2id MUST be supported by any implementation of this document, Argon2id MUST be supported by any implementation of this document,
whereas Argon2d and Argon2i MAY be supported. whereas Argon2d and Argon2i MAY be supported.
Argon2 is also a mode of operation over a fixed-input-length Argon2 is also a mode of operation over a fixed-input-length
compression function G and a variable-input-length hash function H. compression function G and a variable-input-length hash function H.
Even though Argon2 can be potentially used with an arbitrary function Even though Argon2 can be potentially used with an arbitrary function
H, as long as it provides outputs up to 64 bytes, in this document it H, as long as it provides outputs up to 64 bytes, the BLAKE2b
is BLAKE2b [BLAKE2]. function [BLAKE2] is used in this document.
For further background and discussion, see the Argon2 paper [ARGON2]. For further background and discussion, see the Argon2 paper [ARGON2].
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
document are to be interpreted as described in RFC 2119 [RFC2119].
This document represents the consensus of the Crypto Forum Research This document represents the consensus of the Crypto Forum Research
Group (CFRG). 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 2. Notation and Conventions
x^y --- integer x multiplied by itself integer y times x^y integer x multiplied by itself integer y times
a*b --- multiplication of integer a and integer b a*b multiplication of integer a and integer b
c-d --- subtraction of integer d from integer c c-d subtraction of integer d from integer c
E_f --- variable E with subscript index f E_f variable E with subscript index f
g / h --- integer g divided by integer h. The result is a rational g / h integer g divided by integer h. The result is a
number rational number.
I(j) --- function I evaluated at j I(j) function I evaluated at j
K || L --- string K concatenated with string L K || L string K concatenated with string L
a XOR b --- bitwise exclusive-or between bitstrings a and b 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 a mod b remainder of integer a modulo integer b, always in
range [0, b-1]
trunc(a) --- the 64-bit value, truncated to the 32 least significant a >>> n rotation of 64-bit string a to the right by n bits
bits
floor(a) --- the largest integer not bigger than a trunc(a) the 64-bit value, truncated to the 32 least
significant bits
ceil(a) --- the smallest integer not smaller than a floor(a) the largest integer not bigger than a
extract(a, i) --- the i-th set of 32-bits from bitstring a, starting ceil(a) the smallest integer not smaller than a
from 0-th
|A| --- the number of elements in set A extract(a, i) the i-th set of 32 bits from bitstring a, starting
from 0-th
LE32(a) --- 32-bit integer a converted to a bytestring in little |A| the number of elements in set A
endian. Example: 123456 (decimal) is 40 E2 01 00.
LE64(a) --- 64-bit integer a converted to a bytestring in little LE32(a) 32-bit integer a converted to a byte string in little
endian. Example: 123456 (decimal) is 40 E2 01 00 00 00 00 00. endian (for example, 123456 (decimal) is 40 E2 01 00)
int32(s) --- 32-bit string s is converted to non-negative integer in LE64(a) 64-bit integer a converted to a byte string in little
little endian. endian (for example, 123456 (decimal) is 40 E2 01 00
00 00 00 00)
int64(s) --- 64-bit string s is converted to non-negative integer in int32(s) 32-bit string s is converted to a non-negative integer
little endian. in little endian
length(P) --- the bytelength of string P expressed as 32-bit integer int64(s) 64-bit string s is converted to a non-negative integer
in little endian
ZERO(P) --- the P-byte zero string length(P) the byte length of string P expressed as 32-bit
integer
ZERO(P) the P-byte zero string
3. Argon2 Algorithm 3. Argon2 Algorithm
3.1. Argon2 Inputs and Outputs 3.1. Argon2 Inputs and Outputs
Argon2 has the following input parameters: Argon2 has the following input parameters:
o Message string P, which is a password for password hashing * Message string P, which is a password for password hashing
applications. MUST have length not greater than 2^(32) - 1 bytes. applications. It MUST have a length not greater than 2^(32)-1
bytes.
o Nonce S, which is a salt for password hashing applications. MUST * Nonce S, which is a salt for password hashing applications. It
have length not greater than 2^(32)-1 bytes. 16 bytes is MUST have a length not greater than 2^(32)-1 bytes. 16 bytes is
RECOMMENDED for password hashing. Salt SHOULD be unique for each RECOMMENDED for password hashing. The salt SHOULD be unique for
password. each password.
o Degree of parallelism p determines how many independent (but * Degree of parallelism p determines how many independent (but
synchronizing) computational chains (lanes) can be run. It MUST synchronizing) computational chains (lanes) can be run. It MUST
be an integer value from 1 to 2^(24)-1. be an integer value from 1 to 2^(24)-1.
o Tag length T MUST be an integer number of bytes from 4 to 2^(32)- * Tag length T MUST be an integer number of bytes from 4 to 2^(32)-
1. 1.
o Memory size m MUST be an integer number of kibibytes from 8*p to * 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 2^(32)-1. The actual number of blocks is m', which is m rounded
down to the nearest multiple of 4*p. down to the nearest multiple of 4*p.
o Number of passes t (used to tune the running time independently of * 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. the memory size) MUST be an integer number from 1 to 2^(32)-1.
o Version number v MUST be one byte 0x13. * Version number v MUST be one byte 0x13.
o Secret value K is OPTIONAL. If used, it MUST have length not * Secret value K is OPTIONAL. If used, it MUST have a length not
greater than 2^(32)-1 bytes. greater than 2^(32)-1 bytes.
o Associated data X is OPTIONAL. If used, it MUST have length not * Associated data X is OPTIONAL. If used, it MUST have a length not
greater than 2^(32)-1 bytes. greater than 2^(32)-1 bytes.
o Type y of Argon2: MUST be 0 for Argon2d, 1 for Argon2i, 2 for * Type y MUST be 0 for Argon2d, 1 for Argon2i, or 2 for Argon2id.
Argon2id.
The Argon2 output, or "tag" is a string T bytes long. The Argon2 output, or "tag", is a string T bytes long.
3.2. Argon2 Operation 3.2. Argon2 Operation
Argon2 uses an internal compression function G with two 1024-byte Argon2 uses an internal compression function G with two 1024-byte
inputs and a 1024-byte output, and an internal hash function H^x() inputs, a 1024-byte output, and an internal hash function H^x(), with
with x being its output length in bytes. Here H^x() applied to x being its output length in bytes. Here, H^x() applied to string A
string A is the BLAKE2b (Section 3.3) [BLAKE2] function, which takes 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 (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 128 bytes and ll is the length of d in bytes. The compression
function G is based on its internal permutation. A variable-length function G is based on its internal permutation. A variable-length
hash function H' built upon H is also used. G is described in hash function H' built upon H is also used. G is described in
Section 3.5 and H' is described in Section 3.3. Section 3.5, and H' is described in Section 3.3.
The Argon2 operation is as follows. The Argon2 operation is as follows.
1. Establish H_0 as the 64-byte value as shown below. If K, X, or S 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. has zero length, it is just absent, but its length field remains.
H_0 = H^(64)(LE32(p) || LE32(T) || LE32(m) || LE32(t) || H_0 = H^(64)(LE32(p) || LE32(T) || LE32(m) || LE32(t) ||
LE32(v) || LE32(y) || LE32(length(P)) || P || LE32(v) || LE32(y) || LE32(length(P)) || P ||
LE32(length(S)) || S || LE32(length(K)) || K || LE32(length(S)) || S || LE32(length(K)) || K ||
LE32(length(X)) || X) LE32(length(X)) || X)
H_0 generation Figure 1: H_0 Generation
2. Allocate the memory as m' 1024-byte blocks where m' is derived 2. Allocate the memory as m' 1024-byte blocks, where m' is derived
as: as:
m' = 4 * p * floor (m / 4p) m' = 4 * p * floor (m / 4p)
Memory allocation Figure 2: Memory Allocation
For p lanes, the memory is organized in a matrix B[i][j] of For p lanes, the memory is organized in a matrix B[i][j] of
blocks with p rows (lanes) and q = m' / p columns. 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 3. Compute B[i][0] for all i ranging from (and including) 0 to (not
including) p. including) p.
B[i][0] = H'^(1024)(H_0 || LE32(0) || LE32(i)) B[i][0] = H'^(1024)(H_0 || LE32(0) || LE32(i))
Lane starting blocks Figure 3: Lane Starting Blocks
4. Compute B[i][1] for all i ranging from (and including) 0 to (not 4. Compute B[i][1] for all i ranging from (and including) 0 to (not
including) p. including) p.
B[i][1] = H'^(1024)(H_0 || LE32(1) || LE32(i)) B[i][1] = H'^(1024)(H_0 || LE32(1) || LE32(i))
Second lane blocks Figure 4: Second Lane Blocks
5. Compute B[i][j] for all i ranging from (and including) 0 to (not 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 including) p and for all j ranging from (and including) 2 to (not
(not including) q. The computation MUST proceed slicewise including) q. The computation MUST proceed slicewise
(Section 3.4): first blocks from slice 0 are computed for all (Section 3.4): first, blocks from slice 0 are computed for all
lanes (in an arbitrary order of lanes), then blocks from slice 1 lanes (in an arbitrary order of lanes), then blocks from slice 1
are computed etc. The block indices l and z are determined for are computed, etc. The block indices l and z are determined for
each i, j differently for Argon2d, Argon2i, and Argon2id. each i, j differently for Argon2d, Argon2i, and Argon2id.
B[i][j] = G(B[i][j-1], B[l][z]) B[i][j] = G(B[i][j-1], B[l][z])
Further block generation Figure 5: Further Block Generation
6. If the number of passes t is larger than 1, we repeat the steps. 6. If the number of passes t is larger than 1, we repeat step 5. We
However blocks are computed differently as the old value is XORed compute B[i][0] and B[i][j] for all i raging from (and including)
with the new one: 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][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]. B[i][j] = G(B[i][j-1], B[l][z]) XOR B[i][j].
Further passes Figure 6: Further Passes
7. After t steps have been iterated, the final block C is computed 7. After t steps have been iterated, the final block C is computed
as the XOR of the last column: as the XOR of the last column:
C = B[0][q-1] XOR B[1][q-1] XOR ... XOR B[p-1][q-1] C = B[0][q-1] XOR B[1][q-1] XOR ... XOR B[p-1][q-1]
Final block Figure 7: Final Block
8. The output tag is computed as H'^T(C). 8. The output tag is computed as H'^T(C).
3.3. Variable-length hash function H' 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 Let V_i be a 64-byte block and W_i be its first 32 bytes. Then we
define: define function H' as follows:
if T <= 64 if T <= 64
H'^T(A) = H^T(LE32(T)||A) H'^T(A) = H^T(LE32(T)||A)
else else
r = ceil(T/32)-2 r = ceil(T/32)-2
V_1 = H^(64)(LE32(T)||A) V_1 = H^(64)(LE32(T)||A)
V_2 = H^(64)(V_1) V_2 = H^(64)(V_1)
... ...
V_r = H^(64)(V_{r-1}) V_r = H^(64)(V_{r-1})
V_{r+1} = H^(T-32*r)(V_{r}) V_{r+1} = H^(T-32*r)(V_{r})
H'^T(X) = W_1 || W_2 || ... || W_r || V_{r+1} H'^T(X) = W_1 || W_2 || ... || W_r || V_{r+1}
Function H' for tag and initial block computations Figure 8: Function H' for Tag and Initial Block Computations
3.4. Indexing 3.4. Indexing
To enable parallel block computation, we further partition the memory To enable parallel block computation, we further partition the memory
matrix into SL = 4 vertical slices. The intersection of a slice and matrix into SL = 4 vertical slices. The intersection of a slice and
a lane is called a segment, which has length q/SL. Segments of the a lane is called a segment, which has a length of q/SL. Segments of
same slice can be computed in parallel and do not reference blocks the same slice can be computed in parallel and do not reference
from each other. All other blocks can be referenced. blocks from each other. All other blocks can be referenced.
slice 0 slice 1 slice 2 slice 3 slice 0 slice 1 slice 2 slice 3
___/\___ ___/\___ ___/\___ ___/\___ ___/\___ ___/\___ ___/\___ ___/\___
/ \ / \ / \ / \ / \ / \ / \ / \
+----------+----------+----------+----------+ +----------+----------+----------+----------+
| | | | | > lane 0 | | | | | > lane 0
+----------+----------+----------+----------+ +----------+----------+----------+----------+
| | | | | > lane 1 | | | | | > lane 1
+----------+----------+----------+----------+ +----------+----------+----------+----------+
| | | | | > lane 2 | | | | | > lane 2
+----------+----------+----------+----------+ +----------+----------+----------+----------+
| ... ... ... | ... | ... ... ... | ...
+----------+----------+----------+----------+ +----------+----------+----------+----------+
| | | | | > lane p - 1 | | | | | > lane p - 1
+----------+----------+----------+----------+ +----------+----------+----------+----------+
Single-pass Argon2 with p lanes and 4 slices 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. Computing the 32-Bit Values J_1 and J_2
3.4.1.1. Argon2d 3.4.1.1. Argon2d
J_1 is given by the first 32 bits of block B[i][j-1], while J_2 is 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]: given by the next 32 bits of block B[i][j-1]:
J_1 = int32(extract(B[i][j-1], 0)) J_1 = int32(extract(B[i][j-1], 0))
J_2 = int32(extract(B[i][j-1], 1)) J_2 = int32(extract(B[i][j-1], 1))
Deriving J1,J2 in Argon2d Figure 10: Deriving J1,J2 in Argon2d
3.4.1.2. Argon2i 3.4.1.2. Argon2i
For each segment we do the following. First we compute the value Z For each segment, we do the following. First, we compute the value Z
as as:
Z= ( LE64(r) || LE64(l) || LE64(sl) || LE64(m') || Z= ( LE64(r) || LE64(l) || LE64(sl) || LE64(m') ||
LE64(t) || LE64(y) ), where LE64(t) || LE64(y) )
r -- the pass number Figure 11: Input to Compute J1,J2 in Argon2i
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)
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) )),
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 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 as X1||X2 and converted to J_1=int32(X1) and J_2=int32(X2).
values r, l, sl, m', t, y, i are represented as 8 bytes in little-
endian. The values r, l, sl, m', t, y, and i are represented as 8 bytes in
little endian.
3.4.1.3. Argon2id 3.4.1.3. Argon2id
If the pass number is 0 and the slice number is 0 or 1, then compute 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. 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] 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 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 block will be taken. For the first pass (r=0) and the first slice
(sl=0) the block is taken from the current lane. (sl=0), the block is taken from the current lane.
The set W contains the indices that are referenced according to the The set W contains the indices that are referenced according to the
following rules: following rules:
1. If l is the current lane, then W includes the indices of all 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 blocks in the last SL - 1 = 3 segments computed and finished, as
well as the blocks computed in the current segment in the current well as the blocks computed in the current segment in the current
pass excluding B[i][j-1]. pass excluding B[i][j-1].
2. If l is not the current lane, then W includes the indices of all 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 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 lane l. If B[i][j] is the first block of a segment, then the
very last index from W is excluded. very last index from W is excluded.
Then take a block from W with a non-uniform distribution over Then take a block from W with a nonuniform distribution over [0, |W|)
[0, |W|) using the mapping using the following mapping:
J_1 -> |W|(1 - J_1^2 / 2^(64)) J_1 -> |W|(1 - J_1^2 / 2^(64))
Computing J1 Figure 12: Computing J1
To avoid floating point computation, the following approximation is To avoid floating point computation, the following approximation is
used: used:
x = J_1^2 / 2^(32) x = J_1^2 / 2^(32)
y = (|W| * x) / 2^(32) y = (|W| * x) / 2^(32)
zz = |W| - 1 - y zz = |W| - 1 - y
Computing J1, part 2 Figure 13: Computing J1, Part 2
Then take the zz-th index from W, it will be the z value for the Then take the zz-th index from W; it will be the z value for the
reference block index [l][z]. reference block index [l][z].
3.5. Compression function G 3.5. Compression Function G
The compression function G is built upon the BLAKE2b-based The compression function G is built upon the BLAKE2b-based
transformation P. P operates on the 128-byte input, which can be transformation P. P operates on the 128-byte input, which can be
viewed as 8 16-byte registers: viewed as eight 16-byte registers:
P(A_0, A_1, ... ,A_7) = (B_0, B_1, ... ,B_7) P(A_0, A_1, ... ,A_7) = (B_0, B_1, ... ,B_7)
Blake round function P Figure 14: Blake Round Function P
The compression function G(X, Y) operates on two 1024-byte blocks X 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 a 8x8 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 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: 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_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_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) (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_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_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) ( Z_7, Z_15, Z 23, ... , Z_63) <- P( Q_7, Q_15, Q_23, ... , Q_63)
Core of compression function G Figure 15: Core of Compression Function G
Finally, G outputs Z XOR R: Finally, G outputs Z XOR R:
G: (X, Y) -> R -> Q -> Z -> Z XOR R G: (X, Y) -> R -> Q -> Z -> Z XOR R
+---+ +---+ +---+ +---+
| X | | Y | | X | | Y |
+---+ +---+ +---+ +---+
| | | |
---->XOR<---- ---->XOR<----
--------| --------|
| \ / | \ /
| +---+ | +---+
| | R | | | R |
| +---+ | +---+
skipping to change at page 11, line 36 skipping to change at line 499
| \ / | \ /
| +---+ | +---+
| | Z | | | Z |
| +---+ | +---+
| | | |
| \ / | \ /
------>XOR ------>XOR
| |
\ / \ /
Argon2 compression function G. Figure 16: Argon2 Compression Function G
3.6. Permutation P 3.6. Permutation P
Permutation P is based on the round function of BLAKE2b. The 8 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 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}): 64-bit words, where S_i = (v_{2*i+1} || v_{2*i}):
v_0 v_1 v_2 v_3 v_0 v_1 v_2 v_3
v_4 v_5 v_6 v_7 v_4 v_5 v_6 v_7
v_8 v_9 v_10 v_11 v_8 v_9 v_10 v_11
v_12 v_13 v_14 v_15 v_12 v_13 v_14 v_15
Matrix element labeling Figure 17: Matrix Element Labeling
It works as follows: It works as follows:
GB(v_0, v_4, v_8, v_12) GB(v_0, v_4, v_8, v_12)
GB(v_1, v_5, v_9, v_13) GB(v_1, v_5, v_9, v_13)
GB(v_2, v_6, v_10, v_14) GB(v_2, v_6, v_10, v_14)
GB(v_3, v_7, v_11, v_15) GB(v_3, v_7, v_11, v_15)
GB(v_0, v_5, v_10, v_15) GB(v_0, v_5, v_10, v_15)
GB(v_1, v_6, v_11, v_12) GB(v_1, v_6, v_11, v_12)
GB(v_2, v_7, v_8, v_13) GB(v_2, v_7, v_8, v_13)
GB(v_3, v_4, v_9, v_14) GB(v_3, v_4, v_9, v_14)
Feeding matrix elements to GB Figure 18: Feeding Matrix Elements to GB
GB(a, b, c, d) is defined as follows: GB(a, b, c, d) is defined as follows:
a = (a + b + 2 * trunc(a) * trunc(b)) mod 2^(64) a = (a + b + 2 * trunc(a) * trunc(b)) mod 2^(64)
d = (d XOR a) >>> 32 d = (d XOR a) >>> 32
c = (c + d + 2 * trunc(c) * trunc(d)) mod 2^(64) c = (c + d + 2 * trunc(c) * trunc(d)) mod 2^(64)
b = (b XOR c) >>> 24 b = (b XOR c) >>> 24
a = (a + b + 2 * trunc(a) * trunc(b)) mod 2^(64) a = (a + b + 2 * trunc(a) * trunc(b)) mod 2^(64)
d = (d XOR a) >>> 16 d = (d XOR a) >>> 16
c = (c + d + 2 * trunc(c) * trunc(d)) mod 2^(64) c = (c + d + 2 * trunc(c) * trunc(d)) mod 2^(64)
b = (b XOR c) >>> 63 b = (b XOR c) >>> 63
Details of GB Figure 19: Details of GB
The modular additions in GB are combined with 64-bit multiplications. The modular additions in GB are combined with 64-bit multiplications.
Multiplications are the only difference to the original BLAKE2b Multiplications are the only difference from the original BLAKE2b
design. This choice is done to increase the circuit depth and thus design. This choice is done to increase the circuit depth and thus
the running time of ASIC implementations, while having roughly the the running time of ASIC implementations, while having roughly the
same running time on CPUs thanks to parallelism and pipelining. same running time on CPUs thanks to parallelism and pipelining.
4. Parameter Choice 4. Parameter Choice
Argon2d is optimized for settings where the adversary does not get Argon2d is optimized for settings where the adversary does not get
regular access to system memory or CPU, i.e. he can not run side- regular access to system memory or CPU, i.e., they cannot run side-
channel attacks based on the timing information, nor he can recover channel attacks based on the timing information, nor can they recover
the password much faster using garbage collection. These settings the password much faster using garbage collection. These settings
are more typical for backend servers and cryptocurrency minings. For are more typical for backend servers and cryptocurrency minings. For
practice we suggest the following settings: practice, we suggest the following settings:
o Cryptocurrency mining, that takes 0.1 seconds on a 2 Ghz CPU using * Cryptocurrency mining, which takes 0.1 seconds on a 2 GHz CPU
1 core -- Argon2d with 2 lanes and 250 MB of RAM. using 1 core -- Argon2d with 2 lanes and 250 MB of RAM.
Argon2id is optimized for more realistic settings, where the Argon2id is optimized for more realistic settings, where the
adversary possibly can access the same machine, use its CPU or mount adversary can possibly access the same machine, use its CPU, or mount
cold-boot attacks. We suggest the following settings: cold-boot attacks. We suggest the following settings:
o Backend server authentication, that takes 0.5 seconds on a 2 GHz * 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. CPU using 4 cores -- Argon2id with 8 lanes and 4 GiB of RAM.
o Key derivation for hard-drive encryption, that takes 3 seconds on * 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 a 2 GHz CPU using 2 cores -- Argon2id with 4 lanes and 6 GiB of
RAM. RAM.
o Frontend server authentication, that takes 0.5 seconds on a 2 GHz * 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. CPU using 2 cores -- Argon2id with 4 lanes and 1 GiB of RAM.
We recommend the following procedure to select the type and the We recommend the following procedure to select the type and the
parameters for practical use of Argon2. parameters for practical use of Argon2.
1. If you are OK with a uniformly safe option, but not tailored to 1. If a uniformly safe option that is not tailored to your
your application or hardware, select Argon2id with t=1 application or hardware is acceptable, select Argon2id with t=1
iteration, p=4 lanes and m=2^(21) (2 GiB of RAM), 128-bit salt, 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. 256-bit tag size. This is the FIRST RECOMMENDED option.
2. If much less memory is available, a uniformly safe option is 2. If much less memory is available, a uniformly safe option is
Argon2id with t=3 iterations, p=4 lanes and m=2^(16) (64 MiB of Argon2id with t=3 iterations, p=4 lanes, m=2^(16) (64 MiB of
RAM), 128-bit salt, 256-bit tag size. This is the SECOND RAM), 128-bit salt, and 256-bit tag size. This is the SECOND
RECOMMENDED option. RECOMMENDED option.
3. Otherwise, start with selecting the type y. If you do not know 3. Otherwise, start with selecting the type y. If you do not know
the difference between them or you consider side-channel attacks the difference between the types or you consider side-channel
as viable threat, choose Argon2id. attacks to be a viable threat, choose Argon2id.
4. Select p=4 lanes. 4. Select p=4 lanes.
5. Figure out the maximum amount of memory that each call can 5. Figure out the maximum amount of memory that each call can
afford and translate it to the parameter m. afford and translate it to the parameter m.
6. Figure out the maximum amount of time (in seconds) that each 6. Figure out the maximum amount of time (in seconds) that each
call can afford. call can afford.
7. Select the salt length. 128 bits is sufficient for all 7. Select the salt length. A length of 128 bits is sufficient for
applications, but can be reduced to 64 bits in the case of space all applications but can be reduced to 64 bits in the case of
constraints. space constraints.
8. Select the tag length. 128 bits is sufficient for most 8. Select the tag length. A length of 128 bits is sufficient for
applications, including key derivation. If longer keys are most applications, including key derivation. If longer keys are
needed, select longer tags. needed, select longer tags.
9. If side-channel attacks are a viable threat, or if you're 9. If side-channel attacks are a viable threat or if you're
uncertain, enable the memory wiping option in the library call. uncertain, enable the memory-wiping option in the library call.
10. Run the scheme of type y, memory m and p lanes, using different 10. Run the scheme of type y, memory m, and p lanes using a
number of passes t. Figure out the maximum t such that the different number of passes t. Figure out the maximum t such
running time does not exceed the affordable time. If it exceeds that the running time does not exceed the affordable time. If
even for t = 1, reduce m accordingly. it even exceeds for t = 1, reduce m accordingly.
11. Use Argon2 with determined values m, p, and t. 11. Use Argon2 with determined values m, p, and t.
5. Test Vectors 5. Test Vectors
This section contains test vectors for Argon2. This section contains test vectors for Argon2.
5.1. Argon2d Test Vectors 5.1. Argon2d Test Vectors
We provide test vectors with complete outputs (tags). For the We provide test vectors with complete outputs (tags). For the
convenience of developers, we also provide some interim variables, convenience of developers, we also provide some interim variables --
concretely, first and last memory blocks of each pass. concretely, the first and last memory blocks of each pass.
======================================= =======================================
Argon2d version number 19 Argon2d version number 19
======================================= =======================================
Memory: 32 KiB Memory: 32 KiB
Passes: 3 Passes: 3
Parallelism: 4 lanes Parallelism: 4 lanes
Tag length: 32 bytes Tag length: 32 bytes
Password[32]: 01 01 01 01 01 01 01 01 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
skipping to change at page 18, line 7 skipping to change at line 803
... ...
Block 0031 [124]: d723359b485f509b Block 0031 [124]: d723359b485f509b
Block 0031 [125]: cb78824f42375111 Block 0031 [125]: cb78824f42375111
Block 0031 [126]: 35bc8cc6e83b1875 Block 0031 [126]: 35bc8cc6e83b1875
Block 0031 [127]: 0b012846a40f346a Block 0031 [127]: 0b012846a40f346a
Tag: 0d 64 0d f5 8d 78 76 6c 08 c0 37 a3 4a 8b 53 c9 d0 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 1e f0 45 2d 75 b6 5e b5 25 20 e9 6b 01 e6 59
6. IANA Considerations 6. IANA Considerations
None. This document has no IANA actions.
7. Security Considerations 7. Security Considerations
7.1. Security as hash function and KDF 7.1. Security as a Hash Function and KDF
The collision and preimage resistance levels of Argon2 are equivalent The collision and preimage resistance levels of Argon2 are equivalent
to those of the underlying BLAKE2b hash function. To produce a to those of the underlying BLAKE2b hash function. To produce a
collision, 2^(256) inputs are needed. To find a preimage, 2^(512) collision, 2^(256) inputs are needed. To find a preimage, 2^(512)
inputs must be tried. inputs must be tried.
The KDF security is determined by the key length and the size of the 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 internal state of hash function H'. To distinguish the output of the
keyed Argon2 from random, minimum of (2^(128),2^length(K)) calls to keyed Argon2 from random, a minimum of (2^(128),2^length(K)) calls to
BLAKE2b are needed. BLAKE2b are needed.
7.2. Security against time-space tradeoff attacks 7.2. Security against Time-Space Trade-off Attacks
Time-space tradeoffs allow computing a memory-hard function storing Time-space trade-offs allow computing a memory-hard function storing
fewer memory blocks at the cost of more calls to the internal fewer memory blocks at the cost of more calls to the internal
comression function. The advantage of tradeoff attacks is measured compression function. The advantage of trade-off attacks is measured
in the reduction factor to the time-area product, where memory and in the reduction factor to the time-area product, where memory and
extra compression function cores contribute to the area, and time is extra compression function cores contribute to the area and time is
increased to accomodate the recomputation of missed blocks. A high increased to accommodate the recomputation of missed blocks. A high
reduction factor may potentially speed up preimage search. reduction factor may potentially speed up the preimage search.
The best known attacks on the 1-pass and 2-pass Argon2i is the low- 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 storage attack described in [CBS16], which reduces the time-area
product (using the peak memory value) by the factor of 5. The best product (using the peak memory value) by the factor of 5. The best
attack on 3-pass and more Argon2i is [AB16] with reduction factor attack on Argon2i with 3 passes or more is described in [AB16], with
being a function of memory size and the number of passes. For 1 the reduction factor being a function of memory size and the number
gibibyte of memory: 3 for 3 passes, 2.5 for 4 passes, 2 for 6 passes. of passes (e.g., for 1 gibibyte of memory, a reduction factor of 3
The reduction factor grows by about 0.5 with every doubling the for 3 passes, 2.5 for 4 passes, 2 for 6 passes). The reduction
memory size. To completely prevent time-space tradeoffs from [AB16], factor grows by about 0.5 with every doubling of the memory size. To
the number of passes MUST exceed binary logarithm of memory minus 26. completely prevent time-space trade-offs from [AB16], the number of
Asymptotically, the best attack on 1-pass Argon2i is given in [BZ17] passes MUST exceed the binary logarithm of memory minus 26.
with maximal advantage of the adversary upper bounded by O(m^(0.233)) Asymptotically, the best attack on 1-pass Argon2i is given in [BZ17],
where m is the number of blocks. This attack is also asymptotically with maximal advantage of the adversary upper bounded by
optimal as [BZ17] also prove the upper bound on any attack of O(m^(0.233)), where m is the number of blocks. This attack is also
O(m^(0.25)). asymptotically optimal as [BZ17] also proves the upper bound on any
attack is O(m^(0.25)).
The best tradeoff attack on t-pass Argon2d is the ranking tradeoff 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. 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 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 attack on the 1-pass Argon2i with the best attack on a multi-pass
Argon2d. Thus the best tradeoff attack on 1-pass Argon2id is the 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 combined low-storage attack (for the first half of the memory) and
the ranking attack (for the second half), which bring together the the ranking attack (for the second half), which generate the factor
factor of about 2.1. The best tradeoff attack on t-pass Argon2id is of about 2.1. The best trade-off attack on t-pass Argon2id is the
the ranking tradeoff attack, which reduces the time-area product by ranking trade-off attack, which reduces the time-area product by the
the factor of 1.33. factor of 1.33.
7.3. Security for time-bounded defenders 7.3. Security for Time-Bounded Defenders
A bottleneck in a system employing the password-hashing function is A bottleneck in a system employing the password hashing function is
often the function latency rather than memory costs. A rational often the function latency rather than memory costs. A rational
defender would then maximize the bruteforce costs for the attacker defender would then maximize the brute-force costs for the attacker
equipped with a list of hashes, salts, and timing information, for equipped with a list of hashes, salts, and timing information for
fixed computing time on the defender's machine. The attack cost fixed computing time on the defender's machine. The attack cost
estimates from [AB16] imply that for Argon2i, 3 passes is almost estimates from [AB16] imply that for Argon2i, 3 passes is almost
optimal for the most of reasonable memory sizes, and that for Argon2d optimal for most reasonable memory sizes; for Argon2d and Argon2id, 1
and Argon2id, 1 pass maximizes the attack costs for the constant pass maximizes the attack costs for the constant defender time.
defender time.
7.4. Recommendations 7.4. Recommendations
The Argon2id variant with t=1 and 2GiB memory is FIRST RECOMMENDED The Argon2id variant with t=1 and 2 GiB memory is the FIRST
option and is suggested as a default setting for all environments. RECOMMENDED option and is suggested as a default setting for all
This setting is secure against side-channel attacks and maximizes environments. This setting is secure against side-channel attacks
adversarial costs on dedicated bruteforce hardware. The Argon2id and maximizes adversarial costs on dedicated brute-force hardware.
variant with t=3 and 64 MiB memory is SECOND RECOMMENDED option and The Argon2id variant with t=3 and 64 MiB memory is the SECOND
is suggested as a default setting for memory-constrained RECOMMENDED option and is suggested as a default setting for memory-
environments. constrained environments.
8. Acknowledgements
We thank greatly the following authors who helped a lot 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, Gwynne Raskind.
9. References 8. References
9.1. Normative References 8.1. Normative References
[BLAKE2] Saarinen, M-J., Ed. and J-P. Aumasson, "The BLAKE2 [BLAKE2] Saarinen, M-J., Ed. and J-P. Aumasson, "The BLAKE2
Cryptographic Hash and Message Authentication Code (MAC)", Cryptographic Hash and Message Authentication Code (MAC)",
RFC 7693, November 2015, RFC 7693, DOI 10.17487/RFC7693, November 2015,
<https://www.rfc-editor.org/info/rfc7693>. <https://www.rfc-editor.org/info/rfc7693>.
[RFC2119] Bradner, S., "Key words for use in RFCs to Indicate [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate
Requirement Levels", RFC 2119, March 1997, Requirement Levels", BCP 14, RFC 2119,
<http://www.rfc-editor.org/info/rfc2119>. DOI 10.17487/RFC2119, March 1997,
<https://www.rfc-editor.org/info/rfc2119>.
9.2. Informative References [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 [AB15] Biryukov, A. and D. Khovratovich, "Tradeoff Cryptanalysis
of Memory-Hard Functions", Asiacrypt 2015, December 2015, of Memory-Hard Functions", ASIACRYPT 2015,
DOI 10.1007/978-3-662-48800-3_26, December 2015,
<https://eprint.iacr.org/2015/227.pdf>. <https://eprint.iacr.org/2015/227.pdf>.
[AB16] Alwen, J. and J. Blocki, "Efficiently Computing Data- [AB16] Alwen, J. and J. Blocki, "Efficiently Computing Data-
Independent Memory-Hard Functions", Crypto 2016, December Independent Memory-Hard Functions", CRYPTO 2016,
2015, <https://eprint.iacr.org/2016/115.pdf>. 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 [ARGON2] Biryukov, A., Dinu, D., and D. Khovratovich, "Argon2: the
memory-hard function for password hashing and other memory-hard function for password hashing and other
applications", WWW www.cryptolux.org, October 2015, applications", March 2017,
<https://www.cryptolux.org/images/0/0d/Argon2.pdf>. <https://www.cryptolux.org/images/0/0d/Argon2.pdf>.
[ARGON2ESP] [ARGON2ESP]
Biryukov, A., Dinu, D., and D. Khovratovich, "Argon2: New Biryukov, A., Dinu, D., and D. Khovratovich, "Argon2: New
Generation of Memory-Hard Functions for Password Hashing Generation of Memory-Hard Functions for Password Hashing
and Other Applications", Euro SnP 2016, March 2016, and Other Applications", Euro SnP 2016,
DOI 10.1109/EuroSP.2016.31, March 2016,
<https://www.cryptolux.org/images/d/d0/Argon2ESP.pdf>. <https://www.cryptolux.org/images/d/d0/Argon2ESP.pdf>.
[BZ17] Blocki, J. and S. Zhou, "On the Depth-Robustness and [BZ17] Blocki, J. and S. Zhou, "On the Depth-Robustness and
Cumulative Pebbling Cost of Argon2i", TCC 2017, May 2017, 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>. <https://eprint.iacr.org/2017/442.pdf>.
[CBS16] Corrigan-Gibbs, H., Boneh, D., and S. Schechter, "Balloon [CBS16] Boneh, D., Corrigan-Gibbs, H., and S. Schechter, "Balloon
Hashing: Provably Space-Hard Hash Functions with Data- Hashing: A Memory-Hard Function Providing Provable
Independent Access Patterns", Asiacrypt 2016, January Protection Against Sequential Attacks", ASIACRYPT 2016,
2016, <https://eprint.iacr.org/2016/027.pdf>. 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 [HARD] Alwen, J. and V. Serbinenko, "High Parallel Complexity
Graphs and Memory-Hard Functions", STOC 2015, 2014, Graphs and Memory-Hard Functions", STOC '15,
DOI 10.1145/2746539.2746622, June 2015,
<https://eprint.iacr.org/2014/238.pdf>. <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 Authors' Addresses
Alex Biryukov Alex Biryukov
University of Luxembourg University of Luxembourg
Email: alex.biryukov@uni.lu Email: alex.biryukov@uni.lu
Daniel Dinu Daniel Dinu
University of Luxembourg University of Luxembourg
Email: daniel.dinu@intel.com Email: daniel.dinu@intel.com
Dmitry Khovratovich Dmitry Khovratovich
ABDK Consulting ABDK Consulting
Email: khovratovich@gmail.com Email: khovratovich@gmail.com
 End of changes. 151 change blocks. 
324 lines changed or deleted 355 lines changed or added

This html diff was produced by rfcdiff 1.48. The latest version is available from http://tools.ietf.org/tools/rfcdiff/