Class: HKDF
- Inherits:
-
Object
- Object
- HKDF
- Defined in:
- lib/hkdf.rb
Constant Summary collapse
- DefaultAlgorithm =
'SHA256'
- DefaultReadSize =
512 * 1024
Instance Method Summary collapse
- #_generate_blocks(length) ⇒ Object
- #_generate_prk(salt, source, read_size) ⇒ Object
- #algorithm ⇒ Object
-
#initialize(source, options = {}) ⇒ HKDF
constructor
A new instance of HKDF.
- #inspect ⇒ Object
- #max_length ⇒ Object
- #next_bytes(length) ⇒ Object
- #next_hex_bytes(length) ⇒ Object
- #rewind ⇒ Object
- #seek(position) ⇒ Object
Constructor Details
#initialize(source, options = {}) ⇒ HKDF
Returns a new instance of HKDF.
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
# File 'lib/hkdf.rb', line 8 def initialize(source, = {}) source = StringIO.new(source) if source.is_a?(String) algorithm = .fetch(:algorithm, DefaultAlgorithm) @digest = OpenSSL::Digest.new(algorithm) @info = .fetch(:info, '') salt = [:salt] salt = 0.chr * @digest.digest_length if salt.nil? or salt.empty? read_size = .fetch(:read_size, DefaultReadSize) @prk = _generate_prk(salt, source, read_size) @position = 0 @blocks = [] @blocks << '' end |
Instance Method Details
#_generate_blocks(length) ⇒ Object
71 72 73 74 75 76 77 |
# File 'lib/hkdf.rb', line 71 def _generate_blocks(length) start = @blocks.size block_count = (length.to_f / @digest.digest_length).ceil start.upto(block_count) do |n| @blocks << OpenSSL::HMAC.digest(@digest, @prk, @blocks[n - 1] + @info + n.chr) end end |
#_generate_prk(salt, source, read_size) ⇒ Object
63 64 65 66 67 68 69 |
# File 'lib/hkdf.rb', line 63 def _generate_prk(salt, source, read_size) hmac = OpenSSL::HMAC.new(salt, @digest) while block = source.read(read_size) hmac.update(block) end hmac.digest end |
#algorithm ⇒ Object
25 26 27 |
# File 'lib/hkdf.rb', line 25 def algorithm @digest.name end |
#inspect ⇒ Object
59 60 61 |
# File 'lib/hkdf.rb', line 59 def inspect "#{to_s[0..-2]} algorithm=#{@digest.name.inspect} info=#{@info.inspect}>" end |
#max_length ⇒ Object
29 30 31 |
# File 'lib/hkdf.rb', line 29 def max_length @max_length ||= @digest.digest_length * 255 end |
#next_bytes(length) ⇒ Object
43 44 45 46 47 48 49 50 51 52 53 |
# File 'lib/hkdf.rb', line 43 def next_bytes(length) new_position = length + @position raise RangeError.new("requested #{length} bytes, only #{max_length} available") if new_position > max_length _generate_blocks(new_position) start = @position @position = new_position @blocks.join('').slice(start, length) end |
#next_hex_bytes(length) ⇒ Object
55 56 57 |
# File 'lib/hkdf.rb', line 55 def next_hex_bytes(length) next_bytes(length).unpack('H*').first end |
#rewind ⇒ Object
39 40 41 |
# File 'lib/hkdf.rb', line 39 def rewind seek(0) end |
#seek(position) ⇒ Object
33 34 35 36 37 |
# File 'lib/hkdf.rb', line 33 def seek(position) raise RangeError.new("cannot seek past #{max_length}") if position > max_length @position = position end |