hkdf 0.3.0 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 32e2c102c323f4510551f669261ce3fe39c11dc3
4
- data.tar.gz: f2585bdce88e509b0d7acf699b0313029fb767ab
2
+ SHA256:
3
+ metadata.gz: b3981a10daf0d498be5d757d585f60d5b7ed39510da169fd57caaf05cfd19b55
4
+ data.tar.gz: 639210e0fa56a62d07483f2e67e8df7b20d35fb55f0ca55296509f1a029c906c
5
5
  SHA512:
6
- metadata.gz: 303d49a8b562e90325cc90fe5bb1ce6294de07973d6f974f136c50bc9ae23e02cb09f36c725be7394e610bd4526beea9f61b9b5aee67fa7f370a0e553a4b1713
7
- data.tar.gz: 1037d09b22dac87dea10a86a8ec1dea9f84390d43d5a9d5ace084e1d6c02a0e50ce57015a916dad6fe75f58683487cee911043168f63119c15da12ea17347685
6
+ metadata.gz: 62d0e251f2ecc9f713571a38388851a3781667c3de53f339061a7663fdb09f9a78705df12828151b5d252a59754cd401ab80dd95e36f96a255018f1721b4203d
7
+ data.tar.gz: 8be1132f9dc82666401d1034e509c3ce02aff76f63c0c033b716d50836d805747e90cc1358105176e0df9c9cbc2658aa6a23e1140d0c4c52ff11d9cc02f3a4d0
data/README.md CHANGED
@@ -1,4 +1,6 @@
1
- # HKDF [![Build Status](https://secure.travis-ci.org/jtdowney/hkdf.png?branch=master)](http://travis-ci.org/jtdowney/hkdf)
1
+ # HKDF
2
+
3
+ [![CI](https://github.com/jtdowney/hkdf/actions/workflows/ci.yml/badge.svg)](https://github.com/jtdowney/hkdf/actions/workflows/ci.yml)
2
4
 
3
5
  This is a ruby implementation of [RFC 5869](http://tools.ietf.org/html/rfc5869): HMAC-based Extract-and-Expand Key Derivation Function. The goal of HKDF is to take some source key material and generate suitable cryptographic keys from it.
4
6
 
@@ -6,7 +8,7 @@ This is a ruby implementation of [RFC 5869](http://tools.ietf.org/html/rfc5869):
6
8
 
7
9
  ```ruby
8
10
  hkdf = HKDF.new('source key material')
9
- hkdf.next_bytes(32)
11
+ hkdf.read(32)
10
12
  => "\f#\xF4b\x98\x9B\x7Fw>|/|k\xF4k\xB7\xB9\x11e\xC5\x92\xD1\fH\xFDG\x94vt\xB4\x14\xCE"
11
13
  ```
12
14
 
@@ -14,14 +16,18 @@ The default algorithm is HMAC-SHA256, you can override this and other defaults b
14
16
 
15
17
  ```ruby
16
18
  hkdf = HKDF.new('source key material', :salt => 'NaCl', :algorithm => 'SHA1', :info => 'the 411')
17
- hkdf.next_bytes(16)
19
+ hkdf.read(16)
18
20
  => "\xC0<\x13\x85\x8C\x84z\xCE\xC7\xCE+\xFF\x1C\xEB\xE6\xBC"
19
21
  ```
20
22
 
21
- You can also give an IO object as the source. It will be read in as a stream to generate the key. The optional argument ```:read_size``` can be used to control how many bytes are read from the IO at a time.
23
+ You can also give an IO object as the source. It will be read in as a stream to generate the key. The optional argument `:read_size` can be used to control how many bytes are read from the IO at a time.
22
24
 
23
25
  ```ruby
24
26
  hkdf = HKDF.new(File.new('/tmp/filename'), :read_size => 512)
25
- hkdf.next_bytes(32)
27
+ hkdf.read(32)
26
28
  => "\f#\xF4b\x98\x9B\x7Fw>|/|k\xF4k\xB7\xB9\x11e\xC5\x92\xD1\fH\xFDG\x94vt\xB4\x14\xCE"
27
29
  ```
30
+
31
+ ## Requirements
32
+
33
+ - Ruby >= 2.4
data/lib/hkdf.rb CHANGED
@@ -1,74 +1,96 @@
1
- require 'openssl'
2
- require 'stringio'
1
+ # frozen_string_literal: true
3
2
 
4
- class HKDF
5
- DefaultAlgorithm = 'SHA256'
6
- DefaultReadSize = 512 * 1024
3
+ require "openssl"
4
+ require "stringio"
7
5
 
6
+ # Provide HMAC-based Extract-and-Expand Key Derivation Function (HKDF) for Ruby.
7
+ class HKDF
8
+ # Default hash algorithm to use for HMAC.
9
+ DEFAULT_ALGOTIHM = "SHA256"
10
+ # Default buffer size for reading source IO.
11
+ DEFAULT_READ_SIZE = 512 * 1024
12
+
13
+ # Create a new HKDF instance with then provided +source+ key material.
14
+ #
15
+ # Options:
16
+ # - +algorithm:+ hash function to use (defaults to SHA-256)
17
+ # - +info:+ optional context and application specific information
18
+ # - +salt:+ optional salt value (a non-secret random value)
19
+ # - +read_size:+ buffer size when reading from a source IO
8
20
  def initialize(source, options = {})
9
21
  source = StringIO.new(source) if source.is_a?(String)
10
22
 
11
- algorithm = options.fetch(:algorithm, DefaultAlgorithm)
23
+ algorithm = options.fetch(:algorithm, DEFAULT_ALGOTIHM)
12
24
  @digest = OpenSSL::Digest.new(algorithm)
13
- @info = options.fetch(:info, '')
25
+ @info = options.fetch(:info, "")
14
26
 
15
27
  salt = options[:salt]
16
- salt = 0.chr * @digest.digest_length if salt.nil? or salt.empty?
17
- read_size = options.fetch(:read_size, DefaultReadSize)
28
+ salt = 0.chr * @digest.digest_length if salt.nil? || salt.empty?
29
+ read_size = options.fetch(:read_size, DEFAULT_READ_SIZE)
18
30
 
19
- @prk = _generate_prk(salt, source, read_size)
31
+ @prk = generate_prk(salt, source, read_size)
20
32
  @position = 0
21
- @blocks = []
22
- @blocks << ''
33
+ @blocks = [""]
23
34
  end
24
35
 
36
+ # Returns the hash algorithm this instance was configured with.
25
37
  def algorithm
26
38
  @digest.name
27
39
  end
28
40
 
41
+ # Maximum length that can be derived per the RFC.
29
42
  def max_length
30
43
  @max_length ||= @digest.digest_length * 255
31
44
  end
32
45
 
46
+ # Adjust the reading position to an arbitrary offset. Will raise +RangeError+ if you attempt to seek longer than
47
+ # +#max_length+.
33
48
  def seek(position)
34
- raise RangeError.new("cannot seek past #{max_length}") if position > max_length
49
+ raise RangeError, "cannot seek past #{max_length}" if position > max_length
35
50
 
36
51
  @position = position
37
52
  end
38
53
 
54
+ # Adjust reading position back to the beginning.
39
55
  def rewind
40
56
  seek(0)
41
57
  end
42
58
 
43
- def next_bytes(length)
59
+ # Read the next +length+ bytes from the stream. Will raise +RangeError+ if you attempt to read beyond +#max_length+.
60
+ def read(length)
44
61
  new_position = length + @position
45
- raise RangeError.new("requested #{length} bytes, only #{max_length} available") if new_position > max_length
62
+ raise RangeError, "requested #{length} bytes, only #{max_length} available" if new_position > max_length
46
63
 
47
- _generate_blocks(new_position)
64
+ generate_blocks(new_position)
48
65
 
49
66
  start = @position
50
67
  @position = new_position
51
68
 
52
- @blocks.join('').slice(start, length)
69
+ @blocks.join.slice(start, length)
53
70
  end
54
71
 
55
- def next_hex_bytes(length)
56
- next_bytes(length).unpack('H*').first
72
+ # Read the next +length+ bytes from the stream and return them hex encoded. Will raise +RangeError+ if you attempt to
73
+ # read beyond +#max_length+.
74
+ def read_hex(length)
75
+ read(length).unpack1("H*")
57
76
  end
58
77
 
78
+ # :nodoc:
59
79
  def inspect
60
80
  "#{to_s[0..-2]} algorithm=#{@digest.name.inspect} info=#{@info.inspect}>"
61
81
  end
62
82
 
63
- def _generate_prk(salt, source, read_size)
83
+ private
84
+
85
+ def generate_prk(salt, source, read_size)
64
86
  hmac = OpenSSL::HMAC.new(salt, @digest)
65
- while block = source.read(read_size)
87
+ while (block = source.read(read_size))
66
88
  hmac.update(block)
67
89
  end
68
90
  hmac.digest
69
91
  end
70
92
 
71
- def _generate_blocks(length)
93
+ def generate_blocks(length)
72
94
  start = @blocks.size
73
95
  block_count = (length.to_f / @digest.digest_length).ceil
74
96
  start.upto(block_count) do |n|
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ class HKDF
4
+ # :nodoc:
5
+ VERSION = "1.0.0"
6
+ end
data/spec/hkdf_spec.rb CHANGED
@@ -1,132 +1,139 @@
1
- require 'spec_helper'
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
2
4
 
3
5
  describe HKDF do
4
- let(:source) { 'source' }
5
6
  subject(:hkdf) do
6
- HKDF.new(source)
7
+ described_class.new(source)
7
8
  end
8
9
 
9
- describe 'initialize' do
10
- it 'accepts an IO or a string as a source' do
11
- output1 = HKDF.new(source).next_bytes(32)
12
- output2 = HKDF.new(StringIO.new(source)).next_bytes(32)
10
+ let(:source) { "source" }
11
+
12
+ describe "initialize" do
13
+ it "accepts an IO or a string as a source" do
14
+ output1 = described_class.new(source).read(32)
15
+ output2 = described_class.new(StringIO.new(source)).read(32)
13
16
  expect(output1).to eq(output2)
14
17
  end
15
18
 
16
- it 'reads in an IO at a given read size' do
17
- io = StringIO.new(source)
18
- expect(io).to receive(:read).with(1)
19
-
20
- HKDF.new(io, :read_size => 1)
19
+ it "reads in an IO at a given read size" do
20
+ io = instance_spy(StringIO, :io, read: nil)
21
+ described_class.new(io, read_size: 1)
22
+ expect(io).to have_received(:read).with(1)
21
23
  end
22
24
 
23
- it 'reads in the whole IO' do
24
- hkdf1 = HKDF.new(source, :read_size => 1)
25
- hkdf2 = HKDF.new(source)
25
+ it "reads in the whole IO" do
26
+ hkdf1 = described_class.new(source, read_size: 1)
27
+ hkdf2 = described_class.new(source)
26
28
 
27
- expect(hkdf1.next_bytes(32)).to eq(hkdf2.next_bytes(32))
29
+ expect(hkdf1.read(32)).to eq(hkdf2.read(32))
28
30
  end
29
31
 
30
- it 'defaults the algorithm to SHA-256' do
31
- expect(HKDF.new(source).algorithm).to eq('SHA256')
32
+ it "defaults the algorithm to SHA-256" do
33
+ expect(described_class.new(source).algorithm).to eq("SHA256")
32
34
  end
33
35
 
34
- it 'takes an optional digest algorithm' do
35
- hkdf = HKDF.new('source', :algorithm => 'SHA1')
36
- expect(hkdf.algorithm).to eq('SHA1')
36
+ it "takes an optional digest algorithm" do
37
+ hkdf = described_class.new("source", algorithm: "SHA1")
38
+ expect(hkdf.algorithm).to eq("SHA1")
37
39
  end
38
40
 
39
- it 'defaults salt to all zeros of digest length' do
41
+ it "defaults salt to all zeros of digest length" do
40
42
  salt = 0.chr * 32
41
43
 
42
- hkdf_salt = HKDF.new(source, :salt => salt)
43
- hkdf_nosalt = HKDF.new(source)
44
- expect(hkdf_salt.next_bytes(32)).to eq(hkdf_nosalt.next_bytes(32))
44
+ hkdf_salt = described_class.new(source, salt: salt)
45
+ hkdf_nosalt = described_class.new(source)
46
+ expect(hkdf_salt.read(32)).to eq(hkdf_nosalt.read(32))
45
47
  end
46
48
 
47
- it 'sets salt to all zeros if empty' do
48
- hkdf_blanksalt = HKDF.new(source, :salt => '')
49
- hkdf_nosalt = HKDF.new(source)
50
- expect(hkdf_blanksalt.next_bytes(32)).to eq(hkdf_nosalt.next_bytes(32))
49
+ it "sets salt to all zeros if empty" do
50
+ hkdf_blanksalt = described_class.new(source, salt: "")
51
+ hkdf_nosalt = described_class.new(source)
52
+ expect(hkdf_blanksalt.read(32)).to eq(hkdf_nosalt.read(32))
51
53
  end
52
54
 
53
- it 'defaults info to an empty string' do
54
- hkdf_info = HKDF.new(source, :info => '')
55
- hkdf_noinfo = HKDF.new(source)
56
- expect(hkdf_info.next_bytes(32)).to eq(hkdf_noinfo.next_bytes(32))
55
+ it "defaults info to an empty string" do
56
+ hkdf_info = described_class.new(source, info: "")
57
+ hkdf_noinfo = described_class.new(source)
58
+ expect(hkdf_info.read(32)).to eq(hkdf_noinfo.read(32))
57
59
  end
58
60
  end
59
61
 
60
- describe 'max_length' do
61
- it 'is 255 times the digest length' do
62
+ describe "max_length" do
63
+ it "is 255 times the digest length" do
62
64
  expect(hkdf.max_length).to eq(255 * 32)
63
65
  end
64
66
  end
65
67
 
66
- describe 'next_bytes' do
67
- it 'raises an error if requested size is > max_length' do
68
+ describe "read" do
69
+ it "does not raise if reading <= max_length" do
68
70
  expect do
69
- hkdf.next_bytes(hkdf.max_length + 1)
70
- end.to raise_error(RangeError, /requested \d+ bytes, only \d+ available/)
71
+ hkdf.read(hkdf.max_length)
72
+ end.not_to raise_error
73
+ end
71
74
 
75
+ it "raises an error if requested size is > max_length" do
72
76
  expect do
73
- hkdf.next_bytes(hkdf.max_length)
74
- end.to_not raise_error
77
+ hkdf.read(hkdf.max_length + 1)
78
+ end.to raise_error(RangeError, /requested \d+ bytes, only \d+ available/)
75
79
  end
76
80
 
77
- it 'raises an error if requested size + current position is > max_length' do
81
+ it "raises an error if requested size + current position is > max_length" do
78
82
  expect do
79
- hkdf.next_bytes(32)
80
- hkdf.next_bytes(hkdf.max_length - 31)
83
+ hkdf.read(32)
84
+ hkdf.read(hkdf.max_length - 31)
81
85
  end.to raise_error(RangeError, /requested \d+ bytes, only \d+ available/)
82
86
  end
83
87
 
84
- it 'advances the stream position' do
85
- expect(hkdf.next_bytes(32)).not_to eq(hkdf.next_bytes(32))
88
+ it "advances the stream position" do
89
+ expect(hkdf.read(32)).not_to eq(hkdf.read(32))
86
90
  end
87
91
 
88
- test_vectors.each do |name, options|
92
+ TestVectors.vectors.each do |name, options|
89
93
  it "matches output from the '#{name}' test vector" do
90
94
  options[:algorithm] = options[:Hash]
91
95
 
92
- hkdf = HKDF.new(options[:IKM], options)
93
- expect(hkdf.next_bytes(options[:L].to_i)).to eq(options[:OKM])
96
+ hkdf = described_class.new(options[:IKM], options)
97
+ expect(hkdf.read(options[:L].to_i)).to eq(options[:OKM])
94
98
  end
95
99
  end
96
100
  end
97
101
 
98
- describe 'next_hex_bytes' do
99
- it 'returns the next bytes as hex' do
100
- expect(hkdf.next_hex_bytes(20)).to eq('fb496612b8cb82cd2297770f83c72b377af16d7b')
102
+ describe "read_hex" do
103
+ it "returns the next bytes as hex" do
104
+ expect(hkdf.read_hex(20)).to eq("fb496612b8cb82cd2297770f83c72b377af16d7b")
101
105
  end
102
106
  end
103
107
 
104
- describe 'seek' do
105
- it 'sets the position anywhere in the stream' do
106
- hkdf.next_bytes(10)
107
- output = hkdf.next_bytes(32)
108
+ describe "seek" do
109
+ it "sets the position anywhere in the stream" do
110
+ hkdf.read(10)
111
+ output = hkdf.read(32)
108
112
  hkdf.seek(10)
109
- expect(hkdf.next_bytes(32)).to eq(output)
113
+ expect(hkdf.read(32)).to eq(output)
114
+ end
115
+
116
+ it "does not raise if <= max_length" do
117
+ expect { hkdf.seek(hkdf.max_length) }.not_to raise_error
110
118
  end
111
119
 
112
- it 'raises an error if requested to seek past end of stream' do
120
+ it "raises an error if requested to seek past end of stream" do
113
121
  expect { hkdf.seek(hkdf.max_length + 1) }.to raise_error(RangeError, /cannot seek past \d+/)
114
- expect { hkdf.seek(hkdf.max_length) }.to_not raise_error
115
122
  end
116
123
  end
117
124
 
118
- describe 'rewind' do
119
- it 'resets the stream position to the beginning' do
120
- output = hkdf.next_bytes(32)
125
+ describe "rewind" do
126
+ it "resets the stream position to the beginning" do
127
+ output = hkdf.read(32)
121
128
  hkdf.rewind
122
- expect(hkdf.next_bytes(32)).to eq(output)
129
+ expect(hkdf.read(32)).to eq(output)
123
130
  end
124
131
  end
125
132
 
126
- describe 'inspect' do
127
- it 'returns minimal information' do
128
- hkdf = HKDF.new('secret', info: 'public')
129
- expect(hkdf.inspect).to match(/^#<HKDF:0x[\h]+ algorithm="SHA256" info="public">$/)
133
+ describe "inspect" do
134
+ it "returns minimal information" do
135
+ hkdf = described_class.new("secret", info: "public")
136
+ expect(hkdf.inspect).to match(/^#<HKDF:0x[0-9a-f]+ algorithm="SHA256" info="public">$/)
130
137
  end
131
138
  end
132
139
  end
data/spec/spec_helper.rb CHANGED
@@ -1,23 +1,8 @@
1
- require 'hkdf'
1
+ # frozen_string_literal: true
2
2
 
3
- RSpec.configure do |config|
4
- config.order = 'random'
5
- end
3
+ require "hkdf"
4
+ require_relative "support/test_vectors"
6
5
 
7
- def test_vectors
8
- test_parts = File.readlines('spec/fixtures/test_vectors.txt').
9
- map(&:strip).
10
- reject(&:empty?).
11
- each_slice(8)
12
-
13
- test_parts.reduce({}) do |vectors, lines|
14
- name = lines.shift
15
- values = lines.reduce({}) do |hash, line|
16
- key, value = line.split('=').map(&:strip)
17
- value = '' unless value
18
- value = [value.slice(2..-1)].pack('H*') if value.start_with?('0x')
19
- hash.merge(key.to_sym => value)
20
- end
21
- vectors.merge(name => values)
22
- end
6
+ RSpec.configure do |config|
7
+ config.order = "random"
23
8
  end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ # :nodoc:
4
+ module TestVectors
5
+ module_function
6
+
7
+ # :nodoc:
8
+ def vectors
9
+ test_parts = File.readlines("spec/fixtures/test_vectors.txt")
10
+ .map(&:strip)
11
+ .reject(&:empty?)
12
+ .each_slice(8)
13
+
14
+ test_parts.reduce({}) do |vectors, lines|
15
+ name = lines.shift
16
+ values = split_test_vector(lines)
17
+ vectors.merge(name => values)
18
+ end
19
+ end
20
+
21
+ # :nodoc:
22
+ def split_test_vector(lines)
23
+ lines.reduce({}) do |hash, line|
24
+ key, value = line.split("=").map(&:strip)
25
+ value ||= ""
26
+ value = [value.slice(2..-1)].pack("H*") if value.start_with?("0x")
27
+ hash.merge(key.to_sym => value)
28
+ end
29
+ end
30
+ end
metadata CHANGED
@@ -1,60 +1,88 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hkdf
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - John Downey
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-11-09 00:00:00.000000000 Z
11
+ date: 2021-04-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: bundler
14
+ name: rake
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '1.0'
19
+ version: '12.0'
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '1.0'
26
+ version: '12.0'
27
27
  - !ruby/object:Gem::Dependency
28
- name: rake
28
+ name: rspec
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - '='
31
+ - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: 10.5.0
33
+ version: '3.9'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - '='
38
+ - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: 10.5.0
40
+ version: '3.9'
41
41
  - !ruby/object:Gem::Dependency
42
- name: rspec
42
+ name: rubocop
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - '='
45
+ - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: 3.4.0
47
+ version: '1.12'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - '='
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.12'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rubocop-rake
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
53
60
  - !ruby/object:Gem::Version
54
- version: 3.4.0
55
- description: 'A ruby implementation of RFC5869: HMAC-based Extract-and-Expand Key
56
- Derivation Function (HKDF). The goal of HKDF is to take some source key material
57
- and generate suitable cryptographic keys from it.'
61
+ version: 0.5.1
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 0.5.1
69
+ - !ruby/object:Gem::Dependency
70
+ name: rubocop-rspec
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '2.2'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '2.2'
83
+ description: |
84
+ A ruby implementation of RFC5869: HMAC-based Extract-and-Expand Key Derivation Function (HKDF). The goal of HKDF is
85
+ to take some source key material and generate suitable cryptographic keys from it.
58
86
  email:
59
87
  - jdowney@gmail.com
60
88
  executables: []
@@ -64,14 +92,16 @@ files:
64
92
  - LICENSE
65
93
  - README.md
66
94
  - lib/hkdf.rb
95
+ - lib/hkdf/version.rb
67
96
  - spec/fixtures/test_vectors.txt
68
97
  - spec/hkdf_spec.rb
69
98
  - spec/spec_helper.rb
99
+ - spec/support/test_vectors.rb
70
100
  homepage: http://github.com/jtdowney/hkdf
71
101
  licenses:
72
102
  - MIT
73
103
  metadata: {}
74
- post_install_message:
104
+ post_install_message:
75
105
  rdoc_options: []
76
106
  require_paths:
77
107
  - lib
@@ -79,19 +109,19 @@ required_ruby_version: !ruby/object:Gem::Requirement
79
109
  requirements:
80
110
  - - ">="
81
111
  - !ruby/object:Gem::Version
82
- version: '0'
112
+ version: 2.4.0
83
113
  required_rubygems_version: !ruby/object:Gem::Requirement
84
114
  requirements:
85
115
  - - ">="
86
116
  - !ruby/object:Gem::Version
87
117
  version: '0'
88
118
  requirements: []
89
- rubyforge_project:
90
- rubygems_version: 2.5.1
91
- signing_key:
119
+ rubygems_version: 3.2.15
120
+ signing_key:
92
121
  specification_version: 4
93
122
  summary: HMAC-based Key Derivation Function
94
123
  test_files:
95
124
  - spec/fixtures/test_vectors.txt
96
125
  - spec/hkdf_spec.rb
97
126
  - spec/spec_helper.rb
127
+ - spec/support/test_vectors.rb