pbkdf256 0.1.3

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.
@@ -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: