idnits 2.17.1 draft-irtf-cfrg-argon2-03.txt: Checking boilerplate required by RFC 5378 and the IETF Trust (see https://trustee.ietf.org/license-info): ---------------------------------------------------------------------------- No issues found here. Checking nits according to https://www.ietf.org/id-info/1id-guidelines.txt: ---------------------------------------------------------------------------- No issues found here. Checking nits according to https://www.ietf.org/id-info/checklist : ---------------------------------------------------------------------------- ** The document seems to lack a both a reference to RFC 2119 and the recommended RFC 2119 boilerplate, even if it appears to use RFC 2119 keywords. RFC 2119 keyword, line 123: '... MUST be BLAKE2b....' Miscellaneous warnings: ---------------------------------------------------------------------------- == The copyright year in the IETF Trust and authors Copyright Line does not match the current year -- The document date (August 03, 2017) is 2451 days in the past. Is this intentional? -- Found something which looks like a code comment -- if you have code sections in the document, please surround them with '' and '' lines. Checking references for intended status: Informational ---------------------------------------------------------------------------- -- Looks like a reference, but probably isn't: '0' on line 1429 -- Looks like a reference, but probably isn't: '1' on line 1380 -- Looks like a reference, but probably isn't: '2' on line 1381 -- Looks like a reference, but probably isn't: '3' on line 1382 -- Looks like a reference, but probably isn't: '4' on line 1383 -- Looks like a reference, but probably isn't: '5' on line 1384 -- Looks like a reference, but probably isn't: '32' on line 1836 -- Looks like a reference, but probably isn't: '16' on line 1838 -- Looks like a reference, but probably isn't: '8' on line 1839 -- Looks like a reference, but probably isn't: '12' on line 1840 -- Looks like a reference, but probably isn't: '124' on line 1875 -- Looks like a reference, but probably isn't: '125' on line 1876 -- Looks like a reference, but probably isn't: '126' on line 1877 -- Looks like a reference, but probably isn't: '127' on line 1878 == Unused Reference: 'RFC7693' is defined on line 1962, but no explicit reference was found in the text == Unused Reference: 'AB15' is defined on line 1969, but no explicit reference was found in the text Summary: 1 error (**), 0 flaws (~~), 3 warnings (==), 16 comments (--). Run idnits with the --verbose option for more detailed information about the items above. -------------------------------------------------------------------------------- 2 Network Working Group A. Biryukov 3 Internet-Draft D. Dinu 4 Intended status: Informational D. Khovratovich 5 Expires: February 4, 2018 University of Luxembourg 6 S. Josefsson 7 SJD AB 8 August 03, 2017 10 The memory-hard Argon2 password hash and proof-of-work function 11 draft-irtf-cfrg-argon2-03 13 Abstract 15 This document describes the Argon2 memory-hard function for password 16 hashing and proof-of-work applications. We provide an implementer- 17 oriented description together with sample code and test vectors. The 18 purpose is to simplify adoption of Argon2 for Internet protocols. 20 Status of This Memo 22 This Internet-Draft is submitted in full conformance with the 23 provisions of BCP 78 and BCP 79. 25 Internet-Drafts are working documents of the Internet Engineering 26 Task Force (IETF). Note that other groups may also distribute 27 working documents as Internet-Drafts. The list of current Internet- 28 Drafts is at http://datatracker.ietf.org/drafts/current/. 30 Internet-Drafts are draft documents valid for a maximum of six months 31 and may be updated, replaced, or obsoleted by other documents at any 32 time. It is inappropriate to use Internet-Drafts as reference 33 material or to cite them other than as "work in progress." 35 This Internet-Draft will expire on February 4, 2018. 37 Copyright Notice 39 Copyright (c) 2017 IETF Trust and the persons identified as the 40 document authors. All rights reserved. 42 This document is subject to BCP 78 and the IETF Trust's Legal 43 Provisions Relating to IETF Documents 44 (http://trustee.ietf.org/license-info) in effect on the date of 45 publication of this document. Please review these documents 46 carefully, as they describe your rights and restrictions with respect 47 to this document. Code Components extracted from this document must 48 include Simplified BSD License text as described in Section 4.e of 49 the Trust Legal Provisions and are provided without warranty as 50 described in the Simplified BSD License. 52 Table of Contents 54 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 3 55 2. Notation and Conventions . . . . . . . . . . . . . . . . . . 3 56 3. Argon2 Algorithm . . . . . . . . . . . . . . . . . . . . . . 4 57 3.1. Argon2 Inputs and Outputs . . . . . . . . . . . . . . . . 4 58 3.2. Argon2 Operation . . . . . . . . . . . . . . . . . . . . 5 59 3.3. Variable-length hash function H' . . . . . . . . . . . . 7 60 3.4. Indexing . . . . . . . . . . . . . . . . . . . . . . . . 7 61 3.4.1. Getting the 32-bit values J_1 and J_2 . . . . . . . . 8 62 3.4.2. Mapping J_1 and J_2 to reference block index . . . . 9 63 3.5. Compression function G . . . . . . . . . . . . . . . . . 10 64 3.6. Permutation P . . . . . . . . . . . . . . . . . . . . . . 11 65 4. Parameter Choice . . . . . . . . . . . . . . . . . . . . . . 12 66 5. Example Code . . . . . . . . . . . . . . . . . . . . . . . . 14 67 5.1. argon2.h . . . . . . . . . . . . . . . . . . . . . . . . 14 68 5.2. argon2.c . . . . . . . . . . . . . . . . . . . . . . . . 16 69 5.3. core.h . . . . . . . . . . . . . . . . . . . . . . . . . 18 70 5.4. core.c . . . . . . . . . . . . . . . . . . . . . . . . . 21 71 5.5. ref.c . . . . . . . . . . . . . . . . . . . . . . . . . . 28 72 5.6. main.c . . . . . . . . . . . . . . . . . . . . . . . . . 32 73 5.7. blake2.h . . . . . . . . . . . . . . . . . . . . . . . . 34 74 5.8. blake2.c . . . . . . . . . . . . . . . . . . . . . . . . 34 75 5.9. blake2-impl.h . . . . . . . . . . . . . . . . . . . . . . 36 76 5.10. blamka-round-ref.h . . . . . . . . . . . . . . . . . . . 36 77 6. Test Vectors . . . . . . . . . . . . . . . . . . . . . . . . 37 78 6.1. Argon2d Test Vectors . . . . . . . . . . . . . . . . . . 38 79 6.2. Argon2i Test Vectors . . . . . . . . . . . . . . . . . . 39 80 6.3. Argon2id Test Vectors . . . . . . . . . . . . . . . . . . 40 81 7. Acknowledgements . . . . . . . . . . . . . . . . . . . . . . 41 82 8. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 41 83 9. Security Considerations . . . . . . . . . . . . . . . . . . . 41 84 9.1. Security as hash function and KDF . . . . . . . . . . . . 42 85 9.2. Security against time-space tradeoff attacks . . . . . . 42 86 9.3. Security for time-bounded defenders . . . . . . . . . . . 43 87 9.4. Recommendations . . . . . . . . . . . . . . . . . . . . . 43 88 10. References . . . . . . . . . . . . . . . . . . . . . . . . . 43 89 10.1. Normative References . . . . . . . . . . . . . . . . . . 43 90 10.2. Informative References . . . . . . . . . . . . . . . . . 43 91 Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 44 93 1. Introduction 95 This document describes the Argon2 memory-hard function for password 96 hashing and proof-of-work applications. We provide an implementer 97 oriented description together with sample code and test vectors. The 98 purpose is to simplify adoption of Argon2 for Internet protocols. 99 This document corresponds to version 1.3 of the Argon2 hash function. 101 Argon2 summarizes the state of the art in the design of memory-hard 102 functions. It is a streamlined and simple design. It aims at the 103 highest memory filling rate and effective use of multiple computing 104 units, while still providing defense against tradeoff attacks. 105 Argon2 is optimized for the x86 architecture and exploits the cache 106 and memory organization of the recent Intel and AMD processors. 107 Argon2 has one primary variant: Argon2id, and two supplementary 108 variants: Argon2d and Argon2i. Argon2d uses data-dependent memory 109 access, which makes it suitable for cryptocurrencies and proof-of- 110 work applications with no threats from side-channel timing attacks. 111 Argon2i uses data-independent memory access, which is preferred for 112 password hashing and password-based key derivation. Argon2id works 113 as Argon2i for the first half of the first iteration over the memory, 114 and as Argon2d for the rest, thus providing both side-channel attack 115 protection and brute-force cost savings due to time-memory tradeoffs. 116 Argon2i makes more passes over the memory to protect from tradeoff 117 attacks. 119 Argon2 can be viewed as a mode of operation over a fixed-input-length 120 compression function G and a variable-input-length hash function H. 121 Even though Argon2 can be potentially used with arbitrary function H, 122 as long as it provides outputs up to 64 bytes, in this document it 123 MUST be BLAKE2b. 125 For further background and discussion, see the Argon2 paper 126 [ARGON2ESP] and specifications [ARGON2]. 128 2. Notation and Conventions 130 x^y --- integer x multiplied by itself integer y times 132 a*b --- multiplication of integer a and integer b 134 c-d --- substraction of integer c with integer d 136 E_f --- variable E with subscript index f 138 g / h --- integer g divided by integer h. The result is rational 139 number 140 I(j) --- function I evaluated on integer parameter j 142 K || L --- string K concatenated with string L 144 a XOR b --- bitwise exclusive-or between bitstrings a and b 146 a mod b --- remainder of integer a modulo integer b, always in range 147 [0, b-1] 149 a >>> n --- rotation of 64-bit string a to the right by n bits 151 trunc(a) --- the 64-bit value a truncated to the 32 least significant 152 bits 154 floor(a) --- the largest integer not bigger than a 156 ceil(a) --- the smallest integer not smaller than a 158 extract(a, i) --- the i-th set of 32-bits from bitstring a, starting 159 from 0-th 161 |A| --- the number of elements in set A 163 LE32(a) --- 32-bit integer a converted to bytestring in little 164 endian. Example: 123456 (decimal) is 40 E2 01 00. 166 LE64(a) --- 64-bit integer a converted to bytestring in little 167 endian. Example: 123456 (decimal) is 40 E2 01 00. 169 int32(s) --- 32-bit string s is converted to non-negative integer in 170 little endian. 172 int64(s) --- 64-bit string s is converted to non-negative integer in 173 little endian. 175 length(P) --- the bytelength of string P expressed as 32-bit integer 177 3. Argon2 Algorithm 179 3.1. Argon2 Inputs and Outputs 181 Argon2 has the following input parameters: 183 o Message string P, which is a password for password hashing 184 applications. May have any length from 0 to 2^(32) - 1 bytes. 186 o Nonce S, which is a salt for password hashing applications. May 187 have any length from 8 to 2^(32)-1 bytes. 16 bytes is recommended 188 for password hashing. Salt must be unique for each password. 190 o Degree of parallelism p determines how many independent (but 191 synchronizing) computational chains (lanes) can be run. It may 192 take any integer value from 1 to 2^(24)-1. 194 o Tag length T may be any integer number of bytes from 4 to 2^(32)- 195 1. 197 o Memory size m can be any integer number of kibibytes from 8*p to 198 2^(32)-1. The actual number of blocks is m', which is m rounded 199 down to the nearest multiple of 4*p. 201 o Number of iterations t (used to tune the running time 202 independently of the memory size) can be any integer number from 1 203 to 2^(32)-1. 205 o Version number v is one byte 0x13. 207 o Secret value K (serves as key if necessary, but we do not assume 208 any key use by default) may have any length from 0 to 2^(32)-1 209 bytes. 211 o Associated data X may have any length from 0 to 2^(32)-1 bytes. 213 o Type y of Argon2: 0 for Argon2d, 1 for Argon2i, 2 for Argon2id. 215 The Argon2 output is a string T bytes long. 217 3.2. Argon2 Operation 219 Argon2 uses an internal compression function G with two 1024-byte 220 inputs and a 1024-byte output, and an internal hash function H^x(). 221 Here H^x() applied to string a is the BLAKE2b [RFC7693](a,|a|,0,x) 222 hash function, and the compression function G is based on its 223 internal permutation. A variable-length hash function H' built upon 224 H is also used. G is described in Section Section 3.5 and H' is 225 described in Section Section 3.3. 227 The Argon2 operation is as follows. 229 1. Establish H_0 as the 64-bit value as shown below. 231 H_0 = H^(64)(LE32(p), LE32(T), LE32(m), LE32(t), LE32(v), 232 LE32(y), LE32(length(P)), P, LE32(length(S)), S, 233 LE32(length(K)), K, LE32(length(X)), X) 235 H_0 generation 237 2. Allocate the memory as m' 1024-byte blocks where m' is derived 238 as: 240 m' = 4 * p * floor (m / 4p) 242 Memory allocation 244 For p lanes, the memory is organized in a matrix B[i][j] of 245 blocks with p rows (lanes) and q = m' / p columns. 247 3. Compute B[i][0] for all i ranging from (and including) 0 to (not 248 including) p. 250 B[i][0] = H'(H_0 || LE32(0) || LE32(i)) 252 Lane starting blocks 254 4. Compute B[i][1] for all i ranging from (and including) 0 to (not 255 including) p. 257 B[i][1] = H'(H_0 || LE32(1) || LE32(i)) 259 Second lane blocks 261 5. Compute B[i][j] for all i ranging from (and including) 0 to (not 262 including) p, and for all j ranging from (and including) 2) to 263 (not including) q. The block indices i' and j' are determined 264 for each i, j differently for Argon2d, Argon2i, and Argon2id 265 (Section Section 3.4). 267 B[i][j] = G(B[i][j-1], B[i'][j']) 269 Further block generation 271 6. If the number of iterations t is larger than 1, we repeat the 272 steps however replacing the computations with the following 273 expression: 275 B[i][0] = G(B[i][q-1], B[i'][j']) 276 B[i][j] = G(B[i][j-1], B[i'][j']) 278 Further passes 280 7. After t steps have been iterated, the final block C is computed 281 as the XOR of the last column: 283 C = B[0][q-1] XOR B[1][q-1] XOR ... XOR B[p-1][q-1] 285 Final block 287 8. The output tag is computed as H'(C). 289 3.3. Variable-length hash function H' 291 Recall that H^x(a) is BLAKE2b(a,|a|,0,x). Let V_i be a 64-byte 292 block, and A_i be its first 32 bytes. Then we define: 294 if T <= 64 295 H'(X) = H^T(T||X) 296 else 297 r = ceil(T/32)-2 298 V_1 = H^(64)(LE32(T)||X) 299 V_2 = H^(64)(V_1) 300 ... 301 V_r = H^(64)(V_{r-1}) 302 V_{r+1} = H^(T-32*r)(V_{r}) 303 H'(X) = A_1 || A_2 || ... || A_r || V_{r+1} 305 Tag computation 307 3.4. Indexing 309 To enable parallel block computation, we further partition the memory 310 matrix into S = 4 vertical slices. The intersection of a slice and a 311 lane is a segment of length q/S. Segments of the same slice are 312 computed in parallel and may not reference blocks from each other. 313 All other blocks can be referenced. 315 slice 0 slice 1 slice 2 slice 3 316 ___/\___ ___/\___ ___/\___ ___/\___ 317 / \ / \ / \ / \ 318 +----------+----------+----------+----------+ 319 | | | | | > lane 0 320 +----------+----------+----------+----------+ 321 | | | | | > lane 1 322 +----------+----------+----------+----------+ 323 | | | | | > lane 2 324 +----------+----------+----------+----------+ 325 | ... ... ... | ... 326 +----------+----------+----------+----------+ 327 | | | | | > lane p - 1 328 +----------+----------+----------+----------+ 330 Single-pass Argon2 with p lanes and 4 slices 332 3.4.1. Getting the 32-bit values J_1 and J_2 334 3.4.1.1. Argon2d 336 J_1 is given by the first 32 bits of block B[i][j-1], while J_2 is 337 given by the next 32-bits of block B[i][j-1]: 339 J_1 = int32(extract(B[i][j-1], 1)) 340 J_2 = int32(extract(B[i][j-1], 2)) 342 Deriving J1,J2 in Argon2d 344 3.4.1.2. Argon2i 346 Each application of the 2-round compression function G in the counter 347 mode gives 128 64-bit values X, which are viewed as X1||X2 and 348 converted to J_1=int32(X1) and J_2=int32(X2). The first input to G 349 is the all zero block and the second input to G is constructed as 350 follows: 352 ( LE64(r) || LE64(l) || LE64(s) || LE64(m') || LE64(t) || 353 LE64(y) || LE64(i) || ZERO ), where 355 r -- the pass number 356 l -- the lane number 357 s -- the slice number 358 m' -- the total number of memory blocks 359 t -- the total number of passes 360 y -- the Argon2 type: 361 - 0 for Argon2d 362 - 1 for Argon2i 363 - 2 for Argon2id 364 i -- the counter (starts from 1 in each segment) 365 ZERO -- the 968-byte zero string. 367 Input to compute J1,J2 in Argon2i 369 The values r, l, s, m', t, x, i are represented on 8 bytes in little- 370 endian. 372 3.4.1.3. Argon2id 374 If the pass number is 0 and the slice number is 0 or 1, then compute 375 J_1 and J_2 as for Argon2i, else compute J_1 and J_2 as for Argon2d. 377 3.4.2. Mapping J_1 and J_2 to reference block index 379 The value of l = J_2 mod p gives the index of the lane from which the 380 block will be taken. For the firt pass (r=0) and the first slice 381 (s=0) the block is taken from the current lane. 383 The set W contains the indices that can be referenced according to 384 the following rules: 386 1. If l is the current lane, then W includes the indices of all 387 blocks in the last S - 1 = 3 segments computed and finished, as 388 well as the blocks computed in the current segment in the current 389 pass excluding B[i][j-1]. 391 2. If l is not the current lane, then W includes the indices of all 392 blocks in the last S - 1 = 3 segments computed and finished in 393 lane l. If B[i][j] is the first block of a segment, then the 394 very last index from W is excluded. 396 We are going to take a block from W with a non-uniform distribution 397 over [0, |W|) using the mapping 398 J_1 -> |W|(1 - J_1^2 / 2^(64)) 400 Computing J1 402 To avoid floating point computation, the following approximation is 403 used: 405 x = J_1^2 / 2^(32) 406 y = (|W| * x) / 2^(32) 407 z = |W| - 1 - y 409 Computing J1, part 2 411 The value of z gives the reference block index in W. 413 3.5. Compression function G 415 Compression function G is built upon the BLAKE2b round function P. P 416 operates on the 128-byte input, which can be viewed as 8 16-byte 417 registers: 419 P(A_0, A_1, ... ,A_7) = (B_0, B_1, ... ,B_7) 421 Blake round function P 423 Compression function G(X, Y) operates on two 1024-byte blocks X and 424 Y. It first computes R = X XOR Y. Then R is viewed as a 8x8 matrix 425 of 16-byte registers R_0, R_1, ... , R_63. Then P is first applied 426 to each row, and then to each column to get Z: 428 ( Q_0, Q_1, Q_2, ... , Q_7) <- P( R_0, R_1, R_2, ... , R_7) 429 ( Q_8, Q_9, Q_10, ... , Q_15) <- P( R_8, R_9, R_10, ... , R_15) 430 ... 431 (Q_56, Q_57, Q_58, ... , Q_63) <- P(R_56, R_57, R_58, ... , R_63) 432 ( Z_0, Z_8, Z_16, ... , Z_56) <- P( Q_0, Q_8, Q_16, ... , Q_56) 433 ( Z_1, Z_9, Z_17, ... , Z_57) <- P( Q_1, Q_9, Q_17, ... , Q_57) 434 ... 435 ( Z_7, Z_15, Z 23, ... , Z_63) <- P( Q_7, Q_15, Q_23, ... , Q_63) 437 Core of compression function G 439 Finally, G outputs Z XOR R: 441 G: (X, Y) -> R -> Q -> Z -> Z XOR R 442 +---+ +---+ 443 | X | | Y | 444 +---+ +---+ 445 | | 446 ---->XOR<---- 447 --------| 448 | \ / 449 | +---+ 450 | | R | 451 | +---+ 452 | | 453 | \ / 454 | P rowwise 455 | | 456 | \ / 457 | +---+ 458 | | Q | 459 | +---+ 460 | | 461 | \ / 462 | P columnwise 463 | | 464 | \ / 465 | +---+ 466 | | Z | 467 | +---+ 468 | | 469 | \ / 470 ------>XOR 471 | 472 \ / 474 Argon2 compression function G. 476 3.6. Permutation P 478 Permutation P is based on the round function of BLAKE2b. The 8 479 16-byte inputs S_0, S_1, ... , S_7 are viewed as a 4x4 matrix of 480 64-bit words, where S_i = (v_{2*i+1} || v_{2*i}): 482 v_0 v_1 v_2 v_3 483 v_4 v_5 v_6 v_7 484 v_8 v_9 v_10 v_11 485 v_12 v_13 v_14 v_15 487 Matrix element labeling 489 It works as follows: 491 GB(v_0, v_4, v_8, v_12) 492 GB(v_1, v_5, v_9, v_13) 493 GB(v_2, v_6, v_10, v_14) 494 GB(v_3, v_7, v_11, v_15) 496 GB(v_0, v_5, v_10, v_15) 497 GB(v_1, v_6, v_11, v_12) 498 GB(v_2, v_7, v_8, v_13) 499 GB(v_3, v_4, v_9, v_14) 501 Feeding matrix elements to GB 503 GB(a, b, c, d) is defined as follows: 505 a = (a + b + 2 * trunc(a) * trunc(b)) mod 2^(64) 506 d = (d XOR a) >>> 32 507 c = (c + d + 2 * trunc(c) * trunc(d)) mod 2^(64) 508 b = (b XOR c) >>> 24 510 a = (a + b + 2 * trunc(a) * trunc(b)) mod 2^(64) 511 d = (d XOR a) >>> 16 512 c = (c + d + 2 * trunc(c) * trunc(d)) mod 2^(64) 513 b = (b XOR c) >>> 63 515 Details of GB 517 The modular additions in GB are combined with 64-bit multiplications. 518 Multiplications are the only difference to the original BLAKE2b 519 design. This choice is done to increase the circuit depth and thus 520 the running time of ASIC implementations, while having roughly the 521 same running time on CPUs thanks to parallelism and pipelining. 523 4. Parameter Choice 525 Argon2d is optimized for settings where the adversary does not get 526 regular access to system memory or CPU, i.e. he can not run side- 527 channel attacks based on the timing information, nor he can recover 528 the password much faster using garbage collection. These settings 529 are more typical for backend servers and cryptocurrency minings. For 530 practice we suggest the following settings: 532 o Cryptocurrency mining, that takes 0.1 seconds on a 2 Ghz CPU using 533 1 core -- Argon2d with 2 lanes and 250 MB of RAM. 535 Argon2id is optimized for more realistic settings, where the 536 adversary possibly can access the same machine, use its CPU or mount 537 cold-boot attacks. We suggest the following settings: 539 o Backend server authentication, that takes 0.5 seconds on a 2 GHz 540 CPU using 4 cores -- Argon2id with 8 lanes and 4 GiB of RAM. 542 o Key derivation for hard-drive encryption, that takes 3 seconds on 543 a 2 GHz CPU using 2 cores - Argon2id with 4 lanes and 6 GiB of 544 RAM. 546 o Frontend server authentication, that takes 0.5 seconds on a 2 GHz 547 CPU using 2 cores - Argon2id with 4 lanes and 1 GiB of RAM. 549 We recommend the following procedure to select the type and the 550 parameters for practical use of Argon2. 552 1. Select the type y. If you do not know the difference between 553 them or you consider side-channel attacks as viable threat, 554 choose Argon2id. 556 2. Figure out the maximum number h of threads that can be initiated 557 by each call to Argon2. 559 3. Figure out the maximum amount m of memory that each call can 560 afford. 562 4. Figure out the maximum amount x of time (in seconds) that each 563 call can afford. 565 5. Select the salt length. 128 bits is sufficient for all 566 applications, but can be reduced to 64 bits in the case of space 567 constraints. 569 6. Select the tag length. 128 bits is sufficient for most 570 applications, including key derivation. If longer keys are 571 needed, select longer tags. 573 7. If side-channel attacks is a viable threat, enable the memory 574 wiping option in the library call. 576 8. Run the scheme of type y, memory m and h lanes and threads, using 577 different number of passes t. Figure out the maximum t such that 578 the running time does not exceed x. If it exceeds x even for t = 579 1, reduce m accordingly. 581 9. Hash all the passwords with the just determined values m, h, and 582 t. 584 5. Example Code 586 5.1. argon2.h 588 This example code is a compact reference implementation of Argon2. 589 Features such as input validation or secure memory wiping are not 590 included in this code. It does not include the BLAKE2b 591 implementation, but only the code that has to be added to the 592 official BLAKE2b implementation in oreder to support Argon2. A 593 complete implementation can be found in the official Argon2 594 repository [ARGON2GITHUB]. 596 #ifndef ARGON2_H 597 #define ARGON2_H 599 #include 600 #include 601 #include 603 /* Number of synchronization points between lanes */ 604 #define ARGON2_SYNC_POINTS UINT32_C(4) 606 /* Return codes */ 607 #define ARGON2_OK 0 608 #define ARGON2_ERROR -1 610 /* Argon2 internal structure holds Argon2 inputs */ 611 typedef struct Argon2_Context { 612 uint8_t *out; /* output array */ 613 uint32_t outlen; /* digest length */ 615 uint8_t *pwd; /* password array */ 616 uint32_t pwdlen; /* password length */ 618 uint8_t *salt; /* salt array */ 619 uint32_t saltlen; /* salt length */ 621 uint8_t *secret; /* key array */ 622 uint32_t secretlen; /* key length */ 624 uint8_t *ad; /* associated data array */ 625 uint32_t adlen; /* associated data length */ 627 uint32_t t_cost; /* number of passes */ 628 uint32_t m_cost; /* amount of memory requested (KB) */ 629 uint32_t lanes; /* number of lanes */ 630 uint32_t threads; /* maximum number of threads */ 631 uint32_t version; /* version number */ 632 } argon2_context; 634 /* Argon2 primitive type */ 635 typedef enum Argon2_type { 636 Argon2_d = 0, 637 Argon2_i = 1, 638 Argon2_id = 2 639 } argon2_type; 641 /* Version of the algorithm */ 642 typedef enum Argon2_version { 643 ARGON2_VERSION_10 = 0x10, 644 ARGON2_VERSION_13 = 0x13, 645 ARGON2_VERSION_NUMBER = ARGON2_VERSION_13 646 } argon2_version; 648 /* 649 * Function that performs memory-hard hashing with certain degree of 650 * parallelism 651 * @param context Pointer to the Argon2 internal structure 652 * @param type Argon2 primitive type 653 * @return ARGON2_OK if successful, ARGON2_ERROR otherwise 654 */ 655 int argon2_ctx(argon2_context *context, argon2_type type); 657 /** 658 * Hashes a password with Argon2, producing a raw hash at @hash 659 * @param t_cost Number of iterations 660 * @param m_cost Sets memory usage to m_cost kibibytes 661 * @param parallelism Number of threads and compute lanes 662 * @param pwd Pointer to password 663 * @param pwdlen Password size in bytes 664 * @param salt Pointer to salt 665 * @param saltlen Salt size in bytes 666 * @param hash Buffer where to write the raw hash - updated by the 667 * function 668 * @param hashlen Desired length of the hash in bytes 669 * @param type Argon2 primitive type 670 * @param version Version of the algorithm 671 * @pre Different parallelism levels will give different results 672 * @return ARGON2_OK if successful, ARGON2_ERROR otherwise 673 */ 674 int argon2_hash(const uint32_t t_cost, const uint32_t m_cost, 675 const uint32_t parallelism, const void *pwd, 676 const size_t pwdlen, const void *salt, 677 const size_t saltlen, void *hash, const size_t hashlen, 678 argon2_type type, const uint32_t version); 680 #endif 682 5.2. argon2.c 684 #include 685 #include 686 #include 688 #include "argon2.h" 689 #include "core.h" 691 int argon2_ctx(argon2_context *context, argon2_type type) { 692 int result; 693 uint32_t memory_blocks, segment_length; 694 argon2_instance_t instance; 696 /* Minimum memory_blocks = 8L blocks, where L is the number of 697 lanes */ 698 memory_blocks = context->m_cost; 699 if (memory_blocks < 2 * ARGON2_SYNC_POINTS * context->lanes) { 700 memory_blocks = 2 * ARGON2_SYNC_POINTS * context->lanes; 701 } 703 /* Ensure that all segments have equal length */ 704 segment_length = memory_blocks / (context->lanes * 705 ARGON2_SYNC_POINTS); 706 memory_blocks = segment_length * (context->lanes * 707 ARGON2_SYNC_POINTS); 709 instance.version = context->version; 710 instance.memory = NULL; 711 instance.passes = context->t_cost; 712 instance.memory_blocks = memory_blocks; 713 instance.segment_length = segment_length; 714 instance.lane_length = segment_length * ARGON2_SYNC_POINTS; 715 instance.lanes = context->lanes; 716 instance.threads = context->threads; 717 instance.type = type; 719 if (instance.threads > instance.lanes) { 720 instance.threads = instance.lanes; 721 } 723 /* Initialization: hash inputs, allocate memory, fill first 724 blocks */ 725 result = initialize(&instance, context); 726 if (ARGON2_OK != result) { 727 return result; 729 } 731 /* Fill memory */ 732 result = fill_memory_blocks(&instance); 733 if (ARGON2_OK != result) { 734 return result; 735 } 737 /* Finalization */ 738 finalize(context, &instance); 740 return ARGON2_OK; 741 } 743 int argon2_hash(const uint32_t t_cost, const uint32_t m_cost, 744 const uint32_t parallelism, const void *pwd, 745 const size_t pwdlen, const void *salt, 746 const size_t saltlen, void *hash, const size_t hashlen, 747 argon2_type type, const uint32_t version) { 748 argon2_context context; 749 int result; 750 uint8_t *out; 752 out = malloc(hashlen); 753 if (!out) { 754 return ARGON2_ERROR; 755 } 757 context.out = (uint8_t *)out; 758 context.outlen = (uint32_t)hashlen; 759 context.pwd = CONST_CAST(uint8_t *)pwd; 760 context.pwdlen = (uint32_t)pwdlen; 761 context.salt = CONST_CAST(uint8_t *)salt; 762 context.saltlen = (uint32_t)saltlen; 763 context.secret = NULL; 764 context.secretlen = 0; 765 context.ad = NULL; 766 context.adlen = 0; 767 context.t_cost = t_cost; 768 context.m_cost = m_cost; 769 context.lanes = parallelism; 770 context.threads = parallelism; 771 context.version = version; 773 result = argon2_ctx(&context, type); 774 if (result != ARGON2_OK) { 775 free(out); 776 return result; 778 } 780 memcpy(hash, out, hashlen); 781 free(out); 783 return ARGON2_OK; 784 } 786 5.3. core.h 788 #ifndef ARGON2_CORE_H 789 #define ARGON2_CORE_H 791 #include "argon2.h" 793 #define CONST_CAST(x) (x)(uintptr_t) 795 /* Argon2 internal constants */ 797 enum argon2_core_constants { 798 /* Memory block size in bytes */ 799 ARGON2_BLOCK_SIZE = 1024, 800 ARGON2_QWORDS_IN_BLOCK = ARGON2_BLOCK_SIZE / 8, 801 ARGON2_OWORDS_IN_BLOCK = ARGON2_BLOCK_SIZE / 16, 802 ARGON2_HWORDS_IN_BLOCK = ARGON2_BLOCK_SIZE / 32, 804 /* Number of pseudo-random values generated by one call to Blake in 805 Argon2i to generate reference block positions */ 806 ARGON2_ADDRESSES_IN_BLOCK = 128, 808 /* Pre-hashing digest length and its extension*/ 809 ARGON2_PREHASH_DIGEST_LENGTH = 64, 810 ARGON2_PREHASH_SEED_LENGTH = 72 811 }; 813 /* Argon2 internal data types */ 814 /* Structure for the (1KB) memory block implemented as 128 64-bit 815 words */ 816 typedef struct block_ { uint64_t v[ARGON2_QWORDS_IN_BLOCK]; } block; 818 /* Functions that work with the block */ 819 /* Initialize each byte of the block with @in */ 820 void init_block_value(block *b, uint8_t in); 822 /* Copy block @src to block @dst */ 823 void copy_block(block *dst, const block *src); 825 /* XOR @src onto @dst bytewise */ 826 void xor_block(block *dst, const block *src); 828 /* 829 * Argon2 instance: memory pointer, number of passes, amount of memory, 830 * type, and derived values. Used to evaluate the number and location of 831 * blocks to construct in each thread. 832 */ 833 typedef struct Argon2_instance_t { 834 block *memory; /* Memory pointer */ 835 uint32_t version; 836 uint32_t passes; /* Number of passes */ 837 uint32_t memory_blocks; /* Number of blocks in memory */ 838 uint32_t segment_length; 839 uint32_t lane_length; 840 uint32_t lanes; 841 uint32_t threads; 842 argon2_type type; 843 argon2_context *context_ptr; /* Points back to original context */ 844 } argon2_instance_t; 846 /* 847 * Argon2 position: where we construct the block right now. Used to 848 * distribute work between threads. 849 */ 850 typedef struct Argon2_position_t { 851 uint32_t pass; 852 uint32_t lane; 853 uint8_t slice; 854 uint32_t index; 855 } argon2_position_t; 857 /* Struct that holds the inputs for thread handling FillSegment */ 858 typedef struct Argon2_thread_data { 859 argon2_instance_t *instance_ptr; 860 argon2_position_t pos; 861 } argon2_thread_data; 863 /* Argon2 core functions */ 865 /* Allocates memory to the given pointer. Total allocated memory is 866 * @num * @size 867 * @param memory pointer to the pointer to the memory 868 * @param size the size in bytes for each element to be allocated 869 * @param num the number of elements to be allocated 870 * @return ARGON2_OK if @memory is a valid pointer and memory is 871 * allocated 872 */ 873 int allocate_memory(uint8_t **memory, size_t num, size_t size); 874 /* 875 * Frees memory at the given pointer. 876 * @param memory pointer to buffer to be freed 877 */ 878 void free_memory(uint8_t *memory); 880 /* 881 * Computes absolute position of reference block in the lane following a 882 * skewed distribution and using a pseudo-random value as input 883 * @param instance Pointer to the current instance 884 * @param position Pointer to the current position 885 * @param pseudo_rand 32-bit pseudo-random value used to determine the 886 * position 887 * @param same_lane Indicates if the block will be taken from the 888 * current lane. 889 * If so we can reference the current segment 890 * @pre All pointers must be valid 891 */ 892 uint32_t index_alpha(const argon2_instance_t *instance, 893 const argon2_position_t *position, 894 uint32_t pseudo_rand, int same_lane); 896 /* 897 * Hashes all the inputs into @blockhash[PREHASH_DIGEST_LENGTH] 898 * @param blockhash Buffer for pre-hashing digest 899 * @param context Pointer to the Argon2 internal structure containing 900 * memory pointer, and parameters for time and space requirements 901 * @param type Argon2 type 902 * @pre @blockhash must have at least @PREHASH_DIGEST_LENGTH bytes 903 * allocated 904 */ 905 void initial_hash(uint8_t *blockhash, argon2_context *context, 906 argon2_type type); 908 /* 909 * Creates first 2 blocks per lane 910 * @param blockhash Pointer to the pre-hashing digest 911 * @param instance Pointer to the current instance 912 * @pre @blockhash must point to @PREHASH_SEED_LENGTH allocated values 913 */ 914 void fill_first_blocks(uint8_t *blockhash, 915 const argon2_instance_t *instance); 917 /* 918 * Function allocates memory, hashes the inputs with Blake, and creates 919 * first two blocks. Returns the pointer to the main memory with 920 * 2 blocks per lane initialized 921 * @param instance Current Argon2 instance 922 * @param context Pointer to the Argon2 internal structure containing 923 * memory pointer, and parameters for time and space requirements 924 * @return ARGON2_OK if successful, ARGON2_ERROR if memory failed to 925 * allocate. 926 * @context->state will be modified if successful 927 */ 928 int initialize(argon2_instance_t *instance, argon2_context *context); 930 /* 931 * XORing the last block of each lane, hashing it, making the tag. 932 * Deallocates the memory. 933 * @param context Pointer to current Argon2 context (use only the out 934 * parameters from it) 935 * @param instance Pointer to current instance of Argon2 936 * @pre instance->state must point to necessary amount of memory 937 * @pre context->out must point to outlen bytes of memory 938 */ 939 void finalize(const argon2_context *context, 940 argon2_instance_t *instance); 942 /* 943 * Function that fills the segment using previous segments also from 944 * other threads 945 * @param instance Pointer to the current instance 946 * @param position Current position 947 * @pre all block pointers must be valid 948 */ 949 void fill_segment(const argon2_instance_t *instance, 950 argon2_position_t position); 952 /* 953 * Function that fills the entire memory t_cost times based on the first 954 * 2 blocks in each lane 955 * @param instance Pointer to the current instance 956 * @return ARGON2_OK if successful, ARGON2_ERROR otherwise 957 */ 958 int fill_memory_blocks(argon2_instance_t *instance); 960 #endif 962 5.4. core.c 964 #include 965 #include 966 #include 967 #include 969 #include "core.h" 970 #include "blake2/blake2.h" 971 #include "blake2/blake2-impl.h" 973 /* Instance and position constructors */ 974 void init_block_value(block *b, uint8_t in) { 975 memset(b->v, in, sizeof(b->v)); 976 } 978 void copy_block(block *dst, const block *src) { 979 memcpy(dst->v, src->v, sizeof(uint64_t) * ARGON2_QWORDS_IN_BLOCK); 980 } 982 void xor_block(block *dst, const block *src) { 983 int i; 984 for (i = 0; i < ARGON2_QWORDS_IN_BLOCK; ++i) { 985 dst->v[i] ^= src->v[i]; 986 } 987 } 989 static void load_block(block *dst, const void *input) { 990 unsigned i; 991 for (i = 0; i < ARGON2_QWORDS_IN_BLOCK; ++i) { 992 dst->v[i] = load64((const uint8_t *)input + 993 i * sizeof(dst->v[i])); 994 } 995 } 997 static void store_block(void *output, const block *src) { 998 unsigned i; 999 for (i = 0; i < ARGON2_QWORDS_IN_BLOCK; ++i) { 1000 store64((uint8_t *)output + i * sizeof(src->v[i]), src->v[i]); 1001 } 1002 } 1004 /* Memory functions */ 1005 int allocate_memory(uint8_t **memory, size_t num, size_t size) { 1006 size_t memory_size = num * size; 1007 if (memory == NULL) { 1008 return ARGON2_ERROR; 1009 } 1011 /* Check for multiplication overflow */ 1012 if (size != 0 && memory_size / size != num) { 1013 return ARGON2_ERROR; 1014 } 1016 /* Try to allocate with appropriate allocator */ 1017 *memory = malloc(memory_size); 1018 if (*memory == NULL) { 1019 return ARGON2_ERROR; 1020 } 1022 return ARGON2_OK; 1023 } 1025 void free_memory(uint8_t *memory) { 1026 free(memory); 1027 } 1029 void finalize(const argon2_context *context, 1030 argon2_instance_t *instance) { 1031 if (context != NULL && instance != NULL) { 1032 block blockhash; 1033 uint32_t l; 1035 copy_block(&blockhash, 1036 instance->memory + instance->lane_length - 1); 1038 /* XOR the last blocks */ 1039 for (l = 1; l < instance->lanes; ++l) { 1040 uint32_t last_block_in_lane = 1041 l * instance->lane_length + (instance->lane_length - 1); 1042 xor_block(&blockhash, 1043 instance->memory + last_block_in_lane); 1044 } 1046 /* Hash the result */ 1047 { 1048 uint8_t blockhash_bytes[ARGON2_BLOCK_SIZE]; 1049 store_block(blockhash_bytes, &blockhash); 1050 blake2b_long(context->out, context->outlen, blockhash_bytes, 1051 ARGON2_BLOCK_SIZE); 1052 /* clear blockhash and blockhash_bytes */ 1053 memset(blockhash.v, 0, ARGON2_BLOCK_SIZE); 1054 memset(blockhash_bytes, 0, ARGON2_BLOCK_SIZE); 1055 } 1057 free_memory((uint8_t *)instance->memory); 1058 } 1059 } 1061 uint32_t index_alpha(const argon2_instance_t *instance, 1062 const argon2_position_t *position, 1063 uint32_t pseudo_rand, int same_lane) { 1064 /* 1065 * Pass 0: 1067 * This lane : all already finished segments plus already 1068 * constructed blocks in this segment 1069 * Other lanes : all already finished segments 1070 * Pass 1+: 1071 * This lane : (SYNC_POINTS - 1) last segments plus already 1072 * constructed blocks in this segment 1073 * Other lanes : (SYNC_POINTS - 1) last segments 1074 */ 1075 uint32_t reference_area_size; 1076 uint64_t relative_position; 1077 uint32_t start_position, absolute_position; 1079 if (0 == position->pass) { 1080 /* First pass */ 1081 if (0 == position->slice) { 1082 /* First slice */ 1083 reference_area_size = 1084 position->index - 1; /* all but the previous */ 1085 } else { 1086 if (same_lane) { 1087 /* The same lane => add current segment */ 1088 reference_area_size = 1089 position->slice * instance->segment_length + 1090 position->index - 1; 1091 } else { 1092 reference_area_size = 1093 position->slice * instance->segment_length + 1094 ((position->index == 0) ? (-1) : 0); 1095 } 1096 } 1097 } else { 1098 /* Second pass */ 1099 if (same_lane) { 1100 reference_area_size = instance->lane_length - 1101 instance->segment_length + 1102 position->index - 1; 1103 } else { 1104 reference_area_size = instance->lane_length - 1105 instance->segment_length + 1106 ((position->index == 0) ? (-1) : 0); 1107 } 1108 } 1110 /* 1.2.4. Mapping pseudo_rand to 0.. and 1111 * produce relative position */ 1112 relative_position = pseudo_rand; 1113 relative_position = relative_position * relative_position >> 32; 1114 relative_position = reference_area_size - 1 - 1115 (reference_area_size * relative_position >> 32); 1117 /* 1.2.5 Computing starting position */ 1118 start_position = 0; 1120 if (0 != position->pass) { 1121 start_position = (position->slice == ARGON2_SYNC_POINTS - 1) 1122 ? 0 1123 : (position->slice + 1) * 1124 instance->segment_length; 1125 } 1127 /* 1.2.6. Computing absolute position */ 1128 absolute_position = (start_position + relative_position) % 1129 instance->lane_length; /* absolute position */ 1130 return absolute_position; 1131 } 1133 /* Single-threaded version for p=1 case */ 1134 static int fill_memory_blocks_st(argon2_instance_t *instance) { 1135 uint32_t r, s, l; 1137 for (r = 0; r < instance->passes; ++r) { 1138 for (s = 0; s < ARGON2_SYNC_POINTS; ++s) { 1139 for (l = 0; l < instance->lanes; ++l) { 1140 argon2_position_t position = {r, l, (uint8_t)s, 0}; 1141 fill_segment(instance, position); 1142 } 1143 } 1144 } 1145 return ARGON2_OK; 1146 } 1148 int fill_memory_blocks(argon2_instance_t *instance) { 1149 if (instance == NULL || instance->lanes == 0) { 1150 return ARGON2_ERROR; 1151 } 1153 return fill_memory_blocks_st(instance); 1154 } 1156 void fill_first_blocks(uint8_t *blockhash, 1157 const argon2_instance_t *instance) { 1158 uint32_t l; 1159 /* Make the first and second block in each lane as G(H0||0||i) or 1160 G(H0||1||i) */ 1161 uint8_t blockhash_bytes[ARGON2_BLOCK_SIZE]; 1162 for (l = 0; l < instance->lanes; ++l) { 1163 store32(blockhash + ARGON2_PREHASH_DIGEST_LENGTH, 0); 1164 store32(blockhash + ARGON2_PREHASH_DIGEST_LENGTH + 4, l); 1165 blake2b_long(blockhash_bytes, ARGON2_BLOCK_SIZE, blockhash, 1166 ARGON2_PREHASH_SEED_LENGTH); 1167 load_block(&instance->memory[l * instance->lane_length + 0], 1168 blockhash_bytes); 1170 store32(blockhash + ARGON2_PREHASH_DIGEST_LENGTH, 1); 1171 blake2b_long(blockhash_bytes, ARGON2_BLOCK_SIZE, blockhash, 1172 ARGON2_PREHASH_SEED_LENGTH); 1173 load_block(&instance->memory[l * instance->lane_length + 1], 1174 blockhash_bytes); 1175 } 1176 memset(blockhash_bytes, 0, ARGON2_BLOCK_SIZE); 1177 } 1179 void initial_hash(uint8_t *blockhash, argon2_context *context, 1180 argon2_type type) { 1181 blake2b_state BlakeHash; 1182 uint8_t value[sizeof(uint32_t)]; 1184 if (NULL == context || NULL == blockhash) { 1185 return; 1186 } 1188 blake2b_init(&BlakeHash, ARGON2_PREHASH_DIGEST_LENGTH); 1190 store32(&value, context->lanes); 1191 blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value)); 1193 store32(&value, context->outlen); 1194 blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value)); 1196 store32(&value, context->m_cost); 1197 blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value)); 1199 store32(&value, context->t_cost); 1200 blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value)); 1202 store32(&value, context->version); 1203 blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value)); 1205 store32(&value, (uint32_t)type); 1206 blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value)); 1208 store32(&value, context->pwdlen); 1209 blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value)); 1210 if (context->pwd != NULL) { 1211 blake2b_update(&BlakeHash, (const uint8_t *)context->pwd, 1212 context->pwdlen); 1213 } 1215 store32(&value, context->saltlen); 1216 blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value)); 1218 if (context->salt != NULL) { 1219 blake2b_update(&BlakeHash, (const uint8_t *)context->salt, 1220 context->saltlen); 1221 } 1223 store32(&value, context->secretlen); 1224 blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value)); 1226 if (context->secret != NULL) { 1227 blake2b_update(&BlakeHash, (const uint8_t *)context->secret, 1228 context->secretlen); 1229 } 1231 store32(&value, context->adlen); 1232 blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value)); 1234 if (context->ad != NULL) { 1235 blake2b_update(&BlakeHash, (const uint8_t *)context->ad, 1236 context->adlen); 1237 } 1239 blake2b_final(&BlakeHash, blockhash, ARGON2_PREHASH_DIGEST_LENGTH); 1240 } 1242 int initialize(argon2_instance_t *instance, argon2_context *context) { 1243 uint8_t blockhash[ARGON2_PREHASH_SEED_LENGTH]; 1244 int result = ARGON2_OK; 1246 if (instance == NULL || context == NULL) 1247 return ARGON2_ERROR; 1248 instance->context_ptr = context; 1250 /* 1. Memory allocation */ 1251 result = allocate_memory((uint8_t **)&(instance->memory), 1252 instance->memory_blocks, sizeof(block)); 1253 if (result != ARGON2_OK) { 1254 return result; 1255 } 1257 /* 2. Initial hashing */ 1258 /* H_0 + 8 extra bytes to produce the first blocks */ 1259 /* Hashing all inputs */ 1260 initial_hash(blockhash, context, instance->type); 1261 /* Zeroing 8 extra bytes */ 1262 memset(blockhash + ARGON2_PREHASH_DIGEST_LENGTH, 0, 1263 ARGON2_PREHASH_SEED_LENGTH - 1264 ARGON2_PREHASH_DIGEST_LENGTH); 1266 /* 3. Creating first blocks, always at least two blocks in a 1267 * slice */ 1268 fill_first_blocks(blockhash, instance); 1269 /* Clearing the hash */ 1270 memset(blockhash, 0, ARGON2_PREHASH_SEED_LENGTH); 1272 return ARGON2_OK; 1273 } 1275 5.5. ref.c 1277 #include 1278 #include 1279 #include 1281 #include "argon2.h" 1282 #include "core.h" 1284 #include "blake2/blamka-round-ref.h" 1285 #include "blake2/blake2-impl.h" 1286 #include "blake2/blake2.h" 1288 /* 1289 * Fills a new memory block and optionally XORs the old block over the 1290 * new one 1291 * @param prev_block Pointer to the previous block 1292 * @param ref_block Pointer to the reference block 1293 * @param next_block Pointer to the block to be constructed 1294 * @param with_xor Whether to XOR into the new block (1) or just 1295 * overwrite (0) 1296 * @pre all block pointers must be valid 1297 * @pre @next_block must be initialized 1298 */ 1299 static void fill_block(const block *prev_block, const block *ref_block, 1300 block *next_block, int with_xor) { 1301 block blockR, block_tmp; 1302 unsigned i; 1304 copy_block(&blockR, ref_block); 1305 xor_block(&blockR, prev_block); 1306 copy_block(&block_tmp, &blockR); 1307 /* Now blockR = ref_block + prev_block and block_tmp = ref_block + 1308 * prev_block */ 1309 if (with_xor) { 1310 /* Saving the next block contents for XOR over: */ 1311 xor_block(&block_tmp, next_block); 1312 /* Now blockR = ref_block + prev_block and 1313 block_tmp = ref_block + prev_block + next_block */ 1314 } 1316 /* Apply Blake2 on columns of 64-bit words: (0,1,...,15) , then 1317 (16,17,..31)... finally (112,113,...127) */ 1318 for (i = 0; i < 8; ++i) { 1319 BLAKE2_ROUND_NOMSG( 1320 blockR.v[16 * i], blockR.v[16 * i + 1], 1321 blockR.v[16 * i + 2], blockR.v[16 * i + 3], 1322 blockR.v[16 * i + 4], blockR.v[16 * i + 5], 1323 blockR.v[16 * i + 6], blockR.v[16 * i + 7], 1324 blockR.v[16 * i + 8], blockR.v[16 * i + 9], 1325 blockR.v[16 * i + 10], blockR.v[16 * i + 11], 1326 blockR.v[16 * i + 12], blockR.v[16 * i + 13], 1327 blockR.v[16 * i + 14], blockR.v[16 * i + 15]); 1328 } 1330 /* Apply Blake2 on rows of 64-bit words: (0,1,16,17,...112,113), 1331 * then (2,3,18,19,...,114,115) ..., finally 1332 * (14,15,30,31,...,126,127) */ 1333 for (i = 0; i < 8; i++) { 1334 BLAKE2_ROUND_NOMSG( 1335 blockR.v[2 * i], blockR.v[2 * i + 1], 1336 blockR.v[2 * i + 16], blockR.v[2 * i + 17], 1337 blockR.v[2 * i + 32], blockR.v[2 * i + 33], 1338 blockR.v[2 * i + 48], blockR.v[2 * i + 49], 1339 blockR.v[2 * i + 64], blockR.v[2 * i + 65], 1340 blockR.v[2 * i + 80], blockR.v[2 * i + 81], 1341 blockR.v[2 * i + 96], blockR.v[2 * i + 97], 1342 blockR.v[2 * i + 112], blockR.v[2 * i + 113]); 1343 } 1345 copy_block(next_block, &block_tmp); 1346 xor_block(next_block, &blockR); 1347 } 1349 static void next_addresses(block *address_block, block *input_block, 1350 const block *zero_block) { 1351 input_block->v[6]++; 1352 fill_block(zero_block, input_block, address_block, 0); 1353 fill_block(zero_block, address_block, address_block, 0); 1354 } 1356 void fill_segment(const argon2_instance_t *instance, 1357 argon2_position_t position) { 1358 block *ref_block = NULL, *curr_block = NULL; 1359 block address_block, input_block, zero_block; 1360 uint64_t pseudo_rand, ref_index, ref_lane; 1361 uint32_t prev_offset, curr_offset; 1362 uint32_t starting_index; 1363 uint32_t i; 1364 int data_independent_addressing; 1366 if (instance == NULL) { 1367 return; 1368 } 1370 data_independent_addressing = 1371 (instance->type == Argon2_i) || 1372 (instance->type == Argon2_id && (position.pass == 0) && 1373 (position.slice < ARGON2_SYNC_POINTS / 2)); 1375 if (data_independent_addressing) { 1376 init_block_value(&zero_block, 0); 1377 init_block_value(&input_block, 0); 1379 input_block.v[0] = position.pass; 1380 input_block.v[1] = position.lane; 1381 input_block.v[2] = position.slice; 1382 input_block.v[3] = instance->memory_blocks; 1383 input_block.v[4] = instance->passes; 1384 input_block.v[5] = instance->type; 1385 } 1387 starting_index = 0; 1389 if ((0 == position.pass) && (0 == position.slice)) { 1390 /* we have already generated the first two blocks */ 1391 starting_index = 2; 1393 /* Don't forget to generate the first block of addresses: */ 1394 if (data_independent_addressing) { 1395 next_addresses(&address_block, &input_block, &zero_block); 1396 } 1397 } 1399 /* Offset of the current block */ 1400 curr_offset = position.lane * instance->lane_length + 1401 position.slice * instance->segment_length + 1402 starting_index; 1404 if (0 == curr_offset % instance->lane_length) { 1405 /* Last block in this lane */ 1406 prev_offset = curr_offset + instance->lane_length - 1; 1407 } else { 1408 /* Previous block */ 1409 prev_offset = curr_offset - 1; 1410 } 1412 for (i = starting_index; i < instance->segment_length; 1413 ++i, ++curr_offset, ++prev_offset) { 1414 /*1.1 Rotating prev_offset if needed */ 1415 if (curr_offset % instance->lane_length == 1) { 1416 prev_offset = curr_offset - 1; 1417 } 1419 /* 1.2 Computing the index of the reference block */ 1420 /* 1.2.1 Taking pseudo-random value from the previous block */ 1421 if (data_independent_addressing) { 1422 if (i % ARGON2_ADDRESSES_IN_BLOCK == 0) { 1423 next_addresses(&address_block, &input_block, 1424 &zero_block); 1425 } 1426 pseudo_rand = address_block.v[i % 1427 ARGON2_ADDRESSES_IN_BLOCK]; 1428 } else { 1429 pseudo_rand = instance->memory[prev_offset].v[0]; 1430 } 1432 /* 1.2.2 Computing the lane of the reference block */ 1433 ref_lane = ((pseudo_rand >> 32)) % instance->lanes; 1435 if ((position.pass == 0) && (position.slice == 0)) { 1436 /* Can not reference other lanes yet */ 1437 ref_lane = position.lane; 1438 } 1440 /* 1.2.3 Computing the number of possible reference block within 1441 * the lane. */ 1442 position.index = i; 1443 ref_index = index_alpha(instance, &position, pseudo_rand & 1444 0xFFFFFFFF, ref_lane == position.lane); 1446 /* 2 Creating a new block */ 1447 ref_block = 1448 instance->memory + instance->lane_length * ref_lane + 1449 ref_index; 1450 curr_block = instance->memory + curr_offset; 1451 if (ARGON2_VERSION_10 == instance->version) { 1452 /* version 1.2.1 and earlier: overwrite, not XOR */ 1453 fill_block(instance->memory + prev_offset, ref_block, 1454 curr_block, 0); 1455 } else { 1456 if(0 == position.pass) { 1457 fill_block(instance->memory + prev_offset, ref_block, 1458 curr_block, 0); 1459 } else { 1460 fill_block(instance->memory + prev_offset, ref_block, 1461 curr_block, 1); 1462 } 1463 } 1464 } 1465 } 1467 5.6. main.c 1469 #include 1470 #include 1471 #include 1472 #include 1473 #include 1475 #include "argon2.h" 1476 #include "core.h" 1478 #define T_COST 3 1479 #define M_COST 1 << 12 1480 #define THREADS 1 1481 #define OUTLEN 32 1483 char pwd[] = "pasword"; 1484 char salt[] = "somesalt"; 1486 static void print_hex(uint8_t *bytes, size_t bytes_len) { 1487 size_t i; 1488 for (i = 0; i < bytes_len; ++i) { 1489 printf("%02x", bytes[i]); 1490 } 1491 printf("\n"); 1492 } 1494 static int run(uint32_t outlen, char *pwd, char *salt, uint32_t t_cost, 1495 uint32_t m_cost, uint32_t threads, argon2_type type, 1496 uint32_t version, unsigned char *expected_hash) { 1498 size_t pwdlen, saltlen; 1499 uint32_t i; 1500 int result; 1501 unsigned char *out = NULL; 1503 pwdlen = strlen(pwd); 1504 saltlen = strlen(salt); 1506 out = malloc(outlen + 1); 1507 if (!out) { 1508 memset(pwd, 0, strlen(pwd)); 1509 printf("Could not allocate memory for output!"); 1510 } 1512 result = argon2_hash(t_cost, m_cost, threads, pwd, pwdlen, salt, 1513 saltlen, out, outlen, type, version); 1514 if (ARGON2_OK != result) { 1515 printf("Error while hasing!"); 1516 } 1518 printf(" Actual Hash:\t\t"); 1519 print_hex(out, outlen); 1520 printf("Expected Hash:\t\t"); 1521 print_hex(expected_hash, outlen); 1523 if (ARGON2_OK == result) { 1524 for (i = 0; i < outlen; i++) { 1525 if (expected_hash[i] != out[i]) { 1526 return ARGON2_ERROR; 1527 } 1528 } 1529 } 1531 free(out); 1532 return result; 1533 } 1535 int argon2_i_selftest() 1536 { 1537 unsigned char expected_hash[] = { 1538 0x95, 0x7f, 0xc0, 0x72, 0x7d, 0x83, 0xf4, 0x06, 1539 0x0b, 0xb0, 0xf1, 0x07, 0x1e, 0xb5, 0x90, 0xa1, 1540 0x9a, 0x8c, 0x44, 0x8f, 0xc0, 0x20, 0x94, 0x97, 1541 0xee, 0x4f, 0x54, 0xca, 0x24, 0x1f, 0x3c, 0x90}; 1542 return run(OUTLEN, pwd, salt, T_COST, M_COST, THREADS, Argon2_i, 1543 ARGON2_VERSION_NUMBER, expected_hash); 1544 } 1545 int argon2_d_selftest() 1546 { 1547 unsigned char expected_hash[] = { 1548 0x0b, 0x3f, 0x09, 0xe7, 0xb8, 0xd0, 0x36, 0xe5, 1549 0x8c, 0xcd, 0x08, 0xf0, 0x8c, 0xb6, 0xba, 0xbf, 1550 0x7e, 0x5e, 0x24, 0x63, 0xc2, 0x6b, 0xcf, 0x2a, 1551 0x9e, 0x4e, 0xa7, 0x0d, 0x74, 0x7c, 0x40, 0x98}; 1552 return run(OUTLEN, pwd, salt, T_COST, M_COST, THREADS, Argon2_d, 1553 ARGON2_VERSION_NUMBER, expected_hash); 1554 } 1556 int argon2_id_selftest() 1557 { 1558 unsigned char expected_hash[] = { 1559 0xf5, 0x55, 0x35, 0xbf, 0xe9, 0x48, 0x71, 0x00, 1560 0x51, 0x42, 0x4c, 0x74, 0x24, 0xb1, 0x1b, 0xa9, 1561 0xa1, 0x3a, 0x50, 0x23, 0x9b, 0x04, 0x59, 0xf5, 1562 0x6c, 0xa6, 0x95, 0xea, 0x14, 0xbc, 0x19, 0x5e}; 1563 return run(OUTLEN, pwd, salt, T_COST, M_COST, THREADS, Argon2_id, 1564 ARGON2_VERSION_NUMBER, expected_hash); 1565 } 1567 int main(int argc, char *argv[]) { 1568 printf("Argon2i - %s\n", ARGON2_OK == argon2_i_selftest() ? 1569 "OK" : "FAIL"); 1570 printf("Argon2d - %s\n", ARGON2_OK == argon2_d_selftest() ? 1571 "OK" : "FAIL"); 1572 printf("Argon2id - %s\n", ARGON2_OK == argon2_id_selftest() ? 1573 "OK" : "FAIL"); 1575 return ARGON2_OK; 1576 } 1578 5.7. blake2.h 1580 int blake2b_long(void *out, size_t outlen, const void *in, 1581 size_t inlen); 1583 5.8. blake2.c 1585 int blake2b_long(void *pout, size_t outlen, const void *in, 1586 size_t inlen) { 1587 uint8_t *out = (uint8_t *)pout; 1588 blake2b_state blake_state; 1589 uint8_t outlen_bytes[sizeof(uint32_t)] = {0}; 1590 int ret = -1; 1591 if (outlen > UINT32_MAX) { 1592 goto fail; 1593 } 1595 /* Ensure little-endian byte order! */ 1596 store32(outlen_bytes, (uint32_t)outlen); 1598 #define TRY(statement) \ 1599 do { \ 1600 ret = statement; \ 1601 if (ret < 0) { \ 1602 goto fail; \ 1603 } \ 1604 } while ((void)0, 0) 1606 if (outlen <= BLAKE2B_OUTBYTES) { 1607 TRY(blake2b_init(&blake_state, outlen)); 1608 TRY(blake2b_update(&blake_state, outlen_bytes, 1609 sizeof(outlen_bytes))); 1610 TRY(blake2b_update(&blake_state, in, inlen)); 1611 TRY(blake2b_final(&blake_state, out, outlen)); 1612 } else { 1613 uint32_t toproduce; 1614 uint8_t out_buffer[BLAKE2B_OUTBYTES]; 1615 uint8_t in_buffer[BLAKE2B_OUTBYTES]; 1616 TRY(blake2b_init(&blake_state, BLAKE2B_OUTBYTES)); 1617 TRY(blake2b_update(&blake_state, outlen_bytes, 1618 sizeof(outlen_bytes))); 1619 TRY(blake2b_update(&blake_state, in, inlen)); 1620 TRY(blake2b_final(&blake_state, out_buffer, BLAKE2B_OUTBYTES)); 1621 memcpy(out, out_buffer, BLAKE2B_OUTBYTES / 2); 1622 out += BLAKE2B_OUTBYTES / 2; 1623 toproduce = (uint32_t)outlen - BLAKE2B_OUTBYTES / 2; 1625 while (toproduce > BLAKE2B_OUTBYTES) { 1626 memcpy(in_buffer, out_buffer, BLAKE2B_OUTBYTES); 1627 TRY(blake2b(out_buffer, BLAKE2B_OUTBYTES, in_buffer, 1628 BLAKE2B_OUTBYTES, NULL, 0)); 1629 memcpy(out, out_buffer, BLAKE2B_OUTBYTES / 2); 1630 out += BLAKE2B_OUTBYTES / 2; 1631 toproduce -= BLAKE2B_OUTBYTES / 2; 1632 } 1634 memcpy(in_buffer, out_buffer, BLAKE2B_OUTBYTES); 1635 TRY(blake2b(out_buffer, toproduce, in_buffer, BLAKE2B_OUTBYTES, 1636 NULL, 0)); 1637 memcpy(out, out_buffer, toproduce); 1638 } 1640 fail: 1641 memset(&blake_state, 0, sizeof(blake_state)); 1642 return ret; 1643 #undef TRY 1645 5.9. blake2-impl.h 1647 #if (defined(__BYTE_ORDER__) && \ 1648 (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)) || \ 1649 defined(__LITTLE_ENDIAN__) || defined(__ARMEL__) || \ 1650 defined(__MIPSEL__) || defined(__AARCH64EL__) || \ 1651 defined(__amd64__) || defined(__i386__) || \ 1652 defined(_M_IX86) || defined(_M_X64) || \ 1653 defined(_M_AMD64) || defined(_M_ARM) 1654 #define NATIVE_LITTLE_ENDIAN 1655 #endif 1657 5.10. blamka-round-ref.h 1658 #ifndef BLAKE_ROUND_MKA_H 1659 #define BLAKE_ROUND_MKA_H 1661 #include "blake2.h" 1662 #include "blake2-impl.h" 1664 /*designed by the Lyra PHC team */ 1665 static BLAKE2_INLINE uint64_t fBlaMka(uint64_t x, uint64_t y) { 1666 const uint64_t m = UINT64_C(0xFFFFFFFF); 1667 const uint64_t xy = (x & m) * (y & m); 1668 return x + y + 2 * xy; 1669 } 1671 #define G(a, b, c, d) \ 1672 do { \ 1673 a = fBlaMka(a, b); \ 1674 d = rotr64(d ^ a, 32); \ 1675 c = fBlaMka(c, d); \ 1676 b = rotr64(b ^ c, 24); \ 1677 a = fBlaMka(a, b); \ 1678 d = rotr64(d ^ a, 16); \ 1679 c = fBlaMka(c, d); \ 1680 b = rotr64(b ^ c, 63); \ 1681 } while ((void)0, 0) 1683 #define BLAKE2_ROUND_NOMSG(v0, v1, v2, v3, v4, v5, v6, v7, 1684 v8, v9, v10, v11, v12, v13, v14, v15) \ 1685 do { \ 1686 G(v0, v4, v8, v12); \ 1687 G(v1, v5, v9, v13); \ 1688 G(v2, v6, v10, v14); \ 1689 G(v3, v7, v11, v15); \ 1690 G(v0, v5, v10, v15); \ 1691 G(v1, v6, v11, v12); \ 1692 G(v2, v7, v8, v13); \ 1693 G(v3, v4, v9, v14); \ 1694 } while ((void)0, 0) 1696 #endif 1698 6. Test Vectors 1700 This section contains test vectors for Argon2. 1702 6.1. Argon2d Test Vectors 1704 ======================================= 1705 Argon2d version number 19 1706 ======================================= 1707 Memory: 32 KiB 1708 Iterations: 3 1709 Parallelism: 4 lanes 1710 Tag length: 32 bytes 1711 Password[32]: 01 01 01 01 01 01 01 01 1712 01 01 01 01 01 01 01 01 1713 01 01 01 01 01 01 01 01 1714 01 01 01 01 01 01 01 01 1715 Salt[16]: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 1716 Secret[8]: 03 03 03 03 03 03 03 03 1717 Associated data[12]: 04 04 04 04 04 04 04 04 04 04 04 04 1718 Pre-hashing digest: b8 81 97 91 a0 35 96 60 1719 bb 77 09 c8 5f a4 8f 04 1720 d5 d8 2c 05 c5 f2 15 cc 1721 db 88 54 91 71 7c f7 57 1722 08 2c 28 b9 51 be 38 14 1723 10 b5 fc 2e b7 27 40 33 1724 b9 fd c7 ae 67 2b ca ac 1725 5d 17 90 97 a4 af 31 09 1727 After pass 0: 1728 Block 0000 [ 0]: db2fea6b2c6f5c8a 1729 Block 0000 [ 1]: 719413be00f82634 1730 Block 0000 [ 2]: a1e3f6dd42aa25cc 1731 Block 0000 [ 3]: 3ea8efd4d55ac0d1 1732 ... 1733 Block 0031 [124]: 28d17914aea9734c 1734 Block 0031 [125]: 6a4622176522e398 1735 Block 0031 [126]: 951aa08aeecb2c05 1736 Block 0031 [127]: 6a6c49d2cb75d5b6 1738 After pass 1: 1739 Block 0000 [ 0]: d3801200410f8c0d 1740 Block 0000 [ 1]: 0bf9e8a6e442ba6d 1741 Block 0000 [ 2]: e2ca92fe9c541fcc 1742 Block 0000 [ 3]: 6269fe6db177a388 1743 ... 1744 Block 0031 [124]: 9eacfcfbdb3ce0fc 1745 Block 0031 [125]: 07dedaeb0aee71ac 1746 Block 0031 [126]: 074435fad91548f4 1747 Block 0031 [127]: 2dbfff23f31b5883 1749 After pass 2: 1751 Block 0000 [ 0]: 5f047b575c5ff4d2 1752 Block 0000 [ 1]: f06985dbf11c91a8 1753 Block 0000 [ 2]: 89efb2759f9a8964 1754 Block 0000 [ 3]: 7486a73f62f9b142 1755 ... 1756 Block 0031 [124]: 57cfb9d20479da49 1757 Block 0031 [125]: 4099654bc6607f69 1758 Block 0031 [126]: f142a1126075a5c8 1759 Block 0031 [127]: c341b3ca45c10da5 1760 Tag: 51 2b 39 1b 6f 11 62 97 1761 53 71 d3 09 19 73 42 94 1762 f8 68 e3 be 39 84 f3 c1 1763 a1 3a 4d b9 fa be 4a cb 1765 6.2. Argon2i Test Vectors 1767 ======================================= 1768 Argon2i version number 19 1769 ======================================= 1770 Memory: 32 KiB 1771 Iterations: 3 1772 Parallelism: 4 lanes 1773 Tag length: 32 bytes 1774 Password[32]: 01 01 01 01 01 01 01 01 1775 01 01 01 01 01 01 01 01 1776 01 01 01 01 01 01 01 01 1777 01 01 01 01 01 01 01 01 1778 Salt[16]: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 1779 Secret[8]: 03 03 03 03 03 03 03 03 1780 Associated data[12]: 04 04 04 04 04 04 04 04 04 04 04 04 1781 Pre-hashing digest: c4 60 65 81 52 76 a0 b3 1782 e7 31 73 1c 90 2f 1f d8 1783 0c f7 76 90 7f bb 7b 6a 1784 5c a7 2e 7b 56 01 1f ee 1785 ca 44 6c 86 dd 75 b9 46 1786 9a 5e 68 79 de c4 b7 2d 1787 08 63 fb 93 9b 98 2e 5f 1788 39 7c c7 d1 64 fd da a9 1790 After pass 0: 1791 Block 0000 [ 0]: f8f9e84545db08f6 1792 Block 0000 [ 1]: 9b073a5c87aa2d97 1793 Block 0000 [ 2]: d1e868d75ca8d8e4 1794 Block 0000 [ 3]: 349634174e1aebcc 1795 ... 1796 Block 0031 [124]: 975f596583745e30 1797 Block 0031 [125]: e349bdd7edeb3092 1798 Block 0031 [126]: b751a689b7a83659 1799 Block 0031 [127]: c570f2ab2a86cf00 1801 After pass 1: 1802 Block 0000 [ 0]: b2e4ddfcf76dc85a 1803 Block 0000 [ 1]: 4ffd0626c89a2327 1804 Block 0000 [ 2]: 4af1440fff212980 1805 Block 0000 [ 3]: 1e77299c7408505b 1806 ... 1807 Block 0031 [124]: e4274fd675d1e1d6 1808 Block 0031 [125]: 903fffb7c4a14c98 1809 Block 0031 [126]: 7e5db55def471966 1810 Block 0031 [127]: 421b3c6e9555b79d 1812 After pass 2: 1813 Block 0000 [ 0]: af2a8bd8482c2f11 1814 Block 0000 [ 1]: 785442294fa55e6d 1815 Block 0000 [ 2]: 9256a768529a7f96 1816 Block 0000 [ 3]: 25a1c1f5bb953766 1817 ... 1818 Block 0031 [124]: 68cf72fccc7112b9 1819 Block 0031 [125]: 91e8c6f8bb0ad70d 1820 Block 0031 [126]: 4f59c8bd65cbb765 1821 Block 0031 [127]: 71e436f035f30ed0 1822 Tag: c8 14 d9 d1 dc 7f 37 aa 1823 13 f0 d7 7f 24 94 bd a1 1824 c8 de 6b 01 6d d3 88 d2 1825 99 52 a4 c4 67 2b 6c e8 1827 6.3. Argon2id Test Vectors 1829 ======================================= 1830 Argon2id version number 19 1831 ======================================= 1832 Memory: 32 KiB 1833 Iterations: 3 1834 Parallelism: 4 lanes 1835 Tag length: 32 bytes 1836 Password[32]: 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 1837 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 1838 Salt[16]: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 1839 Secret[8]: 03 03 03 03 03 03 03 03 1840 Associated data[12]: 04 04 04 04 04 04 04 04 04 04 04 04 1841 Pre-hashing digest: 28 89 de 48 7e b4 2a e5 00 c0 00 7e d9 25 2f 1842 10 69 ea de c4 0d 57 65 b4 85 de 6d c2 43 7a 67 b8 54 6a 2f 0a 1843 cc 1a 08 82 db 8f cf 74 71 4b 47 2e 94 df 42 1a 5d a1 11 2f fa 1844 11 43 43 70 a1 e9 97 1846 After pass 0: 1848 Block 0000 [ 0]: 6b2e09f10671bd43 1849 Block 0000 [ 1]: f69f5c27918a21be 1850 Block 0000 [ 2]: dea7810ea41290e1 1851 Block 0000 [ 3]: 6787f7171870f893 1852 ... 1853 Block 0031 [124]: 377fa81666dc7f2b 1854 Block 0031 [125]: 50e586398a9c39c8 1855 Block 0031 [126]: 6f732732a550924a 1856 Block 0031 [127]: 81f88b28683ea8e5 1858 After pass 1: 1859 Block 0000 [ 0]: 3653ec9d01583df9 1860 Block 0000 [ 1]: 69ef53a72d1e1fd3 1861 Block 0000 [ 2]: 35635631744ab54f 1862 Block 0000 [ 3]: 599512e96a37ab6e 1863 ... 1864 Block 0031 [124]: 4d4b435cea35caa6 1865 Block 0031 [125]: c582210d99ad1359 1866 Block 0031 [126]: d087971b36fd6d77 1867 Block 0031 [127]: a55222a93754c692 1869 After pass 2: 1870 Block 0000 [ 0]: 942363968ce597a4 1871 Block 0000 [ 1]: a22448c0bdad5760 1872 Block 0000 [ 2]: a5f80662b6fa8748 1873 Block 0000 [ 3]: a0f9b9ce392f719f 1874 ... 1875 Block 0031 [124]: d723359b485f509b 1876 Block 0031 [125]: cb78824f42375111 1877 Block 0031 [126]: 35bc8cc6e83b1875 1878 Block 0031 [127]: 0b012846a40f346a 1879 Tag: 0d 64 0d f5 8d 78 76 6c 08 c0 37 a3 4a 8b 53 c9 d0 1880 1e f0 45 2d 75 b6 5e b5 25 20 e9 6b 01 e6 59 1882 7. Acknowledgements 1884 TBA 1886 8. IANA Considerations 1888 None. 1890 9. Security Considerations 1891 9.1. Security as hash function and KDF 1893 The collision and preimage resistance levels of Argon2 are equivalent 1894 to those of the underlying BLAKE2b hash function. To produce a 1895 collision, 2^(256) inputs are needed. To find a preimage, 2^(512) 1896 inputs must be tried. 1898 The KDF security is determined by the key length and the size of the 1899 internal state of hash function H'. To distinguish the output of 1900 keyed Argon2 from random, minimum of (2^(128),2^length(K)) calls to 1901 BLAKE2b are needed. 1903 9.2. Security against time-space tradeoff attacks 1905 Time-space tradeoffs allow computing a memory-hard function storing 1906 fewer memory blocks at the cost of more calls to the internal 1907 comression function. The advantage of tradeoff attacks is measured 1908 in the reduction factor to the time-area product, where memory and 1909 extra compression function cores contribute to the area, and time is 1910 increased to accomodate the recomputation of missed blocks. A high 1911 reduction factor may potentially speed up preimage search. 1913 The best attacks on the 1-pass and 2-pass Argon2i is the low-storage 1914 attack described in [CBS16], which reduces the time-area product 1915 (using the peak memory value) by the factor of 5. The best attack on 1916 3-pass and more Argon2i is [AB16] with reduction factor being a 1917 function of memory size and the number of passes. For 1 gibibyte of 1918 memory: 3 for 3 passes, 2.5 for 4 passes, 2 for 6 passes. The 1919 reduction factor grows by about 0.5 with every doubling the memory 1920 size. To completely prevent time-space tradeoffs from [AB16], the 1921 number of passes must exceed binary logarithm of memory minus 26. 1922 Asymptotically, the best attack on 1-pass Argon2i is given in [BZ17] 1923 with reduction factor O(m^(0.233)) where m is the number of blocks. 1924 This attack is also asymptotically optimal as [BZ17] also prove the 1925 upper bound of O(m^(0.25)). 1927 The best tradeoff attack on t-pass Argon2d is the ranking tradeoff 1928 attack, which reduces the time-area product by the factor of 1.33. 1930 The best attack on Argon2id can be obtained by complementing the best 1931 attack on the 1-pass Argon2i with the best attack on a multi-pass 1932 Argon2d. Thus The best tradeoff attack on 1-pass Argon2id is the 1933 combined low-storage attack (for the first half of the memory) and 1934 the ranking attack (for the second half), which bring together the 1935 factor of about 2.1. The best tradeoff attack on t-pass Argon2id is 1936 the ranking tradeoff attack, which reduces the time-area product by 1937 the factor of 1.33. 1939 9.3. Security for time-bounded defenders 1941 A bottleneck in a system employing the password-hashing function is 1942 often the function latency rather than memory costs. A rational 1943 defender would then maximize the bruteforce costs for the attacker 1944 equipped with a list of hashes, salts, and timing information, for 1945 fixed computing time on the defender's machine. The attack cost 1946 estimates from [AB16] imply that for Argon2i, 3 passes is almost 1947 optimal for the most of reasonable memory sizes, and that for Argon2d 1948 and Argon2id, 1 pass maximizes the attack costs for the constant 1949 defender time. 1951 9.4. Recommendations 1953 The Argon2id variant with t=1 and maximum available memory is 1954 recommended as a default setting for all environments. This setting 1955 is secure against side-channel attacks and maximizes adversarial 1956 costs on dedicated bruteforce hardware. 1958 10. References 1960 10.1. Normative References 1962 [RFC7693] Saarinen, M-J., Ed. and J-P. Aumasson, "The BLAKE2 1963 Cryptographic Hash and Message Authentication Code (MAC)", 1964 RFC 7693, DOI 10.17487/RFC7693, November 2015, 1965 . 1967 10.2. Informative References 1969 [AB15] Biryukov, A. and D. Khovratovich, "Tradeoff Cryptanalysis 1970 of Memory-Hard Functions", 1971 Asiacrypt'15 , 1972 December 2015. 1974 [AB16] Alwen, J. and J. Blocki, "Efficiently Computing Data- 1975 Independent Memory-Hard Functions", 1976 WWW , December 2015. 1978 [ARGON2] Biryukov, A., Dinu, D., and D. Khovratovich, "Argon2: the 1979 memory-hard function for password hashing and other 1980 applications", 1981 WWW , 1982 October 2015. 1984 [ARGON2ESP] 1985 Biryukov, A., Dinu, D., and D. Khovratovich, "Argon2: New 1986 Generation of Memory-Hard Functions for Password Hashing 1987 and Other Applications", Euro S&P 2016 1988 , 1989 March 2016. 1991 [ARGON2GITHUB] 1992 "The password hash Argon2, winner of PHC", 1993 WWW , July 1994 2017. 1996 [BZ17] Blocki, J. and S. Zhou, "On the Depth-Robustness and 1997 Cumulative Pebbling Cost of Argon2i", 1998 WWW , May 2017. 2000 [CBS16] Corrigan-Gibbs, H., Boneh, D., and S. Schechter, "Balloon 2001 Hashing: Provably Space-Hard Hash Functions with Data- 2002 Independent Access Patterns", 2003 WWW , January 2016. 2005 Authors' Addresses 2007 Alex Biryukov 2008 University of Luxembourg 2010 Email: alex.biryukov@uni.lu 2012 Daniel Dinu 2013 University of Luxembourg 2015 Email: dumitru-daniel.dinu@uni.lu 2017 Dmitry Khovratovich 2018 University of Luxembourg 2020 Email: dmitry.khovratovich@uni.lu 2022 Simon Josefsson 2023 SJD AB 2025 Email: simon@josefsson.org 2026 URI: http://josefsson.org/