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.