scrypt 1.1.0 → 1.2.0

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