GeneralDigest.cs 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. #if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
  2. using System;
  3. using Org.BouncyCastle.Utilities;
  4. namespace Org.BouncyCastle.Crypto.Digests
  5. {
  6. /**
  7. * base implementation of MD4 family style digest as outlined in
  8. * "Handbook of Applied Cryptography", pages 344 - 347.
  9. */
  10. public abstract class GeneralDigest
  11. : IDigest, IMemoable
  12. {
  13. private const int BYTE_LENGTH = 64;
  14. private byte[] xBuf;
  15. private int xBufOff;
  16. private long byteCount;
  17. internal GeneralDigest()
  18. {
  19. xBuf = new byte[4];
  20. }
  21. internal GeneralDigest(GeneralDigest t)
  22. {
  23. xBuf = new byte[t.xBuf.Length];
  24. CopyIn(t);
  25. }
  26. protected void CopyIn(GeneralDigest t)
  27. {
  28. Array.Copy(t.xBuf, 0, xBuf, 0, t.xBuf.Length);
  29. xBufOff = t.xBufOff;
  30. byteCount = t.byteCount;
  31. }
  32. public void Update(byte input)
  33. {
  34. xBuf[xBufOff++] = input;
  35. if (xBufOff == xBuf.Length)
  36. {
  37. ProcessWord(xBuf, 0);
  38. xBufOff = 0;
  39. }
  40. byteCount++;
  41. }
  42. public void BlockUpdate(
  43. byte[] input,
  44. int inOff,
  45. int length)
  46. {
  47. length = System.Math.Max(0, length);
  48. //
  49. // fill the current word
  50. //
  51. int i = 0;
  52. if (xBufOff != 0)
  53. {
  54. while (i < length)
  55. {
  56. xBuf[xBufOff++] = input[inOff + i++];
  57. if (xBufOff == 4)
  58. {
  59. ProcessWord(xBuf, 0);
  60. xBufOff = 0;
  61. break;
  62. }
  63. }
  64. }
  65. //
  66. // process whole words.
  67. //
  68. int limit = ((length - i) & ~3) + i;
  69. for (; i < limit; i += 4)
  70. {
  71. ProcessWord(input, inOff + i);
  72. }
  73. //
  74. // load in the remainder.
  75. //
  76. while (i < length)
  77. {
  78. xBuf[xBufOff++] = input[inOff + i++];
  79. }
  80. byteCount += length;
  81. }
  82. public void Finish()
  83. {
  84. long bitLength = (byteCount << 3);
  85. //
  86. // add the pad bytes.
  87. //
  88. Update((byte)128);
  89. while (xBufOff != 0) Update((byte)0);
  90. ProcessLength(bitLength);
  91. ProcessBlock();
  92. }
  93. public virtual void Reset()
  94. {
  95. byteCount = 0;
  96. xBufOff = 0;
  97. Array.Clear(xBuf, 0, xBuf.Length);
  98. }
  99. public int GetByteLength()
  100. {
  101. return BYTE_LENGTH;
  102. }
  103. internal abstract void ProcessWord(byte[] input, int inOff);
  104. internal abstract void ProcessLength(long bitLength);
  105. internal abstract void ProcessBlock();
  106. public abstract string AlgorithmName { get; }
  107. public abstract int GetDigestSize();
  108. public abstract int DoFinal(byte[] output, int outOff);
  109. public abstract IMemoable Copy();
  110. public abstract void Reset(IMemoable t);
  111. }
  112. }
  113. #endif