void TTMAC_Base::TruncatedFinal(byte *hash, size_t size) { PadLastBlock(BlockSize() - 2*sizeof(HashWordType)); CorrectEndianess(m_data, m_data, BlockSize() - 2*sizeof(HashWordType)); m_data[m_data.size()-2] = GetBitCountLo(); m_data[m_data.size()-1] = GetBitCountHi(); Transform(m_digest, m_data, true); word32 t2 = m_digest[2]; word32 t3 = m_digest[3]; if (size != DIGESTSIZE) { switch (size) { case 16: m_digest[3] += m_digest[1] + m_digest[4]; case 12: m_digest[2] += m_digest[0] + t3; case 8: m_digest[0] += m_digest[1] + t3; m_digest[1] += m_digest[4] + t2; break; case 4: m_digest[0] += m_digest[1] + m_digest[2] + m_digest[3] + m_digest[4]; break; case 0: // Used by HashTransformation::Restart() break; default: throw InvalidArgument("TTMAC_Base: can't truncate a Two-Track-MAC 20 byte digest to " + IntToString(size) + " bytes"); break; } } CorrectEndianess(m_digest, m_digest, size); memcpy(hash, m_digest, size); Restart(); // reinit for next use }
void Whirlpool::TruncatedFinal(byte *hash, size_t size) { ThrowIfInvalidTruncatedSize(size); PadLastBlock(32); CorrectEndianess(m_data, m_data, 32); m_data[m_data.size()-4] = 0; m_data[m_data.size()-3] = 0; m_data[m_data.size()-2] = GetBitCountHi(); m_data[m_data.size()-1] = GetBitCountLo(); Transform(m_digest, m_data); CorrectEndianess(m_digest, m_digest, DigestSize()); memcpy(hash, m_digest, size); Restart(); // reinit for next use }
void HAVAL::TruncatedFinal(byte *hash, unsigned int size) { ThrowIfInvalidTruncatedSize(size); PadLastBlock(118, 1); // first byte of padding for HAVAL is 1 instead of 0x80 CorrectEndianess(m_data, m_data, 120); m_data[29] &= 0xffff; m_data[29] |= ((word32)digestSize<<25) | ((word32)pass<<19) | ((word32)HAVAL_VERSION<<16); m_data[30] = GetBitCountLo(); m_data[31] = GetBitCountHi(); vTransform(m_data); Tailor(digestSize*8); CorrectEndianess(m_digest, m_digest, digestSize); memcpy(hash, m_digest, size); Restart(); // reinit for next use }
void MD5MAC_Base::TruncatedFinal(byte *hash, size_t size) { ThrowIfInvalidTruncatedSize(size); PadLastBlock(56); CorrectEndianess(m_data, m_data, 56); m_data[14] = GetBitCountLo(); m_data[15] = GetBitCountHi(); Transform(m_digest, m_data, m_key+4); unsigned i; for (i=0; i<4; i++) m_data[i] = m_key[8+i]; for (i=0; i<12; i++) m_data[i+4] = T[i] ^ m_key[8+i%4]; Transform(m_digest, m_data, m_key+4); CorrectEndianess(m_digest, m_digest, DIGESTSIZE); memcpy(hash, m_digest, size); Restart(); // reinit for next use }
// Final process, place digest in hash void HASHwithTransform::Final(byte* hash) { word32 blockSz = getBlockSize(); word32 digestSz = getDigestSize(); word32 padSz = getPadSize(); ByteOrder order = getByteOrder(); AddLength(buffLen_); // before adding pads HashLengthType preLoLen = GetBitCountLo(); HashLengthType preHiLen = GetBitCountHi(); byte* local = reinterpret_cast<byte*>(buffer_); local[buffLen_++] = 0x80; // add 1 // pad with zeros if (buffLen_ > padSz) { memset(&local[buffLen_], 0, blockSz - buffLen_); buffLen_ += blockSz - buffLen_; ByteReverseIf(local, local, blockSz, order); Transform(); buffLen_ = 0; } memset(&local[buffLen_], 0, padSz - buffLen_); ByteReverseIf(local, local, blockSz, order); memcpy(&local[padSz], order ? &preHiLen : &preLoLen, sizeof(preLoLen)); memcpy(&local[padSz+4], order ? &preLoLen : &preHiLen, sizeof(preLoLen)); Transform(); ByteReverseIf(digest_, digest_, digestSz, order); memcpy(hash, digest_, digestSz); Init(); // reset state }