pbkdf256 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,3 @@
1
+ -
2
+ ChangeLog.rdoc
3
+ LICENSE.txt
@@ -0,0 +1,20 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ coverage
6
+ InstalledFiles
7
+ lib/bundler/man
8
+ pkg
9
+ rdoc
10
+ spec/reports
11
+ test/tmp
12
+ test/version_tmp
13
+ tmp
14
+
15
+ # YARD artifacts
16
+ .yardoc
17
+ _yardoc
18
+ doc/
19
+
20
+ install.sh
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --colour --format documentation
@@ -0,0 +1 @@
1
+ --markup rdoc --title "PBKDF256 Documentation" --protected
@@ -0,0 +1,8 @@
1
+ === 0.1.0 / 2012-09-25
2
+
3
+ * Initial release
4
+
5
+ === 0.1.2 / 2012-09-26
6
+
7
+ * ISO C90 compatibility
8
+
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2012 Johanns Gregorian
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,68 @@
1
+ = PBKDF256
2
+
3
+ * {Homepage}[https://github.com/johanns/PBKDF256#readme]
4
+ * {Issues}[https://github.com/johanns/PBKDF256/issues]
5
+ * {Documentation}[http://rubydoc.info/gems/PBKDF256/frames]
6
+
7
+ == Description
8
+
9
+ A very simple, but fast (native) PBKDF2-HMAC-SHA256 ruby gem based on Colin Percival's C implementation.
10
+
11
+ This gem is mostly useful for Ruby installations that have been compiled against an OpenSSL version earlier than 0.9.9, which will be lacking PBKDF2 compliant function (i.e., OpenSSL::PKCS5.pbkdf2_hmac).
12
+
13
+ == Limitation
14
+
15
+ SHA256 is the only available Hash function.
16
+
17
+ == Benchmark
18
+
19
+ Performance comparison of {OpenSSL}[http://rubydoc.info/stdlib/openssl/], PBKDF256, and {PBKDF2-ruby}[http://rubydoc.info/gems/pbkdf2/] (Ruby) implementations.
20
+
21
+ PBKDF2("pleaseletmein", "SodiumChloride", 2000, 64):
22
+
23
+ user system total real
24
+ OpenSSL: 0.010000 0.000000 0.010000 ( 0.015129)
25
+ PBKDF256: 0.020000 0.000000 0.020000 ( 0.046734)
26
+ PBKDF2-ruby: 0.140000 0.000000 0.140000 ( 0.153980)
27
+
28
+ PBKDF2("pleaseletmein", "SodiumChloride", 100000, 64):
29
+
30
+ user system total real
31
+ OpenSSL: 0.760000 0.020000 0.780000 ( 1.452442)
32
+ PBKDF256: 0.920000 0.020000 0.940000 ( 1.537676)
33
+ PBKDF2-ruby: 7.030000 0.150000 7.180000 ( 11.195839)
34
+
35
+ * Smaller is better
36
+
37
+ == Install
38
+
39
+ $ gem install pbkdf256
40
+
41
+ == Examples
42
+
43
+ require 'pbkdf256'
44
+ require 'openssl'
45
+
46
+ salt = OpenSSL::Random.random_bytes(16)
47
+ # => "\x14~\xFC\xF7\xF4\xA2\xF7\xF7\x93H5\xF9nX\xB6\xA5"
48
+
49
+ PBKDF256.dk("p@ssw0rd", salt, 2000, 32)
50
+ # => "\xA4\xFF\x83*k\x820#=\x02\x0F\xD1\xE8,\x85K\xAA\x0F\x16{\xE0\xDD\x14\xA2i\x86`\xD3{\xF5^/"
51
+
52
+ PBKDF256.pbkdf2_sha256("M0$terM@gnet", salt, 1353, 16)
53
+ # => "\x80\x80.\x87SC\x96\b\x8F\x9F\xB4\xBD\xAF\x1E\x932"
54
+
55
+ PBKDF256.hmac_sha256 "The Last Samurai", salt, 1, 16
56
+ # => "C<&\x8F\xB2(\x8D\xD8\x82\xEA\xB6l\xE5]O\b"
57
+
58
+ == Requirements
59
+
60
+ Ruby, and native build environment (GCC 4.x).
61
+
62
+ Tested with Ruby 1.9.x on Mac OS X (10.8.2), and Ubuntu 12.04.
63
+
64
+ == Copyright
65
+
66
+ Copyright (c) 2012 Johanns Gregorian
67
+
68
+ See LICENSE.txt for details.
@@ -0,0 +1,40 @@
1
+ # encoding: utf-8
2
+
3
+ require 'rubygems'
4
+ require 'rake'
5
+
6
+ begin
7
+ gem 'rubygems-tasks', '~> 0.2'
8
+ require 'rubygems/tasks'
9
+
10
+ Gem::Tasks.new
11
+ rescue LoadError => e
12
+ warn e.message
13
+ warn "Run `gem install rubygems-tasks` to install Gem::Tasks."
14
+ end
15
+
16
+ begin
17
+ gem 'rspec', '~> 2.4'
18
+ require 'rspec/core/rake_task'
19
+
20
+ RSpec::Core::RakeTask.new
21
+ rescue LoadError => e
22
+ task :spec do
23
+ abort "Please run `gem install rspec` to install RSpec."
24
+ end
25
+ end
26
+
27
+ task :test => :spec
28
+ task :default => :spec
29
+
30
+ begin
31
+ gem 'yard', '~> 0.8'
32
+ require 'yard'
33
+
34
+ YARD::Rake::YardocTask.new
35
+ rescue LoadError => e
36
+ task :yard do
37
+ abort "Please run `gem install yard` to install YARD."
38
+ end
39
+ end
40
+ task :doc => :yard
@@ -0,0 +1,39 @@
1
+ #include <ruby.h>
2
+
3
+ #include "sha256.h"
4
+
5
+ static VALUE mPBKDF256;
6
+
7
+ /* @overload pbkdf2_sha256(passwd, salt, iter, key_len)
8
+ *
9
+ * @param passwd [String] Passphrase used to compute the derived key.
10
+ * @param salt [String] A series of random bits to help prevent 'rainbow table'/pre-computed attacks.
11
+ * @param iter [Fixnum] Number of computing iterations. A value of at least 2000 is recommended.
12
+ * @param key_len [Fixnum] Length of desired derived key.
13
+ *
14
+ * @return [String] Computed derived key
15
+ */
16
+ static VALUE
17
+ m_pbkdf2_hmac_sha256(VALUE self, VALUE passwd, VALUE salt, VALUE iter, VALUE key_len)
18
+ {
19
+ StringValue(passwd);
20
+ StringValue(salt);
21
+
22
+ size_t dk_buff_len = NUM2UINT(key_len);
23
+
24
+ VALUE s;
25
+ s = rb_str_new(0, dk_buff_len);
26
+
27
+ s_PBKDF2_SHA256((const uint8_t *) RSTRING_PTR(passwd), RSTRING_LEN(passwd),
28
+ (const uint8_t *) RSTRING_PTR(salt), RSTRING_LEN(salt), NUM2ULL(iter),
29
+ RSTRING_PTR(s), dk_buff_len);
30
+
31
+ return s;
32
+ }
33
+
34
+ void Init_pbkdf256_n()
35
+ {
36
+ mPBKDF256 = rb_define_module("PBKDF256");
37
+
38
+ rb_define_module_function(mPBKDF256, "hmac_sha256", m_pbkdf2_hmac_sha256, 4);
39
+ }
@@ -0,0 +1,5 @@
1
+ require 'mkmf'
2
+
3
+ $CFLAGS =' -std=gnu89 '
4
+ create_makefile 'pbkdf256_n'
5
+
@@ -0,0 +1,4 @@
1
+ #ifndef _SCRYPT_PLATFORM_H_
2
+ #define _SCRYPT_PLATFORM_H_
3
+
4
+ #endif /* !_SCRYPT_PLATFORM_H_ */
@@ -0,0 +1,421 @@
1
+ /*-
2
+ *
3
+ * WOOOHOOO!!!
4
+ *
5
+ * Sept. 25th 2012: Appending prefix to function prototypes to avoid collision with
6
+ * OpenSSL methods when requiring openssl module in Ruby which causes the VM to crash!
7
+ *
8
+ -*/
9
+
10
+ /*-
11
+ * Copyright 2005,2007,2009 Colin Percival
12
+ * All rights reserved.
13
+ *
14
+ * Redistribution and use in source and binary forms, with or without
15
+ * modification, are permitted provided that the following conditions
16
+ * are met:
17
+ * 1. Redistributions of source code must retain the above copyright
18
+ * notice, this list of conditions and the following disclaimer.
19
+ * 2. Redistributions in binary form must reproduce the above copyright
20
+ * notice, this list of conditions and the following disclaimer in the
21
+ * documentation and/or other materials provided with the distribution.
22
+ *
23
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
24
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
27
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33
+ * SUCH DAMAGE.
34
+ */
35
+ #include "scrypt_platform.h"
36
+
37
+ #include <sys/types.h>
38
+
39
+ #include <stdint.h>
40
+ #include <string.h>
41
+
42
+ #include "sysendian.h"
43
+
44
+ #include "sha256.h"
45
+
46
+ /*
47
+ * Encode a length len/4 vector of (uint32_t) into a length len vector of
48
+ * (unsigned char) in big-endian form. Assumes len is a multiple of 4.
49
+ */
50
+ static void
51
+ be32enc_vect(unsigned char *dst, const uint32_t *src, size_t len)
52
+ {
53
+ size_t i;
54
+
55
+ for (i = 0; i < len / 4; i++)
56
+ be32enc(dst + i * 4, src[i]);
57
+ }
58
+
59
+ /*
60
+ * Decode a big-endian length len vector of (unsigned char) into a length
61
+ * len/4 vector of (uint32_t). Assumes len is a multiple of 4.
62
+ */
63
+ static void
64
+ be32dec_vect(uint32_t *dst, const unsigned char *src, size_t len)
65
+ {
66
+ size_t i;
67
+
68
+ for (i = 0; i < len / 4; i++)
69
+ dst[i] = be32dec(src + i * 4);
70
+ }
71
+
72
+ /* Elementary functions used by SHA256 */
73
+ #define Ch(x, y, z) ((x & (y ^ z)) ^ z)
74
+ #define Maj(x, y, z) ((x & (y | z)) | (y & z))
75
+ #define SHR(x, n) (x >> n)
76
+ #define ROTR(x, n) ((x >> n) | (x << (32 - n)))
77
+ #define S0(x) (ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22))
78
+ #define S1(x) (ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25))
79
+ #define s0(x) (ROTR(x, 7) ^ ROTR(x, 18) ^ SHR(x, 3))
80
+ #define s1(x) (ROTR(x, 17) ^ ROTR(x, 19) ^ SHR(x, 10))
81
+
82
+ /* SHA256 round function */
83
+ #define RND(a, b, c, d, e, f, g, h, k) \
84
+ t0 = h + S1(e) + Ch(e, f, g) + k; \
85
+ t1 = S0(a) + Maj(a, b, c); \
86
+ d += t0; \
87
+ h = t0 + t1;
88
+
89
+ /* Adjusted round function for rotating state */
90
+ #define RNDr(S, W, i, k) \
91
+ RND(S[(64 - i) % 8], S[(65 - i) % 8], \
92
+ S[(66 - i) % 8], S[(67 - i) % 8], \
93
+ S[(68 - i) % 8], S[(69 - i) % 8], \
94
+ S[(70 - i) % 8], S[(71 - i) % 8], \
95
+ W[i] + k)
96
+
97
+ /*
98
+ * SHA256 block compression function. The 256-bit state is transformed via
99
+ * the 512-bit input block to produce a new state.
100
+ */
101
+ static void
102
+ SHA256_Transform(uint32_t * state, const unsigned char block[64])
103
+ {
104
+ uint32_t W[64];
105
+ uint32_t S[8];
106
+ uint32_t t0, t1;
107
+ int i;
108
+
109
+ /* 1. Prepare message schedule W. */
110
+ be32dec_vect(W, block, 64);
111
+ for (i = 16; i < 64; i++)
112
+ W[i] = s1(W[i - 2]) + W[i - 7] + s0(W[i - 15]) + W[i - 16];
113
+
114
+ /* 2. Initialize working variables. */
115
+ memcpy(S, state, 32);
116
+
117
+ /* 3. Mix. */
118
+ RNDr(S, W, 0, 0x428a2f98);
119
+ RNDr(S, W, 1, 0x71374491);
120
+ RNDr(S, W, 2, 0xb5c0fbcf);
121
+ RNDr(S, W, 3, 0xe9b5dba5);
122
+ RNDr(S, W, 4, 0x3956c25b);
123
+ RNDr(S, W, 5, 0x59f111f1);
124
+ RNDr(S, W, 6, 0x923f82a4);
125
+ RNDr(S, W, 7, 0xab1c5ed5);
126
+ RNDr(S, W, 8, 0xd807aa98);
127
+ RNDr(S, W, 9, 0x12835b01);
128
+ RNDr(S, W, 10, 0x243185be);
129
+ RNDr(S, W, 11, 0x550c7dc3);
130
+ RNDr(S, W, 12, 0x72be5d74);
131
+ RNDr(S, W, 13, 0x80deb1fe);
132
+ RNDr(S, W, 14, 0x9bdc06a7);
133
+ RNDr(S, W, 15, 0xc19bf174);
134
+ RNDr(S, W, 16, 0xe49b69c1);
135
+ RNDr(S, W, 17, 0xefbe4786);
136
+ RNDr(S, W, 18, 0x0fc19dc6);
137
+ RNDr(S, W, 19, 0x240ca1cc);
138
+ RNDr(S, W, 20, 0x2de92c6f);
139
+ RNDr(S, W, 21, 0x4a7484aa);
140
+ RNDr(S, W, 22, 0x5cb0a9dc);
141
+ RNDr(S, W, 23, 0x76f988da);
142
+ RNDr(S, W, 24, 0x983e5152);
143
+ RNDr(S, W, 25, 0xa831c66d);
144
+ RNDr(S, W, 26, 0xb00327c8);
145
+ RNDr(S, W, 27, 0xbf597fc7);
146
+ RNDr(S, W, 28, 0xc6e00bf3);
147
+ RNDr(S, W, 29, 0xd5a79147);
148
+ RNDr(S, W, 30, 0x06ca6351);
149
+ RNDr(S, W, 31, 0x14292967);
150
+ RNDr(S, W, 32, 0x27b70a85);
151
+ RNDr(S, W, 33, 0x2e1b2138);
152
+ RNDr(S, W, 34, 0x4d2c6dfc);
153
+ RNDr(S, W, 35, 0x53380d13);
154
+ RNDr(S, W, 36, 0x650a7354);
155
+ RNDr(S, W, 37, 0x766a0abb);
156
+ RNDr(S, W, 38, 0x81c2c92e);
157
+ RNDr(S, W, 39, 0x92722c85);
158
+ RNDr(S, W, 40, 0xa2bfe8a1);
159
+ RNDr(S, W, 41, 0xa81a664b);
160
+ RNDr(S, W, 42, 0xc24b8b70);
161
+ RNDr(S, W, 43, 0xc76c51a3);
162
+ RNDr(S, W, 44, 0xd192e819);
163
+ RNDr(S, W, 45, 0xd6990624);
164
+ RNDr(S, W, 46, 0xf40e3585);
165
+ RNDr(S, W, 47, 0x106aa070);
166
+ RNDr(S, W, 48, 0x19a4c116);
167
+ RNDr(S, W, 49, 0x1e376c08);
168
+ RNDr(S, W, 50, 0x2748774c);
169
+ RNDr(S, W, 51, 0x34b0bcb5);
170
+ RNDr(S, W, 52, 0x391c0cb3);
171
+ RNDr(S, W, 53, 0x4ed8aa4a);
172
+ RNDr(S, W, 54, 0x5b9cca4f);
173
+ RNDr(S, W, 55, 0x682e6ff3);
174
+ RNDr(S, W, 56, 0x748f82ee);
175
+ RNDr(S, W, 57, 0x78a5636f);
176
+ RNDr(S, W, 58, 0x84c87814);
177
+ RNDr(S, W, 59, 0x8cc70208);
178
+ RNDr(S, W, 60, 0x90befffa);
179
+ RNDr(S, W, 61, 0xa4506ceb);
180
+ RNDr(S, W, 62, 0xbef9a3f7);
181
+ RNDr(S, W, 63, 0xc67178f2);
182
+
183
+ /* 4. Mix local working variables into global state */
184
+ for (i = 0; i < 8; i++)
185
+ state[i] += S[i];
186
+
187
+ /* Clean the stack. */
188
+ memset(W, 0, 256);
189
+ memset(S, 0, 32);
190
+ t0 = t1 = 0;
191
+ }
192
+
193
+ static unsigned char PAD[64] = {
194
+ 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
195
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
196
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
197
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
198
+ };
199
+
200
+ /* Add padding and terminating bit-count. */
201
+ static void
202
+ SHA256_Pad(SHA256_CTX * ctx)
203
+ {
204
+ unsigned char len[8];
205
+ uint32_t r, plen;
206
+
207
+ /*
208
+ * Convert length to a vector of bytes -- we do this now rather
209
+ * than later because the length will change after we pad.
210
+ */
211
+ be32enc_vect(len, ctx->count, 8);
212
+
213
+ /* Add 1--64 bytes so that the resulting length is 56 mod 64 */
214
+ r = (ctx->count[1] >> 3) & 0x3f;
215
+ plen = (r < 56) ? (56 - r) : (120 - r);
216
+ s_SHA256_Update(ctx, PAD, (size_t)plen);
217
+
218
+ /* Add the terminating bit-count */
219
+ s_SHA256_Update(ctx, len, 8);
220
+ }
221
+
222
+ /* SHA-256 initialization. Begins a SHA-256 operation. */
223
+ void
224
+ s_SHA256_Init(SHA256_CTX * ctx)
225
+ {
226
+
227
+ /* Zero bits processed so far */
228
+ ctx->count[0] = ctx->count[1] = 0;
229
+
230
+ /* Magic initialization constants */
231
+ ctx->state[0] = 0x6A09E667;
232
+ ctx->state[1] = 0xBB67AE85;
233
+ ctx->state[2] = 0x3C6EF372;
234
+ ctx->state[3] = 0xA54FF53A;
235
+ ctx->state[4] = 0x510E527F;
236
+ ctx->state[5] = 0x9B05688C;
237
+ ctx->state[6] = 0x1F83D9AB;
238
+ ctx->state[7] = 0x5BE0CD19;
239
+ }
240
+
241
+ /* Add bytes into the hash */
242
+ void
243
+ s_SHA256_Update(SHA256_CTX * ctx, const void *in, size_t len)
244
+ {
245
+ uint32_t bitlen[2];
246
+ uint32_t r;
247
+ const unsigned char *src = in;
248
+
249
+ /* Number of bytes left in the buffer from previous updates */
250
+ r = (ctx->count[1] >> 3) & 0x3f;
251
+
252
+ /* Convert the length into a number of bits */
253
+ bitlen[1] = ((uint32_t)len) << 3;
254
+ bitlen[0] = (uint32_t)(len >> 29);
255
+
256
+ /* Update number of bits */
257
+ if ((ctx->count[1] += bitlen[1]) < bitlen[1])
258
+ ctx->count[0]++;
259
+ ctx->count[0] += bitlen[0];
260
+
261
+ /* Handle the case where we don't need to perform any transforms */
262
+ if (len < 64 - r) {
263
+ memcpy(&ctx->buf[r], src, len);
264
+ return;
265
+ }
266
+
267
+ /* Finish the current block */
268
+ memcpy(&ctx->buf[r], src, 64 - r);
269
+ SHA256_Transform(ctx->state, ctx->buf);
270
+ src += 64 - r;
271
+ len -= 64 - r;
272
+
273
+ /* Perform complete blocks */
274
+ while (len >= 64) {
275
+ SHA256_Transform(ctx->state, src);
276
+ src += 64;
277
+ len -= 64;
278
+ }
279
+
280
+ /* Copy left over data into buffer */
281
+ memcpy(ctx->buf, src, len);
282
+ }
283
+
284
+ /*
285
+ * SHA-256 finalization. Pads the input data, exports the hash value,
286
+ * and clears the context state.
287
+ */
288
+ void
289
+ s_SHA256_Final(unsigned char digest[32], SHA256_CTX * ctx)
290
+ {
291
+
292
+ /* Add padding */
293
+ SHA256_Pad(ctx);
294
+
295
+ /* Write the hash */
296
+ be32enc_vect(digest, ctx->state, 32);
297
+
298
+ /* Clear the context state */
299
+ memset((void *)ctx, 0, sizeof(*ctx));
300
+ }
301
+
302
+ /* Initialize an HMAC-SHA256 operation with the given key. */
303
+ void
304
+ s_HMAC_SHA256_Init(HMAC_SHA256_CTX * ctx, const void * _K, size_t Klen)
305
+ {
306
+ unsigned char pad[64];
307
+ unsigned char khash[32];
308
+ const unsigned char * K = _K;
309
+ size_t i;
310
+
311
+ /* If Klen > 64, the key is really SHA256(K). */
312
+ if (Klen > 64) {
313
+ s_SHA256_Init(&ctx->ictx);
314
+ s_SHA256_Update(&ctx->ictx, K, Klen);
315
+ s_SHA256_Final(khash, &ctx->ictx);
316
+ K = khash;
317
+ Klen = 32;
318
+ }
319
+
320
+ /* Inner SHA256 operation is SHA256(K xor [block of 0x36] || data). */
321
+ s_SHA256_Init(&ctx->ictx);
322
+ memset(pad, 0x36, 64);
323
+ for (i = 0; i < Klen; i++)
324
+ pad[i] ^= K[i];
325
+ s_SHA256_Update(&ctx->ictx, pad, 64);
326
+
327
+ /* Outer SHA256 operation is SHA256(K xor [block of 0x5c] || hash). */
328
+ s_SHA256_Init(&ctx->octx);
329
+ memset(pad, 0x5c, 64);
330
+ for (i = 0; i < Klen; i++)
331
+ pad[i] ^= K[i];
332
+ s_SHA256_Update(&ctx->octx, pad, 64);
333
+
334
+ /* Clean the stack. */
335
+ memset(khash, 0, 32);
336
+ }
337
+
338
+ /* Add bytes to the HMAC-SHA256 operation. */
339
+ void
340
+ s_HMAC_SHA256_Update(HMAC_SHA256_CTX * ctx, const void *in, size_t len)
341
+ {
342
+
343
+ /* Feed data to the inner SHA256 operation. */
344
+ s_SHA256_Update(&ctx->ictx, in, len);
345
+ }
346
+
347
+ /* Finish an HMAC-SHA256 operation. */
348
+ void
349
+ s_HMAC_SHA256_Final(unsigned char digest[32], HMAC_SHA256_CTX * ctx)
350
+ {
351
+ unsigned char ihash[32];
352
+
353
+ /* Finish the inner SHA256 operation. */
354
+ s_SHA256_Final(ihash, &ctx->ictx);
355
+
356
+ /* Feed the inner hash to the outer SHA256 operation. */
357
+ s_SHA256_Update(&ctx->octx, ihash, 32);
358
+
359
+ /* Finish the outer SHA256 operation. */
360
+ s_SHA256_Final(digest, &ctx->octx);
361
+
362
+ /* Clean the stack. */
363
+ memset(ihash, 0, 32);
364
+ }
365
+
366
+ /**
367
+ * s_PBKDF2_SHA256(passwd, passwdlen, salt, saltlen, c, buf, dkLen):
368
+ * Compute PBKDF2(passwd, salt, c, dkLen) using HMAC-SHA256 as the PRF, and
369
+ * write the output to buf. The value dkLen must be at most 32 * (2^32 - 1).
370
+ */
371
+ void
372
+ s_PBKDF2_SHA256(const uint8_t * passwd, size_t passwdlen, const uint8_t * salt,
373
+ size_t saltlen, uint64_t c, uint8_t * buf, size_t dkLen)
374
+ {
375
+ HMAC_SHA256_CTX PShctx, hctx;
376
+ size_t i;
377
+ uint8_t ivec[4];
378
+ uint8_t U[32];
379
+ uint8_t T[32];
380
+ uint64_t j;
381
+ int k;
382
+ size_t clen;
383
+
384
+ /* Compute HMAC state after processing P and S. */
385
+ s_HMAC_SHA256_Init(&PShctx, passwd, passwdlen);
386
+ s_HMAC_SHA256_Update(&PShctx, salt, saltlen);
387
+
388
+ /* Iterate through the blocks. */
389
+ for (i = 0; i * 32 < dkLen; i++) {
390
+ /* Generate INT(i + 1). */
391
+ be32enc(ivec, (uint32_t)(i + 1));
392
+
393
+ /* Compute U_1 = PRF(P, S || INT(i)). */
394
+ memcpy(&hctx, &PShctx, sizeof(HMAC_SHA256_CTX));
395
+ s_HMAC_SHA256_Update(&hctx, ivec, 4);
396
+ s_HMAC_SHA256_Final(U, &hctx);
397
+
398
+ /* T_i = U_1 ... */
399
+ memcpy(T, U, 32);
400
+
401
+ for (j = 2; j <= c; j++) {
402
+ /* Compute U_j. */
403
+ s_HMAC_SHA256_Init(&hctx, passwd, passwdlen);
404
+ s_HMAC_SHA256_Update(&hctx, U, 32);
405
+ s_HMAC_SHA256_Final(U, &hctx);
406
+
407
+ /* ... xor U_j ... */
408
+ for (k = 0; k < 32; k++)
409
+ T[k] ^= U[k];
410
+ }
411
+
412
+ /* Copy as many bytes as necessary into buf. */
413
+ clen = dkLen - i * 32;
414
+ if (clen > 32)
415
+ clen = 32;
416
+ memcpy(&buf[i * 32], T, clen);
417
+ }
418
+
419
+ /* Clean PShctx, since we never called _Final on it. */
420
+ memset(&PShctx, 0, sizeof(HMAC_SHA256_CTX));
421
+ }
@@ -0,0 +1,71 @@
1
+ /*-
2
+ *
3
+ * WOOOHOOO!!!
4
+ *
5
+ * Sept. 25th 2012: Appending prefix to function prototypes to avoid collision with
6
+ * OpenSSL methods when requiring openssl module in Ruby which causes the VM to crash!
7
+ *
8
+ -*/
9
+
10
+ /*-
11
+ * Copyright 2005,2007,2009 Colin Percival
12
+ * All rights reserved.
13
+ *
14
+ * Redistribution and use in source and binary forms, with or without
15
+ * modification, are permitted provided that the following conditions
16
+ * are met:
17
+ * 1. Redistributions of source code must retain the above copyright
18
+ * notice, this list of conditions and the following disclaimer.
19
+ * 2. Redistributions in binary form must reproduce the above copyright
20
+ * notice, this list of conditions and the following disclaimer in the
21
+ * documentation and/or other materials provided with the distribution.
22
+ *
23
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
24
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
27
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33
+ * SUCH DAMAGE.
34
+ *
35
+ * $FreeBSD: src/lib/libmd/sha256.h,v 1.2 2006/01/17 15:35:56 phk Exp $
36
+ */
37
+
38
+ #ifndef _SHA256_H_
39
+ #define _SHA256_H_
40
+
41
+ #include <sys/types.h>
42
+
43
+ #include <stdint.h>
44
+
45
+ typedef struct SHA256Context {
46
+ uint32_t state[8];
47
+ uint32_t count[2];
48
+ unsigned char buf[64];
49
+ } SHA256_CTX;
50
+
51
+ typedef struct HMAC_SHA256Context {
52
+ SHA256_CTX ictx;
53
+ SHA256_CTX octx;
54
+ } HMAC_SHA256_CTX;
55
+
56
+ void s_SHA256_Init(SHA256_CTX *);
57
+ void s_SHA256_Update(SHA256_CTX *, const void *, size_t);
58
+ void s_SHA256_Final(unsigned char [32], SHA256_CTX *);
59
+ void s_HMAC_SHA256_Init(HMAC_SHA256_CTX *, const void *, size_t);
60
+ void s_HMAC_SHA256_Update(HMAC_SHA256_CTX *, const void *, size_t);
61
+ void s_HMAC_SHA256_Final(unsigned char [32], HMAC_SHA256_CTX *);
62
+
63
+ /**
64
+ * s_PBKDF2_SHA256(passwd, passwdlen, salt, saltlen, c, buf, dkLen):
65
+ * Compute PBKDF2(passwd, salt, c, dkLen) using HMAC-SHA256 as the PRF, and
66
+ * write the output to buf. The value dkLen must be at most 32 * (2^32 - 1).
67
+ */
68
+ void s_PBKDF2_SHA256(const uint8_t *, size_t, const uint8_t *, size_t,
69
+ uint64_t, uint8_t *, size_t);
70
+
71
+ #endif /* !_SHA256_H_ */
@@ -0,0 +1,140 @@
1
+ /*-
2
+ * Copyright 2007-2009 Colin Percival
3
+ * All rights reserved.
4
+ *
5
+ * Redistribution and use in source and binary forms, with or without
6
+ * modification, are permitted provided that the following conditions
7
+ * are met:
8
+ * 1. Redistributions of source code must retain the above copyright
9
+ * notice, this list of conditions and the following disclaimer.
10
+ * 2. Redistributions in binary form must reproduce the above copyright
11
+ * notice, this list of conditions and the following disclaimer in the
12
+ * documentation and/or other materials provided with the distribution.
13
+ *
14
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24
+ * SUCH DAMAGE.
25
+ *
26
+ * This file was originally written by Colin Percival as part of the Tarsnap
27
+ * online backup system.
28
+ */
29
+ #ifndef _SYSENDIAN_H_
30
+ #define _SYSENDIAN_H_
31
+
32
+ #include "scrypt_platform.h"
33
+
34
+ /* If we don't have be64enc, the <sys/endian.h> we have isn't usable. */
35
+ #if !HAVE_DECL_BE64ENC
36
+ #undef HAVE_SYS_ENDIAN_H
37
+ #endif
38
+
39
+ #ifdef HAVE_SYS_ENDIAN_H
40
+
41
+ #include <sys/endian.h>
42
+
43
+ #else
44
+
45
+ #include <stdint.h>
46
+
47
+ static inline uint32_t
48
+ be32dec(const void *pp)
49
+ {
50
+ const uint8_t *p = (uint8_t const *)pp;
51
+
52
+ return ((uint32_t)(p[3]) + ((uint32_t)(p[2]) << 8) +
53
+ ((uint32_t)(p[1]) << 16) + ((uint32_t)(p[0]) << 24));
54
+ }
55
+
56
+ static inline void
57
+ be32enc(void *pp, uint32_t x)
58
+ {
59
+ uint8_t * p = (uint8_t *)pp;
60
+
61
+ p[3] = x & 0xff;
62
+ p[2] = (x >> 8) & 0xff;
63
+ p[1] = (x >> 16) & 0xff;
64
+ p[0] = (x >> 24) & 0xff;
65
+ }
66
+
67
+ static inline uint64_t
68
+ be64dec(const void *pp)
69
+ {
70
+ const uint8_t *p = (uint8_t const *)pp;
71
+
72
+ return ((uint64_t)(p[7]) + ((uint64_t)(p[6]) << 8) +
73
+ ((uint64_t)(p[5]) << 16) + ((uint64_t)(p[4]) << 24) +
74
+ ((uint64_t)(p[3]) << 32) + ((uint64_t)(p[2]) << 40) +
75
+ ((uint64_t)(p[1]) << 48) + ((uint64_t)(p[0]) << 56));
76
+ }
77
+
78
+ static inline void
79
+ be64enc(void *pp, uint64_t x)
80
+ {
81
+ uint8_t * p = (uint8_t *)pp;
82
+
83
+ p[7] = x & 0xff;
84
+ p[6] = (x >> 8) & 0xff;
85
+ p[5] = (x >> 16) & 0xff;
86
+ p[4] = (x >> 24) & 0xff;
87
+ p[3] = (x >> 32) & 0xff;
88
+ p[2] = (x >> 40) & 0xff;
89
+ p[1] = (x >> 48) & 0xff;
90
+ p[0] = (x >> 56) & 0xff;
91
+ }
92
+
93
+ static inline uint32_t
94
+ le32dec(const void *pp)
95
+ {
96
+ const uint8_t *p = (uint8_t const *)pp;
97
+
98
+ return ((uint32_t)(p[0]) + ((uint32_t)(p[1]) << 8) +
99
+ ((uint32_t)(p[2]) << 16) + ((uint32_t)(p[3]) << 24));
100
+ }
101
+
102
+ static inline void
103
+ le32enc(void *pp, uint32_t x)
104
+ {
105
+ uint8_t * p = (uint8_t *)pp;
106
+
107
+ p[0] = x & 0xff;
108
+ p[1] = (x >> 8) & 0xff;
109
+ p[2] = (x >> 16) & 0xff;
110
+ p[3] = (x >> 24) & 0xff;
111
+ }
112
+
113
+ static inline uint64_t
114
+ le64dec(const void *pp)
115
+ {
116
+ const uint8_t *p = (uint8_t const *)pp;
117
+
118
+ return ((uint64_t)(p[0]) + ((uint64_t)(p[1]) << 8) +
119
+ ((uint64_t)(p[2]) << 16) + ((uint64_t)(p[3]) << 24) +
120
+ ((uint64_t)(p[4]) << 32) + ((uint64_t)(p[5]) << 40) +
121
+ ((uint64_t)(p[6]) << 48) + ((uint64_t)(p[7]) << 56));
122
+ }
123
+
124
+ static inline void
125
+ le64enc(void *pp, uint64_t x)
126
+ {
127
+ uint8_t * p = (uint8_t *)pp;
128
+
129
+ p[0] = x & 0xff;
130
+ p[1] = (x >> 8) & 0xff;
131
+ p[2] = (x >> 16) & 0xff;
132
+ p[3] = (x >> 24) & 0xff;
133
+ p[4] = (x >> 32) & 0xff;
134
+ p[5] = (x >> 40) & 0xff;
135
+ p[6] = (x >> 48) & 0xff;
136
+ p[7] = (x >> 56) & 0xff;
137
+ }
138
+ #endif /* !HAVE_SYS_ENDIAN_H */
139
+
140
+ #endif /* !_SYSENDIAN_H_ */
@@ -0,0 +1,11 @@
1
+ require 'pbkdf256/version'
2
+ require 'pbkdf256_n'
3
+
4
+ module PBKDF256
5
+ extend self
6
+
7
+ class << self
8
+ alias :dk :hmac_sha256
9
+ alias :pbkdf2_sha256 :hmac_sha256
10
+ end
11
+ end
@@ -0,0 +1,4 @@
1
+ module PBKDF256
2
+ # PBKDF256 version
3
+ VERSION = "0.1.3"
4
+ end
@@ -0,0 +1,25 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ require File.expand_path('../lib/pbkdf256/version', __FILE__)
4
+
5
+ Gem::Specification.new do |gem|
6
+ gem.name = "pbkdf256"
7
+ gem.version = PBKDF256::VERSION
8
+ gem.summary = %q{A fast, native PBKDF2-HMAC-SHA256 Ruby gem.}
9
+ gem.description = %q{A very simple, but fast (native) RFC compliant PBKDF2-HMAC-SHA256 ruby gem based on Colin Percival's C implementation.}
10
+ gem.license = "MIT"
11
+ gem.authors = ["Johanns Gregorian"]
12
+ gem.email = "io+pbkdf256@jsani.com"
13
+ gem.homepage = "https://github.com/johanns/PBKDF256#readme"
14
+
15
+ gem.files = `git ls-files`.split($/)
16
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
17
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
+ gem.require_paths = ['lib']
19
+ gem.extensions = ['ext/core/extconf.rb']
20
+
21
+ gem.add_development_dependency "rake-compiler"
22
+ gem.add_development_dependency 'rspec', '~> 2.4'
23
+ gem.add_development_dependency 'rubygems-tasks', '~> 0.2'
24
+ gem.add_development_dependency 'yard', '~> 0.8'
25
+ end
@@ -0,0 +1,16 @@
1
+ require 'benchmark'
2
+ require 'openssl'
3
+ require 'pbkdf2'
4
+ require 'pbkdf256'
5
+
6
+ Benchmark.bm do |x|
7
+ x.report { OpenSSL::PKCS5.pbkdf2_hmac("pleaseletmein", "SodiumChloride", 100000, 64, 'sha256') }
8
+ x.report { PBKDF256.pbkdf2_sha256("pleaseletmein", "SodiumChloride", 100000, 64) }
9
+ x.report { PBKDF2.new(:password => "pleaseletmein", :salt => "SodiumChloride", :iterations => 100000, :key_length => 64).value }
10
+ end
11
+
12
+ Benchmark.bm do |x|
13
+ x.report { OpenSSL::PKCS5.pbkdf2_hmac("pleaseletmein", "SodiumChloride", 2000, 64, 'sha256') }
14
+ x.report { PBKDF256.pbkdf2_sha256("pleaseletmein", "SodiumChloride", 2000, 64) }
15
+ x.report { PBKDF2.new(:password => "pleaseletmein", :salt => "SodiumChloride", :iterations => 2000, :key_length => 64).value }
16
+ end
@@ -0,0 +1,23 @@
1
+ require 'spec_helper'
2
+ require 'pbkdf256'
3
+
4
+ describe PBKDF256 do
5
+ it "should have a VERSION constant" do
6
+ subject.const_get('VERSION').should_not be_empty
7
+ end
8
+ end
9
+
10
+ describe "PBKDF256::pbkdf2_sha256 returned bits" do
11
+ it "should match test vectors" do
12
+ PBKDF256.pbkdf2_sha256("", "", 1, 16).unpack("H*").first.should eq("f7ce0b653d2d72a4108cf5abe912ffdd")
13
+
14
+ PBKDF256.pbkdf2_sha256("password", "NaCl", 1000, 32).unpack("H*").first.should\
15
+ eq("67dbcc78548a75328f6890125bec2c59876e8de2e4c92c99b201872a760e2aec")
16
+
17
+ PBKDF256.pbkdf2_sha256("pleaseletmein", "SodiumChloride", 2000, 64).unpack("H*").first.should\
18
+ eq("36b238ac8d027e1f36d6f0b4438e1943be7af230856513f5d54d58689991726414b3603ab229d8a4f54c6ab5ebdc2ff6c55e9924e1d228e9d7a36cf0a4757d3a")
19
+
20
+ PBKDF256.pbkdf2_sha256("pleaseletmein", "SodiumChloride", 100000, 64).unpack("H*").first.should\
21
+ eq("8270be2612522a439dc2c9629b18fdbbb364e35c6b5080d9bfe2176ca0e7a432b0625aa2177f75080844ec32bc226968381c07ebca0fe162d6df11af975be70e")
22
+ end
23
+ end
@@ -0,0 +1,3 @@
1
+ gem 'rspec', '~> 2.4'
2
+ require 'rspec'
3
+ require 'pbkdf256/version'
metadata ADDED
@@ -0,0 +1,135 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: pbkdf256
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.3
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Johanns Gregorian
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-09-27 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rake-compiler
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: rspec
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ~>
36
+ - !ruby/object:Gem::Version
37
+ version: '2.4'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: '2.4'
46
+ - !ruby/object:Gem::Dependency
47
+ name: rubygems-tasks
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ~>
52
+ - !ruby/object:Gem::Version
53
+ version: '0.2'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: '0.2'
62
+ - !ruby/object:Gem::Dependency
63
+ name: yard
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ~>
68
+ - !ruby/object:Gem::Version
69
+ version: '0.8'
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ~>
76
+ - !ruby/object:Gem::Version
77
+ version: '0.8'
78
+ description: A very simple, but fast (native) RFC compliant PBKDF2-HMAC-SHA256 ruby
79
+ gem based on Colin Percival's C implementation.
80
+ email: io+pbkdf256@jsani.com
81
+ executables: []
82
+ extensions:
83
+ - ext/core/extconf.rb
84
+ extra_rdoc_files: []
85
+ files:
86
+ - .document
87
+ - .gitignore
88
+ - .rspec
89
+ - .yardopts
90
+ - ChangeLog.rdoc
91
+ - LICENSE.txt
92
+ - README.rdoc
93
+ - Rakefile
94
+ - ext/core/_pbkdf256.c
95
+ - ext/core/extconf.rb
96
+ - ext/core/scrypt_platform.h
97
+ - ext/core/sha256.c
98
+ - ext/core/sha256.h
99
+ - ext/core/sysendian.h
100
+ - lib/pbkdf256.rb
101
+ - lib/pbkdf256/version.rb
102
+ - pbkdf256.gemspec
103
+ - spec/bench.rb
104
+ - spec/pbkdf256_spec.rb
105
+ - spec/spec_helper.rb
106
+ homepage: https://github.com/johanns/PBKDF256#readme
107
+ licenses:
108
+ - MIT
109
+ post_install_message:
110
+ rdoc_options: []
111
+ require_paths:
112
+ - lib
113
+ required_ruby_version: !ruby/object:Gem::Requirement
114
+ none: false
115
+ requirements:
116
+ - - ! '>='
117
+ - !ruby/object:Gem::Version
118
+ version: '0'
119
+ required_rubygems_version: !ruby/object:Gem::Requirement
120
+ none: false
121
+ requirements:
122
+ - - ! '>='
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ requirements: []
126
+ rubyforge_project:
127
+ rubygems_version: 1.8.23
128
+ signing_key:
129
+ specification_version: 3
130
+ summary: A fast, native PBKDF2-HMAC-SHA256 Ruby gem.
131
+ test_files:
132
+ - spec/bench.rb
133
+ - spec/pbkdf256_spec.rb
134
+ - spec/spec_helper.rb
135
+ has_rdoc: