DSTU7564Digest.cs 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631
  1. #if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
  2. #pragma warning disable
  3. using System;
  4. using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Utilities;
  5. using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities;
  6. namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Digests
  7. {
  8. /**
  9. * implementation of Ukrainian DSTU 7564 hash function
  10. */
  11. public class Dstu7564Digest
  12. : IDigest, IMemoable
  13. {
  14. private const int NB_512 = 8; //Number of 8-byte words in state for <=256-bit hash code.
  15. private const int NB_1024 = 16; //Number of 8-byte words in state for <=512-bit hash code.
  16. private const int NR_512 = 10; //Number of rounds for 512-bit state.
  17. private const int NR_1024 = 14; //Number of rounds for 1024-bit state.
  18. private int hashSize;
  19. private int blockSize;
  20. private int columns;
  21. private int rounds;
  22. private ulong[] state;
  23. private ulong[] tempState1;
  24. private ulong[] tempState2;
  25. // TODO Guard against 'inputBlocks' overflow (2^64 blocks)
  26. private ulong inputBlocks;
  27. private int bufOff;
  28. private byte[] buf;
  29. public Dstu7564Digest(Dstu7564Digest digest)
  30. {
  31. CopyIn(digest);
  32. }
  33. private void CopyIn(Dstu7564Digest digest)
  34. {
  35. this.hashSize = digest.hashSize;
  36. this.blockSize = digest.blockSize;
  37. this.rounds = digest.rounds;
  38. if (columns > 0 && columns == digest.columns)
  39. {
  40. Array.Copy(digest.state, 0, state, 0, columns);
  41. Array.Copy(digest.buf, 0, buf, 0, blockSize);
  42. }
  43. else
  44. {
  45. this.columns = digest.columns;
  46. this.state = Arrays.Clone(digest.state);
  47. this.tempState1 = new ulong[columns];
  48. this.tempState2 = new ulong[columns];
  49. this.buf = Arrays.Clone(digest.buf);
  50. }
  51. this.inputBlocks = digest.inputBlocks;
  52. this.bufOff = digest.bufOff;
  53. }
  54. public Dstu7564Digest(int hashSizeBits)
  55. {
  56. if (hashSizeBits == 256 || hashSizeBits == 384 || hashSizeBits == 512)
  57. {
  58. this.hashSize = hashSizeBits / 8;
  59. }
  60. else
  61. {
  62. throw new ArgumentException("Hash size is not recommended. Use 256/384/512 instead");
  63. }
  64. if (hashSizeBits > 256)
  65. {
  66. this.columns = NB_1024;
  67. this.rounds = NR_1024;
  68. }
  69. else
  70. {
  71. this.columns = NB_512;
  72. this.rounds = NR_512;
  73. }
  74. this.blockSize = columns << 3;
  75. this.state = new ulong[columns];
  76. this.state[0] = (ulong)blockSize;
  77. this.tempState1 = new ulong[columns];
  78. this.tempState2 = new ulong[columns];
  79. this.buf = new byte[blockSize];
  80. }
  81. public virtual string AlgorithmName
  82. {
  83. get { return "DSTU7564"; }
  84. }
  85. public virtual int GetDigestSize()
  86. {
  87. return hashSize;
  88. }
  89. public virtual int GetByteLength()
  90. {
  91. return blockSize;
  92. }
  93. public virtual void Update(byte input)
  94. {
  95. buf[bufOff++] = input;
  96. if (bufOff == blockSize)
  97. {
  98. ProcessBlock(buf, 0);
  99. bufOff = 0;
  100. ++inputBlocks;
  101. }
  102. }
  103. public virtual void BlockUpdate(byte[] input, int inOff, int length)
  104. {
  105. while (bufOff != 0 && length > 0)
  106. {
  107. Update(input[inOff++]);
  108. --length;
  109. }
  110. while (length >= blockSize)
  111. {
  112. ProcessBlock(input, inOff);
  113. inOff += blockSize;
  114. length -= blockSize;
  115. ++inputBlocks;
  116. }
  117. while (length > 0)
  118. {
  119. Update(input[inOff++]);
  120. --length;
  121. }
  122. }
  123. #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
  124. public virtual void BlockUpdate(ReadOnlySpan<byte> input)
  125. {
  126. while (bufOff != 0 && input.Length > 0)
  127. {
  128. Update(input[0]);
  129. input = input[1..];
  130. }
  131. while (input.Length >= blockSize)
  132. {
  133. ProcessBlock(input);
  134. input = input[blockSize..];
  135. ++inputBlocks;
  136. }
  137. while (input.Length > 0)
  138. {
  139. Update(input[0]);
  140. input = input[1..];
  141. }
  142. }
  143. #endif
  144. public virtual int DoFinal(byte[] output, int outOff)
  145. {
  146. // Apply padding: terminator byte and 96-bit length field
  147. {
  148. int inputBytes = bufOff;
  149. buf[bufOff++] = (byte)0x80;
  150. int lenPos = blockSize - 12;
  151. if (bufOff > lenPos)
  152. {
  153. while (bufOff < blockSize)
  154. {
  155. buf[bufOff++] = 0;
  156. }
  157. bufOff = 0;
  158. ProcessBlock(buf, 0);
  159. }
  160. while (bufOff < lenPos)
  161. {
  162. buf[bufOff++] = 0;
  163. }
  164. ulong c = ((inputBlocks & 0xFFFFFFFFUL) * (ulong)blockSize + (uint)inputBytes) << 3;
  165. Pack.UInt32_To_LE((uint)c, buf, bufOff);
  166. bufOff += 4;
  167. c >>= 32;
  168. c += ((inputBlocks >> 32) * (ulong)blockSize) << 3;
  169. Pack.UInt64_To_LE(c, buf, bufOff);
  170. //bufOff += 8;
  171. ProcessBlock(buf, 0);
  172. }
  173. {
  174. Array.Copy(state, 0, tempState1, 0, columns);
  175. P(tempState1);
  176. for (int col = 0; col < columns; ++col)
  177. {
  178. state[col] ^= tempState1[col];
  179. }
  180. }
  181. int neededColumns = hashSize / 8;
  182. for (int col = columns - neededColumns; col < columns; ++col)
  183. {
  184. Pack.UInt64_To_LE(state[col], output, outOff);
  185. outOff += 8;
  186. }
  187. Reset();
  188. return hashSize;
  189. }
  190. #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
  191. public virtual int DoFinal(Span<byte> output)
  192. {
  193. // Apply padding: terminator byte and 96-bit length field
  194. {
  195. int inputBytes = bufOff;
  196. buf[bufOff++] = (byte)0x80;
  197. int lenPos = blockSize - 12;
  198. if (bufOff > lenPos)
  199. {
  200. while (bufOff < blockSize)
  201. {
  202. buf[bufOff++] = 0;
  203. }
  204. bufOff = 0;
  205. ProcessBlock(buf, 0);
  206. }
  207. while (bufOff < lenPos)
  208. {
  209. buf[bufOff++] = 0;
  210. }
  211. ulong c = ((inputBlocks & 0xFFFFFFFFUL) * (ulong)blockSize + (uint)inputBytes) << 3;
  212. Pack.UInt32_To_LE((uint)c, buf, bufOff);
  213. bufOff += 4;
  214. c >>= 32;
  215. c += ((inputBlocks >> 32) * (ulong)blockSize) << 3;
  216. Pack.UInt64_To_LE(c, buf, bufOff);
  217. //bufOff += 8;
  218. ProcessBlock(buf, 0);
  219. }
  220. {
  221. Array.Copy(state, 0, tempState1, 0, columns);
  222. P(tempState1);
  223. for (int col = 0; col < columns; ++col)
  224. {
  225. state[col] ^= tempState1[col];
  226. }
  227. }
  228. int neededColumns = hashSize / 8;
  229. for (int col = columns - neededColumns; col < columns; ++col)
  230. {
  231. Pack.UInt64_To_LE(state[col], output);
  232. output = output[8..];
  233. }
  234. Reset();
  235. return hashSize;
  236. }
  237. #endif
  238. public virtual void Reset()
  239. {
  240. Array.Clear(state, 0, state.Length);
  241. state[0] = (ulong)blockSize;
  242. inputBlocks = 0;
  243. bufOff = 0;
  244. }
  245. protected virtual void ProcessBlock(byte[] input, int inOff)
  246. {
  247. int pos = inOff;
  248. for (int col = 0; col < columns; ++col)
  249. {
  250. ulong word = Pack.LE_To_UInt64(input, pos);
  251. pos += 8;
  252. tempState1[col] = state[col] ^ word;
  253. tempState2[col] = word;
  254. }
  255. P(tempState1);
  256. Q(tempState2);
  257. for (int col = 0; col < columns; ++col)
  258. {
  259. state[col] ^= tempState1[col] ^ tempState2[col];
  260. }
  261. }
  262. #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
  263. protected virtual void ProcessBlock(ReadOnlySpan<byte> input)
  264. {
  265. for (int col = 0; col < columns; ++col)
  266. {
  267. ulong word = Pack.LE_To_UInt64(input);
  268. input = input[8..];
  269. tempState1[col] = state[col] ^ word;
  270. tempState2[col] = word;
  271. }
  272. P(tempState1);
  273. Q(tempState2);
  274. for (int col = 0; col < columns; ++col)
  275. {
  276. state[col] ^= tempState1[col] ^ tempState2[col];
  277. }
  278. }
  279. #endif
  280. private void P(ulong[] s)
  281. {
  282. for (int round = 0; round < rounds; ++round)
  283. {
  284. ulong rc = (ulong)round;
  285. /* AddRoundConstants */
  286. for (int col = 0; col < columns; ++col)
  287. {
  288. s[col] ^= rc;
  289. rc += 0x10L;
  290. }
  291. ShiftRows(s);
  292. SubBytes(s);
  293. MixColumns(s);
  294. }
  295. }
  296. private void Q(ulong[] s)
  297. {
  298. for (int round = 0; round < rounds; ++round)
  299. {
  300. /* AddRoundConstantsQ */
  301. ulong rc = ((ulong)(((columns - 1) << 4) ^ round) << 56) | 0x00F0F0F0F0F0F0F3UL;
  302. for (int col = 0; col < columns; ++col)
  303. {
  304. s[col] += rc;
  305. rc -= 0x1000000000000000L;
  306. }
  307. ShiftRows(s);
  308. SubBytes(s);
  309. MixColumns(s);
  310. }
  311. }
  312. private static ulong MixColumn(ulong c)
  313. {
  314. //// Calculate column multiplied by powers of 'x'
  315. //ulong x0 = c;
  316. //ulong x1 = ((x0 & 0x7F7F7F7F7F7F7F7FUL) << 1) ^ (((x0 & 0x8080808080808080UL) >> 7) * 0x1DUL);
  317. //ulong x2 = ((x1 & 0x7F7F7F7F7F7F7F7FUL) << 1) ^ (((x1 & 0x8080808080808080UL) >> 7) * 0x1DUL);
  318. //ulong x3 = ((x2 & 0x7F7F7F7F7F7F7F7FUL) << 1) ^ (((x2 & 0x8080808080808080UL) >> 7) * 0x1DUL);
  319. //// Calculate products with circulant matrix from (0x01, 0x01, 0x05, 0x01, 0x08, 0x06, 0x07, 0x04)
  320. //ulong m0 = x0;
  321. //ulong m1 = x0;
  322. //ulong m2 = x0 ^ x2;
  323. //ulong m3 = x0;
  324. //ulong m4 = x3;
  325. //ulong m5 = x1 ^ x2;
  326. //ulong m6 = x0 ^ x1 ^ x2;
  327. //ulong m7 = x2;
  328. //// Assemble the rotated products
  329. //return m0
  330. // ^ Rotate(8, m1)
  331. // ^ Rotate(16, m2)
  332. // ^ Rotate(24, m3)
  333. // ^ Rotate(32, m4)
  334. // ^ Rotate(40, m5)
  335. // ^ Rotate(48, m6)
  336. // ^ Rotate(56, m7);
  337. // Multiply elements by 'x'
  338. ulong x1 = ((c & 0x7F7F7F7F7F7F7F7FUL) << 1) ^ (((c & 0x8080808080808080UL) >> 7) * 0x1DUL);
  339. ulong u, v;
  340. u = Rotate(8, c) ^ c;
  341. u ^= Rotate(16, u);
  342. u ^= Rotate(48, c);
  343. v = u ^ c ^ x1;
  344. // Multiply elements by 'x^2'
  345. v = ((v & 0x3F3F3F3F3F3F3F3FUL) << 2) ^ (((v & 0x8080808080808080UL) >> 6) * 0x1DUL) ^ (((v & 0x4040404040404040UL) >> 6) * 0x1DUL);
  346. return u ^ Rotate(32, v) ^ Rotate(40, x1) ^ Rotate(48, x1);
  347. }
  348. private void MixColumns(ulong[] s)
  349. {
  350. for (int col = 0; col < columns; ++col)
  351. {
  352. s[col] = MixColumn(s[col]);
  353. }
  354. }
  355. private static ulong Rotate(int n, ulong x)
  356. {
  357. return (x >> n) | (x << -n);
  358. }
  359. private void ShiftRows(ulong[] s)
  360. {
  361. switch (columns)
  362. {
  363. case NB_512:
  364. {
  365. ulong c0 = s[0], c1 = s[1], c2 = s[2], c3 = s[3];
  366. ulong c4 = s[4], c5 = s[5], c6 = s[6], c7 = s[7];
  367. ulong d;
  368. d = (c0 ^ c4) & 0xFFFFFFFF00000000UL; c0 ^= d; c4 ^= d;
  369. d = (c1 ^ c5) & 0x00FFFFFFFF000000UL; c1 ^= d; c5 ^= d;
  370. d = (c2 ^ c6) & 0x0000FFFFFFFF0000UL; c2 ^= d; c6 ^= d;
  371. d = (c3 ^ c7) & 0x000000FFFFFFFF00UL; c3 ^= d; c7 ^= d;
  372. d = (c0 ^ c2) & 0xFFFF0000FFFF0000UL; c0 ^= d; c2 ^= d;
  373. d = (c1 ^ c3) & 0x00FFFF0000FFFF00UL; c1 ^= d; c3 ^= d;
  374. d = (c4 ^ c6) & 0xFFFF0000FFFF0000UL; c4 ^= d; c6 ^= d;
  375. d = (c5 ^ c7) & 0x00FFFF0000FFFF00UL; c5 ^= d; c7 ^= d;
  376. d = (c0 ^ c1) & 0xFF00FF00FF00FF00UL; c0 ^= d; c1 ^= d;
  377. d = (c2 ^ c3) & 0xFF00FF00FF00FF00UL; c2 ^= d; c3 ^= d;
  378. d = (c4 ^ c5) & 0xFF00FF00FF00FF00UL; c4 ^= d; c5 ^= d;
  379. d = (c6 ^ c7) & 0xFF00FF00FF00FF00UL; c6 ^= d; c7 ^= d;
  380. s[0] = c0; s[1] = c1; s[2] = c2; s[3] = c3;
  381. s[4] = c4; s[5] = c5; s[6] = c6; s[7] = c7;
  382. break;
  383. }
  384. case NB_1024:
  385. {
  386. ulong c00 = s[0], c01 = s[1], c02 = s[2], c03 = s[3];
  387. ulong c04 = s[4], c05 = s[5], c06 = s[6], c07 = s[7];
  388. ulong c08 = s[8], c09 = s[9], c10 = s[10], c11 = s[11];
  389. ulong c12 = s[12], c13 = s[13], c14 = s[14], c15 = s[15];
  390. ulong d;
  391. // NOTE: Row 7 is shifted by 11
  392. d = (c00 ^ c08) & 0xFF00000000000000UL; c00 ^= d; c08 ^= d;
  393. d = (c01 ^ c09) & 0xFF00000000000000UL; c01 ^= d; c09 ^= d;
  394. d = (c02 ^ c10) & 0xFFFF000000000000UL; c02 ^= d; c10 ^= d;
  395. d = (c03 ^ c11) & 0xFFFFFF0000000000UL; c03 ^= d; c11 ^= d;
  396. d = (c04 ^ c12) & 0xFFFFFFFF00000000UL; c04 ^= d; c12 ^= d;
  397. d = (c05 ^ c13) & 0x00FFFFFFFF000000UL; c05 ^= d; c13 ^= d;
  398. d = (c06 ^ c14) & 0x00FFFFFFFFFF0000UL; c06 ^= d; c14 ^= d;
  399. d = (c07 ^ c15) & 0x00FFFFFFFFFFFF00UL; c07 ^= d; c15 ^= d;
  400. d = (c00 ^ c04) & 0x00FFFFFF00000000UL; c00 ^= d; c04 ^= d;
  401. d = (c01 ^ c05) & 0xFFFFFFFFFF000000UL; c01 ^= d; c05 ^= d;
  402. d = (c02 ^ c06) & 0xFF00FFFFFFFF0000UL; c02 ^= d; c06 ^= d;
  403. d = (c03 ^ c07) & 0xFF0000FFFFFFFF00UL; c03 ^= d; c07 ^= d;
  404. d = (c08 ^ c12) & 0x00FFFFFF00000000UL; c08 ^= d; c12 ^= d;
  405. d = (c09 ^ c13) & 0xFFFFFFFFFF000000UL; c09 ^= d; c13 ^= d;
  406. d = (c10 ^ c14) & 0xFF00FFFFFFFF0000UL; c10 ^= d; c14 ^= d;
  407. d = (c11 ^ c15) & 0xFF0000FFFFFFFF00UL; c11 ^= d; c15 ^= d;
  408. d = (c00 ^ c02) & 0xFFFF0000FFFF0000UL; c00 ^= d; c02 ^= d;
  409. d = (c01 ^ c03) & 0x00FFFF0000FFFF00UL; c01 ^= d; c03 ^= d;
  410. d = (c04 ^ c06) & 0xFFFF0000FFFF0000UL; c04 ^= d; c06 ^= d;
  411. d = (c05 ^ c07) & 0x00FFFF0000FFFF00UL; c05 ^= d; c07 ^= d;
  412. d = (c08 ^ c10) & 0xFFFF0000FFFF0000UL; c08 ^= d; c10 ^= d;
  413. d = (c09 ^ c11) & 0x00FFFF0000FFFF00UL; c09 ^= d; c11 ^= d;
  414. d = (c12 ^ c14) & 0xFFFF0000FFFF0000UL; c12 ^= d; c14 ^= d;
  415. d = (c13 ^ c15) & 0x00FFFF0000FFFF00UL; c13 ^= d; c15 ^= d;
  416. d = (c00 ^ c01) & 0xFF00FF00FF00FF00UL; c00 ^= d; c01 ^= d;
  417. d = (c02 ^ c03) & 0xFF00FF00FF00FF00UL; c02 ^= d; c03 ^= d;
  418. d = (c04 ^ c05) & 0xFF00FF00FF00FF00UL; c04 ^= d; c05 ^= d;
  419. d = (c06 ^ c07) & 0xFF00FF00FF00FF00UL; c06 ^= d; c07 ^= d;
  420. d = (c08 ^ c09) & 0xFF00FF00FF00FF00UL; c08 ^= d; c09 ^= d;
  421. d = (c10 ^ c11) & 0xFF00FF00FF00FF00UL; c10 ^= d; c11 ^= d;
  422. d = (c12 ^ c13) & 0xFF00FF00FF00FF00UL; c12 ^= d; c13 ^= d;
  423. d = (c14 ^ c15) & 0xFF00FF00FF00FF00UL; c14 ^= d; c15 ^= d;
  424. s[0] = c00; s[1] = c01; s[2] = c02; s[3] = c03;
  425. s[4] = c04; s[5] = c05; s[6] = c06; s[7] = c07;
  426. s[8] = c08; s[9] = c09; s[10] = c10; s[11] = c11;
  427. s[12] = c12; s[13] = c13; s[14] = c14; s[15] = c15;
  428. break;
  429. }
  430. default:
  431. {
  432. throw new InvalidOperationException("unsupported state size: only 512/1024 are allowed");
  433. }
  434. }
  435. }
  436. private void SubBytes(ulong[] s)
  437. {
  438. for (int i = 0; i < columns; ++i)
  439. {
  440. ulong u = s[i];
  441. uint lo = (uint)u, hi = (uint)(u >> 32);
  442. byte t0 = S0[lo & 0xFF];
  443. byte t1 = S1[(lo >> 8) & 0xFF];
  444. byte t2 = S2[(lo >> 16) & 0xFF];
  445. byte t3 = S3[lo >> 24];
  446. lo = (uint)t0 | ((uint)t1 << 8) | ((uint)t2 << 16) | ((uint)t3 << 24);
  447. byte t4 = S0[hi & 0xFF];
  448. byte t5 = S1[(hi >> 8) & 0xFF];
  449. byte t6 = S2[(hi >> 16) & 0xFF];
  450. byte t7 = S3[hi >> 24];
  451. hi = (uint)t4 | ((uint)t5 << 8) | ((uint)t6 << 16) | ((uint)t7 << 24);
  452. s[i] = (ulong)lo | ((ulong)hi << 32);
  453. }
  454. }
  455. private static readonly byte[] S0 = new byte[] {
  456. 0xa8, 0x43, 0x5f, 0x06, 0x6b, 0x75, 0x6c, 0x59, 0x71, 0xdf, 0x87, 0x95, 0x17, 0xf0, 0xd8, 0x09,
  457. 0x6d, 0xf3, 0x1d, 0xcb, 0xc9, 0x4d, 0x2c, 0xaf, 0x79, 0xe0, 0x97, 0xfd, 0x6f, 0x4b, 0x45, 0x39,
  458. 0x3e, 0xdd, 0xa3, 0x4f, 0xb4, 0xb6, 0x9a, 0x0e, 0x1f, 0xbf, 0x15, 0xe1, 0x49, 0xd2, 0x93, 0xc6,
  459. 0x92, 0x72, 0x9e, 0x61, 0xd1, 0x63, 0xfa, 0xee, 0xf4, 0x19, 0xd5, 0xad, 0x58, 0xa4, 0xbb, 0xa1,
  460. 0xdc, 0xf2, 0x83, 0x37, 0x42, 0xe4, 0x7a, 0x32, 0x9c, 0xcc, 0xab, 0x4a, 0x8f, 0x6e, 0x04, 0x27,
  461. 0x2e, 0xe7, 0xe2, 0x5a, 0x96, 0x16, 0x23, 0x2b, 0xc2, 0x65, 0x66, 0x0f, 0xbc, 0xa9, 0x47, 0x41,
  462. 0x34, 0x48, 0xfc, 0xb7, 0x6a, 0x88, 0xa5, 0x53, 0x86, 0xf9, 0x5b, 0xdb, 0x38, 0x7b, 0xc3, 0x1e,
  463. 0x22, 0x33, 0x24, 0x28, 0x36, 0xc7, 0xb2, 0x3b, 0x8e, 0x77, 0xba, 0xf5, 0x14, 0x9f, 0x08, 0x55,
  464. 0x9b, 0x4c, 0xfe, 0x60, 0x5c, 0xda, 0x18, 0x46, 0xcd, 0x7d, 0x21, 0xb0, 0x3f, 0x1b, 0x89, 0xff,
  465. 0xeb, 0x84, 0x69, 0x3a, 0x9d, 0xd7, 0xd3, 0x70, 0x67, 0x40, 0xb5, 0xde, 0x5d, 0x30, 0x91, 0xb1,
  466. 0x78, 0x11, 0x01, 0xe5, 0x00, 0x68, 0x98, 0xa0, 0xc5, 0x02, 0xa6, 0x74, 0x2d, 0x0b, 0xa2, 0x76,
  467. 0xb3, 0xbe, 0xce, 0xbd, 0xae, 0xe9, 0x8a, 0x31, 0x1c, 0xec, 0xf1, 0x99, 0x94, 0xaa, 0xf6, 0x26,
  468. 0x2f, 0xef, 0xe8, 0x8c, 0x35, 0x03, 0xd4, 0x7f, 0xfb, 0x05, 0xc1, 0x5e, 0x90, 0x20, 0x3d, 0x82,
  469. 0xf7, 0xea, 0x0a, 0x0d, 0x7e, 0xf8, 0x50, 0x1a, 0xc4, 0x07, 0x57, 0xb8, 0x3c, 0x62, 0xe3, 0xc8,
  470. 0xac, 0x52, 0x64, 0x10, 0xd0, 0xd9, 0x13, 0x0c, 0x12, 0x29, 0x51, 0xb9, 0xcf, 0xd6, 0x73, 0x8d,
  471. 0x81, 0x54, 0xc0, 0xed, 0x4e, 0x44, 0xa7, 0x2a, 0x85, 0x25, 0xe6, 0xca, 0x7c, 0x8b, 0x56, 0x80
  472. };
  473. private static readonly byte[] S1 = new byte[] {
  474. 0xce, 0xbb, 0xeb, 0x92, 0xea, 0xcb, 0x13, 0xc1, 0xe9, 0x3a, 0xd6, 0xb2, 0xd2, 0x90, 0x17, 0xf8,
  475. 0x42, 0x15, 0x56, 0xb4, 0x65, 0x1c, 0x88, 0x43, 0xc5, 0x5c, 0x36, 0xba, 0xf5, 0x57, 0x67, 0x8d,
  476. 0x31, 0xf6, 0x64, 0x58, 0x9e, 0xf4, 0x22, 0xaa, 0x75, 0x0f, 0x02, 0xb1, 0xdf, 0x6d, 0x73, 0x4d,
  477. 0x7c, 0x26, 0x2e, 0xf7, 0x08, 0x5d, 0x44, 0x3e, 0x9f, 0x14, 0xc8, 0xae, 0x54, 0x10, 0xd8, 0xbc,
  478. 0x1a, 0x6b, 0x69, 0xf3, 0xbd, 0x33, 0xab, 0xfa, 0xd1, 0x9b, 0x68, 0x4e, 0x16, 0x95, 0x91, 0xee,
  479. 0x4c, 0x63, 0x8e, 0x5b, 0xcc, 0x3c, 0x19, 0xa1, 0x81, 0x49, 0x7b, 0xd9, 0x6f, 0x37, 0x60, 0xca,
  480. 0xe7, 0x2b, 0x48, 0xfd, 0x96, 0x45, 0xfc, 0x41, 0x12, 0x0d, 0x79, 0xe5, 0x89, 0x8c, 0xe3, 0x20,
  481. 0x30, 0xdc, 0xb7, 0x6c, 0x4a, 0xb5, 0x3f, 0x97, 0xd4, 0x62, 0x2d, 0x06, 0xa4, 0xa5, 0x83, 0x5f,
  482. 0x2a, 0xda, 0xc9, 0x00, 0x7e, 0xa2, 0x55, 0xbf, 0x11, 0xd5, 0x9c, 0xcf, 0x0e, 0x0a, 0x3d, 0x51,
  483. 0x7d, 0x93, 0x1b, 0xfe, 0xc4, 0x47, 0x09, 0x86, 0x0b, 0x8f, 0x9d, 0x6a, 0x07, 0xb9, 0xb0, 0x98,
  484. 0x18, 0x32, 0x71, 0x4b, 0xef, 0x3b, 0x70, 0xa0, 0xe4, 0x40, 0xff, 0xc3, 0xa9, 0xe6, 0x78, 0xf9,
  485. 0x8b, 0x46, 0x80, 0x1e, 0x38, 0xe1, 0xb8, 0xa8, 0xe0, 0x0c, 0x23, 0x76, 0x1d, 0x25, 0x24, 0x05,
  486. 0xf1, 0x6e, 0x94, 0x28, 0x9a, 0x84, 0xe8, 0xa3, 0x4f, 0x77, 0xd3, 0x85, 0xe2, 0x52, 0xf2, 0x82,
  487. 0x50, 0x7a, 0x2f, 0x74, 0x53, 0xb3, 0x61, 0xaf, 0x39, 0x35, 0xde, 0xcd, 0x1f, 0x99, 0xac, 0xad,
  488. 0x72, 0x2c, 0xdd, 0xd0, 0x87, 0xbe, 0x5e, 0xa6, 0xec, 0x04, 0xc6, 0x03, 0x34, 0xfb, 0xdb, 0x59,
  489. 0xb6, 0xc2, 0x01, 0xf0, 0x5a, 0xed, 0xa7, 0x66, 0x21, 0x7f, 0x8a, 0x27, 0xc7, 0xc0, 0x29, 0xd7
  490. };
  491. private static readonly byte[] S2 = new byte[] {
  492. 0x93, 0xd9, 0x9a, 0xb5, 0x98, 0x22, 0x45, 0xfc, 0xba, 0x6a, 0xdf, 0x02, 0x9f, 0xdc, 0x51, 0x59,
  493. 0x4a, 0x17, 0x2b, 0xc2, 0x94, 0xf4, 0xbb, 0xa3, 0x62, 0xe4, 0x71, 0xd4, 0xcd, 0x70, 0x16, 0xe1,
  494. 0x49, 0x3c, 0xc0, 0xd8, 0x5c, 0x9b, 0xad, 0x85, 0x53, 0xa1, 0x7a, 0xc8, 0x2d, 0xe0, 0xd1, 0x72,
  495. 0xa6, 0x2c, 0xc4, 0xe3, 0x76, 0x78, 0xb7, 0xb4, 0x09, 0x3b, 0x0e, 0x41, 0x4c, 0xde, 0xb2, 0x90,
  496. 0x25, 0xa5, 0xd7, 0x03, 0x11, 0x00, 0xc3, 0x2e, 0x92, 0xef, 0x4e, 0x12, 0x9d, 0x7d, 0xcb, 0x35,
  497. 0x10, 0xd5, 0x4f, 0x9e, 0x4d, 0xa9, 0x55, 0xc6, 0xd0, 0x7b, 0x18, 0x97, 0xd3, 0x36, 0xe6, 0x48,
  498. 0x56, 0x81, 0x8f, 0x77, 0xcc, 0x9c, 0xb9, 0xe2, 0xac, 0xb8, 0x2f, 0x15, 0xa4, 0x7c, 0xda, 0x38,
  499. 0x1e, 0x0b, 0x05, 0xd6, 0x14, 0x6e, 0x6c, 0x7e, 0x66, 0xfd, 0xb1, 0xe5, 0x60, 0xaf, 0x5e, 0x33,
  500. 0x87, 0xc9, 0xf0, 0x5d, 0x6d, 0x3f, 0x88, 0x8d, 0xc7, 0xf7, 0x1d, 0xe9, 0xec, 0xed, 0x80, 0x29,
  501. 0x27, 0xcf, 0x99, 0xa8, 0x50, 0x0f, 0x37, 0x24, 0x28, 0x30, 0x95, 0xd2, 0x3e, 0x5b, 0x40, 0x83,
  502. 0xb3, 0x69, 0x57, 0x1f, 0x07, 0x1c, 0x8a, 0xbc, 0x20, 0xeb, 0xce, 0x8e, 0xab, 0xee, 0x31, 0xa2,
  503. 0x73, 0xf9, 0xca, 0x3a, 0x1a, 0xfb, 0x0d, 0xc1, 0xfe, 0xfa, 0xf2, 0x6f, 0xbd, 0x96, 0xdd, 0x43,
  504. 0x52, 0xb6, 0x08, 0xf3, 0xae, 0xbe, 0x19, 0x89, 0x32, 0x26, 0xb0, 0xea, 0x4b, 0x64, 0x84, 0x82,
  505. 0x6b, 0xf5, 0x79, 0xbf, 0x01, 0x5f, 0x75, 0x63, 0x1b, 0x23, 0x3d, 0x68, 0x2a, 0x65, 0xe8, 0x91,
  506. 0xf6, 0xff, 0x13, 0x58, 0xf1, 0x47, 0x0a, 0x7f, 0xc5, 0xa7, 0xe7, 0x61, 0x5a, 0x06, 0x46, 0x44,
  507. 0x42, 0x04, 0xa0, 0xdb, 0x39, 0x86, 0x54, 0xaa, 0x8c, 0x34, 0x21, 0x8b, 0xf8, 0x0c, 0x74, 0x67
  508. };
  509. private static readonly byte[] S3 = new byte[] {
  510. 0x68, 0x8d, 0xca, 0x4d, 0x73, 0x4b, 0x4e, 0x2a, 0xd4, 0x52, 0x26, 0xb3, 0x54, 0x1e, 0x19, 0x1f,
  511. 0x22, 0x03, 0x46, 0x3d, 0x2d, 0x4a, 0x53, 0x83, 0x13, 0x8a, 0xb7, 0xd5, 0x25, 0x79, 0xf5, 0xbd,
  512. 0x58, 0x2f, 0x0d, 0x02, 0xed, 0x51, 0x9e, 0x11, 0xf2, 0x3e, 0x55, 0x5e, 0xd1, 0x16, 0x3c, 0x66,
  513. 0x70, 0x5d, 0xf3, 0x45, 0x40, 0xcc, 0xe8, 0x94, 0x56, 0x08, 0xce, 0x1a, 0x3a, 0xd2, 0xe1, 0xdf,
  514. 0xb5, 0x38, 0x6e, 0x0e, 0xe5, 0xf4, 0xf9, 0x86, 0xe9, 0x4f, 0xd6, 0x85, 0x23, 0xcf, 0x32, 0x99,
  515. 0x31, 0x14, 0xae, 0xee, 0xc8, 0x48, 0xd3, 0x30, 0xa1, 0x92, 0x41, 0xb1, 0x18, 0xc4, 0x2c, 0x71,
  516. 0x72, 0x44, 0x15, 0xfd, 0x37, 0xbe, 0x5f, 0xaa, 0x9b, 0x88, 0xd8, 0xab, 0x89, 0x9c, 0xfa, 0x60,
  517. 0xea, 0xbc, 0x62, 0x0c, 0x24, 0xa6, 0xa8, 0xec, 0x67, 0x20, 0xdb, 0x7c, 0x28, 0xdd, 0xac, 0x5b,
  518. 0x34, 0x7e, 0x10, 0xf1, 0x7b, 0x8f, 0x63, 0xa0, 0x05, 0x9a, 0x43, 0x77, 0x21, 0xbf, 0x27, 0x09,
  519. 0xc3, 0x9f, 0xb6, 0xd7, 0x29, 0xc2, 0xeb, 0xc0, 0xa4, 0x8b, 0x8c, 0x1d, 0xfb, 0xff, 0xc1, 0xb2,
  520. 0x97, 0x2e, 0xf8, 0x65, 0xf6, 0x75, 0x07, 0x04, 0x49, 0x33, 0xe4, 0xd9, 0xb9, 0xd0, 0x42, 0xc7,
  521. 0x6c, 0x90, 0x00, 0x8e, 0x6f, 0x50, 0x01, 0xc5, 0xda, 0x47, 0x3f, 0xcd, 0x69, 0xa2, 0xe2, 0x7a,
  522. 0xa7, 0xc6, 0x93, 0x0f, 0x0a, 0x06, 0xe6, 0x2b, 0x96, 0xa3, 0x1c, 0xaf, 0x6a, 0x12, 0x84, 0x39,
  523. 0xe7, 0xb0, 0x82, 0xf7, 0xfe, 0x9d, 0x87, 0x5c, 0x81, 0x35, 0xde, 0xb4, 0xa5, 0xfc, 0x80, 0xef,
  524. 0xcb, 0xbb, 0x6b, 0x76, 0xba, 0x5a, 0x7d, 0x78, 0x0b, 0x95, 0xe3, 0xad, 0x74, 0x98, 0x3b, 0x36,
  525. 0x64, 0x6d, 0xdc, 0xf0, 0x59, 0xa9, 0x4c, 0x17, 0x7f, 0x91, 0xb8, 0xc9, 0x57, 0x1b, 0xe0, 0x61
  526. };
  527. public virtual IMemoable Copy()
  528. {
  529. return new Dstu7564Digest(this);
  530. }
  531. public virtual void Reset(IMemoable other)
  532. {
  533. Dstu7564Digest d = (Dstu7564Digest)other;
  534. CopyIn(d);
  535. }
  536. }
  537. }
  538. #pragma warning restore
  539. #endif