]> git.tdb.fi Git - libs/crypto.git/blobdiff - source/blockhash.h
Implement the SHA2 hash family
[libs/crypto.git] / source / blockhash.h
diff --git a/source/blockhash.h b/source/blockhash.h
new file mode 100644 (file)
index 0000000..309fbfa
--- /dev/null
@@ -0,0 +1,68 @@
+#ifndef MSP_CRYPTO_BLOCKHASH_H_
+#define MSP_CRYPTO_BLOCKHASH_H_
+
+#include <algorithm>
+#include "hash.h"
+
+namespace Msp {
+namespace Crypto {
+
+template<unsigned B>
+class BlockHash: public Hash
+{
+protected:
+       enum
+       {
+               BLOCK_SIZE = B
+       };
+
+       char unprocessed[BLOCK_SIZE];
+       unsigned unprocessed_bytes;
+
+       BlockHash();
+
+public:
+       using Hash::update;
+       virtual void update(const char *, unsigned);
+
+protected:
+       virtual void process_block(const char *) = 0;
+};
+
+
+template<unsigned B>
+inline BlockHash<B>::BlockHash():
+       unprocessed_bytes(0)
+{ }
+
+template<unsigned B>
+void BlockHash<B>::update(const char *data, unsigned len)
+{
+       if(unprocessed_bytes && unprocessed_bytes+len>=BLOCK_SIZE)
+       {
+               unsigned needed = BLOCK_SIZE-unprocessed_bytes;
+               std::copy(data, data+needed, unprocessed+unprocessed_bytes);
+               process_block(unprocessed);
+               data += needed;
+               len -= needed;
+               unprocessed_bytes = 0;
+       }
+
+       while(len>=BLOCK_SIZE)
+       {
+               process_block(data);
+               data += BLOCK_SIZE;
+               len -= BLOCK_SIZE;
+       }
+
+       if(len>0)
+       {
+               std::copy(data, data+len, unprocessed+unprocessed_bytes);
+               unprocessed_bytes += len;
+       }
+}
+
+} // namespace Crypto
+} // namespace Msp
+
+#endif