argon2 1.1.1 → 1.1.2

Sign up to get free protection for your applications and to get access to all the features.
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
  }