Audacity 3.2.0
SHA256.cpp
Go to the documentation of this file.
1/*
2 * SPDX-License-Identifier: GPL-2.0-or-later
3 * SPDX-FileName: SHA256.h
4 * SPDX-FileContributor: Dmitry Vedenko
5 *
6 * Based on a public domain code by Brad Conte.
7 */
8
9#include "SHA256.h"
10
11#include <cassert>
12#include <cstring>
13
14namespace crypto
15{
16
17namespace
18{
19constexpr uint32_t K[64] = {
20 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1,
21 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
22 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786,
23 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
24 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147,
25 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
26 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b,
27 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
28 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a,
29 0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
30 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
31};
32
33#define ROTLEFT(a, b) (((a) << (b)) | ((a) >> (32 - (b))))
34#define ROTRIGHT(a, b) (((a) >> (b)) | ((a) << (32 - (b))))
35
36#define CH(x, y, z) (((x) & (y)) ^ (~(x) & (z)))
37#define MAJ(x, y, z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
38#define EP0(x) (ROTRIGHT(x, 2) ^ ROTRIGHT(x, 13) ^ ROTRIGHT(x, 22))
39#define EP1(x) (ROTRIGHT(x, 6) ^ ROTRIGHT(x, 11) ^ ROTRIGHT(x, 25))
40#define SIG0(x) (ROTRIGHT(x, 7) ^ ROTRIGHT(x, 18) ^ ((x) >> 3))
41#define SIG1(x) (ROTRIGHT(x, 17) ^ ROTRIGHT(x, 19) ^ ((x) >> 10))
42
43void sha256_transform(uint32_t state[8], const uint8_t data[64])
44{
45 uint32_t m[SHA256::BLOCK_SIZE];
46
47 int i = 0;
48 int j = 0;
49
50 for (; i < 16; ++i, j += 4)
51 m[i] = (data[j] << 24) | (data[j + 1] << 16) | (data[j + 2] << 8) |
52 (data[j + 3]);
53
54 for (; i < 64; ++i)
55 m[i] = SIG1(m[i - 2]) + m[i - 7] + SIG0(m[i - 15]) + m[i - 16];
56
57 uint32_t a = state[0];
58 uint32_t b = state[1];
59 uint32_t c = state[2];
60 uint32_t d = state[3];
61 uint32_t e = state[4];
62 uint32_t f = state[5];
63 uint32_t g = state[6];
64 uint32_t h = state[7];
65
66 for (i = 0; i < SHA256::BLOCK_SIZE; ++i)
67 {
68 const uint32_t t1 = h + EP1(e) + CH(e, f, g) + K[i] + m[i];
69 const uint32_t t2 = EP0(a) + MAJ(a, b, c);
70
71 h = g;
72 g = f;
73 f = e;
74 e = d + t1;
75 d = c;
76 c = b;
77 b = a;
78 a = t1 + t2;
79 }
80
81 state[0] += a;
82 state[1] += b;
83 state[2] += c;
84 state[3] += d;
85 state[4] += e;
86 state[5] += f;
87 state[6] += g;
88 state[7] += h;
89}
90
91} // namespace
92
94{
95 Reset();
96}
97
98void SHA256::Update(const void* data, std::size_t size)
99{
100 const uint8_t* dataPtr = static_cast<const uint8_t*>(data);
101
102 while (size > 0)
103 {
104 std::size_t blockSize =
105 std::min<size_t>(size, SHA256::BLOCK_SIZE - mBufferLength);
106
107 std::memcpy(mBuffer + mBufferLength, dataPtr, blockSize);
108
109 mBufferLength += blockSize;
110 dataPtr += blockSize;
111 size -= blockSize;
112
114 {
116 mBitLength += 512;
117 mBufferLength = 0;
118 }
119 }
120}
121
122void SHA256::Update(const char* zString)
123{
124 Update(zString, std::strlen(zString));
125}
126
127std::string SHA256::Finalize()
128{
129 uint8_t pad[SHA256::BLOCK_SIZE];
130 std::size_t padLength;
131
132 // `mBufferLength` is always less than SHA256::BLOCK_SIZE. See `Update`
133 // method.
135
137
138 if (mBufferLength < 56)
139 {
140 mBuffer[mBufferLength++] = 0x80;
141 std::memset(mBuffer + mBufferLength, 0, 56 - mBufferLength);
142 }
143 else
144 {
145 mBuffer[mBufferLength++] = 0x80;
146 std::memset(
149 std::memset(mBuffer, 0, 56);
150 }
151
152
153 mBuffer[56] = (mBitLength >> 56) & 0xff;
154 mBuffer[57] = (mBitLength >> 48) & 0xff;
155 mBuffer[58] = (mBitLength >> 40) & 0xff;
156 mBuffer[59] = (mBitLength >> 32) & 0xff;
157 mBuffer[60] = (mBitLength >> 24) & 0xff;
158 mBuffer[61] = (mBitLength >> 16) & 0xff;
159 mBuffer[62] = (mBitLength >> 8) & 0xff;
160 mBuffer[63] = (mBitLength >> 0) & 0xff;
161
163
164 uint8_t result[SHA256::HASH_SIZE];
165
166 for (int i = 0; i < 8; ++i)
167 {
168 result[i * 4 + 0] = (mState[i] >> 24) & 0xff;
169 result[i * 4 + 1] = (mState[i] >> 16) & 0xff;
170 result[i * 4 + 2] = (mState[i] >> 8) & 0xff;
171 result[i * 4 + 3] = (mState[i] >> 0) & 0xff;
172 }
173
174 Reset();
175
176 // Convert to hex string
177 constexpr char hexChars[] = "0123456789ABCDEF";
178 std::string resultStr;
179 resultStr.resize(HASH_SIZE * 2);
180
181 for (int i = 0; i < SHA256::HASH_SIZE; ++i)
182 {
183 resultStr[i * 2 + 0] = hexChars[(result[i] >> 4) & 0xf];
184 resultStr[i * 2 + 1] = hexChars[result[i] & 0xf];
185 }
186
187 return resultStr;
188}
189
191{
192 mBitLength = 0;
193
194 mState[0] = 0x6a09e667;
195 mState[1] = 0xbb67ae85;
196 mState[2] = 0x3c6ef372;
197 mState[3] = 0xa54ff53a;
198 mState[4] = 0x510e527f;
199 mState[5] = 0x9b05688c;
200 mState[6] = 0x1f83d9ab;
201 mState[7] = 0x5be0cd19;
202
203 std::memset(mBuffer, 0, sizeof(mBuffer));
204 mBufferLength = 0;
205}
206
207} // namespace crypto
#define EP1(x)
Definition: SHA256.cpp:39
#define CH(x, y, z)
Definition: SHA256.cpp:36
#define SIG0(x)
Definition: SHA256.cpp:40
#define SIG1(x)
Definition: SHA256.cpp:41
#define EP0(x)
Definition: SHA256.cpp:38
#define MAJ(x, y, z)
Definition: SHA256.cpp:37
void Reset()
Definition: SHA256.cpp:190
void Update(const void *data, std::size_t size)
Definition: SHA256.cpp:98
uint8_t mBuffer[BLOCK_SIZE]
Definition: SHA256.h:45
static constexpr std::size_t HASH_SIZE
Definition: SHA256.h:19
uint32_t mState[8]
Definition: SHA256.h:44
static constexpr std::size_t BLOCK_SIZE
Definition: SHA256.h:20
std::string Finalize()
Definition: SHA256.cpp:127
uint64_t mBitLength
Definition: SHA256.h:43
uint32_t mBufferLength
Definition: SHA256.h:46
void sha256_transform(uint32_t state[8], const uint8_t data[64])
Definition: SHA256.cpp:43