enzoic 1.0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (106) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +19 -0
  3. data/.gitmodules +3 -0
  4. data/.travis.yml +3 -0
  5. data/Gemfile +4 -0
  6. data/LICENSE +5 -0
  7. data/README.md +90 -0
  8. data/Rakefile +28 -0
  9. data/enzoic.gemspec +36 -0
  10. data/ext/.DS_Store +0 -0
  11. data/ext/argon2-wrapper/Makefile +74 -0
  12. data/ext/argon2-wrapper/argon2-wrapper.c +165 -0
  13. data/ext/argon2-wrapper/extconf.rb +1 -0
  14. data/ext/argon2_import/.DS_Store +0 -0
  15. data/ext/digest/whirlpool/extconf.rb +10 -0
  16. data/ext/digest/whirlpool/whirlpool-algorithm.c +476 -0
  17. data/ext/digest/whirlpool/whirlpool-algorithm.h +86 -0
  18. data/ext/digest/whirlpool/whirlpool-constants.h +1116 -0
  19. data/ext/digest/whirlpool/whirlpool-portability.h +142 -0
  20. data/ext/digest/whirlpool/whirlpool.c +51 -0
  21. data/ext/phc-winner-argon2/.gitattributes +10 -0
  22. data/ext/phc-winner-argon2/.gitignore +21 -0
  23. data/ext/phc-winner-argon2/.travis.yml +14 -0
  24. data/ext/phc-winner-argon2/Argon2.sln +160 -0
  25. data/ext/phc-winner-argon2/CHANGELOG.md +25 -0
  26. data/ext/phc-winner-argon2/LICENSE +314 -0
  27. data/ext/phc-winner-argon2/Makefile +187 -0
  28. data/ext/phc-winner-argon2/README.md +290 -0
  29. data/ext/phc-winner-argon2/appveyor.yml +25 -0
  30. data/ext/phc-winner-argon2/argon2-specs.pdf +0 -0
  31. data/ext/phc-winner-argon2/export.sh +7 -0
  32. data/ext/phc-winner-argon2/include/argon2.h +435 -0
  33. data/ext/phc-winner-argon2/kats/argon2d +12304 -0
  34. data/ext/phc-winner-argon2/kats/argon2d.shasum +1 -0
  35. data/ext/phc-winner-argon2/kats/argon2d_v16 +12304 -0
  36. data/ext/phc-winner-argon2/kats/argon2d_v16.shasum +1 -0
  37. data/ext/phc-winner-argon2/kats/argon2i +12304 -0
  38. data/ext/phc-winner-argon2/kats/argon2i.shasum +1 -0
  39. data/ext/phc-winner-argon2/kats/argon2i_v16 +12304 -0
  40. data/ext/phc-winner-argon2/kats/argon2i_v16.shasum +1 -0
  41. data/ext/phc-winner-argon2/kats/argon2id +12304 -0
  42. data/ext/phc-winner-argon2/kats/argon2id.shasum +1 -0
  43. data/ext/phc-winner-argon2/kats/argon2id_v16 +12304 -0
  44. data/ext/phc-winner-argon2/kats/argon2id_v16.shasum +1 -0
  45. data/ext/phc-winner-argon2/kats/check-sums.ps1 +42 -0
  46. data/ext/phc-winner-argon2/kats/check-sums.sh +13 -0
  47. data/ext/phc-winner-argon2/kats/test.ps1 +50 -0
  48. data/ext/phc-winner-argon2/kats/test.sh +49 -0
  49. data/ext/phc-winner-argon2/latex/IEEEtran.cls +6347 -0
  50. data/ext/phc-winner-argon2/latex/Makefile +18 -0
  51. data/ext/phc-winner-argon2/latex/argon2-specs.tex +920 -0
  52. data/ext/phc-winner-argon2/latex/pics/argon2-par.pdf +0 -0
  53. data/ext/phc-winner-argon2/latex/pics/compression.pdf +0 -0
  54. data/ext/phc-winner-argon2/latex/pics/generic.pdf +0 -0
  55. data/ext/phc-winner-argon2/latex/pics/power-distribution.jpg +0 -0
  56. data/ext/phc-winner-argon2/latex/tradeoff.bib +822 -0
  57. data/ext/phc-winner-argon2/libargon2.pc +16 -0
  58. data/ext/phc-winner-argon2/man/argon2.1 +57 -0
  59. data/ext/phc-winner-argon2/src/argon2.c +452 -0
  60. data/ext/phc-winner-argon2/src/bench.c +111 -0
  61. data/ext/phc-winner-argon2/src/blake2/blake2-impl.h +156 -0
  62. data/ext/phc-winner-argon2/src/blake2/blake2.h +91 -0
  63. data/ext/phc-winner-argon2/src/blake2/blake2b.c +390 -0
  64. data/ext/phc-winner-argon2/src/blake2/blamka-round-opt.h +328 -0
  65. data/ext/phc-winner-argon2/src/blake2/blamka-round-ref.h +56 -0
  66. data/ext/phc-winner-argon2/src/core.c +635 -0
  67. data/ext/phc-winner-argon2/src/core.h +227 -0
  68. data/ext/phc-winner-argon2/src/encoding.c +463 -0
  69. data/ext/phc-winner-argon2/src/encoding.h +57 -0
  70. data/ext/phc-winner-argon2/src/genkat.c +208 -0
  71. data/ext/phc-winner-argon2/src/genkat.h +49 -0
  72. data/ext/phc-winner-argon2/src/opt.c +241 -0
  73. data/ext/phc-winner-argon2/src/ref.c +194 -0
  74. data/ext/phc-winner-argon2/src/run.c +317 -0
  75. data/ext/phc-winner-argon2/src/test.c +254 -0
  76. data/ext/phc-winner-argon2/src/thread.c +57 -0
  77. data/ext/phc-winner-argon2/src/thread.h +67 -0
  78. data/ext/phc-winner-argon2/vs2015/Argon2Opt/Argon2Opt.vcxproj +226 -0
  79. data/ext/phc-winner-argon2/vs2015/Argon2Opt/Argon2Opt.vcxproj.filters +69 -0
  80. data/ext/phc-winner-argon2/vs2015/Argon2OptBench/Argon2OptBench.vcxproj +226 -0
  81. data/ext/phc-winner-argon2/vs2015/Argon2OptBench/Argon2OptBench.vcxproj.filters +69 -0
  82. data/ext/phc-winner-argon2/vs2015/Argon2OptDll/Argon2OptDll.vcxproj +225 -0
  83. data/ext/phc-winner-argon2/vs2015/Argon2OptDll/Argon2OptDll.vcxproj.filters +66 -0
  84. data/ext/phc-winner-argon2/vs2015/Argon2OptGenKAT/Argon2OptGenKAT.vcxproj +239 -0
  85. data/ext/phc-winner-argon2/vs2015/Argon2OptGenKAT/Argon2OptGenKAT.vcxproj.filters +72 -0
  86. data/ext/phc-winner-argon2/vs2015/Argon2OptTestCI/Argon2OptTestCI.vcxproj +227 -0
  87. data/ext/phc-winner-argon2/vs2015/Argon2OptTestCI/Argon2OptTestCI.vcxproj.filters +69 -0
  88. data/ext/phc-winner-argon2/vs2015/Argon2Ref/Argon2Ref.vcxproj +226 -0
  89. data/ext/phc-winner-argon2/vs2015/Argon2Ref/Argon2Ref.vcxproj.filters +69 -0
  90. data/ext/phc-winner-argon2/vs2015/Argon2RefBench/Argon2RefBench.vcxproj +226 -0
  91. data/ext/phc-winner-argon2/vs2015/Argon2RefBench/Argon2RefBench.vcxproj.filters +69 -0
  92. data/ext/phc-winner-argon2/vs2015/Argon2RefDll/Argon2RefDll.vcxproj +225 -0
  93. data/ext/phc-winner-argon2/vs2015/Argon2RefDll/Argon2RefDll.vcxproj.filters +66 -0
  94. data/ext/phc-winner-argon2/vs2015/Argon2RefGenKAT/Argon2RefGenKAT.vcxproj +227 -0
  95. data/ext/phc-winner-argon2/vs2015/Argon2RefGenKAT/Argon2RefGenKAT.vcxproj.filters +72 -0
  96. data/ext/phc-winner-argon2/vs2015/Argon2RefTestCI/Argon2RefTestCI.vcxproj +226 -0
  97. data/ext/phc-winner-argon2/vs2015/Argon2RefTestCI/Argon2RefTestCI.vcxproj.filters +69 -0
  98. data/lib/enzoic.rb +189 -0
  99. data/lib/enzoic/argon2_errors.rb +39 -0
  100. data/lib/enzoic/argon2_wrapper_ffi.rb +89 -0
  101. data/lib/enzoic/constants.rb +10 -0
  102. data/lib/enzoic/errors.rb +3 -0
  103. data/lib/enzoic/hashing.rb +258 -0
  104. data/lib/enzoic/password_type.rb +25 -0
  105. data/lib/enzoic/version.rb +5 -0
  106. metadata +354 -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
+ }