Calculating cryptographic hashes using libtomcrypt in C/C++

Problem:

You want to calculate a hash of any string in C/C++. LibTomCrypt is WTFPL licensed, so it’s a good choice for commercial and non-commercial projects.

Solution:

This post describes a minimalistic solution. For further info, consult the official docs.

Here is a minimal example C implementation to hash a C-string.

#include <tomcrypt.h>
/**
 * Hashes a given sequence of bytes using the SHA1 algorithm
 * @param input The input sequence pointer
 * @param inputSize The size of the input sequence
 * @return A malloc-allocated pointer to the resulting data. 20 bytes long.
 */
unsigned char* hashSHA1(const char* input, unsigned long inputSize) {
    //Initial
    unsigned char* hashResult = (unsigned char*)malloc(sha1_desc.hashsize);
    //Initialize a state variable for the hash
    hash_state md;
    sha1_init(&md);
    //Process the text - remember you can call process() multiple times
    sha1_process(&md, (const unsigned char*) input, inputSize);
    //Finish the hash calculation
    sha1_done(&md, hashResult);
    // Return the result
    return hashResult;
}

After using this function, you need to free() the memory allocated and returned by it.

Other hash algorithms

In order to use another algorithm (e.g. SHA256 or MD5), you need to replace two things: 1. The hash name (sha1_ in this case) by its counterpart (remember to replace each occurrence!) 2. The hashsize for SHA1 is 20 bytes, it might be something different for other hashes, e.g. 32 for SHA256

Consult the documentation, Figure 4.1 “Built-In Software Hashes” to get a list of valid hash descriptors and their corresponding hash sizes.

C++

Even if you can use the above C code in C++ without any modification, you might want to hash std::string instances.

/**
 * Hashes a given input string using the SHA1 algorithm
 * @param input The input sequence pointer
 * @param inputSize The size of the input sequence
 * @return A new[]-allocated pointer to the resulting data. 20 bytes long.
 */
unsigned char* hashSHA1(const std::string& input) {
    //Initial
    unsigned char* hashResult = new unsigned char[sha1_desc.hashsize];
    //Initialize a state variable for the hash
    hash_state md;
    sha1_init(&md);
    //Process the text - remember you can call process() multiple times
    sha1_process(&md, (const unsigned char*) input.c_str(), input.size());
    //Finish the hash calculation
    sha1_done(&md, hashResult);
    // Return the result
    return hashResult;
}

How to use the functions

In most cases you want to print the resulting hash as hexadecimal string to stdout. Here is an example of how to use the C++ code.

#include <string>

int main(int argc, char** argv) {
    std::string text = "abcdef";
    unsigned char* hashResult = hashSHA1(text);
    //Print as hex string to stdout
    for (int x = 0; x < 20; x++) {
        printf("%x", hashResult[x]); //Hex-format
    }
    printf("\n");
    //Delete the hash result pointer
    delete[] hashResult;
    return 0;
}

This snippet prints 1f8ac1f23c5b5bc1167bda84b833e5c57a77d2.