|
- using System;
- using System.Collections.ObjectModel;
-
- namespace SUISS.Cloud.Crypto
- {
- public class Sha256
- {
- private static uint ROTL(uint x, byte n)
- {
- return x << (int)n | x >> (int)(32 - n);
- }
-
- private static uint ROTR(uint x, byte n)
- {
- return x >> (int)n | x << (int)(32 - n);
- }
-
- private static uint Ch(uint x, uint y, uint z)
- {
- return (x & y) ^ (~x & z);
- }
-
- private static uint Maj(uint x, uint y, uint z)
- {
- return (x & y) ^ (x & z) ^ (y & z);
- }
-
- private static uint Sigma0(uint x)
- {
- return Sha256.ROTR(x, 2) ^ Sha256.ROTR(x, 13) ^ Sha256.ROTR(x, 22);
- }
-
- private static uint Sigma1(uint x)
- {
- return Sha256.ROTR(x, 6) ^ Sha256.ROTR(x, 11) ^ Sha256.ROTR(x, 25);
- }
-
- private static uint sigma0(uint x)
- {
- return Sha256.ROTR(x, 7) ^ Sha256.ROTR(x, 18) ^ x >> 3;
- }
-
- private static uint sigma1(uint x)
- {
- return Sha256.ROTR(x, 17) ^ Sha256.ROTR(x, 19) ^ x >> 10;
- }
-
- private void processBlock(uint[] M)
- {
- uint[] array = new uint[64];
- for (int i = 0; i < 16; i++)
- {
- array[i] = M[i];
- }
- for (int j = 16; j < 64; j++)
- {
- array[j] = Sha256.sigma1(array[j - 2]) + array[j - 7] + Sha256.sigma0(array[j - 15]) + array[j - 16];
- }
- uint num = this.H[0];
- uint num2 = this.H[1];
- uint num3 = this.H[2];
- uint num4 = this.H[3];
- uint num5 = this.H[4];
- uint num6 = this.H[5];
- uint num7 = this.H[6];
- uint num8 = this.H[7];
- for (int k = 0; k < 64; k++)
- {
- uint num9 = num8 + Sha256.Sigma1(num5) + Sha256.Ch(num5, num6, num7) + Sha256.K[k] + array[k];
- uint num10 = Sha256.Sigma0(num) + Sha256.Maj(num, num2, num3);
- num8 = num7;
- num7 = num6;
- num6 = num5;
- num5 = num4 + num9;
- num4 = num3;
- num3 = num2;
- num2 = num;
- num = num9 + num10;
- }
- this.H[0] = num + this.H[0];
- this.H[1] = num2 + this.H[1];
- this.H[2] = num3 + this.H[2];
- this.H[3] = num4 + this.H[3];
- this.H[4] = num5 + this.H[4];
- this.H[5] = num6 + this.H[5];
- this.H[6] = num7 + this.H[6];
- this.H[7] = num8 + this.H[7];
- }
-
- public void AddData(byte[] data, uint offset, uint len)
- {
- if (this.closed)
- {
- throw new InvalidOperationException("Adding data to a closed hasher.");
- }
- if (len == 0u)
- {
- return;
- }
- this.bits_processed += (ulong)(len * 8u);
- while (len > 0u)
- {
- uint num;
- if (len < 64u)
- {
- if (this.pending_block_off + len > 64u)
- {
- num = 64u - this.pending_block_off;
- }
- else
- {
- num = len;
- }
- }
- else
- {
- num = 64u - this.pending_block_off;
- }
- Array.Copy(data, (long)((ulong)offset), this.pending_block, (long)((ulong)this.pending_block_off), (long)((ulong)num));
- len -= num;
- offset += num;
- this.pending_block_off += num;
- if (this.pending_block_off == 64u)
- {
- Sha256.toUintArray(this.pending_block, this.uint_buffer);
- this.processBlock(this.uint_buffer);
- this.pending_block_off = 0u;
- }
- }
- }
-
- public ReadOnlyCollection<byte> GetHash()
- {
- return Sha256.toByteArray(this.GetHashUInt32());
- }
-
- public ReadOnlyCollection<uint> GetHashUInt32()
- {
- if (!this.closed)
- {
- ulong num = this.bits_processed;
- this.AddData(new byte[]
- {
- 128
- }, 0u, 1u);
- uint num2 = 64u - this.pending_block_off;
- if (num2 < 8u)
- {
- num2 += 64u;
- }
- byte[] array = new byte[num2];
- for (uint num3 = 1u; num3 <= 8u; num3 += 1u)
- {
- array[(int)(checked((IntPtr)(unchecked((long)array.Length - (long)((ulong)num3)))))] = (byte)num;
- num >>= 8;
- }
- this.AddData(array, 0u, (uint)array.Length);
- this.closed = true;
- }
- return Array.AsReadOnly<uint>(this.H);
- }
-
- private static void toUintArray(byte[] src, uint[] dest)
- {
- uint num = 0u;
- uint num2 = 0u;
- while ((ulong)num < (ulong)((long)dest.Length))
- {
- dest[(int)((UIntPtr)num)] = (uint)((int)src[(int)((UIntPtr)num2)] << 24 | (int)src[(int)((UIntPtr)(num2 + 1u))] << 16 | (int)src[(int)((UIntPtr)(num2 + 2u))] << 8 | (int)src[(int)((UIntPtr)(num2 + 3u))]);
- num += 1u;
- num2 += 4u;
- }
- }
-
- private static ReadOnlyCollection<byte> toByteArray(ReadOnlyCollection<uint> src)
- {
- byte[] array = new byte[src.Count * 4];
- int num = 0;
- for (int i = 0; i < src.Count; i++)
- {
- array[num++] = (byte)(src[i] >> 24);
- array[num++] = (byte)(src[i] >> 16);
- array[num++] = (byte)(src[i] >> 8);
- array[num++] = (byte)src[i];
- }
- return Array.AsReadOnly<byte>(array);
- }
-
- public static ReadOnlyCollection<byte> HashBytes(params object[] args)
- {
- Sha256 sha = new Sha256();
- foreach (object obj in args)
- {
- if (obj is byte[])
- {
- byte[] array = obj as byte[];
- sha.AddData(array, 0u, (uint)array.Length);
- }
- else
- {
- if (!(obj is ReadOnlyCollection<byte>))
- {
- throw new ArgumentException();
- }
- ReadOnlyCollection<byte> readOnlyCollection = obj as ReadOnlyCollection<byte>;
- byte[] array2 = new byte[readOnlyCollection.Count];
- readOnlyCollection.CopyTo(array2, 0);
- sha.AddData(array2, 0u, (uint)array2.Length);
- }
- }
- return sha.GetHash();
- }
-
- public static byte[] HashToBytes(params object[] args)
- {
- ReadOnlyCollection<byte> readOnlyCollection = Sha256.HashBytes(args);
- byte[] array = new byte[readOnlyCollection.Count];
- readOnlyCollection.CopyTo(array, 0);
- return array;
- }
-
- private static readonly uint[] K = new uint[]
- {
- 1116352408u,
- 1899447441u,
- 3049323471u,
- 3921009573u,
- 961987163u,
- 1508970993u,
- 2453635748u,
- 2870763221u,
- 3624381080u,
- 310598401u,
- 607225278u,
- 1426881987u,
- 1925078388u,
- 2162078206u,
- 2614888103u,
- 3248222580u,
- 3835390401u,
- 4022224774u,
- 264347078u,
- 604807628u,
- 770255983u,
- 1249150122u,
- 1555081692u,
- 1996064986u,
- 2554220882u,
- 2821834349u,
- 2952996808u,
- 3210313671u,
- 3336571891u,
- 3584528711u,
- 113926993u,
- 338241895u,
- 666307205u,
- 773529912u,
- 1294757372u,
- 1396182291u,
- 1695183700u,
- 1986661051u,
- 2177026350u,
- 2456956037u,
- 2730485921u,
- 2820302411u,
- 3259730800u,
- 3345764771u,
- 3516065817u,
- 3600352804u,
- 4094571909u,
- 275423344u,
- 430227734u,
- 506948616u,
- 659060556u,
- 883997877u,
- 958139571u,
- 1322822218u,
- 1537002063u,
- 1747873779u,
- 1955562222u,
- 2024104815u,
- 2227730452u,
- 2361852424u,
- 2428436474u,
- 2756734187u,
- 3204031479u,
- 3329325298u
- };
-
- private uint[] H = new uint[]
- {
- 1779033703u,
- 3144134277u,
- 1013904242u,
- 2773480762u,
- 1359893119u,
- 2600822924u,
- 528734635u,
- 1541459225u
- };
-
- private byte[] pending_block = new byte[64];
-
- private uint pending_block_off;
-
- private uint[] uint_buffer = new uint[16];
-
- private ulong bits_processed;
-
- private bool closed;
- }
- }
|