Module: RbNaCl::Util

Extended by:
Sodium
Defined in:
lib/rbnacl/util.rb

Overview

Various utility functions

Class Method Summary collapse

Methods included from Sodium

primitive, sodium_constant, sodium_function, sodium_primitive, sodium_type

Class Method Details

.bin2hex(bytes) ⇒ String

Hex encodes a message



190
191
192
# File 'lib/rbnacl/util.rb', line 190

def bin2hex(bytes)
  bytes.to_s.unpack("H*").first
end

.check_length(string, length, description) ⇒ Object

Check the length of the passed in string

In several places through the codebase we have to be VERY strict with what length of string we accept. This method supports that.

Raises:



79
80
81
82
83
84
85
86
87
88
89
90
91
92
# File 'lib/rbnacl/util.rb', line 79

def check_length(string, length, description)
  if string.nil?
    fail LengthError,
         "#{description} was nil (Expected #{length.to_int})",
         caller
  end

  if string.bytesize != length.to_int
    fail LengthError,
         "#{description} was #{string.bytesize} bytes (Expected #{length.to_int})",
         caller
  end
  true
end

.check_string(string, length, description) ⇒ Object

Check a passed in string, converting the argument if necessary

In several places through the codebase we have to be VERY strict with the strings we accept. This method supports that.

Raises:

  • (ArgumentError)

    If we cannot convert to a string with #to_str

  • (RbNaCl::LengthError)

    If the string is not the right length



105
106
107
108
109
110
111
112
113
114
115
116
117
# File 'lib/rbnacl/util.rb', line 105

def check_string(string, length, description)
  unless string.respond_to? :to_str
    fail TypeError, "can't convert #{string.class} into String with #to_str"
  end

  string = string.to_str
  unless string.encoding == Encoding::BINARY
    fail EncodingError, "strings must use BINARY encoding (got #{string.encoding})"
  end
  check_length(string, length, description)

  string
end

.hex2bin(hex) ⇒ String

Hex decodes a message



199
200
201
# File 'lib/rbnacl/util.rb', line 199

def hex2bin(hex)
  [hex.to_s].pack("H*")
end

.prepend_zeros(n, message) ⇒ String

Prepends a message with zeros

Many functions require a string with some zeros prepended.



34
35
36
# File 'lib/rbnacl/util.rb', line 34

def prepend_zeros(n, message)
  zeros(n) + message
end

.remove_zeros(n, message) ⇒ String

Remove zeros from the start of a message

Many functions require a string with some zeros prepended, then need them removing after. Note, this modifies the passed in string



46
47
48
# File 'lib/rbnacl/util.rb', line 46

def remove_zeros(n, message)
  message.slice!(n, message.bytesize - n)
end

.verify16(one, two) ⇒ Boolean

Compare two 16 byte strings in constant time

This should help to avoid timing attacks for string comparisons in your application. Note that many of the functions (such as OneTime#verify) use this method under the hood already.



162
163
164
165
# File 'lib/rbnacl/util.rb', line 162

def verify16(one, two)
  return false unless two.bytesize == 16 && one.bytesize == 16
  c_verify16(one, two)
end

.verify16!(one, two) ⇒ Boolean

Compare two 16 byte strings in constant time

This should help to avoid timing attacks for string comparisons in your application. Note that many of the functions (such as OneTime#verify) use this method under the hood already.

Raises:

  • (ArgumentError)

    If the strings are not equal in length



179
180
181
182
183
# File 'lib/rbnacl/util.rb', line 179

def verify16!(one, two)
  check_length(one, 16, "First message")
  check_length(two, 16, "Second message")
  c_verify16(one, two)
end

.verify32(one, two) ⇒ Boolean

Compare two 32 byte strings in constant time

This should help to avoid timing attacks for string comparisons in your application. Note that many of the functions (such as HmacSha256#verify) use this method under the hood already.



129
130
131
132
# File 'lib/rbnacl/util.rb', line 129

def verify32(one, two)
  return false unless two.bytesize == 32 && one.bytesize == 32
  c_verify32(one, two)
end

.verify32!(one, two) ⇒ Boolean

Compare two 32 byte strings in constant time

This should help to avoid timing attacks for string comparisons in your application. Note that many of the functions (such as HmacSha256#verify) use this method under the hood already.

Raises:

  • (ArgumentError)

    If the strings are not equal in length



146
147
148
149
150
# File 'lib/rbnacl/util.rb', line 146

def verify32!(one, two)
  check_length(one, 32, "First message")
  check_length(two, 32, "Second message")
  c_verify32(one, two)
end

.zero_pad(n, message) ⇒ String

Pad a string out to n characters with zeros

Raises:



58
59
60
61
62
63
64
65
66
67
# File 'lib/rbnacl/util.rb', line 58

def zero_pad(n, message)
  len = message.bytesize
  if len == n
    message
  elsif len > n
    fail LengthError, "String too long for zero-padding to #{n} bytes"
  else
    message + zeros(n - len)
  end
end

.zeros(n = 32) ⇒ String

Returns a string of n zeros

Lots of the functions require us to create strings to pass into functions of a specified size.



19
20
21
22
23
24
# File 'lib/rbnacl/util.rb', line 19

def zeros(n = 32)
  zeros = "\0" * n
  # make sure they're 8-bit zeros, not 7-bit zeros.  Otherwise we might get
  # encoding errors later
  zeros.respond_to?(:force_encoding) ? zeros.force_encoding("ASCII-8BIT") : zeros
end