class RbNaCl::Hash::Blake2b

similar to HMAC
Blake2b provides for up to 64-bit digests and also supports a keyed mode
it’d be great if we can calculate hashes quickly if possible.
SHA2 to let the SHA3 judges panel sleep easy. Back in the real world,
Keccak, a much slower hash function but one sufficiently different from
Blake2b is based on Blake, a SHA3 finalist which was snubbed in favor of
The Blake2b hash function

def self.digest(message, options)

Returns:
  • (String) - Blake2b digest of the string as raw bytes

Raises:
  • (RbNaCl::LengthError) - Invalid length specified for one or more options

Options Hash: (**opts)
  • :personal (Personal) -- Provide personalisation string to allow pinning a hash for a particular purpose.
  • :salt (String) -- Provide a salt to support randomised hashing.
  • :digest_size (Integer) -- size of output digest in bytes
  • :key (String) -- for Blake2b keyed mode

Parameters:
  • options (Hash) -- Blake2b configuration
  • message (String) -- Message to be hashed
def self.digest(message, options)
  opts = validate_opts(options)
  digest = Util.zeros(opts[:digest_size])
  generichash_blake2b(digest, opts[:digest_size], message, message.bytesize,
                      opts[:key], opts[:key_size], opts[:salt], opts[:personal]) ||
    raise(CryptoError, "Hashing failed!")
  digest
end

def self.new(opts = {})

def self.new(opts = {})
  opts = validate_opts(opts)
  super
end

def self.validate_opts(opts)

Returns:
  • (Hash) - opts Configuration hash with sanitized values

Raises:
  • (RbNaCl::LengthError) - Invalid length specified for one or more options

Options Hash: (**opts)
  • :personal (Personal) -- Provide personalisation string to allow pinning a hash for a particular purpose.
  • :salt (String) -- Provide a salt to support randomised hashing.
  • :digest_size (Integer) -- size of output digest in bytes
  • :key (String) -- for Blake2b keyed mode

Parameters:
  • options (Hash) -- Blake2b configuration
def self.validate_opts(opts)
  key = opts.fetch(:key, nil)
  if key
    key_size = key.bytesize
    raise LengthError, "key too short" if key_size < KEYBYTES_MIN
    raise LengthError, "key too long"  if key_size > KEYBYTES_MAX
  else
    key_size = 0
  end
  opts[:key_size] = key_size
  digest_size = opts.fetch(:digest_size, BYTES_MAX)
  raise LengthError, "digest size too short" if digest_size < BYTES_MIN
  raise LengthError, "digest size too long"  if digest_size > BYTES_MAX
  opts[:digest_size] = digest_size
  personal = opts.fetch(:personal, EMPTY_PERSONAL)
  opts[:personal] = Util.zero_pad(PERSONALBYTES, personal)
  salt = opts.fetch(:salt, EMPTY_SALT)
  opts[:salt] = Util.zero_pad(SALTBYTES, salt)
  opts
end

def digest

Returns:
  • (String) - Blake2b digest of the string as raw bytes
def digest
  raise(CryptoError, "No message to hash yet!") unless @incycle
  return @digest if @digest
  @digest = Util.zeros(@digest_size)
  self.class.generichash_blake2b_final(@instate.pointer, @digest, @digest_size) ||
    raise(CryptoError, "Hash finalization failed!")
  @digest
end

def initialize(opts = {})

Returns:
  • (RbNaCl::Hash::Blake2b) - A Blake2b hasher object

Raises:
  • (RbNaCl::LengthError) - Invalid length specified for one or more options

Options Hash: (**opts)
  • :personal (Personal) -- Provide personalisation string to allow pinning a hash for a particular purpose.
  • :salt (String) -- Provide a salt to support randomised hashing.
  • :digest_size (Integer) -- size of output digest in bytes
  • :key (String) -- for Blake2b keyed mode

Parameters:
  • opts (Hash) -- Blake2b configuration
def initialize(opts = {})
  @key         = opts[:key]
  @key_size    = opts[:key_size]
  @digest_size = opts[:digest_size]
  @personal    = opts[:personal]
  @salt        = opts[:salt]
  @incycle  = false
  @instate  = nil
end

def reset

this will be called automatically from #update if needed
Initialize state for Blake2b hash calculation,
def reset
  @instate.release if @instate
  @instate = State.new
  self.class.generichash_blake2b_init(@instate.pointer, @key, @key_size, @digest_size, @salt, @personal) ||
    raise(CryptoError, "Hash init failed!")
  @incycle = true
  @digest = nil
end

def update(message)

Parameters:
  • message (String) -- Message to be hashed
def update(message)
  reset unless @incycle
  self.class.generichash_blake2b_update(@instate.pointer, message, message.bytesize) ||
    raise(CryptoError, "Hashing failed!")
end