34 #pragma GCC diagnostic push
35 #pragma GCC diagnostic ignored "-Wsign-conversion"
42constexpr std::array<uint32_t, 64> SHA256::K;
44SHA256::SHA256() : m_blocklen(0), m_bitlen(0)
46 m_state[0] = 0x6a09e667;
47 m_state[1] = 0xbb67ae85;
48 m_state[2] = 0x3c6ef372;
49 m_state[3] = 0xa54ff53a;
50 m_state[4] = 0x510e527f;
51 m_state[5] = 0x9b05688c;
52 m_state[6] = 0x1f83d9ab;
53 m_state[7] = 0x5be0cd19;
56void SHA256::update(
const uint8_t* data,
size_t length)
58 for (
size_t i = 0; i < length; i++)
60 m_data[m_blocklen++] = data[i];
72void SHA256::update(
const std::string& data)
74 update(
reinterpret_cast<const uint8_t*
>(data.c_str()), data.size());
77uint8_t* SHA256::digest()
79 uint8_t* hash =
new uint8_t[32];
87uint32_t SHA256::rotr(uint32_t x, uint32_t n)
89 return (x >> n) | (x << (32 - n));
92uint32_t SHA256::choose(uint32_t e, uint32_t f, uint32_t g)
94 return (e & f) ^ (~e &
g);
97uint32_t SHA256::majority(uint32_t a, uint32_t b, uint32_t c)
99 return (a & (b | c)) | (b & c);
102uint32_t SHA256::sig0(uint32_t x)
104 return SHA256::rotr(x, 7) ^ SHA256::rotr(x, 18) ^ (x >> 3);
107uint32_t SHA256::sig1(uint32_t x)
109 return SHA256::rotr(x, 17) ^ SHA256::rotr(x, 19) ^ (x >> 10);
112void SHA256::transform()
114 uint32_t maj, xorA, ch, xorE, sum, newA, newE, m[64];
117 for (uint8_t i = 0, j = 0; i < 16; i++, j += 4)
119 m[i] = (m_data[j] << 24) | (m_data[j + 1] << 16) | (m_data[j + 2] << 8) | (m_data[j + 3]);
122 for (uint8_t k = 16; k < 64; k++)
124 m[k] = SHA256::sig1(m[k - 2]) + m[k - 7] + SHA256::sig0(m[k - 15]) + m[k - 16];
127 for (uint8_t i = 0; i < 8; i++)
129 state[i] = m_state[i];
132 for (uint8_t i = 0; i < 64; i++)
134 maj = SHA256::majority(state[0], state[1], state[2]);
135 xorA = SHA256::rotr(state[0], 2) ^ SHA256::rotr(state[0], 13) ^ SHA256::rotr(state[0], 22);
137 ch = choose(state[4], state[5], state[6]);
139 xorE = SHA256::rotr(state[4], 6) ^ SHA256::rotr(state[4], 11) ^ SHA256::rotr(state[4], 25);
141 sum = m[i] + K[i] + state[7] + ch + xorE;
142 newA = xorA + maj + sum;
143 newE = state[3] + sum;
155 for (uint8_t i = 0; i < 8; i++)
157 m_state[i] += state[i];
163 uint64_t i = m_blocklen;
164 uint8_t end = m_blocklen < 56 ? 56 : 64;
172 if (m_blocklen >= 56)
175 memset(m_data, 0, 56);
179 m_bitlen += m_blocklen * 8;
180 m_data[63] =
static_cast<uint8_t
>(m_bitlen);
181 m_data[62] =
static_cast<uint8_t
>(m_bitlen >> 8);
182 m_data[61] =
static_cast<uint8_t
>(m_bitlen >> 16);
183 m_data[60] =
static_cast<uint8_t
>(m_bitlen >> 24);
184 m_data[59] =
static_cast<uint8_t
>(m_bitlen >> 32);
185 m_data[58] =
static_cast<uint8_t
>(m_bitlen >> 40);
186 m_data[57] =
static_cast<uint8_t
>(m_bitlen >> 48);
187 m_data[56] =
static_cast<uint8_t
>(m_bitlen >> 56);
191void SHA256::revert(uint8_t* hash)
195 for (uint8_t i = 0; i < 4; i++)
197 for (uint8_t j = 0; j < 8; j++)
199 hash[i + (j * 4)] = (m_state[j] >> (24 - i * 8)) & 0x000000ff;
204std::string SHA256::toString(
const uint8_t* digest)
207 s << std::setfill(
'0') << std::hex;
209 for (uint8_t i = 0; i < 32; i++)
211 s << std::setw(2) << static_cast<unsigned int>(digest[i]);
221#if defined(__clang__)
222 #pragma GCC diagnostic pop
auto transform(std::tuple< Ts... > const &inputs, Function function)
Transform algorithm for tuples.