bcrypt 3.1.12.rc1-java → 3.1.13-java
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 +5 -5
- data/.travis.yml +3 -7
- data/CHANGELOG +7 -1
- data/Gemfile.lock +15 -22
- data/README.md +17 -15
- data/Rakefile +0 -27
- data/appveyor.yml +32 -32
- data/bcrypt.gemspec +1 -3
- data/ext/jruby/bcrypt_jruby/BCrypt.java +524 -351
- data/ext/mri/crypt.h +12 -1
- data/ext/mri/crypt_blowfish.c +265 -144
- data/ext/mri/crypt_blowfish.h +27 -0
- data/ext/mri/crypt_gensalt.c +26 -13
- data/ext/mri/crypt_gensalt.h +30 -0
- data/ext/mri/extconf.rb +6 -0
- data/ext/mri/ow-crypt.h +25 -17
- data/ext/mri/wrapper.c +335 -46
- data/ext/mri/x86.S +203 -0
- data/lib/bcrypt.rb +1 -6
- data/lib/bcrypt/engine.rb +4 -4
- data/lib/bcrypt/password.rb +1 -1
- data/spec/bcrypt/engine_spec.rb +67 -2
- metadata +8 -19
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 0bd5616d754e03fe144d085dffe050b0b92de6206b0526c9bc20bc1d0d69fcd0
|
4
|
+
data.tar.gz: b420a4969f5d7862d601b2f1d2b5acb158c9d22d439ee5fdc40c5784815ad83e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ff5e5ad69d1a78cecd2e4950bd0bfc1c55b5d191097c15e96abba0f1c035bac78f74d6cca5de18457c5d1f6c3f4b836d40273c34f6d45ed07a1b2e5a201db2e7
|
7
|
+
data.tar.gz: '048c3a769830708eea582929f505296c40f6cb2ee84af35f8766c693ec234195186eab21d05c79d983499b91479e9eb31247e2a49f6c65595114c4856797d843'
|
data/.travis.yml
CHANGED
@@ -1,10 +1,9 @@
|
|
1
1
|
language: ruby
|
2
2
|
before_install:
|
3
|
-
- gem
|
4
|
-
- gem
|
3
|
+
- "echo 'gem: --no-rdoc --no-ri' > ~/.gemrc"
|
4
|
+
- gem update --system 2.7.8
|
5
|
+
- gem install bundler -v 1.17.3
|
5
6
|
rvm:
|
6
|
-
- 1.8
|
7
|
-
- 1.9
|
8
7
|
- 2.0
|
9
8
|
- 2.1
|
10
9
|
- 2.2
|
@@ -13,9 +12,6 @@ rvm:
|
|
13
12
|
- 2.5
|
14
13
|
- 2.6
|
15
14
|
- ruby-head
|
16
|
-
- jruby-18mode
|
17
|
-
- jruby-19mode
|
18
15
|
- jruby-head
|
19
16
|
- rbx-3
|
20
|
-
- ree
|
21
17
|
script: bundle exec rake
|
data/CHANGELOG
CHANGED
@@ -83,6 +83,12 @@
|
|
83
83
|
3.1.11 Mar 06 2016
|
84
84
|
- Add support for Ruby 2.2 in compiled Windows binaries
|
85
85
|
|
86
|
-
3.1.12 May
|
86
|
+
3.1.12 May 16 2018
|
87
87
|
- Add support for Ruby 2.3, 2.4, and 2.5 in compiled Windows binaries
|
88
88
|
- Fix compatibility with libxcrypt [GH #164 by @besser82]
|
89
|
+
|
90
|
+
[DRAFT] 4.0.0 MMM DD YYYY
|
91
|
+
- No longer include compiled binaries for Windows. See GH #173.
|
92
|
+
- Update C and Java implementations to latest versions [GH #182 by @fonica]
|
93
|
+
- Bump default cost to 12 [GH #181 by @bdewater]
|
94
|
+
- Remove explicit support for Rubies 1.8 and 1.9
|
data/Gemfile.lock
CHANGED
@@ -1,43 +1,36 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
bcrypt (3.1.
|
4
|
+
bcrypt (3.1.13)
|
5
5
|
|
6
6
|
GEM
|
7
7
|
remote: https://rubygems.org/
|
8
8
|
specs:
|
9
|
-
diff-lcs (1.
|
10
|
-
|
11
|
-
|
12
|
-
rake (10.4.2)
|
13
|
-
rake-compiler (0.9.5)
|
9
|
+
diff-lcs (1.3)
|
10
|
+
rake (12.3.2)
|
11
|
+
rake-compiler (0.9.9)
|
14
12
|
rake
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
rspec-
|
19
|
-
|
20
|
-
rspec-
|
21
|
-
rspec-
|
22
|
-
rspec-support (~> 3.3.0)
|
23
|
-
rspec-expectations (3.3.1)
|
13
|
+
rspec (3.8.0)
|
14
|
+
rspec-core (~> 3.8.0)
|
15
|
+
rspec-expectations (~> 3.8.0)
|
16
|
+
rspec-mocks (~> 3.8.0)
|
17
|
+
rspec-core (3.8.0)
|
18
|
+
rspec-support (~> 3.8.0)
|
19
|
+
rspec-expectations (3.8.3)
|
24
20
|
diff-lcs (>= 1.2.0, < 2.0)
|
25
|
-
rspec-support (~> 3.
|
26
|
-
rspec-mocks (3.
|
21
|
+
rspec-support (~> 3.8.0)
|
22
|
+
rspec-mocks (3.8.0)
|
27
23
|
diff-lcs (>= 1.2.0, < 2.0)
|
28
|
-
rspec-support (~> 3.
|
29
|
-
rspec-support (3.
|
24
|
+
rspec-support (~> 3.8.0)
|
25
|
+
rspec-support (3.8.0)
|
30
26
|
|
31
27
|
PLATFORMS
|
32
28
|
java
|
33
29
|
ruby
|
34
|
-
x64-mingw32
|
35
|
-
x86-mingw32
|
36
30
|
|
37
31
|
DEPENDENCIES
|
38
32
|
bcrypt!
|
39
33
|
rake-compiler (~> 0.9.2)
|
40
|
-
rdoc (~> 3.12)
|
41
34
|
rspec (>= 3)
|
42
35
|
|
43
36
|
BUNDLED WITH
|
data/README.md
CHANGED
@@ -2,9 +2,11 @@
|
|
2
2
|
|
3
3
|
An easy way to keep your users' passwords secure.
|
4
4
|
|
5
|
-
*
|
5
|
+
* https://github.com/codahale/bcrypt-ruby/tree/master
|
6
|
+
|
7
|
+
[](https://travis-ci.org/codahale/bcrypt-ruby)
|
8
|
+
[](https://ci.appveyor.com/project/TJSchuck35975/bcrypt-ruby)
|
6
9
|
|
7
|
-
[](https://travis-ci.org/codahale/bcrypt-ruby)
|
8
10
|
|
9
11
|
## Why you should use `bcrypt()`
|
10
12
|
|
@@ -18,7 +20,7 @@ security experts is not a professional response to risk.
|
|
18
20
|
`bcrypt()` allows you to easily harden your application against these kinds of attacks.
|
19
21
|
|
20
22
|
*Note*: JRuby versions of the bcrypt gem `<= 2.1.3` had a [security
|
21
|
-
vulnerability](
|
23
|
+
vulnerability](https://www.mindrot.org/files/jBCrypt/internat.adv) that
|
22
24
|
was fixed in `>= 2.1.4`. If you used a vulnerable version to hash
|
23
25
|
passwords with international characters in them, you will need to
|
24
26
|
re-hash those passwords. This vulnerability only affected the JRuby gem.
|
@@ -27,16 +29,16 @@ re-hash those passwords. This vulnerability only affected the JRuby gem.
|
|
27
29
|
|
28
30
|
gem install bcrypt
|
29
31
|
|
30
|
-
The bcrypt gem is available on the following
|
32
|
+
The bcrypt gem is available on the following Ruby platforms:
|
31
33
|
|
32
34
|
* JRuby
|
33
|
-
* RubyInstaller
|
34
|
-
* Any
|
35
|
+
* RubyInstaller 2.0 – 2.5 builds on Windows with the DevKit
|
36
|
+
* Any 2.0 – 2.5 Ruby on a BSD/OS X/Linux system with a compiler
|
35
37
|
|
36
38
|
## How to use `bcrypt()` in your Rails application
|
37
39
|
|
38
40
|
*Note*: Rails versions >= 3 ship with `ActiveModel::SecurePassword` which uses bcrypt-ruby.
|
39
|
-
`has_secure_password` [docs](
|
41
|
+
`has_secure_password` [docs](https://api.rubyonrails.org/classes/ActiveModel/SecurePassword/ClassMethods.html#method-i-has_secure_password)
|
40
42
|
implements a similar authentication strategy to the code below.
|
41
43
|
|
42
44
|
### The _User_ model
|
@@ -81,14 +83,14 @@ end
|
|
81
83
|
require 'bcrypt'
|
82
84
|
|
83
85
|
my_password = BCrypt::Password.create("my password")
|
84
|
-
#=> "$2a$
|
86
|
+
#=> "$2a$12$K0ByB.6YI2/OYrB4fQOYLe6Tv0datUVf6VZ/2Jzwm879BW5K1cHey"
|
85
87
|
|
86
88
|
my_password.version #=> "2a"
|
87
|
-
my_password.cost #=>
|
89
|
+
my_password.cost #=> 12
|
88
90
|
my_password == "my password" #=> true
|
89
91
|
my_password == "not my password" #=> false
|
90
92
|
|
91
|
-
my_password = BCrypt::Password.new("$2a$
|
93
|
+
my_password = BCrypt::Password.new("$2a$12$K0ByB.6YI2/OYrB4fQOYLe6Tv0datUVf6VZ/2Jzwm879BW5K1cHey")
|
92
94
|
my_password == "my password" #=> true
|
93
95
|
my_password == "not my password" #=> false
|
94
96
|
```
|
@@ -155,14 +157,14 @@ If an attacker was using Ruby to check each password, they could check ~140,000
|
|
155
157
|
In addition, `bcrypt()` allows you to increase the amount of work required to hash a password as computers get faster. Old
|
156
158
|
passwords will still work fine, but new passwords can keep up with the times.
|
157
159
|
|
158
|
-
The default cost factor used by bcrypt-ruby is
|
160
|
+
The default cost factor used by bcrypt-ruby is 12, which is fine for session-based authentication. If you are using a
|
159
161
|
stateless authentication architecture (e.g., HTTP Basic Auth), you will want to lower the cost factor to reduce your
|
160
162
|
server load and keep your request times down. This will lower the security provided you, but there are few alternatives.
|
161
163
|
|
162
164
|
To change the default cost factor used by bcrypt-ruby, use `BCrypt::Engine.cost = new_value`:
|
163
165
|
```ruby
|
164
166
|
BCrypt::Password.create('secret').cost
|
165
|
-
#=>
|
167
|
+
#=> 12, the default provided by bcrypt-ruby
|
166
168
|
|
167
169
|
# set a new default cost
|
168
170
|
BCrypt::Engine.cost = 8
|
@@ -180,13 +182,13 @@ system available.
|
|
180
182
|
|
181
183
|
For a more technical explanation of the algorithm and its design criteria, please read Niels Provos and David Mazières'
|
182
184
|
Usenix99 paper:
|
183
|
-
|
185
|
+
https://www.usenix.org/events/usenix99/provos.html
|
184
186
|
|
185
187
|
If you'd like more down-to-earth advice regarding cryptography, I suggest reading <i>Practical Cryptography</i> by Niels
|
186
188
|
Ferguson and Bruce Schneier:
|
187
|
-
|
189
|
+
https://www.schneier.com/book-practical.html
|
188
190
|
|
189
191
|
# Etc
|
190
192
|
|
191
193
|
* Author :: Coda Hale <coda.hale@gmail.com>
|
192
|
-
* Website ::
|
194
|
+
* Website :: https://codahale.com
|
data/Rakefile
CHANGED
@@ -8,14 +8,6 @@ require 'benchmark'
|
|
8
8
|
|
9
9
|
CLEAN.include(
|
10
10
|
"tmp",
|
11
|
-
"lib/1.8",
|
12
|
-
"lib/1.9",
|
13
|
-
"lib/2.0",
|
14
|
-
"lib/2.1",
|
15
|
-
"lib/2.2",
|
16
|
-
"lib/2.3",
|
17
|
-
"lib/2.4",
|
18
|
-
"lib/2.5",
|
19
11
|
"lib/bcrypt_ext.jar",
|
20
12
|
"lib/bcrypt_ext.so"
|
21
13
|
)
|
@@ -62,25 +54,6 @@ if RUBY_PLATFORM =~ /java/
|
|
62
54
|
else
|
63
55
|
Rake::ExtensionTask.new("bcrypt_ext", GEMSPEC) do |ext|
|
64
56
|
ext.ext_dir = 'ext/mri'
|
65
|
-
ext.cross_compile = true
|
66
|
-
ext.cross_platform = ['x86-mingw32', 'x64-mingw32']
|
67
|
-
end
|
68
|
-
|
69
|
-
ENV['RUBY_CC_VERSION'].to_s.split(':').each do |ruby_version|
|
70
|
-
platforms = {
|
71
|
-
"x86-mingw32" => "i686-w64-mingw32",
|
72
|
-
"x64-mingw32" => "x86_64-w64-mingw32"
|
73
|
-
}
|
74
|
-
platforms.each do |platform, prefix|
|
75
|
-
task "copy:bcrypt_ext:#{platform}:#{ruby_version}" do |t|
|
76
|
-
%w[lib tmp/#{platform}/stage/lib].each do |dir|
|
77
|
-
so_file = "#{dir}/#{ruby_version[/^\d+\.\d+/]}/bcrypt_ext.so"
|
78
|
-
if File.exists?(so_file)
|
79
|
-
sh "#{prefix}-strip -S #{so_file}"
|
80
|
-
end
|
81
|
-
end
|
82
|
-
end
|
83
|
-
end
|
84
57
|
end
|
85
58
|
end
|
86
59
|
|
data/appveyor.yml
CHANGED
@@ -1,50 +1,50 @@
|
|
1
|
-
###############################################################################
|
2
|
-
#
|
3
|
-
# This AppVeyor config is *NOT* for running the tests on Windows.
|
4
|
-
#
|
5
|
-
# This is to ensure that the latest version of the bcrypt gem can be installed
|
6
|
-
# on Windows across all of the currently supported versions of Ruby.
|
7
|
-
#
|
8
|
-
###############################################################################
|
9
|
-
|
10
1
|
version: "{branch}-{build}"
|
11
2
|
build: off
|
12
3
|
clone_depth: 1
|
13
4
|
|
14
5
|
init:
|
15
|
-
# Install Ruby
|
16
|
-
- if %RUBY_VERSION%==
|
17
|
-
appveyor DownloadFile https://
|
18
|
-
C:\
|
6
|
+
# Install Ruby head
|
7
|
+
- if %RUBY_VERSION%==head (
|
8
|
+
appveyor DownloadFile https://github.com/oneclick/rubyinstaller2/releases/download/rubyinstaller-head/rubyinstaller-head-x86.exe -FileName C:\head_x86.exe &
|
9
|
+
C:\head_x86.exe /verysilent /dir=C:\Ruby%RUBY_VERSION%
|
10
|
+
)
|
11
|
+
- if %RUBY_VERSION%==head-x64 (
|
12
|
+
appveyor DownloadFile https://github.com/oneclick/rubyinstaller2/releases/download/rubyinstaller-head/rubyinstaller-head-x64.exe -FileName C:\head_x64.exe &
|
13
|
+
C:\head_x64.exe /verysilent /dir=C:\Ruby%RUBY_VERSION%
|
19
14
|
)
|
20
15
|
|
16
|
+
# Add Ruby to the path
|
17
|
+
- set PATH=C:\Ruby%RUBY_VERSION%\bin;%PATH%
|
18
|
+
|
21
19
|
environment:
|
22
20
|
matrix:
|
23
|
-
- RUBY_VERSION: "
|
24
|
-
- RUBY_VERSION: "
|
25
|
-
- RUBY_VERSION: "200"
|
26
|
-
- RUBY_VERSION: "200-x64"
|
27
|
-
- RUBY_VERSION: "21"
|
28
|
-
- RUBY_VERSION: "21-x64"
|
29
|
-
- RUBY_VERSION: "22"
|
30
|
-
- RUBY_VERSION: "22-x64"
|
31
|
-
- RUBY_VERSION: "23"
|
32
|
-
- RUBY_VERSION: "23-x64"
|
33
|
-
- RUBY_VERSION: "24"
|
34
|
-
- RUBY_VERSION: "24-x64"
|
21
|
+
- RUBY_VERSION: "head"
|
22
|
+
- RUBY_VERSION: "head-x64"
|
35
23
|
- RUBY_VERSION: "25"
|
36
24
|
- RUBY_VERSION: "25-x64"
|
25
|
+
- RUBY_VERSION: "24"
|
26
|
+
- RUBY_VERSION: "24-x64"
|
27
|
+
- RUBY_VERSION: "23"
|
28
|
+
- RUBY_VERSION: "23-x64"
|
29
|
+
- RUBY_VERSION: "22"
|
30
|
+
- RUBY_VERSION: "22-x64"
|
31
|
+
- RUBY_VERSION: "21"
|
32
|
+
- RUBY_VERSION: "21-x64"
|
33
|
+
- RUBY_VERSION: "200"
|
34
|
+
- RUBY_VERSION: "200-x64"
|
37
35
|
|
38
36
|
install:
|
39
|
-
-
|
40
|
-
- if %RUBY_VERSION%==
|
41
|
-
|
42
|
-
|
37
|
+
- ps: "Set-Content -Value 'gem: --no-ri --no-rdoc ' -Path C:\\ProgramData\\gemrc"
|
38
|
+
- if %RUBY_VERSION%==head ( gem install bundler -v'< 2' )
|
39
|
+
- if %RUBY_VERSION%==head-x64 ( gem install bundler -v'< 2' )
|
40
|
+
- bundle install
|
43
41
|
|
44
|
-
|
42
|
+
before_build:
|
45
43
|
- ruby -v
|
46
44
|
- gem -v
|
47
45
|
|
46
|
+
build_script:
|
47
|
+
- bundle exec rake compile -rdevkit
|
48
|
+
|
48
49
|
test_script:
|
49
|
-
-
|
50
|
-
- ruby -e "require 'rubygems'; require 'bcrypt'"
|
50
|
+
- bundle exec rake spec
|
data/bcrypt.gemspec
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = 'bcrypt'
|
3
|
-
s.version = '3.1.
|
3
|
+
s.version = '3.1.13'
|
4
4
|
|
5
5
|
s.summary = "OpenBSD's bcrypt() password hashing algorithm."
|
6
6
|
s.description = <<-EOF
|
@@ -14,9 +14,7 @@ Gem::Specification.new do |s|
|
|
14
14
|
|
15
15
|
s.add_development_dependency 'rake-compiler', '~> 0.9.2'
|
16
16
|
s.add_development_dependency 'rspec', '>= 3'
|
17
|
-
s.add_development_dependency 'rdoc', '~> 3.12'
|
18
17
|
|
19
|
-
s.has_rdoc = true
|
20
18
|
s.rdoc_options += ['--title', 'bcrypt-ruby', '--line-numbers', '--inline-source', '--main', 'README.md']
|
21
19
|
s.extra_rdoc_files += ['README.md', 'COPYING', 'CHANGELOG', *Dir['lib/**/*.rb']]
|
22
20
|
|
@@ -11,11 +11,10 @@
|
|
11
11
|
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
12
12
|
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
13
13
|
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
14
|
-
|
15
14
|
package bcrypt_jruby;
|
16
15
|
|
17
16
|
import java.io.UnsupportedEncodingException;
|
18
|
-
|
17
|
+
import java.util.Arrays;
|
19
18
|
import java.security.SecureRandom;
|
20
19
|
|
21
20
|
/**
|
@@ -54,12 +53,12 @@ import java.security.SecureRandom;
|
|
54
53
|
* String stronger_salt = BCrypt.gensalt(12)<br />
|
55
54
|
* </code>
|
56
55
|
* <p>
|
57
|
-
* The amount of work increases exponentially (2**log_rounds), so
|
56
|
+
* The amount of work increases exponentially (2**log_rounds), so
|
58
57
|
* each increment is twice as much work. The default log_rounds is
|
59
58
|
* 10, and the valid range is 4 to 31.
|
60
59
|
*
|
61
60
|
* @author Damien Miller
|
62
|
-
* @version 0.
|
61
|
+
* @version 0.3
|
63
62
|
*/
|
64
63
|
public class BCrypt {
|
65
64
|
// BCrypt parameters
|
@@ -71,326 +70,328 @@ public class BCrypt {
|
|
71
70
|
|
72
71
|
// Initial contents of key schedule
|
73
72
|
private static final int P_orig[] = {
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
73
|
+
0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344,
|
74
|
+
0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89,
|
75
|
+
0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c,
|
76
|
+
0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917,
|
77
|
+
0x9216d5d9, 0x8979fb1b
|
79
78
|
};
|
80
79
|
private static final int S_orig[] = {
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
80
|
+
0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7,
|
81
|
+
0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99,
|
82
|
+
0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16,
|
83
|
+
0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e,
|
84
|
+
0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee,
|
85
|
+
0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013,
|
86
|
+
0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef,
|
87
|
+
0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e,
|
88
|
+
0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60,
|
89
|
+
0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440,
|
90
|
+
0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce,
|
91
|
+
0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a,
|
92
|
+
0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e,
|
93
|
+
0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677,
|
94
|
+
0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193,
|
95
|
+
0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032,
|
96
|
+
0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88,
|
97
|
+
0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239,
|
98
|
+
0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e,
|
99
|
+
0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0,
|
100
|
+
0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3,
|
101
|
+
0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98,
|
102
|
+
0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88,
|
103
|
+
0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe,
|
104
|
+
0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6,
|
105
|
+
0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d,
|
106
|
+
0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b,
|
107
|
+
0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7,
|
108
|
+
0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba,
|
109
|
+
0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463,
|
110
|
+
0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f,
|
111
|
+
0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09,
|
112
|
+
0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3,
|
113
|
+
0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb,
|
114
|
+
0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279,
|
115
|
+
0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8,
|
116
|
+
0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab,
|
117
|
+
0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82,
|
118
|
+
0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db,
|
119
|
+
0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573,
|
120
|
+
0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0,
|
121
|
+
0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b,
|
122
|
+
0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790,
|
123
|
+
0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8,
|
124
|
+
0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4,
|
125
|
+
0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0,
|
126
|
+
0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7,
|
127
|
+
0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c,
|
128
|
+
0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad,
|
129
|
+
0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1,
|
130
|
+
0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299,
|
131
|
+
0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9,
|
132
|
+
0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477,
|
133
|
+
0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf,
|
134
|
+
0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49,
|
135
|
+
0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af,
|
136
|
+
0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa,
|
137
|
+
0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5,
|
138
|
+
0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41,
|
139
|
+
0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915,
|
140
|
+
0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400,
|
141
|
+
0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915,
|
142
|
+
0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664,
|
143
|
+
0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a,
|
144
|
+
0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623,
|
145
|
+
0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266,
|
146
|
+
0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1,
|
147
|
+
0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e,
|
148
|
+
0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6,
|
149
|
+
0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1,
|
150
|
+
0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e,
|
151
|
+
0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1,
|
152
|
+
0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737,
|
153
|
+
0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8,
|
154
|
+
0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff,
|
155
|
+
0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd,
|
156
|
+
0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701,
|
157
|
+
0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7,
|
158
|
+
0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41,
|
159
|
+
0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331,
|
160
|
+
0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf,
|
161
|
+
0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af,
|
162
|
+
0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e,
|
163
|
+
0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87,
|
164
|
+
0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c,
|
165
|
+
0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2,
|
166
|
+
0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16,
|
167
|
+
0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd,
|
168
|
+
0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b,
|
169
|
+
0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509,
|
170
|
+
0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e,
|
171
|
+
0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3,
|
172
|
+
0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f,
|
173
|
+
0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a,
|
174
|
+
0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4,
|
175
|
+
0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960,
|
176
|
+
0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66,
|
177
|
+
0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28,
|
178
|
+
0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802,
|
179
|
+
0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84,
|
180
|
+
0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510,
|
181
|
+
0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf,
|
182
|
+
0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14,
|
183
|
+
0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e,
|
184
|
+
0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50,
|
185
|
+
0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7,
|
186
|
+
0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8,
|
187
|
+
0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281,
|
188
|
+
0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99,
|
189
|
+
0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696,
|
190
|
+
0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128,
|
191
|
+
0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73,
|
192
|
+
0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0,
|
193
|
+
0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0,
|
194
|
+
0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105,
|
195
|
+
0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250,
|
196
|
+
0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3,
|
197
|
+
0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285,
|
198
|
+
0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00,
|
199
|
+
0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061,
|
200
|
+
0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb,
|
201
|
+
0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e,
|
202
|
+
0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735,
|
203
|
+
0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc,
|
204
|
+
0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9,
|
205
|
+
0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340,
|
206
|
+
0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20,
|
207
|
+
0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7,
|
208
|
+
0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934,
|
209
|
+
0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068,
|
210
|
+
0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af,
|
211
|
+
0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840,
|
212
|
+
0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45,
|
213
|
+
0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504,
|
214
|
+
0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a,
|
215
|
+
0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb,
|
216
|
+
0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee,
|
217
|
+
0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6,
|
218
|
+
0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42,
|
219
|
+
0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b,
|
220
|
+
0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2,
|
221
|
+
0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb,
|
222
|
+
0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527,
|
223
|
+
0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b,
|
224
|
+
0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33,
|
225
|
+
0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c,
|
226
|
+
0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3,
|
227
|
+
0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc,
|
228
|
+
0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17,
|
229
|
+
0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564,
|
230
|
+
0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b,
|
231
|
+
0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115,
|
232
|
+
0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922,
|
233
|
+
0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728,
|
234
|
+
0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0,
|
235
|
+
0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e,
|
236
|
+
0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37,
|
237
|
+
0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d,
|
238
|
+
0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804,
|
239
|
+
0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b,
|
240
|
+
0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3,
|
241
|
+
0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb,
|
242
|
+
0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d,
|
243
|
+
0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c,
|
244
|
+
0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350,
|
245
|
+
0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9,
|
246
|
+
0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a,
|
247
|
+
0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe,
|
248
|
+
0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d,
|
249
|
+
0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc,
|
250
|
+
0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f,
|
251
|
+
0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61,
|
252
|
+
0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2,
|
253
|
+
0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9,
|
254
|
+
0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2,
|
255
|
+
0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c,
|
256
|
+
0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e,
|
257
|
+
0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633,
|
258
|
+
0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10,
|
259
|
+
0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169,
|
260
|
+
0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52,
|
261
|
+
0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027,
|
262
|
+
0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5,
|
263
|
+
0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62,
|
264
|
+
0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634,
|
265
|
+
0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76,
|
266
|
+
0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24,
|
267
|
+
0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc,
|
268
|
+
0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4,
|
269
|
+
0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c,
|
270
|
+
0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837,
|
271
|
+
0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0,
|
272
|
+
0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b,
|
273
|
+
0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe,
|
274
|
+
0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b,
|
275
|
+
0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4,
|
276
|
+
0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8,
|
277
|
+
0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6,
|
278
|
+
0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304,
|
279
|
+
0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22,
|
280
|
+
0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4,
|
281
|
+
0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6,
|
282
|
+
0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9,
|
283
|
+
0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59,
|
284
|
+
0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593,
|
285
|
+
0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51,
|
286
|
+
0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28,
|
287
|
+
0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c,
|
288
|
+
0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b,
|
289
|
+
0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28,
|
290
|
+
0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c,
|
291
|
+
0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd,
|
292
|
+
0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a,
|
293
|
+
0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319,
|
294
|
+
0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb,
|
295
|
+
0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f,
|
296
|
+
0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991,
|
297
|
+
0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32,
|
298
|
+
0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680,
|
299
|
+
0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166,
|
300
|
+
0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae,
|
301
|
+
0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb,
|
302
|
+
0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5,
|
303
|
+
0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47,
|
304
|
+
0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370,
|
305
|
+
0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d,
|
306
|
+
0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84,
|
307
|
+
0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048,
|
308
|
+
0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8,
|
309
|
+
0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd,
|
310
|
+
0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9,
|
311
|
+
0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7,
|
312
|
+
0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38,
|
313
|
+
0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f,
|
314
|
+
0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c,
|
315
|
+
0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525,
|
316
|
+
0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1,
|
317
|
+
0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442,
|
318
|
+
0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964,
|
319
|
+
0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e,
|
320
|
+
0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8,
|
321
|
+
0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d,
|
322
|
+
0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f,
|
323
|
+
0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299,
|
324
|
+
0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02,
|
325
|
+
0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc,
|
326
|
+
0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614,
|
327
|
+
0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a,
|
328
|
+
0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6,
|
329
|
+
0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b,
|
330
|
+
0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0,
|
331
|
+
0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060,
|
332
|
+
0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e,
|
333
|
+
0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9,
|
334
|
+
0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f,
|
335
|
+
0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6
|
337
336
|
};
|
338
337
|
|
339
338
|
// bcrypt IV: "OrpheanBeholderScryDoubt"
|
340
339
|
static private final int bf_crypt_ciphertext[] = {
|
341
|
-
|
342
|
-
|
340
|
+
0x4f727068, 0x65616e42, 0x65686f6c,
|
341
|
+
0x64657253, 0x63727944, 0x6f756274
|
343
342
|
};
|
344
343
|
|
345
344
|
// Table for Base64 encoding
|
346
345
|
static private final char base64_code[] = {
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
346
|
+
'.', '/', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
|
347
|
+
'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V',
|
348
|
+
'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
|
349
|
+
'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
|
350
|
+
'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5',
|
351
|
+
'6', '7', '8', '9'
|
353
352
|
};
|
354
353
|
|
355
354
|
// Table for Base64 decoding
|
356
355
|
static private final byte index_64[] = {
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
356
|
+
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
357
|
+
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
358
|
+
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
359
|
+
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
360
|
+
-1, -1, -1, -1, -1, -1, 0, 1, 54, 55,
|
361
|
+
56, 57, 58, 59, 60, 61, 62, 63, -1, -1,
|
362
|
+
-1, -1, -1, -1, -1, 2, 3, 4, 5, 6,
|
363
|
+
7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
|
364
|
+
17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,
|
365
|
+
-1, -1, -1, -1, -1, -1, 28, 29, 30,
|
366
|
+
31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
|
367
|
+
41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
|
368
|
+
51, 52, 53, -1, -1, -1, -1, -1
|
370
369
|
};
|
370
|
+
static final int MIN_LOG_ROUNDS = 4;
|
371
|
+
static final int MAX_LOG_ROUNDS = 31;
|
371
372
|
|
372
373
|
// Expanded Blowfish key
|
373
374
|
private int P[];
|
374
375
|
private int S[];
|
375
376
|
|
376
377
|
/**
|
377
|
-
* Encode a byte array using bcrypt's slightly-modified base64
|
378
|
-
*
|
379
|
-
*
|
378
|
+
* Encode a byte array using bcrypt's slightly-modified base64 encoding scheme. Note
|
379
|
+
* that this is <strong>not</strong> compatible with the standard MIME-base64
|
380
|
+
* encoding.
|
380
381
|
*
|
381
|
-
* @param d
|
382
|
-
* @param len
|
383
|
-
* @
|
382
|
+
* @param d the byte array to encode
|
383
|
+
* @param len the number of bytes to encode
|
384
|
+
* @param rs the destination buffer for the base64-encoded string
|
384
385
|
* @exception IllegalArgumentException if the length is invalid
|
385
386
|
*/
|
386
|
-
|
387
|
-
|
387
|
+
static void encode_base64(byte d[], int len, StringBuilder rs)
|
388
|
+
throws IllegalArgumentException {
|
388
389
|
int off = 0;
|
389
|
-
StringBuilder rs = new StringBuilder();
|
390
390
|
int c1, c2;
|
391
391
|
|
392
|
-
if (len <= 0 || len > d.length)
|
393
|
-
throw new IllegalArgumentException
|
392
|
+
if (len <= 0 || len > d.length) {
|
393
|
+
throw new IllegalArgumentException("Invalid len");
|
394
|
+
}
|
394
395
|
|
395
396
|
while (off < len) {
|
396
397
|
c1 = d[off++] & 0xff;
|
@@ -413,7 +414,6 @@ public class BCrypt {
|
|
413
414
|
rs.append(base64_code[c1 & 0x3f]);
|
414
415
|
rs.append(base64_code[c2 & 0x3f]);
|
415
416
|
}
|
416
|
-
return rs.toString();
|
417
417
|
}
|
418
418
|
|
419
419
|
/**
|
@@ -423,9 +423,9 @@ public class BCrypt {
|
|
423
423
|
* @return the decoded value of x
|
424
424
|
*/
|
425
425
|
private static byte char64(char x) {
|
426
|
-
if ((int)x < 0 || (int)x
|
426
|
+
if ((int) x < 0 || (int) x >= index_64.length)
|
427
427
|
return -1;
|
428
|
-
return index_64[(int)x];
|
428
|
+
return index_64[(int) x];
|
429
429
|
}
|
430
430
|
|
431
431
|
/**
|
@@ -437,8 +437,8 @@ public class BCrypt {
|
|
437
437
|
* @return an array containing the decoded bytes
|
438
438
|
* @throws IllegalArgumentException if maxolen is invalid
|
439
439
|
*/
|
440
|
-
|
441
|
-
|
440
|
+
static byte[] decode_base64(String s, int maxolen)
|
441
|
+
throws IllegalArgumentException {
|
442
442
|
StringBuilder rs = new StringBuilder();
|
443
443
|
int off = 0, slen = s.length(), olen = 0;
|
444
444
|
byte ret[];
|
@@ -452,29 +452,29 @@ public class BCrypt {
|
|
452
452
|
c2 = char64(s.charAt(off++));
|
453
453
|
if (c1 == -1 || c2 == -1)
|
454
454
|
break;
|
455
|
-
o = (byte)(c1 << 2);
|
455
|
+
o = (byte) (c1 << 2);
|
456
456
|
o |= (c2 & 0x30) >> 4;
|
457
|
-
rs.append((char)o);
|
457
|
+
rs.append((char) o);
|
458
458
|
if (++olen >= maxolen || off >= slen)
|
459
459
|
break;
|
460
460
|
c3 = char64(s.charAt(off++));
|
461
461
|
if (c3 == -1)
|
462
462
|
break;
|
463
|
-
o = (byte)((c2 & 0x0f) << 4);
|
463
|
+
o = (byte) ((c2 & 0x0f) << 4);
|
464
464
|
o |= (c3 & 0x3c) >> 2;
|
465
|
-
rs.append((char)o);
|
465
|
+
rs.append((char) o);
|
466
466
|
if (++olen >= maxolen || off >= slen)
|
467
467
|
break;
|
468
468
|
c4 = char64(s.charAt(off++));
|
469
|
-
o = (byte)((c3 & 0x03) << 6);
|
469
|
+
o = (byte) ((c3 & 0x03) << 6);
|
470
470
|
o |= c4;
|
471
|
-
rs.append((char)o);
|
471
|
+
rs.append((char) o);
|
472
472
|
++olen;
|
473
473
|
}
|
474
474
|
|
475
475
|
ret = new byte[olen];
|
476
476
|
for (off = 0; off < olen; off++)
|
477
|
-
ret[off] = (byte)rs.charAt(off);
|
477
|
+
ret[off] = (byte) rs.charAt(off);
|
478
478
|
return ret;
|
479
479
|
}
|
480
480
|
|
@@ -512,42 +512,77 @@ public class BCrypt {
|
|
512
512
|
* @param data the string to extract the data from
|
513
513
|
* @param offp a "pointer" (as a one-entry array) to the
|
514
514
|
* current offset into data
|
515
|
-
* @
|
515
|
+
* @param signp a "pointer" (as a one-entry array) to the
|
516
|
+
* cumulative flag for non-benign sign extension
|
517
|
+
* @return correct and buggy next word of material from data as int[2]
|
516
518
|
*/
|
517
|
-
private static int
|
519
|
+
private static int[] streamtowords(byte data[], int offp[], int signp[]) {
|
518
520
|
int i;
|
519
|
-
int
|
521
|
+
int words[] = { 0, 0 };
|
520
522
|
int off = offp[0];
|
523
|
+
int sign = signp[0];
|
521
524
|
|
522
525
|
for (i = 0; i < 4; i++) {
|
523
|
-
|
526
|
+
words[0] = (words[0] << 8) | (data[off] & 0xff);
|
527
|
+
words[1] = (words[1] << 8) | (int) data[off]; // sign extension bug
|
528
|
+
if (i > 0) sign |= words[1] & 0x80;
|
524
529
|
off = (off + 1) % data.length;
|
525
530
|
}
|
526
531
|
|
527
532
|
offp[0] = off;
|
528
|
-
|
533
|
+
signp[0] = sign;
|
534
|
+
return words;
|
535
|
+
}
|
536
|
+
|
537
|
+
/**
|
538
|
+
* Cycically extract a word of key material
|
539
|
+
* @param data the string to extract the data from
|
540
|
+
* @param offp a "pointer" (as a one-entry array) to the
|
541
|
+
* current offset into data
|
542
|
+
* @return the next word of material from data
|
543
|
+
*/
|
544
|
+
private static int streamtoword(byte data[], int offp[]) {
|
545
|
+
int signp[] = { 0 };
|
546
|
+
return streamtowords(data, offp, signp)[0];
|
547
|
+
}
|
548
|
+
|
549
|
+
/**
|
550
|
+
* Cycically extract a word of key material, with sign-extension bug
|
551
|
+
* @param data the string to extract the data from
|
552
|
+
* @param offp a "pointer" (as a one-entry array) to the
|
553
|
+
* current offset into data
|
554
|
+
* @return the next word of material from data
|
555
|
+
*/
|
556
|
+
private static int streamtoword_bug(byte data[], int offp[]) {
|
557
|
+
int signp[] = { 0 };
|
558
|
+
return streamtowords(data, offp, signp)[1];
|
529
559
|
}
|
530
560
|
|
531
561
|
/**
|
532
562
|
* Initialise the Blowfish key schedule
|
533
563
|
*/
|
534
564
|
private void init_key() {
|
535
|
-
P =
|
536
|
-
S =
|
565
|
+
P = P_orig.clone();
|
566
|
+
S = S_orig.clone();
|
537
567
|
}
|
538
568
|
|
539
569
|
/**
|
540
570
|
* Key the Blowfish cipher
|
541
571
|
* @param key an array containing the key
|
572
|
+
* @param sign_ext_bug true to implement the 2x bug
|
573
|
+
* @param safety bit 16 is set when the safety measure is requested
|
542
574
|
*/
|
543
|
-
private void key(byte key[]) {
|
575
|
+
private void key(byte key[], boolean sign_ext_bug, int safety) {
|
544
576
|
int i;
|
545
577
|
int koffp[] = { 0 };
|
546
578
|
int lr[] = { 0, 0 };
|
547
579
|
int plen = P.length, slen = S.length;
|
548
580
|
|
549
581
|
for (i = 0; i < plen; i++)
|
550
|
-
|
582
|
+
if (!sign_ext_bug)
|
583
|
+
P[i] = P[i] ^ streamtoword(key, koffp);
|
584
|
+
else
|
585
|
+
P[i] = P[i] ^ streamtoword_bug(key, koffp);
|
551
586
|
|
552
587
|
for (i = 0; i < plen; i += 2) {
|
553
588
|
encipher(lr, 0);
|
@@ -568,15 +603,53 @@ public class BCrypt {
|
|
568
603
|
* http://www.openbsd.org/papers/bcrypt-paper.ps
|
569
604
|
* @param data salt information
|
570
605
|
* @param key password information
|
606
|
+
* @param sign_ext_bug true to implement the 2x bug
|
607
|
+
* @param safety bit 16 is set when the safety measure is requested
|
571
608
|
*/
|
572
|
-
private void ekskey(byte data[], byte key[]
|
609
|
+
private void ekskey(byte data[], byte key[],
|
610
|
+
boolean sign_ext_bug, int safety) {
|
573
611
|
int i;
|
574
612
|
int koffp[] = { 0 }, doffp[] = { 0 };
|
575
613
|
int lr[] = { 0, 0 };
|
576
614
|
int plen = P.length, slen = S.length;
|
615
|
+
int signp[] = { 0 }; // non-benign sign-extension flag
|
616
|
+
int diff = 0; // zero iff correct and buggy are same
|
577
617
|
|
578
|
-
for (i = 0; i < plen; i++)
|
579
|
-
|
618
|
+
for (i = 0; i < plen; i++) {
|
619
|
+
int words[] = streamtowords(key, koffp, signp);
|
620
|
+
diff |= words[0] ^ words[1];
|
621
|
+
P[i] = P[i] ^ words[sign_ext_bug ? 1 : 0];
|
622
|
+
}
|
623
|
+
|
624
|
+
int sign = signp[0];
|
625
|
+
|
626
|
+
/*
|
627
|
+
* At this point, "diff" is zero iff the correct and buggy algorithms produced
|
628
|
+
* exactly the same result. If so and if "sign" is non-zero, which indicates
|
629
|
+
* that there was a non-benign sign extension, this means that we have a
|
630
|
+
* collision between the correctly computed hash for this password and a set of
|
631
|
+
* passwords that could be supplied to the buggy algorithm. Our safety measure
|
632
|
+
* is meant to protect from such many-buggy to one-correct collisions, by
|
633
|
+
* deviating from the correct algorithm in such cases. Let's check for this.
|
634
|
+
*/
|
635
|
+
diff |= diff >> 16; /* still zero iff exact match */
|
636
|
+
diff &= 0xffff; /* ditto */
|
637
|
+
diff += 0xffff; /* bit 16 set iff "diff" was non-zero (on non-match) */
|
638
|
+
sign <<= 9; /* move the non-benign sign extension flag to bit 16 */
|
639
|
+
sign &= ~diff & safety; /* action needed? */
|
640
|
+
|
641
|
+
/*
|
642
|
+
* If we have determined that we need to deviate from the correct algorithm,
|
643
|
+
* flip bit 16 in initial expanded key. (The choice of 16 is arbitrary, but
|
644
|
+
* let's stick to it now. It came out of the approach we used above, and it's
|
645
|
+
* not any worse than any other choice we could make.)
|
646
|
+
*
|
647
|
+
* It is crucial that we don't do the same to the expanded key used in the main
|
648
|
+
* Eksblowfish loop. By doing it to only one of these two, we deviate from a
|
649
|
+
* state that could be directly specified by a password to the buggy algorithm
|
650
|
+
* (and to the fully correct one as well, but that's a side-effect).
|
651
|
+
*/
|
652
|
+
P[0] ^= sign;
|
580
653
|
|
581
654
|
for (i = 0; i < plen; i += 2) {
|
582
655
|
lr[0] ^= streamtoword(data, doffp);
|
@@ -595,6 +668,13 @@ public class BCrypt {
|
|
595
668
|
}
|
596
669
|
}
|
597
670
|
|
671
|
+
static long roundsForLogRounds(int log_rounds) {
|
672
|
+
if (log_rounds < 4 || log_rounds > 31) {
|
673
|
+
throw new IllegalArgumentException("Bad number of rounds");
|
674
|
+
}
|
675
|
+
return 1L << log_rounds;
|
676
|
+
}
|
677
|
+
|
598
678
|
/**
|
599
679
|
* Perform the central password hashing step in the
|
600
680
|
* bcrypt scheme
|
@@ -602,11 +682,14 @@ public class BCrypt {
|
|
602
682
|
* @param salt the binary salt to hash with the password
|
603
683
|
* @param log_rounds the binary logarithm of the number
|
604
684
|
* of rounds of hashing to apply
|
685
|
+
* @param sign_ext_bug true to implement the 2x bug
|
686
|
+
* @param safety bit 16 is set when the safety measure is requested
|
605
687
|
* @return an array containing the binary hashed password
|
606
688
|
*/
|
607
|
-
private byte[] crypt_raw(byte password[], byte salt[], int log_rounds
|
689
|
+
private byte[] crypt_raw(byte password[], byte salt[], int log_rounds,
|
690
|
+
boolean sign_ext_bug, int safety) {
|
608
691
|
int rounds, i, j;
|
609
|
-
int cdata[] =
|
692
|
+
int cdata[] = bf_crypt_ciphertext.clone();
|
610
693
|
int clen = cdata.length;
|
611
694
|
byte ret[];
|
612
695
|
|
@@ -617,10 +700,10 @@ public class BCrypt {
|
|
617
700
|
throw new IllegalArgumentException ("Bad salt length");
|
618
701
|
|
619
702
|
init_key();
|
620
|
-
ekskey(salt, password);
|
703
|
+
ekskey(salt, password, sign_ext_bug, safety);
|
621
704
|
for (i = 0; i < rounds; i++) {
|
622
|
-
key(password);
|
623
|
-
key(salt);
|
705
|
+
key(password, sign_ext_bug, safety);
|
706
|
+
key(salt, false, safety);
|
624
707
|
}
|
625
708
|
|
626
709
|
for (i = 0; i < 64; i++) {
|
@@ -630,10 +713,10 @@ public class BCrypt {
|
|
630
713
|
|
631
714
|
ret = new byte[clen * 4];
|
632
715
|
for (i = 0, j = 0; i < clen; i++) {
|
633
|
-
ret[j++] = (byte)((cdata[i] >> 24) & 0xff);
|
634
|
-
ret[j++] = (byte)((cdata[i] >> 16) & 0xff);
|
635
|
-
ret[j++] = (byte)((cdata[i] >> 8) & 0xff);
|
636
|
-
ret[j++] = (byte)(cdata[i] & 0xff);
|
716
|
+
ret[j++] = (byte) ((cdata[i] >> 24) & 0xff);
|
717
|
+
ret[j++] = (byte) ((cdata[i] >> 16) & 0xff);
|
718
|
+
ret[j++] = (byte) ((cdata[i] >> 8) & 0xff);
|
719
|
+
ret[j++] = (byte) (cdata[i] & 0xff);
|
637
720
|
}
|
638
721
|
return ret;
|
639
722
|
}
|
@@ -646,20 +729,50 @@ public class BCrypt {
|
|
646
729
|
* @return the hashed password
|
647
730
|
*/
|
648
731
|
public static String hashpw(String password, String salt) {
|
732
|
+
byte passwordb[];
|
733
|
+
|
734
|
+
try {
|
735
|
+
passwordb = password.getBytes("UTF-8");
|
736
|
+
} catch (UnsupportedEncodingException uee) {
|
737
|
+
throw new AssertionError("UTF-8 is not supported");
|
738
|
+
}
|
739
|
+
|
740
|
+
return hashpw(passwordb, salt);
|
741
|
+
}
|
742
|
+
|
743
|
+
/**
|
744
|
+
* Hash a password using the OpenBSD bcrypt scheme
|
745
|
+
* @param passwordb the password to hash, as a byte array
|
746
|
+
* @param salt the salt to hash with (perhaps generated
|
747
|
+
* using BCrypt.gensalt)
|
748
|
+
* @return the hashed password
|
749
|
+
*/
|
750
|
+
public static String hashpw(byte passwordb[], String salt) {
|
649
751
|
BCrypt B;
|
650
752
|
String real_salt;
|
651
|
-
byte
|
652
|
-
char minor = (char)0;
|
653
|
-
int rounds, off
|
753
|
+
byte saltb[], hashed[];
|
754
|
+
char minor = (char) 0;
|
755
|
+
int rounds, off;
|
654
756
|
StringBuilder rs = new StringBuilder();
|
655
757
|
|
758
|
+
if (salt == null) {
|
759
|
+
throw new IllegalArgumentException("salt cannot be null");
|
760
|
+
}
|
761
|
+
|
762
|
+
int saltLength = salt.length();
|
763
|
+
|
764
|
+
if (saltLength < 28) {
|
765
|
+
throw new IllegalArgumentException("Invalid salt");
|
766
|
+
}
|
767
|
+
|
656
768
|
if (salt.charAt(0) != '$' || salt.charAt(1) != '2')
|
657
769
|
throw new IllegalArgumentException ("Invalid salt version");
|
658
770
|
if (salt.charAt(2) == '$')
|
659
771
|
off = 3;
|
660
772
|
else {
|
661
773
|
minor = salt.charAt(2);
|
662
|
-
if (minor != 'a'
|
774
|
+
if ((minor != 'a' && minor != 'x' && minor != 'y' && minor != 'b')
|
775
|
+
|| salt.charAt(3) != '$')
|
663
776
|
throw new IllegalArgumentException ("Invalid salt revision");
|
664
777
|
off = 4;
|
665
778
|
}
|
@@ -670,16 +783,13 @@ public class BCrypt {
|
|
670
783
|
rounds = Integer.parseInt(salt.substring(off, off + 2));
|
671
784
|
|
672
785
|
real_salt = salt.substring(off + 3, off + 25);
|
673
|
-
try {
|
674
|
-
passwordb = (password + (minor >= 'a' ? "\000" : "")).getBytes("UTF-8");
|
675
|
-
} catch (UnsupportedEncodingException uee) {
|
676
|
-
throw new AssertionError("UTF-8 is not supported");
|
677
|
-
}
|
678
|
-
|
679
786
|
saltb = decode_base64(real_salt, BCRYPT_SALT_LEN);
|
680
787
|
|
788
|
+
if (minor >= 'a') // add null terminator
|
789
|
+
passwordb = Arrays.copyOf(passwordb, passwordb.length + 1);
|
790
|
+
|
681
791
|
B = new BCrypt();
|
682
|
-
hashed = B.crypt_raw(passwordb, saltb, rounds);
|
792
|
+
hashed = B.crypt_raw(passwordb, saltb, rounds, minor == 'x', minor == 'a' ? 0x10000 : 0);
|
683
793
|
|
684
794
|
rs.append("$2");
|
685
795
|
if (minor >= 'a')
|
@@ -687,48 +797,95 @@ public class BCrypt {
|
|
687
797
|
rs.append("$");
|
688
798
|
if (rounds < 10)
|
689
799
|
rs.append("0");
|
690
|
-
rs.append(
|
800
|
+
rs.append(rounds);
|
691
801
|
rs.append("$");
|
692
|
-
|
693
|
-
|
694
|
-
bf_crypt_ciphertext.length * 4 - 1));
|
802
|
+
encode_base64(saltb, saltb.length, rs);
|
803
|
+
encode_base64(hashed, bf_crypt_ciphertext.length * 4 - 1, rs);
|
695
804
|
return rs.toString();
|
696
805
|
}
|
697
806
|
|
698
807
|
/**
|
699
808
|
* Generate a salt for use with the BCrypt.hashpw() method
|
809
|
+
* @param prefix the prefix value (default $2a)
|
700
810
|
* @param log_rounds the log2 of the number of rounds of
|
701
811
|
* hashing to apply - the work factor therefore increases as
|
702
812
|
* 2**log_rounds.
|
703
813
|
* @param random an instance of SecureRandom to use
|
704
814
|
* @return an encoded salt value
|
815
|
+
* @exception IllegalArgumentException if prefix or log_rounds is invalid
|
705
816
|
*/
|
706
|
-
public static String gensalt(int log_rounds, SecureRandom random)
|
817
|
+
public static String gensalt(String prefix, int log_rounds, SecureRandom random)
|
818
|
+
throws IllegalArgumentException {
|
707
819
|
StringBuilder rs = new StringBuilder();
|
708
820
|
byte rnd[] = new byte[BCRYPT_SALT_LEN];
|
709
821
|
|
822
|
+
if (!prefix.startsWith("$2") ||
|
823
|
+
(prefix.charAt(2) != 'a' && prefix.charAt(2) != 'y' &&
|
824
|
+
prefix.charAt(2) != 'b')) {
|
825
|
+
throw new IllegalArgumentException ("Invalid prefix");
|
826
|
+
}
|
827
|
+
if (log_rounds < 4 || log_rounds > 31) {
|
828
|
+
throw new IllegalArgumentException ("Invalid log_rounds");
|
829
|
+
}
|
830
|
+
|
710
831
|
random.nextBytes(rnd);
|
711
832
|
|
712
|
-
rs.append("$
|
833
|
+
rs.append("$2");
|
834
|
+
rs.append(prefix.charAt(2));
|
835
|
+
rs.append("$");
|
713
836
|
if (log_rounds < 10)
|
714
837
|
rs.append("0");
|
715
|
-
rs.append(
|
838
|
+
rs.append(log_rounds);
|
716
839
|
rs.append("$");
|
717
|
-
|
840
|
+
encode_base64(rnd, rnd.length, rs);
|
718
841
|
return rs.toString();
|
719
842
|
}
|
720
843
|
|
721
844
|
/**
|
722
845
|
* Generate a salt for use with the BCrypt.hashpw() method
|
846
|
+
* @param prefix the prefix value (default $2a)
|
723
847
|
* @param log_rounds the log2 of the number of rounds of
|
724
848
|
* hashing to apply - the work factor therefore increases as
|
725
849
|
* 2**log_rounds.
|
726
850
|
* @return an encoded salt value
|
851
|
+
* @exception IllegalArgumentException if prefix or log_rounds is invalid
|
727
852
|
*/
|
728
|
-
public static String gensalt(int log_rounds)
|
853
|
+
public static String gensalt(String prefix, int log_rounds)
|
854
|
+
throws IllegalArgumentException {
|
855
|
+
return gensalt(prefix, log_rounds, new SecureRandom());
|
856
|
+
}
|
857
|
+
|
858
|
+
/**
|
859
|
+
* Generate a salt for use with the BCrypt.hashpw() method
|
860
|
+
* @param log_rounds the log2 of the number of rounds of
|
861
|
+
* hashing to apply - the work factor therefore increases as
|
862
|
+
* 2**log_rounds.
|
863
|
+
* @param random an instance of SecureRandom to use
|
864
|
+
* @return an encoded salt value
|
865
|
+
* @exception IllegalArgumentException if log_rounds is invalid
|
866
|
+
*/
|
867
|
+
public static String gensalt(int log_rounds, SecureRandom random)
|
868
|
+
throws IllegalArgumentException {
|
869
|
+
return gensalt("$2a", log_rounds, random);
|
870
|
+
}
|
871
|
+
|
872
|
+
/**
|
873
|
+
* Generate a salt for use with the BCrypt.hashpw() method
|
874
|
+
* @param log_rounds the log2 of the number of rounds of
|
875
|
+
* hashing to apply - the work factor therefore increases as
|
876
|
+
* 2**log_rounds.
|
877
|
+
* @return an encoded salt value
|
878
|
+
* @exception IllegalArgumentException if log_rounds is invalid
|
879
|
+
*/
|
880
|
+
public static String gensalt(int log_rounds)
|
881
|
+
throws IllegalArgumentException {
|
729
882
|
return gensalt(log_rounds, new SecureRandom());
|
730
883
|
}
|
731
884
|
|
885
|
+
public static String gensalt(String prefix) {
|
886
|
+
return gensalt(prefix, GENSALT_DEFAULT_LOG2_ROUNDS);
|
887
|
+
}
|
888
|
+
|
732
889
|
/**
|
733
890
|
* Generate a salt for use with the BCrypt.hashpw() method,
|
734
891
|
* selecting a reasonable default for the number of hashing
|
@@ -747,6 +904,22 @@ public class BCrypt {
|
|
747
904
|
* @return true if the passwords match, false otherwise
|
748
905
|
*/
|
749
906
|
public static boolean checkpw(String plaintext, String hashed) {
|
750
|
-
return (hashed
|
907
|
+
return equalsNoEarlyReturn(hashed, hashpw(plaintext, hashed));
|
908
|
+
}
|
909
|
+
|
910
|
+
static boolean equalsNoEarlyReturn(String a, String b) {
|
911
|
+
char[] caa = a.toCharArray();
|
912
|
+
char[] cab = b.toCharArray();
|
913
|
+
|
914
|
+
if (caa.length != cab.length) {
|
915
|
+
return false;
|
916
|
+
}
|
917
|
+
|
918
|
+
byte ret = 0;
|
919
|
+
for (int i = 0; i < caa.length; i++) {
|
920
|
+
ret |= caa[i] ^ cab[i];
|
921
|
+
}
|
922
|
+
return ret == 0;
|
751
923
|
}
|
752
924
|
}
|
925
|
+
|