ShortenedDigest.cs 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. #if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
  2. #pragma warning disable
  3. using System;
  4. namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Digests
  5. {
  6. /**
  7. * Wrapper class that reduces the output length of a particular digest to
  8. * only the first n bytes of the digest function.
  9. */
  10. public class ShortenedDigest
  11. : IDigest
  12. {
  13. private IDigest baseDigest;
  14. private int length;
  15. /**
  16. * Base constructor.
  17. *
  18. * @param baseDigest underlying digest to use.
  19. * @param length length in bytes of the output of doFinal.
  20. * @exception ArgumentException if baseDigest is null, or length is greater than baseDigest.GetDigestSize().
  21. */
  22. public ShortenedDigest(
  23. IDigest baseDigest,
  24. int length)
  25. {
  26. if (baseDigest == null)
  27. {
  28. throw new ArgumentNullException("baseDigest");
  29. }
  30. if (length > baseDigest.GetDigestSize())
  31. {
  32. throw new ArgumentException("baseDigest output not large enough to support length");
  33. }
  34. this.baseDigest = baseDigest;
  35. this.length = length;
  36. }
  37. public string AlgorithmName
  38. {
  39. get { return baseDigest.AlgorithmName + "(" + length * 8 + ")"; }
  40. }
  41. public int GetDigestSize()
  42. {
  43. return length;
  44. }
  45. public void Update(byte input)
  46. {
  47. baseDigest.Update(input);
  48. }
  49. public void BlockUpdate(byte[] input, int inOff, int length)
  50. {
  51. baseDigest.BlockUpdate(input, inOff, length);
  52. }
  53. #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
  54. public void BlockUpdate(ReadOnlySpan<byte> input)
  55. {
  56. baseDigest.BlockUpdate(input);
  57. }
  58. #endif
  59. public int DoFinal(byte[] output, int outOff)
  60. {
  61. byte[] tmp = new byte[baseDigest.GetDigestSize()];
  62. baseDigest.DoFinal(tmp, 0);
  63. Array.Copy(tmp, 0, output, outOff, length);
  64. return length;
  65. }
  66. #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
  67. public int DoFinal(Span<byte> output)
  68. {
  69. int baseDigestSize = baseDigest.GetDigestSize();
  70. Span<byte> tmp = baseDigestSize <= 128
  71. ? stackalloc byte[baseDigestSize]
  72. : new byte[baseDigestSize];
  73. baseDigest.DoFinal(tmp);
  74. tmp[..length].CopyTo(output);
  75. return length;
  76. }
  77. #endif
  78. public void Reset()
  79. {
  80. baseDigest.Reset();
  81. }
  82. public int GetByteLength()
  83. {
  84. return baseDigest.GetByteLength();
  85. }
  86. }
  87. }
  88. #pragma warning restore
  89. #endif