module RbNaCl::Util
Various utility functions
Public Instance Methods
Hex encodes a message
@param [String] bytes The bytes to encode
@return [String] Tasty, tasty hexadecimal
# File lib/rbnacl/util.rb, line 193 def bin2hex(bytes) bytes.to_s.unpack("H*").first end
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.
@raise [RbNaCl::LengthError] If the string is not the right length
@param string [String] The string to compare @param length [Integer] The desired length @param description [String] Description of the string (used in the error)
# File lib/rbnacl/util.rb, line 82 def check_length(string, length, description) if string.nil? raise LengthError, "#{description} was nil (Expected #{length.to_int})", caller end if string.bytesize != length.to_int raise LengthError, "#{description} was #{string.bytesize} bytes (Expected #{length.to_int})", caller end true end
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.
@raise [ArgumentError] If we cannot convert to a string with to_str @raise [RbNaCl::LengthError] If the string is not the right length
@param string [#to_str] The input string @param length [Integer] The only acceptable length of the string @param description [String] Description of the string (used in the error)
# File lib/rbnacl/util.rb, line 108 def check_string(string, length, description) unless string.respond_to? :to_str raise TypeError, "can't convert #{string.class} into String with #to_str" end string = string.to_str unless string.encoding == Encoding::BINARY raise EncodingError, "strings must use BINARY encoding (got #{string.encoding})" end check_length(string, length, description) string end
Hex decodes a message
@param [String] hex hex to decode.
@return [String] crisp and clean bytes
# File lib/rbnacl/util.rb, line 202 def hex2bin(hex) [hex.to_s].pack("H*") end
Prepends a message with zeros
Many functions require a string with some zeros prepended.
@param [Integer] n The number of zeros to prepend @param [String] message The string to be prepended
@return [String] a bunch of zeros
# File lib/rbnacl/util.rb, line 36 def prepend_zeros(n, message) zeros(n) + message end
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
@param [Integer] n The number of zeros to remove @param [String] message The string to be slice
@return [String] less a bunch of zeros
# File lib/rbnacl/util.rb, line 49 def remove_zeros(n, message) message.slice!(n, message.bytesize - n) end
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.
@param [String] one String #1 @param [String] two String #2
@return [Boolean] Well, are they equal?
# File lib/rbnacl/util.rb, line 165 def verify16(one, two) return false unless two.bytesize == 16 && one.bytesize == 16 c_verify16(one, two) end
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.
@param [String] one String #1 @param [String] two String #2
@raise [ArgumentError] If the strings are not equal in length
@return [Boolean] Well, are they equal?
# File lib/rbnacl/util.rb, line 182 def verify16!(one, two) check_length(one, 16, "First message") check_length(two, 16, "Second message") c_verify16(one, two) end
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.
@param [String] one String #1 @param [String] two String #2
@return [Boolean] Well, are they equal?
# File lib/rbnacl/util.rb, line 132 def verify32(one, two) return false unless two.bytesize == 32 && one.bytesize == 32 c_verify32(one, two) end
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.
@param [String] one String #1 @param [String] two String #2
@raise [ArgumentError] If the strings are not equal in length
@return [Boolean] Well, are they equal?
# File lib/rbnacl/util.rb, line 149 def verify32!(one, two) check_length(one, 32, "First message") check_length(two, 32, "Second message") c_verify32(one, two) end
Pad a string out to n characters with zeros
@param [Integer] n The length of the resulting string @param [String] message the message to be padded
@raise [RbNaCl::LengthError] If the string is too long
@return [String] A string, n bytes long
# File lib/rbnacl/util.rb, line 61 def zero_pad(n, message) len = message.bytesize if len == n message elsif len > n raise LengthError, "String too long for zero-padding to #{n} bytes" else message + zeros(n - len) end end
Returns a string of n zeros
Lots of the functions require us to create strings to pass into functions of a specified size.
@param [Integer] n the size of the string to make
@return [String] A nice collection of zeros
# File lib/rbnacl/util.rb, line 21 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