<PackageReference Include="BouncyCastle.Cryptography" Version="2.7.0-beta.98" />

LongDigest

public abstract class LongDigest : IDigest, IMemoable
using Org.BouncyCastle.Crypto.Utilities; using Org.BouncyCastle.Utilities; using System; namespace Org.BouncyCastle.Crypto.Digests { public abstract class LongDigest : IDigest, IMemoable { private const int MyByteLength = 128; private byte[] xBuf; private int xBufOff; private long byteCount1; private long byteCount2; internal ulong H1; internal ulong H2; internal ulong H3; internal ulong H4; internal ulong H5; internal ulong H6; internal ulong H7; internal ulong H8; private ulong[] W = new ulong[80]; private int wOff; internal static readonly ulong[] K = new ulong[80] { 4794697086780616226, 8158064640168781261, 13096744586834688815, 16840607885511220156, 4131703408338449720, 6480981068601479193, 10538285296894168987, 12329834152419229976, 15566598209576043074, 1334009975649890238, 2608012711638119052, 6128411473006802146, 8268148722764581231, 9286055187155687089, 11230858885718282805, 13951009754708518548, 16472876342353939154, 17275323862435702243, 1135362057144423861, 2597628984639134821, 3308224258029322869, 5365058923640841347, 6679025012923562964, 8573033837759648693, 10970295158949994411, 12119686244451234320, 12683024718118986047, 13788192230050041572, 14330467153632333762, 15395433587784984357, 489312712824947311, 1452737877330783856, 2861767655752347644, 3322285676063803686, 5560940570517711597, 5996557281743188959, 7280758554555802590, 8532644243296465576, 9350256976987008742, 10552545826968843579, 11727347734174303076, 12113106623233404929, 14000437183269869457, 14369950271660146224, 15101387698204529176, 15463397548674623760, 17586052441742319658, 1182934255886127544, 1847814050463011016, 2177327727835720531, 2830643537854262169, 3796741975233480872, 4115178125766777443, 5681478168544905931, 6601373596472566643, 7507060721942968483, 8399075790359081724, 8693463985226723168, 9568029438360202098, 10144078919501101548, 10430055236837252648, 11840083180663258601, 13761210420658862357, 14299343276471374635, 14566680578165727644, 15097957966210449927, 16922976911328602910, 17689382322260857208, 500013540394364858, 748580250866718886, 1242879168328830382, 1977374033974150939, 2944078676154940804, 3659926193048069267, 4368137639120453308, 4836135668995329356, 5532061633213252278, 6448918945643986474, 6902733635092675308, 7801388544844847127 }; public abstract string AlgorithmName { get; } internal LongDigest() { xBuf = new byte[8]; Reset(); } internal LongDigest(LongDigest t) { xBuf = new byte[t.xBuf.Length]; CopyIn(t); } protected void CopyIn(LongDigest t) { Array.Copy(t.xBuf, 0, xBuf, 0, t.xBuf.Length); xBufOff = t.xBufOff; byteCount1 = t.byteCount1; byteCount2 = t.byteCount2; H1 = t.H1; H2 = t.H2; H3 = t.H3; H4 = t.H4; H5 = t.H5; H6 = t.H6; H7 = t.H7; H8 = t.H8; Array.Copy(t.W, 0, W, 0, t.W.Length); wOff = t.wOff; } public void Update(byte input) { xBuf[xBufOff++] = input; if (xBufOff == xBuf.Length) { ProcessWord(xBuf, 0); xBufOff = 0; } byteCount1++; } public void BlockUpdate(byte[] input, int inOff, int length) { while (xBufOff != 0 && length > 0) { Update(input[inOff]); inOff++; length--; } while (length >= xBuf.Length) { ProcessWord(input, inOff); inOff += xBuf.Length; length -= xBuf.Length; byteCount1 += xBuf.Length; } while (length > 0) { Update(input[inOff]); inOff++; length--; } } public void Finish() { AdjustByteCounts(); long lowW = byteCount1 << 3; long hiW = byteCount2; Update(128); while (xBufOff != 0) { Update(0); } ProcessLength(lowW, hiW); ProcessBlock(); } public virtual void Reset() { byteCount1 = 0; byteCount2 = 0; xBufOff = 0; for (int i = 0; i < xBuf.Length; i++) { xBuf[i] = 0; } wOff = 0; Array.Clear(W, 0, W.Length); } internal void ProcessWord(byte[] input, int inOff) { W[wOff] = Pack.BE_To_UInt64(input, inOff); if (++wOff == 16) ProcessBlock(); } private void AdjustByteCounts() { if (byteCount1 > 2305843009213693951) { byteCount2 += (long)((ulong)byteCount1 >> 61); byteCount1 &= 2305843009213693951; } } internal void ProcessLength(long lowW, long hiW) { if (wOff > 14) ProcessBlock(); W[14] = (ulong)hiW; W[15] = (ulong)lowW; } internal void ProcessBlock() { AdjustByteCounts(); for (int i = 16; i <= 79; i++) { W[i] = Sigma1(W[i - 2]) + W[i - 7] + Sigma0(W[i - 15]) + W[i - 16]; } ulong num = H1; ulong num2 = H2; ulong num3 = H3; ulong num4 = H4; ulong num5 = H5; ulong num6 = H6; ulong num7 = H7; ulong num8 = H8; int num9 = 0; for (int j = 0; j < 10; j++) { num8 += Sum1(num5) + Ch(num5, num6, num7) + K[num9] + W[num9++]; num4 += num8; num8 += Sum0(num) + Maj(num, num2, num3); num7 += Sum1(num4) + Ch(num4, num5, num6) + K[num9] + W[num9++]; num3 += num7; num7 += Sum0(num8) + Maj(num8, num, num2); num6 += Sum1(num3) + Ch(num3, num4, num5) + K[num9] + W[num9++]; num2 += num6; num6 += Sum0(num7) + Maj(num7, num8, num); num5 += Sum1(num2) + Ch(num2, num3, num4) + K[num9] + W[num9++]; num += num5; num5 += Sum0(num6) + Maj(num6, num7, num8); num4 += Sum1(num) + Ch(num, num2, num3) + K[num9] + W[num9++]; num8 += num4; num4 += Sum0(num5) + Maj(num5, num6, num7); num3 += Sum1(num8) + Ch(num8, num, num2) + K[num9] + W[num9++]; num7 += num3; num3 += Sum0(num4) + Maj(num4, num5, num6); num2 += Sum1(num7) + Ch(num7, num8, num) + K[num9] + W[num9++]; num6 += num2; num2 += Sum0(num3) + Maj(num3, num4, num5); num += Sum1(num6) + Ch(num6, num7, num8) + K[num9] + W[num9++]; num5 += num; num += Sum0(num2) + Maj(num2, num3, num4); } H1 += num; H2 += num2; H3 += num3; H4 += num4; H5 += num5; H6 += num6; H7 += num7; H8 += num8; wOff = 0; Array.Clear(W, 0, 16); } private static ulong Ch(ulong x, ulong y, ulong z) { return (x & y) ^ (~x & z); } private static ulong Maj(ulong x, ulong y, ulong z) { return (x & y) ^ (x & z) ^ (y & z); } private static ulong Sum0(ulong x) { return ((x << 36) | (x >> 28)) ^ ((x << 30) | (x >> 34)) ^ ((x << 25) | (x >> 39)); } private static ulong Sum1(ulong x) { return ((x << 50) | (x >> 14)) ^ ((x << 46) | (x >> 18)) ^ ((x << 23) | (x >> 41)); } private static ulong Sigma0(ulong x) { return ((x << 63) | (x >> 1)) ^ ((x << 56) | (x >> 8)) ^ (x >> 7); } private static ulong Sigma1(ulong x) { return ((x << 45) | (x >> 19)) ^ ((x << 3) | (x >> 61)) ^ (x >> 6); } public int GetByteLength() { return 128; } public abstract int GetDigestSize(); public abstract int DoFinal(byte[] output, int outOff); public abstract IMemoable Copy(); public abstract void Reset(IMemoable t); } }