argon2 0.0.1 → 0.0.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.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +4 -0
  3. data/.travis.yml +2 -0
  4. data/README.md +25 -9
  5. data/argon2.gemspec +10 -2
  6. data/bin/console +1 -1
  7. data/bin/setup +3 -0
  8. data/ext/argon2_wrap/Makefile +72 -0
  9. data/ext/argon2_wrap/argon_wrap.c +65 -0
  10. data/ext/argon2_wrap/extconf.rb +1 -0
  11. data/ext/argon2_wrap/test.c +67 -0
  12. data/ext/phc-winner-argon2/.gitignore +7 -0
  13. data/ext/phc-winner-argon2/LICENSE +31 -0
  14. data/ext/phc-winner-argon2/Makefile +102 -0
  15. data/ext/phc-winner-argon2/README.md +193 -0
  16. data/ext/phc-winner-argon2/argon2-specs.pdf +0 -0
  17. data/ext/phc-winner-argon2/kats/argon2d +12302 -0
  18. data/ext/phc-winner-argon2/kats/argon2d.shasum +1 -0
  19. data/ext/phc-winner-argon2/kats/argon2i +12302 -0
  20. data/ext/phc-winner-argon2/kats/argon2i.shasum +1 -0
  21. data/ext/phc-winner-argon2/kats/check-sums.sh +13 -0
  22. data/ext/phc-winner-argon2/kats/test.sh +47 -0
  23. data/ext/phc-winner-argon2/src/argon2.c +360 -0
  24. data/ext/phc-winner-argon2/src/argon2.h +298 -0
  25. data/ext/phc-winner-argon2/src/bench.c +111 -0
  26. data/ext/phc-winner-argon2/src/blake2/blake2-impl.h +143 -0
  27. data/ext/phc-winner-argon2/src/blake2/blake2.h +74 -0
  28. data/ext/phc-winner-argon2/src/blake2/blake2b.c +372 -0
  29. data/ext/phc-winner-argon2/src/blake2/blamka-round-opt.h +162 -0
  30. data/ext/phc-winner-argon2/src/blake2/blamka-round-ref.h +39 -0
  31. data/ext/phc-winner-argon2/src/core.c +662 -0
  32. data/ext/phc-winner-argon2/src/core.h +226 -0
  33. data/ext/phc-winner-argon2/src/genkat.c +194 -0
  34. data/ext/phc-winner-argon2/src/genkat.h +45 -0
  35. data/ext/phc-winner-argon2/src/opt.c +173 -0
  36. data/ext/phc-winner-argon2/src/opt.h +49 -0
  37. data/ext/phc-winner-argon2/src/ref.c +175 -0
  38. data/ext/phc-winner-argon2/src/ref.h +49 -0
  39. data/ext/phc-winner-argon2/src/run.c +223 -0
  40. data/ext/phc-winner-argon2/src/thread.c +36 -0
  41. data/ext/phc-winner-argon2/src/thread.h +46 -0
  42. data/lib/argon2.rb +15 -32
  43. data/lib/argon2/constants.rb +6 -0
  44. data/lib/argon2/engine.rb +10 -0
  45. data/lib/argon2/errors.rb +36 -0
  46. data/lib/argon2/ffi_engine.rb +47 -0
  47. data/lib/argon2/version.rb +1 -1
  48. metadata +75 -11
