argon2 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
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