scrypt 1.1.0 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 37b02ce17f2d7078339e92e73b2d6da477aba40f
4
+ data.tar.gz: ec79a618486939f6c3c9ded0f0cd6428e1d68d5c
5
+ SHA512:
6
+ metadata.gz: b8ef5ea97a96bad661a81c648529ed1c3c56d88224ad4dfd68f7e2dc74c7b518bea4b29a5aa72e80d43df5eff7e4e48509133a00ef5099e043e8517c93ec14fd
7
+ data.tar.gz: 334eea1f45c403d2af6d73920ad63217e2772b1dc1ef1ccce58338648d6345aca167b0097fe27ee2678bfa35ef3e69da30c5539fa7c2c1e9410ee40ecc781505
data/README.md CHANGED
@@ -23,22 +23,15 @@ gem install scrypt
23
23
  It works pretty similarly to ruby-bcrypt with a few minor differences, especially where the cost factor is concerned.
24
24
 
25
25
  ```ruby
26
- include "scrypt"
26
+ require "scrypt"
27
27
 
28
28
  # hash a user's password
29
- @password = Password.create("my grand secret")
30
- @password #=> "2000$8$1$f5f2fa5fe5484a7091f1299768fbe92b5a7fbc77$6a385f22c54d92c314b71a4fd5ef33967c93d679"
29
+ @password = SCrypt::Password.create("my grand secret")
30
+ # => "400$8$36$78f4ae6983f76119$37ec6ce55a2b928dc56ff9a7d0cdafbd7dbde49d9282c38a40b1434e88f24cf5"
31
31
 
32
- # store it safely
33
- @user.update_attribute(:password, @password)
34
-
35
- # read it back
36
- @user.reload!
37
- @db_password = Password.new(@user.password)
38
-
39
- # compare it after retrieval
40
- @db_password == "my grand secret" #=> true
41
- @db_password == "a paltry guess" #=> false
32
+ # compare to strings
33
+ @password == "my grand secret" # => true
34
+ @password == "a paltry guess" # => false
42
35
  ```
43
36
 
44
37
  Password.create takes five options which will determine the key length and salt size, as well as the cost limits of the computation:
