Module digest | Tarantool

Module digest

A “digest” is a value which is returned by a function (usually a Cryptographic hash function), applied against a string. Tarantool’s digest module supports several types of cryptographic hash functions ( AES, MD4, MD5, SHA-1, SHA-2, PBKDF2) as well as a checksum function (CRC32), two functions for base64, and two non-cryptographic hash functions (guava, murmur). Some of the digest functionality is also present in the crypto.

Below is a list of all digest functions.

Name Use
digest.aes256cbc.encrypt() Encrypt a string using AES
digest.aes256cbc.decrypt() Decrypt a string using AES
digest.md4() Get a digest made with MD4
digest.md4_hex() Get a hexadecimal digest made with MD4
digest.md5() Get a digest made with MD5
digest.md5_hex() Get a hexadecimal digest made with MD5
digest.pbkdf2() Get a digest made with PBKDF2
digest.sha1() Get a digest made with SHA-1
digest.sha1_hex() Get a hexadecimal digest made with SHA-1
digest.sha224() Get a 224-bit digest made with SHA-2
digest.sha224_hex() Get a 56-byte hexadecimal digest made with SHA-2
digest.sha256() Get a 256-bit digest made with SHA-2
digest.sha256_hex() Get a 64-byte hexadecimal digest made with SHA-2
digest.sha384() Get a 384-bit digest made with SHA-2
digest.sha384_hex() Get a 96-byte hexadecimal digest made with SHA-2
digest.sha512() Get a 512-bit digest made with SHA-2
digest.sha512_hex() Get a 128-byte hexadecimal digest made with SHA-2
digest.base64_encode() Encode a string to Base64
digest.base64_decode() Decode a Base64-encoded string
digest.urandom() Get an array of random bytes
digest.crc32() Get a 32-bit checksum made with CRC32
digest.crc32.new() Initiate incremental CRC32
digest.guava() Get a number made with a consistent hash
digest.murmur() Get a digest made with MurmurHash
digest.murmur.new() Initiate incremental MurmurHash
digest.aes256cbc.encrypt(string, key, iv)
digest.aes256cbc.decrypt(string, key, iv)

Returns 256-bit binary string = digest made with AES.

digest.md4(string)

Returns 128-bit binary string = digest made with MD4.

digest.md4_hex(string)

Returns 32-byte string = hexadecimal of a digest calculated with md4.

digest.md5(string)

Returns 128-bit binary string = digest made with MD5.

digest.md5_hex(string)

Returns 32-byte string = hexadecimal of a digest calculated with md5.

digest.pbkdf2(string, salt[, iterations[, digest-length]])

Returns binary string = digest made with PBKDF2.
For effective encryption the iterations value should be at least several thousand. The digest-length value determines the length of the resulting binary string.

Note

digest.pbkdf2() yields and should not be used in a transaction (between box.begin() and box.commit()/box.rollback()). PBKDF2 is a time-consuming hash algorithm. It runs in a separate coio thread. While calculations are performed, the fiber that calls digest.pbkdf2() yields and another fiber continues working in the tx thread.

digest.sha1(string)

Returns 160-bit binary string = digest made with SHA-1.

digest.sha1_hex(string)

Returns 40-byte string = hexadecimal of a digest calculated with sha1.

digest.sha224(string)

Returns 224-bit binary string = digest made with SHA-2.

digest.sha224_hex(string)

Returns 56-byte string = hexadecimal of a digest calculated with sha224.

digest.sha256(string)

Returns 256-bit binary string = digest made with SHA-2.

digest.sha256_hex(string)

Returns 64-byte string = hexadecimal of a digest calculated with sha256.

digest.sha384(string)

Returns 384-bit binary string = digest made with SHA-2.

digest.sha384_hex(string)

Returns 96-byte string = hexadecimal of a digest calculated with sha384.

digest.sha512(string)

Returns 512-bit binary string = digest made with SHA-2.

