passwordping 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (95) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +16 -0
  3. data/.gitmodules +3 -0
  4. data/Gemfile +4 -0
  5. data/LICENSE +5 -0
  6. data/README.md +89 -0
  7. data/Rakefile +11 -0
  8. data/ext/argon2-wrapper/Makefile +74 -0
  9. data/ext/argon2-wrapper/extconf.rb +1 -0
  10. data/ext/phc-winner-argon2/.gitattributes +10 -0
  11. data/ext/phc-winner-argon2/.gitignore +21 -0
  12. data/ext/phc-winner-argon2/.travis.yml +14 -0
  13. data/ext/phc-winner-argon2/Argon2.sln +160 -0
  14. data/ext/phc-winner-argon2/CHANGELOG.md +25 -0
  15. data/ext/phc-winner-argon2/LICENSE +314 -0
  16. data/ext/phc-winner-argon2/Makefile +187 -0
  17. data/ext/phc-winner-argon2/README.md +290 -0
  18. data/ext/phc-winner-argon2/appveyor.yml +25 -0
  19. data/ext/phc-winner-argon2/argon2-specs.pdf +0 -0
  20. data/ext/phc-winner-argon2/export.sh +7 -0
  21. data/ext/phc-winner-argon2/include/argon2.h +435 -0
  22. data/ext/phc-winner-argon2/kats/argon2d +12304 -0
  23. data/ext/phc-winner-argon2/kats/argon2d.shasum +1 -0
  24. data/ext/phc-winner-argon2/kats/argon2d_v16 +12304 -0
  25. data/ext/phc-winner-argon2/kats/argon2d_v16.shasum +1 -0
  26. data/ext/phc-winner-argon2/kats/argon2i +12304 -0
  27. data/ext/phc-winner-argon2/kats/argon2i.shasum +1 -0
  28. data/ext/phc-winner-argon2/kats/argon2i_v16 +12304 -0
  29. data/ext/phc-winner-argon2/kats/argon2i_v16.shasum +1 -0
  30. data/ext/phc-winner-argon2/kats/argon2id +12304 -0
  31. data/ext/phc-winner-argon2/kats/argon2id.shasum +1 -0
  32. data/ext/phc-winner-argon2/kats/argon2id_v16 +12304 -0
  33. data/ext/phc-winner-argon2/kats/argon2id_v16.shasum +1 -0
  34. data/ext/phc-winner-argon2/kats/check-sums.ps1 +42 -0
  35. data/ext/phc-winner-argon2/kats/check-sums.sh +13 -0
  36. data/ext/phc-winner-argon2/kats/test.ps1 +50 -0
  37. data/ext/phc-winner-argon2/kats/test.sh +49 -0
  38. data/ext/phc-winner-argon2/latex/IEEEtran.cls +6347 -0
  39. data/ext/phc-winner-argon2/latex/Makefile +18 -0
  40. data/ext/phc-winner-argon2/latex/argon2-specs.tex +920 -0
  41. data/ext/phc-winner-argon2/latex/pics/argon2-par.pdf +0 -0
  42. data/ext/phc-winner-argon2/latex/pics/compression.pdf +0 -0
  43. data/ext/phc-winner-argon2/latex/pics/generic.pdf +0 -0
  44. data/ext/phc-winner-argon2/latex/pics/power-distribution.jpg +0 -0
  45. data/ext/phc-winner-argon2/latex/tradeoff.bib +822 -0
  46. data/ext/phc-winner-argon2/libargon2.pc +16 -0
  47. data/ext/phc-winner-argon2/man/argon2.1 +57 -0
  48. data/ext/phc-winner-argon2/src/argon2.c +452 -0
  49. data/ext/phc-winner-argon2/src/bench.c +111 -0
  50. data/ext/phc-winner-argon2/src/blake2/blake2-impl.h +156 -0
  51. data/ext/phc-winner-argon2/src/blake2/blake2.h +91 -0
  52. data/ext/phc-winner-argon2/src/blake2/blake2b.c +390 -0
  53. data/ext/phc-winner-argon2/src/blake2/blamka-round-opt.h +328 -0
  54. data/ext/phc-winner-argon2/src/blake2/blamka-round-ref.h +56 -0
  55. data/ext/phc-winner-argon2/src/core.c +635 -0
  56. data/ext/phc-winner-argon2/src/core.h +227 -0
  57. data/ext/phc-winner-argon2/src/encoding.c +463 -0
  58. data/ext/phc-winner-argon2/src/encoding.h +57 -0
  59. data/ext/phc-winner-argon2/src/genkat.c +208 -0
  60. data/ext/phc-winner-argon2/src/genkat.h +49 -0
  61. data/ext/phc-winner-argon2/src/opt.c +241 -0
  62. data/ext/phc-winner-argon2/src/ref.c +194 -0
  63. data/ext/phc-winner-argon2/src/run.c +317 -0
  64. data/ext/phc-winner-argon2/src/test.c +254 -0
  65. data/ext/phc-winner-argon2/src/thread.c +57 -0
  66. data/ext/phc-winner-argon2/src/thread.h +67 -0
  67. data/ext/phc-winner-argon2/vs2015/Argon2Opt/Argon2Opt.vcxproj +226 -0
  68. data/ext/phc-winner-argon2/vs2015/Argon2Opt/Argon2Opt.vcxproj.filters +69 -0
  69. data/ext/phc-winner-argon2/vs2015/Argon2OptBench/Argon2OptBench.vcxproj +226 -0
  70. data/ext/phc-winner-argon2/vs2015/Argon2OptBench/Argon2OptBench.vcxproj.filters +69 -0
  71. data/ext/phc-winner-argon2/vs2015/Argon2OptDll/Argon2OptDll.vcxproj +225 -0
  72. data/ext/phc-winner-argon2/vs2015/Argon2OptDll/Argon2OptDll.vcxproj.filters +66 -0
  73. data/ext/phc-winner-argon2/vs2015/Argon2OptGenKAT/Argon2OptGenKAT.vcxproj +239 -0
  74. data/ext/phc-winner-argon2/vs2015/Argon2OptGenKAT/Argon2OptGenKAT.vcxproj.filters +72 -0
  75. data/ext/phc-winner-argon2/vs2015/Argon2OptTestCI/Argon2OptTestCI.vcxproj +227 -0
  76. data/ext/phc-winner-argon2/vs2015/Argon2OptTestCI/Argon2OptTestCI.vcxproj.filters +69 -0
  77. data/ext/phc-winner-argon2/vs2015/Argon2Ref/Argon2Ref.vcxproj +226 -0
  78. data/ext/phc-winner-argon2/vs2015/Argon2Ref/Argon2Ref.vcxproj.filters +69 -0
  79. data/ext/phc-winner-argon2/vs2015/Argon2RefBench/Argon2RefBench.vcxproj +226 -0
  80. data/ext/phc-winner-argon2/vs2015/Argon2RefBench/Argon2RefBench.vcxproj.filters +69 -0
  81. data/ext/phc-winner-argon2/vs2015/Argon2RefDll/Argon2RefDll.vcxproj +225 -0
  82. data/ext/phc-winner-argon2/vs2015/Argon2RefDll/Argon2RefDll.vcxproj.filters +66 -0
  83. data/ext/phc-winner-argon2/vs2015/Argon2RefGenKAT/Argon2RefGenKAT.vcxproj +227 -0
  84. data/ext/phc-winner-argon2/vs2015/Argon2RefGenKAT/Argon2RefGenKAT.vcxproj.filters +72 -0
  85. data/ext/phc-winner-argon2/vs2015/Argon2RefTestCI/Argon2RefTestCI.vcxproj +226 -0
  86. data/ext/phc-winner-argon2/vs2015/Argon2RefTestCI/Argon2RefTestCI.vcxproj.filters +69 -0
  87. data/lib/passwordping.rb +186 -0
  88. data/lib/passwordping/argon2_wrapper_ffi.rb +89 -0
  89. data/lib/passwordping/constants.rb +10 -0
  90. data/lib/passwordping/errors.rb +3 -0
  91. data/lib/passwordping/hashing.rb +160 -0
  92. data/lib/passwordping/password_type.rb +24 -0
  93. data/lib/passwordping/version.rb +5 -0
  94. data/passwordping.gemspec +34 -0
  95. metadata +304 -0
