argon2 2.3.1 → 2.3.3
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/.github/workflows/ruby.yml +1 -1
- data/.rubocop.yml +2 -1
- data/argon2.gemspec +2 -2
- data/ext/phc-winner-argon2/.git +1 -0
- data/ext/phc-winner-argon2/.gitattributes +10 -0
- data/ext/phc-winner-argon2/.gitignore +22 -0
- data/ext/phc-winner-argon2/.travis.yml +25 -0
- data/ext/phc-winner-argon2/Argon2.sln +158 -0
- data/ext/phc-winner-argon2/CHANGELOG.md +32 -0
- data/ext/phc-winner-argon2/LICENSE +314 -0
- data/ext/phc-winner-argon2/Makefile +255 -0
- data/ext/phc-winner-argon2/Package.swift +46 -0
- data/ext/phc-winner-argon2/README.md +303 -0
- data/ext/phc-winner-argon2/appveyor.yml +25 -0
- data/ext/phc-winner-argon2/argon2-specs.pdf +0 -0
- data/ext/phc-winner-argon2/export.sh +7 -0
- data/ext/phc-winner-argon2/include/argon2.h +437 -0
- data/ext/phc-winner-argon2/kats/argon2d +12304 -0
- data/ext/phc-winner-argon2/kats/argon2d.shasum +1 -0
- data/ext/phc-winner-argon2/kats/argon2d_v16 +12304 -0
- data/ext/phc-winner-argon2/kats/argon2d_v16.shasum +1 -0
- data/ext/phc-winner-argon2/kats/argon2i +12304 -0
- data/ext/phc-winner-argon2/kats/argon2i.shasum +1 -0
- data/ext/phc-winner-argon2/kats/argon2i_v16 +12304 -0
- data/ext/phc-winner-argon2/kats/argon2i_v16.shasum +1 -0
- 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/check-sums.ps1 +42 -0
- data/ext/phc-winner-argon2/kats/check-sums.sh +13 -0
- data/ext/phc-winner-argon2/kats/test.ps1 +50 -0
- data/ext/phc-winner-argon2/kats/test.sh +49 -0
- data/ext/phc-winner-argon2/latex/IEEEtran.cls +6347 -0
- data/ext/phc-winner-argon2/latex/Makefile +18 -0
- data/ext/phc-winner-argon2/latex/argon2-specs.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.in +18 -0
- data/ext/phc-winner-argon2/man/argon2.1 +57 -0
- data/ext/phc-winner-argon2/src/argon2.c +452 -0
- data/ext/phc-winner-argon2/src/bench.c +111 -0
- data/ext/phc-winner-argon2/src/blake2/blake2-impl.h +156 -0
- data/ext/phc-winner-argon2/src/blake2/blake2.h +89 -0
- data/ext/phc-winner-argon2/src/blake2/blake2b.c +390 -0
- data/ext/phc-winner-argon2/src/blake2/blamka-round-opt.h +471 -0
- data/ext/phc-winner-argon2/src/blake2/blamka-round-ref.h +56 -0
- data/ext/phc-winner-argon2/src/core.c +648 -0
- data/ext/phc-winner-argon2/src/core.h +228 -0
- data/ext/phc-winner-argon2/src/encoding.c +463 -0
- data/ext/phc-winner-argon2/src/encoding.h +57 -0
- data/ext/phc-winner-argon2/src/genkat.c +213 -0
- data/ext/phc-winner-argon2/src/genkat.h +51 -0
- data/ext/phc-winner-argon2/src/opt.c +283 -0
- data/ext/phc-winner-argon2/src/ref.c +194 -0
- data/ext/phc-winner-argon2/src/run.c +337 -0
- data/ext/phc-winner-argon2/src/test.c +289 -0
- data/ext/phc-winner-argon2/src/thread.c +57 -0
- data/ext/phc-winner-argon2/src/thread.h +67 -0
- data/ext/phc-winner-argon2/vs2015/Argon2Opt/Argon2Opt.vcxproj +231 -0
- data/ext/phc-winner-argon2/vs2015/Argon2Opt/Argon2Opt.vcxproj.filters +69 -0
- data/ext/phc-winner-argon2/vs2015/Argon2OptBench/Argon2OptBench.vcxproj +231 -0
- data/ext/phc-winner-argon2/vs2015/Argon2OptBench/Argon2OptBench.vcxproj.filters +69 -0
- data/ext/phc-winner-argon2/vs2015/Argon2OptDll/Argon2OptDll.vcxproj +230 -0
- data/ext/phc-winner-argon2/vs2015/Argon2OptDll/Argon2OptDll.vcxproj.filters +66 -0
- data/ext/phc-winner-argon2/vs2015/Argon2OptGenKAT/Argon2OptGenKAT.vcxproj +244 -0
- data/ext/phc-winner-argon2/vs2015/Argon2OptGenKAT/Argon2OptGenKAT.vcxproj.filters +72 -0
- data/ext/phc-winner-argon2/vs2015/Argon2OptTestCI/Argon2OptTestCI.vcxproj +235 -0
- data/ext/phc-winner-argon2/vs2015/Argon2OptTestCI/Argon2OptTestCI.vcxproj.filters +69 -0
- data/ext/phc-winner-argon2/vs2015/Argon2Ref/Argon2Ref.vcxproj +243 -0
- data/ext/phc-winner-argon2/vs2015/Argon2Ref/Argon2Ref.vcxproj.filters +69 -0
- data/ext/phc-winner-argon2/vs2015/Argon2RefBench/Argon2RefBench.vcxproj +231 -0
- data/ext/phc-winner-argon2/vs2015/Argon2RefBench/Argon2RefBench.vcxproj.filters +69 -0
- data/ext/phc-winner-argon2/vs2015/Argon2RefDll/Argon2RefDll.vcxproj +230 -0
- data/ext/phc-winner-argon2/vs2015/Argon2RefDll/Argon2RefDll.vcxproj.filters +66 -0
- data/ext/phc-winner-argon2/vs2015/Argon2RefGenKAT/Argon2RefGenKAT.vcxproj +232 -0
- data/ext/phc-winner-argon2/vs2015/Argon2RefGenKAT/Argon2RefGenKAT.vcxproj.filters +72 -0
- data/ext/phc-winner-argon2/vs2015/Argon2RefTestCI/Argon2RefTestCI.vcxproj +231 -0
- data/ext/phc-winner-argon2/vs2015/Argon2RefTestCI/Argon2RefTestCI.vcxproj.filters +69 -0
- data/lib/argon2/version.rb +1 -1
- metadata +85 -6
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Argon2 reference source code package - reference C implementations
|
|
3
|
+
*
|
|
4
|
+
* Copyright 2015
|
|
5
|
+
* Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves
|
|
6
|
+
*
|
|
7
|
+
* You may use this work under the terms of a Creative Commons CC0 1.0
|
|
8
|
+
* License/Waiver or the Apache Public License 2.0, at your option. The terms of
|
|
9
|
+
* these licenses can be found at:
|
|
10
|
+
*
|
|
11
|
+
* - CC0 1.0 Universal : https://creativecommons.org/publicdomain/zero/1.0
|
|
12
|
+
* - Apache 2.0 : https://www.apache.org/licenses/LICENSE-2.0
|
|
13
|
+
*
|
|
14
|
+
* You should have received a copy of both of these licenses along with this
|
|
15
|
+
* software. If not, they may be obtained at the above URLs.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
#ifndef ENCODING_H
|
|
19
|
+
#define ENCODING_H
|
|
20
|
+
#include "argon2.h"
|
|
21
|
+
|
|
22
|
+
#define ARGON2_MAX_DECODED_LANES UINT32_C(255)
|
|
23
|
+
#define ARGON2_MIN_DECODED_SALT_LEN UINT32_C(8)
|
|
24
|
+
#define ARGON2_MIN_DECODED_OUT_LEN UINT32_C(12)
|
|
25
|
+
|
|
26
|
+
/*
|
|
27
|
+
* encode an Argon2 hash string into the provided buffer. 'dst_len'
|
|
28
|
+
* contains the size, in characters, of the 'dst' buffer; if 'dst_len'
|
|
29
|
+
* is less than the number of required characters (including the
|
|
30
|
+
* terminating 0), then this function returns ARGON2_ENCODING_ERROR.
|
|
31
|
+
*
|
|
32
|
+
* on success, ARGON2_OK is returned.
|
|
33
|
+
*/
|
|
34
|
+
int encode_string(char *dst, size_t dst_len, argon2_context *ctx,
|
|
35
|
+
argon2_type type);
|
|
36
|
+
|
|
37
|
+
/*
|
|
38
|
+
* Decodes an Argon2 hash string into the provided structure 'ctx'.
|
|
39
|
+
* The only fields that must be set prior to this call are ctx.saltlen and
|
|
40
|
+
* ctx.outlen (which must be the maximal salt and out length values that are
|
|
41
|
+
* allowed), ctx.salt and ctx.out (which must be buffers of the specified
|
|
42
|
+
* length), and ctx.pwd and ctx.pwdlen which must hold a valid password.
|
|
43
|
+
*
|
|
44
|
+
* Invalid input string causes an error. On success, the ctx is valid and all
|
|
45
|
+
* fields have been initialized.
|
|
46
|
+
*
|
|
47
|
+
* Returned value is ARGON2_OK on success, other ARGON2_ codes on error.
|
|
48
|
+
*/
|
|
49
|
+
int decode_string(argon2_context *ctx, const char *str, argon2_type type);
|
|
50
|
+
|
|
51
|
+
/* Returns the length of the encoded byte stream with length len */
|
|
52
|
+
size_t b64len(uint32_t len);
|
|
53
|
+
|
|
54
|
+
/* Returns the length of the encoded number num */
|
|
55
|
+
size_t numlen(uint32_t num);
|
|
56
|
+
|
|
57
|
+
#endif
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Argon2 reference source code package - reference C implementations
|
|
3
|
+
*
|
|
4
|
+
* Copyright 2015
|
|
5
|
+
* Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves
|
|
6
|
+
*
|
|
7
|
+
* You may use this work under the terms of a Creative Commons CC0 1.0
|
|
8
|
+
* License/Waiver or the Apache Public License 2.0, at your option. The terms of
|
|
9
|
+
* these licenses can be found at:
|
|
10
|
+
*
|
|
11
|
+
* - CC0 1.0 Universal : https://creativecommons.org/publicdomain/zero/1.0
|
|
12
|
+
* - Apache 2.0 : https://www.apache.org/licenses/LICENSE-2.0
|
|
13
|
+
*
|
|
14
|
+
* You should have received a copy of both of these licenses along with this
|
|
15
|
+
* software. If not, they may be obtained at the above URLs.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
#include <stdio.h>
|
|
19
|
+
#include <stdlib.h>
|
|
20
|
+
#include <string.h>
|
|
21
|
+
#include "argon2.h"
|
|
22
|
+
#include "core.h"
|
|
23
|
+
#ifdef __MINGW32__
|
|
24
|
+
#include <inttypes.h>
|
|
25
|
+
#else
|
|
26
|
+
/* Don't use <inttypes.h> (it's not C89) */
|
|
27
|
+
#define PRIx64 "llx"
|
|
28
|
+
#endif
|
|
29
|
+
|
|
30
|
+
void initial_kat(const uint8_t *blockhash, const argon2_context *context,
|
|
31
|
+
argon2_type type) {
|
|
32
|
+
unsigned i;
|
|
33
|
+
|
|
34
|
+
if (blockhash != NULL && context != NULL) {
|
|
35
|
+
printf("=======================================\n");
|
|
36
|
+
|
|
37
|
+
printf("%s version number %d\n", argon2_type2string(type, 1),
|
|
38
|
+
context->version);
|
|
39
|
+
|
|
40
|
+
printf("=======================================\n");
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
printf("Memory: %u KiB, Iterations: %u, Parallelism: %u lanes, Tag "
|
|
44
|
+
"length: %u bytes\n",
|
|
45
|
+
context->m_cost, context->t_cost, context->lanes,
|
|
46
|
+
context->outlen);
|
|
47
|
+
|
|
48
|
+
printf("Password[%u]: ", context->pwdlen);
|
|
49
|
+
|
|
50
|
+
if (context->flags & ARGON2_FLAG_CLEAR_PASSWORD) {
|
|
51
|
+
printf("CLEARED\n");
|
|
52
|
+
} else {
|
|
53
|
+
for (i = 0; i < context->pwdlen; ++i) {
|
|
54
|
+
printf("%2.2x ", ((unsigned char *)context->pwd)[i]);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
printf("\n");
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
printf("Salt[%u]: ", context->saltlen);
|
|
61
|
+
|
|
62
|
+
for (i = 0; i < context->saltlen; ++i) {
|
|
63
|
+
printf("%2.2x ", ((unsigned char *)context->salt)[i]);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
printf("\n");
|
|
67
|
+
|
|
68
|
+
printf("Secret[%u]: ", context->secretlen);
|
|
69
|
+
|
|
70
|
+
if (context->flags & ARGON2_FLAG_CLEAR_SECRET) {
|
|
71
|
+
printf("CLEARED\n");
|
|
72
|
+
} else {
|
|
73
|
+
for (i = 0; i < context->secretlen; ++i) {
|
|
74
|
+
printf("%2.2x ", ((unsigned char *)context->secret)[i]);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
printf("\n");
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
printf("Associated data[%u]: ", context->adlen);
|
|
81
|
+
|
|
82
|
+
for (i = 0; i < context->adlen; ++i) {
|
|
83
|
+
printf("%2.2x ", ((unsigned char *)context->ad)[i]);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
printf("\n");
|
|
87
|
+
|
|
88
|
+
printf("Pre-hashing digest: ");
|
|
89
|
+
|
|
90
|
+
for (i = 0; i < ARGON2_PREHASH_DIGEST_LENGTH; ++i) {
|
|
91
|
+
printf("%2.2x ", ((unsigned char *)blockhash)[i]);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
printf("\n");
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
void print_tag(const void *out, uint32_t outlen) {
|
|
99
|
+
unsigned i;
|
|
100
|
+
if (out != NULL) {
|
|
101
|
+
printf("Tag: ");
|
|
102
|
+
|
|
103
|
+
for (i = 0; i < outlen; ++i) {
|
|
104
|
+
printf("%2.2x ", ((uint8_t *)out)[i]);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
printf("\n");
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
void internal_kat(const argon2_instance_t *instance, uint32_t pass) {
|
|
112
|
+
|
|
113
|
+
if (instance != NULL) {
|
|
114
|
+
uint32_t i, j;
|
|
115
|
+
printf("\n After pass %u:\n", pass);
|
|
116
|
+
|
|
117
|
+
for (i = 0; i < instance->memory_blocks; ++i) {
|
|
118
|
+
uint32_t how_many_words =
|
|
119
|
+
(instance->memory_blocks > ARGON2_QWORDS_IN_BLOCK)
|
|
120
|
+
? 1
|
|
121
|
+
: ARGON2_QWORDS_IN_BLOCK;
|
|
122
|
+
|
|
123
|
+
for (j = 0; j < how_many_words; ++j)
|
|
124
|
+
printf("Block %.4u [%3u]: %016" PRIx64 "\n", i, j,
|
|
125
|
+
(unsigned long long)instance->memory[i].v[j]);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
static void fatal(const char *error) {
|
|
131
|
+
fprintf(stderr, "Error: %s\n", error);
|
|
132
|
+
exit(1);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
static void generate_testvectors(argon2_type type, const uint32_t version) {
|
|
136
|
+
#define TEST_OUTLEN 32
|
|
137
|
+
#define TEST_PWDLEN 32
|
|
138
|
+
#define TEST_SALTLEN 16
|
|
139
|
+
#define TEST_SECRETLEN 8
|
|
140
|
+
#define TEST_ADLEN 12
|
|
141
|
+
argon2_context context;
|
|
142
|
+
|
|
143
|
+
unsigned char out[TEST_OUTLEN];
|
|
144
|
+
unsigned char pwd[TEST_PWDLEN];
|
|
145
|
+
unsigned char salt[TEST_SALTLEN];
|
|
146
|
+
unsigned char secret[TEST_SECRETLEN];
|
|
147
|
+
unsigned char ad[TEST_ADLEN];
|
|
148
|
+
const allocate_fptr myown_allocator = NULL;
|
|
149
|
+
const deallocate_fptr myown_deallocator = NULL;
|
|
150
|
+
|
|
151
|
+
unsigned t_cost = 3;
|
|
152
|
+
unsigned m_cost = 32;
|
|
153
|
+
unsigned lanes = 4;
|
|
154
|
+
|
|
155
|
+
memset(pwd, 1, TEST_OUTLEN);
|
|
156
|
+
memset(salt, 2, TEST_SALTLEN);
|
|
157
|
+
memset(secret, 3, TEST_SECRETLEN);
|
|
158
|
+
memset(ad, 4, TEST_ADLEN);
|
|
159
|
+
|
|
160
|
+
context.out = out;
|
|
161
|
+
context.outlen = TEST_OUTLEN;
|
|
162
|
+
context.version = version;
|
|
163
|
+
context.pwd = pwd;
|
|
164
|
+
context.pwdlen = TEST_PWDLEN;
|
|
165
|
+
context.salt = salt;
|
|
166
|
+
context.saltlen = TEST_SALTLEN;
|
|
167
|
+
context.secret = secret;
|
|
168
|
+
context.secretlen = TEST_SECRETLEN;
|
|
169
|
+
context.ad = ad;
|
|
170
|
+
context.adlen = TEST_ADLEN;
|
|
171
|
+
context.t_cost = t_cost;
|
|
172
|
+
context.m_cost = m_cost;
|
|
173
|
+
context.lanes = lanes;
|
|
174
|
+
context.threads = lanes;
|
|
175
|
+
context.allocate_cbk = myown_allocator;
|
|
176
|
+
context.free_cbk = myown_deallocator;
|
|
177
|
+
context.flags = ARGON2_DEFAULT_FLAGS;
|
|
178
|
+
|
|
179
|
+
#undef TEST_OUTLEN
|
|
180
|
+
#undef TEST_PWDLEN
|
|
181
|
+
#undef TEST_SALTLEN
|
|
182
|
+
#undef TEST_SECRETLEN
|
|
183
|
+
#undef TEST_ADLEN
|
|
184
|
+
|
|
185
|
+
argon2_ctx(&context, type);
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
int main(int argc, char *argv[]) {
|
|
189
|
+
/* Get and check Argon2 type */
|
|
190
|
+
const char *type_str = (argc > 1) ? argv[1] : "i";
|
|
191
|
+
argon2_type type = Argon2_i;
|
|
192
|
+
uint32_t version = ARGON2_VERSION_NUMBER;
|
|
193
|
+
if (!strcmp(type_str, "d")) {
|
|
194
|
+
type = Argon2_d;
|
|
195
|
+
} else if (!strcmp(type_str, "i")) {
|
|
196
|
+
type = Argon2_i;
|
|
197
|
+
} else if (!strcmp(type_str, "id")) {
|
|
198
|
+
type = Argon2_id;
|
|
199
|
+
} else {
|
|
200
|
+
fatal("wrong Argon2 type");
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/* Get and check Argon2 version number */
|
|
204
|
+
if (argc > 2) {
|
|
205
|
+
version = strtoul(argv[2], NULL, 10);
|
|
206
|
+
}
|
|
207
|
+
if (ARGON2_VERSION_10 != version && ARGON2_VERSION_NUMBER != version) {
|
|
208
|
+
fatal("wrong Argon2 version number");
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
generate_testvectors(type, version);
|
|
212
|
+
return ARGON2_OK;
|
|
213
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Argon2 reference source code package - reference C implementations
|
|
3
|
+
*
|
|
4
|
+
* Copyright 2015
|
|
5
|
+
* Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves
|
|
6
|
+
*
|
|
7
|
+
* You may use this work under the terms of a Creative Commons CC0 1.0
|
|
8
|
+
* License/Waiver or the Apache Public License 2.0, at your option. The terms of
|
|
9
|
+
* these licenses can be found at:
|
|
10
|
+
*
|
|
11
|
+
* - CC0 1.0 Universal : https://creativecommons.org/publicdomain/zero/1.0
|
|
12
|
+
* - Apache 2.0 : https://www.apache.org/licenses/LICENSE-2.0
|
|
13
|
+
*
|
|
14
|
+
* You should have received a copy of both of these licenses along with this
|
|
15
|
+
* software. If not, they may be obtained at the above URLs.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
#ifndef ARGON2_KAT_H
|
|
19
|
+
#define ARGON2_KAT_H
|
|
20
|
+
|
|
21
|
+
#include "core.h"
|
|
22
|
+
|
|
23
|
+
/*
|
|
24
|
+
* Initial KAT function that prints the inputs to the file
|
|
25
|
+
* @param blockhash Array that contains pre-hashing digest
|
|
26
|
+
* @param context Holds inputs
|
|
27
|
+
* @param type Argon2 type
|
|
28
|
+
* @pre blockhash must point to INPUT_INITIAL_HASH_LENGTH bytes
|
|
29
|
+
* @pre context member pointers must point to allocated memory of size according
|
|
30
|
+
* to the length values
|
|
31
|
+
*/
|
|
32
|
+
void initial_kat(const uint8_t *blockhash, const argon2_context *context,
|
|
33
|
+
argon2_type type);
|
|
34
|
+
|
|
35
|
+
/*
|
|
36
|
+
* Function that prints the output tag
|
|
37
|
+
* @param out output array pointer
|
|
38
|
+
* @param outlen digest length
|
|
39
|
+
* @pre out must point to @a outlen bytes
|
|
40
|
+
**/
|
|
41
|
+
void print_tag(const void *out, uint32_t outlen);
|
|
42
|
+
|
|
43
|
+
/*
|
|
44
|
+
* Function that prints the internal state at given moment
|
|
45
|
+
* @param instance pointer to the current instance
|
|
46
|
+
* @param pass current pass number
|
|
47
|
+
* @pre instance must have necessary memory allocated
|
|
48
|
+
**/
|
|
49
|
+
void internal_kat(const argon2_instance_t *instance, uint32_t pass);
|
|
50
|
+
|
|
51
|
+
#endif
|
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Argon2 reference source code package - reference C implementations
|
|
3
|
+
*
|
|
4
|
+
* Copyright 2015
|
|
5
|
+
* Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves
|
|
6
|
+
*
|
|
7
|
+
* You may use this work under the terms of a Creative Commons CC0 1.0
|
|
8
|
+
* License/Waiver or the Apache Public License 2.0, at your option. The terms of
|
|
9
|
+
* these licenses can be found at:
|
|
10
|
+
*
|
|
11
|
+
* - CC0 1.0 Universal : https://creativecommons.org/publicdomain/zero/1.0
|
|
12
|
+
* - Apache 2.0 : https://www.apache.org/licenses/LICENSE-2.0
|
|
13
|
+
*
|
|
14
|
+
* You should have received a copy of both of these licenses along with this
|
|
15
|
+
* software. If not, they may be obtained at the above URLs.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
#include <stdint.h>
|
|
19
|
+
#include <string.h>
|
|
20
|
+
#include <stdlib.h>
|
|
21
|
+
|
|
22
|
+
#include "argon2.h"
|
|
23
|
+
#include "core.h"
|
|
24
|
+
|
|
25
|
+
#include "blake2/blake2.h"
|
|
26
|
+
#include "blake2/blamka-round-opt.h"
|
|
27
|
+
|
|
28
|
+
/*
|
|
29
|
+
* Function fills a new memory block and optionally XORs the old block over the new one.
|
|
30
|
+
* Memory must be initialized.
|
|
31
|
+
* @param state Pointer to the just produced block. Content will be updated(!)
|
|
32
|
+
* @param ref_block Pointer to the reference block
|
|
33
|
+
* @param next_block Pointer to the block to be XORed over. May coincide with @ref_block
|
|
34
|
+
* @param with_xor Whether to XOR into the new block (1) or just overwrite (0)
|
|
35
|
+
* @pre all block pointers must be valid
|
|
36
|
+
*/
|
|
37
|
+
#if defined(__AVX512F__)
|
|
38
|
+
static void fill_block(__m512i *state, const block *ref_block,
|
|
39
|
+
block *next_block, int with_xor) {
|
|
40
|
+
__m512i block_XY[ARGON2_512BIT_WORDS_IN_BLOCK];
|
|
41
|
+
unsigned int i;
|
|
42
|
+
|
|
43
|
+
if (with_xor) {
|
|
44
|
+
for (i = 0; i < ARGON2_512BIT_WORDS_IN_BLOCK; i++) {
|
|
45
|
+
state[i] = _mm512_xor_si512(
|
|
46
|
+
state[i], _mm512_loadu_si512((const __m512i *)ref_block->v + i));
|
|
47
|
+
block_XY[i] = _mm512_xor_si512(
|
|
48
|
+
state[i], _mm512_loadu_si512((const __m512i *)next_block->v + i));
|
|
49
|
+
}
|
|
50
|
+
} else {
|
|
51
|
+
for (i = 0; i < ARGON2_512BIT_WORDS_IN_BLOCK; i++) {
|
|
52
|
+
block_XY[i] = state[i] = _mm512_xor_si512(
|
|
53
|
+
state[i], _mm512_loadu_si512((const __m512i *)ref_block->v + i));
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
for (i = 0; i < 2; ++i) {
|
|
58
|
+
BLAKE2_ROUND_1(
|
|
59
|
+
state[8 * i + 0], state[8 * i + 1], state[8 * i + 2], state[8 * i + 3],
|
|
60
|
+
state[8 * i + 4], state[8 * i + 5], state[8 * i + 6], state[8 * i + 7]);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
for (i = 0; i < 2; ++i) {
|
|
64
|
+
BLAKE2_ROUND_2(
|
|
65
|
+
state[2 * 0 + i], state[2 * 1 + i], state[2 * 2 + i], state[2 * 3 + i],
|
|
66
|
+
state[2 * 4 + i], state[2 * 5 + i], state[2 * 6 + i], state[2 * 7 + i]);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
for (i = 0; i < ARGON2_512BIT_WORDS_IN_BLOCK; i++) {
|
|
70
|
+
state[i] = _mm512_xor_si512(state[i], block_XY[i]);
|
|
71
|
+
_mm512_storeu_si512((__m512i *)next_block->v + i, state[i]);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
#elif defined(__AVX2__)
|
|
75
|
+
static void fill_block(__m256i *state, const block *ref_block,
|
|
76
|
+
block *next_block, int with_xor) {
|
|
77
|
+
__m256i block_XY[ARGON2_HWORDS_IN_BLOCK];
|
|
78
|
+
unsigned int i;
|
|
79
|
+
|
|
80
|
+
if (with_xor) {
|
|
81
|
+
for (i = 0; i < ARGON2_HWORDS_IN_BLOCK; i++) {
|
|
82
|
+
state[i] = _mm256_xor_si256(
|
|
83
|
+
state[i], _mm256_loadu_si256((const __m256i *)ref_block->v + i));
|
|
84
|
+
block_XY[i] = _mm256_xor_si256(
|
|
85
|
+
state[i], _mm256_loadu_si256((const __m256i *)next_block->v + i));
|
|
86
|
+
}
|
|
87
|
+
} else {
|
|
88
|
+
for (i = 0; i < ARGON2_HWORDS_IN_BLOCK; i++) {
|
|
89
|
+
block_XY[i] = state[i] = _mm256_xor_si256(
|
|
90
|
+
state[i], _mm256_loadu_si256((const __m256i *)ref_block->v + i));
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
for (i = 0; i < 4; ++i) {
|
|
95
|
+
BLAKE2_ROUND_1(state[8 * i + 0], state[8 * i + 4], state[8 * i + 1], state[8 * i + 5],
|
|
96
|
+
state[8 * i + 2], state[8 * i + 6], state[8 * i + 3], state[8 * i + 7]);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
for (i = 0; i < 4; ++i) {
|
|
100
|
+
BLAKE2_ROUND_2(state[ 0 + i], state[ 4 + i], state[ 8 + i], state[12 + i],
|
|
101
|
+
state[16 + i], state[20 + i], state[24 + i], state[28 + i]);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
for (i = 0; i < ARGON2_HWORDS_IN_BLOCK; i++) {
|
|
105
|
+
state[i] = _mm256_xor_si256(state[i], block_XY[i]);
|
|
106
|
+
_mm256_storeu_si256((__m256i *)next_block->v + i, state[i]);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
#else
|
|
110
|
+
static void fill_block(__m128i *state, const block *ref_block,
|
|
111
|
+
block *next_block, int with_xor) {
|
|
112
|
+
__m128i block_XY[ARGON2_OWORDS_IN_BLOCK];
|
|
113
|
+
unsigned int i;
|
|
114
|
+
|
|
115
|
+
if (with_xor) {
|
|
116
|
+
for (i = 0; i < ARGON2_OWORDS_IN_BLOCK; i++) {
|
|
117
|
+
state[i] = _mm_xor_si128(
|
|
118
|
+
state[i], _mm_loadu_si128((const __m128i *)ref_block->v + i));
|
|
119
|
+
block_XY[i] = _mm_xor_si128(
|
|
120
|
+
state[i], _mm_loadu_si128((const __m128i *)next_block->v + i));
|
|
121
|
+
}
|
|
122
|
+
} else {
|
|
123
|
+
for (i = 0; i < ARGON2_OWORDS_IN_BLOCK; i++) {
|
|
124
|
+
block_XY[i] = state[i] = _mm_xor_si128(
|
|
125
|
+
state[i], _mm_loadu_si128((const __m128i *)ref_block->v + i));
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
for (i = 0; i < 8; ++i) {
|
|
130
|
+
BLAKE2_ROUND(state[8 * i + 0], state[8 * i + 1], state[8 * i + 2],
|
|
131
|
+
state[8 * i + 3], state[8 * i + 4], state[8 * i + 5],
|
|
132
|
+
state[8 * i + 6], state[8 * i + 7]);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
for (i = 0; i < 8; ++i) {
|
|
136
|
+
BLAKE2_ROUND(state[8 * 0 + i], state[8 * 1 + i], state[8 * 2 + i],
|
|
137
|
+
state[8 * 3 + i], state[8 * 4 + i], state[8 * 5 + i],
|
|
138
|
+
state[8 * 6 + i], state[8 * 7 + i]);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
for (i = 0; i < ARGON2_OWORDS_IN_BLOCK; i++) {
|
|
142
|
+
state[i] = _mm_xor_si128(state[i], block_XY[i]);
|
|
143
|
+
_mm_storeu_si128((__m128i *)next_block->v + i, state[i]);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
#endif
|
|
147
|
+
|
|
148
|
+
static void next_addresses(block *address_block, block *input_block) {
|
|
149
|
+
/*Temporary zero-initialized blocks*/
|
|
150
|
+
#if defined(__AVX512F__)
|
|
151
|
+
__m512i zero_block[ARGON2_512BIT_WORDS_IN_BLOCK];
|
|
152
|
+
__m512i zero2_block[ARGON2_512BIT_WORDS_IN_BLOCK];
|
|
153
|
+
#elif defined(__AVX2__)
|
|
154
|
+
__m256i zero_block[ARGON2_HWORDS_IN_BLOCK];
|
|
155
|
+
__m256i zero2_block[ARGON2_HWORDS_IN_BLOCK];
|
|
156
|
+
#else
|
|
157
|
+
__m128i zero_block[ARGON2_OWORDS_IN_BLOCK];
|
|
158
|
+
__m128i zero2_block[ARGON2_OWORDS_IN_BLOCK];
|
|
159
|
+
#endif
|
|
160
|
+
|
|
161
|
+
memset(zero_block, 0, sizeof(zero_block));
|
|
162
|
+
memset(zero2_block, 0, sizeof(zero2_block));
|
|
163
|
+
|
|
164
|
+
/*Increasing index counter*/
|
|
165
|
+
input_block->v[6]++;
|
|
166
|
+
|
|
167
|
+
/*First iteration of G*/
|
|
168
|
+
fill_block(zero_block, input_block, address_block, 0);
|
|
169
|
+
|
|
170
|
+
/*Second iteration of G*/
|
|
171
|
+
fill_block(zero2_block, address_block, address_block, 0);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
void fill_segment(const argon2_instance_t *instance,
|
|
175
|
+
argon2_position_t position) {
|
|
176
|
+
block *ref_block = NULL, *curr_block = NULL;
|
|
177
|
+
block address_block, input_block;
|
|
178
|
+
uint64_t pseudo_rand, ref_index, ref_lane;
|
|
179
|
+
uint32_t prev_offset, curr_offset;
|
|
180
|
+
uint32_t starting_index, i;
|
|
181
|
+
#if defined(__AVX512F__)
|
|
182
|
+
__m512i state[ARGON2_512BIT_WORDS_IN_BLOCK];
|
|
183
|
+
#elif defined(__AVX2__)
|
|
184
|
+
__m256i state[ARGON2_HWORDS_IN_BLOCK];
|
|
185
|
+
#else
|
|
186
|
+
__m128i state[ARGON2_OWORDS_IN_BLOCK];
|
|
187
|
+
#endif
|
|
188
|
+
int data_independent_addressing;
|
|
189
|
+
|
|
190
|
+
if (instance == NULL) {
|
|
191
|
+
return;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
data_independent_addressing =
|
|
195
|
+
(instance->type == Argon2_i) ||
|
|
196
|
+
(instance->type == Argon2_id && (position.pass == 0) &&
|
|
197
|
+
(position.slice < ARGON2_SYNC_POINTS / 2));
|
|
198
|
+
|
|
199
|
+
if (data_independent_addressing) {
|
|
200
|
+
init_block_value(&input_block, 0);
|
|
201
|
+
|
|
202
|
+
input_block.v[0] = position.pass;
|
|
203
|
+
input_block.v[1] = position.lane;
|
|
204
|
+
input_block.v[2] = position.slice;
|
|
205
|
+
input_block.v[3] = instance->memory_blocks;
|
|
206
|
+
input_block.v[4] = instance->passes;
|
|
207
|
+
input_block.v[5] = instance->type;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
starting_index = 0;
|
|
211
|
+
|
|
212
|
+
if ((0 == position.pass) && (0 == position.slice)) {
|
|
213
|
+
starting_index = 2; /* we have already generated the first two blocks */
|
|
214
|
+
|
|
215
|
+
/* Don't forget to generate the first block of addresses: */
|
|
216
|
+
if (data_independent_addressing) {
|
|
217
|
+
next_addresses(&address_block, &input_block);
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
/* Offset of the current block */
|
|
222
|
+
curr_offset = position.lane * instance->lane_length +
|
|
223
|
+
position.slice * instance->segment_length + starting_index;
|
|
224
|
+
|
|
225
|
+
if (0 == curr_offset % instance->lane_length) {
|
|
226
|
+
/* Last block in this lane */
|
|
227
|
+
prev_offset = curr_offset + instance->lane_length - 1;
|
|
228
|
+
} else {
|
|
229
|
+
/* Previous block */
|
|
230
|
+
prev_offset = curr_offset - 1;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
memcpy(state, ((instance->memory + prev_offset)->v), ARGON2_BLOCK_SIZE);
|
|
234
|
+
|
|
235
|
+
for (i = starting_index; i < instance->segment_length;
|
|
236
|
+
++i, ++curr_offset, ++prev_offset) {
|
|
237
|
+
/*1.1 Rotating prev_offset if needed */
|
|
238
|
+
if (curr_offset % instance->lane_length == 1) {
|
|
239
|
+
prev_offset = curr_offset - 1;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
/* 1.2 Computing the index of the reference block */
|
|
243
|
+
/* 1.2.1 Taking pseudo-random value from the previous block */
|
|
244
|
+
if (data_independent_addressing) {
|
|
245
|
+
if (i % ARGON2_ADDRESSES_IN_BLOCK == 0) {
|
|
246
|
+
next_addresses(&address_block, &input_block);
|
|
247
|
+
}
|
|
248
|
+
pseudo_rand = address_block.v[i % ARGON2_ADDRESSES_IN_BLOCK];
|
|
249
|
+
} else {
|
|
250
|
+
pseudo_rand = instance->memory[prev_offset].v[0];
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
/* 1.2.2 Computing the lane of the reference block */
|
|
254
|
+
ref_lane = ((pseudo_rand >> 32)) % instance->lanes;
|
|
255
|
+
|
|
256
|
+
if ((position.pass == 0) && (position.slice == 0)) {
|
|
257
|
+
/* Can not reference other lanes yet */
|
|
258
|
+
ref_lane = position.lane;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
/* 1.2.3 Computing the number of possible reference block within the
|
|
262
|
+
* lane.
|
|
263
|
+
*/
|
|
264
|
+
position.index = i;
|
|
265
|
+
ref_index = index_alpha(instance, &position, pseudo_rand & 0xFFFFFFFF,
|
|
266
|
+
ref_lane == position.lane);
|
|
267
|
+
|
|
268
|
+
/* 2 Creating a new block */
|
|
269
|
+
ref_block =
|
|
270
|
+
instance->memory + instance->lane_length * ref_lane + ref_index;
|
|
271
|
+
curr_block = instance->memory + curr_offset;
|
|
272
|
+
if (ARGON2_VERSION_10 == instance->version) {
|
|
273
|
+
/* version 1.2.1 and earlier: overwrite, not XOR */
|
|
274
|
+
fill_block(state, ref_block, curr_block, 0);
|
|
275
|
+
} else {
|
|
276
|
+
if(0 == position.pass) {
|
|
277
|
+
fill_block(state, ref_block, curr_block, 0);
|
|
278
|
+
} else {
|
|
279
|
+
fill_block(state, ref_block, curr_block, 1);
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
}
|