sorcery-argon2 1.0.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (88) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ruby.yml +0 -2
  3. data/.rubocop.yml +34 -2
  4. data/CHANGELOG.md +4 -0
  5. data/MAINTAINING.md +8 -3
  6. data/bin/setup +3 -0
  7. data/ext/phc-winner-argon2/.gitattributes +10 -0
  8. data/ext/phc-winner-argon2/.gitignore +22 -0
  9. data/ext/phc-winner-argon2/.travis.yml +25 -0
  10. data/ext/phc-winner-argon2/Argon2.sln +158 -0
  11. data/ext/phc-winner-argon2/CHANGELOG.md +32 -0
  12. data/ext/phc-winner-argon2/LICENSE +314 -0
  13. data/ext/phc-winner-argon2/Makefile +255 -0
  14. data/ext/phc-winner-argon2/Package.swift +46 -0
  15. data/ext/phc-winner-argon2/README.md +303 -0
  16. data/ext/phc-winner-argon2/appveyor.yml +25 -0
  17. data/ext/phc-winner-argon2/argon2-specs.pdf +0 -0
  18. data/ext/phc-winner-argon2/export.sh +7 -0
  19. data/ext/phc-winner-argon2/include/argon2.h +437 -0
  20. data/ext/phc-winner-argon2/kats/argon2d +12304 -0
  21. data/ext/phc-winner-argon2/kats/argon2d.shasum +1 -0
  22. data/ext/phc-winner-argon2/kats/argon2d_v16 +12304 -0
  23. data/ext/phc-winner-argon2/kats/argon2d_v16.shasum +1 -0
  24. data/ext/phc-winner-argon2/kats/argon2i +12304 -0
  25. data/ext/phc-winner-argon2/kats/argon2i.shasum +1 -0
  26. data/ext/phc-winner-argon2/kats/argon2i_v16 +12304 -0
  27. data/ext/phc-winner-argon2/kats/argon2i_v16.shasum +1 -0
  28. data/ext/phc-winner-argon2/kats/argon2id +12304 -0
  29. data/ext/phc-winner-argon2/kats/argon2id.shasum +1 -0
  30. data/ext/phc-winner-argon2/kats/argon2id_v16 +12304 -0
  31. data/ext/phc-winner-argon2/kats/argon2id_v16.shasum +1 -0
  32. data/ext/phc-winner-argon2/kats/check-sums.ps1 +42 -0
  33. data/ext/phc-winner-argon2/kats/check-sums.sh +13 -0
  34. data/ext/phc-winner-argon2/kats/test.ps1 +50 -0
  35. data/ext/phc-winner-argon2/kats/test.sh +49 -0
  36. data/ext/phc-winner-argon2/latex/IEEEtran.cls +6347 -0
  37. data/ext/phc-winner-argon2/latex/Makefile +18 -0
  38. data/ext/phc-winner-argon2/latex/argon2-specs.tex +920 -0
  39. data/ext/phc-winner-argon2/latex/pics/argon2-par.pdf +0 -0
  40. data/ext/phc-winner-argon2/latex/pics/compression.pdf +0 -0
  41. data/ext/phc-winner-argon2/latex/pics/generic.pdf +0 -0
  42. data/ext/phc-winner-argon2/latex/pics/power-distribution.jpg +0 -0
  43. data/ext/phc-winner-argon2/latex/tradeoff.bib +822 -0
  44. data/ext/phc-winner-argon2/libargon2.pc.in +18 -0
  45. data/ext/phc-winner-argon2/man/argon2.1 +57 -0
  46. data/ext/phc-winner-argon2/src/argon2.c +452 -0
  47. data/ext/phc-winner-argon2/src/bench.c +111 -0
  48. data/ext/phc-winner-argon2/src/blake2/blake2-impl.h +156 -0
  49. data/ext/phc-winner-argon2/src/blake2/blake2.h +89 -0
  50. data/ext/phc-winner-argon2/src/blake2/blake2b.c +390 -0
  51. data/ext/phc-winner-argon2/src/blake2/blamka-round-opt.h +471 -0
  52. data/ext/phc-winner-argon2/src/blake2/blamka-round-ref.h +56 -0
  53. data/ext/phc-winner-argon2/src/core.c +648 -0
  54. data/ext/phc-winner-argon2/src/core.h +228 -0
  55. data/ext/phc-winner-argon2/src/encoding.c +463 -0
  56. data/ext/phc-winner-argon2/src/encoding.h +57 -0
  57. data/ext/phc-winner-argon2/src/genkat.c +213 -0
  58. data/ext/phc-winner-argon2/src/genkat.h +51 -0
  59. data/ext/phc-winner-argon2/src/opt.c +283 -0
  60. data/ext/phc-winner-argon2/src/ref.c +194 -0
  61. data/ext/phc-winner-argon2/src/run.c +337 -0
  62. data/ext/phc-winner-argon2/src/test.c +289 -0
  63. data/ext/phc-winner-argon2/src/thread.c +57 -0
  64. data/ext/phc-winner-argon2/src/thread.h +67 -0
  65. data/ext/phc-winner-argon2/vs2015/Argon2Opt/Argon2Opt.vcxproj +231 -0
  66. data/ext/phc-winner-argon2/vs2015/Argon2Opt/Argon2Opt.vcxproj.filters +69 -0
  67. data/ext/phc-winner-argon2/vs2015/Argon2OptBench/Argon2OptBench.vcxproj +231 -0
  68. data/ext/phc-winner-argon2/vs2015/Argon2OptBench/Argon2OptBench.vcxproj.filters +69 -0
  69. data/ext/phc-winner-argon2/vs2015/Argon2OptDll/Argon2OptDll.vcxproj +230 -0
  70. data/ext/phc-winner-argon2/vs2015/Argon2OptDll/Argon2OptDll.vcxproj.filters +66 -0
  71. data/ext/phc-winner-argon2/vs2015/Argon2OptGenKAT/Argon2OptGenKAT.vcxproj +244 -0
  72. data/ext/phc-winner-argon2/vs2015/Argon2OptGenKAT/Argon2OptGenKAT.vcxproj.filters +72 -0
  73. data/ext/phc-winner-argon2/vs2015/Argon2OptTestCI/Argon2OptTestCI.vcxproj +235 -0
  74. data/ext/phc-winner-argon2/vs2015/Argon2OptTestCI/Argon2OptTestCI.vcxproj.filters +69 -0
  75. data/ext/phc-winner-argon2/vs2015/Argon2Ref/Argon2Ref.vcxproj +243 -0
  76. data/ext/phc-winner-argon2/vs2015/Argon2Ref/Argon2Ref.vcxproj.filters +69 -0
  77. data/ext/phc-winner-argon2/vs2015/Argon2RefBench/Argon2RefBench.vcxproj +231 -0
  78. data/ext/phc-winner-argon2/vs2015/Argon2RefBench/Argon2RefBench.vcxproj.filters +69 -0
  79. data/ext/phc-winner-argon2/vs2015/Argon2RefDll/Argon2RefDll.vcxproj +230 -0
  80. data/ext/phc-winner-argon2/vs2015/Argon2RefDll/Argon2RefDll.vcxproj.filters +66 -0
  81. data/ext/phc-winner-argon2/vs2015/Argon2RefGenKAT/Argon2RefGenKAT.vcxproj +232 -0
  82. data/ext/phc-winner-argon2/vs2015/Argon2RefGenKAT/Argon2RefGenKAT.vcxproj.filters +72 -0
  83. data/ext/phc-winner-argon2/vs2015/Argon2RefTestCI/Argon2RefTestCI.vcxproj +231 -0
  84. data/ext/phc-winner-argon2/vs2015/Argon2RefTestCI/Argon2RefTestCI.vcxproj.filters +69 -0
  85. data/lib/argon2/ffi_engine.rb +4 -4
  86. data/lib/argon2/password.rb +11 -3
  87. data/lib/argon2/version.rb +1 -1
  88. metadata +84 -3
