Haraka256Digest.cs 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  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. public sealed class Haraka256Digest
  7. : HarakaBase
  8. {
  9. private readonly byte[] m_buf;
  10. private int m_bufPos;
  11. public Haraka256Digest()
  12. {
  13. m_buf = new byte[32];
  14. m_bufPos = 0;
  15. }
  16. public override string AlgorithmName => "Haraka-256";
  17. public override int GetByteLength() => 32;
  18. public override void Update(byte input)
  19. {
  20. if (m_bufPos > 32 - 1)
  21. throw new ArgumentException("total input cannot be more than 32 bytes");
  22. m_buf[m_bufPos++] = input;
  23. }
  24. public override void BlockUpdate(byte[] input, int inOff, int len)
  25. {
  26. if (m_bufPos > 32 - len)
  27. throw new ArgumentException("total input cannot be more than 32 bytes");
  28. Array.Copy(input, inOff, m_buf, m_bufPos, len);
  29. m_bufPos += len;
  30. }
  31. #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
  32. public override void BlockUpdate(ReadOnlySpan<byte> input)
  33. {
  34. if (m_bufPos > 32 - input.Length)
  35. throw new ArgumentException("total input cannot be more than 32 bytes");
  36. input.CopyTo(m_buf.AsSpan(m_bufPos));
  37. m_bufPos += input.Length;
  38. }
  39. #endif
  40. public override int DoFinal(byte[] output, int outOff)
  41. {
  42. #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
  43. return DoFinal(output.AsSpan(outOff));
  44. #else
  45. if (m_bufPos != 32)
  46. throw new ArgumentException("input must be exactly 32 bytes");
  47. if (output.Length - outOff < 32)
  48. throw new ArgumentException("output too short to receive digest");
  49. int rv = Haraka256256(m_buf, output, outOff);
  50. Reset();
  51. return rv;
  52. #endif
  53. }
  54. #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
  55. public override int DoFinal(Span<byte> output)
  56. {
  57. if (m_bufPos != 32)
  58. throw new ArgumentException("input must be exactly 32 bytes");
  59. if (output.Length < 32)
  60. throw new ArgumentException("output too short to receive digest");
  61. #if NETCOREAPP3_0_OR_GREATER
  62. if (Haraka256_X86.IsSupported)
  63. {
  64. Haraka256_X86.Hash(m_buf, output);
  65. Reset();
  66. return 32;
  67. }
  68. #endif
  69. int rv = Haraka256256(m_buf, output);
  70. Reset();
  71. return rv;
  72. }
  73. #endif
  74. public override void Reset()
  75. {
  76. m_bufPos = 0;
  77. Array.Clear(m_buf, 0, 32);
  78. }
  79. #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
  80. private static int Haraka256256(ReadOnlySpan<byte> msg, Span<byte> output)
  81. {
  82. byte[][] s1 = new byte[2][];
  83. s1[0] = new byte[16];
  84. s1[1] = new byte[16];
  85. byte[][] s2 = new byte[2][];
  86. s2[0] = new byte[16];
  87. s2[1] = new byte[16];
  88. msg[ ..16].CopyTo(s1[0]);
  89. msg[16..32].CopyTo(s1[1]);
  90. s1[0] = AesEnc(s1[0], RC[0]);
  91. s1[1] = AesEnc(s1[1], RC[1]);
  92. s1[0] = AesEnc(s1[0], RC[2]);
  93. s1[1] = AesEnc(s1[1], RC[3]);
  94. Mix256(s1, s2);
  95. s1[0] = AesEnc(s2[0], RC[4]);
  96. s1[1] = AesEnc(s2[1], RC[5]);
  97. s1[0] = AesEnc(s1[0], RC[6]);
  98. s1[1] = AesEnc(s1[1], RC[7]);
  99. Mix256(s1, s2);
  100. s1[0] = AesEnc(s2[0], RC[8]);
  101. s1[1] = AesEnc(s2[1], RC[9]);
  102. s1[0] = AesEnc(s1[0], RC[10]);
  103. s1[1] = AesEnc(s1[1], RC[11]);
  104. Mix256(s1, s2);
  105. s1[0] = AesEnc(s2[0], RC[12]);
  106. s1[1] = AesEnc(s2[1], RC[13]);
  107. s1[0] = AesEnc(s1[0], RC[14]);
  108. s1[1] = AesEnc(s1[1], RC[15]);
  109. Mix256(s1, s2);
  110. s1[0] = AesEnc(s2[0], RC[16]);
  111. s1[1] = AesEnc(s2[1], RC[17]);
  112. s1[0] = AesEnc(s1[0], RC[18]);
  113. s1[1] = AesEnc(s1[1], RC[19]);
  114. Mix256(s1, s2);
  115. Xor(s2[0], msg , output[ ..16]);
  116. Xor(s2[1], msg[16..], output[16..32]);
  117. return DIGEST_SIZE;
  118. }
  119. #else
  120. private static int Haraka256256(byte[] msg, byte[] output, int outOff)
  121. {
  122. byte[][] s1 = new byte[2][];
  123. s1[0] = new byte[16];
  124. s1[1] = new byte[16];
  125. byte[][] s2 = new byte[2][];
  126. s2[0] = new byte[16];
  127. s2[1] = new byte[16];
  128. Array.Copy(msg, 0, s1[0], 0, 16);
  129. Array.Copy(msg, 16, s1[1], 0, 16);
  130. s1[0] = AesEnc(s1[0], RC[0]);
  131. s1[1] = AesEnc(s1[1], RC[1]);
  132. s1[0] = AesEnc(s1[0], RC[2]);
  133. s1[1] = AesEnc(s1[1], RC[3]);
  134. Mix256(s1, s2);
  135. s1[0] = AesEnc(s2[0], RC[4]);
  136. s1[1] = AesEnc(s2[1], RC[5]);
  137. s1[0] = AesEnc(s1[0], RC[6]);
  138. s1[1] = AesEnc(s1[1], RC[7]);
  139. Mix256(s1, s2);
  140. s1[0] = AesEnc(s2[0], RC[8]);
  141. s1[1] = AesEnc(s2[1], RC[9]);
  142. s1[0] = AesEnc(s1[0], RC[10]);
  143. s1[1] = AesEnc(s1[1], RC[11]);
  144. Mix256(s1, s2);
  145. s1[0] = AesEnc(s2[0], RC[12]);
  146. s1[1] = AesEnc(s2[1], RC[13]);
  147. s1[0] = AesEnc(s1[0], RC[14]);
  148. s1[1] = AesEnc(s1[1], RC[15]);
  149. Mix256(s1, s2);
  150. s1[0] = AesEnc(s2[0], RC[16]);
  151. s1[1] = AesEnc(s2[1], RC[17]);
  152. s1[0] = AesEnc(s1[0], RC[18]);
  153. s1[1] = AesEnc(s1[1], RC[19]);
  154. Mix256(s1, s2);
  155. s1[0] = Xor(s2[0], msg, 0);
  156. s1[1] = Xor(s2[1], msg, 16);
  157. Array.Copy(s1[0], 0, output, outOff , 16);
  158. Array.Copy(s1[1], 0, output, outOff + 16, 16);
  159. return DIGEST_SIZE;
  160. }
  161. #endif
  162. private static void Mix256(byte[][] s1, byte[][] s2)
  163. {
  164. Array.Copy(s1[0], 0, s2[0], 0, 4);
  165. Array.Copy(s1[1], 0, s2[0], 4, 4);
  166. Array.Copy(s1[0], 4, s2[0], 8, 4);
  167. Array.Copy(s1[1], 4, s2[0], 12, 4);
  168. Array.Copy(s1[0], 8, s2[1], 0, 4);
  169. Array.Copy(s1[1], 8, s2[1], 4, 4);
  170. Array.Copy(s1[0], 12, s2[1], 8, 4);
  171. Array.Copy(s1[1], 12, s2[1], 12, 4);
  172. }
  173. }
  174. }
  175. #pragma warning restore
  176. #endif