digest.sha512_hex(string)

Returns 128-byte string = hexadecimal of a digest calculated with sha512.

digest.base64_encode()

Returns base64 encoding from a regular string.

The possible options are:

  • nopad – result must not include ‘=’ for padding at the end,
  • nowrap – result must not include line feed for splitting lines after 72 characters,
  • urlsafe – result must not include ‘=’ or line feed, and may contain ‘-‘ or ‘_’ instead of ‘+’ or ‘/’ for positions 62 and 63 in the index table.

Options may be true or false, the default value is false.

For example:

digest.base64_encode(string_variable,{nopad=true})
digest.base64_decode(string)

Returns a regular string from a base64 encoding.

digest.urandom(integer)

Returns array of random bytes with length = integer.

digest.crc32(string)

Returns 32-bit checksum made with CRC32.

The crc32 and crc32_update functions use the Cyclic Redundancy Check polynomial value: 0x1EDC6F41 / 4812730177. (Other settings are: input = reflected, output = reflected, initial value = 0xFFFFFFFF, final xor value = 0x0.) If it is necessary to be compatible with other checksum functions in other programming languages, ensure that the other functions use the same polynomial value.

For example, in Python, install the crcmod package and say:

>>> import crcmod
>>> fun = crcmod.mkCrcFun('4812730177')
>>> fun('string')
3304160206L

In Perl, install the Digest::CRC module and run the following code:

use Digest::CRC;
$d = Digest::CRC->new(width => 32, poly => 0x1EDC6F41, init => 0xFFFFFFFF, refin => 1, refout => 1);
$d->add('string');
print $d->digest;

(the expected output is 3304160206).

digest.crc32.new()

Initiates incremental crc32. See incremental methods notes.

digest.guava(state, bucket)

Returns a number made with consistent hash.

The guava function uses the Consistent Hashing algorithm of the Google guava library. The first parameter should be a hash code; the second parameter should be the number of buckets; the returned value will be an integer between 0 and the number of buckets. For example,

tarantool> digest.guava(10863919174838991, 11)
---
- 8
...
digest.murmur(string)

Returns 32-bit binary string = digest made with MurmurHash.

digest.murmur.new(opts)

Initiates incremental MurmurHash. See incremental methods notes. For example:

murmur.new({seed=0})

Incremental methods in the digest

Suppose that a digest is done for a string ‘A’, then a new part ‘B’ is appended to the string, then a new digest is required. The new digest could be recomputed for the whole string ‘AB’, but it is faster to take what was computed before for ‘A’ and apply changes based on the new part ‘B’. This is called multi-step or “incremental” digesting, which Tarantool supports with crc32 and with murmur…

digest = require('digest')

-- print crc32 of 'AB', with one step, then incrementally
print(digest.crc32('AB'))
c = digest.crc32.new()
c:update('A')
c:update('B')
print(c:result())

-- print murmur hash of 'AB', with one step, then incrementally
print(digest.murmur('AB'))
m = digest.murmur.new()
m:update('A')
m:update('B')
print(m:result())

In the following example, the user creates two functions, password_insert() which inserts a SHA-1 digest of the word “^S^e^c^ret Wordpass” into a tuple set, and password_check() which requires input of a password.

tarantool> digest = require('digest')
---
...
tarantool> function password_insert()
         >   box.space.tester:insert{1234, digest.sha1('^S^e^c^ret Wordpass')}
         >   return 'OK'
         > end
---
...
tarantool> function password_check(password)
         >   local t = box.space.tester:select{12345}
         >   if digest.sha1(password) == t[2] then
         >     return 'Password is valid'
         >   else
         >     return 'Password is not valid'
         >   end
         > end
---
...
tarantool> password_insert()
---
- 'OK'
...

If a later user calls the password_check() function and enters the wrong password, the result is an error.

tarantool> password_check('Secret Password')
---
- 'Password is not valid'
...
Found what you were looking for?
Feedback