2 // System.Security.Cryptography.SHA512Managed.cs
5 // Dan Lewis (dihlewis@yahoo.co.uk)
6 // Sébastien Pouliot (spouliot@motus.com)
9 // Implementation translated from Bouncy Castle JCE (http://www.bouncycastle.org/)
10 // See bouncycastle.txt for license.
15 namespace System.Security.Cryptography {
17 public class SHA512Managed : SHA512 {
22 private ulong byteCount1;
23 private ulong byteCount2;
25 private ulong H1, H2, H3, H4, H5, H6, H7, H8;
27 private ulong[] W = new ulong [80];
30 public SHA512Managed ()
37 public override void Initialize ()
39 // SHA-512 initial hash value
40 // The first 64 bits of the fractional parts of the square roots
41 // of the first eight prime numbers
42 H1 = 0x6a09e667f3bcc908L;
43 H2 = 0xbb67ae8584caa73bL;
44 H3 = 0x3c6ef372fe94f82bL;
45 H4 = 0xa54ff53a5f1d36f1L;
46 H5 = 0x510e527fade682d1L;
47 H6 = 0x9b05688c2b3e6c1fL;
48 H7 = 0x1f83d9abfb41bd6bL;
49 H8 = 0x5be0cd19137e2179L;
55 for (int i = 0; i < xBuf.Length; i++)
59 for (int i = 0; i != W.Length; i++)
65 protected override void HashCore (byte[] rgb, int start, int count)
67 // fill the current word
68 while ((xBufOff != 0) && (count > 0)) {
74 // process whole words.
75 while (count > xBuf.Length) {
76 processWord(rgb, start);
79 byteCount1 += (ulong) xBuf.Length;
82 // load in the remainder.
90 protected override byte[] HashFinal ()
94 ulong lowBitLength = byteCount1 << 3;
95 ulong hiBitLength = byteCount2;
102 processLength (lowBitLength, hiBitLength);
105 byte[] output = new byte [64];
106 unpackWord(H1, output, 0);
107 unpackWord(H2, output, 8);
108 unpackWord(H3, output, 16);
109 unpackWord(H4, output, 24);
110 unpackWord(H5, output, 32);
111 unpackWord(H6, output, 40);
112 unpackWord(H7, output, 48);
113 unpackWord(H8, output, 56);
119 private void update (byte input)
121 xBuf [xBufOff++] = input;
122 if (xBufOff == xBuf.Length) {
123 processWord(xBuf, 0);
129 private void processWord (byte[] input, int inOff)
131 W [wOff++] = ( (ulong) input [inOff] << 56)
132 | ( (ulong) input [inOff + 1] << 48)
133 | ( (ulong) input [inOff + 2] << 40)
134 | ( (ulong) input [inOff + 3] << 32)
135 | ( (ulong) input [inOff + 4] << 24)
136 | ( (ulong) input [inOff + 5] << 16)
137 | ( (ulong) input [inOff + 6] << 8)
138 | ( (ulong) input [inOff + 7]);
143 private void unpackWord (ulong word, byte[] output, int outOff)
145 output[outOff] = (byte) (word >> 56);
146 output[outOff + 1] = (byte) (word >> 48);
147 output[outOff + 2] = (byte) (word >> 40);
148 output[outOff + 3] = (byte) (word >> 32);
149 output[outOff + 4] = (byte) (word >> 24);
150 output[outOff + 5] = (byte) (word >> 16);
151 output[outOff + 6] = (byte) (word >> 8);
152 output[outOff + 7] = (byte) word;
155 // adjust the byte counts so that byteCount2 represents the
156 // upper long (less 3 bits) word of the byte count.
157 private void adjustByteCounts ()
159 if (byteCount1 > 0x1fffffffffffffffL) {
160 byteCount2 += (byteCount1 >> 61);
161 byteCount1 &= 0x1fffffffffffffffL;
165 private void processLength (ulong lowW, ulong hiW)
173 private void processBlock ()
176 // expand 16 word block into 80 word blocks.
177 for (int t = 16; t <= 79; t++)
178 W[t] = Sigma1 (W [t - 2]) + W [t - 7] + Sigma0 (W [t - 15]) + W [t - 16];
180 // set up working variables.
190 for (int t = 0; t <= 79; t++) {
191 ulong T1 = h + Sum1 (e) + Ch (e, f, g) + K [t] + W [t];
192 ulong T2 = Sum0 (a) + Maj (a, b, c);
211 // reset the offset and clean out the word buffer.
213 for (int i = 0; i != W.Length; i++)
217 private ulong rotateRight (ulong x, int n)
219 return (x >> n) | (x << (64 - n));
222 /* SHA-512 and SHA-512 functions (as for SHA-256 but for longs) */
223 private ulong Ch (ulong x, ulong y, ulong z)
225 return ((x & y) ^ ((~x) & z));
228 private ulong Maj (ulong x, ulong y, ulong z)
230 return ((x & y) ^ (x & z) ^ (y & z));
233 private ulong Sum0 (ulong x)
235 return rotateRight (x, 28) ^ rotateRight (x, 34) ^ rotateRight (x, 39);
238 private ulong Sum1 (ulong x)
240 return rotateRight (x, 14) ^ rotateRight (x, 18) ^ rotateRight (x, 41);
243 private ulong Sigma0 (ulong x)
245 return rotateRight (x, 1) ^ rotateRight(x, 8) ^ (x >> 7);
248 private ulong Sigma1 (ulong x)
250 return rotateRight (x, 19) ^ rotateRight (x, 61) ^ (x >> 6);
253 // SHA-384 and SHA-512 Constants
254 // Rrepresent the first 64 bits of the fractional parts of the
255 // cube roots of the first sixty-four prime numbers
257 0x428a2f98d728ae22L, 0x7137449123ef65cdL, 0xb5c0fbcfec4d3b2fL, 0xe9b5dba58189dbbcL,
258 0x3956c25bf348b538L, 0x59f111f1b605d019L, 0x923f82a4af194f9bL, 0xab1c5ed5da6d8118L,
259 0xd807aa98a3030242L, 0x12835b0145706fbeL, 0x243185be4ee4b28cL, 0x550c7dc3d5ffb4e2L,
260 0x72be5d74f27b896fL, 0x80deb1fe3b1696b1L, 0x9bdc06a725c71235L, 0xc19bf174cf692694L,
261 0xe49b69c19ef14ad2L, 0xefbe4786384f25e3L, 0x0fc19dc68b8cd5b5L, 0x240ca1cc77ac9c65L,
262 0x2de92c6f592b0275L, 0x4a7484aa6ea6e483L, 0x5cb0a9dcbd41fbd4L, 0x76f988da831153b5L,
263 0x983e5152ee66dfabL, 0xa831c66d2db43210L, 0xb00327c898fb213fL, 0xbf597fc7beef0ee4L,
264 0xc6e00bf33da88fc2L, 0xd5a79147930aa725L, 0x06ca6351e003826fL, 0x142929670a0e6e70L,
265 0x27b70a8546d22ffcL, 0x2e1b21385c26c926L, 0x4d2c6dfc5ac42aedL, 0x53380d139d95b3dfL,
266 0x650a73548baf63deL, 0x766a0abb3c77b2a8L, 0x81c2c92e47edaee6L, 0x92722c851482353bL,
267 0xa2bfe8a14cf10364L, 0xa81a664bbc423001L, 0xc24b8b70d0f89791L, 0xc76c51a30654be30L,
268 0xd192e819d6ef5218L, 0xd69906245565a910L, 0xf40e35855771202aL, 0x106aa07032bbd1b8L,
269 0x19a4c116b8d2d0c8L, 0x1e376c085141ab53L, 0x2748774cdf8eeb99L, 0x34b0bcb5e19b48a8L,
270 0x391c0cb3c5c95a63L, 0x4ed8aa4ae3418acbL, 0x5b9cca4f7763e373L, 0x682e6ff3d6b2b8a3L,
271 0x748f82ee5defb2fcL, 0x78a5636f43172f60L, 0x84c87814a1f0ab72L, 0x8cc702081a6439ecL,
272 0x90befffa23631e28L, 0xa4506cebde82bde9L, 0xbef9a3f7b2c67915L, 0xc67178f2e372532bL,
273 0xca273eceea26619cL, 0xd186b8c721c0c207L, 0xeada7dd6cde0eb1eL, 0xf57d4f7fee6ed178L,
274 0x06f067aa72176fbaL, 0x0a637dc5a2c898a6L, 0x113f9804bef90daeL, 0x1b710b35131c471bL,
275 0x28db77f523047d84L, 0x32caab7b40c72493L, 0x3c9ebe0a15c9bebcL, 0x431d67c49c100d4cL,
276 0x4cc5d4becb3e42b6L, 0x597f299cfc657e2aL, 0x5fcb6fab3ad6faecL, 0x6c44198c4a475817L