Files CCore/inc/crypton/HashFunction.h CCore/src/crypton/HashFunction.cpp
HashFunction is an abstract hash function algorithm. It is a template and the template parameter provides all necessary parts to implement the required functionality. An abstract hash function processes the given block of raw data (i.e. a sequence of bytes) into a "message digest", i.e. a short block of bytes of the defined length. A good hash function has a number of properties. For instance, it is difficult to construct an input with the given output.
template <class T>
class HashFunction : NoCopy
{
....
public:
// length in octets
static const ulen DigestLen = T::DigestLen ;
static const ulen BlockLen = T::BlockLen ;
static const char * GetName() { return T::GetName(); }
// constructors
HashFunction();
~HashFunction();
// methods
void reset();
void add(const uint8 *data,ulen len);
void add(PtrLen<const uint8> data);
void finish(uint8 digest[DigestLen]);
};
DigestLen is the length of the digest.
BlockLen is the hash function "block length". It is some internal property of the hash algorithm. Usually an input data is sliced on blocks of the defined length before the processing. The tail is padded to make a whole number of blocks.
GetName() is the hash function common name, like "SHA1".
The HashFunction is working incrementally. To calculate the output, the object must be reset first. It is performed by the constructor and can be performed also by the method reset().
Destructor does clean the internal state from any information, accumulated during the hash calculation.
add() adds the next chunk of the input. Two variants are provided: with pointer and length arguments and with the single PtrLen<const uint8> argument.
finish() completes the hash calculation, copies the output to the given buffer and resets the object.
The real job is performed by the class T. This class must comply with the following pattern:
struct HashAlgo { // global properties static const ulen DigestLen = .... ; static const ulen BlockLen = .... ; static const char * GetName() { return "...."; } // internal state .... // methods void reset(); void forget(); void add(const uint8 *data,ulen len); void finish(uint8 digest[DigestLen]); };
The method forget() is used to clean the state.
KeyedHashFunction calculates a keyed message digest according to the RFC 2104. It uses a template parameter of the same kind as the class HashFunction. This variant of the hash uses the additional argument — the key.
template <class T,ulen L>
class KeyedHashFunction : NoCopy
{
....
public:
// length in octets
static const ulen DigestLen = L ;
static const ulen BlockLen = T::BlockLen ;
static const char * GetName() { return T::GetName(); }
// constructors
KeyedHashFunction();
~KeyedHashFunction();
KeyedHashFunction(const uint8 *key,ulen key_len);
explicit KeyedHashFunction(PtrLen<const uint8> key);
// methods
void key(const uint8 *key,ulen key_len);
void key(PtrLen<const uint8> key);
void unkey();
void reset();
void add(const uint8 *data,ulen len);
void add(PtrLen<const uint8> data);
void finish(uint8 digest[DigestLen]);
};
This class is working the same way as the HashFunction. The main difference is: before the hash calculation a key must be assigned to the object. Otherwise any attempt to perform the hash calculation will throw an exception. To assign a key the method key() can be used. Or the constructor with the key as the argument.
The following guard function is used to throw the "no-hash-key" exception:
void GuardNoHashKey();
The method unkey() cleans the key information from the object. It is called by the destructor.