--- /dev/null
+#ifndef MSP_CRYPTO_SHA2_H_
+#define MSP_CRYPTO_SHA2_H_
+
+#include <msp/core/inttypes.h>
+#include "blockhash.h"
+
+namespace Msp {
+namespace Crypto {
+
+template<typename C>
+class SHA2: public BlockHash<C::BLOCK_SIZE>
+{
+private:
+ typedef C Constants;
+ typedef typename Constants::WordType WordType;
+
+ typename Constants::WordType buffer[8];
+ UInt64 processed_bytes;
+
+public:
+ SHA2();
+ SHA2(const char *, unsigned);
+ SHA2(const std::string &);
+private:
+ void init();
+
+public:
+ virtual unsigned get_digest_size() const { return Constants::DIGEST_SIZE; }
+
+ virtual unsigned get_digest(char *, unsigned) const;
+
+private:
+ virtual void process_block(const char *);
+};
+
+
+struct SHA2_256Constants
+{
+ typedef UInt32 WordType;
+
+ enum
+ {
+ WORD_SIZE = sizeof(WordType),
+ BLOCK_SIZE = 64, // 512 bits
+ DIGEST_SIZE = 32, // 256 bits
+ N_ROUNDS = 64
+ };
+
+ static const WordType initial[8];
+ static const WordType round_constants[N_ROUNDS];
+ static const unsigned sigma_constants[12];
+};
+
+struct SHA2_512Constants
+{
+ typedef UInt64 WordType;
+
+ enum
+ {
+ WORD_SIZE = sizeof(WordType),
+ BLOCK_SIZE = 128, // 1024 bits
+ DIGEST_SIZE = 64, // 512 bits
+ N_ROUNDS = 80
+ };
+
+ static const WordType initial[8];
+ static const WordType round_constants[N_ROUNDS];
+ static const unsigned sigma_constants[12];
+};
+
+typedef SHA2<SHA2_256Constants> SHA256;
+typedef SHA2<SHA2_512Constants> SHA512;
+
+} // namespace Crypto
+} // namespace Msp
+
+#endif