@@ -0,0 +1,57 @@
1
+ /*
2
+ * Argon2 reference source code package - reference C implementations
3
+ *
4
+ * Copyright 2015
5
+ * Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves
6
+ *
7
+ * You may use this work under the terms of a Creative Commons CC0 1.0
8
+ * License/Waiver or the Apache Public License 2.0, at your option. The terms of
9
+ * these licenses can be found at:
10
+ *
11
+ * - CC0 1.0 Universal : https://creativecommons.org/publicdomain/zero/1.0
12
+ * - Apache 2.0 : https://www.apache.org/licenses/LICENSE-2.0
13
+ *
14
+ * You should have received a copy of both of these licenses along with this
15
+ * software. If not, they may be obtained at the above URLs.
16
+ */
17
+
18
+ #ifndef ENCODING_H
19
+ #define ENCODING_H
20
+ #include "argon2.h"
21
+
22
+ #define ARGON2_MAX_DECODED_LANES UINT32_C(255)
23
+ #define ARGON2_MIN_DECODED_SALT_LEN UINT32_C(8)
24
+ #define ARGON2_MIN_DECODED_OUT_LEN UINT32_C(12)
25
+
26
+ /*
27
+ * encode an Argon2 hash string into the provided buffer. 'dst_len'
28
+ * contains the size, in characters, of the 'dst' buffer; if 'dst_len'
29
+ * is less than the number of required characters (including the
30
+ * terminating 0), then this function returns ARGON2_ENCODING_ERROR.
31
+ *
32
+ * on success, ARGON2_OK is returned.
33
+ */
34
+ int encode_string(char *dst, size_t dst_len, argon2_context *ctx,
35
+ argon2_type type);
36
+
37
+ /*
38
+ * Decodes an Argon2 hash string into the provided structure 'ctx'.
39
+ * The only fields that must be set prior to this call are ctx.saltlen and
40
+ * ctx.outlen (which must be the maximal salt and out length values that are
41
+ * allowed), ctx.salt and ctx.out (which must be buffers of the specified
42
+ * length), and ctx.pwd and ctx.pwdlen which must hold a valid password.
43
+ *
44
+ * Invalid input string causes an error. On success, the ctx is valid and all
45
+ * fields have been initialized.
46
+ *
47
+ * Returned value is ARGON2_OK on success, other ARGON2_ codes on error.
48
+ */
49
+ int decode_string(argon2_context *ctx, const char *str, argon2_type type);
50
+
51
+ /* Returns the length of the encoded byte stream with length len */
52
+ size_t b64len(uint32_t len);
53
+
54
+ /* Returns the length of the encoded number num */
55
+ size_t numlen(uint32_t num);
56
+
57
+ #endif
@@ -0,0 +1,213 @@
1
+ /*
2
+ * Argon2 reference source code package - reference C implementations
3
+ *
4
+ * Copyright 2015
5
+ * Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves
6
+ *
7
+ * You may use this work under the terms of a Creative Commons CC0 1.0
8
+ * License/Waiver or the Apache Public License 2.0, at your option. The terms of
9
+ * these licenses can be found at:
10
+ *
11
+ * - CC0 1.0 Universal : https://creativecommons.org/publicdomain/zero/1.0
12
+ * - Apache 2.0 : https://www.apache.org/licenses/LICENSE-2.0
13
+ *
14
+ * You should have received a copy of both of these licenses along with this
15
+ * software. If not, they may be obtained at the above URLs.
16
+ */
17
+
18
+ #include <stdio.h>
19
+ #include <stdlib.h>
20
+ #include <string.h>
21
+ #include "argon2.h"
22
+ #include "core.h"
23
+ #ifdef __MINGW32__
24
+ #include <inttypes.h>
25
+ #else
26
+ /* Don't use <inttypes.h> (it's not C89) */
27
+ #define PRIx64 "llx"
28
+ #endif
29
+
30
+ void initial_kat(const uint8_t *blockhash, const argon2_context *context,
31
+ argon2_type type) {
32
+ unsigned i;
33
+
34
+ if (blockhash != NULL && context != NULL) {
35
+ printf("=======================================\n");
36
+
37
+ printf("%s version number %d\n", argon2_type2string(type, 1),
38
+ context->version);
39
+
40
+ printf("=======================================\n");
41
+
42
+
43
+ printf("Memory: %u KiB, Iterations: %u, Parallelism: %u lanes, Tag "
44
+ "length: %u bytes\n",
45
+ context->m_cost, context->t_cost, context->lanes,
46
+ context->outlen);
47
+
48
+ printf("Password[%u]: ", context->pwdlen);
49
+
50
+ if (context->flags & ARGON2_FLAG_CLEAR_PASSWORD) {
51
+ printf("CLEARED\n");
52
+ } else {
53
+ for (i = 0; i < context->pwdlen; ++i) {
54
+ printf("%2.2x ", ((unsigned char *)context->pwd)[i]);
55
+ }
56
+
57
+ printf("\n");
58
+ }
59
+
60
+ printf("Salt[%u]: ", context->saltlen);
61
+
62
+ for (i = 0; i < context->saltlen; ++i) {
63
+ printf("%2.2x ", ((unsigned char *)context->salt)[i]);
64
+ }
65
+
66
+ printf("\n");
67
+
68
+ printf("Secret[%u]: ", context->secretlen);
69
+
70
+ if (context->flags & ARGON2_FLAG_CLEAR_SECRET) {
71
+ printf("CLEARED\n");
72
+ } else {
73
+ for (i = 0; i < context->secretlen; ++i) {
74
+ printf("%2.2x ", ((unsigned char *)context->secret)[i]);
75
+ }
76
+
77
+ printf("\n");
78
+ }
79
+
80
+ printf("Associated data[%u]: ", context->adlen);
81
+
82
+ for (i = 0; i < context->adlen; ++i) {
83
+ printf("%2.2x ", ((unsigned char *)context->ad)[i]);
84
+ }
85
+
86
+ printf("\n");
87
+
88
+ printf("Pre-hashing digest: ");
89
+
90
+ for (i = 0; i < ARGON2_PREHASH_DIGEST_LENGTH; ++i) {
91
+ printf("%2.2x ", ((unsigned char *)blockhash)[i]);
92
+ }
93
+
94
+ printf("\n");
95
+ }
96
+ }
97
+
98
+ void print_tag(const void *out, uint32_t outlen) {
99
+ unsigned i;
100
+ if (out != NULL) {
101
+ printf("Tag: ");
102
+
103
+ for (i = 0; i < outlen; ++i) {
104
+ printf("%2.2x ", ((uint8_t *)out)[i]);
105
+ }
106
+
107
+ printf("\n");
108
+ }
109
+ }
110
+
111
+ void internal_kat(const argon2_instance_t *instance, uint32_t pass) {
112
+
113
+ if (instance != NULL) {
114
+ uint32_t i, j;
115
+ printf("\n After pass %u:\n", pass);
116
+
117
+ for (i = 0; i < instance->memory_blocks; ++i) {
118
+ uint32_t how_many_words =
119
+ (instance->memory_blocks > ARGON2_QWORDS_IN_BLOCK)
120
+ ? 1
121
+ : ARGON2_QWORDS_IN_BLOCK;
122
+
123
+ for (j = 0; j < how_many_words; ++j)
124
+ printf("Block %.4u [%3u]: %016" PRIx64 "\n", i, j,
125
+ (unsigned long long)instance->memory[i].v[j]);
126
+ }
127
+ }
128
+ }
129
+
130
+ static void fatal(const char *error) {
131
+ fprintf(stderr, "Error: %s\n", error);
132
+ exit(1);
133
+ }
134
+
135
+ static void generate_testvectors(argon2_type type, const uint32_t version) {
136
+ #define TEST_OUTLEN 32
137
+ #define TEST_PWDLEN 32
138
+ #define TEST_SALTLEN 16
139
+ #define TEST_SECRETLEN 8
140
+ #define TEST_ADLEN 12
141
+ argon2_context context;
142
+
143
+ unsigned char out[TEST_OUTLEN];
144
+ unsigned char pwd[TEST_PWDLEN];
145
+ unsigned char salt[TEST_SALTLEN];
146
+ unsigned char secret[TEST_SECRETLEN];
147
+ unsigned char ad[TEST_ADLEN];
148
+ const allocate_fptr myown_allocator = NULL;
149
+ const deallocate_fptr myown_deallocator = NULL;
150
+
151
+ unsigned t_cost = 3;
152
+ unsigned m_cost = 32;
153
+ unsigned lanes = 4;
154
+
155
+ memset(pwd, 1, TEST_OUTLEN);
156
+ memset(salt, 2, TEST_SALTLEN);
157
+ memset(secret, 3, TEST_SECRETLEN);
158
+ memset(ad, 4, TEST_ADLEN);
159
+
160
+ context.out = out;
161
+ context.outlen = TEST_OUTLEN;
162
+ context.version = version;
163
+ context.pwd = pwd;
164
+ context.pwdlen = TEST_PWDLEN;
165
+ context.salt = salt;
166
+ context.saltlen = TEST_SALTLEN;
167
+ context.secret = secret;
168
+ context.secretlen = TEST_SECRETLEN;
169
+ context.ad = ad;
170
+ context.adlen = TEST_ADLEN;
171
+ context.t_cost = t_cost;
172
+ context.m_cost = m_cost;
173
+ context.lanes = lanes;
174
+ context.threads = lanes;
175
+ context.allocate_cbk = myown_allocator;
176
+ context.free_cbk = myown_deallocator;
177
+ context.flags = ARGON2_DEFAULT_FLAGS;
178
+
179
+ #undef TEST_OUTLEN
180
+ #undef TEST_PWDLEN
181
+ #undef TEST_SALTLEN
182
+ #undef TEST_SECRETLEN
183
+ #undef TEST_ADLEN
184
+
185
+ argon2_ctx(&context, type);
186
+ }
187
+
188
+ int main(int argc, char *argv[]) {
189
+ /* Get and check Argon2 type */
190
+ const char *type_str = (argc > 1) ? argv[1] : "i";
191
+ argon2_type type = Argon2_i;
192
+ uint32_t version = ARGON2_VERSION_NUMBER;
193
+ if (!strcmp(type_str, "d")) {
194
+ type = Argon2_d;
195
+ } else if (!strcmp(type_str, "i")) {
196
+ type = Argon2_i;
197
+ } else if (!strcmp(type_str, "id")) {
198
+ type = Argon2_id;
199
+ } else {
200
+ fatal("wrong Argon2 type");
201
+ }
202
+
203
+ /* Get and check Argon2 version number */
204
+ if (argc > 2) {
205
+ version = strtoul(argv[2], NULL, 10);
206
+ }
207
+ if (ARGON2_VERSION_10 != version && ARGON2_VERSION_NUMBER != version) {
208
+ fatal("wrong Argon2 version number");
209
+ }
210
+
211
+ generate_testvectors(type, version);
212
+ return ARGON2_OK;
213
+ }
@@ -0,0 +1,51 @@
1
+ /*
2
+ * Argon2 reference source code package - reference C implementations
3
+ *
4
+ * Copyright 2015
5
+ * Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves
6
+ *
7
+ * You may use this work under the terms of a Creative Commons CC0 1.0
8
+ * License/Waiver or the Apache Public License 2.0, at your option. The terms of
9
+ * these licenses can be found at:
10
+ *
11
+ * - CC0 1.0 Universal : https://creativecommons.org/publicdomain/zero/1.0
12
+ * - Apache 2.0 : https://www.apache.org/licenses/LICENSE-2.0
13
+ *
14
+ * You should have received a copy of both of these licenses along with this
15
+ * software. If not, they may be obtained at the above URLs.
16
+ */
17
+
18
+ #ifndef ARGON2_KAT_H
19
+ #define ARGON2_KAT_H
20
+
21
+ #include "core.h"
22
+
23
+ /*
24
+ * Initial KAT function that prints the inputs to the file
25
+ * @param blockhash Array that contains pre-hashing digest
26
+ * @param context Holds inputs
27
+ * @param type Argon2 type
28
+ * @pre blockhash must point to INPUT_INITIAL_HASH_LENGTH bytes
29
+ * @pre context member pointers must point to allocated memory of size according
30
+ * to the length values
31
+ */
32
+ void initial_kat(const uint8_t *blockhash, const argon2_context *context,
33
+ argon2_type type);
34
+
35
+ /*
36
+ * Function that prints the output tag
37
+ * @param out output array pointer
38
+ * @param outlen digest length
39
+ * @pre out must point to @a outlen bytes
40
+ **/
41
+ void print_tag(const void *out, uint32_t outlen);
42
+
43
+ /*
44
+ * Function that prints the internal state at given moment
45
+ * @param instance pointer to the current instance
46
+ * @param pass current pass number
47
+ * @pre instance must have necessary memory allocated
48
+ **/
49
+ void internal_kat(const argon2_instance_t *instance, uint32_t pass);
50
+
51
+ #endif
@@ -0,0 +1,283 @@
1
+ /*
2
+ * Argon2 reference source code package - reference C implementations
3
+ *
4
+ * Copyright 2015
5
+ * Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves
6
+ *
7
+ * You may use this work under the terms of a Creative Commons CC0 1.0
8
+ * License/Waiver or the Apache Public License 2.0, at your option. The terms of
9
+ * these licenses can be found at:
10
+ *
11
+ * - CC0 1.0 Universal : https://creativecommons.org/publicdomain/zero/1.0
12
+ * - Apache 2.0 : https://www.apache.org/licenses/LICENSE-2.0
13
+ *
14
+ * You should have received a copy of both of these licenses along with this
15
+ * software. If not, they may be obtained at the above URLs.
16
+ */
17
+
18
+ #include <stdint.h>
19
+ #include <string.h>
20
+ #include <stdlib.h>
21
+
22
+ #include "argon2.h"
23
+ #include "core.h"
24
+
25
+ #include "blake2/blake2.h"
26
+ #include "blake2/blamka-round-opt.h"
27
+
28
+ /*
29
+ * Function fills a new memory block and optionally XORs the old block over the new one.
30
+ * Memory must be initialized.
31
+ * @param state Pointer to the just produced block. Content will be updated(!)
32
+ * @param ref_block Pointer to the reference block
33
+ * @param next_block Pointer to the block to be XORed over. May coincide with @ref_block
34
+ * @param with_xor Whether to XOR into the new block (1) or just overwrite (0)
35
+ * @pre all block pointers must be valid
36
+ */
37
+ #if defined(__AVX512F__)
38
+ static void fill_block(__m512i *state, const block *ref_block,
39
+ block *next_block, int with_xor) {
40
+ __m512i block_XY[ARGON2_512BIT_WORDS_IN_BLOCK];
41
+ unsigned int i;
42
+
43
+ if (with_xor) {
44
+ for (i = 0; i < ARGON2_512BIT_WORDS_IN_BLOCK; i++) {
45
+ state[i] = _mm512_xor_si512(
46
+ state[i], _mm512_loadu_si512((const __m512i *)ref_block->v + i));
47
+ block_XY[i] = _mm512_xor_si512(
48
+ state[i], _mm512_loadu_si512((const __m512i *)next_block->v + i));
49
+ }
50
+ } else {
51
+ for (i = 0; i < ARGON2_512BIT_WORDS_IN_BLOCK; i++) {
52
+ block_XY[i] = state[i] = _mm512_xor_si512(
53
+ state[i], _mm512_loadu_si512((const __m512i *)ref_block->v + i));
54
+ }
55
+ }
56
+
57
+ for (i = 0; i < 2; ++i) {
58
+ BLAKE2_ROUND_1(
59
+ state[8 * i + 0], state[8 * i + 1], state[8 * i + 2], state[8 * i + 3],
60
+ state[8 * i + 4], state[8 * i + 5], state[8 * i + 6], state[8 * i + 7]);
61
+ }
62
+
63
+ for (i = 0; i < 2; ++i) {
64
+ BLAKE2_ROUND_2(
65
+ state[2 * 0 + i], state[2 * 1 + i], state[2 * 2 + i], state[2 * 3 + i],
66
+ state[2 * 4 + i], state[2 * 5 + i], state[2 * 6 + i], state[2 * 7 + i]);
67
+ }
68
+
69
+ for (i = 0; i < ARGON2_512BIT_WORDS_IN_BLOCK; i++) {
70
+ state[i] = _mm512_xor_si512(state[i], block_XY[i]);
71
+ _mm512_storeu_si512((__m512i *)next_block->v + i, state[i]);
72
+ }
73
+ }
74
+ #elif defined(__AVX2__)
75
+ static void fill_block(__m256i *state, const block *ref_block,
76
+ block *next_block, int with_xor) {
77
+ __m256i block_XY[ARGON2_HWORDS_IN_BLOCK];
78
+ unsigned int i;
79
+
80
+ if (with_xor) {
81
+ for (i = 0; i < ARGON2_HWORDS_IN_BLOCK; i++) {
82
+ state[i] = _mm256_xor_si256(
83
+ state[i], _mm256_loadu_si256((const __m256i *)ref_block->v + i));
84
+ block_XY[i] = _mm256_xor_si256(
85
+ state[i], _mm256_loadu_si256((const __m256i *)next_block->v + i));
86
+ }
87
+ } else {
88
+ for (i = 0; i < ARGON2_HWORDS_IN_BLOCK; i++) {
89
+ block_XY[i] = state[i] = _mm256_xor_si256(
90
+ state[i], _mm256_loadu_si256((const __m256i *)ref_block->v + i));
91
+ }
92
+ }
93
+
94
+ for (i = 0; i < 4; ++i) {
95
+ BLAKE2_ROUND_1(state[8 * i + 0], state[8 * i + 4], state[8 * i + 1], state[8 * i + 5],
96
+ state[8 * i + 2], state[8 * i + 6], state[8 * i + 3], state[8 * i + 7]);
97
+ }
98
+
99
+ for (i = 0; i < 4; ++i) {
100
+ BLAKE2_ROUND_2(state[ 0 + i], state[ 4 + i], state[ 8 + i], state[12 + i],
101
+ state[16 + i], state[20 + i], state[24 + i], state[28 + i]);
102
+ }
103
+
104
+ for (i = 0; i < ARGON2_HWORDS_IN_BLOCK; i++) {
105
+ state[i] = _mm256_xor_si256(state[i], block_XY[i]);
106
+ _mm256_storeu_si256((__m256i *)next_block->v + i, state[i]);
107
+ }
108
+ }
109
+ #else
110
+ static void fill_block(__m128i *state, const block *ref_block,
111
+ block *next_block, int with_xor) {
112
+ __m128i block_XY[ARGON2_OWORDS_IN_BLOCK];
113
+ unsigned int i;
114
+
115
+ if (with_xor) {
116
+ for (i = 0; i < ARGON2_OWORDS_IN_BLOCK; i++) {
117
+ state[i] = _mm_xor_si128(
118
+ state[i], _mm_loadu_si128((const __m128i *)ref_block->v + i));
119
+ block_XY[i] = _mm_xor_si128(
120
+ state[i], _mm_loadu_si128((const __m128i *)next_block->v + i));
121
+ }
122
+ } else {
123
+ for (i = 0; i < ARGON2_OWORDS_IN_BLOCK; i++) {
124
+ block_XY[i] = state[i] = _mm_xor_si128(
125
+ state[i], _mm_loadu_si128((const __m128i *)ref_block->v + i));
126
+ }
127
+ }
128
+
129
+ for (i = 0; i < 8; ++i) {
130
+ BLAKE2_ROUND(state[8 * i + 0], state[8 * i + 1], state[8 * i + 2],
131
+ state[8 * i + 3], state[8 * i + 4], state[8 * i + 5],
132
+ state[8 * i + 6], state[8 * i + 7]);
133
+ }
134
+
135
+ for (i = 0; i < 8; ++i) {
136
+ BLAKE2_ROUND(state[8 * 0 + i], state[8 * 1 + i], state[8 * 2 + i],
137
+ state[8 * 3 + i], state[8 * 4 + i], state[8 * 5 + i],
138
+ state[8 * 6 + i], state[8 * 7 + i]);
139
+ }
140
+
141
+ for (i = 0; i < ARGON2_OWORDS_IN_BLOCK; i++) {
142
+ state[i] = _mm_xor_si128(state[i], block_XY[i]);
143
+ _mm_storeu_si128((__m128i *)next_block->v + i, state[i]);
144
+ }
145
+ }
146
+ #endif
147
+
148
+ static void next_addresses(block *address_block, block *input_block) {
149
+ /*Temporary zero-initialized blocks*/
150
+ #if defined(__AVX512F__)
151
+ __m512i zero_block[ARGON2_512BIT_WORDS_IN_BLOCK];
152
+ __m512i zero2_block[ARGON2_512BIT_WORDS_IN_BLOCK];
153
+ #elif defined(__AVX2__)
154
+ __m256i zero_block[ARGON2_HWORDS_IN_BLOCK];
155
+ __m256i zero2_block[ARGON2_HWORDS_IN_BLOCK];
156
+ #else
157
+ __m128i zero_block[ARGON2_OWORDS_IN_BLOCK];
158
+ __m128i zero2_block[ARGON2_OWORDS_IN_BLOCK];
159
+ #endif
160
+
161
+ memset(zero_block, 0, sizeof(zero_block));
162
+ memset(zero2_block, 0, sizeof(zero2_block));
163
+
164
+ /*Increasing index counter*/
165
+ input_block->v[6]++;
166
+
167
+ /*First iteration of G*/
168
+ fill_block(zero_block, input_block, address_block, 0);
169
+
170
+ /*Second iteration of G*/
171
+ fill_block(zero2_block, address_block, address_block, 0);
172
+ }
173
+
174
+ void fill_segment(const argon2_instance_t *instance,
175
+ argon2_position_t position) {
176
+ block *ref_block = NULL, *curr_block = NULL;
177
+ block address_block, input_block;
178
+ uint64_t pseudo_rand, ref_index, ref_lane;
179
+ uint32_t prev_offset, curr_offset;
180
+ uint32_t starting_index, i;
181
+ #if defined(__AVX512F__)
182
+ __m512i state[ARGON2_512BIT_WORDS_IN_BLOCK];
183
+ #elif defined(__AVX2__)
184
+ __m256i state[ARGON2_HWORDS_IN_BLOCK];
185
+ #else
186
+ __m128i state[ARGON2_OWORDS_IN_BLOCK];
187
+ #endif
188
+ int data_independent_addressing;
189
+
190
+ if (instance == NULL) {
191
+ return;
192
+ }
193
+
194
+ data_independent_addressing =
195
+ (instance->type == Argon2_i) ||
196
+ (instance->type == Argon2_id && (position.pass == 0) &&
197
+ (position.slice < ARGON2_SYNC_POINTS / 2));
198
+
199
+ if (data_independent_addressing) {
200
+ init_block_value(&input_block, 0);
201
+
202
+ input_block.v[0] = position.pass;
203
+ input_block.v[1] = position.lane;
204
+ input_block.v[2] = position.slice;
205
+ input_block.v[3] = instance->memory_blocks;
206
+ input_block.v[4] = instance->passes;
207
+ input_block.v[5] = instance->type;
208
+ }
209
+
210
+ starting_index = 0;
211
+
212
+ if ((0 == position.pass) && (0 == position.slice)) {
213
+ starting_index = 2; /* we have already generated the first two blocks */
214
+
215
+ /* Don't forget to generate the first block of addresses: */
216
+ if (data_independent_addressing) {
217
+ next_addresses(&address_block, &input_block);
218
+ }
219
+ }
220
+
221
+ /* Offset of the current block */
222
+ curr_offset = position.lane * instance->lane_length +
223
+ position.slice * instance->segment_length + starting_index;
224
+
225
+ if (0 == curr_offset % instance->lane_length) {
226
+ /* Last block in this lane */
227
+ prev_offset = curr_offset + instance->lane_length - 1;
228
+ } else {
229
+ /* Previous block */
230
+ prev_offset = curr_offset - 1;
231
+ }
232
+
233
+ memcpy(state, ((instance->memory + prev_offset)->v), ARGON2_BLOCK_SIZE);
234
+
235
+ for (i = starting_index; i < instance->segment_length;
236
+ ++i, ++curr_offset, ++prev_offset) {
237
+ /*1.1 Rotating prev_offset if needed */
238
+ if (curr_offset % instance->lane_length == 1) {
239
+ prev_offset = curr_offset - 1;
240
+ }
241
+
242
+ /* 1.2 Computing the index of the reference block */
243
+ /* 1.2.1 Taking pseudo-random value from the previous block */
244
+ if (data_independent_addressing) {
245
+ if (i % ARGON2_ADDRESSES_IN_BLOCK == 0) {
246
+ next_addresses(&address_block, &input_block);
247
+ }
248
+ pseudo_rand = address_block.v[i % ARGON2_ADDRESSES_IN_BLOCK];
249
+ } else {
250
+ pseudo_rand = instance->memory[prev_offset].v[0];
251
+ }
252
+
253
+ /* 1.2.2 Computing the lane of the reference block */
254
+ ref_lane = ((pseudo_rand >> 32)) % instance->lanes;
255
+
256
+ if ((position.pass == 0) && (position.slice == 0)) {
257
+ /* Can not reference other lanes yet */
258
+ ref_lane = position.lane;
259
+ }
260
+
261
+ /* 1.2.3 Computing the number of possible reference block within the
262
+ * lane.
263
+ */
264
+ position.index = i;
265
+ ref_index = index_alpha(instance, &position, pseudo_rand & 0xFFFFFFFF,
266
+ ref_lane == position.lane);
267
+
268
+ /* 2 Creating a new block */
269
+ ref_block =
270
+ instance->memory + instance->lane_length * ref_lane + ref_index;
271
+ curr_block = instance->memory + curr_offset;
272
+ if (ARGON2_VERSION_10 == instance->version) {
273
+ /* version 1.2.1 and earlier: overwrite, not XOR */
274
+ fill_block(state, ref_block, curr_block, 0);
275
+ } else {
276
+ if(0 == position.pass) {
277
+ fill_block(state, ref_block, curr_block, 0);
278
+ } else {
279
+ fill_block(state, ref_block, curr_block, 1);
280
+ }
281
+ }
282
+ }
283
+ }