1
0
Fork 0

Move into module

This commit is contained in:
Alex Kotov 2019-09-21 11:27:55 +05:00
parent 07d60f1537
commit 15a8690010
Signed by: kotovalexarian
GPG Key ID: 553C0EBBEB5D5F08
22 changed files with 147 additions and 133 deletions

2
.gitignore vendored
View File

@ -5,7 +5,7 @@
# git config --global core.excludesfile '~/.gitignore_global'
/lib/*.bundle
/lib/blake2b_ext.so
/lib/digest/blake2b_ext.so
*.o
*.gem

View File

@ -2,9 +2,9 @@ require 'bundler/gem_tasks'
require 'rake/testtask'
require 'rake/extensiontask'
spec = Gem::Specification.load('blake2b.gemspec')
spec = Gem::Specification.load('digest-blake2b.gemspec')
Rake::ExtensionTask.new('blake2b_ext', spec) do |ext|
Rake::ExtensionTask.new('digest/blake2b_ext', spec) do |ext|
ext.source_pattern = '*.{c,h}'
end
@ -22,7 +22,7 @@ task full: %w(clean compile test)
def gemspec
@gemspec ||= begin
file = File.expand_path('../blake2b.gemspec', __FILE__)
file = File.expand_path('digest-blake2b.gemspec', __dir__)
eval(File.read(file), binding, file)
end
end
@ -35,7 +35,7 @@ end
desc "Build the gem"
task :gem => [:gemspec, :build] do
mkdir_p "pkg"
sh "gem build blake2b.gemspec"
sh "gem build digest-blake2b.gemspec"
mv "#{gemspec.full_name}.gem", "pkg"
require 'digest/sha2'

View File

@ -40,7 +40,7 @@ Gem::Specification.new do |spec|
spec.executables = spec.files.grep %r{^exe/}, &File.method(:basename)
spec.extensions << 'ext/blake2b_ext/extconf.rb'
spec.extensions << 'ext/digest/blake2b_ext/extconf.rb'
spec.add_development_dependency 'rake-compiler', '~> 0.9'
spec.add_development_dependency 'bundler' , '~> 1.5'

View File

@ -1,3 +1,3 @@
require 'mkmf'
$CFLAGS += ' -Wall -Wextra -std=c99 -pedantic -Wno-long-long'
create_makefile 'blake2b_ext'
create_makefile 'digest/blake2b_ext'

View File

@ -13,7 +13,8 @@ typedef struct {
VALUE to_bytes;
} Blake2;
VALUE cBlake2;
VALUE mDigest;
VALUE mDigest_cBlake2;
static void blake2_free(Blake2 *blake2) {
free(blake2->key_bytes);
@ -100,9 +101,11 @@ VALUE m_blake2_digest(VALUE self, VALUE _input, VALUE _representation) {
}
void Init_blake2b_ext() {
cBlake2 = rb_define_class("Blake2b", rb_cObject);
rb_define_alloc_func(cBlake2, blake2_alloc);
mDigest = rb_define_module("Digest");
rb_define_private_method(cBlake2, "initialize", RUBY_METHOD_FUNC(m_blake2_initialize), 2);
rb_define_method(cBlake2, "digest", RUBY_METHOD_FUNC(m_blake2_digest), 2);
mDigest_cBlake2 = rb_define_class_under(mDigest, "Blake2b", rb_cObject);
rb_define_alloc_func(mDigest_cBlake2, blake2_alloc);
rb_define_private_method(mDigest_cBlake2, "initialize", RUBY_METHOD_FUNC(m_blake2_initialize), 2);
rb_define_method(mDigest_cBlake2, "digest", RUBY_METHOD_FUNC(m_blake2_digest), 2);
}

View File

@ -1,29 +0,0 @@
require 'blake2b_ext'
require 'blake2b/key'
class Blake2b
def self.hex(input, key = Blake2b::Key.none, out_len = 32)
check_if_valid!(input, key, out_len)
Blake2b.new(out_len, key).digest(input, :to_hex)
end
def self.bytes(input, key = Blake2b::Key.none, out_len = 32)
check_if_valid!(input, key, out_len)
Blake2b.new(out_len, key).digest(input, :to_bytes)
end
def self.check_if_valid!(input, key, out_len)
unless input.is_a?(String)
raise ArgumentError, 'input arg must be a String'
end
unless key.is_a?(Blake2b::Key)
raise ArgumentError, 'key arg must be a Blake2b::Key'
end
unless out_len.is_a?(Integer) && out_len.between?(1, 64)
raise ArgumentError, 'out_len arg must be an Integer between 1 and 64 inclusive'
end
end
private_class_method :check_if_valid!
end

View File

@ -1,55 +0,0 @@
class Blake2b
# Validate and normalize an HMAC key, provided in different formats,
# into an Array of Integer Bytes.
class Key
attr_reader :bytes
def initialize(bytes)
@bytes = bytes
end
# Create a blank Key
#
# @return [Blake2b::Key] a Blake2b::Key object with a `bytes` attr
def self.none
new([])
end
# Create a key from an ASCII String
#
# @param str [String] an ASCII String key
# @return [Blake2b::Key] a Blake2b::Key object with a `bytes` attr
def self.from_string(str)
if str.is_a?(String) && str.ascii_only?
new(str.bytes)
else
raise ArgumentError, 'key must be an ASCII String'
end
end
# Create a key from a Hex String [a-fA-F0-9]
#
# @param str [String] a Hex String key
# @return [Blake2b::Key] a Blake2b::Key object with a `bytes` attr
def self.from_hex(str)
if str.is_a?(String) && str.match(/^[a-fA-F0-9]+$/)
new([str].pack('H*').bytes)
else
raise ArgumentError, 'key must be a Hex String [a-fA-F0-9]'
end
end
# Create a key from Array of Integer (0-255) Bytes.
# This simply validates and passes through the Array.
#
# @param str [Array] an Array of Integer (0-255) Bytes
# @return [Blake2b::Key] a Blake2b::Key object with a `bytes` attr
def self.from_bytes(bytes)
if bytes.all? { |b| b.is_a?(Integer) && b.between?(0, 255) }
new(bytes)
else
raise ArgumentError, 'key must be a Byte Array of Integers (0-255)'
end
end
end
end

36
lib/digest/blake2b.rb Normal file
View File

@ -0,0 +1,36 @@
# frozen_string_literal: true
require 'digest/blake2b_ext'
require 'digest/blake2b/key'
require 'digest/blake2b/version'
module Digest
class Blake2b
def self.hex(input, key = Blake2b::Key.none, out_len = 32)
check_if_valid!(input, key, out_len)
Blake2b.new(out_len, key).digest(input, :to_hex)
end
def self.bytes(input, key = Blake2b::Key.none, out_len = 32)
check_if_valid!(input, key, out_len)
Blake2b.new(out_len, key).digest(input, :to_bytes)
end
def self.check_if_valid!(input, key, out_len)
unless input.is_a?(String)
raise ArgumentError, 'input arg must be a String'
end
unless key.is_a?(Blake2b::Key)
raise ArgumentError, 'key arg must be a Blake2b::Key'
end
unless out_len.is_a?(Integer) && out_len.between?(1, 64)
raise ArgumentError, 'out_len arg must be an Integer between 1 and 64 inclusive'
end
end
private_class_method :check_if_valid!
end
end

59
lib/digest/blake2b/key.rb Executable file
View File

@ -0,0 +1,59 @@
# frozen_string_literal: true
module Digest
class Blake2b
# Validate and normalize an HMAC key, provided in different formats,
# into an Array of Integer Bytes.
class Key
attr_reader :bytes
def initialize(bytes)
@bytes = bytes
end
# Create a blank Key
#
# @return [Blake2b::Key] a Blake2b::Key object with a `bytes` attr
def self.none
new([])
end
# Create a key from an ASCII String
#
# @param str [String] an ASCII String key
# @return [Blake2b::Key] a Blake2b::Key object with a `bytes` attr
def self.from_string(str)
if str.is_a?(String) && str.ascii_only?
new(str.bytes)
else
raise ArgumentError, 'key must be an ASCII String'
end
end
# Create a key from a Hex String [a-fA-F0-9]
#
# @param str [String] a Hex String key
# @return [Blake2b::Key] a Blake2b::Key object with a `bytes` attr
def self.from_hex(str)
if str.is_a?(String) && str.match(/^[a-fA-F0-9]+$/)
new([str].pack('H*').bytes)
else
raise ArgumentError, 'key must be a Hex String [a-fA-F0-9]'
end
end
# Create a key from Array of Integer (0-255) Bytes.
# This simply validates and passes through the Array.
#
# @param str [Array] an Array of Integer (0-255) Bytes
# @return [Blake2b::Key] a Blake2b::Key object with a `bytes` attr
def self.from_bytes(bytes)
if bytes.all? { |b| b.is_a?(Integer) && b.between?(0, 255) }
new(bytes)
else
raise ArgumentError, 'key must be a Byte Array of Integers (0-255)'
end
end
end
end
end

View File

@ -2,41 +2,41 @@ require 'test_helper'
class KeyTest < MiniTest::Test
def test_none
key = Blake2b::Key.none
key = Digest::Blake2b::Key.none
assert_equal [], key.bytes
end
def test_from_string
key = Blake2b::Key.from_string('foo bar baz')
key = Digest::Blake2b::Key.from_string('foo bar baz')
assert_equal [102, 111, 111, 32, 98, 97, 114, 32, 98, 97, 122], key.bytes
end
def test_from_string_raises_on_non_ascii_string
assert_raises(ArgumentError) { Blake2b::Key.from_string('💩') }
assert_raises(ArgumentError) { Digest::Blake2b::Key.from_string('💩') }
end
def test_from_hex
key = Blake2b::Key.from_hex('DEADBEAF')
key = Digest::Blake2b::Key.from_hex('DEADBEAF')
assert_equal [222, 173, 190, 175], key.bytes
end
def test_from_hex_raises_on_non_hex_string
assert_raises(ArgumentError) { Blake2b::Key.from_hex('DEADBEAFZZ') }
assert_raises(ArgumentError) { Digest::Blake2b::Key.from_hex('DEADBEAFZZ') }
end
def test_from_bytes_hex
key = Blake2b::Key.from_bytes([0xDE, 0xAD, 0xBE, 0xAF])
key = Digest::Blake2b::Key.from_bytes([0xDE, 0xAD, 0xBE, 0xAF])
assert_equal [222, 173, 190, 175], key.bytes
end
def test_from_bytes_int
key = Blake2b::Key.from_bytes([222, 173, 190, 175])
key = Digest::Blake2b::Key.from_bytes([222, 173, 190, 175])
assert_equal [222, 173, 190, 175], key.bytes
end
def test_from_hex_raises_on_non_valid_byte_array
assert_raises(ArgumentError) { Blake2b::Key.from_bytes([-1]) }
assert_raises(ArgumentError) { Blake2b::Key.from_bytes([256]) }
assert_raises(ArgumentError) { Blake2b::Key.from_bytes(['foo']) }
assert_raises(ArgumentError) { Digest::Blake2b::Key.from_bytes([-1]) }
assert_raises(ArgumentError) { Digest::Blake2b::Key.from_bytes([256]) }
assert_raises(ArgumentError) { Digest::Blake2b::Key.from_bytes(['foo']) }
end
end

View File

@ -2,13 +2,13 @@ require 'test_helper'
class Blake2bTest < MiniTest::Test
def test_hex_with_input_only
res = Blake2b.hex('abc')
res = Digest::Blake2b.hex('abc')
assert_kind_of String, res
assert_equal 'bddd813c634239723171ef3fee98579b94964e3bb1cb3e427262c8c068d52319', res
end
def test_hex_with_input_and_key
res = Blake2b.hex('abc', Blake2b::Key.none)
res = Digest::Blake2b.hex('abc', Digest::Blake2b::Key.none)
assert_kind_of String, res
assert_equal 'bddd813c634239723171ef3fee98579b94964e3bb1cb3e427262c8c068d52319', res
end
@ -16,59 +16,59 @@ class Blake2bTest < MiniTest::Test
# From the computation in the RFC
# https://tools.ietf.org/html/rfc7693#appendix-A
def test_hex_with_input_key_and_length
res = Blake2b.hex('abc', Blake2b::Key.none, 64)
res = Digest::Blake2b.hex('abc', Digest::Blake2b::Key.none, 64)
assert_kind_of String, res
assert_equal 'ba80a53f981c4d0d6a2797b69f12f6e94c212f14685ac4b74b12bb6fdbffa2d17d87c5392aab792dc252d5de4533cc9518d38aa8dbf1925ab92386edd4009923', res
end
def test_hex_with_blank_input_key_and_length
res = Blake2b.hex('', Blake2b::Key.none, 64)
res = Digest::Blake2b.hex('', Digest::Blake2b::Key.none, 64)
assert_kind_of String, res
assert_equal '786a02f742015903c6c6fd852552d272912f4740e15847618a86e217f71f5419d25e1031afee585313896444934eb04b903a685b1448b755d56f701afe9be2ce', res
end
def test_hex_with_known_input_key_and_length
res = Blake2b.hex('The quick brown fox jumps over the lazy dog', Blake2b::Key.none, 64)
res = Digest::Blake2b.hex('The quick brown fox jumps over the lazy dog', Digest::Blake2b::Key.none, 64)
assert_kind_of String, res
assert_equal 'a8add4bdddfd93e4877d2746e62817b116364a1fa7bc148d95090bc7333b3673f82401cf7aa2e4cb1ecd90296e3f14cb5413f8ed77be73045b13914cdcd6a918', res
end
def test_bytes_with_input_only
res = Blake2b.bytes('abc')
res = Digest::Blake2b.bytes('abc')
assert_kind_of Array, res
assert_equal [189, 221, 129, 60, 99, 66, 57, 114, 49, 113, 239, 63, 238, 152, 87, 155, 148, 150, 78, 59, 177, 203, 62, 66, 114, 98, 200, 192, 104, 213, 35, 25], res
end
def test_bytes_with_input_and_key
res = Blake2b.bytes('abc', Blake2b::Key.none)
res = Digest::Blake2b.bytes('abc', Digest::Blake2b::Key.none)
assert_kind_of Array, res
assert_equal [189, 221, 129, 60, 99, 66, 57, 114, 49, 113, 239, 63, 238, 152, 87, 155, 148, 150, 78, 59, 177, 203, 62, 66, 114, 98, 200, 192, 104, 213, 35, 25], res
end
def test_bytes_with_input_key_and_length
res = Blake2b.bytes('abc', Blake2b::Key.none, 32)
res = Digest::Blake2b.bytes('abc', Digest::Blake2b::Key.none, 32)
assert_kind_of Array, res
assert_equal [189, 221, 129, 60, 99, 66, 57, 114, 49, 113, 239, 63, 238, 152, 87, 155, 148, 150, 78, 59, 177, 203, 62, 66, 114, 98, 200, 192, 104, 213, 35, 25], res
end
def test_input_raises_on_non_string
assert_raises(ArgumentError) { Blake2b.hex(nil) }
assert_raises(ArgumentError) { Blake2b.bytes(nil) }
assert_raises(ArgumentError) { Digest::Blake2b.hex(nil) }
assert_raises(ArgumentError) { Digest::Blake2b.bytes(nil) }
end
def test_key_raises_on_non_key
assert_raises(ArgumentError) { Blake2b.hex('abc', []) }
assert_raises(ArgumentError) { Blake2b.bytes('abc', []) }
assert_raises(ArgumentError) { Digest::Blake2b.hex('abc', []) }
assert_raises(ArgumentError) { Digest::Blake2b.bytes('abc', []) }
end
def test_length_raises_on_invalid
assert_raises(ArgumentError) { Blake2b.hex('abc', Blake2b::Key.none, -1) }
assert_raises(ArgumentError) { Blake2b.hex('abc', Blake2b::Key.none, 0) }
assert_raises(ArgumentError) { Blake2b.hex('abc', Blake2b::Key.none, 65) }
assert_raises(ArgumentError) { Blake2b.hex('abc', Blake2b::Key.none, '32') }
assert_raises(ArgumentError) { Blake2b.bytes('abc', Blake2b::Key.none, -1) }
assert_raises(ArgumentError) { Blake2b.bytes('abc', Blake2b::Key.none, 0) }
assert_raises(ArgumentError) { Blake2b.bytes('abc', Blake2b::Key.none, 65) }
assert_raises(ArgumentError) { Blake2b.bytes('abc', Blake2b::Key.none, '32') }
assert_raises(ArgumentError) { Digest::Blake2b.hex('abc', Digest::Blake2b::Key.none, -1) }
assert_raises(ArgumentError) { Digest::Blake2b.hex('abc', Digest::Blake2b::Key.none, 0) }
assert_raises(ArgumentError) { Digest::Blake2b.hex('abc', Digest::Blake2b::Key.none, 65) }
assert_raises(ArgumentError) { Digest::Blake2b.hex('abc', Digest::Blake2b::Key.none, '32') }
assert_raises(ArgumentError) { Digest::Blake2b.bytes('abc', Digest::Blake2b::Key.none, -1) }
assert_raises(ArgumentError) { Digest::Blake2b.bytes('abc', Digest::Blake2b::Key.none, 0) }
assert_raises(ArgumentError) { Digest::Blake2b.bytes('abc', Digest::Blake2b::Key.none, 65) }
assert_raises(ArgumentError) { Digest::Blake2b.bytes('abc', Digest::Blake2b::Key.none, '32') }
end
end

View File

@ -3,9 +3,9 @@ require 'test_helper'
class Blake2bTest < MiniTest::Test
def setup
out_len = 64
key = Blake2b::Key.from_string('foo bar baz')
key = Digest::Blake2b::Key.from_string('foo bar baz')
@digestor = Blake2b.new(out_len, key)
@digestor = Digest::Blake2b.new(out_len, key)
@input = 'The quick brown fox jumps over the lazy dog'
@expected = '2c2d3abee08b19d67e4de4e953bbe0dba2f9e878f61e087191d00cf459a173281d93b0e28ea5303fe488312178dd7603d45b8d09311affe4aaa9a467cae3c9ef'

View File

@ -535,7 +535,7 @@ class Blake2bVectorTest < MiniTest::Test
j += 1
end
res = Blake2b.new(64, Blake2b::Key.none).digest(bytes_to_string(buf), :to_hex)
res = Digest::Blake2b.new(64, Digest::Blake2b::Key.none).digest(bytes_to_string(buf), :to_hex)
assert_kind_of String, res
assert_equal @golden[i], res
end
@ -553,7 +553,7 @@ class Blake2bVectorTest < MiniTest::Test
j += 1
end
res = Blake2b.new(64, Blake2b::Key.from_string(bytes_to_string(key))).digest(bytes_to_string(buf), :to_hex)
res = Digest::Blake2b.new(64, Digest::Blake2b::Key.from_string(bytes_to_string(key))).digest(bytes_to_string(buf), :to_hex)
assert_kind_of String, res
assert_equal @golden_keyed[i], res
end
@ -572,7 +572,7 @@ class Blake2bVectorTest < MiniTest::Test
j += 1
end
res = Blake2b.new(64, Blake2b::Key.from_hex(key_hex)).digest(bytes_to_string(buf), :to_hex)
res = Digest::Blake2b.new(64, Digest::Blake2b::Key.from_hex(key_hex)).digest(bytes_to_string(buf), :to_hex)
assert_kind_of String, res
assert_equal @golden_keyed[i], res
end

View File

@ -3,7 +3,7 @@ require 'test_helper'
class Blake2bGCTest < MiniTest::Test
def test_a_million_iteration
1_000_000.times do |i|
Blake2b.new(32, Blake2b::Key.none).digest('abc', :to_hex)
Digest::Blake2b.new(32, Digest::Blake2b::Key.none).digest('abc', :to_hex)
end
end
end

View File

@ -1,3 +1,3 @@
require 'minitest/autorun'
require 'minitest/assertions'
require 'blake2b'
require 'digest/blake2b'