Class: Krypt::FFI::Digest

Inherits:
Object
  • Object
show all
Includes:
LibC
Defined in:
lib/krypt/provider/ffi/digest.rb

Overview

A Krypt::Digest implementation using FFI.

Defined Under Namespace

Classes: NativeHandle

Instance Method Summary collapse

Constructor Details

#initialize(provider, type) ⇒ Digest

call-seq:

Krypt::FFI::Digest.new(provider, name_or_oid) -> Digest

Creates a Digest using a C struct krypt_provider as provider argument. The provider is typically obtained by a separate FFI call to a publicly visible function offered by the implementation of the krypt Provider C API. name_or_oid can be either the name of the digest algorithm to be used (e.g. “SHA1”) or the OID String uniquely identifying the digest algorithm.



20
21
22
23
24
25
26
# File 'lib/krypt/provider/ffi/digest.rb', line 20

def initialize(provider, type)
  unless (@handle = interface_for_name(provider, type))
    unless (@handle = interface_for_oid(provider, type))
      raise Krypt::Provider::ServiceNotAvailableError.new("Unknown digest algorithm: #{type}")
    end
  end
end

Instance Method Details

#block_lengthObject

call-seq:

digest.block_length -> integer

Returns the block length of the digest algorithm, i.e. the length in bytes of an individual block. Most modern algorithms partition a message to be digested into a sequence of fix-sized blocks that are processed consecutively.

Example

digest = Krypt::Digest::SHA1.new
puts digest.block_length # => 64


132
133
134
# File 'lib/krypt/provider/ffi/digest.rb', line 132

def block_length
  read_length(@handle.interface[:md_block_length])
end

#digest(data = nil) ⇒ Object

call-seq:

digest.digest([string]) -> String

When called with no arguments, the result will be the hash of the data that has been fed to this Digest instance so far. If called with a String argument, the hash of that argument will be computed.

Example

digest = Krypt::Digest::SHA256.new
result = digest.digest('First input')

is equivalent to

digest = Krypt::Digest::SHA256.new
digest << 'First input' # equivalent to digest.update('Second input')
result = digest.digest


82
83
84
85
86
87
88
89
90
# File 'lib/krypt/provider/ffi/digest.rb', line 82

def digest(data=nil)
  if data
    ret = digest_once(data)
  else
    ret = digest_finalize
  end
  reset
  ret
end

#digest_lengthObject

call-seq:

digest.digest_length -> integer

Returns the output size of the digest, i.e. the length in bytes of the final message digest result.

Example

digest = Krypt::Digest::SHA1.new
puts digest.digest_length # => 20


115
116
117
# File 'lib/krypt/provider/ffi/digest.rb', line 115

def digest_length
  read_length(@handle.interface[:md_digest_length])
end

#hexdigest(data = nil) ⇒ Object

call-seq:

digest.hexdigest([string]) -> String

Works the with the same semantics as Digest#digest with the difference that instead of the raw bytes the hex-encoded form of the raw representation is returned.



100
101
102
# File 'lib/krypt/provider/ffi/digest.rb', line 100

def hexdigest(data=nil)
  Krypt::Hex.encode(digest(data))
end

#nameObject

call-seq:

digest.name -> string

Returns the sn of this Digest instance.

Example

digest = Krypt::Digest::SHA512.new
puts digest.name # => SHA512


147
148
149
150
151
152
153
# File 'lib/krypt/provider/ffi/digest.rb', line 147

def name
  name_ptr = FFI::MemoryPointer.new(:pointer)
  result = @handle.interface[:md_name].call(@handle.container, name_ptr)
  raise_on_error("Error while obtaining digest name", result)

  name_ptr.read_pointer.get_string(0)
end

#resetObject

call-seq:

digest.reset -> self

Resets the Digest in the sense that any Digest#update that has been performed is abandoned and the Digest is set to its initial state again.



35
36
37
38
39
# File 'lib/krypt/provider/ffi/digest.rb', line 35

def reset
  result = @handle.interface[:md_reset].call(@handle.container)
  raise_on_error("Error while resetting digest", result)
  self
end

#update(data) ⇒ Object Also known as: <<

call-seq:

digest.update(string) -> aString

Not every message digest can be computed in one single pass. If a message digest is to be computed from several subsequent sources, then each may be passed individually to the Digest instance.

Example

digest = Krypt::Digest::SHA256.new
digest.update('First input')
digest << 'Second input' # equivalent to digest.update('Second input')
result = digest.digest


56
57
58
59
60
# File 'lib/krypt/provider/ffi/digest.rb', line 56

def update(data)
  result = @handle.interface[:md_update].call(@handle.container, data, data.length)
  raise_on_error("Error while updating digest", result)
  self
end