@@ -50,3 +43,30 @@ Password.create takes five options which will determine the key length and salt
50
43
  * `: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.
51
44
 
52
45
  Default options will result in calculation time of approx. 200 ms with 1 MB memory use.
46
+
47
+ ## Other things you can do
48
+
49
+ ```ruby
50
+ require "scrypt"
51
+
52
+ SCrypt::Engine.calibrate
53
+ # => "400$8$25$"
54
+
55
+ salt = SCrypt::Engine.generate_salt
56
+ # => "400$8$26$b62e0f787a5fc373"
57
+
58
+ SCrypt::Engine.hash_secret "my grand secret", salt
59
+ # => "400$8$26$b62e0f787a5fc373$0399ccd4fa26642d92741b17c366b7f6bd12ccea5214987af445d2bed97bc6a2"
60
+ ```
61
+
62
+ ## Usage in Rails (and the like)
63
+
64
+ ```ruby
65
+ # store it safely in the user model
66
+ @user.update_attribute(:password, @password)
67
+
68
+ # read it back later
69
+ @user.reload!
70
+ @password = SCrypt::Password.new(@user.password)
71
+ @password == "my grand secret" # => true
72
+ ```
data/Rakefile CHANGED
@@ -1,13 +1,39 @@
1
- require 'bundler'
2
- Bundler::GemHelper.install_tasks
1
+ require 'bundler/setup'
2
+ require 'bundler/gem_tasks'
3
3
 
4
4
  require 'rake'
5
5
  require 'rake/clean'
6
- require 'rdoc/task'
6
+
7
7
  require 'rspec/core/rake_task'
8
8
 
9
- task :default => [:compile, :spec]
9
+ require 'ffi'
10
+ require 'ffi-compiler/compile_task'
11
+
12
+ require 'rubygems'
13
+ require 'rubygems/package_task'
14
+
15
+ require 'rdoc/task'
16
+
17
+ task :default => [:clean, :compile_ffi, :spec]
10
18
 
19
+ desc "clean, make and run specs"
20
+ task :spec do
21
+ RSpec::Core::RakeTask.new
22
+ end
23
+
24
+ desc "FFI compiler"
25
+ namespace "ffi-compiler" do
26
+ FFI::Compiler::CompileTask.new('ext/scrypt/scrypt_ext') do |t|
27
+ t.cflags << "-Wall -msse -msse2"
28
+ t.cflags << "-D_GNU_SOURCE=1" if RbConfig::CONFIG["host_os"].downcase =~ /mingw/
29
+ t.cflags << "-arch x86_64 -arch i386" if t.platform.mac?
30
+ t.ldflags << "-arch x86_64 -arch i386" if t.platform.mac?
31
+ end
32
+ end
33
+ task :compile_ffi => ["ffi-compiler:default"]
34
+
35
+ CLEAN.include('ext/scrypt/*{.o,.log,.so,.bundle}')
36
+ CLEAN.include('lib/**/*{.o,.log,.so,.bundle}')
11
37
 
12
38
  desc 'Generate RDoc'
13
39
  rd = Rake::RDocTask.new do |rdoc|
@@ -23,20 +49,14 @@ RSpec::Core::RakeTask.new do |t|
23
49
  rspec_opts = ['--colour','--backtrace']
24
50
  end
25
51
 
52
+ def gem_spec
53
+ @gem_spec ||= Gem::Specification.load('scrypt.gemspec')
54
+ end
26
55
 
27
- desc "Clean native extension build files."
28
- task :clean do
29
- Dir.chdir('ext/mri') do
30
- ruby "extconf.rb"
31
- sh "make clean"
32
- end
56
+ Gem::PackageTask.new(gem_spec) do |pkg|
57
+ pkg.need_zip = true
58
+ pkg.need_tar = true
59
+ pkg.package_dir = 'pkg'
33
60
  end
34
61
 
35
62
 
36
- desc "Compile the native extension."
37
- task :compile do
38
- Dir.chdir('ext/mri') do
39
- ruby "extconf.rb"
40
- sh "make"
41
- end
42
- end
@@ -0,0 +1,9 @@
1
+ require 'ffi-compiler/compile_task'
2
+
3
+ FFI::Compiler::CompileTask.new('scrypt_ext') do |t|
4
+ t.cflags << "-Wall -msse -msse2"
5
+ t.cflags << "-D_GNU_SOURCE=1" if RbConfig::CONFIG["host_os"].downcase =~ /mingw/
6
+ t.cflags << "-arch x86_64 -arch i386" if t.platform.mac?
7
+ t.ldflags << "-arch x86_64 -arch i386" if t.platform.mac?
8
+ t.export '../../lib/scrypt/scrypt_ext.rb'
9
+ end
@@ -262,13 +262,14 @@ smix(uint8_t * B, size_t r, uint64_t N, void * V, void * XY)
262
262
  */
263
263
  int
264
264
  crypto_scrypt(const uint8_t * passwd, size_t passwdlen,
265
- const uint8_t * salt, size_t saltlen, uint64_t N, uint32_t r, uint32_t p,
265
+ const uint8_t * salt, size_t saltlen, uint64_t N, uint32_t _r, uint32_t _p,
266
266
  uint8_t * buf, size_t buflen)
267
267
  {
268
268
  void * B0, * V0, * XY0;
269
269
  uint8_t * B;
270
270
  uint32_t * V;
271
271
  uint32_t * XY;
272
+ size_t r = _r, p = _p;
272
273
  uint32_t i;
273
274
 
274
275
  /* Sanity-check parameters. */
@@ -282,7 +283,7 @@ crypto_scrypt(const uint8_t * passwd, size_t passwdlen,
282
283
  errno = EFBIG;
283
284
  goto err0;
284
285
  }
285
- if (((N & (N - 1)) != 0) || (N == 0)) {
286
+ if (((N & (N - 1)) != 0) || (N < 2)) {
286
287
  errno = EINVAL;
287
288
  goto err0;
288
289
  }
@@ -40,6 +40,7 @@
40
40
  *
41
41
  * Return 0 on success; or -1 on error.
42
42
  */
43
- int crypto_scrypt(const uint8_t *, size_t, const uint8_t *, size_t, uint64_t, uint32_t, uint32_t, uint8_t *, size_t);
43
+ int crypto_scrypt(const uint8_t *, size_t, const uint8_t *, size_t, uint64_t,
44
+ uint32_t, uint32_t, uint8_t *, size_t);
44
45
 
45
46
  #endif /* !_CRYPTO_SCRYPT_H_ */
File without changes
File without changes
File without changes
File without changes
@@ -0,0 +1,16 @@
1
+ #include "scrypt_ext.h"
2
+ #include "scrypt_calibrate.h"
3
+ #include "crypto_scrypt.h"
4
+
5
+
6
+ typedef struct {
7
+ uint64_t n;
8
+ uint32_t r;
9
+ uint32_t p;
10
+ } Calibration;
11
+
12
+
13
+ RBFFI_EXPORT int sc_calibrate(size_t maxmem, double maxmemfrac, double maxtime, Calibration *result)
14
+ {
15
+ return calibrate(maxmem, maxmemfrac, maxtime, &result->n, &result->r, &result->p); // 0 == success
16
+ }
@@ -0,0 +1,13 @@
1
+ #ifndef SCRYPT_EXT_H
2
+ #define SCRYPT_EXT_H 1
3
+
4
+ #ifndef RBFFI_EXPORT
5
+ # ifdef __cplusplus
6
+ # define RBFFI_EXPORT extern "C"
7
+ # else
8
+ # define RBFFI_EXPORT
9
+ # endif
10
+ #endif
11
+
12
+
13
+ #endif /* SCRYPT_EXT_H */
File without changes
@@ -163,7 +163,7 @@ scryptenc_cpuperf(double * opps)
163
163
  break;
164
164
  } while (1);
165
165
 
166
- /* Could how many scryps we can do before the next tick. */
166
+ /* Count how many scrypts we can do before the next tick. */
167
167
  if (getclocktime(&st))
168
168
  return (2);
169
169
  do {
File without changes
File without changes
File without changes
File without changes
data/lib/scrypt.rb CHANGED
@@ -1,13 +1,19 @@
1
1
  # A wrapper for the scrypt algorithm.
2
2
 
3
- $LOAD_PATH.unshift(File.expand_path(File.join(File.dirname(__FILE__), "..", "ext", "mri")))
4
- require "scrypt_ext"
3
+ require "scrypt/scrypt_ext"
5
4
  require "openssl"
6
5
  require "scanf"
6
+ require "ffi"
7
7
 
8
8
 
9
9
  module SCrypt
10
10
 
11
+ module Ext
12
+ # Bind the external functions
13
+ attach_function :sc_calibrate, [:size_t, :double, :double, :pointer], :int, :blocking => true
14
+ attach_function :crypto_scrypt, [:pointer, :size_t, :pointer, :size_t, :uint64, :uint32, :uint32, :pointer, :size_t], :int, :blocking => true # todo
15
+ end
16
+
11
17
  module Errors
12
18
  class InvalidSalt < StandardError; end # The salt parameter provided is invalid.
13
19
  class InvalidHash < StandardError; end # The hash parameter provided is invalid.
@@ -23,9 +29,6 @@ module SCrypt
23
29
  :max_time => 0.2
24
30
  }
25
31
 
26
- private_class_method :__sc_calibrate
27
- private_class_method :__sc_crypt
28
-
29
32
  def self.scrypt(secret, salt, *args)
30
33
  if args.length == 2
31
34
  # args is [cost_string, key_len]
@@ -118,6 +121,48 @@ module SCrypt
118
121
  def self.autodetect_cost(salt)
119
122
  salt[/^[0-9a-z]+\$[0-9a-z]+\$[0-9a-z]+\$/]
120
123
  end
124
+
125
+ private
126
+
127
+ class Calibration < FFI::Struct
128
+ layout :n, :uint64,
129
+ :r, :uint32,
130
+ :p, :uint32
131
+ end
132
+
133
+ def self.__sc_calibrate(max_mem, max_memfrac, max_time)
134
+ result = nil
135
+
136
+ calibration = Calibration.new
137
+ retval = SCrypt::Ext.sc_calibrate(max_mem, max_memfrac, max_time, calibration)
138
+
139
+ if retval == 0
140
+ result = [calibration[:n], calibration[:r], calibration[:p]]
141
+ else
142
+ raise "calibration error #{result}"
143
+ end
144
+
145
+ result
146
+ end
147
+
148
+ def self.__sc_crypt(secret, salt, n, r, p, key_len)
149
+ result = nil
150
+
151
+ FFI::MemoryPointer.new(:char, key_len) do |buffer|
152
+ retval = SCrypt::Ext.crypto_scrypt(
153
+ secret, secret.length, salt, salt.length,
154
+ n, r, p,
155
+ buffer, key_len
156
+ )
157
+ if retval == 0
158
+ result = buffer.read_string(key_len)
159
+ else
160
+ raise "scrypt error #{retval}"
161
+ end
162
+ end
163
+
164
+ result
165
+ end
121
166
  end
122
167
 
123
168
  # A password management class which allows you to safely store users' passwords and compare them.
@@ -0,0 +1,9 @@
1
+ require 'ffi'
2
+ require 'ffi-compiler/loader'
3
+
4
+ module SCrypt
5
+ module Ext
6
+ extend FFI::Library
7
+ ffi_lib FFI::Compiler::Loader.find('scrypt_ext')
8
+ end
9
+ end
@@ -1,3 +1,3 @@
1
1
  module SCrypt
2
- VERSION = "1.1.0"
2
+ VERSION = "1.2.0"
3
3
  end
data/scrypt.gemspec CHANGED
@@ -5,7 +5,6 @@ require "scrypt/version"
5
5
  Gem::Specification.new do |s|
6
6
  s.name = "scrypt"
7
7
  s.version = SCrypt::VERSION
8
- s.platform = Gem::Platform::RUBY
9
8
  s.authors = ["Patrick Hogan"]
10
9
  s.email = ["pbhogan@gmail.com"]
11
10
  s.homepage = ""
@@ -16,17 +15,18 @@ Gem::Specification.new do |s|
16
15
  alternative functions such as PBKDF2 or bcrypt.
17
16
  EOF
18
17
 
18
+ s.add_dependency 'ffi-compiler', '>= 0.0.2'
19
+ s.add_dependency 'rake'
19
20
  s.add_development_dependency "rspec"
20
21
  s.add_development_dependency "rdoc"
21
- s.add_development_dependency "rake", "~> 0.9.2"
22
22
  s.add_development_dependency "awesome_print"
23
23
 
24
24
  s.rubyforge_project = "scrypt"
25
25
 
26
- s.extensions = ["ext/mri/extconf.rb"]
26
+ s.extensions = ["ext/scrypt/Rakefile"]
27
27
 
28
- s.files = `git ls-files`.split("\n")
29
- s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
30
- s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
28
+ s.files = %w(Rakefile scrypt.gemspec README.md COPYING) + Dir.glob("{lib,spec,autotest}/**/*")
29
+ s.files += Dir.glob("ext/scrypt/*")
30
+ s.test_files = Dir.glob("spec/**/*")
31
31
  s.require_paths = ["lib"]
32
32
  end
@@ -47,8 +47,8 @@ describe "Generating SCrypt hashes" do
47
47
 
48
48
  it "should raise an InvalidSecret error if the secret is invalid" do
49
49
  lambda { SCrypt::Engine.hash_secret(MyInvalidSecret.new, @salt) }.should raise_error(SCrypt::Errors::InvalidSecret)
50
- lambda { SCrypt::Engine.hash_secret(nil, @salt) }.should_not raise_error(SCrypt::Errors::InvalidSecret)
51
- lambda { SCrypt::Engine.hash_secret(false, @salt) }.should_not raise_error(SCrypt::Errors::InvalidSecret)
50
+ lambda { SCrypt::Engine.hash_secret(nil, @salt) }.should_not raise_error
51
+ lambda { SCrypt::Engine.hash_secret(false, @salt) }.should_not raise_error
52
52
  end
53
53
 
54
54
  it "should call #to_s on the secret and use the return value as the actual secret data" do
@@ -14,9 +14,9 @@ describe "Creating a hashed password" do
14
14
  end
15
15
 
16
16
  it "should behave normally if the secret is not a string" do
17
- lambda { SCrypt::Password.create(nil) }.should_not raise_error(SCrypt::Errors::InvalidSecret)
18
- lambda { SCrypt::Password.create({:woo => "yeah"}) }.should_not raise_error(SCrypt::Errors::InvalidSecret)
19
- lambda { SCrypt::Password.create(false) }.should_not raise_error(SCrypt::Errors::InvalidSecret)
17
+ lambda { SCrypt::Password.create(nil) }.should_not raise_error
18
+ lambda { SCrypt::Password.create({:woo => "yeah"}) }.should_not raise_error
19
+ lambda { SCrypt::Password.create(false) }.should_not raise_error
20
20
  end
21
21
 
22
22
  it "should tolerate empty string secrets" do
metadata CHANGED
@@ -1,152 +1,144 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: scrypt
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
5
- prerelease:
4
+ version: 1.2.0
6
5
  platform: ruby
7
6
  authors:
8
7
  - Patrick Hogan
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2012-05-07 00:00:00.000000000 Z
11
+ date: 2013-07-10 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
- name: rspec
14
+ name: ffi-compiler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '>='
18
+ - !ruby/object:Gem::Version
19
+ version: 0.0.2
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '>='
25
+ - !ruby/object:Gem::Version
26
+ version: 0.0.2
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
16
29
  requirement: !ruby/object:Gem::Requirement
17
- none: false
18
30
  requirements:
19
- - - ! '>='
31
+ - - '>='
20
32
  - !ruby/object:Gem::Version
21
33
  version: '0'
22
- type: :development
34
+ type: :runtime
23
35
  prerelease: false
24
36
  version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
37
  requirements:
27
- - - ! '>='
38
+ - - '>='
28
39
  - !ruby/object:Gem::Version
29
40
  version: '0'
30
41
  - !ruby/object:Gem::Dependency
31
- name: rdoc
42
+ name: rspec
32
43
  requirement: !ruby/object:Gem::Requirement
33
- none: false
34
44
  requirements:
35
- - - ! '>='
45
+ - - '>='
36
46
  - !ruby/object:Gem::Version
37
47
  version: '0'
38
48
  type: :development
39
49
  prerelease: false
40
50
  version_requirements: !ruby/object:Gem::Requirement
41
- none: false
42
51
  requirements:
43
- - - ! '>='
52
+ - - '>='
44
53
  - !ruby/object:Gem::Version
45
54
  version: '0'
46
55
  - !ruby/object:Gem::Dependency
47
- name: rake
56
+ name: rdoc
48
57
  requirement: !ruby/object:Gem::Requirement
49
- none: false
50
58
  requirements:
51
- - - ~>
59
+ - - '>='
52
60
  - !ruby/object:Gem::Version
53
- version: 0.9.2
61
+ version: '0'
54
62
  type: :development
55
63
  prerelease: false
56
64
  version_requirements: !ruby/object:Gem::Requirement
57
- none: false
58
65
  requirements:
59
- - - ~>
66
+ - - '>='
60
67
  - !ruby/object:Gem::Version
61
- version: 0.9.2
68
+ version: '0'
62
69
  - !ruby/object:Gem::Dependency
63
70
  name: awesome_print
64
71
  requirement: !ruby/object:Gem::Requirement
65
- none: false
66
72
  requirements:
67
- - - ! '>='
73
+ - - '>='
68
74
  - !ruby/object:Gem::Version
69
75
  version: '0'
70
76
  type: :development
71
77
  prerelease: false
72
78
  version_requirements: !ruby/object:Gem::Requirement
73
- none: false
74
79
  requirements:
75
- - - ! '>='
80
+ - - '>='
76
81
  - !ruby/object:Gem::Version
77
82
  version: '0'
78
- description: ! " The scrypt key derivation function is designed to be far\n more
79
- secure against hardware brute-force attacks than\n alternative functions such
80
- as PBKDF2 or bcrypt.\n"
83
+ description: |2
84
+ The scrypt key derivation function is designed to be far
85
+ more secure against hardware brute-force attacks than
86
+ alternative functions such as PBKDF2 or bcrypt.
81
87
  email:
82
88
  - pbhogan@gmail.com
83
89
  executables: []
84
90
  extensions:
85
- - ext/mri/extconf.rb
91
+ - ext/scrypt/Rakefile
86
92
  extra_rdoc_files: []
87
93
  files:
88
- - .gitignore
89
- - .rspec
90
- - .rvmrc
91
- - .travis.yml
92
- - COPYING
93
- - Gemfile
94
- - Gemfile.lock
95
- - README.md
96
94
  - Rakefile
97
- - autotest/discover.rb
98
- - ext/mri/alt-impl/crypto_scrypt-nosse.c
99
- - ext/mri/alt-impl/crypto_scrypt-ref.c
100
- - ext/mri/crypto_scrypt-sse.c
101
- - ext/mri/crypto_scrypt.h
102
- - ext/mri/extconf.rb
103
- - ext/mri/memlimit.c
104
- - ext/mri/memlimit.h
105
- - ext/mri/scrypt_calibrate.c
106
- - ext/mri/scrypt_calibrate.h
107
- - ext/mri/scrypt_ext.c
108
- - ext/mri/scrypt_platform.h
109
- - ext/mri/scryptenc_cpuperf.c
110
- - ext/mri/scryptenc_cpuperf.h
111
- - ext/mri/sha256.c
112
- - ext/mri/sha256.h
113
- - ext/mri/sysendian.h
114
- - kdf-comparison.png
115
- - lib/scrypt.rb
116
- - lib/scrypt/version.rb
117
95
  - scrypt.gemspec
96
+ - README.md
97
+ - COPYING
98
+ - lib/scrypt/scrypt_ext.rb
99
+ - lib/scrypt/version.rb
100
+ - lib/scrypt.rb
118
101
  - spec/scrypt/engine_spec.rb
119
102
  - spec/scrypt/password_spec.rb
120
103
  - spec/spec_helper.rb
104
+ - autotest/discover.rb
105
+ - ext/scrypt/Rakefile
106
+ - ext/scrypt/crypto_scrypt-sse.c
107
+ - ext/scrypt/crypto_scrypt.h
108
+ - ext/scrypt/memlimit.c
109
+ - ext/scrypt/memlimit.h
110
+ - ext/scrypt/scrypt_calibrate.c
111
+ - ext/scrypt/scrypt_calibrate.h
112
+ - ext/scrypt/scrypt_ext.c
113
+ - ext/scrypt/scrypt_ext.h
114
+ - ext/scrypt/scrypt_platform.h
115
+ - ext/scrypt/scryptenc_cpuperf.c
116
+ - ext/scrypt/scryptenc_cpuperf.h
117
+ - ext/scrypt/sha256.c
118
+ - ext/scrypt/sha256.h
119
+ - ext/scrypt/sysendian.h
121
120
  homepage: ''
122
121
  licenses: []
122
+ metadata: {}
123
123
  post_install_message:
124
124
  rdoc_options: []
125
125
  require_paths:
126
126
  - lib
127
127
  required_ruby_version: !ruby/object:Gem::Requirement
128
- none: false
129
128
  requirements:
130
- - - ! '>='
129
+ - - '>='
131
130
  - !ruby/object:Gem::Version
132
131
  version: '0'
133
- segments:
134
- - 0
135
- hash: -214930008180539210
136
132
  required_rubygems_version: !ruby/object:Gem::Requirement
137
- none: false
138
133
  requirements:
139
- - - ! '>='
134
+ - - '>='
140
135
  - !ruby/object:Gem::Version
141
136
  version: '0'
142
- segments:
143
- - 0
144
- hash: -214930008180539210
145
137
  requirements: []
146
138
  rubyforge_project: scrypt
147
- rubygems_version: 1.8.21
139
+ rubygems_version: 2.0.3
148
140
  signing_key:
149
- specification_version: 3
141
+ specification_version: 4
150
142
  summary: scrypt password hashing algorithm.
151
143
  test_files:
152
144
  - spec/scrypt/engine_spec.rb