fastpbkdf2 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/Rakefile +11 -0
- data/ext/fastpbkdf2_native/binding.c +54 -0
- data/ext/fastpbkdf2_native/extconf.rb +9 -0
- data/ext/fastpbkdf2_native/fastpbkdf2.c +393 -0
- data/ext/fastpbkdf2_native/fastpbkdf2.h +71 -0
- data/lib/fastpbkdf2.rb +14 -0
- metadata +78 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 986b8e83bd6d157efa281fcb0e5f137153a3e67c
|
4
|
+
data.tar.gz: 34841f44f77a35343122ae7891f8083febf68bfc
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: a7a9ea8322183fe84df4037a04e9ea1c6ef2cd3a1abc218e22f0da94a3f20b934c0d8adf5a9803adb4ac7eeae4aa61a7e2f067ccf52091d08769cfaa9b6fbadd
|
7
|
+
data.tar.gz: a119f1e7cb847e3a1674d37b759be06db62d0dd3925fd2c9079782a6d1ff96e190dc28bbbfb74a777da694186d993b650aa6dcbe57562f8bbdd953fdcb36a733
|
data/Rakefile
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
require 'rake/extensiontask'
|
2
|
+
|
3
|
+
spec = Gem::Specification.load('fastpbkdf2.gemspec')
|
4
|
+
Rake::ExtensionTask.new('fastpbkdf2_native', spec)
|
5
|
+
|
6
|
+
require 'rake/testtask'
|
7
|
+
Rake::TestTask.new do |t|
|
8
|
+
t.libs << "test"
|
9
|
+
t.test_files = FileList['test/ruby/test*.rb']
|
10
|
+
t.verbose = true
|
11
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
#include <ruby.h>
|
2
|
+
#include "fastpbkdf2.h"
|
3
|
+
|
4
|
+
static VALUE fastpbkdf2;
|
5
|
+
|
6
|
+
static VALUE Sha1(VALUE self, VALUE _pw, VALUE _salt, VALUE _iterations, VALUE _keylen) {
|
7
|
+
uint8_t *pw = NULL, *salt = NULL;
|
8
|
+
size_t npw, nsalt;
|
9
|
+
unsigned int iterations, keylen;
|
10
|
+
unsigned char out[2048] = {0};
|
11
|
+
VALUE result;
|
12
|
+
|
13
|
+
Check_Type(_pw, T_STRING);
|
14
|
+
pw = (unsigned char*) RSTRING_PTR(_pw);
|
15
|
+
npw = RSTRING_LEN(_pw);
|
16
|
+
if (npw > 1024) {
|
17
|
+
rb_raise(rb_eRangeError, "password length must be between 0 and 1024");
|
18
|
+
}
|
19
|
+
// printf("pw: %s\n", pw);
|
20
|
+
|
21
|
+
Check_Type(_salt, T_STRING);
|
22
|
+
salt = (unsigned char*) RSTRING_PTR(_salt);
|
23
|
+
nsalt = RSTRING_LEN(_salt);
|
24
|
+
if (nsalt > 1024) {
|
25
|
+
rb_raise(rb_eRangeError, "salt length must be between 0 and 1024");
|
26
|
+
}
|
27
|
+
// printf("salt: %s\n", salt);
|
28
|
+
|
29
|
+
Check_Type(_iterations, T_FIXNUM);
|
30
|
+
iterations = NUM2ULL(_iterations);
|
31
|
+
if (iterations <= 0) {
|
32
|
+
rb_raise(rb_eRangeError, "iterations must be greater than 0");
|
33
|
+
}
|
34
|
+
// printf("iterations: %d\n", iterations);
|
35
|
+
|
36
|
+
Check_Type(_keylen, T_FIXNUM);
|
37
|
+
keylen = NUM2ULL(_keylen);
|
38
|
+
if (keylen <= 0 || keylen > 1024) {
|
39
|
+
rb_raise(rb_eRangeError, "keylen must be between 1 and 1024");
|
40
|
+
}
|
41
|
+
// printf("keylen: %d\n", keylen);
|
42
|
+
|
43
|
+
fastpbkdf2_hmac_sha1(pw, npw, salt, nsalt, iterations, out, keylen);
|
44
|
+
|
45
|
+
result = rb_str_new(out, keylen);
|
46
|
+
|
47
|
+
return result;
|
48
|
+
}
|
49
|
+
|
50
|
+
void Init_fastpbkdf2_native(void) {
|
51
|
+
fastpbkdf2 = rb_define_module("Fastpbkdf2");
|
52
|
+
|
53
|
+
rb_define_module_function(fastpbkdf2, "sha1", Sha1, 4);
|
54
|
+
}
|
@@ -0,0 +1,393 @@
|
|
1
|
+
/*
|
2
|
+
* fast-pbkdf2 - Optimal PBKDF2-HMAC calculation
|
3
|
+
* Written in 2015 by Joseph Birr-Pixton <jpixton@gmail.com>
|
4
|
+
*
|
5
|
+
* To the extent possible under law, the author(s) have dedicated all
|
6
|
+
* copyright and related and neighboring rights to this software to the
|
7
|
+
* public domain worldwide. This software is distributed without any
|
8
|
+
* warranty.
|
9
|
+
*
|
10
|
+
* You should have received a copy of the CC0 Public Domain Dedication
|
11
|
+
* along with this software. If not, see
|
12
|
+
* <http://creativecommons.org/publicdomain/zero/1.0/>.
|
13
|
+
*/
|
14
|
+
|
15
|
+
#include "fastpbkdf2.h"
|
16
|
+
|
17
|
+
#include <assert.h>
|
18
|
+
#include <string.h>
|
19
|
+
|
20
|
+
#include <openssl/sha.h>
|
21
|
+
|
22
|
+
/* --- Common useful things --- */
|
23
|
+
#define MIN(a, b) ((a) > (b)) ? (b) : (a)
|
24
|
+
|
25
|
+
static inline void write32_be(uint32_t n, uint8_t out[4])
|
26
|
+
{
|
27
|
+
#if __GNUC__ >= 4 && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
28
|
+
*(uint32_t *)(out) = __builtin_bswap32(n);
|
29
|
+
#else
|
30
|
+
out[0] = (n >> 24) & 0xff;
|
31
|
+
out[1] = (n >> 16) & 0xff;
|
32
|
+
out[2] = (n >> 8) & 0xff;
|
33
|
+
out[3] = n & 0xff;
|
34
|
+
#endif
|
35
|
+
}
|
36
|
+
|
37
|
+
static inline void write64_be(uint64_t n, uint8_t out[8])
|
38
|
+
{
|
39
|
+
#if __GNUC__ >= 4 && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
40
|
+
*(uint64_t *)(out) = __builtin_bswap64(n);
|
41
|
+
#else
|
42
|
+
write32_be((n >> 32) & 0xffffffff, out);
|
43
|
+
write32_be(n & 0xffffffff, out + 4);
|
44
|
+
#endif
|
45
|
+
}
|
46
|
+
|
47
|
+
/* --- Optional OpenMP parallelisation of consecutive blocks --- */
|
48
|
+
#ifdef WITH_OPENMP
|
49
|
+
# define OPENMP_PARALLEL_FOR _Pragma("omp parallel for")
|
50
|
+
#else
|
51
|
+
# define OPENMP_PARALLEL_FOR
|
52
|
+
#endif
|
53
|
+
|
54
|
+
/* Prepare block (of blocksz bytes) to contain md padding denoting a msg-size
|
55
|
+
* message (in bytes). block has a prefix of used bytes.
|
56
|
+
*
|
57
|
+
* Message length is expressed in 32 bits (so suitable for sha1, sha256, sha512). */
|
58
|
+
static inline void md_pad(uint8_t *block, size_t blocksz, size_t used, size_t msg)
|
59
|
+
{
|
60
|
+
memset(block + used, 0, blocksz - used - 4);
|
61
|
+
block[used] = 0x80;
|
62
|
+
block += blocksz - 4;
|
63
|
+
write32_be(msg * 8, block);
|
64
|
+
}
|
65
|
+
|
66
|
+
/* Internal function/type names for hash-specific things. */
|
67
|
+
#define HMAC_CTX(_name) HMAC_ ## _name ## _ctx
|
68
|
+
#define HMAC_INIT(_name) HMAC_ ## _name ## _init
|
69
|
+
#define HMAC_UPDATE(_name) HMAC_ ## _name ## _update
|
70
|
+
#define HMAC_FINAL(_name) HMAC_ ## _name ## _final
|
71
|
+
|
72
|
+
#define PBKDF2_F(_name) pbkdf2_f_ ## _name
|
73
|
+
#define PBKDF2(_name) pbkdf2_ ## _name
|
74
|
+
|
75
|
+
/* This macro expands to decls for the whole implementation for a given
|
76
|
+
* hash function. Arguments are:
|
77
|
+
*
|
78
|
+
* _name like 'sha1', added to symbol names
|
79
|
+
* _blocksz block size, in bytes
|
80
|
+
* _hashsz digest output, in bytes
|
81
|
+
* _ctx hash context type
|
82
|
+
* _init hash context initialisation function
|
83
|
+
* args: (_ctx *c)
|
84
|
+
* _update hash context update function
|
85
|
+
* args: (_ctx *c, const void *data, size_t ndata)
|
86
|
+
* _final hash context finish function
|
87
|
+
* args: (void *out, _ctx *c)
|
88
|
+
* _xform hash context raw block update function
|
89
|
+
* args: (_ctx *c, const void *data)
|
90
|
+
* _xcpy hash context raw copy function (only need copy hash state)
|
91
|
+
* args: (_ctx * restrict out, const _ctx *restrict in)
|
92
|
+
* _xtract hash context state extraction
|
93
|
+
* args: args (_ctx *restrict c, uint8_t *restrict out)
|
94
|
+
* _xxor hash context xor function (only need xor hash state)
|
95
|
+
* args: (_ctx *restrict out, const _ctx *restrict in)
|
96
|
+
*
|
97
|
+
* The resulting function is named PBKDF2(_name).
|
98
|
+
*/
|
99
|
+
#define DECL_PBKDF2(_name, _blocksz, _hashsz, _ctx, \
|
100
|
+
_init, _update, _xform, _final, _xcpy, _xtract, _xxor) \
|
101
|
+
typedef struct { \
|
102
|
+
_ctx inner; \
|
103
|
+
_ctx outer; \
|
104
|
+
} HMAC_CTX(_name); \
|
105
|
+
\
|
106
|
+
static inline void HMAC_INIT(_name)(HMAC_CTX(_name) *ctx, \
|
107
|
+
const uint8_t *key, size_t nkey) \
|
108
|
+
{ \
|
109
|
+
/* Prepare key: */ \
|
110
|
+
uint8_t k[_blocksz]; \
|
111
|
+
\
|
112
|
+
/* Shorten long keys. */ \
|
113
|
+
if (nkey > _blocksz) \
|
114
|
+
{ \
|
115
|
+
_init(&ctx->inner); \
|
116
|
+
_update(&ctx->inner, key, nkey); \
|
117
|
+
_final(k, &ctx->inner); \
|
118
|
+
\
|
119
|
+
key = k; \
|
120
|
+
nkey = _hashsz; \
|
121
|
+
} \
|
122
|
+
\
|
123
|
+
/* Standard doesn't cover case where blocksz < hashsz. */ \
|
124
|
+
assert(nkey <= _blocksz); \
|
125
|
+
\
|
126
|
+
/* Right zero-pad short keys. */ \
|
127
|
+
if (k != key) \
|
128
|
+
memcpy(k, key, nkey); \
|
129
|
+
if (_blocksz > nkey) \
|
130
|
+
memset(k + nkey, 0, _blocksz - nkey); \
|
131
|
+
\
|
132
|
+
/* Start inner hash computation */ \
|
133
|
+
uint8_t blk_inner[_blocksz]; \
|
134
|
+
uint8_t blk_outer[_blocksz]; \
|
135
|
+
\
|
136
|
+
for (size_t i = 0; i < _blocksz; i++) \
|
137
|
+
{ \
|
138
|
+
blk_inner[i] = 0x36 ^ k[i]; \
|
139
|
+
blk_outer[i] = 0x5c ^ k[i]; \
|
140
|
+
} \
|
141
|
+
\
|
142
|
+
_init(&ctx->inner); \
|
143
|
+
_update(&ctx->inner, blk_inner, sizeof blk_inner); \
|
144
|
+
\
|
145
|
+
/* And outer. */ \
|
146
|
+
_init(&ctx->outer); \
|
147
|
+
_update(&ctx->outer, blk_outer, sizeof blk_outer); \
|
148
|
+
} \
|
149
|
+
\
|
150
|
+
static inline void HMAC_UPDATE(_name)(HMAC_CTX(_name) *ctx, \
|
151
|
+
const void *data, size_t ndata) \
|
152
|
+
{ \
|
153
|
+
_update(&ctx->inner, data, ndata); \
|
154
|
+
} \
|
155
|
+
\
|
156
|
+
static inline void HMAC_FINAL(_name)(HMAC_CTX(_name) *ctx, \
|
157
|
+
uint8_t out[_hashsz]) \
|
158
|
+
{ \
|
159
|
+
_final(out, &ctx->inner); \
|
160
|
+
_update(&ctx->outer, out, _hashsz); \
|
161
|
+
_final(out, &ctx->outer); \
|
162
|
+
} \
|
163
|
+
\
|
164
|
+
\
|
165
|
+
/* --- PBKDF2 --- */ \
|
166
|
+
static inline void PBKDF2_F(_name)(const HMAC_CTX(_name) *startctx, \
|
167
|
+
uint32_t counter, \
|
168
|
+
const uint8_t *salt, size_t nsalt, \
|
169
|
+
uint32_t iterations, \
|
170
|
+
uint8_t *out) \
|
171
|
+
{ \
|
172
|
+
uint8_t countbuf[4]; \
|
173
|
+
write32_be(counter, countbuf); \
|
174
|
+
\
|
175
|
+
/* Prepare loop-invariant padding block. */ \
|
176
|
+
uint8_t Ublock[_blocksz]; \
|
177
|
+
md_pad(Ublock, _blocksz, _hashsz, _blocksz + _hashsz); \
|
178
|
+
\
|
179
|
+
/* First iteration: \
|
180
|
+
* U_1 = PRF(P, S || INT_32_BE(i)) \
|
181
|
+
*/ \
|
182
|
+
HMAC_CTX(_name) ctx = *startctx; \
|
183
|
+
HMAC_UPDATE(_name)(&ctx, salt, nsalt); \
|
184
|
+
HMAC_UPDATE(_name)(&ctx, countbuf, sizeof countbuf); \
|
185
|
+
HMAC_FINAL(_name)(&ctx, Ublock); \
|
186
|
+
_ctx result = ctx.outer; \
|
187
|
+
\
|
188
|
+
/* Subsequent iterations: \
|
189
|
+
* U_c = PRF(P, U_{c-1}) \
|
190
|
+
*/ \
|
191
|
+
for (uint32_t i = 1; i < iterations; i++) \
|
192
|
+
{ \
|
193
|
+
/* Complete inner hash with previous U */ \
|
194
|
+
_xcpy(&ctx.inner, &startctx->inner); \
|
195
|
+
_xform(&ctx.inner, Ublock); \
|
196
|
+
_xtract(&ctx.inner, Ublock); \
|
197
|
+
/* Complete outer hash with inner output */ \
|
198
|
+
_xcpy(&ctx.outer, &startctx->outer); \
|
199
|
+
_xform(&ctx.outer, Ublock); \
|
200
|
+
_xtract(&ctx.outer, Ublock); \
|
201
|
+
_xxor(&result, &ctx.outer); \
|
202
|
+
} \
|
203
|
+
\
|
204
|
+
/* Reform result into output buffer. */ \
|
205
|
+
_xtract(&result, out); \
|
206
|
+
} \
|
207
|
+
\
|
208
|
+
static inline void PBKDF2(_name)(const uint8_t *pw, size_t npw, \
|
209
|
+
const uint8_t *salt, size_t nsalt, \
|
210
|
+
uint32_t iterations, \
|
211
|
+
uint8_t *out, size_t nout) \
|
212
|
+
{ \
|
213
|
+
assert(iterations); \
|
214
|
+
assert(out && nout); \
|
215
|
+
\
|
216
|
+
/* Starting point for inner loop. */ \
|
217
|
+
HMAC_CTX(_name) ctx; \
|
218
|
+
HMAC_INIT(_name)(&ctx, pw, npw); \
|
219
|
+
\
|
220
|
+
/* How many blocks do we need? */ \
|
221
|
+
uint32_t blocks_needed = (nout + _hashsz - 1) / _hashsz; \
|
222
|
+
\
|
223
|
+
OPENMP_PARALLEL_FOR \
|
224
|
+
for (uint32_t counter = 1; counter <= blocks_needed; counter++) \
|
225
|
+
{ \
|
226
|
+
uint8_t block[_hashsz]; \
|
227
|
+
PBKDF2_F(_name)(&ctx, counter, salt, nsalt, iterations, block); \
|
228
|
+
\
|
229
|
+
size_t offset = (counter - 1) * _hashsz; \
|
230
|
+
size_t taken = MIN(nout - offset, _hashsz); \
|
231
|
+
memcpy(out + offset, block, taken); \
|
232
|
+
} \
|
233
|
+
}
|
234
|
+
|
235
|
+
static inline void sha1_extract(SHA_CTX *restrict ctx, uint8_t *restrict out)
|
236
|
+
{
|
237
|
+
write32_be(ctx->h0, out);
|
238
|
+
write32_be(ctx->h1, out + 4);
|
239
|
+
write32_be(ctx->h2, out + 8);
|
240
|
+
write32_be(ctx->h3, out + 12);
|
241
|
+
write32_be(ctx->h4, out + 16);
|
242
|
+
}
|
243
|
+
|
244
|
+
static inline void sha1_cpy(SHA_CTX *restrict out, const SHA_CTX *restrict in)
|
245
|
+
{
|
246
|
+
out->h0 = in->h0;
|
247
|
+
out->h1 = in->h1;
|
248
|
+
out->h2 = in->h2;
|
249
|
+
out->h3 = in->h3;
|
250
|
+
out->h4 = in->h4;
|
251
|
+
}
|
252
|
+
|
253
|
+
static inline void sha1_xor(SHA_CTX *restrict out, const SHA_CTX *restrict in)
|
254
|
+
{
|
255
|
+
out->h0 ^= in->h0;
|
256
|
+
out->h1 ^= in->h1;
|
257
|
+
out->h2 ^= in->h2;
|
258
|
+
out->h3 ^= in->h3;
|
259
|
+
out->h4 ^= in->h4;
|
260
|
+
}
|
261
|
+
|
262
|
+
DECL_PBKDF2(sha1,
|
263
|
+
SHA_CBLOCK,
|
264
|
+
SHA_DIGEST_LENGTH,
|
265
|
+
SHA_CTX,
|
266
|
+
SHA1_Init,
|
267
|
+
SHA1_Update,
|
268
|
+
SHA1_Transform,
|
269
|
+
SHA1_Final,
|
270
|
+
sha1_cpy,
|
271
|
+
sha1_extract,
|
272
|
+
sha1_xor)
|
273
|
+
|
274
|
+
static inline void sha256_extract(SHA256_CTX *restrict ctx, uint8_t *restrict out)
|
275
|
+
{
|
276
|
+
write32_be(ctx->h[0], out);
|
277
|
+
write32_be(ctx->h[1], out + 4);
|
278
|
+
write32_be(ctx->h[2], out + 8);
|
279
|
+
write32_be(ctx->h[3], out + 12);
|
280
|
+
write32_be(ctx->h[4], out + 16);
|
281
|
+
write32_be(ctx->h[5], out + 20);
|
282
|
+
write32_be(ctx->h[6], out + 24);
|
283
|
+
write32_be(ctx->h[7], out + 28);
|
284
|
+
}
|
285
|
+
|
286
|
+
static inline void sha256_cpy(SHA256_CTX *restrict out, const SHA256_CTX *restrict in)
|
287
|
+
{
|
288
|
+
out->h[0] = in->h[0];
|
289
|
+
out->h[1] = in->h[1];
|
290
|
+
out->h[2] = in->h[2];
|
291
|
+
out->h[3] = in->h[3];
|
292
|
+
out->h[4] = in->h[4];
|
293
|
+
out->h[5] = in->h[5];
|
294
|
+
out->h[6] = in->h[6];
|
295
|
+
out->h[7] = in->h[7];
|
296
|
+
}
|
297
|
+
|
298
|
+
static inline void sha256_xor(SHA256_CTX *restrict out, const SHA256_CTX *restrict in)
|
299
|
+
{
|
300
|
+
out->h[0] ^= in->h[0];
|
301
|
+
out->h[1] ^= in->h[1];
|
302
|
+
out->h[2] ^= in->h[2];
|
303
|
+
out->h[3] ^= in->h[3];
|
304
|
+
out->h[4] ^= in->h[4];
|
305
|
+
out->h[5] ^= in->h[5];
|
306
|
+
out->h[6] ^= in->h[6];
|
307
|
+
out->h[7] ^= in->h[7];
|
308
|
+
}
|
309
|
+
|
310
|
+
DECL_PBKDF2(sha256,
|
311
|
+
SHA256_CBLOCK,
|
312
|
+
SHA256_DIGEST_LENGTH,
|
313
|
+
SHA256_CTX,
|
314
|
+
SHA256_Init,
|
315
|
+
SHA256_Update,
|
316
|
+
SHA256_Transform,
|
317
|
+
SHA256_Final,
|
318
|
+
sha256_cpy,
|
319
|
+
sha256_extract,
|
320
|
+
sha256_xor)
|
321
|
+
|
322
|
+
static inline void sha512_extract(SHA512_CTX *restrict ctx, uint8_t *restrict out)
|
323
|
+
{
|
324
|
+
write64_be(ctx->h[0], out);
|
325
|
+
write64_be(ctx->h[1], out + 8);
|
326
|
+
write64_be(ctx->h[2], out + 16);
|
327
|
+
write64_be(ctx->h[3], out + 24);
|
328
|
+
write64_be(ctx->h[4], out + 32);
|
329
|
+
write64_be(ctx->h[5], out + 40);
|
330
|
+
write64_be(ctx->h[6], out + 48);
|
331
|
+
write64_be(ctx->h[7], out + 56);
|
332
|
+
}
|
333
|
+
|
334
|
+
static inline void sha512_cpy(SHA512_CTX *restrict out, const SHA512_CTX *restrict in)
|
335
|
+
{
|
336
|
+
out->h[0] = in->h[0];
|
337
|
+
out->h[1] = in->h[1];
|
338
|
+
out->h[2] = in->h[2];
|
339
|
+
out->h[3] = in->h[3];
|
340
|
+
out->h[4] = in->h[4];
|
341
|
+
out->h[5] = in->h[5];
|
342
|
+
out->h[6] = in->h[6];
|
343
|
+
out->h[7] = in->h[7];
|
344
|
+
}
|
345
|
+
|
346
|
+
static inline void sha512_xor(SHA512_CTX *restrict out, const SHA512_CTX *restrict in)
|
347
|
+
{
|
348
|
+
out->h[0] ^= in->h[0];
|
349
|
+
out->h[1] ^= in->h[1];
|
350
|
+
out->h[2] ^= in->h[2];
|
351
|
+
out->h[3] ^= in->h[3];
|
352
|
+
out->h[4] ^= in->h[4];
|
353
|
+
out->h[5] ^= in->h[5];
|
354
|
+
out->h[6] ^= in->h[6];
|
355
|
+
out->h[7] ^= in->h[7];
|
356
|
+
}
|
357
|
+
|
358
|
+
DECL_PBKDF2(sha512,
|
359
|
+
SHA512_CBLOCK,
|
360
|
+
SHA512_DIGEST_LENGTH,
|
361
|
+
SHA512_CTX,
|
362
|
+
SHA512_Init,
|
363
|
+
SHA512_Update,
|
364
|
+
SHA512_Transform,
|
365
|
+
SHA512_Final,
|
366
|
+
sha512_cpy,
|
367
|
+
sha512_extract,
|
368
|
+
sha512_xor)
|
369
|
+
|
370
|
+
void fastpbkdf2_hmac_sha1(const uint8_t *pw, size_t npw,
|
371
|
+
const uint8_t *salt, size_t nsalt,
|
372
|
+
uint32_t iterations,
|
373
|
+
uint8_t *out, size_t nout)
|
374
|
+
{
|
375
|
+
PBKDF2(sha1)(pw, npw, salt, nsalt, iterations, out, nout);
|
376
|
+
}
|
377
|
+
|
378
|
+
void fastpbkdf2_hmac_sha256(const uint8_t *pw, size_t npw,
|
379
|
+
const uint8_t *salt, size_t nsalt,
|
380
|
+
uint32_t iterations,
|
381
|
+
uint8_t *out, size_t nout)
|
382
|
+
{
|
383
|
+
PBKDF2(sha256)(pw, npw, salt, nsalt, iterations, out, nout);
|
384
|
+
}
|
385
|
+
|
386
|
+
void fastpbkdf2_hmac_sha512(const uint8_t *pw, size_t npw,
|
387
|
+
const uint8_t *salt, size_t nsalt,
|
388
|
+
uint32_t iterations,
|
389
|
+
uint8_t *out, size_t nout)
|
390
|
+
{
|
391
|
+
PBKDF2(sha512)(pw, npw, salt, nsalt, iterations, out, nout);
|
392
|
+
}
|
393
|
+
|
@@ -0,0 +1,71 @@
|
|
1
|
+
/*
|
2
|
+
* fastpbkdf2 - Faster PBKDF2-HMAC calculation
|
3
|
+
* Written in 2015 by Joseph Birr-Pixton <jpixton@gmail.com>
|
4
|
+
*
|
5
|
+
* To the extent possible under law, the author(s) have dedicated all
|
6
|
+
* copyright and related and neighboring rights to this software to the
|
7
|
+
* public domain worldwide. This software is distributed without any
|
8
|
+
* warranty.
|
9
|
+
*
|
10
|
+
* You should have received a copy of the CC0 Public Domain Dedication
|
11
|
+
* along with this software. If not, see
|
12
|
+
* <http://creativecommons.org/publicdomain/zero/1.0/>.
|
13
|
+
*/
|
14
|
+
|
15
|
+
#ifndef FASTPBKDF2_H
|
16
|
+
#define FASTPBKDF2_H
|
17
|
+
|
18
|
+
#include <stdlib.h>
|
19
|
+
#include <stdint.h>
|
20
|
+
|
21
|
+
#ifdef __cplusplus
|
22
|
+
extern "C" {
|
23
|
+
#endif
|
24
|
+
|
25
|
+
/** Calculates PBKDF2-HMAC-SHA1.
|
26
|
+
*
|
27
|
+
* @p npw bytes at @p pw are the password input.
|
28
|
+
* @p nsalt bytes at @p salt are the salt input.
|
29
|
+
* @p iterations is the PBKDF2 iteration count and must be non-zero.
|
30
|
+
* @p nout bytes of output are written to @p out. @p nout must be non-zero.
|
31
|
+
*
|
32
|
+
* This function cannot fail; it does not report errors.
|
33
|
+
*/
|
34
|
+
void fastpbkdf2_hmac_sha1(const uint8_t *pw, size_t npw,
|
35
|
+
const uint8_t *salt, size_t nsalt,
|
36
|
+
uint32_t iterations,
|
37
|
+
uint8_t *out, size_t nout);
|
38
|
+
|
39
|
+
/** Calculates PBKDF2-HMAC-SHA256.
|
40
|
+
*
|
41
|
+
* @p npw bytes at @p pw are the password input.
|
42
|
+
* @p nsalt bytes at @p salt are the salt input.
|
43
|
+
* @p iterations is the PBKDF2 iteration count and must be non-zero.
|
44
|
+
* @p nout bytes of output are written to @p out. @p nout must be non-zero.
|
45
|
+
*
|
46
|
+
* This function cannot fail; it does not report errors.
|
47
|
+
*/
|
48
|
+
void fastpbkdf2_hmac_sha256(const uint8_t *pw, size_t npw,
|
49
|
+
const uint8_t *salt, size_t nsalt,
|
50
|
+
uint32_t iterations,
|
51
|
+
uint8_t *out, size_t nout);
|
52
|
+
|
53
|
+
/** Calculates PBKDF2-HMAC-SHA512.
|
54
|
+
*
|
55
|
+
* @p npw bytes at @p pw are the password input.
|
56
|
+
* @p nsalt bytes at @p salt are the salt input.
|
57
|
+
* @p iterations is the PBKDF2 iteration count and must be non-zero.
|
58
|
+
* @p nout bytes of output are written to @p out. @p nout must be non-zero.
|
59
|
+
*
|
60
|
+
* This function cannot fail; it does not report errors.
|
61
|
+
*/
|
62
|
+
void fastpbkdf2_hmac_sha512(const uint8_t *pw, size_t npw,
|
63
|
+
const uint8_t *salt, size_t nsalt,
|
64
|
+
uint32_t iterations,
|
65
|
+
uint8_t *out, size_t nout);
|
66
|
+
|
67
|
+
#ifdef __cplusplus
|
68
|
+
}
|
69
|
+
#endif
|
70
|
+
|
71
|
+
#endif
|
data/lib/fastpbkdf2.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'fastpbkdf2_native'
|
2
|
+
|
3
|
+
#"\x0c\x60\xc8\x0f\x96\x1f\x0e\x71\xf3\xa9\xb5\x24\xaf\x60\x12\x06\x2f\xe0\x37\xa6"
|
4
|
+
|
5
|
+
|
6
|
+
# class LZ4
|
7
|
+
# def self.compress(source)
|
8
|
+
# return LZ4Native::compress(source)
|
9
|
+
# end
|
10
|
+
|
11
|
+
# def self.uncompress(source)
|
12
|
+
# return LZ4Native::uncompress(source)
|
13
|
+
# end
|
14
|
+
# end
|
metadata
ADDED
@@ -0,0 +1,78 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: fastpbkdf2
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- S-YOU
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-10-26 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rake-compiler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10'
|
41
|
+
description: Ruby bindings for fastpbkdf2
|
42
|
+
email: S-YOU@users.noreply.github.com
|
43
|
+
executables: []
|
44
|
+
extensions:
|
45
|
+
- ext/fastpbkdf2_native/extconf.rb
|
46
|
+
extra_rdoc_files: []
|
47
|
+
files:
|
48
|
+
- Rakefile
|
49
|
+
- ext/fastpbkdf2_native/binding.c
|
50
|
+
- ext/fastpbkdf2_native/extconf.rb
|
51
|
+
- ext/fastpbkdf2_native/fastpbkdf2.c
|
52
|
+
- ext/fastpbkdf2_native/fastpbkdf2.h
|
53
|
+
- lib/fastpbkdf2.rb
|
54
|
+
homepage: https://github.com/S-YOU/ruby-fastpbkdf2
|
55
|
+
licenses:
|
56
|
+
- MIT
|
57
|
+
metadata: {}
|
58
|
+
post_install_message:
|
59
|
+
rdoc_options: []
|
60
|
+
require_paths:
|
61
|
+
- lib
|
62
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
63
|
+
requirements:
|
64
|
+
- - ">="
|
65
|
+
- !ruby/object:Gem::Version
|
66
|
+
version: '0'
|
67
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
68
|
+
requirements:
|
69
|
+
- - ">="
|
70
|
+
- !ruby/object:Gem::Version
|
71
|
+
version: '0'
|
72
|
+
requirements: []
|
73
|
+
rubyforge_project:
|
74
|
+
rubygems_version: 2.4.5
|
75
|
+
signing_key:
|
76
|
+
specification_version: 4
|
77
|
+
summary: Ruby bindings for fastpbkdf2
|
78
|
+
test_files: []
|