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