byte[] Sha512Algorithm(byte[] plaintext, UInt64[] H0, int numberBits) { Block1024[] blocks = ConvertPaddedMessageToBlock1024Array(PadPlainText1024(plaintext)); // Define the hash variable and set its initial values. UInt64[] H = H0; for (int i = 0; i < blocks.Length; i++) { UInt64[] W = CreateMessageScheduleSha512(blocks[i]); // Set the working variables a,...,h to the current hash values. UInt64 a = H[0]; UInt64 b = H[1]; UInt64 c = H[2]; UInt64 d = H[3]; UInt64 e = H[4]; UInt64 f = H[5]; UInt64 g = H[6]; UInt64 h = H[7]; for (int t = 0; t < 80; t++) { UInt64 T1 = h + Sigma1_512(e) + Ch(e, f, g) + this.K512[t] + W[t]; UInt64 T2 = Sigma0_512(a) + Maj(a, b, c); h = g; g = f; f = e; e = d + T1; d = c; c = b; b = a; a = T1 + T2; } // Update the current value of the hash H after processing block i. H[0] += a; H[1] += b; H[2] += c; H[3] += d; H[4] += e; H[5] += f; H[6] += g; H[7] += h; } // Concatenate all the Word64 Hash Values byte[] hash = ShaUtilities.Word64ArrayToByteArray(H); // The number of bytes in the final output hash int numberBytes = numberBits / 8; byte[] truncatedHash = new byte[numberBytes]; Array.Copy(hash, truncatedHash, numberBytes); return(truncatedHash); }
static Block1024[] ConvertPaddedMessageToBlock1024Array(byte[] M) { // We are assuming M is padded, so the number of bits in M is divisible by 1024 int numberBlocks = (M.Length * 8) / 1024; // same as: M.Length / 128 Block1024[] blocks = new Block1024[numberBlocks]; for (int i = 0; i < numberBlocks; i++) { // First extract the relavant subarray from M byte[] B = new byte[128]; // 128 * 8 = 1024 for (int j = 0; j < 128; j++) { B[j] = M[i * 128 + j]; } UInt64[] words = ShaUtilities.ByteArrayToWord64Array(B); blocks[i] = new Block1024(words); } return(blocks); }