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.
- data/.document +3 -0
- data/.gitignore +20 -0
- data/.rspec +1 -0
- data/.yardopts +1 -0
- data/ChangeLog.rdoc +8 -0
- data/LICENSE.txt +20 -0
- data/README.rdoc +68 -0
- data/Rakefile +40 -0
- data/ext/core/_pbkdf256.c +39 -0
- data/ext/core/extconf.rb +5 -0
- data/ext/core/scrypt_platform.h +4 -0
- data/ext/core/sha256.c +421 -0
- data/ext/core/sha256.h +71 -0
- data/ext/core/sysendian.h +140 -0
- data/lib/pbkdf256.rb +11 -0
- data/lib/pbkdf256/version.rb +4 -0
- data/pbkdf256.gemspec +25 -0
- data/spec/bench.rb +16 -0
- data/spec/pbkdf256_spec.rb +23 -0
- data/spec/spec_helper.rb +3 -0
- metadata +135 -0
data/.document
ADDED
data/.gitignore
ADDED
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--colour --format documentation
|
data/.yardopts
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--markup rdoc --title "PBKDF256 Documentation" --protected
|
data/ChangeLog.rdoc
ADDED
data/LICENSE.txt
ADDED
@@ -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.
|
data/README.rdoc
ADDED
@@ -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.
|
data/Rakefile
ADDED
@@ -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
|
+
}
|
data/ext/core/extconf.rb
ADDED
data/ext/core/sha256.c
ADDED
@@ -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
|
+
}
|
data/ext/core/sha256.h
ADDED
@@ -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_ */
|
data/lib/pbkdf256.rb
ADDED
data/pbkdf256.gemspec
ADDED
@@ -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
|
data/spec/bench.rb
ADDED
@@ -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
|
data/spec/spec_helper.rb
ADDED
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:
|