argon2 1.1.1 → 1.1.2

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 (67) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +7 -4
  3. data/Changelog.md +3 -0
  4. data/README.md +2 -0
  5. data/argon2.gemspec +1 -1
  6. data/ext/argon2_wrap/Makefile +6 -0
  7. data/ext/argon2_wrap/argon_wrap.c +1 -7
  8. data/ext/phc-winner-argon2/.gitignore +1 -0
  9. data/ext/phc-winner-argon2/Argon2.sln +64 -2
  10. data/ext/phc-winner-argon2/CHANGELOG.md +8 -1
  11. data/ext/phc-winner-argon2/LICENSE +301 -18
  12. data/ext/phc-winner-argon2/Makefile +85 -20
  13. data/ext/phc-winner-argon2/README.md +73 -30
  14. data/ext/phc-winner-argon2/argon2-specs.pdf +0 -0
  15. data/ext/phc-winner-argon2/include/argon2.h +73 -10
  16. data/ext/phc-winner-argon2/kats/argon2id +12304 -0
  17. data/ext/phc-winner-argon2/kats/argon2id.shasum +1 -0
  18. data/ext/phc-winner-argon2/kats/argon2id_v16 +12304 -0
  19. data/ext/phc-winner-argon2/kats/argon2id_v16.shasum +1 -0
  20. data/ext/phc-winner-argon2/kats/test.ps1 +1 -1
  21. data/ext/phc-winner-argon2/kats/test.sh +1 -1
  22. data/ext/phc-winner-argon2/latex/IEEEtran.cls +6347 -0
  23. data/ext/phc-winner-argon2/latex/argon2-spec.tex +920 -0
  24. data/ext/phc-winner-argon2/latex/pics/argon2-par.pdf +0 -0
  25. data/ext/phc-winner-argon2/latex/pics/compression.pdf +0 -0
  26. data/ext/phc-winner-argon2/latex/pics/generic.pdf +0 -0
  27. data/ext/phc-winner-argon2/latex/pics/power-distribution.jpg +0 -0
  28. data/ext/phc-winner-argon2/latex/tradeoff.bib +822 -0
  29. data/ext/phc-winner-argon2/libargon2.pc +16 -0
  30. data/ext/phc-winner-argon2/man/argon2.1 +13 -3
  31. data/ext/phc-winner-argon2/src/argon2.c +112 -68
  32. data/ext/phc-winner-argon2/src/bench.c +44 -27
  33. data/ext/phc-winner-argon2/src/blake2/blake2-impl.h +18 -5
  34. data/ext/phc-winner-argon2/src/blake2/blake2.h +17 -0
  35. data/ext/phc-winner-argon2/src/blake2/blake2b.c +25 -7
  36. data/ext/phc-winner-argon2/src/blake2/blamka-round-opt.h +17 -0
  37. data/ext/phc-winner-argon2/src/blake2/blamka-round-ref.h +17 -0
  38. data/ext/phc-winner-argon2/src/core.c +138 -110
  39. data/ext/phc-winner-argon2/src/core.h +41 -26
  40. data/ext/phc-winner-argon2/src/encoding.c +79 -55
  41. data/ext/phc-winner-argon2/src/encoding.h +25 -8
  42. data/ext/phc-winner-argon2/src/genkat.c +35 -39
  43. data/ext/phc-winner-argon2/src/genkat.h +11 -7
  44. data/ext/phc-winner-argon2/src/opt.c +65 -99
  45. data/ext/phc-winner-argon2/src/opt.h +15 -32
  46. data/ext/phc-winner-argon2/src/ref.c +50 -93
  47. data/ext/phc-winner-argon2/src/ref.h +15 -31
  48. data/ext/phc-winner-argon2/src/run.c +73 -30
  49. data/ext/phc-winner-argon2/src/test.c +33 -2
  50. data/ext/phc-winner-argon2/src/thread.c +21 -0
  51. data/ext/phc-winner-argon2/src/thread.h +21 -0
  52. data/ext/phc-winner-argon2/vs2015/Argon2Opt/Argon2Opt.vcxproj +69 -1
  53. data/ext/phc-winner-argon2/vs2015/Argon2OptBench/Argon2OptBench.vcxproj +69 -1
  54. data/ext/phc-winner-argon2/vs2015/Argon2OptDll/Argon2OptDll.vcxproj +225 -0
  55. data/ext/phc-winner-argon2/vs2015/Argon2OptDll/Argon2OptDll.vcxproj.filters +66 -0
  56. data/ext/phc-winner-argon2/vs2015/Argon2OptGenKAT/Argon2OptGenKAT.vcxproj +73 -1
  57. data/ext/phc-winner-argon2/vs2015/Argon2OptTestCI/Argon2OptTestCI.vcxproj +69 -1
  58. data/ext/phc-winner-argon2/vs2015/Argon2Ref/Argon2Ref.vcxproj +69 -1
  59. data/ext/phc-winner-argon2/vs2015/Argon2RefBench/Argon2RefBench.vcxproj +69 -1
  60. data/ext/phc-winner-argon2/vs2015/Argon2RefDll/Argon2RefDll.vcxproj +225 -0
  61. data/ext/phc-winner-argon2/vs2015/Argon2RefDll/Argon2RefDll.vcxproj.filters +66 -0
  62. data/ext/phc-winner-argon2/vs2015/Argon2RefGenKAT/Argon2RefGenKAT.vcxproj +69 -1
  63. data/ext/phc-winner-argon2/vs2015/Argon2RefTestCI/Argon2RefTestCI.vcxproj +69 -1
  64. data/lib/argon2.rb +3 -3
  65. data/lib/argon2/ffi_engine.rb +3 -3
  66. data/lib/argon2/version.rb +1 -1
  67. metadata +21 -5
