From ea43a6109401c347e888483e1258533ea03752f4 Mon Sep 17 00:00:00 2001 From: Karol Szuster Date: Mon, 22 Aug 2016 11:21:46 +0200 Subject: [PATCH] Update hashing library (#384) --- third_party/hashing/hashers/crc32.cpp | 17 +++-- third_party/hashing/hashers/crc32.h | 14 +++- third_party/hashing/hashers/keccak.cpp | 27 ++++++-- third_party/hashing/hashers/keccak.h | 2 +- third_party/hashing/hashers/md5.cpp | 93 ++++++++++---------------- third_party/hashing/hashers/md5.h | 14 ++-- third_party/hashing/hashers/sha1.cpp | 63 +++++++++-------- third_party/hashing/hashers/sha1.h | 14 ++-- third_party/hashing/hashers/sha256.cpp | 63 +++++++++-------- third_party/hashing/hashers/sha256.h | 16 +++-- third_party/hashing/hashers/sha3.cpp | 29 +++++--- third_party/hashing/hashers/sha3.h | 2 +- 12 files changed, 200 insertions(+), 154 deletions(-) diff --git a/third_party/hashing/hashers/crc32.cpp b/third_party/hashing/hashers/crc32.cpp index 7a6f0b03..1cff1a49 100644 --- a/third_party/hashing/hashers/crc32.cpp +++ b/third_party/hashing/hashers/crc32.cpp @@ -1,6 +1,6 @@ // ////////////////////////////////////////////////////////// // crc32.cpp -// Copyright (c) 2014 Stephan Brumme. All rights reserved. +// Copyright (c) 2014,2015 Stephan Brumme. All rights reserved. // see http://create.stephan-brumme.com/disclaimer.html // @@ -374,7 +374,7 @@ void CRC32::add(const void* data, size_t numBytes) } -/// return latest hash as 16 hex characters +/// return latest hash as 8 hex characters const char* CRC32::getHash() { // convert hash to string @@ -390,12 +390,21 @@ const char* CRC32::getHash() hashBuffer[5] = dec2hex[(m_hash >> 8) & 15]; hashBuffer[6] = dec2hex[(m_hash >> 4) & 15]; hashBuffer[7] = dec2hex[ m_hash & 15]; - // zero-terminated string hashBuffer[8] = 0; // convert to std::string - return (const char *)hashBuffer; + return const_cast(hashBuffer); +} + + +/// return latest hash as bytes +void CRC32::getHash(unsigned char buffer[CRC32::HashBytes]) +{ + buffer[0] = (m_hash >> 24) & 0xFF; + buffer[1] = (m_hash >> 16) & 0xFF; + buffer[2] = (m_hash >> 8) & 0xFF; + buffer[3] = m_hash & 0xFF; } diff --git a/third_party/hashing/hashers/crc32.h b/third_party/hashing/hashers/crc32.h index ea4ee403..2eacb61e 100644 --- a/third_party/hashing/hashers/crc32.h +++ b/third_party/hashing/hashers/crc32.h @@ -1,6 +1,6 @@ // ////////////////////////////////////////////////////////// // crc32.h -// Copyright (c) 2014 Stephan Brumme. All rights reserved. +// Copyright (c) 2014,2015 Stephan Brumme. All rights reserved. // see http://create.stephan-brumme.com/disclaimer.html // @@ -20,10 +20,18 @@ while (more data available) crc32.add(pointer to fresh data, number of new bytes); std::string myHash3 = crc32.getHash(); + + Note: + You can find code for the faster Slicing-by-16 algorithm on my website, too: + http://create.stephan-brumme.com/crc32/ + Its unrolled version is about twice as fast but its look-up table doubled in size as well. */ class CRC32 //: public Hash { public: + /// hash is 4 bytes long + enum { HashBytes = 4 }; + /// same as reset() CRC32(); @@ -35,8 +43,10 @@ public: /// add arbitrary number of bytes void add(const void* data, size_t numBytes); - /// return latest hash as 16 hex characters + /// return latest hash as 8 hex characters const char* getHash(); + /// return latest hash as bytes + void getHash(unsigned char buffer[HashBytes]); /// restart void reset(); diff --git a/third_party/hashing/hashers/keccak.cpp b/third_party/hashing/hashers/keccak.cpp index 6444de3a..b9b06112 100644 --- a/third_party/hashing/hashers/keccak.cpp +++ b/third_party/hashing/hashers/keccak.cpp @@ -1,6 +1,6 @@ // ////////////////////////////////////////////////////////// // keccak.cpp -// Copyright (c) 2014 Stephan Brumme. All rights reserved. +// Copyright (c) 2014,2015 Stephan Brumme. All rights reserved. // see http://create.stephan-brumme.com/disclaimer.html // @@ -18,10 +18,10 @@ Keccak::Keccak(Bits bits) /// same as reset() void Keccak::changeBits(Bits bits) { - m_blockSize = (200 - 2 * (bits / 8)); - m_bits = bits; + m_blockSize = (200 - 2 * (bits / 8)); + m_bits = bits; - reset(); + reset(); } /// restart @@ -225,11 +225,11 @@ void Keccak::processBuffer() // add a "1" byte m_buffer[offset++] = 1; // fill with zeros - while (offset < blockSize - 1) + while (offset < blockSize) m_buffer[offset++] = 0; // and add a single set bit - m_buffer[blockSize - 1] = 0x80; + m_buffer[blockSize - 1] |= 0x80; processBlock(m_buffer); } @@ -257,8 +257,21 @@ const char* Keccak::getHash() result[written++] = dec2hex[oneByte >> 4]; result[written++] = dec2hex[oneByte & 15]; } + + // Keccak224's last entry in m_hash provides only 32 bits instead of 64 bits + unsigned int remainder = m_bits - hashLength * 64; + unsigned int processed = 0; + while (processed < remainder) + { + // convert a byte to hex + unsigned char oneByte = (unsigned char) (m_hash[hashLength] >> processed); + result[written++] = dec2hex[oneByte >> 4]; + result[written++] = dec2hex[oneByte & 15]; + + processed += 8; + } result[written] = 0; - return (const char *)result; + return const_cast(result); } diff --git a/third_party/hashing/hashers/keccak.h b/third_party/hashing/hashers/keccak.h index c0084c67..8ebb845c 100644 --- a/third_party/hashing/hashers/keccak.h +++ b/third_party/hashing/hashers/keccak.h @@ -1,6 +1,6 @@ // ////////////////////////////////////////////////////////// // keccak.h -// Copyright (c) 2014 Stephan Brumme. All rights reserved. +// Copyright (c) 2014,2015 Stephan Brumme. All rights reserved. // see http://create.stephan-brumme.com/disclaimer.html // diff --git a/third_party/hashing/hashers/md5.cpp b/third_party/hashing/hashers/md5.cpp index cf7b5fb8..6406e1ac 100644 --- a/third_party/hashing/hashers/md5.cpp +++ b/third_party/hashing/hashers/md5.cpp @@ -1,6 +1,6 @@ // ////////////////////////////////////////////////////////// // md5.cpp -// Copyright (c) 2014 Stephan Brumme. All rights reserved. +// Copyright (c) 2014,2015 Stephan Brumme. All rights reserved. // see http://create.stephan-brumme.com/disclaimer.html // @@ -311,72 +311,49 @@ void MD5::processBuffer() } -/// return latest hash as 16 hex characters +/// return latest hash as 32 hex characters const char* MD5::getHash() { - // convert hash to string - static const char dec2hex[16+1] = "0123456789abcdef"; + // compute hash (as raw bytes) + unsigned char rawHash[HashBytes]; + getHash(rawHash); + // convert to hex string + static char result[32+1]; + size_t written = 0; + for (int i = 0; i < HashBytes; i++) + { + static const char dec2hex[16+1] = "0123456789abcdef"; + result[written++] = dec2hex[(rawHash[i] >> 4) & 15]; + result[written++] = dec2hex[ rawHash[i] & 15]; + } + result[written] = 0; + return const_cast(result); +} + + +/// return latest hash as bytes +void MD5::getHash(unsigned char buffer[MD5::HashBytes]) +{ // save old hash if buffer is partially filled - uint32_t oldHash[4]; - oldHash[0] = m_hash[0]; - oldHash[1] = m_hash[1]; - oldHash[2] = m_hash[2]; - oldHash[3] = m_hash[3]; + uint32_t oldHash[HashValues]; + for (int i = 0; i < HashValues; i++) + oldHash[i] = m_hash[i]; // process remaining bytes processBuffer(); - // create hash string - static char hashBuffer[4*8+1]; + unsigned char* current = buffer; + for (int i = 0; i < HashValues; i++) + { + *current++ = m_hash[i] & 0xFF; + *current++ = (m_hash[i] >> 8) & 0xFF; + *current++ = (m_hash[i] >> 16) & 0xFF; + *current++ = (m_hash[i] >> 24) & 0xFF; - hashBuffer[ 0] = dec2hex[(m_hash[0] >> 4) & 15]; - hashBuffer[ 1] = dec2hex[ m_hash[0] & 15]; - hashBuffer[ 2] = dec2hex[(m_hash[0] >> 12) & 15]; - hashBuffer[ 3] = dec2hex[(m_hash[0] >> 8) & 15]; - hashBuffer[ 4] = dec2hex[(m_hash[0] >> 20) & 15]; - hashBuffer[ 5] = dec2hex[(m_hash[0] >> 16) & 15]; - hashBuffer[ 6] = dec2hex[ m_hash[0] >> 28 ]; - hashBuffer[ 7] = dec2hex[(m_hash[0] >> 24) & 15]; - - hashBuffer[ 8] = dec2hex[(m_hash[1] >> 4) & 15]; - hashBuffer[ 9] = dec2hex[ m_hash[1] & 15]; - hashBuffer[10] = dec2hex[(m_hash[1] >> 12) & 15]; - hashBuffer[11] = dec2hex[(m_hash[1] >> 8) & 15]; - hashBuffer[12] = dec2hex[(m_hash[1] >> 20) & 15]; - hashBuffer[13] = dec2hex[(m_hash[1] >> 16) & 15]; - hashBuffer[14] = dec2hex[ m_hash[1] >> 28 ]; - hashBuffer[15] = dec2hex[(m_hash[1] >> 24) & 15]; - - hashBuffer[16] = dec2hex[(m_hash[2] >> 4) & 15]; - hashBuffer[17] = dec2hex[ m_hash[2] & 15]; - hashBuffer[18] = dec2hex[(m_hash[2] >> 12) & 15]; - hashBuffer[19] = dec2hex[(m_hash[2] >> 8) & 15]; - hashBuffer[20] = dec2hex[(m_hash[2] >> 20) & 15]; - hashBuffer[21] = dec2hex[(m_hash[2] >> 16) & 15]; - hashBuffer[22] = dec2hex[ m_hash[2] >> 28 ]; - hashBuffer[23] = dec2hex[(m_hash[2] >> 24) & 15]; - - hashBuffer[24] = dec2hex[(m_hash[3] >> 4) & 15]; - hashBuffer[25] = dec2hex[ m_hash[3] & 15]; - hashBuffer[26] = dec2hex[(m_hash[3] >> 12) & 15]; - hashBuffer[27] = dec2hex[(m_hash[3] >> 8) & 15]; - hashBuffer[28] = dec2hex[(m_hash[3] >> 20) & 15]; - hashBuffer[29] = dec2hex[(m_hash[3] >> 16) & 15]; - hashBuffer[30] = dec2hex[ m_hash[3] >> 28 ]; - hashBuffer[31] = dec2hex[(m_hash[3] >> 24) & 15]; - - // zero-terminated string - hashBuffer[32] = 0; - - // restore old hash - m_hash[0] = oldHash[0]; - m_hash[1] = oldHash[1]; - m_hash[2] = oldHash[2]; - m_hash[3] = oldHash[3]; - - // convert to std::string - return (const char*)hashBuffer; + // restore old hash + m_hash[i] = oldHash[i]; + } } diff --git a/third_party/hashing/hashers/md5.h b/third_party/hashing/hashers/md5.h index eb08b5ca..7ff19e33 100644 --- a/third_party/hashing/hashers/md5.h +++ b/third_party/hashing/hashers/md5.h @@ -24,6 +24,9 @@ class MD5 //: public Hash { public: + /// split into 64 byte blocks (=> 512 bits), hash is 16 bytes long + enum { BlockSize = 512 / 8, HashBytes = 16 }; + /// same as reset() MD5(); @@ -35,8 +38,10 @@ public: /// add arbitrary number of bytes void add(const void* data, size_t numBytes); - /// return latest hash as 16 hex characters + /// return latest hash as 32 hex characters const char* getHash(); + /// return latest hash as bytes + void getHash(unsigned char buffer[HashBytes]); /// restart void reset(); @@ -47,15 +52,14 @@ private: /// process everything left in the internal buffer void processBuffer(); - /// split into 64 byte blocks (=> 512 bits) - enum { BlockSize = 512 / 8 }; - /// size of processed data in bytes uint64_t m_numBytes; /// valid bytes in m_buffer size_t m_bufferSize; /// bytes not processed yet uint8_t m_buffer[BlockSize]; + + enum { HashValues = HashBytes / 4 }; /// hash, stored as integers - uint32_t m_hash[4]; + uint32_t m_hash[HashValues]; }; diff --git a/third_party/hashing/hashers/sha1.cpp b/third_party/hashing/hashers/sha1.cpp index 92e054ce..334fbdf8 100644 --- a/third_party/hashing/hashers/sha1.cpp +++ b/third_party/hashing/hashers/sha1.cpp @@ -1,6 +1,6 @@ // ////////////////////////////////////////////////////////// // sha1.cpp -// Copyright (c) 2014 Stephan Brumme. All rights reserved. +// Copyright (c) 2014,2015 Stephan Brumme. All rights reserved. // see http://create.stephan-brumme.com/disclaimer.html // @@ -239,14 +239,14 @@ void SHA1::processBuffer() addLength = extra + paddedLength - BlockSize; // must be big endian - *addLength++ = (msgBits >> 56) & 0xFF; - *addLength++ = (msgBits >> 48) & 0xFF; - *addLength++ = (msgBits >> 40) & 0xFF; - *addLength++ = (msgBits >> 32) & 0xFF; - *addLength++ = (msgBits >> 24) & 0xFF; - *addLength++ = (msgBits >> 16) & 0xFF; - *addLength++ = (msgBits >> 8) & 0xFF; - *addLength = msgBits & 0xFF; + *addLength++ = (unsigned char)((msgBits >> 56) & 0xFF); + *addLength++ = (unsigned char)((msgBits >> 48) & 0xFF); + *addLength++ = (unsigned char)((msgBits >> 40) & 0xFF); + *addLength++ = (unsigned char)((msgBits >> 32) & 0xFF); + *addLength++ = (unsigned char)((msgBits >> 24) & 0xFF); + *addLength++ = (unsigned char)((msgBits >> 16) & 0xFF); + *addLength++ = (unsigned char)((msgBits >> 8) & 0xFF); + *addLength = (unsigned char)( msgBits & 0xFF); // process blocks processBlock(m_buffer); @@ -256,12 +256,30 @@ void SHA1::processBuffer() } -/// return latest hash as 16 hex characters +/// return latest hash as 40 hex characters const char* SHA1::getHash() { - // convert hash to string - static const char dec2hex[16+1] = "0123456789abcdef"; + // compute hash (as raw bytes) + unsigned char rawHash[HashBytes]; + getHash(rawHash); + // convert to hex string + static char result[40+1]; + size_t written = 0; + for (int i = 0; i < HashBytes; i++) + { + static const char dec2hex[16+1] = "0123456789abcdef"; + result[written++] = dec2hex[(rawHash[i] >> 4) & 15]; + result[written++] = dec2hex[ rawHash[i] & 15]; + } + result[written] = 0; + return const_cast(result); +} + + +/// return latest hash as bytes +void SHA1::getHash(unsigned char buffer[SHA1::HashBytes]) +{ // save old hash if buffer is partially filled uint32_t oldHash[HashValues]; for (int i = 0; i < HashValues; i++) @@ -270,28 +288,17 @@ const char* SHA1::getHash() // process remaining bytes processBuffer(); - // create hash string - static char hashBuffer[HashValues*8+1]; - size_t offset = 0; + unsigned char* current = buffer; for (int i = 0; i < HashValues; i++) { - hashBuffer[offset++] = dec2hex[(m_hash[i] >> 28) & 15]; - hashBuffer[offset++] = dec2hex[(m_hash[i] >> 24) & 15]; - hashBuffer[offset++] = dec2hex[(m_hash[i] >> 20) & 15]; - hashBuffer[offset++] = dec2hex[(m_hash[i] >> 16) & 15]; - hashBuffer[offset++] = dec2hex[(m_hash[i] >> 12) & 15]; - hashBuffer[offset++] = dec2hex[(m_hash[i] >> 8) & 15]; - hashBuffer[offset++] = dec2hex[(m_hash[i] >> 4) & 15]; - hashBuffer[offset++] = dec2hex[ m_hash[i] & 15]; + *current++ = (m_hash[i] >> 24) & 0xFF; + *current++ = (m_hash[i] >> 16) & 0xFF; + *current++ = (m_hash[i] >> 8) & 0xFF; + *current++ = m_hash[i] & 0xFF; // restore old hash m_hash[i] = oldHash[i]; } - // zero-terminated string - hashBuffer[offset] = 0; - - // convert to std::string - return (const char *)hashBuffer; } diff --git a/third_party/hashing/hashers/sha1.h b/third_party/hashing/hashers/sha1.h index 4c2a2843..26796764 100644 --- a/third_party/hashing/hashers/sha1.h +++ b/third_party/hashing/hashers/sha1.h @@ -1,6 +1,6 @@ // ////////////////////////////////////////////////////////// // sha1.h -// Copyright (c) 2014 Stephan Brumme. All rights reserved. +// Copyright (c) 2014,2015 Stephan Brumme. All rights reserved. // see http://create.stephan-brumme.com/disclaimer.html // @@ -24,6 +24,9 @@ class SHA1 //: public Hash { public: + /// split into 64 byte blocks (=> 512 bits), hash is 20 bytes long + enum { BlockSize = 512 / 8, HashBytes = 20 }; + /// same as reset() SHA1(); @@ -35,8 +38,10 @@ public: /// add arbitrary number of bytes void add(const void* data, size_t numBytes); - /// return latest hash as 16 hex characters + /// return latest hash as 40 hex characters const char* getHash(); + /// return latest hash as bytes + void getHash(unsigned char buffer[HashBytes]); /// restart void reset(); @@ -47,15 +52,14 @@ private: /// process everything left in the internal buffer void processBuffer(); - /// split into 64 byte blocks (=> 512 bits) - enum { BlockSize = 512 / 8, HashValues = 5 }; - /// size of processed data in bytes uint64_t m_numBytes; /// valid bytes in m_buffer size_t m_bufferSize; /// bytes not processed yet uint8_t m_buffer[BlockSize]; + + enum { HashValues = HashBytes / 4 }; /// hash, stored as integers uint32_t m_hash[HashValues]; }; diff --git a/third_party/hashing/hashers/sha256.cpp b/third_party/hashing/hashers/sha256.cpp index 4dfb0c41..8b12699b 100644 --- a/third_party/hashing/hashers/sha256.cpp +++ b/third_party/hashing/hashers/sha256.cpp @@ -1,6 +1,6 @@ // ////////////////////////////////////////////////////////// // sha256.cpp -// Copyright (c) 2014 Stephan Brumme. All rights reserved. +// Copyright (c) 2014,2015 Stephan Brumme. All rights reserved. // see http://create.stephan-brumme.com/disclaimer.html // @@ -325,14 +325,14 @@ void SHA256::processBuffer() addLength = extra + paddedLength - BlockSize; // must be big endian - *addLength++ = (msgBits >> 56) & 0xFF; - *addLength++ = (msgBits >> 48) & 0xFF; - *addLength++ = (msgBits >> 40) & 0xFF; - *addLength++ = (msgBits >> 32) & 0xFF; - *addLength++ = (msgBits >> 24) & 0xFF; - *addLength++ = (msgBits >> 16) & 0xFF; - *addLength++ = (msgBits >> 8) & 0xFF; - *addLength = msgBits & 0xFF; + *addLength++ = (unsigned char)((msgBits >> 56) & 0xFF); + *addLength++ = (unsigned char)((msgBits >> 48) & 0xFF); + *addLength++ = (unsigned char)((msgBits >> 40) & 0xFF); + *addLength++ = (unsigned char)((msgBits >> 32) & 0xFF); + *addLength++ = (unsigned char)((msgBits >> 24) & 0xFF); + *addLength++ = (unsigned char)((msgBits >> 16) & 0xFF); + *addLength++ = (unsigned char)((msgBits >> 8) & 0xFF); + *addLength = (unsigned char)( msgBits & 0xFF); // process blocks processBlock(m_buffer); @@ -342,12 +342,30 @@ void SHA256::processBuffer() } -/// return latest hash as 16 hex characters +/// return latest hash as 64 hex characters const char* SHA256::getHash() { - // convert hash to string - static const char dec2hex[16+1] = "0123456789abcdef"; + // compute hash (as raw bytes) + unsigned char rawHash[HashBytes]; + getHash(rawHash); + // convert to hex string + static char result[64+1]; + size_t written = 0; + for (int i = 0; i < HashBytes; i++) + { + static const char dec2hex[16+1] = "0123456789abcdef"; + result[written++] = dec2hex[(rawHash[i] >> 4) & 15]; + result[written++] = dec2hex[ rawHash[i] & 15]; + } + result[written] = 0; + return const_cast(result); +} + + +/// return latest hash as bytes +void SHA256::getHash(unsigned char buffer[SHA256::HashBytes]) +{ // save old hash if buffer is partially filled uint32_t oldHash[HashValues]; for (int i = 0; i < HashValues; i++) @@ -356,28 +374,17 @@ const char* SHA256::getHash() // process remaining bytes processBuffer(); - // create hash string - static char hashBuffer[HashValues*8+1]; - size_t offset = 0; + unsigned char* current = buffer; for (int i = 0; i < HashValues; i++) { - hashBuffer[offset++] = dec2hex[(m_hash[i] >> 28) & 15]; - hashBuffer[offset++] = dec2hex[(m_hash[i] >> 24) & 15]; - hashBuffer[offset++] = dec2hex[(m_hash[i] >> 20) & 15]; - hashBuffer[offset++] = dec2hex[(m_hash[i] >> 16) & 15]; - hashBuffer[offset++] = dec2hex[(m_hash[i] >> 12) & 15]; - hashBuffer[offset++] = dec2hex[(m_hash[i] >> 8) & 15]; - hashBuffer[offset++] = dec2hex[(m_hash[i] >> 4) & 15]; - hashBuffer[offset++] = dec2hex[ m_hash[i] & 15]; + *current++ = (m_hash[i] >> 24) & 0xFF; + *current++ = (m_hash[i] >> 16) & 0xFF; + *current++ = (m_hash[i] >> 8) & 0xFF; + *current++ = m_hash[i] & 0xFF; // restore old hash m_hash[i] = oldHash[i]; } - // zero-terminated string - hashBuffer[offset] = 0; - - // convert to std::string - return (const char *)hashBuffer; } diff --git a/third_party/hashing/hashers/sha256.h b/third_party/hashing/hashers/sha256.h index bf040066..e77a9458 100644 --- a/third_party/hashing/hashers/sha256.h +++ b/third_party/hashing/hashers/sha256.h @@ -1,6 +1,6 @@ // ////////////////////////////////////////////////////////// // sha256.h -// Copyright (c) 2014 Stephan Brumme. All rights reserved. +// Copyright (c) 2014,2015 Stephan Brumme. All rights reserved. // see http://create.stephan-brumme.com/disclaimer.html // @@ -24,6 +24,9 @@ class SHA256 //: public Hash { public: + /// split into 64 byte blocks (=> 512 bits), hash is 32 bytes long + enum { BlockSize = 512 / 8, HashBytes = 32 }; + /// same as reset() SHA256(); @@ -35,8 +38,10 @@ public: /// add arbitrary number of bytes void add(const void* data, size_t numBytes); - /// return latest hash as 16 hex characters + /// return latest hash as 64 hex characters const char* getHash(); + /// return latest hash as bytes + void getHash(unsigned char buffer[HashBytes]); /// restart void reset(); @@ -47,15 +52,14 @@ private: /// process everything left in the internal buffer void processBuffer(); - /// split into 64 byte blocks (=> 512 bits) - enum { BlockSize = 512 / 8, HashValues = 8 }; - /// size of processed data in bytes uint64_t m_numBytes; /// valid bytes in m_buffer size_t m_bufferSize; /// bytes not processed yet uint8_t m_buffer[BlockSize]; + + enum { HashValues = HashBytes / 4 }; /// hash, stored as integers - uint32_t m_hash[8]; + uint32_t m_hash[HashValues]; }; diff --git a/third_party/hashing/hashers/sha3.cpp b/third_party/hashing/hashers/sha3.cpp index d06507ce..d238848f 100644 --- a/third_party/hashing/hashers/sha3.cpp +++ b/third_party/hashing/hashers/sha3.cpp @@ -1,6 +1,6 @@ // ////////////////////////////////////////////////////////// // sha3.cpp -// Copyright (c) 2014 Stephan Brumme. All rights reserved. +// Copyright (c) 2014,2015 Stephan Brumme. All rights reserved. // see http://create.stephan-brumme.com/disclaimer.html // @@ -24,7 +24,6 @@ void SHA3::changeBits(Bits bits) reset(); } - /// restart void SHA3::reset() { @@ -177,6 +176,7 @@ void SHA3::add(const void* data, size_t numBytes) { const uint8_t* current = (const uint8_t*) data; + // copy data to buffer if (m_bufferSize > 0) { while (numBytes > 0 && m_bufferSize < m_blockSize) @@ -219,18 +219,16 @@ void SHA3::add(const void* data, size_t numBytes) /// process everything left in the internal buffer void SHA3::processBuffer() { - unsigned int blockSize = 200 - 2 * (m_bits / 8); - // add padding size_t offset = m_bufferSize; // add a "1" byte m_buffer[offset++] = 0x06; // fill with zeros - while (offset < blockSize - 1) + while (offset < m_blockSize) m_buffer[offset++] = 0; // and add a single set bit - m_buffer[blockSize - 1] = 0x80; + m_buffer[offset - 1] |= 0x80; processBlock(m_buffer); } @@ -255,11 +253,24 @@ const char* SHA3::getHash() { // convert a byte to hex unsigned char oneByte = (unsigned char) (m_hash[i] >> (8 * j)); - result[written++]= dec2hex[oneByte >> 4]; - result[written++]= dec2hex[oneByte & 15]; + result[written++] = dec2hex[oneByte >> 4]; + result[written++] = dec2hex[oneByte & 15]; } + + // SHA3-224's last entry in m_hash provides only 32 bits instead of 64 bits + unsigned int remainder = m_bits - hashLength * 64; + unsigned int processed = 0; + while (processed < remainder) + { + // convert a byte to hex + unsigned char oneByte = (unsigned char) (m_hash[hashLength] >> processed); + result[written++] = dec2hex[oneByte >> 4]; + result[written++] = dec2hex[oneByte & 15]; + + processed += 8; + } result[written] = 0; - return (const char*)result; + return const_cast(result); } diff --git a/third_party/hashing/hashers/sha3.h b/third_party/hashing/hashers/sha3.h index 89b161e2..abd62d01 100644 --- a/third_party/hashing/hashers/sha3.h +++ b/third_party/hashing/hashers/sha3.h @@ -1,6 +1,6 @@ // ////////////////////////////////////////////////////////// // sha3.h -// Copyright (c) 2014 Stephan Brumme. All rights reserved. +// Copyright (c) 2014,2015 Stephan Brumme. All rights reserved. // see http://create.stephan-brumme.com/disclaimer.html //