Sha512tDigest.cs 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. #if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
  2. #pragma warning disable
  3. using System;
  4. using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Utilities;
  5. using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities;
  6. namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Digests
  7. {
  8. /**
  9. * FIPS 180-4 implementation of SHA-512/t
  10. */
  11. public class Sha512tDigest
  12. : LongDigest
  13. {
  14. private const ulong A5 = 0xa5a5a5a5a5a5a5a5UL;
  15. private readonly int digestLength;
  16. private ulong H1t, H2t, H3t, H4t, H5t, H6t, H7t, H8t;
  17. /**
  18. * Standard constructor
  19. */
  20. public Sha512tDigest(int bitLength)
  21. {
  22. if (bitLength >= 512)
  23. throw new ArgumentException("cannot be >= 512", "bitLength");
  24. if (bitLength % 8 != 0)
  25. throw new ArgumentException("needs to be a multiple of 8", "bitLength");
  26. if (bitLength == 384)
  27. throw new ArgumentException("cannot be 384 use SHA384 instead", "bitLength");
  28. this.digestLength = bitLength / 8;
  29. tIvGenerate(digestLength * 8);
  30. Reset();
  31. }
  32. /**
  33. * Copy constructor. This will copy the state of the provided
  34. * message digest.
  35. */
  36. public Sha512tDigest(Sha512tDigest t)
  37. : base(t)
  38. {
  39. this.digestLength = t.digestLength;
  40. Reset(t);
  41. }
  42. public override string AlgorithmName
  43. {
  44. get { return "SHA-512/" + (digestLength * 8); }
  45. }
  46. public override int GetDigestSize()
  47. {
  48. return digestLength;
  49. }
  50. public override int DoFinal(byte[] output, int outOff)
  51. {
  52. Finish();
  53. UInt64_To_BE(H1, output, outOff, digestLength);
  54. UInt64_To_BE(H2, output, outOff + 8, digestLength - 8);
  55. UInt64_To_BE(H3, output, outOff + 16, digestLength - 16);
  56. UInt64_To_BE(H4, output, outOff + 24, digestLength - 24);
  57. UInt64_To_BE(H5, output, outOff + 32, digestLength - 32);
  58. UInt64_To_BE(H6, output, outOff + 40, digestLength - 40);
  59. UInt64_To_BE(H7, output, outOff + 48, digestLength - 48);
  60. UInt64_To_BE(H8, output, outOff + 56, digestLength - 56);
  61. Reset();
  62. return digestLength;
  63. }
  64. /**
  65. * reset the chaining variables
  66. */
  67. public override void Reset()
  68. {
  69. base.Reset();
  70. /*
  71. * initial hash values use the iv generation algorithm for t.
  72. */
  73. H1 = H1t;
  74. H2 = H2t;
  75. H3 = H3t;
  76. H4 = H4t;
  77. H5 = H5t;
  78. H6 = H6t;
  79. H7 = H7t;
  80. H8 = H8t;
  81. }
  82. private void tIvGenerate(int bitLength)
  83. {
  84. H1 = 0x6a09e667f3bcc908UL ^ A5;
  85. H2 = 0xbb67ae8584caa73bUL ^ A5;
  86. H3 = 0x3c6ef372fe94f82bUL ^ A5;
  87. H4 = 0xa54ff53a5f1d36f1UL ^ A5;
  88. H5 = 0x510e527fade682d1UL ^ A5;
  89. H6 = 0x9b05688c2b3e6c1fUL ^ A5;
  90. H7 = 0x1f83d9abfb41bd6bUL ^ A5;
  91. H8 = 0x5be0cd19137e2179UL ^ A5;
  92. Update(0x53);
  93. Update(0x48);
  94. Update(0x41);
  95. Update(0x2D);
  96. Update(0x35);
  97. Update(0x31);
  98. Update(0x32);
  99. Update(0x2F);
  100. if (bitLength > 100)
  101. {
  102. Update((byte)(bitLength / 100 + 0x30));
  103. bitLength = bitLength % 100;
  104. Update((byte)(bitLength / 10 + 0x30));
  105. bitLength = bitLength % 10;
  106. Update((byte)(bitLength + 0x30));
  107. }
  108. else if (bitLength > 10)
  109. {
  110. Update((byte)(bitLength / 10 + 0x30));
  111. bitLength = bitLength % 10;
  112. Update((byte)(bitLength + 0x30));
  113. }
  114. else
  115. {
  116. Update((byte)(bitLength + 0x30));
  117. }
  118. Finish();
  119. H1t = H1;
  120. H2t = H2;
  121. H3t = H3;
  122. H4t = H4;
  123. H5t = H5;
  124. H6t = H6;
  125. H7t = H7;
  126. H8t = H8;
  127. }
  128. private static void UInt64_To_BE(ulong n, byte[] bs, int off, int max)
  129. {
  130. if (max > 0)
  131. {
  132. UInt32_To_BE((uint)(n >> 32), bs, off, max);
  133. if (max > 4)
  134. {
  135. UInt32_To_BE((uint)n, bs, off + 4, max - 4);
  136. }
  137. }
  138. }
  139. private static void UInt32_To_BE(uint n, byte[] bs, int off, int max)
  140. {
  141. int num = System.Math.Min(4, max);
  142. while (--num >= 0)
  143. {
  144. int shift = 8 * (3 - num);
  145. bs[off + num] = (byte)(n >> shift);
  146. }
  147. }
  148. public override IMemoable Copy()
  149. {
  150. return new Sha512tDigest(this);
  151. }
  152. public override void Reset(IMemoable other)
  153. {
  154. Sha512tDigest t = (Sha512tDigest)other;
  155. if (this.digestLength != t.digestLength)
  156. {
  157. throw new MemoableResetException("digestLength inappropriate in other");
  158. }
  159. base.CopyIn(t);
  160. this.H1t = t.H1t;
  161. this.H2t = t.H2t;
  162. this.H3t = t.H3t;
  163. this.H4t = t.H4t;
  164. this.H5t = t.H5t;
  165. this.H6t = t.H6t;
  166. this.H7t = t.H7t;
  167. this.H8t = t.H8t;
  168. }
  169. }
  170. }
  171. #pragma warning restore
  172. #endif