@@ -0,0 +1,226 @@
1
+ /*
2
+ * Argon2 source code package
3
+ *
4
+ * Written by Daniel Dinu and Dmitry Khovratovich, 2015
5
+ *
6
+ * This work is licensed under a Creative Commons CC0 1.0 License/Waiver.
7
+ *
8
+ * You should have received a copy of the CC0 Public Domain Dedication along
9
+ * with
10
+ * this software. If not, see
11
+ * <http://creativecommons.org/publicdomain/zero/1.0/>.
12
+ */
13
+
14
+ #ifndef ARGON2_CORE_H
15
+ #define ARGON2_CORE_H
16
+
17
+ #if defined(_MSC_VER)
18
+ #define ALIGN(n) __declspec(align(16))
19
+ #elif defined(__GNUC__) || defined(__clang)
20
+ #define ALIGN(x) __attribute__((__aligned__(x)))
21
+ #else
22
+ #define ALIGN(x)
23
+ #endif
24
+
25
+ /*************************Argon2 internal
26
+ * constants**************************************************/
27
+
28
+ enum argon2_core_constants {
29
+ /* Version of the algorithm */
30
+ ARGON2_VERSION_NUMBER = 0x10,
31
+
32
+ /* Memory block size in bytes */
33
+ ARGON2_BLOCK_SIZE = 1024,
34
+ ARGON2_WORDS_IN_BLOCK = ARGON2_BLOCK_SIZE / 8,
35
+ ARGON2_QWORDS_IN_BLOCK = 64,
36
+
37
+ /* Number of pseudo-random values generated by one call to Blake in Argon2i
38
+ to
39
+ generate reference block positions */
40
+ ARGON2_ADDRESSES_IN_BLOCK = 128,
41
+
42
+ /* Pre-hashing digest length and its extension*/
43
+ ARGON2_PREHASH_DIGEST_LENGTH = 64,
44
+ ARGON2_PREHASH_SEED_LENGTH = 72
45
+ };
46
+
47
+ /* Argon2 primitive type */
48
+ typedef enum Argon2_type { Argon2_d = 0, Argon2_i = 1 } argon2_type;
49
+
50
+ /*************************Argon2 internal data
51
+ * types**************************************************/
52
+
53
+ /*
54
+ * Structure for the (1KB) memory block implemented as 128 64-bit words.
55
+ * Memory blocks can be copied, XORed. Internal words can be accessed by [] (no
56
+ * bounds checking).
57
+ */
58
+ typedef struct _block { uint64_t v[ARGON2_WORDS_IN_BLOCK]; } block;
59
+
60
+ /*****************Functions that work with the block******************/
61
+
62
+ /* Initialize each byte of the block with @in */
63
+ void init_block_value(block *b, uint8_t in);
64
+
65
+ /* Copy block @src to block @dst */
66
+ void copy_block(block *dst, const block *src);
67
+
68
+ /* XOR @src onto @dst bytewise */
69
+ void xor_block(block *dst, const block *src);
70
+
71
+ /*
72
+ * Argon2 instance: memory pointer, number of passes, amount of memory, type,
73
+ * and derived values.
74
+ * Used to evaluate the number and location of blocks to construct in each
75
+ * thread
76
+ */
77
+ typedef struct Argon2_instance_t {
78
+ block *memory; /* Memory pointer */
79
+ uint32_t passes; /* Number of passes */
80
+ uint32_t memory_blocks; /* Number of blocks in memory */
81
+ uint32_t segment_length;
82
+ uint32_t lane_length;
83
+ uint32_t lanes;
84
+ uint32_t threads;
85
+ argon2_type type;
86
+ int print_internals; /* whether to print the memory blocks */
87
+ } argon2_instance_t;
88
+
89
+ /*
90
+ * Argon2 position: where we construct the block right now. Used to distribute
91
+ * work between threads.
92
+ */
93
+ typedef struct Argon2_position_t {
94
+ uint32_t pass;
95
+ uint32_t lane;
96
+ uint8_t slice;
97
+ uint32_t index;
98
+ } argon2_position_t;
99
+
100
+ /*Struct that holds the inputs for thread handling FillSegment*/
101
+ typedef struct Argon2_thread_data {
102
+ argon2_instance_t *instance_ptr;
103
+ argon2_position_t pos;
104
+ } argon2_thread_data;
105
+
106
+ /*************************Argon2 core
107
+ * functions**************************************************/
108
+
109
+ /* Allocates memory to the given pointer
110
+ * @param memory pointer to the pointer to the memory
111
+ * @param m_cost number of blocks to allocate in the memory
112
+ * @return ARGON2_OK if @memory is a valid pointer and memory is allocated
113
+ */
114
+ int allocate_memory(block **memory, uint32_t m_cost);
115
+
116
+ /* Function that securely cleans the memory
117
+ * @param mem Pointer to the memory
118
+ * @param s Memory size in bytes
119
+ */
120
+ void secure_wipe_memory(void *v, size_t n);
121
+
122
+ /* Clears memory
123
+ * @param instance pointer to the current instance
124
+ * @param clear_memory indicates if we clear the memory with zeros.
125
+ */
126
+ void clear_memory(argon2_instance_t *instance, int clear);
127
+
128
+ /* Deallocates memory
129
+ * @param memory pointer to the blocks
130
+ */
131
+ void free_memory(block *memory);
132
+
133
+ /*
134
+ * Computes absolute position of reference block in the lane following a skewed
135
+ * distribution and using a pseudo-random value as input
136
+ * @param instance Pointer to the current instance
137
+ * @param position Pointer to the current position
138
+ * @param pseudo_rand 32-bit pseudo-random value used to determine the position
139
+ * @param same_lane Indicates if the block will be taken from the current lane.
140
+ * If so we can reference the current segment
141
+ * @pre All pointers must be valid
142
+ */
143
+ uint32_t index_alpha(const argon2_instance_t *instance,
144
+ const argon2_position_t *position, uint32_t pseudo_rand,
145
+ int same_lane);
146
+
147
+ /*
148
+ * Function that validates all inputs against predefined restrictions and return
149
+ * an error code
150
+ * @param context Pointer to current Argon2 context
151
+ * @return ARGON2_OK if everything is all right, otherwise one of error codes
152
+ * (all defined in <argon2.h>
153
+ */
154
+ int validate_inputs(const argon2_context *context);
155
+
156
+ /*
157
+ * Hashes all the inputs into @a blockhash[PREHASH_DIGEST_LENGTH], clears
158
+ * password and secret if needed
159
+ * @param context Pointer to the Argon2 internal structure containing memory
160
+ * pointer, and parameters for time and space requirements.
161
+ * @param blockhash Buffer for pre-hashing digest
162
+ * @param type Argon2 type
163
+ * @pre @a blockhash must have at least @a PREHASH_DIGEST_LENGTH bytes
164
+ * allocated
165
+ */
166
+ void initial_hash(uint8_t *blockhash, argon2_context *context,
167
+ argon2_type type);
168
+
169
+ /*
170
+ * Function creates first 2 blocks per lane
171
+ * @param instance Pointer to the current instance
172
+ * @param blockhash Pointer to the pre-hashing digest
173
+ * @pre blockhash must point to @a PREHASH_SEED_LENGTH allocated values
174
+ */
175
+ void fill_firsts_blocks(uint8_t *blockhash, const argon2_instance_t *instance);
176
+
177
+ /*
178
+ * Function allocates memory, hashes the inputs with Blake, and creates first
179
+ * two blocks. Returns the pointer to the main memory with 2 blocks per lane
180
+ * initialized
181
+ * @param context Pointer to the Argon2 internal structure containing memory
182
+ * pointer, and parameters for time and space requirements.
183
+ * @param instance Current Argon2 instance
184
+ * @return Zero if successful, -1 if memory failed to allocate. @context->state
185
+ * will be modified if successful.
186
+ */
187
+ int initialize(argon2_instance_t *instance, argon2_context *context);
188
+
189
+ /*
190
+ * XORing the last block of each lane, hashing it, making the tag. Deallocates
191
+ * the memory.
192
+ * @param context Pointer to current Argon2 context (use only the out parameters
193
+ * from it)
194
+ * @param instance Pointer to current instance of Argon2
195
+ * @pre instance->state must point to necessary amount of memory
196
+ * @pre context->out must point to outlen bytes of memory
197
+ * @pre if context->free_cbk is not NULL, it should point to a function that
198
+ * deallocates memory
199
+ */
200
+ void finalize(const argon2_context *context, argon2_instance_t *instance);
201
+
202
+ /*
203
+ * Function that fills the segment using previous segments also from other
204
+ * threads
205
+ * @param instance Pointer to the current instance
206
+ * @param position Current position
207
+ * @pre all block pointers must be valid
208
+ */
209
+ void fill_segment(const argon2_instance_t *instance,
210
+ argon2_position_t position);
211
+
212
+ /*
213
+ * Function that fills the entire memory t_cost times based on the first two
214
+ * blocks in each lane
215
+ * @param instance Pointer to the current instance
216
+ */
217
+ void fill_memory_blocks(argon2_instance_t *instance);
218
+
219
+ /*
220
+ * Function that performs memory-hard hashing with certain degree of parallelism
221
+ * @param context Pointer to the Argon2 internal structure
222
+ * @return Error code if smth is wrong, ARGON2_OK otherwise
223
+ */
224
+ int argon2_core(argon2_context *context, argon2_type type);
225
+
226
+ #endif
@@ -0,0 +1,194 @@
1
+ /*
2
+ * Argon2 source code package
3
+ *
4
+ * Written by Daniel Dinu and Dmitry Khovratovich, 2015
5
+ *
6
+ * This work is licensed under a Creative Commons CC0 1.0 License/Waiver.
7
+ *
8
+ * You should have received a copy of the CC0 Public Domain Dedication along
9
+ * with
10
+ * this software. If not, see
11
+ * <http://creativecommons.org/publicdomain/zero/1.0/>.
12
+ */
13
+
14
+ #include <inttypes.h>
15
+ #include <stdio.h>
16
+ #include <stdlib.h>
17
+ #include <string.h>
18
+ #include "argon2.h"
19
+ #include "core.h"
20
+
21
+ void initial_kat(const uint8_t *blockhash, const argon2_context *context,
22
+ argon2_type type) {
23
+ unsigned i;
24
+
25
+ if (blockhash != NULL && context != NULL) {
26
+ printf("=======================================");
27
+
28
+ switch (type) {
29
+ case Argon2_d:
30
+ printf("Argon2d\n");
31
+ break;
32
+
33
+ case Argon2_i:
34
+ printf("Argon2i\n");
35
+ break;
36
+
37
+ default:
38
+ break;
39
+ }
40
+
41
+ printf("Memory: %u KiB, Iterations: %u, Parallelism: %u lanes, Tag "
42
+ "length: %u bytes\n",
43
+ context->m_cost, context->t_cost, context->lanes,
44
+ context->outlen);
45
+
46
+ printf("Password[%u]: ", context->pwdlen);
47
+
48
+ if (context->flags & ARGON2_FLAG_CLEAR_PASSWORD) {
49
+ printf("CLEARED\n");
50
+ } else {
51
+ for (i = 0; i < context->pwdlen; ++i) {
52
+ printf("%2.2x ", ((unsigned char *)context->pwd)[i]);
53
+ }
54
+
55
+ printf("\n");
56
+ }
57
+
58
+ printf("Salt[%u]: ", context->saltlen);
59
+
60
+ for (i = 0; i < context->saltlen; ++i) {
61
+ printf("%2.2x ", ((unsigned char *)context->salt)[i]);
62
+ }
63
+
64
+ printf("\n");
65
+
66
+ printf("Secret[%u]: ", context->secretlen);
67
+
68
+ if (context->flags & ARGON2_FLAG_CLEAR_SECRET) {
69
+ printf("CLEARED\n");
70
+ } else {
71
+ for (i = 0; i < context->secretlen; ++i) {
72
+ printf("%2.2x ", ((unsigned char *)context->secret)[i]);
73
+ }
74
+
75
+ printf("\n");
76
+ }
77
+
78
+ printf("Associated data[%u]: ", context->adlen);
79
+
80
+ for (i = 0; i < context->adlen; ++i) {
81
+ printf("%2.2x ", ((unsigned char *)context->ad)[i]);
82
+ }
83
+
84
+ printf("\n");
85
+
86
+ printf("Pre-hashing digest: ");
87
+
88
+ for (i = 0; i < ARGON2_PREHASH_DIGEST_LENGTH; ++i) {
89
+ printf("%2.2x ", ((unsigned char *)blockhash)[i]);
90
+ }
91
+
92
+ printf("\n");
93
+ }
94
+ }
95
+
96
+ void print_tag(const void *out, uint32_t outlen) {
97
+ unsigned i;
98
+ if (out != NULL) {
99
+ printf("Tag: ");
100
+
101
+ for (i = 0; i < outlen; ++i) {
102
+ printf("%2.2x ", ((uint8_t *)out)[i]);
103
+ }
104
+
105
+ printf("\n");
106
+ }
107
+ }
108
+
109
+ void internal_kat(const argon2_instance_t *instance, uint32_t pass) {
110
+
111
+ if (instance != NULL) {
112
+ uint32_t i, j;
113
+ printf("\n After pass %u:\n", pass);
114
+
115
+ for (i = 0; i < instance->memory_blocks; ++i) {
116
+ uint32_t how_many_words =
117
+ (instance->memory_blocks > ARGON2_WORDS_IN_BLOCK)
118
+ ? 1
119
+ : ARGON2_WORDS_IN_BLOCK;
120
+
121
+ for (j = 0; j < how_many_words; ++j)
122
+ printf("Block %.4u [%3u]: %016" PRIx64 "\n", i, j,
123
+ instance->memory[i].v[j]);
124
+ }
125
+ }
126
+ }
127
+
128
+ static void fatal(const char *error) {
129
+ fprintf(stderr, "Error: %s\n", error);
130
+ exit(1);
131
+ }
132
+
133
+ static void generate_testvectors(const char *type) {
134
+ #define TEST_OUTLEN 32
135
+ #define TEST_PWDLEN 32
136
+ #define TEST_SALTLEN 16
137
+ #define TEST_SECRETLEN 8
138
+ #define TEST_ADLEN 12
139
+ argon2_context context;
140
+
141
+ unsigned char out[TEST_OUTLEN];
142
+ unsigned char pwd[TEST_PWDLEN];
143
+ unsigned char salt[TEST_SALTLEN];
144
+ unsigned char secret[TEST_SECRETLEN];
145
+ unsigned char ad[TEST_ADLEN];
146
+ const allocate_fptr myown_allocator = NULL;
147
+ const deallocate_fptr myown_deallocator = NULL;
148
+
149
+ unsigned t_cost = 3;
150
+ unsigned m_cost = 16;
151
+ unsigned lanes = 4;
152
+
153
+ memset(pwd, 1, TEST_OUTLEN);
154
+ memset(salt, 2, TEST_SALTLEN);
155
+ memset(secret, 3, TEST_SECRETLEN);
156
+ memset(ad, 4, TEST_ADLEN);
157
+
158
+ context.out = out;
159
+ context.outlen = TEST_OUTLEN;
160
+ context.pwd = pwd;
161
+ context.pwdlen = TEST_PWDLEN;
162
+ context.salt = salt;
163
+ context.saltlen = TEST_SALTLEN;
164
+ context.secret = secret;
165
+ context.secretlen = TEST_SECRETLEN;
166
+ context.ad = ad;
167
+ context.adlen = TEST_ADLEN;
168
+ context.t_cost = t_cost;
169
+ context.m_cost = m_cost;
170
+ context.lanes = lanes;
171
+ context.threads = lanes;
172
+ context.allocate_cbk = myown_allocator;
173
+ context.free_cbk = myown_deallocator;
174
+ context.flags = 0;
175
+
176
+ #undef TEST_OUTLEN
177
+ #undef TEST_PWDLEN
178
+ #undef TEST_SALTLEN
179
+ #undef TEST_SECRETLEN
180
+ #undef TEST_ADLEN
181
+
182
+ if (!strcmp(type, "d")) {
183
+ argon2d(&context);
184
+ } else if (!strcmp(type, "i")) {
185
+ argon2i(&context);
186
+ } else
187
+ fatal("wrong Argon2 type");
188
+ }
189
+
190
+ int main(int argc, char *argv[]) {
191
+ const char *type = (argc > 1) ? argv[1] : "i";
192
+ generate_testvectors(type);
193
+ return ARGON2_OK;
194
+ }
@@ -0,0 +1,45 @@
1
+ /*
2
+ * Argon2 source code package
3
+ *
4
+ * Written by Daniel Dinu and Dmitry Khovratovich, 2015
5
+ *
6
+ * This work is licensed under a Creative Commons CC0 1.0 License/Waiver.
7
+ *
8
+ * You should have received a copy of the CC0 Public Domain Dedication along
9
+ * with
10
+ * this software. If not, see
11
+ * <http://creativecommons.org/publicdomain/zero/1.0/>.
12
+ */
13
+
14
+ #ifndef ARGON2_KAT_H
15
+ #define ARGON2_KAT_H
16
+
17
+ /*
18
+ * Initial KAT function that prints the inputs to the file
19
+ * @param blockhash Array that contains pre-hashing digest
20
+ * @param context Holds inputs
21
+ * @param type Argon2 type
22
+ * @pre blockhash must point to INPUT_INITIAL_HASH_LENGTH bytes
23
+ * @pre context member pointers must point to allocated memory of size according
24
+ * to the length values
25
+ */
26
+ void initial_kat(const uint8_t *blockhash, const argon2_context *context,
27
+ argon2_type type);
28
+
29
+ /*
30
+ * Function that prints the output tag
31
+ * @param out output array pointer
32
+ * @param outlen digest length
33
+ * @pre out must point to @a outlen bytes
34
+ **/
35
+ void print_tag(const void *out, uint32_t outlen);
36
+
37
+ /*
38
+ * Function that prints the internal state at given moment
39
+ * @param instance pointer to the current instance
40
+ * @param pass current pass number
41
+ * @pre instance must have necessary memory allocated
42
+ **/
43
+ void internal_kat(const argon2_instance_t *instance, uint32_t pass);
44
+
45
+ #endif