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.
- 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
|
}
|