Helpers
Constant-time test for equality
When a comparison involves secret data (e.g. a key, an authentication tag, etc), it is critical to use a constant-time comparison function. This property does not relate to computational complexity: it means the time needed to perform the comparison is the same for all data of the same size. The goal is to mitigate side-channel attacks.
The sodium_memcmp()
function can be used for this purpose.
The function returns 0
if the len
bytes pointed to by b1_
match the len
bytes pointed to by b2_
. Otherwise, it returns -1
.
Note: sodium_memcmp()
is not a lexicographic comparator and is not a generic replacement for memcmp()
.
Hexadecimal encoding/decoding
The sodium_bin2hex()
function converts bin_len
bytes stored at bin
into a hexadecimal string.
The string is stored into hex
and includes a nul byte (\0
) terminator.
hex_maxlen
is the maximum number of bytes that the function is allowed to write starting at hex
. It must be at least bin_len * 2 + 1
bytes.
The function always returns hex
. It evaluates in constant time for a given size.
The sodium_hex2bin()
function parses a hexadecimal string hex
and converts it to a byte sequence.
hex
does not have to be nul terminated, as the number of characters to parse is supplied via the hex_len
parameter.
ignore
is a string of characters to skip. For example, the string ": "
allows colons and spaces to be present at any location in the hexadecimal string. These characters will just be ignored. As a result, "69:FC"
, "69 FC"
, "69 : FC"
and "69FC"
will be valid inputs and produce the same output.
ignore
can be set to NULL
to disallow any non-hexadecimal character.
bin_maxlen
is the maximum number of bytes to put into bin
.
The parser stops when a non-hexadecimal, non-ignored character is found or when bin_maxlen
bytes have been written.
If hex_end
is not NULL
, it will be set to the address of the first byte after the last valid parsed character.
The function returns 0
on success.
It returns -1
if more than bin_maxlen
bytes would be required to store the parsed string or the string couldn’t be fully parsed, but a valid pointer for hex_end
was not provided.
It evaluates in constant time for a given length and format.
Base64 encoding/decoding
The sodium_bin2base64()
function encodes bin
as a Base64 string. variant
must be one of:
sodium_base64_VARIANT_ORIGINAL
sodium_base64_VARIANT_ORIGINAL_NO_PADDING
sodium_base64_VARIANT_URLSAFE
sodium_base64_VARIANT_URLSAFE_NO_PADDING
None of these Base64 variants provides any form of encryption; just like hex encoding, anyone can decode them.
Computing a correct size for b64_maxlen
is not straightforward and depends on the chosen variant.
The sodium_base64_ENCODED_LEN(BIN_LEN, VARIANT)
macro returns the minimum number of bytes required to encode BIN_LEN
bytes using the Base64 variant VARIANT
. The returned length includes a trailing \0
byte.
The sodium_base64_encoded_len(size_t bin_len, int variant)
function is also available for the same purpose.
The sodium_base642bin()
function decodes a Base64 string using the given variant and an optional set of characters to ignore (typically: whitespaces and newlines).
If b64_end
is not NULL
, it will be set to the address of the first byte after the last valid parsed character.
Base64 encodes 3 bytes as 4 characters, so the result of decoding a b64_len
string will always be at most b64_len / 4 * 3
bytes long.
The function returns 0
on success.
It returns -1
if more than bin_maxlen
bytes would be required to store the parsed string or the string couldn’t be fully parsed, but a valid pointer for b64_end
was not provided.
Incrementing large numbers
The sodium_increment()
function takes a pointer to an arbitrary-long unsigned number and increments it.
It runs in constant time for a given length and considers the number to be encoded in a little-endian format.
sodium_increment()
can be used to increment nonces in constant time.
Adding large numbers
The sodium_add()
function accepts two pointers to unsigned numbers encoded in little-endian format, a
and b
, both of size len
bytes.
It computes (a + b) mod 2^(8*len)
in constant time for a given length and overwrites a
with the result.
Subtracting large numbers
The sodium_sub()
function accepts two pointers to unsigned numbers encoded in little-endian format, a
and b
, both of size len
bytes.
It computes (a - b) mod 2^(8*len)
in constant time for a given length and overwrites a
with the result.
This function was introduced in libsodium 1.0.17.
Comparing large numbers
Given b1_
and b2_
, two len
bytes numbers encoded in little-endian format, this function returns:
-1
ifb1_
is less thanb2_
0
ifb1_
equalsb2_
1
ifb1_
is greater thanb2_
The comparison is done in constant time for a given length.
This function can be used with nonces to prevent replay attacks.
Testing for all zeros
This function returns 1
if the nlen
bytes vector pointed by n
contains only zeros. It returns 0
if non-zero bits are found.
Its execution time is constant for a given length.
Clearing the stack
The sodium_stackzero()
function clears len
bytes above the current stack pointer, to overwrite sensitive values that may have been temporarily stored on the stack.
Note that these values can still be present in registers.
This function was introduced in libsodium 1.0.16.
Notes
The sodium_base64_VARIANT_*()
macros don’t have associated symbols. Bindings are encouraged to define specialized encoding/decoding functions instead.
Last updated