X-Git-Url: http://git.tdb.fi/?p=libs%2Fcrypto.git;a=blobdiff_plain;f=source%2Fblockhash.h;fp=source%2Fblockhash.h;h=309fbfac86593c01a0a321c66a1762f42c7b0dfd;hp=0000000000000000000000000000000000000000;hb=6511a62c3cec0a64bbdd7ac8e3588d39c164af09;hpb=cb6ee39a05f6903a0ef521c81e6f42d05289b1a1 diff --git a/source/blockhash.h b/source/blockhash.h new file mode 100644 index 0000000..309fbfa --- /dev/null +++ b/source/blockhash.h @@ -0,0 +1,68 @@ +#ifndef MSP_CRYPTO_BLOCKHASH_H_ +#define MSP_CRYPTO_BLOCKHASH_H_ + +#include +#include "hash.h" + +namespace Msp { +namespace Crypto { + +template +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 +inline BlockHash::BlockHash(): + unprocessed_bytes(0) +{ } + +template +void BlockHash::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