| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187 |
- #if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
- #pragma warning disable
- using System;
- using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities;
- namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Digests
- {
- /**
- * base implementation of MD4 family style digest as outlined in
- * "Handbook of Applied Cryptography", pages 344 - 347.
- */
- public abstract class GeneralDigest
- : IDigest, IMemoable
- {
- private const int BYTE_LENGTH = 64;
- private byte[] xBuf;
- private int xBufOff;
- private long byteCount;
- internal GeneralDigest()
- {
- xBuf = new byte[4];
- }
- internal GeneralDigest(GeneralDigest t)
- {
- xBuf = new byte[t.xBuf.Length];
- CopyIn(t);
- }
- protected void CopyIn(GeneralDigest t)
- {
- Array.Copy(t.xBuf, 0, xBuf, 0, t.xBuf.Length);
- xBufOff = t.xBufOff;
- byteCount = t.byteCount;
- }
- public void Update(byte input)
- {
- xBuf[xBufOff++] = input;
- if (xBufOff == xBuf.Length)
- {
- ProcessWord(xBuf, 0);
- xBufOff = 0;
- }
- byteCount++;
- }
- public void BlockUpdate(
- byte[] input,
- int inOff,
- int length)
- {
- length = System.Math.Max(0, length);
- //
- // fill the current word
- //
- int i = 0;
- if (xBufOff != 0)
- {
- while (i < length)
- {
- xBuf[xBufOff++] = input[inOff + i++];
- if (xBufOff == 4)
- {
- ProcessWord(xBuf, 0);
- xBufOff = 0;
- break;
- }
- }
- }
- //
- // process whole words.
- //
- int limit = length - 3;
- for (; i < limit; i += 4)
- {
- ProcessWord(input, inOff + i);
- }
- //
- // load in the remainder.
- //
- while (i < length)
- {
- xBuf[xBufOff++] = input[inOff + i++];
- }
- byteCount += length;
- }
- #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || _UNITY_2021_2_OR_NEWER_
- public void BlockUpdate(ReadOnlySpan<byte> input)
- {
- int length = input.Length;
- //
- // fill the current word
- //
- int i = 0;
- if (xBufOff != 0)
- {
- while (i < length)
- {
- xBuf[xBufOff++] = input[i++];
- if (xBufOff == 4)
- {
- ProcessWord(xBuf, 0);
- xBufOff = 0;
- break;
- }
- }
- }
- //
- // process whole words.
- //
- int limit = length - 3;
- for (; i < limit; i += 4)
- {
- ProcessWord(input.Slice(i, 4));
- }
- //
- // load in the remainder.
- //
- while (i < length)
- {
- xBuf[xBufOff++] = input[i++];
- }
- byteCount += length;
- }
- #endif
- public void Finish()
- {
- long bitLength = (byteCount << 3);
- //
- // add the pad bytes.
- //
- Update((byte)128);
- while (xBufOff != 0) Update((byte)0);
- ProcessLength(bitLength);
- ProcessBlock();
- }
- public virtual void Reset()
- {
- byteCount = 0;
- xBufOff = 0;
- Array.Clear(xBuf, 0, xBuf.Length);
- }
- public int GetByteLength()
- {
- return BYTE_LENGTH;
- }
- internal abstract void ProcessWord(byte[] input, int inOff);
- #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || _UNITY_2021_2_OR_NEWER_
- internal abstract void ProcessWord(ReadOnlySpan<byte> word);
- #endif
- internal abstract void ProcessLength(long bitLength);
- internal abstract void ProcessBlock();
- public abstract string AlgorithmName { get; }
- public abstract int GetDigestSize();
- public abstract int DoFinal(byte[] output, int outOff);
- public abstract IMemoable Copy();
- public abstract void Reset(IMemoable t);
- #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || _UNITY_2021_2_OR_NEWER_
- public abstract int DoFinal(Span<byte> output);
- #endif
- }
- }
- #pragma warning restore
- #endif
|