| 34 | size -= count; |
| 35 | _blockSize += count; |
| 36 | if (_blockSize == _block.size()) |
| 37 | { |
| 38 | Transform(_block.data()); |
| 39 | _blockSize = 0; |
| 40 | } |
| 41 | } |
| 42 | } |
| 43 | |
| 44 | std::array<uint8_t, 32> Finish() |
| 45 | { |
| 46 | _block[_blockSize++] = 0x80; |
| 47 | if (_blockSize > 56) |
| 48 | { |
| 49 | std::fill(_block.begin() + _blockSize, _block.end(), 0); |
| 50 | Transform(_block.data()); |
| 51 | _blockSize = 0; |
| 52 | } |
| 53 | std::fill(_block.begin() + _blockSize, _block.begin() + 56, 0); |
| 54 | for (int i = 0; i < 8; ++i) |
| 55 | _block[63 - i] = static_cast<uint8_t>(_bitCount >> (i * 8)); |
| 56 | Transform(_block.data()); |
| 57 | |
| 58 | std::array<uint8_t, 32> digest{}; |
| 59 | for (size_t i = 0; i < _state.size(); ++i) |
| 60 | for (int byte = 0; byte < 4; ++byte) |
| 61 | digest[i * 4 + byte] = static_cast<uint8_t>(_state[i] >> (24 - byte * 8)); |
| 62 | return digest; |
| 63 | } |
| 64 | |
| 65 | private: |
| 66 | static uint32_t Rotate(uint32_t value, int count) { return (value >> count) | (value << (32 - count)); } |
| 67 | void Transform(const uint8_t* block) |
| 68 | { |
| 69 | static constexpr uint32_t constants[64] = { |
| 70 | 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, |
| 71 | 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, |
| 72 | 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, |
| 73 | 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, |
no test coverage detected