@@ -1,14 +1,18 @@
1
1
  /*
2
- * Argon2 source code package
2
+ * Argon2 reference source code package - reference C implementations
3
3
  *
4
- * Written by Daniel Dinu and Dmitry Khovratovich, 2015
4
+ * Copyright 2015
5
+ * Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves
5
6
  *
6
- * This work is licensed under a Creative Commons CC0 1.0 License/Waiver.
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:
7
10
  *
8
- * You should have received a copy of the CC0 Public Domain Dedication along
9
- * with
10
- * this software. If not, see
11
- * <http://creativecommons.org/publicdomain/zero/1.0/>.
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.
12
16
  */
13
17
 
14
18
  #ifndef ARGON2_KAT_H
@@ -1,14 +1,18 @@
1
1
  /*
2
- * Argon2 source code package
2
+ * Argon2 reference source code package - reference C implementations
3
3
  *
4
- * Written by Daniel Dinu and Dmitry Khovratovich, 2015
4
+ * Copyright 2015
5
+ * Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves
5
6
  *
6
- * This work is licensed under a Creative Commons CC0 1.0 License/Waiver.
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:
7
10
  *
8
- * You should have received a copy of the CC0 Public Domain Dedication along
9
- * with
10
- * this software. If not, see
11
- * <http://creativecommons.org/publicdomain/zero/1.0/>.
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.
12
16
  */
13
17
 
14
18
  #include <stdint.h>
@@ -21,13 +25,23 @@
21
25
  #include "blake2/blake2.h"
22
26
  #include "blake2/blamka-round-opt.h"
23
27
 
