1 // Written in the D programming language.
2 /**
3 This has been temporarily added to DAuth until it becomes part of Phobos:
4 $(LINK https://github.com/D-Programming-Language/phobos/pull/2129)
5 
6 Main module: $(LINK2 index.html,dauth)$(BR)
7 
8  * Computes SHA1 and SHA2 hashes of arbitrary data. SHA hashes are 20 to 64 byte
9  * quantities (depending on the SHA algorithm) that are like a checksum or CRC,
10  * but are more robust. 
11  *
12  * SHA2 comes in several different versions, all supported by this module:
13  * SHA-224, SHA-256, SHA-384, SHA-512, SHA-512/224 and SHA-512/256.
14  *
15  * This module conforms to the APIs defined in $(D std.digest.digest). To understand the
16  * differences between the template and the OOP API, see $(D std.digest.digest).
17  *
18  * This module publicly imports $(D std.digest.digest) and can be used as a stand-alone
19  * module.
20  *
21  * License:   <a href="http://www.boost.org/LICENSE_1_0.txt">Boost License 1.0</a>
22  *
23  * CTFE:
24  * Digests do not work in CTFE
25  *
26  * Authors:
27  * The routines and algorithms are derived from the
28  * $(I Secure Hash Signature Standard (SHS) (FIPS PUB 180-2)). $(BR )
29  * Kai Nacke, Johannes Pfau, Nick Sabalausky
30  *
31  * References:
32  * $(UL
33  * $(LI $(LINK2 http://csrc.nist.gov/publications/fips/fips180-2/fips180-2withchangenotice.pdf, FIPS PUB180-2))
34  * $(LI $(LINK2 http://software.intel.com/en-us/articles/improving-the-performance-of-the-secure-hash-algorithm-1/, Fast implementation of SHA1))
35  * $(LI $(LINK2 http://en.wikipedia.org/wiki/Secure_Hash_Algorithm, Wikipedia article about SHA))
36  * )
37  *
38  * Source: $(PHOBOSSRC std/digest/_sha.d)
39  *
40  * Macros:
41  *      WIKI = Phobos/StdSha1
42  *      MYREF = <font face='Consolas, "Bitstream Vera Sans Mono", "Andale Mono", Monaco, "DejaVu Sans Mono", "Lucida Console", monospace'><a href="#$1">$1</a>&nbsp;</font>
43  */
44 
45 /*          Copyright Kai Nacke 2012.
46  * Distributed under the Boost Software License, Version 1.0.
47  *    (See accompanying file LICENSE_1_0.txt or copy at
48  *          http://www.boost.org/LICENSE_1_0.txt)
49  */
50 //module std.digest.sha;
51 module dauth.sha;
52 
53 ///
54 unittest
55 {
56     //Template API
57     ubyte[20] hash1 = sha1Of("abc");
58     assert(toHexString(hash1) == "A9993E364706816ABA3E25717850C26C9CD0D89D");
59 
60     ubyte[28] hash224 = sha224Of("abc");
61     assert(toHexString(hash224) == "23097D223405D8228642A477BDA255B32AADBCE4BDA0B3F7E36C9DA7");
62 
63     //Feeding data
64     ubyte[1024] data;
65     SHA1 sha1;
66     sha1.start();
67     sha1.put(data[]);
68     sha1.start(); //Start again
69     sha1.put(data[]);
70     hash1 = sha1.finish();
71 }
72 
73 ///
74 unittest
75 {
76     //OOP API
77     auto sha1 = new SHA1Digest();
78     ubyte[] hash1 = sha1.digest("abc");
79     assert(toHexString(hash1) == "A9993E364706816ABA3E25717850C26C9CD0D89D");
80 
81     auto sha224 = new SHA224Digest();
82     ubyte[] hash224 = sha224.digest("abc");
83     assert(toHexString(hash224) == "23097D223405D8228642A477BDA255B32AADBCE4BDA0B3F7E36C9DA7");
84 
85     //Feeding data
86     ubyte[1024] data;
87     sha1.put(data[]);
88     sha1.reset(); //Start again
89     sha1.put(data[]);
90     hash1 = sha1.finish();
91 }
92 
93 version(D_PIC)
94 {
95     // Do not use (Bug9378).
96 }
97 else version(Win64)
98 {
99     // wrong calling convention
100 }
101 else version(D_InlineAsm_X86)
102 {
103     private version = USE_SSSE3;
104 }
105 else version(D_InlineAsm_X86_64)
106 {
107     private version = USE_SSSE3;
108 }
109 
110 import std.ascii : hexDigits;
111 import std.exception : assumeUnique;
112 import core.bitop : bswap;
113 version(USE_SSSE3) import core.cpuid : hasSSSE3Support = ssse3;
114 version(USE_SSSE3) import std.internal.digest.sha_SSSE3 : transformSSSE3;
115 
116 
117 version(unittest)
118 {
119     import std.exception;
120 }
121 
122 
123 public import std.digest.digest;
124 
125 /*
126  * Helper methods for encoding the buffer.
127  * Can be removed if the optimizer can inline the methods from std.bitmanip.
128  */
129 private ubyte[8] nativeToBigEndian(ulong val) @trusted pure nothrow
130 {
131     version(LittleEndian)
132         immutable ulong res = (cast(ulong)  bswap(cast(uint) val)) << 32 | bswap(cast(uint) (val >> 32));
133     else
134         immutable ulong res = val;
135     return *cast(ubyte[8]*) &res;
136 }
137 
138 private ubyte[4] nativeToBigEndian(uint val) @trusted pure nothrow
139 {
140     version(LittleEndian)
141         immutable uint res = bswap(val);
142     else
143         immutable uint res = val;
144     return *cast(ubyte[4]*) &res;
145 }
146 
147 private ulong bigEndianToNative(ubyte[8] val) @trusted pure nothrow
148 {
149     version(LittleEndian)
150     {
151         static import std.bitmanip;
152         return std.bitmanip.bigEndianToNative!ulong(val);
153     }
154     else
155         return *cast(ulong*) &val;
156 }
157 
158 private uint bigEndianToNative(ubyte[4] val) @trusted pure nothrow
159 {
160     version(LittleEndian)
161         return bswap(*cast(uint*) &val);
162     else
163         return *cast(uint*) &val;
164 }
165 
166 //rotateLeft rotates x left n bits
167 private nothrow pure uint rotateLeft(uint x, uint n)
168 {
169     // With recently added optimization to DMD (commit 32ea0206 at 07/28/11), this is translated to rol.
170     // No assembler required.
171     return (x << n) | (x >> (32-n));
172 }
173 
174 //rotateRight rotates x right n bits
175 private nothrow pure uint rotateRight(uint x, uint n)
176 {
177     return (x >> n) | (x << (32-n));
178 }
179 private nothrow pure ulong rotateRight(ulong x, uint n)
180 {
181     return (x >> n) | (x << (64-n));
182 }
183 
184 /**
185  * Template API SHA1/SHA2 implementation. Supports: SHA-1, SHA-224, SHA-256,
186  * SHA-384, SHA-512, SHA-512/224 and SHA-512/256.
187  * 
188  * The blockSize and digestSize are in bits. However, it's likely easier to
189  * simply use the convenience aliases: SHA1, SHA224, SHA256, SHA384, SHA512,
190  * SHA512_224 and SHA512_256.
191  * 
192  * See $(D std.digest.digest) for differences between template and OOP API.
193  */
194 struct SHA(int blockSize, int digestSize)
195 {
196     static assert(blockSize == 512 || blockSize == 1024,
197         "Invalid SHA blockSize, must be 512 or 1024");
198     static assert(digestSize == 160 || digestSize == 224 || digestSize == 256 || digestSize == 384 || digestSize == 512,
199         "Invalid SHA digestSize, must be 224, 256, 384 or 512");
200     static assert(!(blockSize == 512 && digestSize > 256),
201         "Invalid SHA digestSize for a blockSize of 512. The digestSize must be 160, 224 or 256.");
202     static assert(!(blockSize == 1024 && digestSize < 224),
203         "Invalid SHA digestSize for a blockSize of 1024. The digestSize must be 224, 256, 384 or 512.");
204 
205     static if(digestSize==160) /* SHA-1 */
206     {
207         version(USE_SSSE3)
208         {
209             private __gshared immutable nothrow pure void function(uint[5]* state, const(ubyte[64])* block) transform;
210 
211             shared static this()
212             {
213                 transform = hasSSSE3Support ? &transformSSSE3 : &transformX86;
214             }
215         }
216         else
217         {
218             alias transform = transformX86;
219         }
220     }
221     else static if(blockSize == 512) /* SHA-224, SHA-256 */
222         alias transform = transformSHA2!uint;
223     else static if(blockSize == 1024) /* SHA-384, SHA-512, SHA-512/224, SHA-512/256 */
224         alias transform = transformSHA2!ulong;
225     else
226         static assert(0);
227 
228     private:
229         /* magic initialization constants - state (ABCDEFGH) */
230         static if(blockSize == 512 && digestSize == 160) /* SHA-1 */
231         {
232             uint[5] state =
233             [0x67452301,0xefcdab89,0x98badcfe,0x10325476,0xc3d2e1f0];
234         }
235         else static if(blockSize == 512 && digestSize == 224) /* SHA-224 */
236         {
237             uint[8] state = [
238                 0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939,
239                 0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4,
240             ];
241         }
242         else static if(blockSize == 512 && digestSize == 256) /* SHA-256 */
243         {
244             uint[8] state = [
245                 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
246                 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19,
247             ];
248         }
249         else static if(blockSize == 1024 && digestSize == 224) /* SHA-512/224 */
250         {
251             ulong[8] state = [
252                 0x8C3D37C8_19544DA2, 0x73E19966_89DCD4D6,
253                 0x1DFAB7AE_32FF9C82, 0x679DD514_582F9FCF,
254                 0x0F6D2B69_7BD44DA8, 0x77E36F73_04C48942,
255                 0x3F9D85A8_6A1D36C8, 0x1112E6AD_91D692A1,
256             ];
257         }
258         else static if(blockSize == 1024 && digestSize == 256) /* SHA-512/256 */
259         {
260             ulong[8] state = [
261                 0x22312194_FC2BF72C, 0x9F555FA3_C84C64C2,
262                 0x2393B86B_6F53B151, 0x96387719_5940EABD,
263                 0x96283EE2_A88EFFE3, 0xBE5E1E25_53863992,
264                 0x2B0199FC_2C85B8AA, 0x0EB72DDC_81C52CA2,
265             ];
266         }
267         else static if(blockSize == 1024 && digestSize == 384) /* SHA-384 */
268         {
269             ulong[8] state = [
270                 0xcbbb9d5d_c1059ed8, 0x629a292a_367cd507,
271                 0x9159015a_3070dd17, 0x152fecd8_f70e5939,
272                 0x67332667_ffc00b31, 0x8eb44a87_68581511,
273                 0xdb0c2e0d_64f98fa7, 0x47b5481d_befa4fa4,
274             ];
275         }
276         else static if(blockSize == 1024 && digestSize == 512) /* SHA-512 */
277         {
278             ulong[8] state = [
279                 0x6a09e667_f3bcc908, 0xbb67ae85_84caa73b,
280                 0x3c6ef372_fe94f82b, 0xa54ff53a_5f1d36f1,
281                 0x510e527f_ade682d1, 0x9b05688c_2b3e6c1f,
282                 0x1f83d9ab_fb41bd6b, 0x5be0cd19_137e2179,
283             ];
284         }
285         else
286             static assert(0);
287 
288         /* constants */
289         static if(blockSize == 512)
290         {
291             static immutable uint[64] constants = [
292                 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
293                 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
294                 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
295                 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
296                 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
297                 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
298                 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
299                 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2,
300             ];
301         }
302         else static if(blockSize == 1024)
303         {
304             static immutable ulong[80] constants = [
305                 0x428a2f98_d728ae22, 0x71374491_23ef65cd, 0xb5c0fbcf_ec4d3b2f, 0xe9b5dba5_8189dbbc,
306                 0x3956c25b_f348b538, 0x59f111f1_b605d019, 0x923f82a4_af194f9b, 0xab1c5ed5_da6d8118,
307                 0xd807aa98_a3030242, 0x12835b01_45706fbe, 0x243185be_4ee4b28c, 0x550c7dc3_d5ffb4e2,
308                 0x72be5d74_f27b896f, 0x80deb1fe_3b1696b1, 0x9bdc06a7_25c71235, 0xc19bf174_cf692694,
309                 0xe49b69c1_9ef14ad2, 0xefbe4786_384f25e3, 0x0fc19dc6_8b8cd5b5, 0x240ca1cc_77ac9c65,
310                 0x2de92c6f_592b0275, 0x4a7484aa_6ea6e483, 0x5cb0a9dc_bd41fbd4, 0x76f988da_831153b5,
311                 0x983e5152_ee66dfab, 0xa831c66d_2db43210, 0xb00327c8_98fb213f, 0xbf597fc7_beef0ee4,
312                 0xc6e00bf3_3da88fc2, 0xd5a79147_930aa725, 0x06ca6351_e003826f, 0x14292967_0a0e6e70,
313                 0x27b70a85_46d22ffc, 0x2e1b2138_5c26c926, 0x4d2c6dfc_5ac42aed, 0x53380d13_9d95b3df,
314                 0x650a7354_8baf63de, 0x766a0abb_3c77b2a8, 0x81c2c92e_47edaee6, 0x92722c85_1482353b,
315                 0xa2bfe8a1_4cf10364, 0xa81a664b_bc423001, 0xc24b8b70_d0f89791, 0xc76c51a3_0654be30,
316                 0xd192e819_d6ef5218, 0xd6990624_5565a910, 0xf40e3585_5771202a, 0x106aa070_32bbd1b8,
317                 0x19a4c116_b8d2d0c8, 0x1e376c08_5141ab53, 0x2748774c_df8eeb99, 0x34b0bcb5_e19b48a8,
318                 0x391c0cb3_c5c95a63, 0x4ed8aa4a_e3418acb, 0x5b9cca4f_7763e373, 0x682e6ff3_d6b2b8a3,
319                 0x748f82ee_5defb2fc, 0x78a5636f_43172f60, 0x84c87814_a1f0ab72, 0x8cc70208_1a6439ec,
320                 0x90befffa_23631e28, 0xa4506ceb_de82bde9, 0xbef9a3f7_b2c67915, 0xc67178f2_e372532b,
321                 0xca273ece_ea26619c, 0xd186b8c7_21c0c207, 0xeada7dd6_cde0eb1e, 0xf57d4f7f_ee6ed178,
322                 0x06f067aa_72176fba, 0x0a637dc5_a2c898a6, 0x113f9804_bef90dae, 0x1b710b35_131c471b,
323                 0x28db77f5_23047d84, 0x32caab7b_40c72493, 0x3c9ebe0a_15c9bebc, 0x431d67c4_9c100d4c,
324                 0x4cc5d4be_cb3e42b6, 0x597f299c_fc657e2a, 0x5fcb6fab_3ad6faec, 0x6c44198c_4a475817,
325             ];
326         }
327         else
328             static assert(0);
329         
330         /*
331          * number of bits, modulo 2^64 (ulong[1]) or 2^128 (ulong[2]),
332          * should just use ucent instead of ulong[2] once it's available
333          */
334         ulong[blockSize/512] count;
335         ubyte[blockSize/8]   buffer; /* input buffer */
336 
337         enum ubyte[128] padding =
338         [
339           0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
340           0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
341           0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
342 
343           0x00, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
344           0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
345           0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
346         ];
347 
348         /*
349          * Basic SHA1/SHA2 functions.
350          */
351         static pure nothrow
352         {
353             /* All SHA1/SHA2 */
354             T Ch(T)(T x, T y, T z) { return z ^ (x & (y ^ z)); }
355             T Maj(T)(T x, T y, T z) { return (x & y) | (z & (x ^ y)); }
356             
357             /* SHA-1 */
358             uint Parity(uint x, uint y, uint z) { return x ^ y ^ z; }
359             
360             /* SHA-224, SHA-256 */
361             uint BigSigma0(uint x) { return rotateRight(x, 2) ^ rotateRight(x, 13) ^ rotateRight(x, 22); }
362             uint BigSigma1(uint x) { return rotateRight(x, 6) ^ rotateRight(x, 11) ^ rotateRight(x, 25); }
363             uint SmSigma0(uint x) { return rotateRight(x, 7) ^ rotateRight(x, 18) ^ x >> 3; }
364             uint SmSigma1(uint x) { return rotateRight(x, 17) ^ rotateRight(x, 19) ^ x >> 10; }
365 
366             /* SHA-384, SHA-512, SHA-512/224, SHA-512/256 */
367             ulong BigSigma0(ulong x) { return rotateRight(x, 28) ^ rotateRight(x, 34) ^ rotateRight(x, 39); }
368             ulong BigSigma1(ulong x) { return rotateRight(x, 14) ^ rotateRight(x, 18) ^ rotateRight(x, 41); }
369             ulong SmSigma0(ulong x) { return rotateRight(x, 1) ^ rotateRight(x, 8) ^ x >> 7; }
370             ulong SmSigma1(ulong x) { return rotateRight(x, 19) ^ rotateRight(x, 61) ^ x >> 6; }
371         }
372 
373         /*
374          * SHA1 basic transformation. Transforms state based on block.
375          */
376         static nothrow pure void T_0_15(int i, const(ubyte[64])* input, ref uint[16] W, uint A, ref uint B, uint C, uint D,
377             uint E, ref uint T)
378         {
379             uint Wi = W[i] = bigEndianToNative(*cast(ubyte[4]*)&((*input)[i*4]));
380             T = Ch(B, C, D) + E + rotateLeft(A, 5) + Wi + 0x5a827999;
381             B = rotateLeft(B, 30);
382         }
383 
384         static nothrow pure void T_16_19(int i, ref uint[16] W, uint A, ref uint B, uint C, uint D, uint E, ref uint T)
385         {
386             W[i&15] = rotateLeft(W[(i-3)&15] ^ W[(i-8)&15] ^ W[(i-14)&15] ^ W[(i-16)&15], 1);
387             T = Ch(B, C, D) + E + rotateLeft(A, 5) + W[i&15] + 0x5a827999;
388             B = rotateLeft(B, 30);
389         }
390 
391         static nothrow pure void T_20_39(int i, ref uint[16] W, uint A, ref uint B, uint C, uint D, uint E,
392             ref uint T)
393         {
394             W[i&15] = rotateLeft(W[(i-3)&15] ^ W[(i-8)&15] ^ W[(i-14)&15] ^ W[(i-16)&15], 1);
395             T = Parity(B, C, D) + E + rotateLeft(A, 5) + W[i&15] + 0x6ed9eba1;
396             B = rotateLeft(B, 30);
397         }
398 
399         static nothrow pure void T_40_59(int i, ref uint[16] W, uint A, ref uint B, uint C, uint D, uint E,
400             ref uint T)
401         {
402             W[i&15] = rotateLeft(W[(i-3)&15] ^ W[(i-8)&15] ^ W[(i-14)&15] ^ W[(i-16)&15], 1);
403             T = Maj(B, C, D) + E + rotateLeft(A, 5) + W[i&15] + 0x8f1bbcdc;
404             B = rotateLeft(B, 30);
405         }
406 
407         static nothrow pure void T_60_79(int i, ref uint[16] W, uint A, ref uint B, uint C, uint D, uint E,
408             ref uint T)
409         {
410             W[i&15] = rotateLeft(W[(i-3)&15] ^ W[(i-8)&15] ^ W[(i-14)&15] ^ W[(i-16)&15], 1);
411             T = Parity(B, C, D) + E + rotateLeft(A, 5) + W[i&15] + 0xca62c1d6;
412             B = rotateLeft(B, 30);
413         }
414 
415         private static nothrow pure void transformX86(uint[5]* state, const(ubyte[64])* block)
416         {
417             uint A, B, C, D, E, T;
418             uint[16] W = void;
419 
420             A = (*state)[0];
421             B = (*state)[1];
422             C = (*state)[2];
423             D = (*state)[3];
424             E = (*state)[4];
425 
426             T_0_15 ( 0, block, W, A, B, C, D, E, T);
427             T_0_15 ( 1, block, W, T, A, B, C, D, E);
428             T_0_15 ( 2, block, W, E, T, A, B, C, D);
429             T_0_15 ( 3, block, W, D, E, T, A, B, C);
430             T_0_15 ( 4, block, W, C, D, E, T, A, B);
431             T_0_15 ( 5, block, W, B, C, D, E, T, A);
432             T_0_15 ( 6, block, W, A, B, C, D, E, T);
433             T_0_15 ( 7, block, W, T, A, B, C, D, E);
434             T_0_15 ( 8, block, W, E, T, A, B, C, D);
435             T_0_15 ( 9, block, W, D, E, T, A, B, C);
436             T_0_15 (10, block, W, C, D, E, T, A, B);
437             T_0_15 (11, block, W, B, C, D, E, T, A);
438             T_0_15 (12, block, W, A, B, C, D, E, T);
439             T_0_15 (13, block, W, T, A, B, C, D, E);
440             T_0_15 (14, block, W, E, T, A, B, C, D);
441             T_0_15 (15, block, W, D, E, T, A, B, C);
442             T_16_19(16, W, C, D, E, T, A, B);
443             T_16_19(17, W, B, C, D, E, T, A);
444             T_16_19(18, W, A, B, C, D, E, T);
445             T_16_19(19, W, T, A, B, C, D, E);
446             T_20_39(20, W, E, T, A, B, C, D);
447             T_20_39(21, W, D, E, T, A, B, C);
448             T_20_39(22, W, C, D, E, T, A, B);
449             T_20_39(23, W, B, C, D, E, T, A);
450             T_20_39(24, W, A, B, C, D, E, T);
451             T_20_39(25, W, T, A, B, C, D, E);
452             T_20_39(26, W, E, T, A, B, C, D);
453             T_20_39(27, W, D, E, T, A, B, C);
454             T_20_39(28, W, C, D, E, T, A, B);
455             T_20_39(29, W, B, C, D, E, T, A);
456             T_20_39(30, W, A, B, C, D, E, T);
457             T_20_39(31, W, T, A, B, C, D, E);
458             T_20_39(32, W, E, T, A, B, C, D);
459             T_20_39(33, W, D, E, T, A, B, C);
460             T_20_39(34, W, C, D, E, T, A, B);
461             T_20_39(35, W, B, C, D, E, T, A);
462             T_20_39(36, W, A, B, C, D, E, T);
463             T_20_39(37, W, T, A, B, C, D, E);
464             T_20_39(38, W, E, T, A, B, C, D);
465             T_20_39(39, W, D, E, T, A, B, C);
466             T_40_59(40, W, C, D, E, T, A, B);
467             T_40_59(41, W, B, C, D, E, T, A);
468             T_40_59(42, W, A, B, C, D, E, T);
469             T_40_59(43, W, T, A, B, C, D, E);
470             T_40_59(44, W, E, T, A, B, C, D);
471             T_40_59(45, W, D, E, T, A, B, C);
472             T_40_59(46, W, C, D, E, T, A, B);
473             T_40_59(47, W, B, C, D, E, T, A);
474             T_40_59(48, W, A, B, C, D, E, T);
475             T_40_59(49, W, T, A, B, C, D, E);
476             T_40_59(50, W, E, T, A, B, C, D);
477             T_40_59(51, W, D, E, T, A, B, C);
478             T_40_59(52, W, C, D, E, T, A, B);
479             T_40_59(53, W, B, C, D, E, T, A);
480             T_40_59(54, W, A, B, C, D, E, T);
481             T_40_59(55, W, T, A, B, C, D, E);
482             T_40_59(56, W, E, T, A, B, C, D);
483             T_40_59(57, W, D, E, T, A, B, C);
484             T_40_59(58, W, C, D, E, T, A, B);
485             T_40_59(59, W, B, C, D, E, T, A);
486             T_60_79(60, W, A, B, C, D, E, T);
487             T_60_79(61, W, T, A, B, C, D, E);
488             T_60_79(62, W, E, T, A, B, C, D);
489             T_60_79(63, W, D, E, T, A, B, C);
490             T_60_79(64, W, C, D, E, T, A, B);
491             T_60_79(65, W, B, C, D, E, T, A);
492             T_60_79(66, W, A, B, C, D, E, T);
493             T_60_79(67, W, T, A, B, C, D, E);
494             T_60_79(68, W, E, T, A, B, C, D);
495             T_60_79(69, W, D, E, T, A, B, C);
496             T_60_79(70, W, C, D, E, T, A, B);
497             T_60_79(71, W, B, C, D, E, T, A);
498             T_60_79(72, W, A, B, C, D, E, T);
499             T_60_79(73, W, T, A, B, C, D, E);
500             T_60_79(74, W, E, T, A, B, C, D);
501             T_60_79(75, W, D, E, T, A, B, C);
502             T_60_79(76, W, C, D, E, T, A, B);
503             T_60_79(77, W, B, C, D, E, T, A);
504             T_60_79(78, W, A, B, C, D, E, T);
505             T_60_79(79, W, T, A, B, C, D, E);
506 
507             (*state)[0] += E;
508             (*state)[1] += T;
509             (*state)[2] += A;
510             (*state)[3] += B;
511             (*state)[4] += C;
512 
513             /* Zeroize sensitive information. */
514             W[] = 0;
515         }
516 
517         /*
518          * SHA2 basic transformation. Transforms state based on block.
519          */
520         static nothrow pure void T_SHA2_0_15(Word)(int i, const(ubyte[blockSize/8])* input, ref Word[16] W,
521             Word A, Word B, Word C, ref Word D, Word E, Word F, Word G, ref Word H, Word K)
522         {
523             Word Wi = W[i] = bigEndianToNative(*cast(ubyte[Word.sizeof]*)&((*input)[i*Word.sizeof]));
524             Word T1 = H + BigSigma1(E) + Ch(E, F, G) + K + Wi;
525             Word T2 = BigSigma0(A) + Maj(A, B, C);
526             D += T1;
527             H = T1 + T2;
528         }
529 
530         static nothrow pure void T_SHA2_16_79(Word)(int i, ref Word[16] W,
531             Word A, Word B, Word C, ref Word D, Word E, Word F, Word G, ref Word H, Word K)
532         {
533             W[i&15] = SmSigma1(W[(i-2)&15]) + W[(i-7)&15] + SmSigma0(W[(i-15)&15]) + W[i&15];
534             Word T1 = H + BigSigma1(E) + Ch(E, F, G) + K + W[i&15];
535             Word T2 = BigSigma0(A) + Maj(A, B, C);
536             D += T1;
537             H = T1 + T2;
538         }
539 
540         private static nothrow pure void transformSHA2(Word)(Word[8]* state, const(ubyte[blockSize/8])* block)
541         {
542             Word A, B, C, D, E, F, G, H;
543             Word[16] W = void;
544 
545             A = (*state)[0];
546             B = (*state)[1];
547             C = (*state)[2];
548             D = (*state)[3];
549             E = (*state)[4];
550             F = (*state)[5];
551             G = (*state)[6];
552             H = (*state)[7];
553 
554             T_SHA2_0_15!Word ( 0, block, W, A, B, C, D, E, F, G, H, constants[ 0]);
555             T_SHA2_0_15!Word ( 1, block, W, H, A, B, C, D, E, F, G, constants[ 1]);
556             T_SHA2_0_15!Word ( 2, block, W, G, H, A, B, C, D, E, F, constants[ 2]);
557             T_SHA2_0_15!Word ( 3, block, W, F, G, H, A, B, C, D, E, constants[ 3]);
558             T_SHA2_0_15!Word ( 4, block, W, E, F, G, H, A, B, C, D, constants[ 4]);
559             T_SHA2_0_15!Word ( 5, block, W, D, E, F, G, H, A, B, C, constants[ 5]);
560             T_SHA2_0_15!Word ( 6, block, W, C, D, E, F, G, H, A, B, constants[ 6]);
561             T_SHA2_0_15!Word ( 7, block, W, B, C, D, E, F, G, H, A, constants[ 7]);
562             T_SHA2_0_15!Word ( 8, block, W, A, B, C, D, E, F, G, H, constants[ 8]);
563             T_SHA2_0_15!Word ( 9, block, W, H, A, B, C, D, E, F, G, constants[ 9]);
564             T_SHA2_0_15!Word (10, block, W, G, H, A, B, C, D, E, F, constants[10]);
565             T_SHA2_0_15!Word (11, block, W, F, G, H, A, B, C, D, E, constants[11]);
566             T_SHA2_0_15!Word (12, block, W, E, F, G, H, A, B, C, D, constants[12]);
567             T_SHA2_0_15!Word (13, block, W, D, E, F, G, H, A, B, C, constants[13]);
568             T_SHA2_0_15!Word (14, block, W, C, D, E, F, G, H, A, B, constants[14]);
569             T_SHA2_0_15!Word (15, block, W, B, C, D, E, F, G, H, A, constants[15]);
570             T_SHA2_16_79!Word(16, W, A, B, C, D, E, F, G, H, constants[16]);
571             T_SHA2_16_79!Word(17, W, H, A, B, C, D, E, F, G, constants[17]);
572             T_SHA2_16_79!Word(18, W, G, H, A, B, C, D, E, F, constants[18]);
573             T_SHA2_16_79!Word(19, W, F, G, H, A, B, C, D, E, constants[19]);
574             T_SHA2_16_79!Word(20, W, E, F, G, H, A, B, C, D, constants[20]);
575             T_SHA2_16_79!Word(21, W, D, E, F, G, H, A, B, C, constants[21]);
576             T_SHA2_16_79!Word(22, W, C, D, E, F, G, H, A, B, constants[22]);
577             T_SHA2_16_79!Word(23, W, B, C, D, E, F, G, H, A, constants[23]);
578             T_SHA2_16_79!Word(24, W, A, B, C, D, E, F, G, H, constants[24]);
579             T_SHA2_16_79!Word(25, W, H, A, B, C, D, E, F, G, constants[25]);
580             T_SHA2_16_79!Word(26, W, G, H, A, B, C, D, E, F, constants[26]);
581             T_SHA2_16_79!Word(27, W, F, G, H, A, B, C, D, E, constants[27]);
582             T_SHA2_16_79!Word(28, W, E, F, G, H, A, B, C, D, constants[28]);
583             T_SHA2_16_79!Word(29, W, D, E, F, G, H, A, B, C, constants[29]);
584             T_SHA2_16_79!Word(30, W, C, D, E, F, G, H, A, B, constants[30]);
585             T_SHA2_16_79!Word(31, W, B, C, D, E, F, G, H, A, constants[31]);
586             T_SHA2_16_79!Word(32, W, A, B, C, D, E, F, G, H, constants[32]);
587             T_SHA2_16_79!Word(33, W, H, A, B, C, D, E, F, G, constants[33]);
588             T_SHA2_16_79!Word(34, W, G, H, A, B, C, D, E, F, constants[34]);
589             T_SHA2_16_79!Word(35, W, F, G, H, A, B, C, D, E, constants[35]);
590             T_SHA2_16_79!Word(36, W, E, F, G, H, A, B, C, D, constants[36]);
591             T_SHA2_16_79!Word(37, W, D, E, F, G, H, A, B, C, constants[37]);
592             T_SHA2_16_79!Word(38, W, C, D, E, F, G, H, A, B, constants[38]);
593             T_SHA2_16_79!Word(39, W, B, C, D, E, F, G, H, A, constants[39]);
594             T_SHA2_16_79!Word(40, W, A, B, C, D, E, F, G, H, constants[40]);
595             T_SHA2_16_79!Word(41, W, H, A, B, C, D, E, F, G, constants[41]);
596             T_SHA2_16_79!Word(42, W, G, H, A, B, C, D, E, F, constants[42]);
597             T_SHA2_16_79!Word(43, W, F, G, H, A, B, C, D, E, constants[43]);
598             T_SHA2_16_79!Word(44, W, E, F, G, H, A, B, C, D, constants[44]);
599             T_SHA2_16_79!Word(45, W, D, E, F, G, H, A, B, C, constants[45]);
600             T_SHA2_16_79!Word(46, W, C, D, E, F, G, H, A, B, constants[46]);
601             T_SHA2_16_79!Word(47, W, B, C, D, E, F, G, H, A, constants[47]);
602             T_SHA2_16_79!Word(48, W, A, B, C, D, E, F, G, H, constants[48]);
603             T_SHA2_16_79!Word(49, W, H, A, B, C, D, E, F, G, constants[49]);
604             T_SHA2_16_79!Word(50, W, G, H, A, B, C, D, E, F, constants[50]);
605             T_SHA2_16_79!Word(51, W, F, G, H, A, B, C, D, E, constants[51]);
606             T_SHA2_16_79!Word(52, W, E, F, G, H, A, B, C, D, constants[52]);
607             T_SHA2_16_79!Word(53, W, D, E, F, G, H, A, B, C, constants[53]);
608             T_SHA2_16_79!Word(54, W, C, D, E, F, G, H, A, B, constants[54]);
609             T_SHA2_16_79!Word(55, W, B, C, D, E, F, G, H, A, constants[55]);
610             T_SHA2_16_79!Word(56, W, A, B, C, D, E, F, G, H, constants[56]);
611             T_SHA2_16_79!Word(57, W, H, A, B, C, D, E, F, G, constants[57]);
612             T_SHA2_16_79!Word(58, W, G, H, A, B, C, D, E, F, constants[58]);
613             T_SHA2_16_79!Word(59, W, F, G, H, A, B, C, D, E, constants[59]);
614             T_SHA2_16_79!Word(60, W, E, F, G, H, A, B, C, D, constants[60]);
615             T_SHA2_16_79!Word(61, W, D, E, F, G, H, A, B, C, constants[61]);
616             T_SHA2_16_79!Word(62, W, C, D, E, F, G, H, A, B, constants[62]);
617             T_SHA2_16_79!Word(63, W, B, C, D, E, F, G, H, A, constants[63]);
618             
619             static if(is(Word==ulong))
620             {
621                 T_SHA2_16_79!Word(64, W, A, B, C, D, E, F, G, H, constants[64]);
622                 T_SHA2_16_79!Word(65, W, H, A, B, C, D, E, F, G, constants[65]);
623                 T_SHA2_16_79!Word(66, W, G, H, A, B, C, D, E, F, constants[66]);
624                 T_SHA2_16_79!Word(67, W, F, G, H, A, B, C, D, E, constants[67]);
625                 T_SHA2_16_79!Word(68, W, E, F, G, H, A, B, C, D, constants[68]);
626                 T_SHA2_16_79!Word(69, W, D, E, F, G, H, A, B, C, constants[69]);
627                 T_SHA2_16_79!Word(70, W, C, D, E, F, G, H, A, B, constants[70]);
628                 T_SHA2_16_79!Word(71, W, B, C, D, E, F, G, H, A, constants[71]);
629                 T_SHA2_16_79!Word(72, W, A, B, C, D, E, F, G, H, constants[72]);
630                 T_SHA2_16_79!Word(73, W, H, A, B, C, D, E, F, G, constants[73]);
631                 T_SHA2_16_79!Word(74, W, G, H, A, B, C, D, E, F, constants[74]);
632                 T_SHA2_16_79!Word(75, W, F, G, H, A, B, C, D, E, constants[75]);
633                 T_SHA2_16_79!Word(76, W, E, F, G, H, A, B, C, D, constants[76]);
634                 T_SHA2_16_79!Word(77, W, D, E, F, G, H, A, B, C, constants[77]);
635                 T_SHA2_16_79!Word(78, W, C, D, E, F, G, H, A, B, constants[78]);
636                 T_SHA2_16_79!Word(79, W, B, C, D, E, F, G, H, A, constants[79]);
637             }
638 
639             (*state)[0] += A;
640             (*state)[1] += B;
641             (*state)[2] += C;
642             (*state)[3] += D;
643             (*state)[4] += E;
644             (*state)[5] += F;
645             (*state)[6] += G;
646             (*state)[7] += H;
647 
648             /* Zeroize sensitive information. */
649             W[] = 0;
650         }
651 
652     public:
653         /**
654          * SHA initialization. Begins an SHA1/SHA2 operation.
655          *
656          * Note:
657          * For this SHA Digest implementation calling start after default construction
658          * is not necessary. Calling start is only necessary to reset the Digest.
659          *
660          * Generic code which deals with different Digest types should always call start though.
661          *
662          * Examples:
663          * --------
664          * SHA1 digest;
665          * //digest.start(); //Not necessary
666          * digest.put(0);
667          * --------
668          */
669         @trusted nothrow pure void start()
670         {
671             this = typeof(this).init;
672         }
673 
674         /**
675          * Use this to feed the digest with data.
676          * Also implements the $(XREF range, OutputRange) interface for $(D ubyte) and
677          * $(D const(ubyte)[]).
678          */
679         @trusted nothrow pure void put(scope const(ubyte)[] input...)
680         {
681             enum blockSizeInBytes = blockSize/8;
682             uint i, index, partLen;
683             auto inputLen = input.length;
684 
685             /* Compute number of bytes mod block size (64 or 128 bytes) */
686             index = (cast(uint)count[0] >> 3) & (blockSizeInBytes - 1);
687 
688             /* Update number of bits */
689             static if(blockSize==512)
690                 count[0] += inputLen * 8;
691             else static if(blockSize==1024)
692             {
693                 /* ugly hack to work around lack of ucent */
694                 auto oldCount0 = count[0];
695                 count[0] += inputLen * 8;
696                 if(count[0] < oldCount0)
697                     count[1]++;
698             }
699             else
700                 static assert(0);
701 
702             partLen = blockSizeInBytes - index;
703 
704             /* Transform as many times as possible. */
705             if (inputLen >= partLen)
706             {
707                 (&buffer[index])[0 .. partLen] = input.ptr[0 .. partLen];
708                 transform (&state, &buffer);
709 
710                 for (i = partLen; i + blockSizeInBytes-1 < inputLen; i += blockSizeInBytes)
711                    transform(&state, cast(ubyte[blockSizeInBytes]*)(input.ptr + i));
712 
713                 index = 0;
714             }
715             else
716                 i = 0;
717 
718             /* Buffer remaining input */
719             if (inputLen - i)
720                 (&buffer[index])[0 .. inputLen-i] = (&input[i])[0 .. inputLen-i];
721         }
722         ///
723         unittest
724         {
725             typeof(this) dig;
726             dig.put(cast(ubyte)0); //single ubyte
727             dig.put(cast(ubyte)0, cast(ubyte)0); //variadic
728             ubyte[10] buf;
729             dig.put(buf); //buffer
730         }
731 
732 
733         /**
734          * Returns the finished SHA hash. This also calls $(LREF start) to
735          * reset the internal state.
736          */
737         @trusted nothrow pure ubyte[digestSize/8] finish()
738         {
739             static if(blockSize==512)
740             {
741                 ubyte[32] data = void;
742                 uint index, padLen;
743 
744                 /* Save number of bits */
745                 ubyte bits[8] = nativeToBigEndian(count[0]);
746 
747                 /* Pad out to 56 mod 64. */
748                 index = (cast(uint)count[0] >> 3) & (64 - 1);
749                 padLen = (index < 56) ? (56 - index) : (120 - index);
750                 put(padding[0 .. padLen]);
751 
752                 /* Append length (before padding) */
753                 put(bits);
754 
755                 /* Store state in digest */
756                 for (auto i = 0; i < ((digestSize == 160)? 5 : 8); i++)
757                     data[i*4..(i+1)*4] = nativeToBigEndian(state[i])[];
758 
759                 /* Zeroize sensitive information. */
760                 start();
761                 return data[0..digestSize/8];
762             }
763             else static if(blockSize==1024)
764             {
765                 ubyte[64] data = void;
766                 uint index, padLen;
767 
768                 /* Save number of bits */
769                 ubyte bits[16];
770                 bits[ 0..8] = nativeToBigEndian(count[1]);
771                 bits[8..16] = nativeToBigEndian(count[0]);
772 
773                 /* Pad out to 112 mod 128. */
774                 index = (cast(uint)count[0] >> 3) & (128 - 1);
775                 padLen = (index < 112) ? (112 - index) : (240 - index);
776                 put(padding[0 .. padLen]);
777 
778                 /* Append length (before padding) */
779                 put(bits);
780 
781                 /* Store state in digest */
782                 for (auto i = 0; i < 8; i++)
783                     data[i*8..(i+1)*8] = nativeToBigEndian(state[i])[];
784 
785                 /* Zeroize sensitive information. */
786                 start();
787                 return data[0..digestSize/8];
788             }
789             else
790                 static assert(0);
791         }
792         ///
793         unittest
794         {
795             //Simple example
796             SHA1 hash;
797             hash.start();
798             hash.put(cast(ubyte)0);
799             ubyte[20] result = hash.finish();
800         }
801 }
802 
803 alias SHA1 = SHA!(512, 160);  /// SHA alias for SHA-1, hash is ubyte[20]
804 alias SHA224 = SHA!(512, 224);  /// SHA alias for SHA-224, hash is ubyte[28]
805 alias SHA256 = SHA!(512, 256);  /// SHA alias for SHA-256, hash is ubyte[32]
806 alias SHA384 = SHA!(1024, 384); /// SHA alias for SHA-384, hash is ubyte[48]
807 alias SHA512 = SHA!(1024, 512); /// SHA alias for SHA-512, hash is ubyte[64]
808 alias SHA512_224 = SHA!(1024, 224); /// SHA alias for SHA-512/224, hash is ubyte[28]
809 alias SHA512_256 = SHA!(1024, 256); /// SHA alias for SHA-512/256, hash is ubyte[32]
810 
811 ///
812 unittest
813 {
814     //Simple example, hashing a string using sha1Of helper function
815     ubyte[20] hash = sha1Of("abc");
816     //Let's get a hash string
817     assert(toHexString(hash) == "A9993E364706816ABA3E25717850C26C9CD0D89D");
818 
819     //The same, but using SHA-224
820     ubyte[28] hash224 = sha224Of("abc");
821     assert(toHexString(hash224) == "23097D223405D8228642A477BDA255B32AADBCE4BDA0B3F7E36C9DA7");
822 }
823 
824 ///
825 unittest
826 {
827     //Using the basic API
828     SHA1 hash;
829     hash.start();
830     ubyte[1024] data;
831     //Initialize data here...
832     hash.put(data);
833     ubyte[20] result = hash.finish();
834 }
835 
836 ///
837 unittest
838 {
839     //Let's use the template features:
840     //Note: When passing a SHA1 to a function, it must be passed by reference!
841     void doSomething(T)(ref T hash) if(isDigest!T)
842     {
843       hash.put(cast(ubyte)0);
844     }
845     SHA1 sha;
846     sha.start();
847     doSomething(sha);
848     assert(toHexString(sha.finish()) == "5BA93C9DB0CFF93F52B521D7420E43F6EDA2784F");
849 }
850 
851 unittest
852 {
853     assert(isDigest!SHA1);
854     assert(isDigest!SHA224);
855     assert(isDigest!SHA256);
856     assert(isDigest!SHA384);
857     assert(isDigest!SHA512);
858     assert(isDigest!SHA512_224);
859     assert(isDigest!SHA512_256);
860 }
861 
862 unittest
863 {
864     import std.range;
865 
866     ubyte[20] digest;
867     ubyte[28] digest224;
868     ubyte[32] digest256;
869     ubyte[48] digest384;
870     ubyte[64] digest512;
871     ubyte[28] digest512_224;
872     ubyte[32] digest512_256;
873 
874     SHA1 sha;
875     sha.put(cast(ubyte[])"abcdef");
876     sha.start();
877     sha.put(cast(ubyte[])"");
878     assert(sha.finish() == cast(ubyte[])x"da39a3ee5e6b4b0d3255bfef95601890afd80709");
879 
880     SHA224 sha224;
881     sha224.put(cast(ubyte[])"abcdef");
882     sha224.start();
883     sha224.put(cast(ubyte[])"");
884     assert(sha224.finish() == cast(ubyte[])x"d14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f");
885 
886     SHA256 sha256;
887     sha256.put(cast(ubyte[])"abcdef");
888     sha256.start();
889     sha256.put(cast(ubyte[])"");
890     assert(sha256.finish() == cast(ubyte[])x"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855");
891 
892     SHA384 sha384;
893     sha384.put(cast(ubyte[])"abcdef");
894     sha384.start();
895     sha384.put(cast(ubyte[])"");
896     assert(sha384.finish() == cast(ubyte[])x"38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b");
897 
898     SHA512 sha512;
899     sha512.put(cast(ubyte[])"abcdef");
900     sha512.start();
901     sha512.put(cast(ubyte[])"");
902     assert(sha512.finish() == cast(ubyte[])x"cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e");
903 
904     SHA512_224 sha512_224;
905     sha512_224.put(cast(ubyte[])"abcdef");
906     sha512_224.start();
907     sha512_224.put(cast(ubyte[])"");
908     assert(sha512_224.finish() == cast(ubyte[])x"6ed0dd02806fa89e25de060c19d3ac86cabb87d6a0ddd05c333b84f4");
909 
910     SHA512_256 sha512_256;
911     sha512_256.put(cast(ubyte[])"abcdef");
912     sha512_256.start();
913     sha512_256.put(cast(ubyte[])"");
914     assert(sha512_256.finish() == cast(ubyte[])x"c672b8d1ef56ed28ab87c3622c5114069bdd3ad7b8f9737498d0c01ecef0967a");
915 
916     digest        = sha1Of      ("");
917     digest224     = sha224Of    ("");
918     digest256     = sha256Of    ("");
919     digest384     = sha384Of    ("");
920     digest512     = sha512Of    ("");
921     digest512_224 = sha512_224Of("");
922     digest512_256 = sha512_256Of("");
923     assert(digest == cast(ubyte[])x"da39a3ee5e6b4b0d3255bfef95601890afd80709");
924     assert(digest224 == cast(ubyte[])x"d14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f");
925     assert(digest256 == cast(ubyte[])x"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855");
926     assert(digest384 == cast(ubyte[])x"38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b");
927     assert(digest512 == cast(ubyte[])x"cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e");
928     assert(digest512_224 == cast(ubyte[])x"6ed0dd02806fa89e25de060c19d3ac86cabb87d6a0ddd05c333b84f4");
929     assert(digest512_256 == cast(ubyte[])x"c672b8d1ef56ed28ab87c3622c5114069bdd3ad7b8f9737498d0c01ecef0967a");
930 
931     digest        = sha1Of      ("a");
932     digest224     = sha224Of    ("a");
933     digest256     = sha256Of    ("a");
934     digest384     = sha384Of    ("a");
935     digest512     = sha512Of    ("a");
936     digest512_224 = sha512_224Of("a");
937     digest512_256 = sha512_256Of("a");
938     assert(digest == cast(ubyte[])x"86f7e437faa5a7fce15d1ddcb9eaeaea377667b8");
939     assert(digest224 == cast(ubyte[])x"abd37534c7d9a2efb9465de931cd7055ffdb8879563ae98078d6d6d5");
940     assert(digest256 == cast(ubyte[])x"ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb");
941     assert(digest384 == cast(ubyte[])x"54a59b9f22b0b80880d8427e548b7c23abd873486e1f035dce9cd697e85175033caa88e6d57bc35efae0b5afd3145f31");
942     assert(digest512 == cast(ubyte[])x"1f40fc92da241694750979ee6cf582f2d5d7d28e18335de05abc54d0560e0f5302860c652bf08d560252aa5e74210546f369fbbbce8c12cfc7957b2652fe9a75");
943     assert(digest512_224 == cast(ubyte[])x"d5cdb9ccc769a5121d4175f2bfdd13d6310e0d3d361ea75d82108327");
944     assert(digest512_256 == cast(ubyte[])x"455e518824bc0601f9fb858ff5c37d417d67c2f8e0df2babe4808858aea830f8");
945 
946     digest        = sha1Of      ("abc");
947     digest224     = sha224Of    ("abc");
948     digest256     = sha256Of    ("abc");
949     digest384     = sha384Of    ("abc");
950     digest512     = sha512Of    ("abc");
951     digest512_224 = sha512_224Of("abc");
952     digest512_256 = sha512_256Of("abc");
953     assert(digest == cast(ubyte[])x"a9993e364706816aba3e25717850c26c9cd0d89d");
954     assert(digest224 == cast(ubyte[])x"23097d223405d8228642a477bda255b32aadbce4bda0b3f7e36c9da7");
955     assert(digest256 == cast(ubyte[])x"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad");
956     assert(digest384 == cast(ubyte[])x"cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed8086072ba1e7cc2358baeca134c825a7");
957     assert(digest512 == cast(ubyte[])x"ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f");
958     assert(digest512_224 == cast(ubyte[])x"4634270f707b6a54daae7530460842e20e37ed265ceee9a43e8924aa");
959     assert(digest512_256 == cast(ubyte[])x"53048e2681941ef99b2e29b76b4c7dabe4c2d0c634fc6d46e0e2f13107e7af23");
960 
961     digest        = sha1Of      ("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq");
962     digest224     = sha224Of    ("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq");
963     digest256     = sha256Of    ("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq");
964     digest384     = sha384Of    ("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq");
965     digest512     = sha512Of    ("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq");
966     digest512_224 = sha512_224Of("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq");
967     digest512_256 = sha512_256Of("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq");
968     assert(digest == cast(ubyte[])x"84983e441c3bd26ebaae4aa1f95129e5e54670f1");
969     assert(digest224 == cast(ubyte[])x"75388b16512776cc5dba5da1fd890150b0c6455cb4f58b1952522525");
970     assert(digest256 == cast(ubyte[])x"248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1");
971     assert(digest384 == cast(ubyte[])x"3391fdddfc8dc7393707a65b1b4709397cf8b1d162af05abfe8f450de5f36bc6b0455a8520bc4e6f5fe95b1fe3c8452b");
972     assert(digest512 == cast(ubyte[])x"204a8fc6dda82f0a0ced7beb8e08a41657c16ef468b228a8279be331a703c33596fd15c13b1b07f9aa1d3bea57789ca031ad85c7a71dd70354ec631238ca3445");
973     assert(digest512_224 == cast(ubyte[])x"e5302d6d54bb242275d1e7622d68df6eb02dedd13f564c13dbda2174");
974     assert(digest512_256 == cast(ubyte[])x"bde8e1f9f19bb9fd3406c90ec6bc47bd36d8ada9f11880dbc8a22a7078b6a461");
975 
976     digest        = sha1Of      ("message digest");
977     digest224     = sha224Of    ("message digest");
978     digest256     = sha256Of    ("message digest");
979     digest384     = sha384Of    ("message digest");
980     digest512     = sha512Of    ("message digest");
981     digest512_224 = sha512_224Of("message digest");
982     digest512_256 = sha512_256Of("message digest");
983     assert(digest == cast(ubyte[])x"c12252ceda8be8994d5fa0290a47231c1d16aae3");
984     assert(digest224 == cast(ubyte[])x"2cb21c83ae2f004de7e81c3c7019cbcb65b71ab656b22d6d0c39b8eb");
985     assert(digest256 == cast(ubyte[])x"f7846f55cf23e14eebeab5b4e1550cad5b509e3348fbc4efa3a1413d393cb650");
986     assert(digest384 == cast(ubyte[])x"473ed35167ec1f5d8e550368a3db39be54639f828868e9454c239fc8b52e3c61dbd0d8b4de1390c256dcbb5d5fd99cd5");
987     assert(digest512 == cast(ubyte[])x"107dbf389d9e9f71a3a95f6c055b9251bc5268c2be16d6c13492ea45b0199f3309e16455ab1e96118e8a905d5597b72038ddb372a89826046de66687bb420e7c");
988     assert(digest512_224 == cast(ubyte[])x"ad1a4db188fe57064f4f24609d2a83cd0afb9b398eb2fcaeaae2c564");
989     assert(digest512_256 == cast(ubyte[])x"0cf471fd17ed69d990daf3433c89b16d63dec1bb9cb42a6094604ee5d7b4e9fb");
990 
991     digest        = sha1Of      ("abcdefghijklmnopqrstuvwxyz");
992     digest224     = sha224Of    ("abcdefghijklmnopqrstuvwxyz");
993     digest256     = sha256Of    ("abcdefghijklmnopqrstuvwxyz");
994     digest384     = sha384Of    ("abcdefghijklmnopqrstuvwxyz");
995     digest512     = sha512Of    ("abcdefghijklmnopqrstuvwxyz");
996     digest512_224 = sha512_224Of("abcdefghijklmnopqrstuvwxyz");
997     digest512_256 = sha512_256Of("abcdefghijklmnopqrstuvwxyz");
998     assert(digest == cast(ubyte[])x"32d10c7b8cf96570ca04ce37f2a19d84240d3a89");
999     assert(digest224 == cast(ubyte[])x"45a5f72c39c5cff2522eb3429799e49e5f44b356ef926bcf390dccc2");
1000     assert(digest256 == cast(ubyte[])x"71c480df93d6ae2f1efad1447c66c9525e316218cf51fc8d9ed832f2daf18b73");
1001     assert(digest384 == cast(ubyte[])x"feb67349df3db6f5924815d6c3dc133f091809213731fe5c7b5f4999e463479ff2877f5f2936fa63bb43784b12f3ebb4");
1002     assert(digest512 == cast(ubyte[])x"4dbff86cc2ca1bae1e16468a05cb9881c97f1753bce3619034898faa1aabe429955a1bf8ec483d7421fe3c1646613a59ed5441fb0f321389f77f48a879c7b1f1");
1003     assert(digest512_224 == cast(ubyte[])x"ff83148aa07ec30655c1b40aff86141c0215fe2a54f767d3f38743d8");
1004     assert(digest512_256 == cast(ubyte[])x"fc3189443f9c268f626aea08a756abe7b726b05f701cb08222312ccfd6710a26");
1005 
1006     digest        = sha1Of      ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789");
1007     digest224     = sha224Of    ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789");
1008     digest256     = sha256Of    ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789");
1009     digest384     = sha384Of    ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789");
1010     digest512     = sha512Of    ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789");
1011     digest512_224 = sha512_224Of("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789");
1012     digest512_256 = sha512_256Of("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789");
1013     assert(digest == cast(ubyte[])x"761c457bf73b14d27e9e9265c46f4b4dda11f940");
1014     assert(digest224 == cast(ubyte[])x"bff72b4fcb7d75e5632900ac5f90d219e05e97a7bde72e740db393d9");
1015     assert(digest256 == cast(ubyte[])x"db4bfcbd4da0cd85a60c3c37d3fbd8805c77f15fc6b1fdfe614ee0a7c8fdb4c0");
1016     assert(digest384 == cast(ubyte[])x"1761336e3f7cbfe51deb137f026f89e01a448e3b1fafa64039c1464ee8732f11a5341a6f41e0c202294736ed64db1a84");
1017     assert(digest512 == cast(ubyte[])x"1e07be23c26a86ea37ea810c8ec7809352515a970e9253c26f536cfc7a9996c45c8370583e0a78fa4a90041d71a4ceab7423f19c71b9d5a3e01249f0bebd5894");
1018     assert(digest512_224 == cast(ubyte[])x"a8b4b9174b99ffc67d6f49be9981587b96441051e16e6dd036b140d3");
1019     assert(digest512_256 == cast(ubyte[])x"cdf1cc0effe26ecc0c13758f7b4a48e000615df241284185c39eb05d355bb9c8");
1020 
1021     digest        = sha1Of      ("1234567890123456789012345678901234567890"~
1022                                  "1234567890123456789012345678901234567890");
1023     digest224     = sha224Of    ("1234567890123456789012345678901234567890"~
1024                                  "1234567890123456789012345678901234567890");
1025     digest256     = sha256Of    ("1234567890123456789012345678901234567890"~
1026                                  "1234567890123456789012345678901234567890");
1027     digest384     = sha384Of    ("1234567890123456789012345678901234567890"~
1028                                  "1234567890123456789012345678901234567890");
1029     digest512     = sha512Of    ("1234567890123456789012345678901234567890"~
1030                                  "1234567890123456789012345678901234567890");
1031     digest512_224 = sha512_224Of("1234567890123456789012345678901234567890"~
1032                                  "1234567890123456789012345678901234567890");
1033     digest512_256 = sha512_256Of("1234567890123456789012345678901234567890"~
1034                                  "1234567890123456789012345678901234567890");
1035     assert(digest == cast(ubyte[])x"50abf5706a150990a08b2c5ea40fa0e585554732");
1036     assert(digest224 == cast(ubyte[])x"b50aecbe4e9bb0b57bc5f3ae760a8e01db24f203fb3cdcd13148046e");
1037     assert(digest256 == cast(ubyte[])x"f371bc4a311f2b009eef952dd83ca80e2b60026c8e935592d0f9c308453c813e");
1038     assert(digest384 == cast(ubyte[])x"b12932b0627d1c060942f5447764155655bd4da0c9afa6dd9b9ef53129af1b8fb0195996d2de9ca0df9d821ffee67026");
1039     assert(digest512 == cast(ubyte[])x"72ec1ef1124a45b047e8b7c75a932195135bb61de24ec0d1914042246e0aec3a2354e093d76f3048b456764346900cb130d2a4fd5dd16abb5e30bcb850dee843");
1040     assert(digest512_224 == cast(ubyte[])x"ae988faaa47e401a45f704d1272d99702458fea2ddc6582827556dd2");
1041     assert(digest512_256 == cast(ubyte[])x"2c9fdbc0c90bdd87612ee8455474f9044850241dc105b1e8b94b8ddf5fac9148");
1042 
1043     ubyte[] onemilliona = new ubyte[1000000];
1044     onemilliona[] = 'a';
1045     digest = sha1Of(onemilliona);
1046     digest224 = sha224Of(onemilliona);
1047     digest256 = sha256Of(onemilliona);
1048     digest384 = sha384Of(onemilliona);
1049     digest512 = sha512Of(onemilliona);
1050     digest512_224 = sha512_224Of(onemilliona);
1051     digest512_256 = sha512_256Of(onemilliona);
1052     assert(digest == cast(ubyte[])x"34aa973cd4c4daa4f61eeb2bdbad27316534016f");
1053     assert(digest224 == cast(ubyte[])x"20794655980c91d8bbb4c1ea97618a4bf03f42581948b2ee4ee7ad67");
1054     assert(digest256 == cast(ubyte[])x"cdc76e5c9914fb9281a1c7e284d73e67f1809a48a497200e046d39ccc7112cd0");
1055     assert(digest384 == cast(ubyte[])x"9d0e1809716474cb086e834e310a4a1ced149e9c00f248527972cec5704c2a5b07b8b3dc38ecc4ebae97ddd87f3d8985");
1056     assert(digest512 == cast(ubyte[])x"e718483d0ce769644e2e42c7bc15b4638e1f98b13b2044285632a803afa973ebde0ff244877ea60a4cb0432ce577c31beb009c5c2c49aa2e4eadb217ad8cc09b");
1057     assert(digest512_224 == cast(ubyte[])x"37ab331d76f0d36de422bd0edeb22a28accd487b7a8453ae965dd287");
1058     assert(digest512_256 == cast(ubyte[])x"9a59a052930187a97038cae692f30708aa6491923ef5194394dc68d56c74fb21");
1059 
1060     auto oneMillionRange = repeat!ubyte(cast(ubyte)'a', 1000000);
1061     digest = sha1Of(oneMillionRange);
1062     digest224 = sha224Of(oneMillionRange);
1063     digest256 = sha256Of(oneMillionRange);
1064     digest384 = sha384Of(oneMillionRange);
1065     digest512 = sha512Of(oneMillionRange);
1066     digest512_224 = sha512_224Of(oneMillionRange);
1067     digest512_256 = sha512_256Of(oneMillionRange);
1068     assert(digest == cast(ubyte[])x"34aa973cd4c4daa4f61eeb2bdbad27316534016f");
1069     assert(digest224 == cast(ubyte[])x"20794655980c91d8bbb4c1ea97618a4bf03f42581948b2ee4ee7ad67");
1070     assert(digest256 == cast(ubyte[])x"cdc76e5c9914fb9281a1c7e284d73e67f1809a48a497200e046d39ccc7112cd0");
1071     assert(digest384 == cast(ubyte[])x"9d0e1809716474cb086e834e310a4a1ced149e9c00f248527972cec5704c2a5b07b8b3dc38ecc4ebae97ddd87f3d8985");
1072     assert(digest512 == cast(ubyte[])x"e718483d0ce769644e2e42c7bc15b4638e1f98b13b2044285632a803afa973ebde0ff244877ea60a4cb0432ce577c31beb009c5c2c49aa2e4eadb217ad8cc09b");
1073     assert(digest512_224 == cast(ubyte[])x"37ab331d76f0d36de422bd0edeb22a28accd487b7a8453ae965dd287");
1074     assert(digest512_256 == cast(ubyte[])x"9a59a052930187a97038cae692f30708aa6491923ef5194394dc68d56c74fb21");
1075 
1076     assert(toHexString(cast(ubyte[20])x"a9993e364706816aba3e25717850c26c9cd0d89d")
1077         == "A9993E364706816ABA3E25717850C26C9CD0D89D");
1078 }
1079 
1080 /**
1081  * These are convenience aliases for $(XREF digest.digest, digest) using the
1082  * SHA implementation.
1083  */
1084 //simple alias doesn't work here, hope this gets inlined...
1085 auto sha1Of(T...)(T data)
1086 {
1087     return digest!(SHA1, T)(data);
1088 }
1089 ///ditto
1090 auto sha224Of(T...)(T data)
1091 {
1092     return digest!(SHA224, T)(data);
1093 }
1094 ///ditto
1095 auto sha256Of(T...)(T data)
1096 {
1097     return digest!(SHA256, T)(data);
1098 }
1099 ///ditto
1100 auto sha384Of(T...)(T data)
1101 {
1102     return digest!(SHA384, T)(data);
1103 }
1104 ///ditto
1105 auto sha512Of(T...)(T data)
1106 {
1107     return digest!(SHA512, T)(data);
1108 }
1109 ///ditto
1110 auto sha512_224Of(T...)(T data)
1111 {
1112     return digest!(SHA512_224, T)(data);
1113 }
1114 ///ditto
1115 auto sha512_256Of(T...)(T data)
1116 {
1117     return digest!(SHA512_256, T)(data);
1118 }
1119 
1120 ///
1121 unittest
1122 {
1123     ubyte[20] hash = sha1Of("abc");
1124     assert(hash == digest!SHA1("abc"));
1125 
1126     ubyte[28] hash224 = sha224Of("abc");
1127     assert(hash224 == digest!SHA224("abc"));
1128 
1129     ubyte[32] hash256 = sha256Of("abc");
1130     assert(hash256 == digest!SHA256("abc"));
1131 
1132     ubyte[48] hash384 = sha384Of("abc");
1133     assert(hash384 == digest!SHA384("abc"));
1134 
1135     ubyte[64] hash512 = sha512Of("abc");
1136     assert(hash512 == digest!SHA512("abc"));
1137 
1138     ubyte[28] hash512_224 = sha512_224Of("abc");
1139     assert(hash512_224 == digest!SHA512_224("abc"));
1140 
1141     ubyte[32] hash512_256 = sha512_256Of("abc");
1142     assert(hash512_256 == digest!SHA512_256("abc"));
1143 }
1144 
1145 unittest
1146 {
1147     string a = "Mary has ", b = "a little lamb";
1148     int[] c = [ 1, 2, 3, 4, 5 ];
1149     string d = toHexString(sha1Of(a, b, c));
1150     version(LittleEndian)
1151         assert(d == "CDBB611D00AC2387B642D3D7BDF4C3B342237110", d);
1152     else
1153         assert(d == "A0F1196C7A379C09390476D9CA4AA11B71FD11C8", d);
1154 }
1155 
1156 /**
1157  * OOP API SHA1 and SHA2 implementations.
1158  * See $(D std.digest.digest) for differences between template and OOP API.
1159  *
1160  * This is an alias for $(XREF digest.digest, WrapperDigest)!SHA1, see
1161  * $(XREF digest.digest, WrapperDigest) for more information.
1162  */
1163 alias SHA1Digest = WrapperDigest!SHA1;
1164 alias SHA224Digest = WrapperDigest!SHA224; ///ditto
1165 alias SHA256Digest = WrapperDigest!SHA256; ///ditto
1166 alias SHA384Digest = WrapperDigest!SHA384; ///ditto
1167 alias SHA512Digest = WrapperDigest!SHA512; ///ditto
1168 alias SHA512_224Digest = WrapperDigest!SHA512_224; ///ditto
1169 alias SHA512_256Digest = WrapperDigest!SHA512_256; ///ditto
1170 
1171 ///
1172 unittest
1173 {
1174     //Simple example, hashing a string using Digest.digest helper function
1175     auto sha = new SHA1Digest();
1176     ubyte[] hash = sha.digest("abc");
1177     //Let's get a hash string
1178     assert(toHexString(hash) == "A9993E364706816ABA3E25717850C26C9CD0D89D");
1179 
1180     //The same, but using SHA-224
1181     auto sha224 = new SHA224Digest();
1182     ubyte[] hash224 = sha224.digest("abc");
1183     //Let's get a hash string
1184     assert(toHexString(hash224) == "23097D223405D8228642A477BDA255B32AADBCE4BDA0B3F7E36C9DA7");
1185 }
1186 
1187 ///
1188 unittest
1189 {
1190     //Let's use the OOP features:
1191     void test(Digest dig)
1192     {
1193       dig.put(cast(ubyte)0);
1194     }
1195     auto sha = new SHA1Digest();
1196     test(sha);
1197 
1198     //Let's use a custom buffer:
1199     ubyte[20] buf;
1200     ubyte[] result = sha.finish(buf[]);
1201     assert(toHexString(result) == "5BA93C9DB0CFF93F52B521D7420E43F6EDA2784F");
1202 }
1203 
1204 unittest
1205 {
1206     auto sha = new SHA1Digest();
1207 
1208     sha.put(cast(ubyte[])"abcdef");
1209     sha.reset();
1210     sha.put(cast(ubyte[])"");
1211     assert(sha.finish() == cast(ubyte[])x"da39a3ee5e6b4b0d3255bfef95601890afd80709");
1212 
1213     sha.put(cast(ubyte[])"abcdefghijklmnopqrstuvwxyz");
1214     ubyte[22] result;
1215     auto result2 = sha.finish(result[]);
1216     assert(result[0 .. 20] == result2 && result2 == cast(ubyte[])x"32d10c7b8cf96570ca04ce37f2a19d84240d3a89");
1217 
1218     debug
1219         assertThrown!Error(sha.finish(result[0 .. 15]));
1220 
1221     assert(sha.length == 20);
1222 
1223     assert(sha.digest("") == cast(ubyte[])x"da39a3ee5e6b4b0d3255bfef95601890afd80709");
1224 
1225     assert(sha.digest("a") == cast(ubyte[])x"86f7e437faa5a7fce15d1ddcb9eaeaea377667b8");
1226 
1227     assert(sha.digest("abc") == cast(ubyte[])x"a9993e364706816aba3e25717850c26c9cd0d89d");
1228 
1229     assert(sha.digest("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq")
1230            == cast(ubyte[])x"84983e441c3bd26ebaae4aa1f95129e5e54670f1");
1231 
1232     assert(sha.digest("message digest") == cast(ubyte[])x"c12252ceda8be8994d5fa0290a47231c1d16aae3");
1233 
1234     assert(sha.digest("abcdefghijklmnopqrstuvwxyz")
1235            == cast(ubyte[])x"32d10c7b8cf96570ca04ce37f2a19d84240d3a89");
1236 
1237     assert(sha.digest("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789")
1238            == cast(ubyte[])x"761c457bf73b14d27e9e9265c46f4b4dda11f940");
1239 
1240     assert(sha.digest("1234567890123456789012345678901234567890",
1241                                    "1234567890123456789012345678901234567890")
1242            == cast(ubyte[])x"50abf5706a150990a08b2c5ea40fa0e585554732");
1243 
1244     ubyte[] onemilliona = new ubyte[1000000];
1245     onemilliona[] = 'a';
1246     assert(sha.digest(onemilliona) == cast(ubyte[])x"34aa973cd4c4daa4f61eeb2bdbad27316534016f");
1247 }