scrypt 1.0.6 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +2 -0
- data/.travis.yml +4 -0
- data/Gemfile.lock +5 -1
- data/README.md +4 -2
- data/Rakefile +1 -1
- data/ext/mri/scrypt_ext.c +5 -71
- data/lib/scrypt.rb +53 -16
- data/lib/scrypt/version.rb +1 -1
- data/scrypt.gemspec +1 -0
- data/spec/scrypt/engine_spec.rb +15 -0
- data/spec/scrypt/password_spec.rb +70 -1
- metadata +21 -6
- data/CHANGELOG +0 -3
- data/ext/mri/Makefile +0 -213
data/.gitignore
CHANGED
data/.travis.yml
ADDED
data/Gemfile.lock
CHANGED
@@ -1,14 +1,17 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
scrypt (1.0
|
4
|
+
scrypt (1.1.0)
|
5
5
|
|
6
6
|
GEM
|
7
7
|
remote: http://rubygems.org/
|
8
8
|
specs:
|
9
9
|
awesome_print (1.0.2)
|
10
10
|
diff-lcs (1.1.3)
|
11
|
+
json (1.7.0)
|
11
12
|
rake (0.9.2.2)
|
13
|
+
rdoc (3.12)
|
14
|
+
json (~> 1.4)
|
12
15
|
rspec (2.9.0)
|
13
16
|
rspec-core (~> 2.9.0)
|
14
17
|
rspec-expectations (~> 2.9.0)
|
@@ -24,5 +27,6 @@ PLATFORMS
|
|
24
27
|
DEPENDENCIES
|
25
28
|
awesome_print
|
26
29
|
rake (~> 0.9.2)
|
30
|
+
rdoc
|
27
31
|
rspec
|
28
32
|
scrypt!
|
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
scrypt
|
1
|
+
scrypt [![Build Status](https://secure.travis-ci.org/pbhogan/scrypt.png)](http://travis-ci.org/pbhogan/scrypt)
|
2
2
|
======
|
3
3
|
|
4
4
|
The scrypt key derivation function is designed to be far more secure against hardware brute-force attacks than alternative functions such as PBKDF2 or bcrypt.
|
@@ -41,8 +41,10 @@ include "scrypt"
|
|
41
41
|
@db_password == "a paltry guess" #=> false
|
42
42
|
```
|
43
43
|
|
44
|
-
Password.create takes
|
44
|
+
Password.create takes five options which will determine the key length and salt size, as well as the cost limits of the computation:
|
45
45
|
|
46
|
+
* `:key_len` specifies the length in bytes of the key you want to generate. The default is 32 bytes (256 bits). Minimum is 16 bytes (128 bits). Maximum is 512 bytes (4096 bits).
|
47
|
+
* `:salt_size` specifies the size in bytes of the random salt you want to generate. The default and minimum is 8 bytes (64 bits). Maximum is 32 bytes (256 bits).
|
46
48
|
* `:max_time` specifies the maximum number of seconds the computation should take.
|
47
49
|
* `:max_mem` specifies the maximum number of bytes the computation should take. A value of 0 specifies no upper limit. The minimum is always 1 MB.
|
48
50
|
* `:max_memfrac` specifies the maximum memory in a fraction of available resources to use. Any value equal to 0 or greater than 0.5 will result in 0.5 being used.
|
data/Rakefile
CHANGED
@@ -14,7 +14,7 @@ rd = Rake::RDocTask.new do |rdoc|
|
|
14
14
|
rdoc.rdoc_dir = 'doc/rdoc'
|
15
15
|
rdoc.options << '--title' << 'scrypt-ruby' << '--line-numbers' << '--inline-source' << '--main' << 'README'
|
16
16
|
rdoc.template = ENV['TEMPLATE'] if ENV['TEMPLATE']
|
17
|
-
rdoc.rdoc_files.include('
|
17
|
+
rdoc.rdoc_files.include('COPYING', 'lib/**/*.rb')
|
18
18
|
end
|
19
19
|
|
20
20
|
|
data/ext/mri/scrypt_ext.c
CHANGED
@@ -24,49 +24,28 @@ static VALUE sc_calibrate( VALUE self, VALUE maxmem, VALUE maxmemfrac, VALUE max
|
|
24
24
|
|
25
25
|
if (calibrate( mm, mf, mt, & n, & r, & p ) == 0)
|
26
26
|
{
|
27
|
-
|
28
|
-
memset( cost_str, '\0', 33 );
|
29
|
-
#ifdef __MINGW32__
|
30
|
-
sprintf( cost_str, "%lx$%x$%x$", (long unsigned int)n, (unsigned int)r, (unsigned int)p );
|
31
|
-
#else
|
32
|
-
sprintf( cost_str, "%Lx$%x$%x$", n, r, p );
|
33
|
-
#endif
|
34
|
-
return rb_str_new2( cost_str );
|
27
|
+
return rb_ary_new3( 3, UINT2NUM( n ), UINT2NUM( r ), UINT2NUM( p ));
|
35
28
|
}
|
36
29
|
|
37
30
|
return Qnil;
|
38
31
|
}
|
39
32
|
|
40
33
|
|
41
|
-
static VALUE sc_crypt( VALUE self, VALUE key, VALUE salt, VALUE
|
34
|
+
static VALUE sc_crypt( VALUE self, VALUE key, VALUE salt, VALUE n, VALUE r, VALUE p, VALUE keylen )
|
42
35
|
{
|
43
|
-
uint64_t n = 0;
|
44
|
-
uint32_t r = 0;
|
45
|
-
uint32_t p = 0;
|
46
36
|
int result;
|
47
37
|
|
48
38
|
const char * safe_key = RSTRING_PTR(key) ? RSTRING_PTR(key) : "";
|
49
39
|
const char * safe_salt = RSTRING_PTR(salt) ? RSTRING_PTR(salt) : "";
|
50
40
|
|
51
|
-
const size_t buffer_size =
|
41
|
+
const size_t buffer_size = NUM2UINT( keylen );
|
52
42
|
char buffer[buffer_size];
|
53
43
|
memset( buffer, '\0', buffer_size );
|
54
44
|
|
55
|
-
if (!RSTRING_PTR( cost ))
|
56
|
-
{
|
57
|
-
return Qnil;
|
58
|
-
}
|
59
|
-
|
60
|
-
#ifdef __MINGW32__
|
61
|
-
sscanf( RSTRING_PTR( cost ), "%lx$%x$%x$", (long unsigned int*)& n, (unsigned int*)& r, (unsigned int*)& p );
|
62
|
-
#else
|
63
|
-
sscanf( RSTRING_PTR( cost ), "%Lx$%x$%x$", & n, & r, & p );
|
64
|
-
#endif
|
65
|
-
|
66
45
|
result = crypto_scrypt(
|
67
46
|
(uint8_t *) safe_key, strlen(safe_key),
|
68
47
|
(uint8_t *) safe_salt, strlen(safe_salt),
|
69
|
-
n, r, p,
|
48
|
+
NUM2UINT( n ), NUM2UINT( r ), NUM2UINT( p ),
|
70
49
|
(uint8_t *) buffer, buffer_size
|
71
50
|
);
|
72
51
|
|
@@ -87,50 +66,5 @@ void Init_scrypt_ext()
|
|
87
66
|
cSCryptEngine = rb_define_class_under( mSCrypt, "Engine", rb_cObject );
|
88
67
|
|
89
68
|
rb_define_singleton_method( cSCryptEngine, "__sc_calibrate", sc_calibrate, 3 );
|
90
|
-
rb_define_singleton_method( cSCryptEngine, "__sc_crypt", sc_crypt,
|
91
|
-
}
|
92
|
-
|
93
|
-
|
94
|
-
/*
|
95
|
-
#include <stdio.h>
|
96
|
-
#include <string.h>
|
97
|
-
#include "scrypt_calibrate.h"
|
98
|
-
#include "crypto_scrypt.h"
|
99
|
-
|
100
|
-
int main (int argc, const char * argv[])
|
101
|
-
{
|
102
|
-
uint64_t n;
|
103
|
-
uint32_t r;
|
104
|
-
uint32_t p;
|
105
|
-
|
106
|
-
int result = calibrate( 0, 0.001, 0.25, & n, & r, & p );
|
107
|
-
|
108
|
-
printf( "%Ld %d %d \n", n, r, p );
|
109
|
-
|
110
|
-
char header[33];
|
111
|
-
sprintf( header, "%.16Lx%.8x%.8x", n, r, p );
|
112
|
-
printf( "%s \n", header );
|
113
|
-
|
114
|
-
uint64_t a = 0;
|
115
|
-
uint32_t b = 0;
|
116
|
-
uint32_t c = 0;
|
117
|
-
sscanf( header, "%16Lx%8x%8x", & a, & b, & c );
|
118
|
-
printf( "%Ld %d %d \n", a, b, c );
|
119
|
-
|
120
|
-
char password[] = "helloworld!";
|
121
|
-
char salt[] = "qwerty";
|
122
|
-
const size_t buffer_size = 32;
|
123
|
-
char buffer[buffer_size];
|
124
|
-
memset(buffer, '\0', buffer_size);
|
125
|
-
|
126
|
-
result = crypto_scrypt( (uint8_t *) password, strlen(password), (uint8_t *) salt, strlen(salt), n, r, p, (uint8_t *) buffer, buffer_size );
|
127
|
-
|
128
|
-
for (size_t i=0; i<buffer_size; i++)
|
129
|
-
{
|
130
|
-
printf( "%.2x", buffer[i] );
|
131
|
-
}
|
132
|
-
printf( "\n" );
|
133
|
-
|
134
|
-
return 0;
|
69
|
+
rb_define_singleton_method( cSCryptEngine, "__sc_crypt", sc_crypt, 6 );
|
135
70
|
}
|
136
|
-
*/
|
data/lib/scrypt.rb
CHANGED
@@ -3,12 +3,11 @@
|
|
3
3
|
$LOAD_PATH.unshift(File.expand_path(File.join(File.dirname(__FILE__), "..", "ext", "mri")))
|
4
4
|
require "scrypt_ext"
|
5
5
|
require "openssl"
|
6
|
-
require "digest/sha1"
|
7
6
|
require "scanf"
|
8
7
|
|
9
8
|
|
10
9
|
module SCrypt
|
11
|
-
|
10
|
+
|
12
11
|
module Errors
|
13
12
|
class InvalidSalt < StandardError; end # The salt parameter provided is invalid.
|
14
13
|
class InvalidHash < StandardError; end # The hash parameter provided is invalid.
|
@@ -16,21 +15,47 @@ module SCrypt
|
|
16
15
|
end
|
17
16
|
|
18
17
|
class Engine
|
19
|
-
DEFAULTS = {
|
20
|
-
:
|
18
|
+
DEFAULTS = {
|
19
|
+
:key_len => 32,
|
20
|
+
:salt_size => 8,
|
21
|
+
:max_mem => 1024 * 1024,
|
21
22
|
:max_memfrac => 0.5,
|
22
|
-
:max_time
|
23
|
+
:max_time => 0.2
|
23
24
|
}
|
24
25
|
|
25
26
|
private_class_method :__sc_calibrate
|
26
27
|
private_class_method :__sc_crypt
|
27
28
|
|
29
|
+
def self.scrypt(secret, salt, *args)
|
30
|
+
if args.length == 2
|
31
|
+
# args is [cost_string, key_len]
|
32
|
+
n, r, p = args[0].split('$').map{ |x| x.to_i(16) }
|
33
|
+
key_len = args[1]
|
34
|
+
__sc_crypt(secret, salt, n, r, p, key_len)
|
35
|
+
elsif args.length == 4
|
36
|
+
# args is [n, r, p, key_len]
|
37
|
+
n, r, p = args[0, 3]
|
38
|
+
key_len = args[3]
|
39
|
+
__sc_crypt(secret, salt, n, r, p, key_len)
|
40
|
+
else
|
41
|
+
raise ArgumentError.new("invalid number of arguments (4 or 6)")
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
28
45
|
# Given a secret and a valid salt (see SCrypt::Engine.generate_salt) calculates an scrypt password hash.
|
29
|
-
def self.hash_secret(secret, salt)
|
46
|
+
def self.hash_secret(secret, salt, key_len = DEFAULTS[:key_len])
|
30
47
|
if valid_secret?(secret)
|
31
48
|
if valid_salt?(salt)
|
32
49
|
cost = autodetect_cost(salt)
|
33
|
-
|
50
|
+
salt_only = salt[/\$([A-Za-z0-9]{16,64})$/, 1]
|
51
|
+
if salt_only.length == 40
|
52
|
+
# Old-style hash with 40-character salt
|
53
|
+
salt + "$" + Digest::SHA1.hexdigest(scrypt(secret.to_s, salt, cost, 256))
|
54
|
+
else
|
55
|
+
# New-style hash
|
56
|
+
salt_only = [salt_only.sub(/^(00)+/, '')].pack('H*')
|
57
|
+
salt + "$" + scrypt(secret.to_s, salt_only, cost, key_len).unpack('H*').first.rjust(key_len * 2, '0')
|
58
|
+
end
|
34
59
|
else
|
35
60
|
raise Errors::InvalidSalt.new("invalid salt")
|
36
61
|
end
|
@@ -43,7 +68,11 @@ module SCrypt
|
|
43
68
|
def self.generate_salt(options = {})
|
44
69
|
options = DEFAULTS.merge(options)
|
45
70
|
cost = calibrate(options)
|
46
|
-
salt =
|
71
|
+
salt = OpenSSL::Random.random_bytes(options[:salt_size]).unpack('H*').first.rjust(16,'0')
|
72
|
+
if salt.length == 40
|
73
|
+
#If salt is 40 characters, the regexp will think that it is an old-style hash, so add a '0'.
|
74
|
+
salt = '0' + salt
|
75
|
+
end
|
47
76
|
cost + salt
|
48
77
|
end
|
49
78
|
|
@@ -54,7 +83,7 @@ module SCrypt
|
|
54
83
|
|
55
84
|
# Returns true if +salt+ is a valid salt, false if not.
|
56
85
|
def self.valid_salt?(salt)
|
57
|
-
salt.match(/^[0-9a-z]+\$[0-9a-z]+\$[0-9a-z]+\$[A-Za-z0-9]{
|
86
|
+
salt.match(/^[0-9a-z]+\$[0-9a-z]+\$[0-9a-z]+\$[A-Za-z0-9]{16,64}$/) != nil
|
58
87
|
end
|
59
88
|
|
60
89
|
# Returns true if +secret+ is a valid secret, false if not.
|
@@ -76,9 +105,9 @@ module SCrypt
|
|
76
105
|
#
|
77
106
|
def self.calibrate(options = {})
|
78
107
|
options = DEFAULTS.merge(options)
|
79
|
-
__sc_calibrate(options[:max_mem], options[:max_memfrac], options[:max_time])
|
108
|
+
"%x$%x$%x$" % __sc_calibrate(options[:max_mem], options[:max_memfrac], options[:max_time])
|
80
109
|
end
|
81
|
-
|
110
|
+
|
82
111
|
# Computes the memory use of the given +cost+
|
83
112
|
def self.memory_use(cost)
|
84
113
|
n, r, p = cost.scanf("%x$%x$%x$")
|
@@ -121,8 +150,10 @@ module SCrypt
|
|
121
150
|
attr_reader :cost
|
122
151
|
|
123
152
|
class << self
|
124
|
-
# Hashes a secret, returning a SCrypt::Password instance.
|
125
|
-
# Takes
|
153
|
+
# Hashes a secret, returning a SCrypt::Password instance.
|
154
|
+
# Takes five options (optional), which will determine the salt/key's length and the cost limits of the computation.
|
155
|
+
# <tt>:key_len</tt> specifies the length in bytes of the key you want to generate. The default is 32 bytes (256 bits). Minimum is 16 bytes (128 bits). Maximum is 512 bytes (4096 bits).
|
156
|
+
# <tt>:salt_size</tt> specifies the size in bytes of the random salt you want to generate. The default and minimum is 8 bytes (64 bits). Maximum is 32 bytes (256 bits).
|
126
157
|
# <tt>:max_time</tt> specifies the maximum number of seconds the computation should take.
|
127
158
|
# <tt>:max_mem</tt> specifies the maximum number of bytes the computation should take. A value of 0 specifies no upper limit. The minimum is always 1 MB.
|
128
159
|
# <tt>:max_memfrac</tt> specifies the maximum memory in a fraction of available resources to use. Any value equal to 0 or greater than 0.5 will result in 0.5 being used.
|
@@ -135,8 +166,14 @@ module SCrypt
|
|
135
166
|
#
|
136
167
|
def create(secret, options = {})
|
137
168
|
options = SCrypt::Engine::DEFAULTS.merge(options)
|
169
|
+
#Clamp minimum/maximum keylen
|
170
|
+
options[:key_len] = 16 if options[:key_len] < 16
|
171
|
+
options[:key_len] = 512 if options[:key_len] > 512
|
172
|
+
#Clamp minimum/maximum salt_size
|
173
|
+
options[:salt_size] = 8 if options[:salt_size] < 8
|
174
|
+
options[:salt_size] = 32 if options[:salt_size] > 32
|
138
175
|
salt = SCrypt::Engine.generate_salt(options)
|
139
|
-
hash = SCrypt::Engine.hash_secret(secret, salt)
|
176
|
+
hash = SCrypt::Engine.hash_secret(secret, salt, options[:key_len])
|
140
177
|
Password.new(hash)
|
141
178
|
end
|
142
179
|
end
|
@@ -153,14 +190,14 @@ module SCrypt
|
|
153
190
|
|
154
191
|
# Compares a potential secret against the hash. Returns true if the secret is the original secret, false otherwise.
|
155
192
|
def ==(secret)
|
156
|
-
super(SCrypt::Engine.hash_secret(secret, @cost + @salt))
|
193
|
+
super(SCrypt::Engine.hash_secret(secret, @cost + @salt, self.hash.length / 2))
|
157
194
|
end
|
158
195
|
alias_method :is_password?, :==
|
159
196
|
|
160
197
|
private
|
161
198
|
# Returns true if +h+ is a valid hash.
|
162
199
|
def valid_hash?(h)
|
163
|
-
h.match(/^[0-9a-z]+\$[0-9a-z]+\$[0-9a-z]+\$[A-Za-z0-9]{
|
200
|
+
h.match(/^[0-9a-z]+\$[0-9a-z]+\$[0-9a-z]+\$[A-Za-z0-9]{16,64}\$[A-Za-z0-9]{32,1024}$/) != nil
|
164
201
|
end
|
165
202
|
|
166
203
|
# call-seq:
|
data/lib/scrypt/version.rb
CHANGED
data/scrypt.gemspec
CHANGED
data/spec/scrypt/engine_spec.rb
CHANGED
@@ -56,3 +56,18 @@ describe "Generating SCrypt hashes" do
|
|
56
56
|
end
|
57
57
|
end
|
58
58
|
|
59
|
+
describe "SCrypt test vectors" do
|
60
|
+
it "should match results of SCrypt function" do
|
61
|
+
SCrypt::Engine.scrypt('', '', 16, 1, 1, 64).unpack('H*').first.should eq('77d6576238657b203b19ca42c18a0497f16b4844e3074ae8dfdffa3fede21442fcd0069ded0948f8326a753a0fc81f17e8d3e0fb2e0d3628cf35e20c38d18906')
|
62
|
+
SCrypt::Engine.scrypt('password', 'NaCl', 1024, 8, 16, 64).unpack('H*').first.should eq('fdbabe1c9d3472007856e7190d01e9fe7c6ad7cbc8237830e77376634b3731622eaf30d92e22a3886ff109279d9830dac727afb94a83ee6d8360cbdfa2cc0640')
|
63
|
+
SCrypt::Engine.scrypt('pleaseletmein', 'SodiumChloride', 16384, 8, 1, 64).unpack('H*').first.should eq('7023bdcb3afd7348461c06cd81fd38ebfda8fbba904f8e3ea9b543f6545da1f2d5432955613f0fcf62d49705242a9af9e61e85dc0d651e40dfcf017b45575887')
|
64
|
+
SCrypt::Engine.scrypt('pleaseletmein', 'SodiumChloride', 1048576, 8, 1, 64).unpack('H*').first.should eq('2101cb9b6a511aaeaddbbe09cf70f881ec568d574a2ffd4dabe5ee9820adaa478e56fd8f4ba5d09ffa1c6d927c40f4c337304049e8a952fbcbf45c6fa77a41a4')
|
65
|
+
end
|
66
|
+
|
67
|
+
it "should match equivalent results sent through hash_secret() function" do
|
68
|
+
SCrypt::Engine.hash_secret('', '10$1$1$0000000000000000', 64).should match(/\$77d6576238657b203b19ca42c18a0497f16b4844e3074ae8dfdffa3fede21442fcd0069ded0948f8326a753a0fc81f17e8d3e0fb2e0d3628cf35e20c38d18906$/)
|
69
|
+
SCrypt::Engine.hash_secret('password', '400$8$10$000000004e61436c', 64).should match(/\$fdbabe1c9d3472007856e7190d01e9fe7c6ad7cbc8237830e77376634b3731622eaf30d92e22a3886ff109279d9830dac727afb94a83ee6d8360cbdfa2cc0640$/)
|
70
|
+
SCrypt::Engine.hash_secret('pleaseletmein', '4000$8$1$536f6469756d43686c6f72696465', 64).should match(/\$7023bdcb3afd7348461c06cd81fd38ebfda8fbba904f8e3ea9b543f6545da1f2d5432955613f0fcf62d49705242a9af9e61e85dc0d651e40dfcf017b45575887$/)
|
71
|
+
SCrypt::Engine.hash_secret('pleaseletmein', '100000$8$1$536f6469756d43686c6f72696465', 64).should match(/\$2101cb9b6a511aaeaddbbe09cf70f881ec568d574a2ffd4dabe5ee9820adaa478e56fd8f4ba5d09ffa1c6d927c40f4c337304049e8a952fbcbf45c6fa77a41a4$/)
|
72
|
+
end
|
73
|
+
end
|
@@ -45,7 +45,6 @@ describe "Reading a hashed password" do
|
|
45
45
|
end
|
46
46
|
end
|
47
47
|
|
48
|
-
|
49
48
|
describe "Comparing a hashed password with a secret" do
|
50
49
|
before :each do
|
51
50
|
@secret = "s3cr3t"
|
@@ -59,5 +58,75 @@ describe "Comparing a hashed password with a secret" do
|
|
59
58
|
it "should compare unsuccessfully to anything besides original secret" do
|
60
59
|
(@password == "@secret").should be(false)
|
61
60
|
end
|
61
|
+
|
62
62
|
end
|
63
63
|
|
64
|
+
describe "non-default salt sizes" do
|
65
|
+
before :each do
|
66
|
+
@secret = "s3cret"
|
67
|
+
end
|
68
|
+
|
69
|
+
it "should enforce a minimum salt of 8 bytes" do
|
70
|
+
@password = SCrypt::Password.create(@secret, :salt_size => 7)
|
71
|
+
@password.salt.length.should eq(8 * 2)
|
72
|
+
end
|
73
|
+
|
74
|
+
it "should allow a salt of 32 bytes" do
|
75
|
+
@password = SCrypt::Password.create(@secret, :salt_size => 32)
|
76
|
+
@password.salt.length.should eq(32 * 2)
|
77
|
+
end
|
78
|
+
|
79
|
+
it "should enforce a maximum salt of 32 bytes" do
|
80
|
+
@password = SCrypt::Password.create(@secret, :salt_size => 33)
|
81
|
+
@password.salt.length.should eq(32 * 2)
|
82
|
+
end
|
83
|
+
|
84
|
+
it "should pad a 20-byte salt to not look like a 20-byte SHA1" do
|
85
|
+
@password = SCrypt::Password.create(@secret, :salt_size => 20)
|
86
|
+
@password.salt.length.should eq(41)
|
87
|
+
end
|
88
|
+
|
89
|
+
it "should properly compare a non-standard salt hash" do
|
90
|
+
@password = SCrypt::Password.create(@secret, :salt_size => 20)
|
91
|
+
(SCrypt::Password.new(@password.to_s) == @secret).should be(true)
|
92
|
+
end
|
93
|
+
|
94
|
+
end
|
95
|
+
|
96
|
+
describe "non-default key lengths" do
|
97
|
+
before :each do
|
98
|
+
@secret = "s3cret"
|
99
|
+
end
|
100
|
+
|
101
|
+
it "should enforce a minimum keylength of 16 bytes" do
|
102
|
+
@password = SCrypt::Password.create(@secret, :key_len => 15)
|
103
|
+
@password.hash.length.should eq(16 * 2)
|
104
|
+
end
|
105
|
+
|
106
|
+
it "should allow a keylength of 512 bytes" do
|
107
|
+
@password = SCrypt::Password.create(@secret, :key_len => 512)
|
108
|
+
@password.hash.length.should eq(512 * 2)
|
109
|
+
end
|
110
|
+
|
111
|
+
it "should enforce a maximum keylength of 512 bytes" do
|
112
|
+
@password = SCrypt::Password.create(@secret, :key_len => 513)
|
113
|
+
@password.hash.length.should eq(512 * 2)
|
114
|
+
end
|
115
|
+
|
116
|
+
it "should properly compare a non-standard hash" do
|
117
|
+
@password = SCrypt::Password.create(@secret, :key_len => 512)
|
118
|
+
(SCrypt::Password.new(@password.to_s) == @secret).should be(true)
|
119
|
+
end
|
120
|
+
|
121
|
+
end
|
122
|
+
|
123
|
+
describe "Old-style hashes" do
|
124
|
+
before :each do
|
125
|
+
@secret = "my secret"
|
126
|
+
@hash = "400$8$d$173a8189751c095a29b933789560b73bf17b2e01$9bf66d74bd6f3ebcf99da3b379b689b89db1cb07"
|
127
|
+
end
|
128
|
+
|
129
|
+
it "should compare successfully" do
|
130
|
+
(SCrypt::Password.new(@hash) == @secret).should be(true)
|
131
|
+
end
|
132
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: scrypt
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0
|
4
|
+
version: 1.1.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-05-
|
12
|
+
date: 2012-05-07 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rspec
|
@@ -27,6 +27,22 @@ dependencies:
|
|
27
27
|
- - ! '>='
|
28
28
|
- !ruby/object:Gem::Version
|
29
29
|
version: '0'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: rdoc
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
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: '0'
|
30
46
|
- !ruby/object:Gem::Dependency
|
31
47
|
name: rake
|
32
48
|
requirement: !ruby/object:Gem::Requirement
|
@@ -72,14 +88,13 @@ files:
|
|
72
88
|
- .gitignore
|
73
89
|
- .rspec
|
74
90
|
- .rvmrc
|
75
|
-
-
|
91
|
+
- .travis.yml
|
76
92
|
- COPYING
|
77
93
|
- Gemfile
|
78
94
|
- Gemfile.lock
|
79
95
|
- README.md
|
80
96
|
- Rakefile
|
81
97
|
- autotest/discover.rb
|
82
|
-
- ext/mri/Makefile
|
83
98
|
- ext/mri/alt-impl/crypto_scrypt-nosse.c
|
84
99
|
- ext/mri/alt-impl/crypto_scrypt-ref.c
|
85
100
|
- ext/mri/crypto_scrypt-sse.c
|
@@ -117,7 +132,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
117
132
|
version: '0'
|
118
133
|
segments:
|
119
134
|
- 0
|
120
|
-
hash:
|
135
|
+
hash: -214930008180539210
|
121
136
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
122
137
|
none: false
|
123
138
|
requirements:
|
@@ -126,7 +141,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
126
141
|
version: '0'
|
127
142
|
segments:
|
128
143
|
- 0
|
129
|
-
hash:
|
144
|
+
hash: -214930008180539210
|
130
145
|
requirements: []
|
131
146
|
rubyforge_project: scrypt
|
132
147
|
rubygems_version: 1.8.21
|
data/CHANGELOG
DELETED
data/ext/mri/Makefile
DELETED
@@ -1,213 +0,0 @@
|
|
1
|
-
|
2
|
-
SHELL = /bin/sh
|
3
|
-
|
4
|
-
# V=0 quiet, V=1 verbose. other values don't work.
|
5
|
-
V = 0
|
6
|
-
Q1 = $(V:1=)
|
7
|
-
Q = $(Q1:0=@)
|
8
|
-
n=$(NULLCMD)
|
9
|
-
ECHO1 = $(V:1=@$n)
|
10
|
-
ECHO = $(ECHO1:0=@echo)
|
11
|
-
|
12
|
-
#### Start of system configuration section. ####
|
13
|
-
|
14
|
-
srcdir = .
|
15
|
-
topdir = /Volumes/Secondary/Users/pbhogan/.rvm/rubies/ruby-1.9.3-p125/include/ruby-1.9.1
|
16
|
-
hdrdir = /Volumes/Secondary/Users/pbhogan/.rvm/rubies/ruby-1.9.3-p125/include/ruby-1.9.1
|
17
|
-
arch_hdrdir = /Volumes/Secondary/Users/pbhogan/.rvm/rubies/ruby-1.9.3-p125/include/ruby-1.9.1/$(arch)
|
18
|
-
VPATH = $(srcdir):$(arch_hdrdir)/ruby:$(hdrdir)/ruby
|
19
|
-
prefix = $(DESTDIR)/Volumes/Secondary/Users/pbhogan/.rvm/rubies/ruby-1.9.3-p125
|
20
|
-
rubylibprefix = $(libdir)/$(RUBY_BASE_NAME)
|
21
|
-
exec_prefix = $(prefix)
|
22
|
-
vendorhdrdir = $(rubyhdrdir)/vendor_ruby
|
23
|
-
sitehdrdir = $(rubyhdrdir)/site_ruby
|
24
|
-
rubyhdrdir = $(includedir)/$(RUBY_BASE_NAME)-$(ruby_version)
|
25
|
-
vendordir = $(rubylibprefix)/vendor_ruby
|
26
|
-
sitedir = $(rubylibprefix)/site_ruby
|
27
|
-
ridir = $(datarootdir)/$(RI_BASE_NAME)
|
28
|
-
mandir = $(datarootdir)/man
|
29
|
-
localedir = $(datarootdir)/locale
|
30
|
-
libdir = $(exec_prefix)/lib
|
31
|
-
psdir = $(docdir)
|
32
|
-
pdfdir = $(docdir)
|
33
|
-
dvidir = $(docdir)
|
34
|
-
htmldir = $(docdir)
|
35
|
-
infodir = $(datarootdir)/info
|
36
|
-
docdir = $(datarootdir)/doc/$(PACKAGE)
|
37
|
-
oldincludedir = $(DESTDIR)/usr/include
|
38
|
-
includedir = $(prefix)/include
|
39
|
-
localstatedir = $(prefix)/var
|
40
|
-
sharedstatedir = $(prefix)/com
|
41
|
-
sysconfdir = $(prefix)/etc
|
42
|
-
datadir = $(datarootdir)
|
43
|
-
datarootdir = $(prefix)/share
|
44
|
-
libexecdir = $(exec_prefix)/libexec
|
45
|
-
sbindir = $(exec_prefix)/sbin
|
46
|
-
bindir = $(exec_prefix)/bin
|
47
|
-
rubylibdir = $(rubylibprefix)/$(ruby_version)
|
48
|
-
archdir = $(rubylibdir)/$(arch)
|
49
|
-
sitelibdir = $(sitedir)/$(ruby_version)
|
50
|
-
sitearchdir = $(sitelibdir)/$(sitearch)
|
51
|
-
vendorlibdir = $(vendordir)/$(ruby_version)
|
52
|
-
vendorarchdir = $(vendorlibdir)/$(sitearch)
|
53
|
-
|
54
|
-
NULLCMD = :
|
55
|
-
|
56
|
-
CC = /usr/bin/gcc-4.2 -Wall -msse -msse2
|
57
|
-
CXX = g++-4.2
|
58
|
-
LIBRUBY = $(LIBRUBY_SO)
|
59
|
-
LIBRUBY_A = lib$(RUBY_SO_NAME)-static.a
|
60
|
-
LIBRUBYARG_SHARED = -l$(RUBY_SO_NAME)
|
61
|
-
LIBRUBYARG_STATIC = -l$(RUBY_SO_NAME)-static
|
62
|
-
OUTFLAG = -o
|
63
|
-
COUTFLAG = -o
|
64
|
-
|
65
|
-
RUBY_EXTCONF_H =
|
66
|
-
cflags = $(optflags) $(debugflags) $(warnflags)
|
67
|
-
optflags = -O3
|
68
|
-
debugflags = -g
|
69
|
-
warnflags = -Wextra -Wno-unused-parameter -Wno-parentheses -Wno-long-long -Wno-missing-field-initializers -Wpointer-arith -Wwrite-strings -Wdeclaration-after-statement -Wshorten-64-to-32 -Wimplicit-function-declaration
|
70
|
-
CFLAGS = -fno-common $(cflags) -fno-common -pipe $(ARCH_FLAG)
|
71
|
-
INCFLAGS = -I. -I$(arch_hdrdir) -I$(hdrdir)/ruby/backward -I$(hdrdir) -I$(srcdir)
|
72
|
-
DEFS =
|
73
|
-
CPPFLAGS = -I/Volumes/Secondary/Users/pbhogan/.rvm/usr/include -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE $(DEFS) $(cppflags)
|
74
|
-
CXXFLAGS = $(CFLAGS) $(cxxflags)
|
75
|
-
ldflags = -L. -L/usr/local/lib
|
76
|
-
dldflags = -Wl,-undefined,dynamic_lookup -Wl,-multiply_defined,suppress -Wl,-flat_namespace
|
77
|
-
ARCH_FLAG =
|
78
|
-
DLDFLAGS = $(ldflags) $(dldflags) $(ARCH_FLAG)
|
79
|
-
LDSHARED = $(CC) -dynamic -bundle
|
80
|
-
LDSHAREDXX = $(CXX) -dynamic -bundle
|
81
|
-
AR = ar
|
82
|
-
EXEEXT =
|
83
|
-
|
84
|
-
RUBY_BASE_NAME = ruby
|
85
|
-
RUBY_INSTALL_NAME = ruby
|
86
|
-
RUBY_SO_NAME = ruby.1.9.1
|
87
|
-
arch = x86_64-darwin11.3.0
|
88
|
-
sitearch = $(arch)
|
89
|
-
ruby_version = 1.9.1
|
90
|
-
ruby = /Volumes/Secondary/Users/pbhogan/.rvm/rubies/ruby-1.9.3-p125/bin/ruby
|
91
|
-
RUBY = $(ruby)
|
92
|
-
RM = rm -f
|
93
|
-
RM_RF = $(RUBY) -run -e rm -- -rf
|
94
|
-
RMDIRS = rmdir -p
|
95
|
-
MAKEDIRS = mkdir -p
|
96
|
-
INSTALL = /usr/bin/install -c
|
97
|
-
INSTALL_PROG = $(INSTALL) -m 0755
|
98
|
-
INSTALL_DATA = $(INSTALL) -m 644
|
99
|
-
COPY = cp
|
100
|
-
|
101
|
-
#### End of system configuration section. ####
|
102
|
-
|
103
|
-
preload =
|
104
|
-
|
105
|
-
libpath = . $(libdir) /Volumes/Secondary/Users/pbhogan/.rvm/usr/lib
|
106
|
-
LIBPATH = -L. -L$(libdir) -L/Volumes/Secondary/Users/pbhogan/.rvm/usr/lib
|
107
|
-
DEFFILE =
|
108
|
-
|
109
|
-
CLEANFILES = mkmf.log
|
110
|
-
DISTCLEANFILES =
|
111
|
-
DISTCLEANDIRS =
|
112
|
-
|
113
|
-
extout =
|
114
|
-
extout_prefix =
|
115
|
-
target_prefix =
|
116
|
-
LOCAL_LIBS =
|
117
|
-
LIBS = $(LIBRUBYARG_SHARED) -lpthread -ldl -lobjc
|
118
|
-
SRCS = crypto_scrypt-sse.c memlimit.c scrypt_calibrate.c scrypt_ext.c scryptenc_cpuperf.c sha256.c
|
119
|
-
OBJS = crypto_scrypt-sse.o memlimit.o scrypt_calibrate.o scrypt_ext.o scryptenc_cpuperf.o sha256.o
|
120
|
-
TARGET = scrypt_ext
|
121
|
-
DLLIB = $(TARGET).bundle
|
122
|
-
EXTSTATIC =
|
123
|
-
STATIC_LIB =
|
124
|
-
|
125
|
-
BINDIR = $(bindir)
|
126
|
-
RUBYCOMMONDIR = $(sitedir)$(target_prefix)
|
127
|
-
RUBYLIBDIR = $(sitelibdir)$(target_prefix)
|
128
|
-
RUBYARCHDIR = $(sitearchdir)$(target_prefix)
|
129
|
-
HDRDIR = $(rubyhdrdir)/ruby$(target_prefix)
|
130
|
-
ARCHHDRDIR = $(rubyhdrdir)/$(arch)/ruby$(target_prefix)
|
131
|
-
|
132
|
-
TARGET_SO = $(DLLIB)
|
133
|
-
CLEANLIBS = $(TARGET).bundle
|
134
|
-
CLEANOBJS = *.o *.bak
|
135
|
-
|
136
|
-
all: $(DLLIB)
|
137
|
-
static: $(STATIC_LIB)
|
138
|
-
.PHONY: all install static install-so install-rb
|
139
|
-
.PHONY: clean clean-so clean-rb
|
140
|
-
|
141
|
-
clean-rb-default::
|
142
|
-
clean-rb::
|
143
|
-
clean-so::
|
144
|
-
clean: clean-so clean-rb-default clean-rb
|
145
|
-
@-$(RM) $(CLEANLIBS) $(CLEANOBJS) $(CLEANFILES)
|
146
|
-
|
147
|
-
distclean-rb-default::
|
148
|
-
distclean-rb::
|
149
|
-
distclean-so::
|
150
|
-
distclean: clean distclean-so distclean-rb-default distclean-rb
|
151
|
-
@-$(RM) Makefile $(RUBY_EXTCONF_H) conftest.* mkmf.log
|
152
|
-
@-$(RM) core ruby$(EXEEXT) *~ $(DISTCLEANFILES)
|
153
|
-
@-$(RMDIRS) $(DISTCLEANDIRS) 2> /dev/null || true
|
154
|
-
|
155
|
-
realclean: distclean
|
156
|
-
install: install-so install-rb
|
157
|
-
|
158
|
-
install-so: $(RUBYARCHDIR)
|
159
|
-
install-so: $(RUBYARCHDIR)/$(DLLIB)
|
160
|
-
$(RUBYARCHDIR)/$(DLLIB): $(DLLIB)
|
161
|
-
@-$(MAKEDIRS) $(@D)
|
162
|
-
$(INSTALL_PROG) $(DLLIB) $(@D)
|
163
|
-
install-rb: pre-install-rb install-rb-default
|
164
|
-
install-rb-default: pre-install-rb-default
|
165
|
-
pre-install-rb: Makefile
|
166
|
-
pre-install-rb-default: Makefile
|
167
|
-
pre-install-rb-default:
|
168
|
-
$(ECHO) installing default scrypt_ext libraries
|
169
|
-
$(RUBYARCHDIR):
|
170
|
-
$(Q) $(MAKEDIRS) $@
|
171
|
-
|
172
|
-
site-install: site-install-so site-install-rb
|
173
|
-
site-install-so: install-so
|
174
|
-
site-install-rb: install-rb
|
175
|
-
|
176
|
-
.SUFFIXES: .c .m .cc .mm .cxx .cpp .C .o
|
177
|
-
|
178
|
-
.cc.o:
|
179
|
-
$(ECHO) compiling $(<)
|
180
|
-
$(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $<
|
181
|
-
|
182
|
-
.mm.o:
|
183
|
-
$(ECHO) compiling $(<)
|
184
|
-
$(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $<
|
185
|
-
|
186
|
-
.cxx.o:
|
187
|
-
$(ECHO) compiling $(<)
|
188
|
-
$(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $<
|
189
|
-
|
190
|
-
.cpp.o:
|
191
|
-
$(ECHO) compiling $(<)
|
192
|
-
$(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $<
|
193
|
-
|
194
|
-
.C.o:
|
195
|
-
$(ECHO) compiling $(<)
|
196
|
-
$(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $<
|
197
|
-
|
198
|
-
.c.o:
|
199
|
-
$(ECHO) compiling $(<)
|
200
|
-
$(Q) $(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) $(COUTFLAG)$@ -c $<
|
201
|
-
|
202
|
-
.m.o:
|
203
|
-
$(ECHO) compiling $(<)
|
204
|
-
$(Q) $(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) $(COUTFLAG)$@ -c $<
|
205
|
-
|
206
|
-
$(DLLIB): $(OBJS) Makefile
|
207
|
-
$(ECHO) linking shared-object $(DLLIB)
|
208
|
-
@-$(RM) $(@)
|
209
|
-
$(Q) $(LDSHARED) -o $@ $(OBJS) $(LIBPATH) $(DLDFLAGS) $(LOCAL_LIBS) $(LIBS)
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
$(OBJS): $(hdrdir)/ruby.h $(hdrdir)/ruby/defines.h $(arch_hdrdir)/ruby/config.h
|