argon2 1.1.1 → 1.1.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +7 -4
- data/Changelog.md +3 -0
- data/README.md +2 -0
- data/argon2.gemspec +1 -1
- data/ext/argon2_wrap/Makefile +6 -0
- data/ext/argon2_wrap/argon_wrap.c +1 -7
- data/ext/phc-winner-argon2/.gitignore +1 -0
- data/ext/phc-winner-argon2/Argon2.sln +64 -2
- data/ext/phc-winner-argon2/CHANGELOG.md +8 -1
- data/ext/phc-winner-argon2/LICENSE +301 -18
- data/ext/phc-winner-argon2/Makefile +85 -20
- data/ext/phc-winner-argon2/README.md +73 -30
- data/ext/phc-winner-argon2/argon2-specs.pdf +0 -0
- data/ext/phc-winner-argon2/include/argon2.h +73 -10
- data/ext/phc-winner-argon2/kats/argon2id +12304 -0
- data/ext/phc-winner-argon2/kats/argon2id.shasum +1 -0
- data/ext/phc-winner-argon2/kats/argon2id_v16 +12304 -0
- data/ext/phc-winner-argon2/kats/argon2id_v16.shasum +1 -0
- data/ext/phc-winner-argon2/kats/test.ps1 +1 -1
- data/ext/phc-winner-argon2/kats/test.sh +1 -1
- data/ext/phc-winner-argon2/latex/IEEEtran.cls +6347 -0
- data/ext/phc-winner-argon2/latex/argon2-spec.tex +920 -0
- data/ext/phc-winner-argon2/latex/pics/argon2-par.pdf +0 -0
- data/ext/phc-winner-argon2/latex/pics/compression.pdf +0 -0
- data/ext/phc-winner-argon2/latex/pics/generic.pdf +0 -0
- data/ext/phc-winner-argon2/latex/pics/power-distribution.jpg +0 -0
- data/ext/phc-winner-argon2/latex/tradeoff.bib +822 -0
- data/ext/phc-winner-argon2/libargon2.pc +16 -0
- data/ext/phc-winner-argon2/man/argon2.1 +13 -3
- data/ext/phc-winner-argon2/src/argon2.c +112 -68
- data/ext/phc-winner-argon2/src/bench.c +44 -27
- data/ext/phc-winner-argon2/src/blake2/blake2-impl.h +18 -5
- data/ext/phc-winner-argon2/src/blake2/blake2.h +17 -0
- data/ext/phc-winner-argon2/src/blake2/blake2b.c +25 -7
- data/ext/phc-winner-argon2/src/blake2/blamka-round-opt.h +17 -0
- data/ext/phc-winner-argon2/src/blake2/blamka-round-ref.h +17 -0
- data/ext/phc-winner-argon2/src/core.c +138 -110
- data/ext/phc-winner-argon2/src/core.h +41 -26
- data/ext/phc-winner-argon2/src/encoding.c +79 -55
- data/ext/phc-winner-argon2/src/encoding.h +25 -8
- data/ext/phc-winner-argon2/src/genkat.c +35 -39
- data/ext/phc-winner-argon2/src/genkat.h +11 -7
- data/ext/phc-winner-argon2/src/opt.c +65 -99
- data/ext/phc-winner-argon2/src/opt.h +15 -32
- data/ext/phc-winner-argon2/src/ref.c +50 -93
- data/ext/phc-winner-argon2/src/ref.h +15 -31
- data/ext/phc-winner-argon2/src/run.c +73 -30
- data/ext/phc-winner-argon2/src/test.c +33 -2
- data/ext/phc-winner-argon2/src/thread.c +21 -0
- data/ext/phc-winner-argon2/src/thread.h +21 -0
- data/ext/phc-winner-argon2/vs2015/Argon2Opt/Argon2Opt.vcxproj +69 -1
- data/ext/phc-winner-argon2/vs2015/Argon2OptBench/Argon2OptBench.vcxproj +69 -1
- data/ext/phc-winner-argon2/vs2015/Argon2OptDll/Argon2OptDll.vcxproj +225 -0
- data/ext/phc-winner-argon2/vs2015/Argon2OptDll/Argon2OptDll.vcxproj.filters +66 -0
- data/ext/phc-winner-argon2/vs2015/Argon2OptGenKAT/Argon2OptGenKAT.vcxproj +73 -1
- data/ext/phc-winner-argon2/vs2015/Argon2OptTestCI/Argon2OptTestCI.vcxproj +69 -1
- data/ext/phc-winner-argon2/vs2015/Argon2Ref/Argon2Ref.vcxproj +69 -1
- data/ext/phc-winner-argon2/vs2015/Argon2RefBench/Argon2RefBench.vcxproj +69 -1
- data/ext/phc-winner-argon2/vs2015/Argon2RefDll/Argon2RefDll.vcxproj +225 -0
- data/ext/phc-winner-argon2/vs2015/Argon2RefDll/Argon2RefDll.vcxproj.filters +66 -0
- data/ext/phc-winner-argon2/vs2015/Argon2RefGenKAT/Argon2RefGenKAT.vcxproj +69 -1
- data/ext/phc-winner-argon2/vs2015/Argon2RefTestCI/Argon2RefTestCI.vcxproj +69 -1
- data/lib/argon2.rb +3 -3
- data/lib/argon2/ffi_engine.rb +3 -3
- data/lib/argon2/version.rb +1 -1
- 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
|
-
*
|
4
|
+
* Copyright 2015
|
5
|
+
* Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves
|
5
6
|
*
|
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:
|
7
10
|
*
|
8
|
-
*
|
9
|
-
*
|
10
|
-
*
|
11
|
-
*
|
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
|
-
*
|
4
|
+
* Copyright 2015
|
5
|
+
* Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves
|
5
6
|
*
|
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:
|
7
10
|
*
|
8
|
-
*
|
9
|
-
*
|
10
|
-
*
|
11
|
-
*
|
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
|
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
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
state[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 *)
|
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
|
82
|
-
|
83
|
-
|
84
|
-
|
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
|
-
|
88
|
-
|
70
|
+
memset(zero_block, 0, sizeof(zero_block));
|
71
|
+
memset(zero2_block, 0, sizeof(zero2_block));
|
89
72
|
|
90
|
-
|
91
|
-
|
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
|
-
|
99
|
-
|
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
|
-
|
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 =
|
139
|
-
|
140
|
-
|
141
|
-
|
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
|
-
|
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
|
-
|
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,
|
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,
|
211
|
-
(uint8_t *)curr_block->v);
|
180
|
+
fill_block(state, ref_block, curr_block, 0);
|
212
181
|
} else {
|
213
|
-
|
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
|
-
*
|
4
|
+
* Copyright 2015
|
5
|
+
* Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves
|
5
6
|
*
|
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:
|
7
10
|
*
|
8
|
-
*
|
9
|
-
*
|
10
|
-
*
|
11
|
-
*
|
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
|
22
|
-
*
|
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
|
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
|
-
*
|
4
|
+
* Copyright 2015
|
5
|
+
* Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves
|
5
6
|
*
|
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:
|
7
10
|
*
|
8
|
-
*
|
9
|
-
*
|
10
|
-
*
|
11
|
-
*
|
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
|
-
|
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
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
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
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
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 =
|
149
|
-
|
150
|
-
|
151
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
222
|
-
|
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
|
}
|