1
+ // ====- SHA256.cpp - SHA256 implementation ---*- C++ -* ======//
2
+ //
3
+ // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
+ // See https://llvm.org/LICENSE.txt for license information.
5
+ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
+ //
7
+ // ===----------------------------------------------------------------------===//
8
+ /*
9
+ * The SHA-256 Secure Hash Standard was published by NIST in 2002.
10
+ *
11
+ * http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf
12
+ *
13
+ * The implementation is based on nacl's sha256 implementation [0] and LLVM's
14
+ * pre-exsiting SHA1 code [1].
15
+ *
16
+ * [0] https://hyperelliptic.org/nacl/nacl-20110221.tar.bz2 (public domain
17
+ * code)
18
+ * [1] llvm/lib/Support/SHA1.{h,cpp}
19
+ */
20
+ // ===----------------------------------------------------------------------===//
21
+
22
+ #include " llvm/Support/SHA256.h"
23
+ #include " llvm/ADT/ArrayRef.h"
24
+ #include " llvm/ADT/StringRef.h"
25
+ #include " llvm/Support/Endian.h"
26
+ #include " llvm/Support/Host.h"
27
+ #include < string.h>
28
+
29
+ namespace llvm {
30
+
31
+ #if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && BYTE_ORDER == BIG_ENDIAN
32
+ #define SHA_BIG_ENDIAN
33
+ #endif
34
+
35
+ #define SHR (x, c ) ((x) >> (c))
36
+ #define ROTR (x, n ) (((x) >> n) | ((x) << (32 - (n))))
37
+
38
+ #define CH (x, y, z ) (((x) & (y)) ^ (~(x) & (z)))
39
+ #define MAJ (x, y, z ) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
40
+
41
+ #define SIGMA_0 (x ) (ROTR(x, 2 ) ^ ROTR(x, 13 ) ^ ROTR(x, 22 ))
42
+ #define SIGMA_1 (x ) (ROTR(x, 6 ) ^ ROTR(x, 11 ) ^ ROTR(x, 25 ))
43
+
44
+ #define SIGMA_2 (x ) (ROTR(x, 17 ) ^ ROTR(x, 19 ) ^ SHR(x, 10 ))
45
+ #define SIGMA_3 (x ) (ROTR(x, 7 ) ^ ROTR(x, 18 ) ^ SHR(x, 3 ))
46
+
47
+ #define F_EXPAND (A, B, C, D, E, F, G, H, M1, M2, M3, M4, k ) \
48
+ do { \
49
+ H += SIGMA_1 (E) + CH (E, F, G) + M1 + k; \
50
+ D += H; \
51
+ H += SIGMA_0 (A) + MAJ (A, B, C); \
52
+ M1 += SIGMA_2 (M2) + M3 + SIGMA_3 (M4); \
53
+ } while (0 );
54
+
55
+ void SHA256::init () {
56
+ InternalState.State [0 ] = 0x6A09E667 ;
57
+ InternalState.State [1 ] = 0xBB67AE85 ;
58
+ InternalState.State [2 ] = 0x3C6EF372 ;
59
+ InternalState.State [3 ] = 0xA54FF53A ;
60
+ InternalState.State [4 ] = 0x510E527F ;
61
+ InternalState.State [5 ] = 0x9B05688C ;
62
+ InternalState.State [6 ] = 0x1F83D9AB ;
63
+ InternalState.State [7 ] = 0x5BE0CD19 ;
64
+ InternalState.ByteCount = 0 ;
65
+ InternalState.BufferOffset = 0 ;
66
+ }
67
+
68
+ void SHA256::hashBlock () {
69
+ uint32_t A = InternalState.State [0 ];
70
+ uint32_t B = InternalState.State [1 ];
71
+ uint32_t C = InternalState.State [2 ];
72
+ uint32_t D = InternalState.State [3 ];
73
+ uint32_t E = InternalState.State [4 ];
74
+ uint32_t F = InternalState.State [5 ];
75
+ uint32_t G = InternalState.State [6 ];
76
+ uint32_t H = InternalState.State [7 ];
77
+
78
+ uint32_t W00 = InternalState.Buffer .L [0 ];
79
+ uint32_t W01 = InternalState.Buffer .L [1 ];
80
+ uint32_t W02 = InternalState.Buffer .L [2 ];
81
+ uint32_t W03 = InternalState.Buffer .L [3 ];
82
+ uint32_t W04 = InternalState.Buffer .L [4 ];
83
+ uint32_t W05 = InternalState.Buffer .L [5 ];
84
+ uint32_t W06 = InternalState.Buffer .L [6 ];
85
+ uint32_t W07 = InternalState.Buffer .L [7 ];
86
+ uint32_t W08 = InternalState.Buffer .L [8 ];
87
+ uint32_t W09 = InternalState.Buffer .L [9 ];
88
+ uint32_t W10 = InternalState.Buffer .L [10 ];
89
+ uint32_t W11 = InternalState.Buffer .L [11 ];
90
+ uint32_t W12 = InternalState.Buffer .L [12 ];
91
+ uint32_t W13 = InternalState.Buffer .L [13 ];
92
+ uint32_t W14 = InternalState.Buffer .L [14 ];
93
+ uint32_t W15 = InternalState.Buffer .L [15 ];
94
+
95
+ F_EXPAND (A, B, C, D, E, F, G, H, W00, W14, W09, W01, 0x428A2F98 );
96
+ F_EXPAND (H, A, B, C, D, E, F, G, W01, W15, W10, W02, 0x71374491 );
97
+ F_EXPAND (G, H, A, B, C, D, E, F, W02, W00, W11, W03, 0xB5C0FBCF );
98
+ F_EXPAND (F, G, H, A, B, C, D, E, W03, W01, W12, W04, 0xE9B5DBA5 );
99
+ F_EXPAND (E, F, G, H, A, B, C, D, W04, W02, W13, W05, 0x3956C25B );
100
+ F_EXPAND (D, E, F, G, H, A, B, C, W05, W03, W14, W06, 0x59F111F1 );
101
+ F_EXPAND (C, D, E, F, G, H, A, B, W06, W04, W15, W07, 0x923F82A4 );
102
+ F_EXPAND (B, C, D, E, F, G, H, A, W07, W05, W00, W08, 0xAB1C5ED5 );
103
+ F_EXPAND (A, B, C, D, E, F, G, H, W08, W06, W01, W09, 0xD807AA98 );
104
+ F_EXPAND (H, A, B, C, D, E, F, G, W09, W07, W02, W10, 0x12835B01 );
105
+ F_EXPAND (G, H, A, B, C, D, E, F, W10, W08, W03, W11, 0x243185BE );
106
+ F_EXPAND (F, G, H, A, B, C, D, E, W11, W09, W04, W12, 0x550C7DC3 );
107
+ F_EXPAND (E, F, G, H, A, B, C, D, W12, W10, W05, W13, 0x72BE5D74 );
108
+ F_EXPAND (D, E, F, G, H, A, B, C, W13, W11, W06, W14, 0x80DEB1FE );
109
+ F_EXPAND (C, D, E, F, G, H, A, B, W14, W12, W07, W15, 0x9BDC06A7 );
110
+ F_EXPAND (B, C, D, E, F, G, H, A, W15, W13, W08, W00, 0xC19BF174 );
111
+
112
+ F_EXPAND (A, B, C, D, E, F, G, H, W00, W14, W09, W01, 0xE49B69C1 );
113
+ F_EXPAND (H, A, B, C, D, E, F, G, W01, W15, W10, W02, 0xEFBE4786 );
114
+ F_EXPAND (G, H, A, B, C, D, E, F, W02, W00, W11, W03, 0x0FC19DC6 );
115
+ F_EXPAND (F, G, H, A, B, C, D, E, W03, W01, W12, W04, 0x240CA1CC );
116
+ F_EXPAND (E, F, G, H, A, B, C, D, W04, W02, W13, W05, 0x2DE92C6F );
117
+ F_EXPAND (D, E, F, G, H, A, B, C, W05, W03, W14, W06, 0x4A7484AA );
118
+ F_EXPAND (C, D, E, F, G, H, A, B, W06, W04, W15, W07, 0x5CB0A9DC );
119
+ F_EXPAND (B, C, D, E, F, G, H, A, W07, W05, W00, W08, 0x76F988DA );
120
+ F_EXPAND (A, B, C, D, E, F, G, H, W08, W06, W01, W09, 0x983E5152 );
121
+ F_EXPAND (H, A, B, C, D, E, F, G, W09, W07, W02, W10, 0xA831C66D );
122
+ F_EXPAND (G, H, A, B, C, D, E, F, W10, W08, W03, W11, 0xB00327C8 );
123
+ F_EXPAND (F, G, H, A, B, C, D, E, W11, W09, W04, W12, 0xBF597FC7 );
124
+ F_EXPAND (E, F, G, H, A, B, C, D, W12, W10, W05, W13, 0xC6E00BF3 );
125
+ F_EXPAND (D, E, F, G, H, A, B, C, W13, W11, W06, W14, 0xD5A79147 );
126
+ F_EXPAND (C, D, E, F, G, H, A, B, W14, W12, W07, W15, 0x06CA6351 );
127
+ F_EXPAND (B, C, D, E, F, G, H, A, W15, W13, W08, W00, 0x14292967 );
128
+
129
+ F_EXPAND (A, B, C, D, E, F, G, H, W00, W14, W09, W01, 0x27B70A85 );
130
+ F_EXPAND (H, A, B, C, D, E, F, G, W01, W15, W10, W02, 0x2E1B2138 );
131
+ F_EXPAND (G, H, A, B, C, D, E, F, W02, W00, W11, W03, 0x4D2C6DFC );
132
+ F_EXPAND (F, G, H, A, B, C, D, E, W03, W01, W12, W04, 0x53380D13 );
133
+ F_EXPAND (E, F, G, H, A, B, C, D, W04, W02, W13, W05, 0x650A7354 );
134
+ F_EXPAND (D, E, F, G, H, A, B, C, W05, W03, W14, W06, 0x766A0ABB );
135
+ F_EXPAND (C, D, E, F, G, H, A, B, W06, W04, W15, W07, 0x81C2C92E );
136
+ F_EXPAND (B, C, D, E, F, G, H, A, W07, W05, W00, W08, 0x92722C85 );
137
+ F_EXPAND (A, B, C, D, E, F, G, H, W08, W06, W01, W09, 0xA2BFE8A1 );
138
+ F_EXPAND (H, A, B, C, D, E, F, G, W09, W07, W02, W10, 0xA81A664B );
139
+ F_EXPAND (G, H, A, B, C, D, E, F, W10, W08, W03, W11, 0xC24B8B70 );
140
+ F_EXPAND (F, G, H, A, B, C, D, E, W11, W09, W04, W12, 0xC76C51A3 );
141
+ F_EXPAND (E, F, G, H, A, B, C, D, W12, W10, W05, W13, 0xD192E819 );
142
+ F_EXPAND (D, E, F, G, H, A, B, C, W13, W11, W06, W14, 0xD6990624 );
143
+ F_EXPAND (C, D, E, F, G, H, A, B, W14, W12, W07, W15, 0xF40E3585 );
144
+ F_EXPAND (B, C, D, E, F, G, H, A, W15, W13, W08, W00, 0x106AA070 );
145
+
146
+ F_EXPAND (A, B, C, D, E, F, G, H, W00, W14, W09, W01, 0x19A4C116 );
147
+ F_EXPAND (H, A, B, C, D, E, F, G, W01, W15, W10, W02, 0x1E376C08 );
148
+ F_EXPAND (G, H, A, B, C, D, E, F, W02, W00, W11, W03, 0x2748774C );
149
+ F_EXPAND (F, G, H, A, B, C, D, E, W03, W01, W12, W04, 0x34B0BCB5 );
150
+ F_EXPAND (E, F, G, H, A, B, C, D, W04, W02, W13, W05, 0x391C0CB3 );
151
+ F_EXPAND (D, E, F, G, H, A, B, C, W05, W03, W14, W06, 0x4ED8AA4A );
152
+ F_EXPAND (C, D, E, F, G, H, A, B, W06, W04, W15, W07, 0x5B9CCA4F );
153
+ F_EXPAND (B, C, D, E, F, G, H, A, W07, W05, W00, W08, 0x682E6FF3 );
154
+ F_EXPAND (A, B, C, D, E, F, G, H, W08, W06, W01, W09, 0x748F82EE );
155
+ F_EXPAND (H, A, B, C, D, E, F, G, W09, W07, W02, W10, 0x78A5636F );
156
+ F_EXPAND (G, H, A, B, C, D, E, F, W10, W08, W03, W11, 0x84C87814 );
157
+ F_EXPAND (F, G, H, A, B, C, D, E, W11, W09, W04, W12, 0x8CC70208 );
158
+ F_EXPAND (E, F, G, H, A, B, C, D, W12, W10, W05, W13, 0x90BEFFFA );
159
+ F_EXPAND (D, E, F, G, H, A, B, C, W13, W11, W06, W14, 0xA4506CEB );
160
+ F_EXPAND (C, D, E, F, G, H, A, B, W14, W12, W07, W15, 0xBEF9A3F7 );
161
+ F_EXPAND (B, C, D, E, F, G, H, A, W15, W13, W08, W00, 0xC67178F2 );
162
+
163
+ InternalState.State [0 ] += A;
164
+ InternalState.State [1 ] += B;
165
+ InternalState.State [2 ] += C;
166
+ InternalState.State [3 ] += D;
167
+ InternalState.State [4 ] += E;
168
+ InternalState.State [5 ] += F;
169
+ InternalState.State [6 ] += G;
170
+ InternalState.State [7 ] += H;
171
+ }
172
+
173
+ void SHA256::addUncounted (uint8_t Data) {
174
+ #ifdef SHA_BIG_ENDIAN
175
+ InternalState.Buffer .C [InternalState.BufferOffset ] = Data;
176
+ #else
177
+ InternalState.Buffer .C [InternalState.BufferOffset ^ 3 ] = Data;
178
+ #endif
179
+
180
+ InternalState.BufferOffset ++;
181
+ if (InternalState.BufferOffset == BLOCK_LENGTH) {
182
+ hashBlock ();
183
+ InternalState.BufferOffset = 0 ;
184
+ }
185
+ }
186
+
187
+ void SHA256::writebyte (uint8_t Data) {
188
+ ++InternalState.ByteCount ;
189
+ addUncounted (Data);
190
+ }
191
+
192
+ void SHA256::update (ArrayRef<uint8_t > Data) {
193
+ InternalState.ByteCount += Data.size ();
194
+
195
+ // Finish the current block.
196
+ if (InternalState.BufferOffset > 0 ) {
197
+ const size_t Remainder = std::min<size_t >(
198
+ Data.size (), BLOCK_LENGTH - InternalState.BufferOffset );
199
+ for (size_t I = 0 ; I < Remainder; ++I)
200
+ addUncounted (Data[I]);
201
+ Data = Data.drop_front (Remainder);
202
+ }
203
+
204
+ // Fast buffer filling for large inputs.
205
+ while (Data.size () >= BLOCK_LENGTH) {
206
+ assert (InternalState.BufferOffset == 0 );
207
+ assert (BLOCK_LENGTH % 4 == 0 );
208
+ constexpr size_t BLOCK_LENGTH_32 = BLOCK_LENGTH / 4 ;
209
+ for (size_t I = 0 ; I < BLOCK_LENGTH_32; ++I)
210
+ InternalState.Buffer .L [I] = support::endian::read32be (&Data[I * 4 ]);
211
+ hashBlock ();
212
+ Data = Data.drop_front (BLOCK_LENGTH);
213
+ }
214
+
215
+ // Finish the remainder.
216
+ for (uint8_t C : Data)
217
+ addUncounted (C);
218
+ }
219
+
220
+ void SHA256::update (StringRef Str) {
221
+ update (
222
+ ArrayRef<uint8_t >((uint8_t *)const_cast <char *>(Str.data ()), Str.size ()));
223
+ }
224
+
225
+ void SHA256::pad () {
226
+ // Implement SHA-2 padding (fips180-2 5.1.1)
227
+
228
+ // Pad with 0x80 followed by 0x00 until the end of the block
229
+ addUncounted (0x80 );
230
+ while (InternalState.BufferOffset != 56 )
231
+ addUncounted (0x00 );
232
+
233
+ uint64_t len = InternalState.ByteCount << 3 ; // bit size
234
+
235
+ // Append length in the last 8 bytes big edian encoded
236
+ addUncounted (len >> 56 );
237
+ addUncounted (len >> 48 );
238
+ addUncounted (len >> 40 );
239
+ addUncounted (len >> 32 );
240
+ addUncounted (len >> 24 );
241
+ addUncounted (len >> 16 );
242
+ addUncounted (len >> 8 );
243
+ addUncounted (len);
244
+ }
245
+
246
+ StringRef SHA256::final () {
247
+ // Pad to complete the last block
248
+ pad ();
249
+
250
+ #ifdef SHA_BIG_ENDIAN
251
+ // Just copy the current state
252
+ for (int i = 0 ; i < 8 ; i++) {
253
+ HashResult[i] = InternalState.State [i];
254
+ }
255
+ #else
256
+ // Swap byte order back
257
+ for (int i = 0 ; i < 8 ; i++) {
258
+ HashResult[i] = (((InternalState.State [i]) << 24 ) & 0xff000000 ) |
259
+ (((InternalState.State [i]) << 8 ) & 0x00ff0000 ) |
260
+ (((InternalState.State [i]) >> 8 ) & 0x0000ff00 ) |
261
+ (((InternalState.State [i]) >> 24 ) & 0x000000ff );
262
+ }
263
+ #endif
264
+
265
+ // Return pointer to hash (32 characters)
266
+ return StringRef ((char *)HashResult, HASH_LENGTH);
267
+ }
268
+
269
+ StringRef SHA256::result () {
270
+ auto StateToRestore = InternalState;
271
+
272
+ auto Hash = final ();
273
+
274
+ // Restore the state
275
+ InternalState = StateToRestore;
276
+
277
+ // Return pointer to hash (32 characters)
278
+ return Hash;
279
+ }
280
+
281
+ std::array<uint8_t , 32 > SHA256::hash (ArrayRef<uint8_t > Data) {
282
+ SHA256 Hash;
283
+ Hash.update (Data);
284
+ StringRef S = Hash.final ();
285
+
286
+ std::array<uint8_t , 32 > Arr;
287
+ memcpy (Arr.data (), S.data (), S.size ());
288
+ return Arr;
289
+ }
290
+
291
+ } // namespace llvm
0 commit comments