blake.rb 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +38 -0
- data/.rubocop.yml +48 -0
- data/.rubocop_todo.yml +51 -0
- data/.simplecov +3 -0
- data/.travis.yml +8 -0
- data/Gemfile +6 -0
- data/LICENSE +20 -0
- data/README.md +64 -0
- data/Rakefile +25 -0
- data/blake.gemspec +47 -0
- data/lib/blake.rb +11 -0
- data/lib/blake/main.rb +236 -0
- data/lib/blake/version.rb +5 -0
- metadata +164 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 55e8f3406599d56f1096eeb1a1ccb4798b8182abd4bcb085c7eb887f90f0d59c
|
4
|
+
data.tar.gz: 11972db8f764c21587b0595a97ef2bc2e3baafaeac5953c7209036d764c5cb77
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 2e704069b8f67616819ac882939699429630b04aa5f16bf1dca6532f7503f1e555568b4aed26bae46a219ea1948264027d4d19bc311ef4ac5471e10746a13ad9
|
7
|
+
data.tar.gz: 3ad0bb667e2468725cfeed7945be3f4fa4abd9a004f69e67a6256f03eb97997d54b786b371ee3c97265b7694c5fa9f34e3b924e5ec885165449f50800163f2d9
|
data/.gitignore
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
# See https://help.github.com/articles/ignoring-files for more about ignoring files.
|
2
|
+
#
|
3
|
+
# If you find yourself ignoring temporary files generated by your text editor
|
4
|
+
# or operating system, you probably want to add a global ignore instead:
|
5
|
+
# git config --global core.excludesfile '~/.gitignore_global'
|
6
|
+
|
7
|
+
*.gem
|
8
|
+
*.rbc
|
9
|
+
/.config
|
10
|
+
/.rake_tasks~
|
11
|
+
/coverage/
|
12
|
+
/InstalledFiles
|
13
|
+
/pkg/
|
14
|
+
/tmp/
|
15
|
+
|
16
|
+
# RSpec configuration and generated files:
|
17
|
+
/.rspec
|
18
|
+
/spec/examples.txt
|
19
|
+
|
20
|
+
# Documentation cache and generated files:
|
21
|
+
/.yardoc/
|
22
|
+
/_yardoc/
|
23
|
+
/doc/
|
24
|
+
/rdoc/
|
25
|
+
|
26
|
+
# Environment normalization:
|
27
|
+
/.bundle/
|
28
|
+
/vendor/bundle
|
29
|
+
/lib/bundler/man/
|
30
|
+
|
31
|
+
# For a library or gem, you might want to ignore these files since the code is
|
32
|
+
# intended to run in multiple environments; otherwise, check them in:
|
33
|
+
/Gemfile.lock
|
34
|
+
/.ruby-version
|
35
|
+
/.ruby-gemset
|
36
|
+
|
37
|
+
# Unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
|
38
|
+
.rvmrc
|
data/.rubocop.yml
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
inherit_from: .rubocop_todo.yml
|
2
|
+
|
3
|
+
require:
|
4
|
+
- rubocop-performance
|
5
|
+
|
6
|
+
AllCops:
|
7
|
+
TargetRubyVersion: 2.5
|
8
|
+
DisplayCopNames: true
|
9
|
+
|
10
|
+
Layout/AccessModifierIndentation:
|
11
|
+
EnforcedStyle: outdent
|
12
|
+
|
13
|
+
Lint/ReturnInVoidContext:
|
14
|
+
Enabled: false
|
15
|
+
|
16
|
+
Style/AndOr:
|
17
|
+
EnforcedStyle: conditionals
|
18
|
+
|
19
|
+
Style/AsciiComments:
|
20
|
+
Enabled: false
|
21
|
+
|
22
|
+
Style/Documentation:
|
23
|
+
Enabled: false
|
24
|
+
|
25
|
+
Style/DoubleNegation:
|
26
|
+
Enabled: false
|
27
|
+
|
28
|
+
Style/FrozenStringLiteralComment:
|
29
|
+
Enabled: true
|
30
|
+
EnforcedStyle: always
|
31
|
+
|
32
|
+
Style/IfUnlessModifier:
|
33
|
+
Enabled: false
|
34
|
+
|
35
|
+
Style/RegexpLiteral:
|
36
|
+
Enabled: false
|
37
|
+
|
38
|
+
Style/RescueStandardError:
|
39
|
+
EnforcedStyle: implicit
|
40
|
+
|
41
|
+
Style/TrailingCommaInArguments:
|
42
|
+
EnforcedStyleForMultiline: comma
|
43
|
+
|
44
|
+
Style/TrailingCommaInArrayLiteral:
|
45
|
+
EnforcedStyleForMultiline: comma
|
46
|
+
|
47
|
+
Style/TrailingCommaInHashLiteral:
|
48
|
+
EnforcedStyleForMultiline: comma
|
data/.rubocop_todo.yml
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
# This configuration was generated by
|
2
|
+
# `rubocop --auto-gen-config`
|
3
|
+
# on 2020-02-22 16:27:26 +0300 using RuboCop version 0.73.0.
|
4
|
+
# The point is for the user to remove these configuration records
|
5
|
+
# one by one as the offenses are removed from the code base.
|
6
|
+
# Note that changes in the inspected code, or installation of new
|
7
|
+
# versions of RuboCop, may require this file to be generated again.
|
8
|
+
|
9
|
+
# Offense count: 2
|
10
|
+
Metrics/AbcSize:
|
11
|
+
Max: 82
|
12
|
+
|
13
|
+
# Offense count: 1
|
14
|
+
# Configuration parameters: CountComments, ExcludedMethods.
|
15
|
+
# ExcludedMethods: refine
|
16
|
+
Metrics/BlockLength:
|
17
|
+
Max: 122
|
18
|
+
|
19
|
+
# Offense count: 1
|
20
|
+
# Configuration parameters: CountComments.
|
21
|
+
Metrics/ClassLength:
|
22
|
+
Max: 177
|
23
|
+
|
24
|
+
# Offense count: 1
|
25
|
+
Metrics/CyclomaticComplexity:
|
26
|
+
Max: 11
|
27
|
+
|
28
|
+
# Offense count: 3
|
29
|
+
# Configuration parameters: CountComments, ExcludedMethods.
|
30
|
+
Metrics/MethodLength:
|
31
|
+
Max: 29
|
32
|
+
|
33
|
+
# Offense count: 1
|
34
|
+
Metrics/PerceivedComplexity:
|
35
|
+
Max: 9
|
36
|
+
|
37
|
+
# Offense count: 2
|
38
|
+
# Cop supports --auto-correct.
|
39
|
+
# Configuration parameters: EnforcedStyle.
|
40
|
+
# SupportedStyles: always, never
|
41
|
+
Style/FrozenStringLiteralComment:
|
42
|
+
Exclude:
|
43
|
+
- 'lib/blake/main.rb'
|
44
|
+
- 'spec/lib/blake/main_spec.rb'
|
45
|
+
|
46
|
+
# Offense count: 26
|
47
|
+
# Cop supports --auto-correct.
|
48
|
+
# Configuration parameters: AutoCorrect, AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, IgnoredPatterns.
|
49
|
+
# URISchemes: http, https
|
50
|
+
Metrics/LineLength:
|
51
|
+
Max: 141
|
data/.simplecov
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2014
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
6
|
+
this software and associated documentation files (the "Software"), to deal in
|
7
|
+
the Software without restriction, including without limitation the rights to
|
8
|
+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
9
|
+
the Software, and to permit persons to whom the Software is furnished to do so,
|
10
|
+
subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
17
|
+
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
18
|
+
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
19
|
+
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
20
|
+
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
Blake.rb
|
2
|
+
========
|
3
|
+
|
4
|
+
BLAKE is a cryptographic hash function based on Dan Bernstein's ChaCha stream
|
5
|
+
cipher, but a permuted copy of the input block, XORed with round constants, is
|
6
|
+
added before each ChaCha round. Like SHA-2, there are two variants differing in
|
7
|
+
the word size. ChaCha operates on a 4×4 array of words. BLAKE repeatedly
|
8
|
+
combines an 8-word hash value with 16 message words, truncating the ChaCha
|
9
|
+
result to obtain the next hash value. BLAKE-256 and BLAKE-224 use 32-bit words
|
10
|
+
and produce digest sizes of 256 bits and 224 bits, respectively, while
|
11
|
+
BLAKE-512 and BLAKE-384 use 64-bit words and produce digest sizes of 512 bits
|
12
|
+
and 384 bits, respectively.
|
13
|
+
|
14
|
+
## Install
|
15
|
+
|
16
|
+
```
|
17
|
+
gem install blake
|
18
|
+
```
|
19
|
+
|
20
|
+
## Usage
|
21
|
+
|
22
|
+
```ruby
|
23
|
+
require 'blake'
|
24
|
+
```
|
25
|
+
|
26
|
+
The output size and salt can be specified, or left as their defaults of 512 and nil.
|
27
|
+
|
28
|
+
By default:
|
29
|
+
```ruby
|
30
|
+
Blake.digest("The quick brown fox jumps over the lazy dog").unpack('H*').join
|
31
|
+
#=> "1f7e26f63b6ad25a0896fd978fd050a1766391d2fd0471a77afb975e5034b7ad2d9ccf8dfb47abbbe656e1b82fbc634ba42ce186e8dc5e1ce09a885d41f43451"
|
32
|
+
```
|
33
|
+
|
34
|
+
When output size is specified:
|
35
|
+
```ruby
|
36
|
+
Blake.digest("The quick brown fox jumps over the lazy dog", 224).unpack('H*').join
|
37
|
+
#=> "c8e92d7088ef87c1530aee2ad44dc720cc10589cc2ec58f95a15e51b"
|
38
|
+
|
39
|
+
Blake.digest("The quick brown fox jumps over the lazy dog", 256).unpack('H*').join
|
40
|
+
#=> "7576698ee9cad30173080678e5965916adbb11cb5245d386bf1ffda1cb26c9d7"
|
41
|
+
|
42
|
+
Blake.digest("The quick brown fox jumps over the lazy dog", 384).unpack('H*').join
|
43
|
+
#=> "67c9e8ef665d11b5b57a1d99c96adffb3034d8768c0827d1c6e60b54871e8673651767a2c6c43d0ba2a9bb2500227406"
|
44
|
+
|
45
|
+
Blake.digest("The quick brown fox jumps over the lazy dog", 512).unpack('H*').join
|
46
|
+
#=> "1f7e26f63b6ad25a0896fd978fd050a1766391d2fd0471a77afb975e5034b7ad2d9ccf8dfb47abbbe656e1b82fbc634ba42ce186e8dc5e1ce09a885d41f43451"
|
47
|
+
```
|
48
|
+
|
49
|
+
When salt is specified:
|
50
|
+
```ruby
|
51
|
+
salt = [0, 2, 4, 8]
|
52
|
+
|
53
|
+
Blake.digest("The quick brown fox jumps over the lazy dog", 224, salt).unpack('H*').join
|
54
|
+
#=> "9c745e156e27705b3dfa07cd26d623991655c049242953c4a331d133"
|
55
|
+
|
56
|
+
Blake.digest("The quick brown fox jumps over the lazy dog", 256, salt).unpack('H*').join
|
57
|
+
#=> "d24ce44e7964dba5e27a20e80377ebef308215b7ff6da949dc96190ebd5818c6"
|
58
|
+
|
59
|
+
Blake.digest("The quick brown fox jumps over the lazy dog", 384, salt).unpack('H*').join
|
60
|
+
#=> "42e7983093f97c4fb8238bbc9378251b274c8f0f7ffd28ca73935a34e1f567dfee6bf31d6cea5766c92fdf4a3a5d3718"
|
61
|
+
|
62
|
+
Blake.digest("The quick brown fox jumps over the lazy dog", 512, salt).unpack('H*').join
|
63
|
+
#=> "930cddb5e7b41ba85b8179e14617fc4cb6372ba565b479c8cb726ef8c2a6526ff1b901af461ef9a6f91d71bda8079c0cc5e284f44014a1d2ec0d8d7814ae33f6"
|
64
|
+
```
|
data/Rakefile
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'bundler/gem_tasks'
|
4
|
+
|
5
|
+
task default: %i[test lint]
|
6
|
+
|
7
|
+
task test: :spec
|
8
|
+
|
9
|
+
task lint: :rubocop
|
10
|
+
|
11
|
+
task fix: 'rubocop:auto_correct'
|
12
|
+
|
13
|
+
begin
|
14
|
+
require 'rspec/core/rake_task'
|
15
|
+
RSpec::Core::RakeTask.new
|
16
|
+
rescue LoadError
|
17
|
+
nil
|
18
|
+
end
|
19
|
+
|
20
|
+
begin
|
21
|
+
require 'rubocop/rake_task'
|
22
|
+
RuboCop::RakeTask.new
|
23
|
+
rescue LoadError
|
24
|
+
nil
|
25
|
+
end
|
data/blake.gemspec
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
$LOAD_PATH.unshift File.expand_path('lib', __dir__)
|
4
|
+
require 'blake/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = 'blake.rb'
|
8
|
+
spec.version = Blake::VERSION
|
9
|
+
spec.license = 'MIT'
|
10
|
+
spec.homepage = 'https://github.com/ydakuka/blake.rb'
|
11
|
+
spec.summary = 'BLAKE hash function library for ruby'
|
12
|
+
spec.platform = Gem::Platform::RUBY
|
13
|
+
|
14
|
+
spec.authors = ['Daniel Cavanagh (danielcavanagh)']
|
15
|
+
|
16
|
+
spec.description = <<-DESCRIPTION.split.join ' '
|
17
|
+
BLAKE is a cryptographic hash function based on Dan Bernstein's ChaCha
|
18
|
+
stream cipher, but a permuted copy of the input block, XORed with round
|
19
|
+
constants, is added before each ChaCha round. Like SHA-2, there are two
|
20
|
+
variants differing in the word size. ChaCha operates on a 4×4 array of
|
21
|
+
words. BLAKE repeatedly combines an 8-word hash value with 16 message words,
|
22
|
+
truncating the ChaCha result to obtain the next hash value. BLAKE-256 and
|
23
|
+
BLAKE-224 use 32-bit words and produce digest sizes of 256 bits and 224
|
24
|
+
bits, respectively, while BLAKE-512 and BLAKE-384 use 64-bit words and
|
25
|
+
produce digest sizes of 512 bits and 384 bits, respectively.
|
26
|
+
DESCRIPTION
|
27
|
+
|
28
|
+
spec.metadata = {
|
29
|
+
'homepage_uri' => 'https://github.com/ydakuka/blake.rb',
|
30
|
+
'source_code_uri' => 'https://github.com/ydakuka/blake.rb',
|
31
|
+
'bug_tracker_uri' => 'https://github.com/ydakuka/blake.rb/issues',
|
32
|
+
}.freeze
|
33
|
+
|
34
|
+
spec.require_paths = ['lib']
|
35
|
+
|
36
|
+
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
37
|
+
f.match %r{^(test|spec)/}
|
38
|
+
end
|
39
|
+
|
40
|
+
spec.add_development_dependency 'bundler', '~> 1.16'
|
41
|
+
spec.add_development_dependency 'pry', '~> 0.12'
|
42
|
+
spec.add_development_dependency 'rake', '~> 12.3'
|
43
|
+
spec.add_development_dependency 'rspec', '~> 3.8'
|
44
|
+
spec.add_development_dependency 'rubocop', '~> 0.73'
|
45
|
+
spec.add_development_dependency 'rubocop-performance', '~> 1.5'
|
46
|
+
spec.add_development_dependency 'simplecov', '~> 0.17'
|
47
|
+
end
|
data/lib/blake.rb
ADDED
data/lib/blake/main.rb
ADDED
@@ -0,0 +1,236 @@
|
|
1
|
+
class Integer
|
2
|
+
def ror(shift, word_size = size)
|
3
|
+
word_size *= 8
|
4
|
+
self >> shift | (self << (word_size - shift) & (2**word_size - 1))
|
5
|
+
end
|
6
|
+
end
|
7
|
+
|
8
|
+
module Blake
|
9
|
+
class Main
|
10
|
+
##
|
11
|
+
# IVx for BLAKE-x
|
12
|
+
IV64 = [
|
13
|
+
0x6a09e667f3bcc908, 0xbb67ae8584caa73b,
|
14
|
+
0x3c6ef372fe94f82b, 0xa54ff53a5f1d36f1,
|
15
|
+
0x510e527fade682d1, 0x9b05688c2b3e6c1f,
|
16
|
+
0x1f83d9abfb41bd6b, 0x5be0cd19137e2179
|
17
|
+
].freeze
|
18
|
+
|
19
|
+
IV48 = [
|
20
|
+
0xcbbb9d5dc1059ed8, 0x629a292a367cd507,
|
21
|
+
0x9159015a3070dd17, 0x152fecd8f70e5939,
|
22
|
+
0x67332667ffc00b31, 0x8eb44a8768581511,
|
23
|
+
0xdb0c2e0d64f98fa7, 0x47b5481dbefa4fa4
|
24
|
+
].freeze
|
25
|
+
|
26
|
+
##
|
27
|
+
# The values here are the same as the high-order half-words of IV64
|
28
|
+
IV32 = [
|
29
|
+
0x6a09e667, 0xbb67ae85,
|
30
|
+
0x3c6ef372, 0xa54ff53a,
|
31
|
+
0x510e527f, 0x9b05688c,
|
32
|
+
0x1f83d9ab, 0x5be0cd19
|
33
|
+
].freeze
|
34
|
+
|
35
|
+
##
|
36
|
+
# The values here are the same as the low-order half-words of IV48
|
37
|
+
IV28 = [
|
38
|
+
0xc1059ed8, 0x367cd507,
|
39
|
+
0x3070dd17, 0xf70e5939,
|
40
|
+
0xffc00b31, 0x68581511,
|
41
|
+
0x64f98fa7, 0xbefa4fa4
|
42
|
+
].freeze
|
43
|
+
|
44
|
+
##
|
45
|
+
# constants for BLAKE-64 and BLAKE-48
|
46
|
+
C64 = [
|
47
|
+
0x243f6a8885a308d3, 0x13198a2e03707344,
|
48
|
+
0xa4093822299f31d0, 0x082efa98ec4e6c89,
|
49
|
+
0x452821e638d01377, 0xbe5466cf34e90c6c,
|
50
|
+
0xc0ac29b7c97c50dd, 0x3f84d5b5b5470917,
|
51
|
+
0x9216d5d98979fb1b, 0xd1310ba698dfb5ac,
|
52
|
+
0x2ffd72dbd01adfb7, 0xb8e1afed6a267e96,
|
53
|
+
0xba7c9045f12c7f99, 0x24a19947b3916cf7,
|
54
|
+
0x0801f2e2858efc16, 0x636920d871574e69
|
55
|
+
].freeze
|
56
|
+
|
57
|
+
##
|
58
|
+
# constants for BLAKE-32 and BLAKE-28
|
59
|
+
# Concatenate and the values are the same as the values
|
60
|
+
# for the 1st half of C64
|
61
|
+
C32 = [
|
62
|
+
0x243f6a88, 0x85a308d3,
|
63
|
+
0x13198a2e, 0x03707344,
|
64
|
+
0xa4093822, 0x299f31d0,
|
65
|
+
0x082efa98, 0xec4e6c89,
|
66
|
+
0x452821e6, 0x38d01377,
|
67
|
+
0xbe5466cf, 0x34e90c6c,
|
68
|
+
0xc0ac29b7, 0xc97c50dd,
|
69
|
+
0x3f84d5b5, 0xb5470917
|
70
|
+
].freeze
|
71
|
+
|
72
|
+
##
|
73
|
+
# the 10 permutations of: 0,...15}
|
74
|
+
SIGMA = [
|
75
|
+
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15],
|
76
|
+
[14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3],
|
77
|
+
[11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4],
|
78
|
+
[7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8],
|
79
|
+
[9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13],
|
80
|
+
[2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9],
|
81
|
+
[12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11],
|
82
|
+
[13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10],
|
83
|
+
[6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5],
|
84
|
+
[10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0],
|
85
|
+
].freeze
|
86
|
+
|
87
|
+
V_STEP = [
|
88
|
+
[0, 4, 8, 12],
|
89
|
+
[1, 5, 9, 13],
|
90
|
+
[2, 6, 10, 14],
|
91
|
+
[3, 7, 11, 15],
|
92
|
+
[0, 5, 10, 15],
|
93
|
+
[1, 6, 11, 12],
|
94
|
+
[2, 7, 8, 13],
|
95
|
+
[3, 4, 9, 14],
|
96
|
+
].freeze
|
97
|
+
|
98
|
+
MASK64BITS = 0xFFFFFFFFFFFFFFFF
|
99
|
+
|
100
|
+
# private_class_method :new
|
101
|
+
|
102
|
+
def initialize(output_size = 512, salt = nil)
|
103
|
+
self.output_size = output_size
|
104
|
+
self.salt = salt
|
105
|
+
|
106
|
+
if output_words <= 32
|
107
|
+
@word_size = 4
|
108
|
+
@pack_code = 'L>'
|
109
|
+
@num_rounds = 14
|
110
|
+
@pi = C32
|
111
|
+
@rot_off = [16, 12, 8, 7]
|
112
|
+
else
|
113
|
+
@word_size = 8
|
114
|
+
@pack_code = 'Q>'
|
115
|
+
@num_rounds = 16
|
116
|
+
@pi = C64
|
117
|
+
@rot_off = [32, 25, 16, 11]
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
def mask
|
122
|
+
@mask ||= 2**(@word_size * 8) - 1
|
123
|
+
end
|
124
|
+
|
125
|
+
def block_size
|
126
|
+
@block_size ||= @word_size * 16
|
127
|
+
end
|
128
|
+
|
129
|
+
def output_words
|
130
|
+
@output_words ||= @output_size / 8
|
131
|
+
end
|
132
|
+
|
133
|
+
def digest(input, salt = @salt)
|
134
|
+
# use a different salt just this once if one has been provided
|
135
|
+
orig_salt = @salt
|
136
|
+
self.salt = salt if salt != @salt
|
137
|
+
|
138
|
+
# pad input and append its length in bits
|
139
|
+
total_bits = input.length * 8
|
140
|
+
input << "\x80" # mark the end of the input
|
141
|
+
rem = (input.length + @word_size * 2) % block_size
|
142
|
+
# pad to block size - (2 * word size)
|
143
|
+
input << ("\0" * (block_size - rem)) if rem.positive?
|
144
|
+
# set last marker bit
|
145
|
+
input[-1] = (input[-1].ord | 0x01).chr if (output_words % 32).zero?
|
146
|
+
# append high-order bytes of input bit length
|
147
|
+
input << [total_bits >> 64].pack('Q>') if @word_size == 8
|
148
|
+
# append low-order bytes of input bit length
|
149
|
+
input << [total_bits & MASK64BITS].pack('Q>')
|
150
|
+
|
151
|
+
@state = case output_words
|
152
|
+
when 28 then IV28.dup
|
153
|
+
when 32 then IV32.dup
|
154
|
+
when 48 then IV48.dup
|
155
|
+
when 64 then IV64.dup
|
156
|
+
end
|
157
|
+
|
158
|
+
@next_offset = 0
|
159
|
+
|
160
|
+
while input.length.positive?
|
161
|
+
block = input.slice!(0, block_size).unpack(@pack_code + '*')
|
162
|
+
@next_offset += block_size * 8
|
163
|
+
# next_offset must only count input data, not padding, and must be 0 if the block contains only padding
|
164
|
+
if @next_offset >= total_bits
|
165
|
+
@next_offset = total_bits
|
166
|
+
total_bits = 0
|
167
|
+
end
|
168
|
+
chacha(block)
|
169
|
+
end
|
170
|
+
|
171
|
+
@salt = orig_salt
|
172
|
+
|
173
|
+
@state.pack(@pack_code + '*')[0...output_words]
|
174
|
+
end
|
175
|
+
|
176
|
+
def chacha(block)
|
177
|
+
v = @state[0..7] + @pi[0..7]
|
178
|
+
(0..3).each { |i| v[8 + i] ^= @salt[i] }
|
179
|
+
if @next_offset != 0
|
180
|
+
v[12] ^= @next_offset & mask
|
181
|
+
v[13] ^= @next_offset & mask
|
182
|
+
v[14] ^= @next_offset >> (@word_size * 8)
|
183
|
+
v[15] ^= @next_offset >> (@word_size * 8)
|
184
|
+
end
|
185
|
+
|
186
|
+
(0...@num_rounds).each do |r|
|
187
|
+
(0..7).each do |i|
|
188
|
+
step = V_STEP[i]
|
189
|
+
a, b, c, d = step.map { |x| v[x] }
|
190
|
+
|
191
|
+
j = SIGMA[r % 10][i *= 2]
|
192
|
+
k = SIGMA[r % 10][i + 1]
|
193
|
+
a = a + b + (block[j] ^ @pi[k]) & mask
|
194
|
+
d = (d ^ a).ror(@rot_off[0], @word_size)
|
195
|
+
c = c + d & mask
|
196
|
+
b = (b ^ c).ror(@rot_off[1], @word_size)
|
197
|
+
a = a + b + (block[k] ^ @pi[j]) & mask
|
198
|
+
d = (d ^ a).ror(@rot_off[2], @word_size)
|
199
|
+
c = c + d & mask
|
200
|
+
b = (b ^ c).ror(@rot_off[3], @word_size)
|
201
|
+
|
202
|
+
v[step[0]] = a
|
203
|
+
v[step[1]] = b
|
204
|
+
v[step[2]] = c
|
205
|
+
v[step[3]] = d
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
209
|
+
(0..7).each { |i| @state[i] ^= v[i] ^ v[8 + i] ^ @salt[i & 0x03] }
|
210
|
+
end
|
211
|
+
|
212
|
+
private
|
213
|
+
|
214
|
+
attr_reader :output_size, :salt
|
215
|
+
|
216
|
+
def output_size=(value)
|
217
|
+
unless value.is_a? Integer
|
218
|
+
raise TypeError, "Expected #{Integer}, got #{value.class}"
|
219
|
+
end
|
220
|
+
|
221
|
+
@output_size = value
|
222
|
+
end
|
223
|
+
|
224
|
+
def salt=(salt)
|
225
|
+
if !salt
|
226
|
+
@salt = [0] * 4
|
227
|
+
elsif salt.is_a?(Array) && salt.length == 4
|
228
|
+
@salt = salt
|
229
|
+
elsif salt.length == @word_size * 4
|
230
|
+
@salt = salt.unpack(@pack_code + '*')
|
231
|
+
else
|
232
|
+
raise "salt must be #{@word_size * 4} bytes"
|
233
|
+
end
|
234
|
+
end
|
235
|
+
end
|
236
|
+
end
|
metadata
ADDED
@@ -0,0 +1,164 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: blake.rb
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Daniel Cavanagh (danielcavanagh)
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2020-02-22 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.16'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.16'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: pry
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0.12'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0.12'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rake
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '12.3'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '12.3'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rspec
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '3.8'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '3.8'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rubocop
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0.73'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0.73'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rubocop-performance
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '1.5'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '1.5'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: simplecov
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0.17'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0.17'
|
111
|
+
description: BLAKE is a cryptographic hash function based on Dan Bernstein's ChaCha
|
112
|
+
stream cipher, but a permuted copy of the input block, XORed with round constants,
|
113
|
+
is added before each ChaCha round. Like SHA-2, there are two variants differing
|
114
|
+
in the word size. ChaCha operates on a 4×4 array of words. BLAKE repeatedly combines
|
115
|
+
an 8-word hash value with 16 message words, truncating the ChaCha result to obtain
|
116
|
+
the next hash value. BLAKE-256 and BLAKE-224 use 32-bit words and produce digest
|
117
|
+
sizes of 256 bits and 224 bits, respectively, while BLAKE-512 and BLAKE-384 use
|
118
|
+
64-bit words and produce digest sizes of 512 bits and 384 bits, respectively.
|
119
|
+
email:
|
120
|
+
executables: []
|
121
|
+
extensions: []
|
122
|
+
extra_rdoc_files: []
|
123
|
+
files:
|
124
|
+
- ".gitignore"
|
125
|
+
- ".rubocop.yml"
|
126
|
+
- ".rubocop_todo.yml"
|
127
|
+
- ".simplecov"
|
128
|
+
- ".travis.yml"
|
129
|
+
- Gemfile
|
130
|
+
- LICENSE
|
131
|
+
- README.md
|
132
|
+
- Rakefile
|
133
|
+
- blake.gemspec
|
134
|
+
- lib/blake.rb
|
135
|
+
- lib/blake/main.rb
|
136
|
+
- lib/blake/version.rb
|
137
|
+
homepage: https://github.com/ydakuka/blake.rb
|
138
|
+
licenses:
|
139
|
+
- MIT
|
140
|
+
metadata:
|
141
|
+
homepage_uri: https://github.com/ydakuka/blake.rb
|
142
|
+
source_code_uri: https://github.com/ydakuka/blake.rb
|
143
|
+
bug_tracker_uri: https://github.com/ydakuka/blake.rb/issues
|
144
|
+
post_install_message:
|
145
|
+
rdoc_options: []
|
146
|
+
require_paths:
|
147
|
+
- lib
|
148
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - ">="
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: '0'
|
153
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
154
|
+
requirements:
|
155
|
+
- - ">="
|
156
|
+
- !ruby/object:Gem::Version
|
157
|
+
version: '0'
|
158
|
+
requirements: []
|
159
|
+
rubyforge_project:
|
160
|
+
rubygems_version: 2.7.7
|
161
|
+
signing_key:
|
162
|
+
specification_version: 4
|
163
|
+
summary: BLAKE hash function library for ruby
|
164
|
+
test_files: []
|