argon2 0.1.4 → 1.0.0
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/.rubocop.yml +5 -9
- data/.travis.yml +0 -1
- data/CONTRIBUTING.md +12 -0
- data/Changelog.md +10 -11
- data/README.md +23 -14
- data/ext/argon2_wrap/Makefile +8 -6
- data/ext/argon2_wrap/argon_wrap.c +23 -12
- data/ext/argon2_wrap/test.c +14 -42
- data/ext/phc-winner-argon2/.gitignore +5 -1
- data/ext/phc-winner-argon2/.travis.yml +14 -0
- data/ext/phc-winner-argon2/Makefile +33 -12
- data/ext/phc-winner-argon2/README.md +48 -19
- data/ext/phc-winner-argon2/argon2-specs.pdf +0 -0
- data/ext/phc-winner-argon2/{src → include}/argon2.h +137 -137
- data/ext/phc-winner-argon2/kats/argon2d +12290 -12290
- data/ext/phc-winner-argon2/kats/argon2d.shasum +1 -1
- data/ext/phc-winner-argon2/kats/argon2i +12290 -12290
- data/ext/phc-winner-argon2/kats/argon2i.shasum +1 -1
- data/ext/phc-winner-argon2/opt.o +0 -0
- data/ext/phc-winner-argon2/src/argon2.c +125 -145
- data/ext/phc-winner-argon2/src/bench.c +5 -5
- data/ext/phc-winner-argon2/src/core.c +15 -20
- data/ext/phc-winner-argon2/src/core.h +5 -2
- data/ext/phc-winner-argon2/src/encoding.c +45 -72
- data/ext/phc-winner-argon2/src/encoding.h +24 -0
- data/ext/phc-winner-argon2/src/genkat.c +2 -2
- data/ext/phc-winner-argon2/src/opt.c +19 -10
- data/ext/phc-winner-argon2/src/opt.h +5 -17
- data/ext/phc-winner-argon2/src/ref.c +12 -9
- data/ext/phc-winner-argon2/src/ref.h +4 -12
- data/ext/phc-winner-argon2/src/run.c +67 -42
- data/ext/phc-winner-argon2/src/test.c +131 -0
- data/lib/argon2.rb +6 -5
- data/lib/argon2/constants.rb +3 -2
- data/lib/argon2/engine.rb +1 -0
- data/lib/argon2/errors.rb +37 -36
- data/lib/argon2/ffi_engine.rb +10 -10
- data/lib/argon2/version.rb +2 -1
- metadata +7 -12
@@ -24,12 +24,14 @@
|
|
24
24
|
#define ALIGN(x)
|
25
25
|
#endif
|
26
26
|
|
27
|
+
#define CONST_CAST(x) (x)(uintptr_t)
|
28
|
+
|
27
29
|
/*************************Argon2 internal
|
28
30
|
* constants**************************************************/
|
29
31
|
|
30
32
|
enum argon2_core_constants {
|
31
33
|
/* Version of the algorithm */
|
32
|
-
ARGON2_VERSION_NUMBER =
|
34
|
+
ARGON2_VERSION_NUMBER = 0x13,
|
33
35
|
|
34
36
|
/* Memory block size in bytes */
|
35
37
|
ARGON2_BLOCK_SIZE = 1024,
|
@@ -212,7 +214,8 @@ void fill_segment(const argon2_instance_t *instance,
|
|
212
214
|
* Function that fills the entire memory t_cost times based on the first two
|
213
215
|
* blocks in each lane
|
214
216
|
* @param instance Pointer to the current instance
|
217
|
+
* @return ARGON2_OK if successful, @context->state
|
215
218
|
*/
|
216
|
-
|
219
|
+
int fill_memory_blocks(argon2_instance_t *instance);
|
217
220
|
|
218
221
|
#endif
|
@@ -3,9 +3,10 @@
|
|
3
3
|
#include <string.h>
|
4
4
|
#include <limits.h>
|
5
5
|
#include "encoding.h"
|
6
|
+
#include "core.h"
|
6
7
|
|
7
|
-
|
8
|
-
* Example code for a decoder and encoder of "hash strings", with
|
8
|
+
/*
|
9
|
+
* Example code for a decoder and encoder of "hash strings", with Argon2
|
9
10
|
* parameters.
|
10
11
|
*
|
11
12
|
* This code comprises three sections:
|
@@ -17,7 +18,7 @@
|
|
17
18
|
* the relevant functions are made public (non-static) and be given
|
18
19
|
* reasonable names to avoid collisions with other functions.
|
19
20
|
*
|
20
|
-
* -- The second section is specific to
|
21
|
+
* -- The second section is specific to Argon2. It encodes and decodes
|
21
22
|
* the parameters, salts and outputs. It does not compute the hash
|
22
23
|
* itself.
|
23
24
|
*
|
@@ -58,7 +59,7 @@
|
|
58
59
|
* Some macros for constant-time comparisons. These work over values in
|
59
60
|
* the 0..255 range. Returned value is 0x00 on "false", 0xFF on "true".
|
60
61
|
*/
|
61
|
-
#define EQ(x, y) ((((0U-((unsigned)(x) ^ (unsigned)(y))) >> 8) & 0xFF) ^ 0xFF)
|
62
|
+
#define EQ(x, y) ((((0U - ((unsigned)(x) ^ (unsigned)(y))) >> 8) & 0xFF) ^ 0xFF)
|
62
63
|
#define GT(x, y) ((((unsigned)(y) - (unsigned)(x)) >> 8) & 0xFF)
|
63
64
|
#define GE(x, y) (GT(y, x) ^ 0xFF)
|
64
65
|
#define LT(x, y) GT(y, x)
|
@@ -122,11 +123,11 @@ static size_t to_base64(char *dst, size_t dst_len, const void *src,
|
|
122
123
|
acc_len += 8;
|
123
124
|
while (acc_len >= 6) {
|
124
125
|
acc_len -= 6;
|
125
|
-
*dst++ = (char)
|
126
|
+
*dst++ = (char)b64_byte_to_char((acc >> acc_len) & 0x3F);
|
126
127
|
}
|
127
128
|
}
|
128
129
|
if (acc_len > 0) {
|
129
|
-
*dst++ = (char)
|
130
|
+
*dst++ = (char)b64_byte_to_char((acc << (6 - acc_len)) & 0x3F);
|
130
131
|
}
|
131
132
|
*dst++ = 0;
|
132
133
|
return olen;
|
@@ -224,16 +225,17 @@ static const char *decode_decimal(const char *str, unsigned long *v) {
|
|
224
225
|
|
225
226
|
/* ==================================================================== */
|
226
227
|
/*
|
227
|
-
* Code specific to
|
228
|
+
* Code specific to Argon2.
|
228
229
|
*
|
229
230
|
* The code below applies the following format:
|
230
231
|
*
|
231
|
-
* $
|
232
|
+
* $argon2<T>$m=<num>,t=<num>,p=<num>[,keyid=<bin>][,data=<bin>][$<bin>[$<bin>]]
|
232
233
|
*
|
233
|
-
* where <num> is a decimal integer (positive, fits in
|
234
|
-
* and <bin> is Base64-encoded data (no '=' padding
|
235
|
-
* or whitespace).
|
236
|
-
*
|
234
|
+
* where <T> is either 'd' or 'i', <num> is a decimal integer (positive, fits in
|
235
|
+
* an 'unsigned long'), and <bin> is Base64-encoded data (no '=' padding
|
236
|
+
* characters, no newline or whitespace).
|
237
|
+
* The "keyid" is a binary identifier for a key (up to 8 bytes);
|
238
|
+
* "data" is associated data (up to 32 bytes). When the 'keyid'
|
237
239
|
* (resp. the 'data') is empty, then it is ommitted from the output.
|
238
240
|
*
|
239
241
|
* The last two binary chunks (encoded in Base64) are, in that order,
|
@@ -242,20 +244,19 @@ static const char *decode_decimal(const char *str, unsigned long *v) {
|
|
242
244
|
* The output length is always exactly 32 bytes.
|
243
245
|
*/
|
244
246
|
|
245
|
-
/*
|
246
|
-
* Decode an Argon2i hash string into the provided structure 'ctx'.
|
247
|
-
* Returned value is 1 on success, 0 on error.
|
248
|
-
*/
|
249
247
|
int decode_string(argon2_context *ctx, const char *str, argon2_type type) {
|
248
|
+
|
249
|
+
/* check for prefix */
|
250
250
|
#define CC(prefix) \
|
251
251
|
do { \
|
252
252
|
size_t cc_len = strlen(prefix); \
|
253
253
|
if (strncmp(str, prefix, cc_len) != 0) { \
|
254
|
-
return
|
254
|
+
return ARGON2_DECODING_FAIL; \
|
255
255
|
} \
|
256
256
|
str += cc_len; \
|
257
257
|
} while ((void)0, 0)
|
258
258
|
|
259
|
+
/* prefix checking with supplied code */
|
259
260
|
#define CC_opt(prefix, code) \
|
260
261
|
do { \
|
261
262
|
size_t cc_len = strlen(prefix); \
|
@@ -265,12 +266,13 @@ int decode_string(argon2_context *ctx, const char *str, argon2_type type) {
|
|
265
266
|
} \
|
266
267
|
} while ((void)0, 0)
|
267
268
|
|
269
|
+
/* Decoding prefix into decimal */
|
268
270
|
#define DECIMAL(x) \
|
269
271
|
do { \
|
270
272
|
unsigned long dec_x; \
|
271
273
|
str = decode_decimal(str, &dec_x); \
|
272
274
|
if (str == NULL) { \
|
273
|
-
return
|
275
|
+
return ARGON2_DECODING_FAIL; \
|
274
276
|
} \
|
275
277
|
(x) = dec_x; \
|
276
278
|
} while ((void)0, 0)
|
@@ -280,7 +282,7 @@ int decode_string(argon2_context *ctx, const char *str, argon2_type type) {
|
|
280
282
|
size_t bin_len = (max_len); \
|
281
283
|
str = from_base64(buf, &bin_len, str); \
|
282
284
|
if (str == NULL || bin_len > UINT32_MAX) { \
|
283
|
-
return
|
285
|
+
return ARGON2_DECODING_FAIL; \
|
284
286
|
} \
|
285
287
|
(len) = (uint32_t)bin_len; \
|
286
288
|
} while ((void)0, 0)
|
@@ -288,16 +290,19 @@ int decode_string(argon2_context *ctx, const char *str, argon2_type type) {
|
|
288
290
|
size_t maxadlen = ctx->adlen;
|
289
291
|
size_t maxsaltlen = ctx->saltlen;
|
290
292
|
size_t maxoutlen = ctx->outlen;
|
293
|
+
int validation_result;
|
291
294
|
|
292
295
|
ctx->adlen = 0;
|
293
296
|
ctx->saltlen = 0;
|
294
297
|
ctx->outlen = 0;
|
298
|
+
ctx->pwdlen = 0;
|
299
|
+
|
295
300
|
if (type == Argon2_i)
|
296
301
|
CC("$argon2i");
|
297
302
|
else if (type == Argon2_d)
|
298
303
|
CC("$argon2d");
|
299
304
|
else
|
300
|
-
return
|
305
|
+
return ARGON2_INCORRECT_TYPE;
|
301
306
|
CC("$m=");
|
302
307
|
DECIMAL(ctx->m_cost);
|
303
308
|
CC(",t=");
|
@@ -306,75 +311,39 @@ int decode_string(argon2_context *ctx, const char *str, argon2_type type) {
|
|
306
311
|
DECIMAL(ctx->lanes);
|
307
312
|
ctx->threads = ctx->lanes;
|
308
313
|
|
309
|
-
/*
|
310
|
-
* Both m and t must be no more than 2^32-1. The tests below
|
311
|
-
* use a shift by 30 bits to avoid a direct comparison with
|
312
|
-
* 0xFFFFFFFF, which may trigger a spurious compiler warning
|
313
|
-
* on machines where 'unsigned long' is a 32-bit type.
|
314
|
-
*/
|
315
|
-
if (ctx->m_cost < 1 || (ctx->m_cost >> 30) > 3) {
|
316
|
-
return 0;
|
317
|
-
}
|
318
|
-
if (ctx->t_cost < 1 || (ctx->t_cost >> 30) > 3) {
|
319
|
-
return 0;
|
320
|
-
}
|
321
|
-
|
322
|
-
/*
|
323
|
-
* The parallelism p must be between 1 and 255. The memory cost
|
324
|
-
* parameter, expressed in kilobytes, must be at least 8 times
|
325
|
-
* the value of p.
|
326
|
-
*/
|
327
|
-
if (ctx->lanes < 1 || ctx->lanes > 255) {
|
328
|
-
return 0;
|
329
|
-
}
|
330
|
-
if (ctx->m_cost < (ctx->lanes << 3)) {
|
331
|
-
return 0;
|
332
|
-
}
|
333
|
-
|
334
314
|
CC_opt(",data=", BIN(ctx->ad, maxadlen, ctx->adlen));
|
335
315
|
if (*str == 0) {
|
336
|
-
return
|
316
|
+
return ARGON2_OK;
|
337
317
|
}
|
338
318
|
CC("$");
|
339
319
|
BIN(ctx->salt, maxsaltlen, ctx->saltlen);
|
340
|
-
if (ctx->saltlen < 8) {
|
341
|
-
return 0;
|
342
|
-
}
|
343
320
|
if (*str == 0) {
|
344
|
-
return
|
321
|
+
return ARGON2_OK;
|
345
322
|
}
|
346
323
|
CC("$");
|
347
324
|
BIN(ctx->out, maxoutlen, ctx->outlen);
|
348
|
-
|
349
|
-
|
325
|
+
validation_result = validate_inputs(ctx);
|
326
|
+
if (validation_result != ARGON2_OK) {
|
327
|
+
return validation_result;
|
328
|
+
}
|
329
|
+
if (*str == 0) {
|
330
|
+
return ARGON2_OK;
|
331
|
+
} else {
|
332
|
+
return ARGON2_DECODING_FAIL;
|
350
333
|
}
|
351
|
-
return *str == 0;
|
352
|
-
|
353
334
|
#undef CC
|
354
335
|
#undef CC_opt
|
355
336
|
#undef DECIMAL
|
356
337
|
#undef BIN
|
357
338
|
}
|
358
339
|
|
359
|
-
/*
|
360
|
-
* encode an argon2i hash string into the provided buffer. 'dst_len'
|
361
|
-
* contains the size, in characters, of the 'dst' buffer; if 'dst_len'
|
362
|
-
* is less than the number of required characters (including the
|
363
|
-
* terminating 0), then this function returns 0.
|
364
|
-
*
|
365
|
-
* if pp->output_len is 0, then the hash string will be a salt string
|
366
|
-
* (no output). if pp->salt_len is also 0, then the string will be a
|
367
|
-
* parameter-only string (no salt and no output).
|
368
|
-
*
|
369
|
-
* on success, 1 is returned.
|
370
|
-
*/
|
371
340
|
int encode_string(char *dst, size_t dst_len, argon2_context *ctx,
|
372
341
|
argon2_type type) {
|
373
342
|
#define SS(str) \
|
374
343
|
do { \
|
375
344
|
size_t pp_len = strlen(str); \
|
376
345
|
if (pp_len >= dst_len) { \
|
377
|
-
return
|
346
|
+
return ARGON2_ENCODING_FAIL; \
|
378
347
|
} \
|
379
348
|
memcpy(dst, str, pp_len + 1); \
|
380
349
|
dst += pp_len; \
|
@@ -392,7 +361,7 @@ int encode_string(char *dst, size_t dst_len, argon2_context *ctx,
|
|
392
361
|
do { \
|
393
362
|
size_t sb_len = to_base64(dst, dst_len, buf, len); \
|
394
363
|
if (sb_len == (size_t)-1) { \
|
395
|
-
return
|
364
|
+
return ARGON2_ENCODING_FAIL; \
|
396
365
|
} \
|
397
366
|
dst += sb_len; \
|
398
367
|
dst_len -= sb_len; \
|
@@ -403,7 +372,11 @@ int encode_string(char *dst, size_t dst_len, argon2_context *ctx,
|
|
403
372
|
else if (type == Argon2_d)
|
404
373
|
SS("$argon2d$m=");
|
405
374
|
else
|
406
|
-
return
|
375
|
+
return ARGON2_ENCODING_FAIL;
|
376
|
+
|
377
|
+
if (validate_inputs(ctx) != ARGON2_OK) {
|
378
|
+
return validate_inputs(ctx);
|
379
|
+
}
|
407
380
|
SX(ctx->m_cost);
|
408
381
|
SS(",t=");
|
409
382
|
SX(ctx->t_cost);
|
@@ -416,17 +389,17 @@ int encode_string(char *dst, size_t dst_len, argon2_context *ctx,
|
|
416
389
|
}
|
417
390
|
|
418
391
|
if (ctx->saltlen == 0)
|
419
|
-
return
|
392
|
+
return ARGON2_OK;
|
420
393
|
|
421
394
|
SS("$");
|
422
395
|
SB(ctx->salt, ctx->saltlen);
|
423
396
|
|
424
397
|
if (ctx->outlen == 0)
|
425
|
-
return
|
398
|
+
return ARGON2_OK;
|
426
399
|
|
427
400
|
SS("$");
|
428
401
|
SB(ctx->out, ctx->outlen);
|
429
|
-
return
|
402
|
+
return ARGON2_OK;
|
430
403
|
|
431
404
|
#undef SS
|
432
405
|
#undef SX
|
@@ -2,9 +2,33 @@
|
|
2
2
|
#define ENCODING_H
|
3
3
|
#include "argon2.h"
|
4
4
|
|
5
|
+
#define ARGON2_MAX_DECODED_LANES UINT32_C(255)
|
6
|
+
#define ARGON2_MIN_DECODED_SALT_LEN UINT32_C(8)
|
7
|
+
#define ARGON2_MIN_DECODED_OUT_LEN UINT32_C(12)
|
8
|
+
|
9
|
+
/*
|
10
|
+
* encode an Argon2 hash string into the provided buffer. 'dst_len'
|
11
|
+
* contains the size, in characters, of the 'dst' buffer; if 'dst_len'
|
12
|
+
* is less than the number of required characters (including the
|
13
|
+
* terminating 0), then this function returns ARGON2_ENCODING_ERROR.
|
14
|
+
*
|
15
|
+
* if ctx->outlen is 0, then the hash string will be a salt string
|
16
|
+
* (no output). if ctx->saltlen is also 0, then the string will be a
|
17
|
+
* parameter-only string (no salt and no output).
|
18
|
+
*
|
19
|
+
* on success, ARGON2_OK is returned.
|
20
|
+
*
|
21
|
+
* No other parameters are checked
|
22
|
+
*/
|
5
23
|
int encode_string(char *dst, size_t dst_len, argon2_context *ctx,
|
6
24
|
argon2_type type);
|
7
25
|
|
26
|
+
/*
|
27
|
+
* Decodes an Argon2 hash string into the provided structure 'ctx'.
|
28
|
+
* The fields ctx.saltlen, ctx.adlen, ctx.outlen set the maximal salt, ad, out
|
29
|
+
* length values that are allowed; invalid input string causes an error.
|
30
|
+
* Returned value is ARGON2_OK on success, other ARGON2_ codes on error.
|
31
|
+
*/
|
8
32
|
int decode_string(argon2_context *ctx, const char *str, argon2_type type);
|
9
33
|
|
10
34
|
#endif
|
@@ -180,9 +180,9 @@ static void generate_testvectors(const char *type) {
|
|
180
180
|
#undef TEST_ADLEN
|
181
181
|
|
182
182
|
if (!strcmp(type, "d")) {
|
183
|
-
|
183
|
+
argon2d_ctx(&context);
|
184
184
|
} else if (!strcmp(type, "i")) {
|
185
|
-
|
185
|
+
argon2i_ctx(&context);
|
186
186
|
} else
|
187
187
|
fatal("wrong Argon2 type");
|
188
188
|
}
|
@@ -16,19 +16,20 @@
|
|
16
16
|
#include <stdlib.h>
|
17
17
|
|
18
18
|
#include "argon2.h"
|
19
|
-
#include "core.h"
|
20
19
|
#include "opt.h"
|
21
20
|
|
22
21
|
#include "blake2/blake2.h"
|
23
22
|
#include "blake2/blamka-round-opt.h"
|
24
23
|
|
25
|
-
void
|
24
|
+
void fill_block_with_xor(__m128i *state, const uint8_t *ref_block, uint8_t *next_block) {
|
26
25
|
__m128i block_XY[ARGON2_OWORDS_IN_BLOCK];
|
27
26
|
uint32_t i;
|
28
27
|
|
29
|
-
for (i = 0; i < ARGON2_OWORDS_IN_BLOCK; i++) {
|
30
|
-
|
28
|
+
for (i = 0; i < ARGON2_OWORDS_IN_BLOCK; i++) {
|
29
|
+
state[i] = _mm_xor_si128(
|
31
30
|
state[i], _mm_loadu_si128((__m128i const *)(&ref_block[16 * i])));
|
31
|
+
block_XY[i] = _mm_xor_si128(
|
32
|
+
state[i], _mm_loadu_si128((__m128i const *)(&next_block[16 * i])));
|
32
33
|
}
|
33
34
|
|
34
35
|
for (i = 0; i < 8; ++i) {
|
@@ -52,7 +53,7 @@ void fill_block(__m128i *state, const uint8_t *ref_block, uint8_t *next_block) {
|
|
52
53
|
void generate_addresses(const argon2_instance_t *instance,
|
53
54
|
const argon2_position_t *position,
|
54
55
|
uint64_t *pseudo_rands) {
|
55
|
-
block address_block, input_block;
|
56
|
+
block address_block, input_block, tmp_block;
|
56
57
|
uint32_t i;
|
57
58
|
|
58
59
|
init_block_value(&address_block, 0);
|
@@ -68,14 +69,20 @@ void generate_addresses(const argon2_instance_t *instance,
|
|
68
69
|
|
69
70
|
for (i = 0; i < instance->segment_length; ++i) {
|
70
71
|
if (i % ARGON2_ADDRESSES_IN_BLOCK == 0) {
|
72
|
+
/*Temporary zero-initialized blocks*/
|
71
73
|
__m128i zero_block[ARGON2_OWORDS_IN_BLOCK];
|
72
74
|
__m128i zero2_block[ARGON2_OWORDS_IN_BLOCK];
|
73
75
|
memset(zero_block, 0, sizeof(zero_block));
|
74
76
|
memset(zero2_block, 0, sizeof(zero2_block));
|
77
|
+
init_block_value(&address_block, 0);
|
78
|
+
init_block_value(&tmp_block, 0);
|
79
|
+
/*Increasing index counter*/
|
75
80
|
input_block.v[6]++;
|
76
|
-
|
77
|
-
|
78
|
-
|
81
|
+
/*First iteration of G*/
|
82
|
+
fill_block_with_xor(zero_block, (uint8_t *)&input_block.v,
|
83
|
+
(uint8_t *)&tmp_block.v);
|
84
|
+
/*Second iteration of G*/
|
85
|
+
fill_block_with_xor(zero2_block, (uint8_t *)&tmp_block.v,
|
79
86
|
(uint8_t *)&address_block.v);
|
80
87
|
}
|
81
88
|
|
@@ -91,7 +98,7 @@ void fill_segment(const argon2_instance_t *instance,
|
|
91
98
|
uint32_t prev_offset, curr_offset;
|
92
99
|
uint32_t starting_index, i;
|
93
100
|
__m128i state[64];
|
94
|
-
int data_independent_addressing
|
101
|
+
int data_independent_addressing;
|
95
102
|
|
96
103
|
/* Pseudo-random values that determine the reference block position */
|
97
104
|
uint64_t *pseudo_rands = NULL;
|
@@ -100,6 +107,8 @@ void fill_segment(const argon2_instance_t *instance,
|
|
100
107
|
return;
|
101
108
|
}
|
102
109
|
|
110
|
+
data_independent_addressing = (instance->type == Argon2_i);
|
111
|
+
|
103
112
|
pseudo_rands =
|
104
113
|
(uint64_t *)malloc(sizeof(uint64_t) * instance->segment_length);
|
105
114
|
if (pseudo_rands == NULL) {
|
@@ -164,7 +173,7 @@ void fill_segment(const argon2_instance_t *instance,
|
|
164
173
|
ref_block =
|
165
174
|
instance->memory + instance->lane_length * ref_lane + ref_index;
|
166
175
|
curr_block = instance->memory + curr_offset;
|
167
|
-
|
176
|
+
fill_block_with_xor(state, (uint8_t *)ref_block->v, (uint8_t *)curr_block->v);
|
168
177
|
}
|
169
178
|
|
170
179
|
free(pseudo_rands);
|
@@ -14,19 +14,18 @@
|
|
14
14
|
#ifndef ARGON2_OPT_H
|
15
15
|
#define ARGON2_OPT_H
|
16
16
|
|
17
|
-
#include <stdint.h>
|
18
|
-
#include <emmintrin.h>
|
19
|
-
#include "argon2.h"
|
20
17
|
#include "core.h"
|
18
|
+
#include <emmintrin.h>
|
21
19
|
|
22
20
|
/*
|
23
|
-
* Function fills a new memory block.
|
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
|
24
23
|
* @param state Pointer to the just produced block. Content will be updated(!)
|
25
24
|
* @param ref_block Pointer to the reference block
|
26
|
-
* @param next_block Pointer to the block to be
|
25
|
+
* @param next_block Pointer to the block to be XORed over. May coincide with @ref_block
|
27
26
|
* @pre all block pointers must be valid
|
28
27
|
*/
|
29
|
-
void
|
28
|
+
void fill_block_with_xor(__m128i *state, const uint8_t *ref_block, uint8_t *next_block);
|
30
29
|
|
31
30
|
/*
|
32
31
|
* Generate pseudo-random values to reference blocks in the segment and puts
|
@@ -40,15 +39,4 @@ void generate_addresses(const argon2_instance_t *instance,
|
|
40
39
|
const argon2_position_t *position,
|
41
40
|
uint64_t *pseudo_rands);
|
42
41
|
|
43
|
-
/*
|
44
|
-
* Function that fills the segment using previous segments also from other
|
45
|
-
* threads.
|
46
|
-
* Identical to the reference code except that it calls optimized FillBlock()
|
47
|
-
* @param instance Pointer to the current instance
|
48
|
-
* @param position Current position
|
49
|
-
* @pre all block pointers must be valid
|
50
|
-
*/
|
51
|
-
void fill_segment(const argon2_instance_t *instance,
|
52
|
-
argon2_position_t position);
|
53
|
-
|
54
42
|
#endif /* ARGON2_OPT_H */
|