@@ -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 : http://creativecommons.org/publicdomain/zero/1.0
12
+ * - Apache 2.0 : http://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,208 @@
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 : http://creativecommons.org/publicdomain/zero/1.0
12
+ * - Apache 2.0 : http://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 <inttypes.h>
19
+ #include <stdio.h>
20
+ #include <stdlib.h>
21
+ #include <string.h>
22
+ #include "argon2.h"
23
+ #include "core.h"
24
+
25
+ void initial_kat(const uint8_t *blockhash, const argon2_context *context,
26
+ argon2_type type) {
27
+ unsigned i;
28
+
29
+ if (blockhash != NULL && context != NULL) {
30
+ printf("=======================================\n");
31
+
32
+ printf("%s version number %d\n", argon2_type2string(type, 1),
33
+ context->version);
34
+
35
+ printf("=======================================\n");
36
+
37
+
38
+ printf("Memory: %u KiB, Iterations: %u, Parallelism: %u lanes, Tag "
39
+ "length: %u bytes\n",
40
+ context->m_cost, context->t_cost, context->lanes,
41
+ context->outlen);
42
+
43
+ printf("Password[%u]: ", context->pwdlen);
44
+
45
+ if (context->flags & ARGON2_FLAG_CLEAR_PASSWORD) {
46
+ printf("CLEARED\n");
47
+ } else {
48
+ for (i = 0; i < context->pwdlen; ++i) {
49
+ printf("%2.2x ", ((unsigned char *)context->pwd)[i]);
50
+ }
51
+
52
+ printf("\n");
53
+ }
54
+
55
+ printf("Salt[%u]: ", context->saltlen);
56
+
57
+ for (i = 0; i < context->saltlen; ++i) {
58
+ printf("%2.2x ", ((unsigned char *)context->salt)[i]);
59
+ }
60
+
61
+ printf("\n");
62
+
63
+ printf("Secret[%u]: ", context->secretlen);
64
+
65
+ if (context->flags & ARGON2_FLAG_CLEAR_SECRET) {
66
+ printf("CLEARED\n");
67
+ } else {
68
+ for (i = 0; i < context->secretlen; ++i) {
69
+ printf("%2.2x ", ((unsigned char *)context->secret)[i]);
70
+ }
71
+
72
+ printf("\n");
73
+ }
74
+
75
+ printf("Associated data[%u]: ", context->adlen);
76
+
77
+ for (i = 0; i < context->adlen; ++i) {
78
+ printf("%2.2x ", ((unsigned char *)context->ad)[i]);
79
+ }
80
+
81
+ printf("\n");
82
+
83
+ printf("Pre-hashing digest: ");
84
+
85
+ for (i = 0; i < ARGON2_PREHASH_DIGEST_LENGTH; ++i) {
86
+ printf("%2.2x ", ((unsigned char *)blockhash)[i]);
87
+ }
88
+
89
+ printf("\n");
90
+ }
91
+ }
92
+
93
+ void print_tag(const void *out, uint32_t outlen) {
94
+ unsigned i;
95
+ if (out != NULL) {
96
+ printf("Tag: ");
97
+
98
+ for (i = 0; i < outlen; ++i) {
99
+ printf("%2.2x ", ((uint8_t *)out)[i]);
100
+ }
101
+
102
+ printf("\n");
103
+ }
104
+ }
105
+
106
+ void internal_kat(const argon2_instance_t *instance, uint32_t pass) {
107
+
108
+ if (instance != NULL) {
109
+ uint32_t i, j;
110
+ printf("\n After pass %u:\n", pass);
111
+
112
+ for (i = 0; i < instance->memory_blocks; ++i) {
113
+ uint32_t how_many_words =
114
+ (instance->memory_blocks > ARGON2_QWORDS_IN_BLOCK)
115
+ ? 1
116
+ : ARGON2_QWORDS_IN_BLOCK;
117
+
118
+ for (j = 0; j < how_many_words; ++j)
119
+ printf("Block %.4u [%3u]: %016" PRIx64 "\n", i, j,
120
+ instance->memory[i].v[j]);
121
+ }
122
+ }
123
+ }
124
+
125
+ static void fatal(const char *error) {
126
+ fprintf(stderr, "Error: %s\n", error);
127
+ exit(1);
128
+ }
129
+
130
+ static void generate_testvectors(argon2_type type, const uint32_t version) {
131
+ #define TEST_OUTLEN 32
132
+ #define TEST_PWDLEN 32
133
+ #define TEST_SALTLEN 16
134
+ #define TEST_SECRETLEN 8
135
+ #define TEST_ADLEN 12
136
+ argon2_context context;
137
+
138
+ unsigned char out[TEST_OUTLEN];
139
+ unsigned char pwd[TEST_PWDLEN];
140
+ unsigned char salt[TEST_SALTLEN];
141
+ unsigned char secret[TEST_SECRETLEN];
142
+ unsigned char ad[TEST_ADLEN];
143
+ const allocate_fptr myown_allocator = NULL;
144
+ const deallocate_fptr myown_deallocator = NULL;
145
+
146
+ unsigned t_cost = 3;
147
+ unsigned m_cost = 32;
148
+ unsigned lanes = 4;
149
+
150
+ memset(pwd, 1, TEST_OUTLEN);
151
+ memset(salt, 2, TEST_SALTLEN);
152
+ memset(secret, 3, TEST_SECRETLEN);
153
+ memset(ad, 4, TEST_ADLEN);
154
+
155
+ context.out = out;
156
+ context.outlen = TEST_OUTLEN;
157
+ context.version = version;
158
+ context.pwd = pwd;
159
+ context.pwdlen = TEST_PWDLEN;
160
+ context.salt = salt;
161
+ context.saltlen = TEST_SALTLEN;
162
+ context.secret = secret;
163
+ context.secretlen = TEST_SECRETLEN;
164
+ context.ad = ad;
165
+ context.adlen = TEST_ADLEN;
166
+ context.t_cost = t_cost;
167
+ context.m_cost = m_cost;
168
+ context.lanes = lanes;
169
+ context.threads = lanes;
170
+ context.allocate_cbk = myown_allocator;
171
+ context.free_cbk = myown_deallocator;
172
+ context.flags = ARGON2_DEFAULT_FLAGS;
173
+
174
+ #undef TEST_OUTLEN
175
+ #undef TEST_PWDLEN
176
+ #undef TEST_SALTLEN
177
+ #undef TEST_SECRETLEN
178
+ #undef TEST_ADLEN
179
+
180
+ argon2_ctx(&context, type);
181
+ }
182
+
183
+ int main(int argc, char *argv[]) {
184
+ /* Get and check Argon2 type */
185
+ const char *type_str = (argc > 1) ? argv[1] : "i";
186
+ argon2_type type = Argon2_i;
187
+ uint32_t version = ARGON2_VERSION_NUMBER;
188
+ if (!strcmp(type_str, "d")) {
189
+ type = Argon2_d;
190
+ } else if (!strcmp(type_str, "i")) {
191
+ type = Argon2_i;
192
+ } else if (!strcmp(type_str, "id")) {
193
+ type = Argon2_id;
194
+ } else {
195
+ fatal("wrong Argon2 type");
196
+ }
197
+
198
+ /* Get and check Argon2 version number */
199
+ if (argc > 2) {
200
+ version = strtoul(argv[2], NULL, 10);
201
+ }
202
+ if (ARGON2_VERSION_10 != version && ARGON2_VERSION_NUMBER != version) {
203
+ fatal("wrong Argon2 version number");
204
+ }
205
+
206
+ generate_testvectors(type, version);
207
+ return ARGON2_OK;
208
+ }
@@ -0,0 +1,49 @@
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 : http://creativecommons.org/publicdomain/zero/1.0
12
+ * - Apache 2.0 : http://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
+ /*
22
+ * Initial KAT function that prints the inputs to the file
23
+ * @param blockhash Array that contains pre-hashing digest
24
+ * @param context Holds inputs
25
+ * @param type Argon2 type
26
+ * @pre blockhash must point to INPUT_INITIAL_HASH_LENGTH bytes
27
+ * @pre context member pointers must point to allocated memory of size according
28
+ * to the length values
29
+ */
30
+ void initial_kat(const uint8_t *blockhash, const argon2_context *context,
31
+ argon2_type type);
32
+
33
+ /*
34
+ * Function that prints the output tag
35
+ * @param out output array pointer
36
+ * @param outlen digest length
37
+ * @pre out must point to @a outlen bytes
38
+ **/
39
+ void print_tag(const void *out, uint32_t outlen);
40
+
41
+ /*
42
+ * Function that prints the internal state at given moment
43
+ * @param instance pointer to the current instance
44
+ * @param pass current pass number
45
+ * @pre instance must have necessary memory allocated
46
+ **/
47
+ void internal_kat(const argon2_instance_t *instance, uint32_t pass);
48
+
49
+ #endif
@@ -0,0 +1,241 @@
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 : http://creativecommons.org/publicdomain/zero/1.0
12
+ * - Apache 2.0 : http://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(__AVX2__)
38
+ static void fill_block(__m256i *state, const block *ref_block,
39
+ block *next_block, int with_xor) {
40
+ __m256i block_XY[ARGON2_HWORDS_IN_BLOCK];
41
+ unsigned int i;
42
+
43
+ if (with_xor) {
44
+ for (i = 0; i < ARGON2_HWORDS_IN_BLOCK; i++) {
45
+ state[i] = _mm256_xor_si256(
46
+ state[i], _mm256_loadu_si256((const __m256i *)ref_block->v + i));
47
+ block_XY[i] = _mm256_xor_si256(
48
+ state[i], _mm256_loadu_si256((const __m256i *)next_block->v + i));
49
+ }
50
+ } else {
51
+ for (i = 0; i < ARGON2_HWORDS_IN_BLOCK; i++) {
52
+ block_XY[i] = state[i] = _mm256_xor_si256(
53
+ state[i], _mm256_loadu_si256((const __m256i *)ref_block->v + i));
54
+ }
55
+ }
56
+
57
+ for (i = 0; i < 4; ++i) {
58
+ BLAKE2_ROUND_1(state[8 * i + 0], state[8 * i + 4], state[8 * i + 1], state[8 * i + 5],
59
+ state[8 * i + 2], state[8 * i + 6], state[8 * i + 3], state[8 * i + 7]);
60
+ }
61
+
62
+ for (i = 0; i < 4; ++i) {
63
+ BLAKE2_ROUND_2(state[ 0 + i], state[ 4 + i], state[ 8 + i], state[12 + i],
64
+ state[16 + i], state[20 + i], state[24 + i], state[28 + i]);
65
+ }
66
+
67
+ for (i = 0; i < ARGON2_HWORDS_IN_BLOCK; i++) {
68
+ state[i] = _mm256_xor_si256(state[i], block_XY[i]);
69
+ _mm256_storeu_si256((__m256i *)next_block->v + i, state[i]);
70
+ }
71
+ }
72
+ #else
73
+ static void fill_block(__m128i *state, const block *ref_block,
74
+ block *next_block, int with_xor) {
75
+ __m128i block_XY[ARGON2_OWORDS_IN_BLOCK];
76
+ unsigned int i;
77
+
78
+ if (with_xor) {
79
+ for (i = 0; i < ARGON2_OWORDS_IN_BLOCK; i++) {
80
+ state[i] = _mm_xor_si128(
81
+ state[i], _mm_loadu_si128((const __m128i *)ref_block->v + i));
82
+ block_XY[i] = _mm_xor_si128(
83
+ state[i], _mm_loadu_si128((const __m128i *)next_block->v + i));
84
+ }
85
+ } else {
86
+ for (i = 0; i < ARGON2_OWORDS_IN_BLOCK; i++) {
87
+ block_XY[i] = state[i] = _mm_xor_si128(
88
+ state[i], _mm_loadu_si128((const __m128i *)ref_block->v + i));
89
+ }
90
+ }
91
+
92
+ for (i = 0; i < 8; ++i) {
93
+ BLAKE2_ROUND(state[8 * i + 0], state[8 * i + 1], state[8 * i + 2],
94
+ state[8 * i + 3], state[8 * i + 4], state[8 * i + 5],
95
+ state[8 * i + 6], state[8 * i + 7]);
96
+ }
97
+
98
+ for (i = 0; i < 8; ++i) {
99
+ BLAKE2_ROUND(state[8 * 0 + i], state[8 * 1 + i], state[8 * 2 + i],
100
+ state[8 * 3 + i], state[8 * 4 + i], state[8 * 5 + i],
101
+ state[8 * 6 + i], state[8 * 7 + i]);
102
+ }
103
+
104
+ for (i = 0; i < ARGON2_OWORDS_IN_BLOCK; i++) {
105
+ state[i] = _mm_xor_si128(state[i], block_XY[i]);
106
+ _mm_storeu_si128((__m128i *)next_block->v + i, state[i]);
107
+ }
108
+ }
109
+ #endif
110
+
111
+ static void next_addresses(block *address_block, block *input_block) {
112
+ /*Temporary zero-initialized blocks*/
113
+ #if defined(__AVX2__)
114
+ __m256i zero_block[ARGON2_HWORDS_IN_BLOCK];
115
+ __m256i zero2_block[ARGON2_HWORDS_IN_BLOCK];
116
+ #else
117
+ __m128i zero_block[ARGON2_OWORDS_IN_BLOCK];
118
+ __m128i zero2_block[ARGON2_OWORDS_IN_BLOCK];
119
+ #endif
120
+
121
+ memset(zero_block, 0, sizeof(zero_block));
122
+ memset(zero2_block, 0, sizeof(zero2_block));
123
+
124
+ /*Increasing index counter*/
125
+ input_block->v[6]++;
126
+
127
+ /*First iteration of G*/
128
+ fill_block(zero_block, input_block, address_block, 0);
129
+
130
+ /*Second iteration of G*/
131
+ fill_block(zero2_block, address_block, address_block, 0);
132
+ }
133
+
134
+ void fill_segment(const argon2_instance_t *instance,
135
+ argon2_position_t position) {
136
+ block *ref_block = NULL, *curr_block = NULL;
137
+ block address_block, input_block;
138
+ uint64_t pseudo_rand, ref_index, ref_lane;
139
+ uint32_t prev_offset, curr_offset;
140
+ uint32_t starting_index, i;
141
+ #if defined(__AVX2__)
142
+ __m256i state[32];
143
+ #else
144
+ __m128i state[64];
145
+ #endif
146
+ int data_independent_addressing;
147
+
148
+ if (instance == NULL) {
149
+ return;
150
+ }
151
+
152
+ data_independent_addressing =
153
+ (instance->type == Argon2_i) ||
154
+ (instance->type == Argon2_id && (position.pass == 0) &&
155
+ (position.slice < ARGON2_SYNC_POINTS / 2));
156
+
157
+ if (data_independent_addressing) {
158
+ init_block_value(&input_block, 0);
159
+
160
+ input_block.v[0] = position.pass;
161
+ input_block.v[1] = position.lane;
162
+ input_block.v[2] = position.slice;
163
+ input_block.v[3] = instance->memory_blocks;
164
+ input_block.v[4] = instance->passes;
165
+ input_block.v[5] = instance->type;
166
+ }
167
+
168
+ starting_index = 0;
169
+
170
+ if ((0 == position.pass) && (0 == position.slice)) {
171
+ starting_index = 2; /* we have already generated the first two blocks */
172
+
173
+ /* Don't forget to generate the first block of addresses: */
174
+ if (data_independent_addressing) {
175
+ next_addresses(&address_block, &input_block);
176
+ }
177
+ }
178
+
179
+ /* Offset of the current block */
180
+ curr_offset = position.lane * instance->lane_length +
181
+ position.slice * instance->segment_length + starting_index;
182
+
183
+ if (0 == curr_offset % instance->lane_length) {
184
+ /* Last block in this lane */
185
+ prev_offset = curr_offset + instance->lane_length - 1;
186
+ } else {
187
+ /* Previous block */
188
+ prev_offset = curr_offset - 1;
189
+ }
190
+
191
+ memcpy(state, ((instance->memory + prev_offset)->v), ARGON2_BLOCK_SIZE);
192
+
193
+ for (i = starting_index; i < instance->segment_length;
194
+ ++i, ++curr_offset, ++prev_offset) {
195
+ /*1.1 Rotating prev_offset if needed */
196
+ if (curr_offset % instance->lane_length == 1) {
197
+ prev_offset = curr_offset - 1;
198
+ }
199
+
200
+ /* 1.2 Computing the index of the reference block */
201
+ /* 1.2.1 Taking pseudo-random value from the previous block */
202
+ if (data_independent_addressing) {
203
+ if (i % ARGON2_ADDRESSES_IN_BLOCK == 0) {
204
+ next_addresses(&address_block, &input_block);
205
+ }
206
+ pseudo_rand = address_block.v[i % ARGON2_ADDRESSES_IN_BLOCK];
207
+ } else {
208
+ pseudo_rand = instance->memory[prev_offset].v[0];
209
+ }
210
+
211
+ /* 1.2.2 Computing the lane of the reference block */
212
+ ref_lane = ((pseudo_rand >> 32)) % instance->lanes;
213
+
214
+ if ((position.pass == 0) && (position.slice == 0)) {
215
+ /* Can not reference other lanes yet */
216
+ ref_lane = position.lane;
217
+ }
218
+
219
+ /* 1.2.3 Computing the number of possible reference block within the
220
+ * lane.
221
+ */
222
+ position.index = i;
223
+ ref_index = index_alpha(instance, &position, pseudo_rand & 0xFFFFFFFF,
224
+ ref_lane == position.lane);
225
+
226
+ /* 2 Creating a new block */
227
+ ref_block =
228
+ instance->memory + instance->lane_length * ref_lane + ref_index;
229
+ curr_block = instance->memory + curr_offset;
230
+ if (ARGON2_VERSION_10 == instance->version) {
231
+ /* version 1.2.1 and earlier: overwrite, not XOR */
232
+ fill_block(state, ref_block, curr_block, 0);
233
+ } else {
234
+ if(0 == position.pass) {
235
+ fill_block(state, ref_block, curr_block, 0);
236
+ } else {
237
+ fill_block(state, ref_block, curr_block, 1);
238
+ }
239
+ }
240
+ }
241
+ }