24
- void fill_block(__m128i *state, const uint8_t *ref_block, uint8_t *next_block) {
28
+ void fill_block(__m128i *state, const block *ref_block, block *next_block,
29
+ int with_xor) {
25
30
  __m128i block_XY[ARGON2_OWORDS_IN_BLOCK];
26
- uint32_t i;
27
-
28
- for (i = 0; i < ARGON2_OWORDS_IN_BLOCK; i++) {
29
- block_XY[i] = state[i] = _mm_xor_si128(
30
- state[i], _mm_loadu_si128((__m128i const *)(&ref_block[16 * i])));
31
+ unsigned int i;
32
+
33
+ if (with_xor) {
34
+ for (i = 0; i < ARGON2_OWORDS_IN_BLOCK; i++) {
35
+ state[i] = _mm_xor_si128(
36
+ state[i], _mm_loadu_si128((const __m128i *)ref_block->v + i));
37
+ block_XY[i] = _mm_xor_si128(
38
+ state[i], _mm_loadu_si128((const __m128i *)next_block->v + i));
39
+ }
40
+ } else {
41
+ for (i = 0; i < ARGON2_OWORDS_IN_BLOCK; i++) {
42
+ block_XY[i] = state[i] = _mm_xor_si128(
43
+ state[i], _mm_loadu_si128((const __m128i *)ref_block->v + i));
44
+ }
31
45
  }
32
46
 
33
47
  for (i = 0; i < 8; ++i) {
@@ -44,113 +58,67 @@ void fill_block(__m128i *state, const uint8_t *ref_block, uint8_t *next_block) {
44
58
 
45
59
  for (i = 0; i < ARGON2_OWORDS_IN_BLOCK; i++) {
46
60
  state[i] = _mm_xor_si128(state[i], block_XY[i]);
47
- _mm_storeu_si128((__m128i *)(&next_block[16 * i]), state[i]);
48
- }
49
- }
50
-
51
- void fill_block_with_xor(__m128i *state, const uint8_t *ref_block,
52
- uint8_t *next_block) {
53
- __m128i block_XY[ARGON2_OWORDS_IN_BLOCK];
54
- uint32_t i;
55
-
56
- for (i = 0; i < ARGON2_OWORDS_IN_BLOCK; i++) {
57
- state[i] = _mm_xor_si128(
58
- state[i], _mm_loadu_si128((__m128i const *)(&ref_block[16 * i])));
59
- block_XY[i] = _mm_xor_si128(
60
- state[i], _mm_loadu_si128((__m128i const *)(&next_block[16 * i])));
61
- }
62
-
63
- for (i = 0; i < 8; ++i) {
64
- BLAKE2_ROUND(state[8 * i + 0], state[8 * i + 1], state[8 * i + 2],
65
- state[8 * i + 3], state[8 * i + 4], state[8 * i + 5],
66
- state[8 * i + 6], state[8 * i + 7]);
67
- }
68
-
69
- for (i = 0; i < 8; ++i) {
70
- BLAKE2_ROUND(state[8 * 0 + i], state[8 * 1 + i], state[8 * 2 + i],
71
- state[8 * 3 + i], state[8 * 4 + i], state[8 * 5 + i],
72
- state[8 * 6 + i], state[8 * 7 + i]);
73
- }
74
-
75
- for (i = 0; i < ARGON2_OWORDS_IN_BLOCK; i++) {
76
- state[i] = _mm_xor_si128(state[i], block_XY[i]);
77
- _mm_storeu_si128((__m128i *)(&next_block[16 * i]), state[i]);
61
+ _mm_storeu_si128((__m128i *)next_block->v + i, state[i]);
78
62
  }
79
63
  }
80
64
 
81
- void generate_addresses(const argon2_instance_t *instance,
82
- const argon2_position_t *position,
83
- uint64_t *pseudo_rands) {
84
- block address_block, input_block, tmp_block;
85
- uint32_t i;
65
+ static void next_addresses(block *address_block, block *input_block) {
66
+ /*Temporary zero-initialized blocks*/
67
+ __m128i zero_block[ARGON2_OWORDS_IN_BLOCK];
68
+ __m128i zero2_block[ARGON2_OWORDS_IN_BLOCK];
86
69
 
87
- init_block_value(&address_block, 0);
88
- init_block_value(&input_block, 0);
70
+ memset(zero_block, 0, sizeof(zero_block));
71
+ memset(zero2_block, 0, sizeof(zero2_block));
89
72
 
90
- if (instance != NULL && position != NULL) {
91
- input_block.v[0] = position->pass;
92
- input_block.v[1] = position->lane;
93
- input_block.v[2] = position->slice;
94
- input_block.v[3] = instance->memory_blocks;
95
- input_block.v[4] = instance->passes;
96
- input_block.v[5] = instance->type;
73
+ /*Increasing index counter*/
74
+ input_block->v[6]++;
97
75
 
98
- for (i = 0; i < instance->segment_length; ++i) {
99
- if (i % ARGON2_ADDRESSES_IN_BLOCK == 0) {
100
- /*Temporary zero-initialized blocks*/
101
- __m128i zero_block[ARGON2_OWORDS_IN_BLOCK];
102
- __m128i zero2_block[ARGON2_OWORDS_IN_BLOCK];
103
- memset(zero_block, 0, sizeof(zero_block));
104
- memset(zero2_block, 0, sizeof(zero2_block));
105
- init_block_value(&address_block, 0);
106
- init_block_value(&tmp_block, 0);
107
- /*Increasing index counter*/
108
- input_block.v[6]++;
109
- /*First iteration of G*/
110
- fill_block_with_xor(zero_block, (uint8_t *)&input_block.v,
111
- (uint8_t *)&tmp_block.v);
112
- /*Second iteration of G*/
113
- fill_block_with_xor(zero2_block, (uint8_t *)&tmp_block.v,
114
- (uint8_t *)&address_block.v);
115
- }
76
+ /*First iteration of G*/
77
+ fill_block(zero_block, input_block, address_block, 0);
116
78
 
117
- pseudo_rands[i] = address_block.v[i % ARGON2_ADDRESSES_IN_BLOCK];
118
- }
119
- }
79
+ /*Second iteration of G*/
80
+ fill_block(zero2_block, address_block, address_block, 0);
120
81
  }
121
82
 
122
83
  void fill_segment(const argon2_instance_t *instance,
123
84
  argon2_position_t position) {
124
85
  block *ref_block = NULL, *curr_block = NULL;
86
+ block address_block, input_block;
125
87
  uint64_t pseudo_rand, ref_index, ref_lane;
126
88
  uint32_t prev_offset, curr_offset;
127
89
  uint32_t starting_index, i;
128
90
  __m128i state[64];
129
91
  int data_independent_addressing;
130
92
 
131
- /* Pseudo-random values that determine the reference block position */
132
- uint64_t *pseudo_rands = NULL;
133
-
134
93
  if (instance == NULL) {
135
94
  return;
136
95
  }
137
96
 
138
- data_independent_addressing = (instance->type == Argon2_i);
139
-
140
- pseudo_rands =
141
- (uint64_t *)malloc(sizeof(uint64_t) * instance->segment_length);
142
- if (pseudo_rands == NULL) {
143
- return;
144
- }
97
+ data_independent_addressing =
98
+ (instance->type == Argon2_i) ||
99
+ (instance->type == Argon2_id && (position.pass == 0) &&
100
+ (position.slice < ARGON2_SYNC_POINTS / 2));
145
101
 
146
102
  if (data_independent_addressing) {
147
- generate_addresses(instance, &position, pseudo_rands);
103
+ init_block_value(&input_block, 0);
104
+
105
+ input_block.v[0] = position.pass;
106
+ input_block.v[1] = position.lane;
107
+ input_block.v[2] = position.slice;
108
+ input_block.v[3] = instance->memory_blocks;
109
+ input_block.v[4] = instance->passes;
110
+ input_block.v[5] = instance->type;
148
111
  }
149
112
 
150
113
  starting_index = 0;
151
114
 
152
115
  if ((0 == position.pass) && (0 == position.slice)) {
153
116
  starting_index = 2; /* we have already generated the first two blocks */
117
+
118
+ /* Don't forget to generate the first block of addresses: */
119
+ if (data_independent_addressing) {
120
+ next_addresses(&address_block, &input_block);
121
+ }
154
122
  }
155
123
 
156
124
  /* Offset of the current block */
@@ -177,7 +145,10 @@ void fill_segment(const argon2_instance_t *instance,
177
145
  /* 1.2 Computing the index of the reference block */
178
146
  /* 1.2.1 Taking pseudo-random value from the previous block */
179
147
  if (data_independent_addressing) {
180
- pseudo_rand = pseudo_rands[i];
148
+ if (i % ARGON2_ADDRESSES_IN_BLOCK == 0) {
149
+ next_addresses(&address_block, &input_block);
150
+ }
151
+ pseudo_rand = address_block.v[i % ARGON2_ADDRESSES_IN_BLOCK];
181
152
  } else {
182
153
  pseudo_rand = instance->memory[prev_offset].v[0];
183
154
  }
@@ -203,18 +174,13 @@ void fill_segment(const argon2_instance_t *instance,
203
174
  curr_block = instance->memory + curr_offset;
204
175
  if (ARGON2_VERSION_10 == instance->version) {
205
176
  /* version 1.2.1 and earlier: overwrite, not XOR */
206
- fill_block(state, (uint8_t *)ref_block->v,
207
- (uint8_t *)curr_block->v);
177
+ fill_block(state, ref_block, curr_block, 0);
208
178
  } else {
209
179
  if(0 == position.pass) {
210
- fill_block(state, (uint8_t *)ref_block->v,
211
- (uint8_t *)curr_block->v);
180
+ fill_block(state, ref_block, curr_block, 0);
212
181
  } else {
213
- fill_block_with_xor(state, (uint8_t *)ref_block->v,
214
- (uint8_t *)curr_block->v);
182
+ fill_block(state, ref_block, curr_block, 1);
215
183
  }
216
184
  }
217
185
  }
218
-
219
- free(pseudo_rands);
220
186
  }
@@ -1,14 +1,18 @@
1
1
  /*
2
- * Argon2 source code package
2
+ * Argon2 reference source code package - reference C implementations
3
3
  *
4
- * Written by Daniel Dinu and Dmitry Khovratovich, 2015
4
+ * Copyright 2015
5
+ * Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves
5
6
  *
6
- * This work is licensed under a Creative Commons CC0 1.0 License/Waiver.
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:
7
10
  *
8
- * You should have received a copy of the CC0 Public Domain Dedication along
9
- * with
10
- * this software. If not, see
11
- * <http://creativecommons.org/publicdomain/zero/1.0/>.
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.
12
16
  */
13
17
 
14
18
  #ifndef ARGON2_OPT_H
@@ -18,35 +22,14 @@
18
22
  #include <emmintrin.h>
19
23
 
20
24
  /*
21
- * Function fills a new memory block by XORing the new block over the old one. Memory must be initialized.
22
- * After finishing, @state is identical to @next_block
25
+ * Function fills a new memory block and optionally XORs the old block over the new one.
26
+ * Memory must be initialized.
23
27
  * @param state Pointer to the just produced block. Content will be updated(!)
24
28
  * @param ref_block Pointer to the reference block
25
29
  * @param next_block Pointer to the block to be XORed over. May coincide with @ref_block
30
+ * @param with_xor Whether to XOR into the new block (1) or just overwrite (0)
26
31
  * @pre all block pointers must be valid
27
32
  */
28
- void fill_block_with_xor(__m128i *state, const uint8_t *ref_block, uint8_t *next_block);
29
-
30
- /* LEGACY CODE: version 1.2.1 and earlier
31
- * Function fills a new memory block by overwriting @next_block.
32
- * @param state Pointer to the just produced block. Content will be updated(!)
33
- * @param ref_block Pointer to the reference block
34
- * @param next_block Pointer to the block to be XORed over. May coincide with @ref_block
35
- * @pre all block pointers must be valid
36
- */
37
- void fill_block(__m128i *state, const uint8_t *ref_block, uint8_t *next_block);
38
-
39
-
40
- /*
41
- * Generate pseudo-random values to reference blocks in the segment and puts
42
- * them into the array
43
- * @param instance Pointer to the current instance
44
- * @param position Pointer to the current position
45
- * @param pseudo_rands Pointer to the array of 64-bit values
46
- * @pre pseudo_rands must point to @a instance->segment_length allocated values
47
- */
48
- void generate_addresses(const argon2_instance_t *instance,
49
- const argon2_position_t *position,
50
- uint64_t *pseudo_rands);
33
+ void fill_block(__m128i *s, const block *ref_block, block *next_block, int with_xor);
51
34
 
52
35
  #endif /* ARGON2_OPT_H */
@@ -1,14 +1,18 @@
1
1
  /*
2
- * Argon2 source code package
2
+ * Argon2 reference source code package - reference C implementations
3
3
  *
4
- * Written by Daniel Dinu and Dmitry Khovratovich, 2015
4
+ * Copyright 2015
5
+ * Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves
5
6
  *
6
- * This work is licensed under a Creative Commons CC0 1.0 License/Waiver.
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:
7
10
  *
8
- * You should have received a copy of the CC0 Public Domain Dedication along
9
- * with
10
- * this software. If not, see
11
- * <http://creativecommons.org/publicdomain/zero/1.0/>.
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.
12
16
  */
13
17
 
14
18
  #include <stdint.h>
@@ -24,53 +28,21 @@
24
28
 
25
29
 
26
30
  void fill_block(const block *prev_block, const block *ref_block,
27
- block *next_block) {
31
+ block *next_block, int with_xor) {
28
32
  block blockR, block_tmp;
29
33
  unsigned i;
30
34
 
31
35
  copy_block(&blockR, ref_block);
32
36
  xor_block(&blockR, prev_block);
33
37
  copy_block(&block_tmp, &blockR);
34
- /*Now blockR = ref_block + prev_block and bloc_tmp = ref_block + prev_block */
35
- /* Apply Blake2 on columns of 64-bit words: (0,1,...,15) , then
36
- (16,17,..31)... finally (112,113,...127) */
37
- for (i = 0; i < 8; ++i) {
38
- BLAKE2_ROUND_NOMSG(
39
- blockR.v[16 * i], blockR.v[16 * i + 1], blockR.v[16 * i + 2],
40
- blockR.v[16 * i + 3], blockR.v[16 * i + 4], blockR.v[16 * i + 5],
41
- blockR.v[16 * i + 6], blockR.v[16 * i + 7], blockR.v[16 * i + 8],
42
- blockR.v[16 * i + 9], blockR.v[16 * i + 10], blockR.v[16 * i + 11],
43
- blockR.v[16 * i + 12], blockR.v[16 * i + 13], blockR.v[16 * i + 14],
44
- blockR.v[16 * i + 15]);
38
+ /* Now blockR = ref_block + prev_block and block_tmp = ref_block + prev_block */
39
+ if (with_xor) {
40
+ /* Saving the next block contents for XOR over: */
41
+ xor_block(&block_tmp, next_block);
42
+ /* Now blockR = ref_block + prev_block and
43
+ block_tmp = ref_block + prev_block + next_block */
45
44
  }
46
45
 
47
- /* Apply Blake2 on rows of 64-bit words: (0,1,16,17,...112,113), then
48
- (2,3,18,19,...,114,115).. finally (14,15,30,31,...,126,127) */
49
- for (i = 0; i < 8; i++) {
50
- BLAKE2_ROUND_NOMSG(
51
- blockR.v[2 * i], blockR.v[2 * i + 1], blockR.v[2 * i + 16],
52
- blockR.v[2 * i + 17], blockR.v[2 * i + 32], blockR.v[2 * i + 33],
53
- blockR.v[2 * i + 48], blockR.v[2 * i + 49], blockR.v[2 * i + 64],
54
- blockR.v[2 * i + 65], blockR.v[2 * i + 80], blockR.v[2 * i + 81],
55
- blockR.v[2 * i + 96], blockR.v[2 * i + 97], blockR.v[2 * i + 112],
56
- blockR.v[2 * i + 113]);
57
- }
58
-
59
- copy_block(next_block, &block_tmp);
60
- xor_block(next_block, &blockR);
61
- }
62
-
63
-
64
- void fill_block_with_xor(const block *prev_block, const block *ref_block,
65
- block *next_block) {
66
- block blockR, block_tmp;
67
- unsigned i;
68
-
69
- copy_block(&blockR, ref_block);
70
- xor_block(&blockR, prev_block);
71
- copy_block(&block_tmp, &blockR);
72
- xor_block(&block_tmp, next_block); /*Saving the next block contents for XOR over*/
73
- /*Now blockR = ref_block + prev_block and bloc_tmp = ref_block + prev_block + next_block*/
74
46
  /* Apply Blake2 on columns of 64-bit words: (0,1,...,15) , then
75
47
  (16,17,..31)... finally (112,113,...127) */
76
48
  for (i = 0; i < 8; ++i) {
@@ -99,69 +71,53 @@ void fill_block_with_xor(const block *prev_block, const block *ref_block,
99
71
  xor_block(next_block, &blockR);
100
72
  }
101
73
 
102
- void generate_addresses(const argon2_instance_t *instance,
103
- const argon2_position_t *position,
104
- uint64_t *pseudo_rands) {
105
- block zero_block, input_block, address_block,tmp_block;
106
- uint32_t i;
107
-
108
- init_block_value(&zero_block, 0);
109
- init_block_value(&input_block, 0);
110
-
111
- if (instance != NULL && position != NULL) {
112
- input_block.v[0] = position->pass;
113
- input_block.v[1] = position->lane;
114
- input_block.v[2] = position->slice;
115
- input_block.v[3] = instance->memory_blocks;
116
- input_block.v[4] = instance->passes;
117
- input_block.v[5] = instance->type;
118
-
119
- for (i = 0; i < instance->segment_length; ++i) {
120
- if (i % ARGON2_ADDRESSES_IN_BLOCK == 0) {
121
- input_block.v[6]++;
122
- init_block_value(&tmp_block, 0);
123
- init_block_value(&address_block, 0);
124
- fill_block_with_xor(&zero_block, &input_block, &tmp_block);
125
- fill_block_with_xor(&zero_block, &tmp_block, &address_block);
126
- }
127
-
128
- pseudo_rands[i] = address_block.v[i % ARGON2_ADDRESSES_IN_BLOCK];
129
- }
130
- }
74
+ static void next_addresses(block *address_block, block *input_block,
75
+ const block *zero_block) {
76
+ input_block->v[6]++;
77
+ fill_block(zero_block, input_block, address_block, 0);
78
+ fill_block(zero_block, address_block, address_block, 0);
131
79
  }
132
80
 
133
81
  void fill_segment(const argon2_instance_t *instance,
134
82
  argon2_position_t position) {
135
83
  block *ref_block = NULL, *curr_block = NULL;
84
+ block address_block, input_block, zero_block;
136
85
  uint64_t pseudo_rand, ref_index, ref_lane;
137
86
  uint32_t prev_offset, curr_offset;
138
87
  uint32_t starting_index;
139
88
  uint32_t i;
140
89
  int data_independent_addressing;
141
- /* Pseudo-random values that determine the reference block position */
142
- uint64_t *pseudo_rands = NULL;
143
90
 
144
91
  if (instance == NULL) {
145
92
  return;
146
93
  }
147
94
 
148
- data_independent_addressing = (instance->type == Argon2_i);
149
-
150
- pseudo_rands =
151
- (uint64_t *)malloc(sizeof(uint64_t) * (instance->segment_length));
152
-
153
- if (pseudo_rands == NULL) {
154
- return;
155
- }
95
+ data_independent_addressing =
96
+ (instance->type == Argon2_i) ||
97
+ (instance->type == Argon2_id && (position.pass == 0) &&
98
+ (position.slice < ARGON2_SYNC_POINTS / 2));
156
99
 
157
100
  if (data_independent_addressing) {
158
- generate_addresses(instance, &position, pseudo_rands);
101
+ init_block_value(&zero_block, 0);
102
+ init_block_value(&input_block, 0);
103
+
104
+ input_block.v[0] = position.pass;
105
+ input_block.v[1] = position.lane;
106
+ input_block.v[2] = position.slice;
107
+ input_block.v[3] = instance->memory_blocks;
108
+ input_block.v[4] = instance->passes;
109
+ input_block.v[5] = instance->type;
159
110
  }
160
111
 
161
112
  starting_index = 0;
162
113
 
163
114
  if ((0 == position.pass) && (0 == position.slice)) {
164
115
  starting_index = 2; /* we have already generated the first two blocks */
116
+
117
+ /* Don't forget to generate the first block of addresses: */
118
+ if (data_independent_addressing) {
119
+ next_addresses(&address_block, &input_block, &zero_block);
120
+ }
165
121
  }
166
122
 
167
123
  /* Offset of the current block */
@@ -186,7 +142,10 @@ void fill_segment(const argon2_instance_t *instance,
186
142
  /* 1.2 Computing the index of the reference block */
187
143
  /* 1.2.1 Taking pseudo-random value from the previous block */
188
144
  if (data_independent_addressing) {
189
- pseudo_rand = pseudo_rands[i];
145
+ if (i % ARGON2_ADDRESSES_IN_BLOCK == 0) {
146
+ next_addresses(&address_block, &input_block, &zero_block);
147
+ }
148
+ pseudo_rand = address_block.v[i % ARGON2_ADDRESSES_IN_BLOCK];
190
149
  } else {
191
150
  pseudo_rand = instance->memory[prev_offset].v[0];
192
151
  }
@@ -212,17 +171,15 @@ void fill_segment(const argon2_instance_t *instance,
212
171
  curr_block = instance->memory + curr_offset;
213
172
  if (ARGON2_VERSION_10 == instance->version) {
214
173
  /* version 1.2.1 and earlier: overwrite, not XOR */
215
- fill_block(instance->memory + prev_offset, ref_block, curr_block);
174
+ fill_block(instance->memory + prev_offset, ref_block, curr_block, 0);
216
175
  } else {
217
176
  if(0 == position.pass) {
218
177
  fill_block(instance->memory + prev_offset, ref_block,
219
- curr_block);
178
+ curr_block, 0);
220
179
  } else {
221
- fill_block_with_xor(instance->memory + prev_offset, ref_block,
222
- curr_block);
180
+ fill_block(instance->memory + prev_offset, ref_block,
181
+ curr_block, 1);
223
182
  }
224
183
  }
225
184
  }
226
-
227
- free(pseudo_rands);
228
185
  }