rfc9106xml2.original.xml | rfc9106.xml | |||
---|---|---|---|---|
<?xml version="1.0"?> | <?xml version="1.0" encoding="UTF-8"?> | |||
<!DOCTYPE rfc SYSTEM "rfc2629.dtd" [ | ||||
<!ENTITY RFC4086 PUBLIC '' 'http://xml2rfc.ietf.org/public/rfc/bibxml/reference. | ||||
RFC.4086.xml'> | ||||
<!ENTITY RFC4634 PUBLIC '' 'http://xml2rfc.ietf.org/public/rfc/bibxml/reference. | ||||
RFC.4634.xml'> | ||||
<!ENTITY BLAKE2 PUBLIC '' 'http://xml2rfc.ietf.org/public/rfc/bibxml/reference.R | ||||
FC.7693.xml'> | ||||
]> | ||||
<?rfc compact="no"?> | <!DOCTYPE rfc SYSTEM "rfc2629-xhtml.ent"> | |||
<?rfc toc="yes"?> | ||||
<?rfc symrefs="yes"?> | ||||
<rfc category="info" ipr="trust200902" | <rfc xmlns:xi="http://www.w3.org/2001/XInclude" ipr="trust200902" docName="draft | |||
docName="draft-irtf-cfrg-argon2-13"> | -irtf-cfrg-argon2-13" number="9106" obsoletes="" updates="" submissionType="IRTF | |||
" category="info" consensus="true" xml:lang="en" tocInclude="true" sortRefs="tru | ||||
e" symRefs="true" version="3"> | ||||
<front> | <front> | |||
<title abbrev="Argon2"> | <title abbrev="Argon2"> | |||
The memory-hard Argon2 password hash and proof-of-work function | Argon2 Memory-Hard Function for Password Hashing and Proof-of-Work Applica tions | |||
</title> | </title> | |||
<seriesInfo name="RFC" value="9106"/> | ||||
<author initials="A." surname="Biryukov" fullname="Alex Biryukov"> | <author initials="A." surname="Biryukov" fullname="Alex Biryukov"> | |||
<organization>University of Luxembourg</organization> | <organization>University of Luxembourg</organization> | |||
<address> | <address> | |||
<email>alex.biryukov@uni.lu</email> | <email>alex.biryukov@uni.lu</email> | |||
</address> | </address> | |||
</author> | </author> | |||
<author initials="D." surname="Dinu" fullname="Daniel Dinu"> | <author initials="D." surname="Dinu" fullname="Daniel Dinu"> | |||
<organization>University of Luxembourg</organization> | <organization>University of Luxembourg</organization> | |||
<address> | <address> | |||
<email>daniel.dinu@intel.com</email> | <email>daniel.dinu@intel.com</email> | |||
</address> | </address> | |||
</author> | </author> | |||
<author initials="D." surname="Khovratovich" fullname="Dmitry Khovratovich"> | ||||
<author initials="D." surname="Khovratovich" | ||||
fullname="Dmitry Khovratovich"> | ||||
<organization>ABDK Consulting</organization> | <organization>ABDK Consulting</organization> | |||
<address> | <address> | |||
<email>khovratovich@gmail.com</email> | <email>khovratovich@gmail.com</email> | |||
</address> | </address> | |||
</author> | </author> | |||
<author initials="S." surname="Josefsson" fullname="Simon Josefsson"> | ||||
<author initials="S." surname="Josefsson" | ||||
fullname="Simon Josefsson"> | ||||
<organization>SJD AB</organization> | <organization>SJD AB</organization> | |||
<address> | <address> | |||
<email>simon@josefsson.org</email> | <email>simon@josefsson.org</email> | |||
<uri>http://josefsson.org/</uri> | <uri>http://josefsson.org/</uri> | |||
</address> | </address> | |||
</author> | </author> | |||
<date month="September" year="2021"/> | ||||
<workgroup>Crypto Forum</workgroup> | ||||
<date day="11" month="March" year="2021"/> | <keyword>Argon2d</keyword> | |||
<workgroup>CFRG</workgroup> | <keyword>Argon2i</keyword> | |||
<keyword>Argon2id</keyword> | ||||
<keyword>KDF</keyword> | ||||
<keyword>Cryptocurrency</keyword> | ||||
<keyword>Time-Space Trade-Off Attacks</keyword> | ||||
<keyword>Security</keyword> | ||||
<abstract> | <abstract> | |||
<t>This document describes the Argon2 memory-hard function for | <t>This document describes the Argon2 memory-hard function for | |||
password hashing and proof-of-work applications. We provide an | password hashing and proof-of-work applications. We provide an | |||
implementer-oriented description with | implementer-oriented description with | |||
test vectors. The purpose is to simplify adoption of Argon2 for | test vectors. The purpose is to simplify adoption of Argon2 for | |||
Internet protocols. This document is a product of the Crypto Forum Resear ch Group (CFRG) | Internet protocols. This document is a product of the Crypto Forum Resear ch Group (CFRG) | |||
in the IRTF.</t> | in the IRTF.</t> | |||
</abstract> | </abstract> | |||
</front> | </front> | |||
<middle> | <middle> | |||
<section anchor="intro" numbered="true" toc="default"> | ||||
<section anchor="intro" | <name>Introduction</name> | |||
title="Introduction"> | <t>This document describes the <xref target="ARGON2ESP" format="default">A | |||
rgon2</xref> memory-hard function for | ||||
<t>This document describes the <xref | ||||
target="ARGON2ESP">Argon2</xref> memory-hard function for | ||||
password hashing and proof-of-work applications. We provide an | password hashing and proof-of-work applications. We provide an | |||
implementer oriented description with | implementer-oriented description with | |||
test vectors. The purpose is to simplify adoption of Argon2 for | test vectors. The purpose is to simplify adoption of Argon2 for | |||
Internet protocols. This document corresponds to version 1.3 of the Argon2 hash | Internet protocols. This document corresponds to version 1.3 of the Argon2 hash | |||
function.</t> | function.</t> | |||
<t>Argon2 is a <xref target="HARD" format="default">memory-hard function</ | ||||
<t>Argon2 is a traditional | xref>. It is a streamlined design. | |||
<xref | It aims at the highest memory-filling rate and effective use of | |||
target="HARD">memory-hard function</xref>. 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 | multiple computing units, while still providing defense against | |||
tradeoff attacks. Argon2 is optimized for the x86 architecture | trade-off attacks. Argon2 is optimized for the x86 architecture | |||
and exploits the cache and memory organization of the recent | and exploits the cache and memory organization of the recent | |||
Intel and AMD processors. Argon2 has one primary variant: Argon2id and tw o supplementary variants: Argon2d and | Intel and AMD processors. Argon2 has one primary variant, Argon2id, and t wo supplementary variants, Argon2d and | |||
Argon2i. Argon2d uses data-dependent memory | Argon2i. Argon2d uses data-dependent memory | |||
access, which makes it suitable for cryptocurrencies and | access, which makes it suitable for cryptocurrencies and | |||
proof-of-work applications with no threats from side-channel | proof-of-work applications with no threats from side-channel | |||
timing attacks. Argon2i uses data-independent memory access, | timing attacks. Argon2i uses data-independent memory access, | |||
which is preferred for password hashing and password-based key | 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 | 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 pro | memory and as Argon2d for the rest, thus providing both side-channel attack prot | |||
tection and | ection and | |||
brute-force cost savings due to time-memory tradeoffs. Argon2i ma | brute-force cost savings due to time-memory trade-offs. Argon2i m | |||
kes more passes over the | akes more passes over the | |||
memory to protect from <xref | memory to protect from <xref target="AB15" format="default">trade-off atta | |||
target="AB15">tradeoff attacks</xref>.</t> | cks</xref>.</t> | |||
<t>Argon2id <bcp14>MUST</bcp14> be supported by any implementation of this | ||||
<t> Argon2id MUST be supported by any implementation of this document, whe | document, whereas Argon2d and Argon2i <bcp14>MAY</bcp14> be supported. | |||
reas Argon2d and Argon2i MAY be supported. | </t> | |||
</t> | <t> Argon2 is also a mode of operation over a fixed-input-length compressi | |||
on function G and | ||||
<t> Argon2 is also a mode of operation over a fixed-input-length compre | ||||
ssion function G and | ||||
a variable-input-length hash function H. Even though Argon2 can be pote ntially used with an arbitrary function H, | a variable-input-length hash function H. Even though Argon2 can be pote ntially used with an arbitrary function H, | |||
as long as it provides outputs up to 64 bytes, in this document it is < | as long as it provides outputs up to 64 bytes, the <xref target="RFC769 | |||
xref | 3" format="default">BLAKE2b function</xref> is used in this document.</t> | |||
target="BLAKE2">BLAKE2b</xref>.</t> | <t>For further background and discussion, see the <xref target="ARGON2" fo | |||
rmat="default">Argon2 paper</xref>.</t> | ||||
<t>For further background and discussion, see the <xref | ||||
target="ARGON2">Argon2 paper</xref>.</t> | ||||
<t>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 <xref | ||||
target="RFC2119">RFC 2119</xref>.</t> | ||||
<t> This document represents the consensus of the Crypto Forum Research | <t> This document represents the consensus of the Crypto Forum Research | |||
Group (CFRG).</t> | Group (CFRG).</t> | |||
<section anchor="reqs"> | ||||
<name>Requirements Language</name> | ||||
<t> | ||||
The key words "<bcp14>MUST</bcp14>", "<bcp14>MUST NOT</bcp14>", "<bcp14>REQU | ||||
IRED</bcp14>", "<bcp14>SHALL</bcp14>", "<bcp14>SHALL | ||||
NOT</bcp14>", "<bcp14>SHOULD</bcp14>", "<bcp14>SHOULD NOT</bcp14>", "<bcp14> | ||||
RECOMMENDED</bcp14>", "<bcp14>NOT RECOMMENDED</bcp14>", | ||||
"<bcp14>MAY</bcp14>", and "<bcp14>OPTIONAL</bcp14>" in this document are to | ||||
be interpreted as | ||||
described in BCP 14 <xref target="RFC2119"/> <xref target="RFC8174"/> | ||||
when, and only when, they appear in all capitals, as shown here. | ||||
</t> | ||||
</section> | ||||
</section> | </section> | |||
<section numbered="true" toc="default"> | ||||
<section title="Notation and Conventions"> | <name>Notation and Conventions</name> | |||
<dl indent="15"> | ||||
<t>x^y --- integer x multiplied by itself integer y times</t> | <dt>x^y</dt><dd>integer x multiplied by itself integer y times</dd> | |||
<dt>a*b</dt><dd>multiplication of integer a and integer b</dd> | ||||
<t>a*b --- multiplication of integer a and integer b</t> | <dt>c-d</dt><dd>subtraction of integer d from integer c</dd> | |||
<dt>E_f</dt><dd>variable E with subscript index f</dd> | ||||
<t>c-d --- subtraction of integer d from integer c</t> | <dt>g / h</dt><dd>integer g divided by integer h. The result is a rational | |||
number.</dd> | ||||
<t>E_f --- variable E with subscript index f</t> | <dt>I(j)</dt><dd>function I evaluated at j</dd> | |||
<dt>K || L</dt><dd>string K concatenated with string L</dd> | ||||
<t>g / h --- integer g divided by integer h. The result is a rational numb | <dt>a XOR b</dt><dd>bitwise exclusive-or between bitstrings a and b</dd> | |||
er</t> | <dt>a mod b</dt><dd>remainder of integer a modulo integer b, always in ran | |||
ge [0, b-1]</dd> | ||||
<t>I(j) --- function I evaluated at j</t> | <dt>a >>> n</dt><dd>rotation of 64-bit string a to the right by n | |||
bits</dd> | ||||
<t>K || L --- string K concatenated with string L</t> | <dt>trunc(a)</dt><dd>the 64-bit value, truncated to the 32 least significa | |||
nt | ||||
<t>a XOR b --- bitwise exclusive-or between bitstrings a and b</t> | bits</dd> | |||
<dt>floor(a)</dt><dd>the largest integer not bigger than a</dd> | ||||
<t>a mod b --- remainder of integer a modulo integer b, always in range [0 | <dt>ceil(a)</dt><dd>the smallest integer not smaller than a</dd> | |||
, b-1]</t> | <dt>extract(a, i)</dt><dd>the i-th set of 32 bits from bitstring a, starti | |||
ng from 0-th</dd> | ||||
<t>a >>> n --- rotation of 64-bit string a to the right by n bits</t> | <dt>|A|</dt><dd>the number of elements in set A</dd> | |||
<dt>LE32(a)</dt><dd>32-bit integer a converted to a byte string in little | ||||
<t>trunc(a) --- the 64-bit value, truncated to the 32 least significant | endian (for example, 123456 (decimal) is 40 E2 01 00)</dd> | |||
bits</t> | <dt>LE64(a)</dt><dd>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)</dd> | ||||
<t>floor(a) --- the largest integer not bigger than a</t> | <dt>int32(s)</dt><dd>32-bit string s is converted to a non-negative intege | |||
r in little endian</dd> | ||||
<t>ceil(a) --- the smallest integer not smaller than a</t> | <dt>int64(s)</dt><dd>64-bit string s is converted to a non-negative intege | |||
r in little endian</dd> | ||||
<t>extract(a, i) --- the i-th set of 32-bits from bitstring a, starting fr | <dt>length(P)</dt><dd>the byte length of string P expressed as 32-bit inte | |||
om 0-th</t> | ger</dd> | |||
<dt>ZERO(P)</dt><dd>the P-byte zero string</dd> | ||||
<t>|A| --- the number of elements in set A</t> | </dl> | |||
<t>LE32(a) --- 32-bit integer a converted to a bytestring in little end | ||||
ian. Example: 123456 (decimal) is 40 E2 01 00.</t> | ||||
<t>LE64(a) --- 64-bit integer a converted to a bytestring in little end | ||||
ian. Example: 123456 (decimal) is 40 E2 01 00 00 00 00 00.</t> | ||||
<t>int32(s) --- 32-bit string s is converted to non-negative integer in | ||||
little endian.</t> | ||||
<t>int64(s) --- 64-bit string s is converted to non-negative integer in | ||||
little endian.</t> | ||||
<t>length(P) --- the bytelength of string P expressed as 32-bit integer | ||||
</t> | ||||
<t>ZERO(P) --- the P-byte zero string</t> | ||||
</section> | </section> | |||
<section anchor="argon2-algorithm" numbered="true" toc="default"> | ||||
<name>Argon2 Algorithm</name> | ||||
<section anchor="argon2-inouts" numbered="true" toc="default"> | ||||
<name>Argon2 Inputs and Outputs</name> | ||||
<t>Argon2 has the following input parameters: | ||||
<section anchor="argon2-algorithm" | </t> | |||
title="Argon2 Algorithm"> | <ul spacing="normal"> | |||
<li>Message string P, which is a password for password hashing | ||||
<section anchor="argon2-inouts" | applications. It <bcp14>MUST</bcp14> have a length not greater than 2^( | |||
title="Argon2 Inputs and Outputs"> | 32)-1 bytes.</li> | |||
<li>Nonce S, which is a salt for password hashing applications. It <bc | ||||
<t>Argon2 has the following input parameters: | p14>MUST</bcp14> have a length not greater than 2^(32)-1 bytes. 16 bytes is <bc | |||
p14>RECOMMENDED</bcp14> for | ||||
<list style="symbols"> | password hashing. The salt <bcp14>SHOULD</bcp14> be unique for each pa | |||
ssword.</li> | ||||
<t>Message string P, which is a password for password hashing | <li>Degree of parallelism p determines how many independent | |||
applications. MUST have length not greater than 2^(32) - 1 bytes.</t> | ||||
<t>Nonce S, which is a salt for password hashing applications. | ||||
MUST have length not greater than 2^(32)-1 bytes. 16 bytes is RECOMME | ||||
NDED for | ||||
password hashing. Salt SHOULD be unique for each password.</t> | ||||
<t>Degree of parallelism p determines how many independent | ||||
(but synchronizing) computational chains (lanes) can be | (but synchronizing) computational chains (lanes) can be | |||
run. It MUST be an integer value from 1 to 2^(24)-1.</t> | run. It <bcp14>MUST</bcp14> be an integer value from 1 to 2^(24)-1.</li | |||
> | ||||
<t>Tag length T MUST be an integer number of bytes from 4 to | <li>Tag length T <bcp14>MUST</bcp14> be an integer number of bytes fro | |||
2^(32)-1.</t> | m 4 to | |||
2^(32)-1.</li> | ||||
<t>Memory size m MUST be an integer number of kibibytes from | <li>Memory size m <bcp14>MUST</bcp14> be an integer number of kibibyte | |||
s from | ||||
8*p to 2^(32)-1. The actual number of blocks is m', which is | 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.</t> | m rounded down to the nearest multiple of 4*p.</li> | |||
<li>Number of passes t (used to tune the running time | ||||
<t>Number of passes t (used to tune the running time | independently of the memory size) <bcp14>MUST</bcp14> be an integer num | |||
independently of the memory size) MUST be an integer number | ber | |||
from 1 to 2^(32)-1.</t> | from 1 to 2^(32)-1.</li> | |||
<li>Version number v <bcp14>MUST</bcp14> be one byte 0x13.</li> | ||||
<t>Version number v MUST be one byte 0x13.</t> | <li>Secret value K is <bcp14>OPTIONAL</bcp14>. If used, it <bcp14>MUST | |||
</bcp14> have a length not greater than | ||||
<t>Secret value K is OPTIONAL. If used, it MUST have length not great | 2^(32)-1 bytes.</li> | |||
er than | <li>Associated data X is <bcp14>OPTIONAL</bcp14>. If used, it <bcp14>M | |||
2^(32)-1 bytes.</t> | UST</bcp14> have a length not greater than 2^(32)-1 | |||
bytes.</li> | ||||
<t>Associated data X is OPTIONAL. If used, it MUST have length not gre | <li>Type y <bcp14>MUST</bcp14> be 0 for Argon2d, 1 for Argon2i, or 2 f | |||
ater than 2^(32)-1 | or Argon2id.</li> | |||
bytes.</t> | </ul> | |||
<t>Type y of Argon2: MUST be 0 for Argon2d, 1 for Argon2i, 2 for Argon2 | ||||
id.</t> | ||||
</list></t> | ||||
<t>The Argon2 output, or "tag" is a string T bytes long.</t> | ||||
<t>The Argon2 output, or "tag", is a string T bytes long.</t> | ||||
</section> | </section> | |||
<section anchor="argon2-operation" numbered="true" toc="default"> | ||||
<section anchor="argon2-operation" | <name>Argon2 Operation</name> | |||
title="Argon2 Operation"> | <t>Argon2 uses an internal compression function G with two | |||
1024-byte inputs, a 1024-byte output, and an internal hash | ||||
<t>Argon2 uses an internal compression function G with two | function H^x(), with x being its output length in bytes. Here, H^x() app | |||
1024-byte inputs and a 1024-byte output, and an internal hash | lied to string A is the BLAKE2b (<xref target="RFC7693" section="3.3" sectionFor | |||
function H^x() with x being its output length in bytes. Here H^x() appli | mat="comma"/>) function, which takes (d,ll,kk=0,nn=x) as parameters, | |||
ed to string A is the <xref | ||||
target="BLAKE2">BLAKE2b (Section 3.3)</xref> function, which takes (d,ll, | ||||
kk=0,nn=x) as parameters | ||||
where d is A padded to a multiple of 128 bytes | 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 o n its internal | and ll is the length of d in bytes. The compression function G is based o n its internal | |||
permutation. A variable-length hash function H' built upon H | permutation. A variable-length hash function H' built upon H | |||
is also used. G is described in <xref target="G-function"></xref> and H | is also used. G is described in <xref target="G-function" format="defau | |||
' is described in | lt"/>, and H' is described in | |||
<xref target="H-function"></xref>.</t> | <xref target="H-function" format="default"/>.</t> | |||
<t>The Argon2 operation is as follows. | ||||
<t>The Argon2 operation is as follows. | ||||
<list style="numbers"> | ||||
<t>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 lengt | ||||
h field remains. | ||||
<figure title="H_0 generation"> | </t> | |||
<artwork> | <ol spacing="normal" type="1"><li> | |||
H_0 = H^(64)(LE32(p) || LE32(T) || LE32(m) || LE32(t) || | <t>Establish H_0 as the 64-byte value as shown | |||
LE32(v) || LE32(y) || LE32(length(P)) || P || | below. If K, X, or S has zero length, it is just absent, but its leng | |||
LE32(length(S)) || S || LE32(length(K)) || K || | th field remains. | |||
LE32(length(X)) || X) | ||||
</artwork> | ||||
</figure></t> | ||||
<t>Allocate the memory as m' 1024-byte blocks where m' is | </t> | |||
<figure> | ||||
<name>H_0 Generation</name> | ||||
<artwork name="" type="" align="left" alt=""><![CDATA[ | ||||
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) | ||||
]]></artwork> | ||||
</figure> | ||||
</li> | ||||
<li> | ||||
<t>Allocate the memory as m' 1024-byte blocks, where m' is | ||||
derived as: | derived as: | |||
<figure title="Memory allocation"> | </t> | |||
<artwork> | <figure> | |||
m' = 4 * p * floor (m / 4p) | <name>Memory Allocation</name> | |||
</artwork> | <artwork name="" type="" align="left" alt=""><![CDATA[ | |||
</figure> | m' = 4 * p * floor (m / 4p) | |||
]]></artwork> | ||||
</figure> | ||||
<t> | ||||
For p lanes, the memory is | For p lanes, the memory is | |||
organized in a matrix B[i][j] of blocks with p rows (lanes) | organized in a matrix B[i][j] of blocks with p rows (lanes) | |||
and q = m' / p columns.</t> | and q = m' / p columns.</t> | |||
</li> | ||||
<t>Compute B[i][0] for all i ranging from (and including) 0 | <li> | |||
<t>Compute B[i][0] for all i ranging from (and including) 0 | ||||
to (not including) p. | to (not including) p. | |||
<figure title="Lane starting blocks"> | </t> | |||
<artwork> | <figure> | |||
B[i][0] = H'^(1024)(H_0 || LE32(0) || LE32(i)) | <name>Lane Starting Blocks</name> | |||
</artwork> | <artwork name="" type="" align="left" alt=""><![CDATA[ | |||
</figure> | B[i][0] = H'^(1024)(H_0 || LE32(0) || LE32(i)) | |||
]]></artwork> | ||||
</t> | </figure> | |||
</li> | ||||
<t>Compute B[i][1] for all i ranging from (and including) 0 | <li> | |||
<t>Compute B[i][1] for all i ranging from (and including) 0 | ||||
to (not including) p. | to (not including) p. | |||
<figure title ="Second lane blocks"> | </t> | |||
<artwork> | <figure> | |||
B[i][1] = H'^(1024)(H_0 || LE32(1) || LE32(i)) | <name>Second Lane Blocks</name> | |||
</artwork> | <artwork name="" type="" align="left" alt=""><![CDATA[ | |||
</figure> | B[i][1] = H'^(1024)(H_0 || LE32(1) || LE32(i)) | |||
]]></artwork> | ||||
</t> | </figure> | |||
</li> | ||||
<li> | ||||
<t>Compute B[i][j] for all i ranging from (and including) 0 | <t anchor="step5">Compute B[i][j] for all i ranging from (and includ | |||
to (not including) p, and for all j ranging from (and | ing) 0 | |||
including) 2) to (not including) q. The computation MUST proceed slice | to (not including) p and for all j ranging from (and | |||
wise (<xref target="indexing"></xref>): first blocks from slice 0 are computed | including) 2 to (not including) q. The computation <bcp14>MUST</bcp14> | |||
for all lanes (in an arbitrary order of lanes), then blocks from slice 1 are | proceed slicewise (<xref target="indexing" format="default"/>): first, blocks | |||
computed etc. The block indices l | 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, an d Argon2id. | and z are determined for each i, j differently for Argon2d, Argon2i, an d Argon2id. | |||
<figure title="Further block generation"> | </t> | |||
<artwork> | <figure> | |||
B[i][j] = G(B[i][j-1], B[l][z]) | <name>Further Block Generation</name> | |||
</artwork> | <artwork name="" type="" align="left" alt=""><![CDATA[ | |||
</figure></t> | B[i][j] = G(B[i][j-1], B[l][z]) | |||
]]></artwork> | ||||
<t>If the number of passes t is larger than 1, we repeat | </figure> | |||
the steps. However blocks are computed differently as the old value is | </li> | |||
XORed with the new one: | <li> | |||
<figure title="Further passes"> | <t>If the number of passes t is larger than 1, we repeat | |||
<artwork> | <xref target="step5" format="none">step 5</xref>. We compute B[i][0] an | |||
B[i][0] = G(B[i][q-1], B[l][z]) XOR B[i][0]; | d B[i][j] for all i raging from (and including) 0 to (not including) p and for a | |||
B[i][j] = G(B[i][j-1], B[l][z]) XOR B[i][j]. | ll j ranging from | |||
</artwork> | (and including) 1 to (not including) q. However, blocks are computed differen | |||
</figure></t> | tly as the old value is XORed with the new one: | |||
</t> | ||||
<t>After t steps have been iterated, the final block C is computed as | <figure> | |||
<name>Further Passes</name> | ||||
<artwork name="" type="" align="left" alt=""><![CDATA[ | ||||
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]. | ||||
]]></artwork> | ||||
</figure> | ||||
</li> | ||||
<li> | ||||
<t>After t steps have been iterated, the final block C is computed a | ||||
s | ||||
the XOR of the last column: | the XOR of the last column: | |||
<figure title="Final block"> | </t> | |||
<artwork> | <figure> | |||
C = B[0][q-1] XOR B[1][q-1] XOR ... XOR B[p-1][q-1] | <name>Final Block</name> | |||
</artwork> | <artwork name="" type="" align="left" alt=""><![CDATA[ | |||
</figure></t> | C = B[0][q-1] XOR B[1][q-1] XOR ... XOR B[p-1][q-1] | |||
]]></artwork> | ||||
<t>The output tag is computed as H'^T(C).</t> | </figure> | |||
</li> | ||||
</list></t> | <li>The output tag is computed as H'^T(C).</li> | |||
</ol> | ||||
</section> | </section> | |||
<section anchor="H-function" numbered="true" toc="default"> | ||||
<section anchor="H-function" title="Variable-length hash function H'"> | <name>Variable-Length Hash Function H'</name> | |||
<t>Let V_i be a 64-byte block and W_i be its first 32 bytes. Then we de | ||||
<t>Let V_i be a 64-byte block, and W_i be its first 32 bytes. Then we de | fine function H' as follows: | |||
fine: | </t> | |||
<figure> | ||||
<figure title="Function H' for tag and initial block computations"> | <name>Function H' for Tag and Initial Block Computations</name> | |||
<artwork> | <sourcecode type="pseudocode"> | |||
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} | |||
</artwork> | </sourcecode> | |||
</figure> | </figure> | |||
</t> | ||||
</section> | </section> | |||
<section anchor="indexing" numbered="true" toc="default"> | ||||
<section anchor="indexing" title="Indexing"> | <name>Indexing</name> | |||
<t>To enable parallel block computation, we further partition the | ||||
<t>To enable parallel block computation, we further partition the | ||||
memory matrix into SL = 4 vertical slices. The intersection of a | memory 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 t he | 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 | same slice can be computed in parallel and do not reference blocks | |||
from each other. All other blocks can be referenced.</t> | from each other. All other blocks can be referenced.</t> | |||
<figure> | ||||
<figure title="Single-pass Argon2 with p lanes and 4 slices"> | <name>Single-Pass Argon2 with p Lanes and 4 Slices</name> | |||
<artwork name="" type="" align="left" alt=""><![CDATA[ | ||||
<artwork> | 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 | +----------+----------+----------+----------+ | |||
+----------+----------+----------+----------+ | ]]></artwork> | |||
</artwork> | </figure> | |||
</figure> | <section numbered="true" toc="default"> | |||
<name>Computing the 32-Bit Values J_1 and J_2</name> | ||||
<section title="Computing the 32-bit values J_1 and J_2"> | <section numbered="true" toc="default"> | |||
<section title="Argon2d"> | <name>Argon2d</name> | |||
<t>J_1 is given by the first 32 bits of block B[i][j-1], | <t>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]: | while J_2 is given by the next 32 bits of block B[i][j-1]: | |||
<figure title ="Deriving J1,J2 in Argon2d"> | </t> | |||
<artwork> | <figure> | |||
J_1 = int32(extract(B[i][j-1], 0)) | <name>Deriving J1,J2 in Argon2d</name> | |||
J_2 = int32(extract(B[i][j-1], 1)) | <artwork name="" type="" align="left" alt=""><![CDATA[ | |||
</artwork> | J_1 = int32(extract(B[i][j-1], 0)) | |||
</figure></t> | J_2 = int32(extract(B[i][j-1], 1)) | |||
]]></artwork> | ||||
</figure> | ||||
</section> | </section> | |||
<section numbered="true" toc="default"> | ||||
<name>Argon2i</name> | ||||
<t>For each segment, we do the following. First, we compute the valu | ||||
e Z as: | ||||
<section title="Argon2i"> | </t> | |||
<t>For each segment we do the following. First we compute the va | <figure> | |||
lue Z as | <name>Input to Compute J1,J2 in Argon2i</name> | |||
<artwork name="" type="" align="left" alt=""><![CDATA[ | ||||
<figure title="Input to compute J1,J2 in Argon2i"> | Z= ( LE64(r) || LE64(l) || LE64(sl) || LE64(m') || | |||
<artwork> | LE64(t) || LE64(y) ) | |||
Z= ( LE64(r) || LE64(l) || LE64(sl) || LE64(m') || | ]]></artwork> | |||
LE64(t) || LE64(y) ), where | </figure> | |||
<t>where</t> | ||||
r -- the pass number | <dl indent="5" spacing="compact"> | |||
l -- the lane number | <dt>r:</dt><dd>the pass number</dd> | |||
sl -- the slice number | <dt>l:</dt><dd>the lane number</dd> | |||
m' -- the total number of memory blocks | <dt>sl:</dt><dd>the slice number</dd> | |||
t -- the total number of passes | <dt>m':</dt><dd>the total number of memory blocks</dd> | |||
y -- the Argon2 type (0 for Argon2d, | <dt>t:</dt><dd>the total number of passes</dd> | |||
1 for Argon2i, 2 for Argon2id) | <dt>y:</dt><dd>the Argon2 type (0 for Argon2d, | |||
</artwork> | 1 for Argon2i, 2 for Argon2id)</dd> | |||
</figure> | </dl> | |||
Then we compute q/(128*SL) 1024-byte values G(ZERO(1024),G(ZERO(1024), Z || LE6 | <t> | |||
4(1) || ZERO(968) )), | Then we compute:</t> | |||
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 part | ||||
itioned 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, i are represented as 8 bytes in | ||||
little-endian.</t> | ||||
<artwork name="" type="" align="left" alt=""><![CDATA[ | ||||
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) )), | ||||
]]></artwork><t> | ||||
which are partitioned into q/(SL) 8-byte values X, which are viewed as X1||X2 a | ||||
nd converted to J_1=int32(X1) and J_2=int32(X2).</t> | ||||
<t> | ||||
The values r, l, sl, m', t, y, and i are represented as 8 bytes in | ||||
little endian.</t> | ||||
</section> | </section> | |||
<section title="Argon2id"> | <section numbered="true" toc="default"> | |||
<name>Argon2id</name> | ||||
<t>If the pass number is 0 and the slice number is 0 or 1, then comp ute J_1 and J_2 as | <t>If the pass number is 0 and the slice number is 0 or 1, then comp ute J_1 and J_2 as | |||
for Argon2i, else compute J_1 and J_2 as for Argon2d.</t> | for Argon2i, else compute J_1 and J_2 as for Argon2d.</t> | |||
</section> | </section> | |||
</section> | </section> | |||
<section numbered="true" toc="default"> | ||||
<section title="Mapping J_1 and J_2 to reference block index [l][z]"> | <name>Mapping J_1 and J_2 to Reference Block Index [l][z]</name> | |||
<t>The value of l = J_2 mod p gives the index of the lane from | <t>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 | 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.</t> | the first slice (sl=0), the block is taken from the current lane.</t | |||
> | ||||
<t>The set W contains the indices that are referenced | <t>The set W contains the indices that are referenced | |||
according to the following rules: | according to the following rules: | |||
<list style="numbers"> | </t> | |||
<t>If l is the current lane, then W includes the indices of | <ol spacing="normal" type="1"><li>If l is the current lane, then W inc | |||
ludes the indices of | ||||
all blocks in the last SL - 1 = 3 segments computed and finished , as well as | 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 | the blocks computed in the current segment in the current pass | |||
excluding B[i][j-1].</t> | excluding B[i][j-1].</li> | |||
<t>If l is not the current lane, then W includes the indices of | <li>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 | 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 | in lane l. If B[i][j] is the first block of a segment, then the | |||
very last index from W is excluded.</t> | very last index from W is excluded.</li> | |||
</list> | </ol> | |||
</t> | <t>Then take a block from W with a nonuniform | |||
distribution over [0, |W|) using the following mapping: | ||||
<t>Then take a block from W with a non-uniform | ||||
distribution over [0, |W|) using the mapping | ||||
<figure title="Computing J1"> | ||||
<artwork> | ||||
J_1 -> |W|(1 - J_1^2 / 2^(64)) | ||||
</artwork> | ||||
</figure></t> | ||||
<t>To avoid floating point computation, the following approximation | </t> | |||
<figure> | ||||
<name>Computing J1</name> | ||||
<artwork name="" type="" align="left" alt=""><![CDATA[ | ||||
J_1 -> |W|(1 - J_1^2 / 2^(64)) | ||||
]]></artwork> | ||||
</figure> | ||||
<t>To avoid floating point computation, the following approximation | ||||
is used: | is used: | |||
<figure title="Computing J1, part 2"> | </t> | |||
<artwork> | <figure> | |||
x = J_1^2 / 2^(32) | <name>Computing J1, Part 2</name> | |||
y = (|W| * x) / 2^(32) | <artwork name="" type="" align="left" alt=""><![CDATA[ | |||
zz = |W| - 1 - y | x = J_1^2 / 2^(32) | |||
</artwork> | y = (|W| * x) / 2^(32) | |||
</figure></t> | zz = |W| - 1 - y | |||
]]></artwork> | ||||
<t>Then take the zz-th index from W, it will be the z value for the | </figure> | |||
reference block index [l][z].</t> | <t>Then take the zz-th index from W; it will be the z value for the re | |||
ference block index [l][z].</t> | ||||
</section> | </section> | |||
</section> | </section> | |||
<section anchor="G-function" numbered="true" toc="default"> | ||||
<section anchor="G-function" title="Compression function G"> | <name>Compression Function G</name> | |||
<t>The compression function G is built upon the BLAKE2b-based transform | ||||
<t>The compression function G is built upon the BLAKE2b-based transforma | ation P. | |||
tion P. | ||||
P operates on the 128-byte input, which can be | P operates on the 128-byte input, which can be | |||
viewed as 8 16-byte registers: | viewed as eight 16-byte registers: | |||
<figure title="Blake round function P"> | ||||
<artwork> | ||||
P(A_0, A_1, ... ,A_7) = (B_0, B_1, ... ,B_7) | ||||
</artwork> | ||||
</figure></t> | ||||
<t>The compression function G(X, Y) operates on two 1024-byte | </t> | |||
<figure> | ||||
<name>Blake Round Function P</name> | ||||
<artwork name="" type="" align="left" alt=""><![CDATA[ | ||||
P(A_0, A_1, ... ,A_7) = (B_0, B_1, ... ,B_7) | ||||
]]></artwork> | ||||
</figure> | ||||
<t>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 | blocks X and Y. It first computes R = X XOR Y. Then R is | |||
viewed as a 8x8 matrix of 16-byte registers R_0, R_1, ... , | 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 | R_63. Then P is first applied to each row, and then to each column to | |||
get Z: | get Z: | |||
<figure title="Core of compression function G"> | </t> | |||
<artwork> | <figure> | |||
( Q_0, Q_1, Q_2, ... , Q_7) <- P( R_0, R_1, R_2, ... , R_7) | <name>Core of Compression Function G</name> | |||
( Q_8, Q_9, Q_10, ... , Q_15) <- P( R_8, R_9, R_10, ... , R_15) | <artwork name="" type="" align="left" alt=""><![CDATA[ | |||
( 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) | (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) | |||
</artwork> | ]]></artwork> | |||
</figure></t> | </figure> | |||
<t>Finally, G outputs Z XOR R: | ||||
<t>Finally, G outputs Z XOR R: | ||||
<figure> | ||||
<artwork> | ||||
G: (X, Y) -> R -> Q -> Z -> Z XOR R | ||||
</artwork> | ||||
</figure> | ||||
<figure title="Argon2 compression function G."> | </t> | |||
<artwork> | <artwork name="" type="" align="left" alt=""><![CDATA[ | |||
G: (X, Y) -> R -> Q -> Z -> Z XOR R | ||||
]]></artwork> | ||||
<figure> | ||||
<name>Argon2 Compression Function G</name> | ||||
<artwork name="" type="" align="left" alt=""><![CDATA[ | ||||
+---+ +---+ | +---+ +---+ | |||
| X | | Y | | | X | | Y | | |||
+---+ +---+ | +---+ +---+ | |||
| | | | | | |||
---->XOR<---- | ---->XOR<---- | |||
--------| | --------| | |||
| \ / | | \ / | |||
| +---+ | | +---+ | |||
| | R | | | | R | | |||
| +---+ | | +---+ | |||
| | | | | | |||
| \ / | | \ / | |||
| P rowwise | | P rowwise | |||
| | | | | | |||
| \ / | | \ / | |||
skipping to change at line 527 ¶ | skipping to change at line 494 ¶ | |||
| | | | | | |||
| \ / | | \ / | |||
| +---+ | | +---+ | |||
| | Z | | | | Z | | |||
| +---+ | | +---+ | |||
| | | | | | |||
| \ / | | \ / | |||
------>XOR | ------>XOR | |||
| | | | |||
\ / | \ / | |||
</artwork> | ]]></artwork> | |||
</figure></t> | </figure> | |||
</section> | </section> | |||
<section anchor="P-permutation" numbered="true" toc="default"> | ||||
<section anchor="P-permutation" title="Permutation P"> | <name>Permutation P</name> | |||
<t>Permutation P is based on the round function of BLAKE2b. The eight | ||||
<t>Permutation P is based on the round function of BLAKE2b. The 8 | ||||
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}): | |||
<figure title="Matrix element labeling"> | </t> | |||
<artwork> | <figure> | |||
<name>Matrix Element Labeling</name> | ||||
<artwork name="" type="" align="left" alt=""><![CDATA[ | ||||
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 | |||
</artwork> | ]]></artwork> | |||
</figure> | </figure> | |||
<t> | ||||
It works as follows: | It works as follows: | |||
<figure title="Feeding matrix elements to GB"> | </t> | |||
<artwork> | <figure> | |||
<name>Feeding Matrix Elements to GB</name> | ||||
<artwork name="" type="" align="left" alt=""><![CDATA[ | ||||
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) | |||
</artwork> | ]]></artwork> | |||
</figure> | </figure> | |||
<t> | ||||
GB(a, b, c, d) is defined as follows: | GB(a, b, c, d) is defined as follows: | |||
<figure title="Details of GB"> | </t> | |||
<artwork> | <figure> | |||
<name>Details of GB</name> | ||||
<artwork name="" type="" align="left" alt=""><![CDATA[ | ||||
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 | |||
</artwork> | ]]></artwork> | |||
</figure> | </figure> | |||
<t> | ||||
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 design. | Multiplications are the only difference from the original BLAKE2b design . | |||
This choice is done to increase the circuit depth and thus the running | This choice is done to increase the circuit depth and thus the running | |||
time of ASIC implementations, while having roughly the same running | time of ASIC implementations, while having roughly the same running | |||
time on CPUs thanks to parallelism and pipelining. | time on CPUs thanks to parallelism and pipelining. | |||
</t> | </t> | |||
</section> | </section> | |||
</section> | </section> | |||
<section anchor="parameter-choice" numbered="true" toc="default"> | ||||
<section anchor="parameter-choice" | <name>Parameter Choice</name> | |||
title="Parameter Choice"> | ||||
<t>Argon2d is optimized for settings where the adversary does | <t>Argon2d is optimized for settings where the adversary does | |||
not get regular access to system memory or CPU, i.e. he can not | not get regular access to system memory or CPU, i.e., they cannot | |||
run side-channel attacks based on the timing information, nor he | run side-channel attacks based on the timing information, nor can they | |||
can recover the password much faster using garbage | recover the password much faster using garbage | |||
collection. These settings are more typical for backend servers | collection. These settings are more typical for backend servers | |||
and cryptocurrency minings. For practice we suggest the | and cryptocurrency minings. For practice, we suggest the | |||
following settings: | following settings: | |||
<list style="symbols"> | </t> | |||
<ul spacing="normal"> | ||||
<t>Cryptocurrency mining, that takes 0.1 seconds on a 2 Ghz | <li>Cryptocurrency mining, which takes 0.1 seconds on a 2 GHz | |||
CPU using 1 core — Argon2d with 2 lanes and 250 MB of RAM.</t> | CPU using 1 core -- Argon2d with 2 lanes and 250 MB of RAM.</li> | |||
</ul> | ||||
</list></t> | ||||
<t>Argon2id is optimized for more realistic settings, where the | <t>Argon2id is optimized for more realistic settings, where the | |||
adversary possibly can access the same machine, use its CPU or | adversary can possibly access the same machine, use its CPU, or | |||
mount cold-boot attacks. We suggest the following | mount cold-boot attacks. We suggest the following | |||
settings: | settings: | |||
<list style="symbols"> | </t> | |||
<t>Backend server authentication, that takes 0.5 seconds on a | <ul spacing="normal"> | |||
2 GHz CPU using 4 cores — Argon2id with 8 lanes and 4 GiB of | <li>Backend server authentication, which takes 0.5 seconds on a | |||
RAM.</t> | 2 GHz CPU using 4 cores -- Argon2id with 8 lanes and 4 GiB of | |||
RAM.</li> | ||||
<t>Key derivation for hard-drive encryption, that takes 3 | <li>Key derivation for hard-drive encryption, which takes 3 | |||
seconds on a 2 GHz CPU using 2 cores - Argon2id with 4 lanes | seconds on a 2 GHz CPU using 2 cores -- Argon2id with 4 lanes | |||
and 6 GiB of RAM.</t> | and 6 GiB of RAM.</li> | |||
<li>Frontend server authentication, which takes 0.5 seconds on a | ||||
<t>Frontend server authentication, that takes 0.5 seconds on a | 2 GHz CPU using 2 cores -- Argon2id with 4 lanes and 1 GiB of | |||
2 GHz CPU using 2 cores - Argon2id with 4 lanes and 1 GiB of | RAM.</li> | |||
RAM.</t> | </ul> | |||
</list></t> | ||||
<t>We recommend the following procedure to select the type and | <t>We recommend the following procedure to select the type and | |||
the parameters for practical use of Argon2. | the parameters for practical use of Argon2. | |||
<list style="numbers"> | </t> | |||
<t> If you are OK with a uniformly safe option, but not tailored to your appli | ||||
cation or hardware, | ||||
select Argon2id with t=1 iteration, p=4 lanes and m=2^(21) (2 GiB of RAM), 128 | ||||
-bit salt, 256-bit tag size. | ||||
This is the FIRST RECOMMENDED option.</t> | ||||
<t> If much less memory is available, a uniformly safe option is Argon2id wit | ||||
h t=3 iterations, p=4 lanes and m=2^(16) | ||||
(64 MiB of RAM), 128-bit salt, 256-bit tag size. | ||||
This is the SECOND RECOMMENDED option.</t> | ||||
<t>Otherwise, start with selecting the type y. If you do not know the dif | ||||
ference | ||||
between them or you consider side-channel attacks as viable | ||||
threat, choose Argon2id.</t> | ||||
<t>Select p=4 lanes.</t> | ||||
<t>Figure out the maximum amount of memory that each call | ||||
can afford and translate it to the parameter m.</t> | ||||
<t>Figure out the maximum amount of time (in seconds) that | ||||
each call can afford.</t> | ||||
<t>Select the salt length. 128 bits is sufficient for all | <ol spacing="normal" type="1"><li> If a uniformly safe option that is not | |||
applications, but can be reduced to 64 bits in the case of | tailored to your application or hardware is acceptable, | |||
space constraints.</t> | select Argon2id with t=1 iteration, p=4 lanes, m=2^(21) (2 GiB of RAM), 128-bi | |||
t salt, and 256-bit tag size. | ||||
This is the FIRST <bcp14>RECOMMENDED</bcp14> option.</li> | ||||
<li> If much less memory is available, a uniformly safe option is Argon2 | ||||
id 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 <bcp14>RECOMMENDED</bcp14> option.</li> | ||||
<t>Select the tag length. 128 bits is sufficient for most | <li>Otherwise, start with selecting the type y. If you do not know the d | |||
ifference | ||||
between the types or you consider side-channel attacks to be a viable | ||||
threat, choose Argon2id.</li> | ||||
<li>Select p=4 lanes.</li> | ||||
<li>Figure out the maximum amount of memory that each call | ||||
can afford and translate it to the parameter m.</li> | ||||
<li>Figure out the maximum amount of time (in seconds) that | ||||
each call can afford.</li> | ||||
<li>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.</li> | ||||
<li>Select the tag length. A length of 128 bits is sufficient for most | ||||
applications, including key derivation. If longer keys are | applications, including key derivation. If longer keys are | |||
needed, select longer tags.</t> | needed, select longer tags.</li> | |||
<li>If side-channel attacks are a viable threat or if you're uncertain, | ||||
<t>If side-channel attacks are a viable threat, or if you're uncertain, e | enable the | |||
nable the | memory-wiping option in the library call.</li> | |||
memory wiping option in the library call.</t> | <li>Run the scheme of type y, memory m, and p lanes | |||
using a different number of passes t. Figure out the maximum t | ||||
<t>Run the scheme of type y, memory m and p lanes, | such that the running time does not exceed the affordable time. If it eve | |||
using different number of passes t. Figure out the maximum t | n exceeds for t = 1, reduce m accordingly.</li> | |||
such that the running time does not exceed the affordable time. If it exc | <li> Use Argon2 with determined values m, | |||
eeds | p, and t.</li> | |||
even for t = 1, reduce m accordingly.</t> | </ol> | |||
<t> Use Argon2 with determined values m, | ||||
p, and t.</t> | ||||
</list></t> | ||||
</section> | </section> | |||
<section anchor="test-vectors" numbered="true" toc="default"> | ||||
<section anchor="test-vectors" | <name>Test Vectors</name> | |||
title="Test Vectors"> | ||||
<t>This section contains test vectors for Argon2.</t> | <t>This section contains test vectors for Argon2.</t> | |||
<section anchor="argon2d-test-vectors" numbered="true" toc="default"> | ||||
<section anchor="argon2d-test-vectors" | <name>Argon2d Test Vectors</name> | |||
title="Argon2d Test Vectors"> | <t>We provide test vectors with complete outputs (tags). For the conveni | |||
ence of developers, we also provide some interim variables -- concretely, the fi | ||||
<t>We provide test vectors with complete outputs (tags). For the convenie | rst and last memory blocks of each pass.</t> | |||
nce of developers, we also provide some interim variables, concretely, first and | <sourcecode type="test-vectors"> | |||
last memory blocks of each pass.</t> | ||||
<figure> | ||||
<artwork> | ||||
======================================= | ======================================= | |||
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 | |||
01 01 01 01 01 01 01 01 | 01 01 01 01 01 01 01 01 | |||
skipping to change at line 745 ¶ | skipping to change at line 695 ¶ | |||
Block 0000 [ 3]: 7486a73f62f9b142 | Block 0000 [ 3]: 7486a73f62f9b142 | |||
... | ... | |||
Block 0031 [124]: 57cfb9d20479da49 | Block 0031 [124]: 57cfb9d20479da49 | |||
Block 0031 [125]: 4099654bc6607f69 | Block 0031 [125]: 4099654bc6607f69 | |||
Block 0031 [126]: f142a1126075a5c8 | Block 0031 [126]: f142a1126075a5c8 | |||
Block 0031 [127]: c341b3ca45c10da5 | Block 0031 [127]: c341b3ca45c10da5 | |||
Tag: 51 2b 39 1b 6f 11 62 97 | Tag: 51 2b 39 1b 6f 11 62 97 | |||
53 71 d3 09 19 73 42 94 | 53 71 d3 09 19 73 42 94 | |||
f8 68 e3 be 39 84 f3 c1 | f8 68 e3 be 39 84 f3 c1 | |||
a1 3a 4d b9 fa be 4a cb | a1 3a 4d b9 fa be 4a cb | |||
</artwork> | </sourcecode> | |||
</figure> | ||||
</section> | </section> | |||
<section anchor="argon2i-test-vectors" numbered="true" toc="default"> | ||||
<section anchor="argon2i-test-vectors" | <name>Argon2i Test Vectors</name> | |||
title="Argon2i Test Vectors"> | <sourcecode type="test-vectors"> | |||
<figure> | ||||
<artwork> | ||||
======================================= | ======================================= | |||
Argon2i version number 19 | Argon2i 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 | |||
01 01 01 01 01 01 01 01 | 01 01 01 01 01 01 01 01 | |||
skipping to change at line 814 ¶ | skipping to change at line 759 ¶ | |||
Block 0000 [ 3]: 25a1c1f5bb953766 | Block 0000 [ 3]: 25a1c1f5bb953766 | |||
... | ... | |||
Block 0031 [124]: 68cf72fccc7112b9 | Block 0031 [124]: 68cf72fccc7112b9 | |||
Block 0031 [125]: 91e8c6f8bb0ad70d | Block 0031 [125]: 91e8c6f8bb0ad70d | |||
Block 0031 [126]: 4f59c8bd65cbb765 | Block 0031 [126]: 4f59c8bd65cbb765 | |||
Block 0031 [127]: 71e436f035f30ed0 | Block 0031 [127]: 71e436f035f30ed0 | |||
Tag: c8 14 d9 d1 dc 7f 37 aa | Tag: c8 14 d9 d1 dc 7f 37 aa | |||
13 f0 d7 7f 24 94 bd a1 | 13 f0 d7 7f 24 94 bd a1 | |||
c8 de 6b 01 6d d3 88 d2 | c8 de 6b 01 6d d3 88 d2 | |||
99 52 a4 c4 67 2b 6c e8 | 99 52 a4 c4 67 2b 6c e8 | |||
</artwork> | </sourcecode> | |||
</figure> | ||||
</section> | </section> | |||
<section anchor="argon2id-test-vectors" numbered="true" toc="default"> | ||||
<section anchor="argon2id-test-vectors" | <name>Argon2id Test Vectors</name> | |||
title="Argon2id Test Vectors"> | <sourcecode type="test-vectors"> | |||
<figure> | ||||
<artwork> | ||||
======================================= | ======================================= | |||
Argon2id version number 19 | Argon2id version number 19 | |||
======================================= | ======================================= | |||
Memory: 32 KiB, Passes: 3, | Memory: 32 KiB, Passes: 3, | |||
Parallelism: 4 lanes, Tag length: 32 bytes | 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 | 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 | 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 | 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 | 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 | Associated data[12]: 04 04 04 04 04 04 04 04 04 04 04 04 | |||
skipping to change at line 873 ¶ | skipping to change at line 813 ¶ | |||
Block 0000 [ 1]: a22448c0bdad5760 | Block 0000 [ 1]: a22448c0bdad5760 | |||
Block 0000 [ 2]: a5f80662b6fa8748 | Block 0000 [ 2]: a5f80662b6fa8748 | |||
Block 0000 [ 3]: a0f9b9ce392f719f | Block 0000 [ 3]: a0f9b9ce392f719f | |||
... | ... | |||
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 | |||
</artwork> | </sourcecode> | |||
</figure> | ||||
</section> | </section> | |||
</section> | </section> | |||
<section anchor="iana" numbered="true" toc="default"> | ||||
<section anchor="iana" | <name>IANA Considerations</name> | |||
title="IANA Considerations"> | <t>This document has no IANA actions.</t> | |||
<t>None.</t> | ||||
</section> | </section> | |||
<section anchor="security" numbered="true" toc="default"> | ||||
<section anchor="security" | <name>Security Considerations</name> | |||
title="Security Considerations"> | <section anchor="security-hash" numbered="true" toc="default"> | |||
<section anchor="security-hash" | <name>Security as a Hash Function and KDF</name> | |||
title="Security as hash function and KDF"> | <t>The collision and preimage resistance levels of Argon2 are equivalent | |||
<t>The collision and preimage resistance levels of Argon2 are equiv | to those of the underlying BLAKE2b hash function. | |||
alent to those of the underlying BLAKE2b hash function. | ||||
To produce a collision, 2^(256) inputs are needed. To find a preima ge, 2^(512) inputs must be tried.</t> | To produce a collision, 2^(256) inputs are needed. To find a preima ge, 2^(512) inputs must be tried.</t> | |||
<t>The KDF security is determined by the key length | ||||
<t>The KDF security is determined by the key length | ||||
and the size of the internal state of hash function H'. | and the size of the internal state of hash function H'. | |||
To distinguish the output of keyed Argon2 from random, minimum of ( | To distinguish the output of the keyed Argon2 from random, a minimu | |||
2^(128),2^length(K)) calls to BLAKE2b are needed. </t> | m of (2^(128),2^length(K)) calls to BLAKE2b are needed. </t> | |||
</section> | </section> | |||
<section anchor="security-tradeoff" numbered="true" toc="default"> | ||||
<section anchor="security-tradeoff" | <name>Security against Time-Space Trade-off Attacks</name> | |||
title="Security against time-space tradeoff attacks"> | <t>Time-space trade-offs allow computing a memory-hard function storing | |||
<t>Time-space tradeoffs allow computing a memory-hard function sto | fewer memory blocks at the cost of more calls to | |||
ring fewer memory blocks at the cost of more calls to | the internal compression function. The advantage of trade-off attac | |||
the internal comression function. The advantage of tradeoff attacks | ks is measured in the reduction factor to the time-area | |||
is measured in the reduction factor to the time-area | product, where memory and extra compression function cores contribu | |||
product, where memory and extra compression function cores contribu | te to the area and time is increased to accommodate the recomputation | |||
te to the area, and time is increased to accomodate the recomputation | of missed blocks. A high reduction factor may potentially speed up | |||
of missed blocks. A high reduction factor may potentially speed up | the preimage search. | |||
preimage search. | </t> | |||
</t> | <t>The best-known attack on the 1-pass and 2-pass Argon2i is the low-sto | |||
<t>The best known attacks on the 1-pass and 2-pass Argon2i is the low-stor | rage | |||
age | attack described in <xref target="CBS16" format="default"/>, which reduces | |||
attack described in <xref target="CBS16"></xref>, which reduces the | the | |||
time-area product (using the peak memory value) by the factor of 5. | time-area product (using the peak memory value) by the factor of 5. | |||
The best attack on 3-pass and more Argon2i is <xref target="AB16"></xref> | ||||
with reduction factor being a function of | ||||
memory size and the number of passes. For 1 gibibyte of memory: 3 for 3 | ||||
passes, 2.5 for 4 passes, 2 for 6 passes. The reduction | ||||
factor grows by about 0.5 with every doubling the memory size. | ||||
To completely prevent time-space tradeoffs from <xref target="AB16"></x | ||||
ref>, the | ||||
number of passes MUST exceed binary logarithm of memory minus 26. | ||||
Asymptotically, the best attack on 1-pass Argon2i is given in <xref tar | ||||
get="BZ17"></xref> 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 <xref target="BZ17"></xre | ||||
f> also prove the upper bound on any attack of O(m^(0.25)). | ||||
</t> | ||||
<t>The best tradeoff attack on t-pass Argon2d is the ranking tradeoff atta | The best attack on Argon2i with 3 passes or more is described in <xref tar | |||
ck, | get="AB16" format="default"/>, 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 redu | ||||
ction | ||||
factor grows by about 0.5 with every doubling of the memory size. | ||||
To completely prevent time-space trade-offs from <xref target="AB16" fo | ||||
rmat="default"/>, the | ||||
number of passes <bcp14>MUST</bcp14> exceed the binary logarithm of memory | ||||
minus 26. | ||||
Asymptotically, the best attack on 1-pass Argon2i is given in <xref tar | ||||
get="BZ17" format="default"/>, 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 <xref target="BZ17" format | ||||
="default"/> also proves the upper bound on any attack is O(m^(0.25)). | ||||
</t> | ||||
<t>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. | which reduces the time-area product by the factor of 1.33. | |||
</t> | </t> | |||
<t>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. | ||||
<t>The best attack on Argon2id can be obtained by complementing the bes | Thus, the best trade-off attack on 1-pass Argon2id is the combined low-storage a | |||
t attack | ttack (for the first half of the memory) and | |||
on the 1-pass Argon2i with the best attack on a multi-pass Argon2d. Thu | the ranking attack (for the second half), which generate the factor of | |||
s the best tradeoff attack on 1-pass Argon2id is the combined low-storage attack | about 2.1. The best trade-off attack on | |||
(for the first half of the memory) and | t-pass Argon2id is the ranking trade-off attack, | |||
the ranking attack (for the second half), which bring together the fact | ||||
or of about 2.1. The best tradeoff attack on | ||||
t-pass Argon2id is the ranking tradeoff attack, | ||||
which reduces the time-area product by the factor of 1.33. | which reduces the time-area product by the factor of 1.33. | |||
</t> | </t> | |||
</section> | </section> | |||
<section anchor="security-general" numbered="true" toc="default"> | ||||
<section anchor="security-general" title="Security for time-bounded | <name>Security for Time-Bounded Defenders</name> | |||
defenders"> | <t>A bottleneck in a system employing the password hashing function | |||
<t>A bottleneck in a system employing the password-hashi | ||||
ng function | ||||
is often the function latency rather than memory costs. A rational | is often the function latency rather than memory costs. A rational | |||
defender would then maximize the bruteforce costs for th | defender would then maximize the brute-force costs for t | |||
e attacker equipped | he attacker equipped | |||
with a list of hashes, salts, and timing information, fo | with a list of hashes, salts, and timing information for | |||
r fixed computing time | fixed computing time | |||
on the defender’s machine. The attack cost estimates fr | on the defender's machine. The attack cost estimates fr | |||
om <xref target="AB16"></xref> | om <xref target="AB16" format="default"/> | |||
imply that for Argon2i, 3 passes is almost optimal for t | imply that for Argon2i, 3 passes is almost optimal for m | |||
he most of reasonable memory sizes, | ost reasonable memory sizes; for Argon2d and Argon2id, 1 pass maximizes the atta | |||
and that for Argon2d and Argon2id, 1 pass maximizes the | ck costs for the constant defender time. | |||
attack costs for the constant defender time. | </t> | |||
</t> | </section> | |||
</section> | <section anchor="security-recommend" numbered="true" toc="default"> | |||
<name>Recommendations</name> | ||||
<section anchor="security-recommend" | <t> | |||
title="Recommendations"> | The Argon2id variant with t=1 and 2 GiB memory is the FIRST <bcp14>RECOMMENDED</ | |||
<t> | bcp14> option and is suggested | |||
The Argon2id variant with t=1 and 2GiB memory is FIRST RECOMMENDED option and is | as a default setting for all environments. This setting is secure against side-c | |||
suggested | hannel attacks | |||
as a default setting for all environments. This setting is secure against side- | and maximizes adversarial costs on dedicated brute-force hardware. The Argon2id | |||
channel attacks | variant with t=3 and 64 MiB memory is the SECOND <bcp14>RECOMMENDED</bcp14> opti | |||
and maximizes adversarial costs on dedicated bruteforce hardware. The Argon2id v | on and is suggested | |||
ariant with t=3 and 64 MiB memory is | ||||
SECOND RECOMMENDED option and is suggested | ||||
as a default setting for memory-constrained environments. | as a default setting for memory-constrained environments. | |||
</t> | </t> | |||
</section> | </section> | |||
</section> | </section> | |||
<section anchor="ack" | ||||
title="Acknowledgements"> | ||||
<t>We thank greatly the following authors who helped a lot in preparing an | ||||
d reviewing | ||||
this document: Jean-Philippe Aumasson, | ||||
Samuel Neves, Joel Alwen, Jeremiah Blocki, Bill Cox, Arnold Reinhold, S | ||||
olar Designer, Russ Housley, | ||||
Stanislav Smyshlyaev, Kenny Paterson, Alexey Melnikov, Gwynne Raskind.</t> | ||||
</section> | ||||
</middle> | </middle> | |||
<back> | <back> | |||
<references title="Normative References"> | <displayreference target="RFC7693" to="BLAKE2"/> | |||
<reference anchor="RFC2119" target = "http://www.rfc-editor.org/info/rf | ||||
c2119"> | ||||
<front> | ||||
<title>Key words for use in RFCs to Indicate | ||||
Requirement Levels</title> | ||||
<author surname="Bradner" initials ="S."/> | ||||
<date month="March" year="1997" /> | ||||
</front> | ||||
<seriesInfo name="RFC" value="2119"/> | ||||
</reference> | ||||
<reference anchor="BLAKE2" target="https://www.rfc-editor.org/info/rfc769 | ||||
3"> | ||||
<front> | ||||
<title> | ||||
The BLAKE2 Cryptographic Hash and Message Authentication Code (MAC) | ||||
</title> | ||||
<author initials="M-J." surname="Saarinen" fullname="M-J. Saarinen" role= | ||||
"editor"> | ||||
<organization/> | ||||
</author> | ||||
<author initials="J-P." surname="Aumasson" fullname="J-P. Aumasson"> | ||||
<organization/> | ||||
</author> | ||||
<date year="2015" month="November"/> | ||||
<abstract> | ||||
<t> | ||||
This document describes the cryptographic hash function BLAKE2 and makes | ||||
the algorithm specification and C source code conveniently available to the Inte | ||||
rnet community. BLAKE2 comes in two main flavors: BLAKE2b is optimized for 64-bi | ||||
t platforms and BLAKE2s for smaller architectures. BLAKE2 can be directly keyed, | ||||
making it functionally equivalent to a Message Authentication Code (MAC). | ||||
</t> | ||||
</abstract> | ||||
</front> | ||||
<seriesInfo name="RFC" value="7693"/> | ||||
</reference> | ||||
</references> | ||||
<references title="Informative References"> | ||||
<!-- &RFC4086; --> | <references> | |||
<name>References</name> | ||||
<references> | ||||
<name>Normative References</name> | ||||
<xi:include href="https://xml2rfc.ietf.org/public/rfc/bibxml/reference.R | ||||
FC.2119.xml"/> | ||||
<xi:include href="https://xml2rfc.ietf.org/public/rfc/bibxml/reference.R | ||||
FC.8174.xml"/> | ||||
<xi:include href="https://xml2rfc.ietf.org/public/rfc/bibxml/reference.R | ||||
FC.7693.xml"/> | ||||
</references> | ||||
<references> | ||||
<name>Informative References</name> | ||||
<reference anchor="ARGON2" target = "https://www.cryptolux.org/images/0/0d | <reference anchor="ARGON2" target="https://www.cryptolux.org/images/0/0d/A | |||
/Argon2.pdf"> | rgon2.pdf"> | |||
<front> | <front> | |||
<title>Argon2: the memory-hard function for password hashing | <title>Argon2: the memory-hard function for password hashing | |||
and other applications</title> | and other applications</title> | |||
<author initials="A." surname="Biryukov" fullname="Alex Biryukov"/> | <author initials="A." surname="Biryukov" fullname="Alex Biryukov"/> | |||
<author initials="D." surname="Dinu" fullname="Daniel Dinu"/> | <author initials="D." surname="Dinu" fullname="Daniel Dinu"/> | |||
<author initials="D." surname="Khovratovich" | <author initials="D." surname="Khovratovich" fullname="Dmitry Khovra | |||
fullname="Dmitry Khovratovich"/> | tovich"/> | |||
<date month="October" year="2015" /> | <date month="March" year="2017"/> | |||
</front> | </front> | |||
<seriesInfo name="WWW" | </reference> | |||
value="www.cryptolux.org" /> | ||||
</reference> | ||||
<reference anchor="HARD" target="https://eprint.iacr.org/2014/238.pdf"> | <reference anchor="HARD" target="https://eprint.iacr.org/2014/238.pdf"> | |||
<front> | <front> | |||
<title>High Parallel Complexity Graphs and Memory-Hard Functions</title | <title>High Parallel Complexity Graphs and Memory-Hard Functions</ti | |||
> | tle> | |||
<author initials="J." surname="Alwen" fullname="Joel Alwen"/> | <author initials="J." surname="Alwen" fullname="Joel Alwen"/> | |||
<author initials="V." surname="Serbinenko" fullname="Vladimir Serbinenk | <author initials="V." surname="Serbinenko" fullname="Vladimir Serbin | |||
o"/> | enko"/> | |||
<date year="2014" /> | <date year="2015" month="June"/> | |||
</front> | </front> | |||
<seriesInfo name="STOC" value="2015"/> | <seriesInfo name="DOI" value="10.1145/2746539.2746622"/> | |||
</reference> | <refcontent>STOC '15</refcontent> | |||
</reference> | ||||
<reference anchor="CBS16" target="https://eprint.iacr.org/2016/027.pdf"> | <reference anchor="CBS16" target="https://eprint.iacr.org/2016/027.pdf"> | |||
<front> | <front> | |||
<title>Balloon Hashing: Provably Space-Hard Hash Functions with | <title>Balloon Hashing: A Memory-Hard Function Providing Provable Pr | |||
Data-Independent Access Patterns</title> | otection Against Sequential Attacks</title> | |||
<author initials="H." surname="Corrigan-Gibbs" | <author initials="D." surname="Boneh" fullname="Dan Boneh"/> | |||
fullname="Henry Corrigan-Gibs"/> | <author initials="H." surname="Corrigan-Gibbs" fullname="Henry Corri | |||
<author initials="D." surname="Boneh" fullname="Dan Boneh"/> | gan-Gibbs"/> | |||
<author initials="S." surname="Schechter" fullname="Stuart Schechter"/> | <author initials="S." surname="Schechter" fullname="Stuart Schechter | |||
<date month="January" year="2016" /> | "/> | |||
</front> | <date month="May" year="2017"/> | |||
<seriesInfo name="Asiacrypt" value="2016"/> | </front> | |||
</reference> | <seriesInfo name="DOI" value="10.1007/978-3-662-53887-6_8"/> | |||
<refcontent>ASIACRYPT 2016</refcontent> | ||||
</reference> | ||||
<reference anchor="AB16" target="https://eprint.iacr.org/2016/115.pdf"> | <reference anchor="AB16" target="https://eprint.iacr.org/2016/115.pdf"> | |||
<front> | <front> | |||
<title>Efficiently Computing Data-Independent Memory-Hard Functions</tit | <title>Efficiently Computing Data-Independent Memory-Hard Functions< | |||
le> | /title> | |||
<author initials="J." surname="Alwen" | <author initials="J." surname="Alwen" fullname="Joel Alwen"/> | |||
fullname="Joel Alwen"/> | <author initials="J." surname="Blocki" fullname="Jeremiah Blocki"/> | |||
<author initials="J." surname="Blocki" fullname="Jeremiah Blocki"/> | <date month="March" year="2016"/> | |||
<date month="December" year="2015" /> | </front> | |||
</front> | <seriesInfo name="DOI" value="10.1007/978-3-662-53008-5_9"/> | |||
<seriesInfo name="Crypto" value="2016"/> | <refcontent>CRYPTO 2016</refcontent> | |||
</reference> | </reference> | |||
<reference anchor="BZ17" target="https://eprint.iacr.org/2017/442.pdf"> | <reference anchor="BZ17" target="https://eprint.iacr.org/2017/442.pdf"> | |||
<front> | <front> | |||
<title>On the Depth-Robustness and Cumulative Pebbling Cost of Argon2i</ | <title>On the Depth-Robustness and Cumulative Pebbling Cost of Argon | |||
title> | 2i</title> | |||
<author initials="J." surname="Blocki" | <author initials="J." surname="Blocki" fullname="Jeremiah Blocki"/> | |||
fullname="Jeremiah Blocki"/> | <author initials="S." surname="Zhou" fullname="Samson Zhou"/> | |||
<author initials="S." surname="Zhou" fullname="Samson Zhou"/> | <date month="May" year="2017"/> | |||
<date month="May" year="2017" /> | </front> | |||
</front> | <seriesInfo name="DOI" value="10.1007/978-3-319-70500-2_15"/> | |||
<seriesInfo name="TCC" value="2017"/> | <refcontent>TCC 2017</refcontent> | |||
</reference> | </reference> | |||
<reference anchor="ARGON2ESP" target="https://www.cryptolux.org/imag | <reference anchor="ARGON2ESP" target="https://www.cryptolux.org/images/d | |||
es/d/d0/Argon2ESP.pdf"> | /d0/Argon2ESP.pdf"> | |||
<front> | <front> | |||
<title>Argon2: New Generation of Memory-Hard Functions for Password Has | <title>Argon2: New Generation of Memory-Hard Functions for Password | |||
hing | Hashing | |||
and Other Applications</title> | and Other Applications</title> | |||
<author initials="A." surname="Biryukov" fullname="Alex Biryukov"/> | <author initials="A." surname="Biryukov" fullname="Alex Biryukov"/> | |||
<author initials="D." surname="Dinu" fullname="Daniel Dinu"/> | <author initials="D." surname="Dinu" fullname="Daniel Dinu"/> | |||
<author initials="D." surname="Khovratovich" | <author initials="D." surname="Khovratovich" fullname="Dmitry Khovra | |||
fullname="Dmitry Khovratovich"/> | tovich"/> | |||
<date month="March" year="2016" /> | <date month="March" year="2016"/> | |||
</front> | </front> | |||
<seriesInfo name="Euro SnP" value="2016"/> | <seriesInfo name="DOI" value="10.1109/EuroSP.2016.31"/> | |||
</reference> | <refcontent>Euro SnP 2016</refcontent> | |||
</reference> | ||||
<reference anchor="AB15" target="https://eprint.iacr.org/2015/227.pdf"> | ||||
<front> | ||||
<title>Tradeoff Cryptanalysis of Memory-Hard Functions</title> | ||||
<author initials="A." surname="Biryukov" | ||||
fullname="Alex Biryukov"/> | ||||
<author initials="D." surname="Khovratovich" fullname="Dmitry Khovratovi | ||||
ch"/> | ||||
<date month="December" year="2015" /> | ||||
</front> | ||||
<seriesInfo name="Asiacrypt" value="2015"/> | ||||
</reference> | ||||
<reference anchor="AB15" target="https://eprint.iacr.org/2015/227.pdf"> | ||||
<front> | ||||
<title>Tradeoff Cryptanalysis of Memory-Hard Functions</title> | ||||
<author initials="A." surname="Biryukov" fullname="Alex Biryukov"/> | ||||
<author initials="D." surname="Khovratovich" fullname="Dmitry Khovra | ||||
tovich"/> | ||||
<date month="December" year="2015"/> | ||||
</front> | ||||
<seriesInfo name="DOI" value="10.1007/978-3-662-48800-3_26"/> | ||||
<refcontent>ASIACRYPT 2015</refcontent> | ||||
</reference> | ||||
</references> | ||||
</references> | </references> | |||
<section anchor="ack" numbered="false" toc="default"> | ||||
<name>Acknowledgements</name> | ||||
<t>We greatly thank the following individuals who helped in preparing and | ||||
reviewing | ||||
this document: <contact fullname="Jean-Philippe Aumasson"/>, | ||||
<contact fullname="Samuel Neves"/>, <contact fullname="Joel Alwen"/>, < | ||||
contact fullname="Jeremiah Blocki"/>, <contact fullname="Bill Cox"/>, <contact f | ||||
ullname="Arnold Reinhold"/>, <contact fullname="Solar Designer"/>, <contact full | ||||
name="Russ Housley"/>, | ||||
<contact fullname="Stanislav Smyshlyaev"/>, <contact fullname="Kenny Paters | ||||
on"/>, <contact fullname="Alexey Melnikov"/>, and <contact fullname="Gwynne Rask | ||||
ind"/>.</t> | ||||
<t>The work described in this document was done before <contact fullname="Daniel | ||||
Dinu"/> joined Intel, while he was at the University of Luxembourg.</t> | ||||
</section> | ||||
</back> | </back> | |||
</rfc> | </rfc> | |||
End of changes. 126 change blocks. | ||||
770 lines changed or deleted | 692 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/ |