AesEngine_X86.cs 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834
  1. #if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
  2. #pragma warning disable
  3. #if NETCOREAPP3_0_OR_GREATER
  4. using System;
  5. using System.Buffers.Binary;
  6. using System.Runtime.CompilerServices;
  7. using System.Runtime.InteropServices;
  8. using System.Runtime.Intrinsics;
  9. using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
  10. using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities;
  11. namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Engines
  12. {
  13. using Aes = System.Runtime.Intrinsics.X86.Aes;
  14. using Sse2 = System.Runtime.Intrinsics.X86.Sse2;
  15. public struct AesEngine_X86
  16. : IBlockCipher
  17. {
  18. public static bool IsSupported => Aes.IsSupported;
  19. private static Vector128<byte>[] CreateRoundKeys(byte[] key, bool forEncryption)
  20. {
  21. Vector128<byte>[] K;
  22. switch (key.Length)
  23. {
  24. case 16:
  25. {
  26. ReadOnlySpan<byte> rcon = stackalloc byte[]{ 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36 };
  27. K = new Vector128<byte>[11];
  28. var s = Load128(key.AsSpan(0, 16));
  29. K[0] = s;
  30. for (int round = 0; round < 10;)
  31. {
  32. var t = Aes.KeygenAssist(s, rcon[round++]);
  33. t = Sse2.Shuffle(t.AsInt32(), 0xFF).AsByte();
  34. s = Sse2.Xor(s, Sse2.ShiftLeftLogical128BitLane(s, 8));
  35. s = Sse2.Xor(s, Sse2.ShiftLeftLogical128BitLane(s, 4));
  36. s = Sse2.Xor(s, t);
  37. K[round] = s;
  38. }
  39. break;
  40. }
  41. case 24:
  42. {
  43. K = new Vector128<byte>[13];
  44. var s1 = Load128(key.AsSpan(0, 16));
  45. var s2 = Load64(key.AsSpan(16, 8)).ToVector128();
  46. K[0] = s1;
  47. byte rcon = 0x01;
  48. for (int round = 0;;)
  49. {
  50. var t1 = Aes.KeygenAssist(s2, rcon); rcon <<= 1;
  51. t1 = Sse2.Shuffle(t1.AsInt32(), 0x55).AsByte();
  52. s1 = Sse2.Xor(s1, Sse2.ShiftLeftLogical128BitLane(s1, 8));
  53. s1 = Sse2.Xor(s1, Sse2.ShiftLeftLogical128BitLane(s1, 4));
  54. s1 = Sse2.Xor(s1, t1);
  55. K[++round] = Sse2.Xor(s2, Sse2.ShiftLeftLogical128BitLane(s1, 8));
  56. var s3 = Sse2.Xor(s2, Sse2.ShiftRightLogical128BitLane(s1, 12));
  57. s3 = Sse2.Xor(s3, Sse2.ShiftLeftLogical128BitLane(s3, 4));
  58. K[++round] = Sse2.Xor(
  59. Sse2.ShiftRightLogical128BitLane(s1, 8),
  60. Sse2.ShiftLeftLogical128BitLane(s3, 8));
  61. var t2 = Aes.KeygenAssist(s3, rcon); rcon <<= 1;
  62. t2 = Sse2.Shuffle(t2.AsInt32(), 0x55).AsByte();
  63. s1 = Sse2.Xor(s1, Sse2.ShiftLeftLogical128BitLane(s1, 8));
  64. s1 = Sse2.Xor(s1, Sse2.ShiftLeftLogical128BitLane(s1, 4));
  65. s1 = Sse2.Xor(s1, t2);
  66. K[++round] = s1;
  67. if (round == 12)
  68. break;
  69. s2 = Sse2.Xor(s3, Sse2.ShiftRightLogical128BitLane(s1, 12));
  70. s2 = Sse2.Xor(s2, Sse2.ShiftLeftLogical128BitLane(s2, 4));
  71. s2 = s2.WithUpper(Vector64<byte>.Zero);
  72. }
  73. break;
  74. }
  75. case 32:
  76. {
  77. K = new Vector128<byte>[15];
  78. var s1 = Load128(key.AsSpan(0, 16));
  79. var s2 = Load128(key.AsSpan(16, 16));
  80. K[0] = s1;
  81. K[1] = s2;
  82. byte rcon = 0x01;
  83. for (int round = 1;;)
  84. {
  85. var t1 = Aes.KeygenAssist(s2, rcon); rcon <<= 1;
  86. t1 = Sse2.Shuffle(t1.AsInt32(), 0xFF).AsByte();
  87. s1 = Sse2.Xor(s1, Sse2.ShiftLeftLogical128BitLane(s1, 8));
  88. s1 = Sse2.Xor(s1, Sse2.ShiftLeftLogical128BitLane(s1, 4));
  89. s1 = Sse2.Xor(s1, t1);
  90. K[++round] = s1;
  91. if (round == 14)
  92. break;
  93. var t2 = Aes.KeygenAssist(s1, 0x00);
  94. t2 = Sse2.Shuffle(t2.AsInt32(), 0xAA).AsByte();
  95. s2 = Sse2.Xor(s2, Sse2.ShiftLeftLogical128BitLane(s2, 8));
  96. s2 = Sse2.Xor(s2, Sse2.ShiftLeftLogical128BitLane(s2, 4));
  97. s2 = Sse2.Xor(s2, t2);
  98. K[++round] = s2;
  99. }
  100. break;
  101. }
  102. default:
  103. throw new ArgumentException("Key length not 128/192/256 bits.");
  104. }
  105. if (!forEncryption)
  106. {
  107. for (int i = 1, last = K.Length - 1; i < last; ++i)
  108. {
  109. K[i] = Aes.InverseMixColumns(K[i]);
  110. }
  111. Array.Reverse(K);
  112. }
  113. return K;
  114. }
  115. private enum Mode { DEC_128, DEC_192, DEC_256, ENC_128, ENC_192, ENC_256, UNINITIALIZED };
  116. private Vector128<byte>[] m_roundKeys = null;
  117. private Mode m_mode = Mode.UNINITIALIZED;
  118. public AesEngine_X86()
  119. {
  120. if (!IsSupported)
  121. throw new PlatformNotSupportedException(nameof(AesEngine_X86));
  122. }
  123. public string AlgorithmName => "AES";
  124. public int GetBlockSize() => 16;
  125. public void Init(bool forEncryption, ICipherParameters parameters)
  126. {
  127. if (!(parameters is KeyParameter keyParameter))
  128. {
  129. ArgumentNullException.ThrowIfNull(parameters, nameof(parameters));
  130. throw new ArgumentException("invalid type: " + Org.BouncyCastle.Utilities.Platform.GetTypeName(parameters), nameof(parameters));
  131. }
  132. m_roundKeys = CreateRoundKeys(keyParameter.GetKey(), forEncryption);
  133. if (m_roundKeys.Length == 11)
  134. {
  135. m_mode = forEncryption ? Mode.ENC_128 : Mode.DEC_128;
  136. }
  137. else if (m_roundKeys.Length == 13)
  138. {
  139. m_mode = forEncryption ? Mode.ENC_192 : Mode.DEC_192;
  140. }
  141. else
  142. {
  143. m_mode = forEncryption ? Mode.ENC_256 : Mode.DEC_256;
  144. }
  145. }
  146. public int ProcessBlock(byte[] inBuf, int inOff, byte[] outBuf, int outOff)
  147. {
  148. Check.DataLength(inBuf, inOff, 16, "input buffer too short");
  149. Check.OutputLength(outBuf, outOff, 16, "output buffer too short");
  150. var state = Load128(inBuf.AsSpan(inOff, 16));
  151. ImplRounds(ref state);
  152. Store128(state, outBuf.AsSpan(outOff, 16));
  153. return 16;
  154. }
  155. public int ProcessBlock(ReadOnlySpan<byte> input, Span<byte> output)
  156. {
  157. Check.DataLength(input, 16, "input buffer too short");
  158. Check.OutputLength(output, 16, "output buffer too short");
  159. var state = Load128(input[..16]);
  160. ImplRounds(ref state);
  161. Store128(state, output[..16]);
  162. return 16;
  163. }
  164. public int ProcessFourBlocks(ReadOnlySpan<byte> input, Span<byte> output)
  165. {
  166. Check.DataLength(input, 64, "input buffer too short");
  167. Check.OutputLength(output, 64, "output buffer too short");
  168. var s1 = Load128(input[..16]);
  169. var s2 = Load128(input[16..32]);
  170. var s3 = Load128(input[32..48]);
  171. var s4 = Load128(input[48..64]);
  172. ImplRounds(ref s1, ref s2, ref s3, ref s4);
  173. Store128(s1, output[..16]);
  174. Store128(s2, output[16..32]);
  175. Store128(s3, output[32..48]);
  176. Store128(s4, output[48..64]);
  177. return 64;
  178. }
  179. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  180. private void ImplRounds(ref Vector128<byte> state)
  181. {
  182. switch (m_mode)
  183. {
  184. case Mode.DEC_128: Decrypt128(m_roundKeys, ref state); break;
  185. case Mode.DEC_192: Decrypt192(m_roundKeys, ref state); break;
  186. case Mode.DEC_256: Decrypt256(m_roundKeys, ref state); break;
  187. case Mode.ENC_128: Encrypt128(m_roundKeys, ref state); break;
  188. case Mode.ENC_192: Encrypt192(m_roundKeys, ref state); break;
  189. case Mode.ENC_256: Encrypt256(m_roundKeys, ref state); break;
  190. default: throw new InvalidOperationException(nameof(AesEngine_X86) + " not initialised");
  191. }
  192. }
  193. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  194. private void ImplRounds(
  195. ref Vector128<byte> s1, ref Vector128<byte> s2, ref Vector128<byte> s3, ref Vector128<byte> s4)
  196. {
  197. switch (m_mode)
  198. {
  199. case Mode.DEC_128: DecryptFour128(m_roundKeys, ref s1, ref s2, ref s3, ref s4); break;
  200. case Mode.DEC_192: DecryptFour192(m_roundKeys, ref s1, ref s2, ref s3, ref s4); break;
  201. case Mode.DEC_256: DecryptFour256(m_roundKeys, ref s1, ref s2, ref s3, ref s4); break;
  202. case Mode.ENC_128: EncryptFour128(m_roundKeys, ref s1, ref s2, ref s3, ref s4); break;
  203. case Mode.ENC_192: EncryptFour192(m_roundKeys, ref s1, ref s2, ref s3, ref s4); break;
  204. case Mode.ENC_256: EncryptFour256(m_roundKeys, ref s1, ref s2, ref s3, ref s4); break;
  205. default: throw new InvalidOperationException(nameof(AesEngine_X86) + " not initialised");
  206. }
  207. }
  208. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  209. private static void Decrypt128(Vector128<byte>[] roundKeys, ref Vector128<byte> state)
  210. {
  211. state = Sse2.Xor(state, roundKeys[0]);
  212. state = Aes.Decrypt(state, roundKeys[1]);
  213. state = Aes.Decrypt(state, roundKeys[2]);
  214. state = Aes.Decrypt(state, roundKeys[3]);
  215. state = Aes.Decrypt(state, roundKeys[4]);
  216. state = Aes.Decrypt(state, roundKeys[5]);
  217. state = Aes.Decrypt(state, roundKeys[6]);
  218. state = Aes.Decrypt(state, roundKeys[7]);
  219. state = Aes.Decrypt(state, roundKeys[8]);
  220. state = Aes.Decrypt(state, roundKeys[9]);
  221. state = Aes.DecryptLast(state, roundKeys[10]);
  222. }
  223. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  224. private static void Decrypt192(Vector128<byte>[] roundKeys, ref Vector128<byte> state)
  225. {
  226. state = Sse2.Xor(state, roundKeys[0]);
  227. state = Aes.Decrypt(state, roundKeys[1]);
  228. state = Aes.Decrypt(state, roundKeys[2]);
  229. state = Aes.Decrypt(state, roundKeys[3]);
  230. state = Aes.Decrypt(state, roundKeys[4]);
  231. state = Aes.Decrypt(state, roundKeys[5]);
  232. state = Aes.Decrypt(state, roundKeys[6]);
  233. state = Aes.Decrypt(state, roundKeys[7]);
  234. state = Aes.Decrypt(state, roundKeys[8]);
  235. state = Aes.Decrypt(state, roundKeys[9]);
  236. state = Aes.Decrypt(state, roundKeys[10]);
  237. state = Aes.Decrypt(state, roundKeys[11]);
  238. state = Aes.DecryptLast(state, roundKeys[12]);
  239. }
  240. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  241. private static void Decrypt256(Vector128<byte>[] roundKeys, ref Vector128<byte> state)
  242. {
  243. state = Sse2.Xor(state, roundKeys[0]);
  244. state = Aes.Decrypt(state, roundKeys[1]);
  245. state = Aes.Decrypt(state, roundKeys[2]);
  246. state = Aes.Decrypt(state, roundKeys[3]);
  247. state = Aes.Decrypt(state, roundKeys[4]);
  248. state = Aes.Decrypt(state, roundKeys[5]);
  249. state = Aes.Decrypt(state, roundKeys[6]);
  250. state = Aes.Decrypt(state, roundKeys[7]);
  251. state = Aes.Decrypt(state, roundKeys[8]);
  252. state = Aes.Decrypt(state, roundKeys[9]);
  253. state = Aes.Decrypt(state, roundKeys[10]);
  254. state = Aes.Decrypt(state, roundKeys[11]);
  255. state = Aes.Decrypt(state, roundKeys[12]);
  256. state = Aes.Decrypt(state, roundKeys[13]);
  257. state = Aes.DecryptLast(state, roundKeys[14]);
  258. }
  259. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  260. private static void DecryptFour128(Vector128<byte>[] rk,
  261. ref Vector128<byte> s1, ref Vector128<byte> s2, ref Vector128<byte> s3, ref Vector128<byte> s4)
  262. {
  263. s1 = Sse2.Xor(s1, rk[0]);
  264. s2 = Sse2.Xor(s2, rk[0]);
  265. s3 = Sse2.Xor(s3, rk[0]);
  266. s4 = Sse2.Xor(s4, rk[0]);
  267. s1 = Aes.Decrypt(s1, rk[1]);
  268. s2 = Aes.Decrypt(s2, rk[1]);
  269. s3 = Aes.Decrypt(s3, rk[1]);
  270. s4 = Aes.Decrypt(s4, rk[1]);
  271. s1 = Aes.Decrypt(s1, rk[2]);
  272. s2 = Aes.Decrypt(s2, rk[2]);
  273. s3 = Aes.Decrypt(s3, rk[2]);
  274. s4 = Aes.Decrypt(s4, rk[2]);
  275. s1 = Aes.Decrypt(s1, rk[3]);
  276. s2 = Aes.Decrypt(s2, rk[3]);
  277. s3 = Aes.Decrypt(s3, rk[3]);
  278. s4 = Aes.Decrypt(s4, rk[3]);
  279. s1 = Aes.Decrypt(s1, rk[4]);
  280. s2 = Aes.Decrypt(s2, rk[4]);
  281. s3 = Aes.Decrypt(s3, rk[4]);
  282. s4 = Aes.Decrypt(s4, rk[4]);
  283. s1 = Aes.Decrypt(s1, rk[5]);
  284. s2 = Aes.Decrypt(s2, rk[5]);
  285. s3 = Aes.Decrypt(s3, rk[5]);
  286. s4 = Aes.Decrypt(s4, rk[5]);
  287. s1 = Aes.Decrypt(s1, rk[6]);
  288. s2 = Aes.Decrypt(s2, rk[6]);
  289. s3 = Aes.Decrypt(s3, rk[6]);
  290. s4 = Aes.Decrypt(s4, rk[6]);
  291. s1 = Aes.Decrypt(s1, rk[7]);
  292. s2 = Aes.Decrypt(s2, rk[7]);
  293. s3 = Aes.Decrypt(s3, rk[7]);
  294. s4 = Aes.Decrypt(s4, rk[7]);
  295. s1 = Aes.Decrypt(s1, rk[8]);
  296. s2 = Aes.Decrypt(s2, rk[8]);
  297. s3 = Aes.Decrypt(s3, rk[8]);
  298. s4 = Aes.Decrypt(s4, rk[8]);
  299. s1 = Aes.Decrypt(s1, rk[9]);
  300. s2 = Aes.Decrypt(s2, rk[9]);
  301. s3 = Aes.Decrypt(s3, rk[9]);
  302. s4 = Aes.Decrypt(s4, rk[9]);
  303. s1 = Aes.DecryptLast(s1, rk[10]);
  304. s2 = Aes.DecryptLast(s2, rk[10]);
  305. s3 = Aes.DecryptLast(s3, rk[10]);
  306. s4 = Aes.DecryptLast(s4, rk[10]);
  307. }
  308. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  309. private static void DecryptFour192(Vector128<byte>[] rk,
  310. ref Vector128<byte> s1, ref Vector128<byte> s2, ref Vector128<byte> s3, ref Vector128<byte> s4)
  311. {
  312. s1 = Sse2.Xor(s1, rk[0]);
  313. s2 = Sse2.Xor(s2, rk[0]);
  314. s3 = Sse2.Xor(s3, rk[0]);
  315. s4 = Sse2.Xor(s4, rk[0]);
  316. s1 = Aes.Decrypt(s1, rk[1]);
  317. s2 = Aes.Decrypt(s2, rk[1]);
  318. s3 = Aes.Decrypt(s3, rk[1]);
  319. s4 = Aes.Decrypt(s4, rk[1]);
  320. s1 = Aes.Decrypt(s1, rk[2]);
  321. s2 = Aes.Decrypt(s2, rk[2]);
  322. s3 = Aes.Decrypt(s3, rk[2]);
  323. s4 = Aes.Decrypt(s4, rk[2]);
  324. s1 = Aes.Decrypt(s1, rk[3]);
  325. s2 = Aes.Decrypt(s2, rk[3]);
  326. s3 = Aes.Decrypt(s3, rk[3]);
  327. s4 = Aes.Decrypt(s4, rk[3]);
  328. s1 = Aes.Decrypt(s1, rk[4]);
  329. s2 = Aes.Decrypt(s2, rk[4]);
  330. s3 = Aes.Decrypt(s3, rk[4]);
  331. s4 = Aes.Decrypt(s4, rk[4]);
  332. s1 = Aes.Decrypt(s1, rk[5]);
  333. s2 = Aes.Decrypt(s2, rk[5]);
  334. s3 = Aes.Decrypt(s3, rk[5]);
  335. s4 = Aes.Decrypt(s4, rk[5]);
  336. s1 = Aes.Decrypt(s1, rk[6]);
  337. s2 = Aes.Decrypt(s2, rk[6]);
  338. s3 = Aes.Decrypt(s3, rk[6]);
  339. s4 = Aes.Decrypt(s4, rk[6]);
  340. s1 = Aes.Decrypt(s1, rk[7]);
  341. s2 = Aes.Decrypt(s2, rk[7]);
  342. s3 = Aes.Decrypt(s3, rk[7]);
  343. s4 = Aes.Decrypt(s4, rk[7]);
  344. s1 = Aes.Decrypt(s1, rk[8]);
  345. s2 = Aes.Decrypt(s2, rk[8]);
  346. s3 = Aes.Decrypt(s3, rk[8]);
  347. s4 = Aes.Decrypt(s4, rk[8]);
  348. s1 = Aes.Decrypt(s1, rk[9]);
  349. s2 = Aes.Decrypt(s2, rk[9]);
  350. s3 = Aes.Decrypt(s3, rk[9]);
  351. s4 = Aes.Decrypt(s4, rk[9]);
  352. s1 = Aes.Decrypt(s1, rk[10]);
  353. s2 = Aes.Decrypt(s2, rk[10]);
  354. s3 = Aes.Decrypt(s3, rk[10]);
  355. s4 = Aes.Decrypt(s4, rk[10]);
  356. s1 = Aes.Decrypt(s1, rk[11]);
  357. s2 = Aes.Decrypt(s2, rk[11]);
  358. s3 = Aes.Decrypt(s3, rk[11]);
  359. s4 = Aes.Decrypt(s4, rk[11]);
  360. s1 = Aes.DecryptLast(s1, rk[12]);
  361. s2 = Aes.DecryptLast(s2, rk[12]);
  362. s3 = Aes.DecryptLast(s3, rk[12]);
  363. s4 = Aes.DecryptLast(s4, rk[12]);
  364. }
  365. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  366. private static void DecryptFour256(Vector128<byte>[] rk,
  367. ref Vector128<byte> s1, ref Vector128<byte> s2, ref Vector128<byte> s3, ref Vector128<byte> s4)
  368. {
  369. s1 = Sse2.Xor(s1, rk[0]);
  370. s2 = Sse2.Xor(s2, rk[0]);
  371. s3 = Sse2.Xor(s3, rk[0]);
  372. s4 = Sse2.Xor(s4, rk[0]);
  373. s1 = Aes.Decrypt(s1, rk[1]);
  374. s2 = Aes.Decrypt(s2, rk[1]);
  375. s3 = Aes.Decrypt(s3, rk[1]);
  376. s4 = Aes.Decrypt(s4, rk[1]);
  377. s1 = Aes.Decrypt(s1, rk[2]);
  378. s2 = Aes.Decrypt(s2, rk[2]);
  379. s3 = Aes.Decrypt(s3, rk[2]);
  380. s4 = Aes.Decrypt(s4, rk[2]);
  381. s1 = Aes.Decrypt(s1, rk[3]);
  382. s2 = Aes.Decrypt(s2, rk[3]);
  383. s3 = Aes.Decrypt(s3, rk[3]);
  384. s4 = Aes.Decrypt(s4, rk[3]);
  385. s1 = Aes.Decrypt(s1, rk[4]);
  386. s2 = Aes.Decrypt(s2, rk[4]);
  387. s3 = Aes.Decrypt(s3, rk[4]);
  388. s4 = Aes.Decrypt(s4, rk[4]);
  389. s1 = Aes.Decrypt(s1, rk[5]);
  390. s2 = Aes.Decrypt(s2, rk[5]);
  391. s3 = Aes.Decrypt(s3, rk[5]);
  392. s4 = Aes.Decrypt(s4, rk[5]);
  393. s1 = Aes.Decrypt(s1, rk[6]);
  394. s2 = Aes.Decrypt(s2, rk[6]);
  395. s3 = Aes.Decrypt(s3, rk[6]);
  396. s4 = Aes.Decrypt(s4, rk[6]);
  397. s1 = Aes.Decrypt(s1, rk[7]);
  398. s2 = Aes.Decrypt(s2, rk[7]);
  399. s3 = Aes.Decrypt(s3, rk[7]);
  400. s4 = Aes.Decrypt(s4, rk[7]);
  401. s1 = Aes.Decrypt(s1, rk[8]);
  402. s2 = Aes.Decrypt(s2, rk[8]);
  403. s3 = Aes.Decrypt(s3, rk[8]);
  404. s4 = Aes.Decrypt(s4, rk[8]);
  405. s1 = Aes.Decrypt(s1, rk[9]);
  406. s2 = Aes.Decrypt(s2, rk[9]);
  407. s3 = Aes.Decrypt(s3, rk[9]);
  408. s4 = Aes.Decrypt(s4, rk[9]);
  409. s1 = Aes.Decrypt(s1, rk[10]);
  410. s2 = Aes.Decrypt(s2, rk[10]);
  411. s3 = Aes.Decrypt(s3, rk[10]);
  412. s4 = Aes.Decrypt(s4, rk[10]);
  413. s1 = Aes.Decrypt(s1, rk[11]);
  414. s2 = Aes.Decrypt(s2, rk[11]);
  415. s3 = Aes.Decrypt(s3, rk[11]);
  416. s4 = Aes.Decrypt(s4, rk[11]);
  417. s1 = Aes.Decrypt(s1, rk[12]);
  418. s2 = Aes.Decrypt(s2, rk[12]);
  419. s3 = Aes.Decrypt(s3, rk[12]);
  420. s4 = Aes.Decrypt(s4, rk[12]);
  421. s1 = Aes.Decrypt(s1, rk[13]);
  422. s2 = Aes.Decrypt(s2, rk[13]);
  423. s3 = Aes.Decrypt(s3, rk[13]);
  424. s4 = Aes.Decrypt(s4, rk[13]);
  425. s1 = Aes.DecryptLast(s1, rk[14]);
  426. s2 = Aes.DecryptLast(s2, rk[14]);
  427. s3 = Aes.DecryptLast(s3, rk[14]);
  428. s4 = Aes.DecryptLast(s4, rk[14]);
  429. }
  430. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  431. private static void Encrypt128(Vector128<byte>[] roundKeys, ref Vector128<byte> state)
  432. {
  433. state = Sse2.Xor(state, roundKeys[0]);
  434. state = Aes.Encrypt(state, roundKeys[1]);
  435. state = Aes.Encrypt(state, roundKeys[2]);
  436. state = Aes.Encrypt(state, roundKeys[3]);
  437. state = Aes.Encrypt(state, roundKeys[4]);
  438. state = Aes.Encrypt(state, roundKeys[5]);
  439. state = Aes.Encrypt(state, roundKeys[6]);
  440. state = Aes.Encrypt(state, roundKeys[7]);
  441. state = Aes.Encrypt(state, roundKeys[8]);
  442. state = Aes.Encrypt(state, roundKeys[9]);
  443. state = Aes.EncryptLast(state, roundKeys[10]);
  444. }
  445. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  446. private static void Encrypt192(Vector128<byte>[] roundKeys, ref Vector128<byte> state)
  447. {
  448. state = Sse2.Xor(state, roundKeys[0]);
  449. state = Aes.Encrypt(state, roundKeys[1]);
  450. state = Aes.Encrypt(state, roundKeys[2]);
  451. state = Aes.Encrypt(state, roundKeys[3]);
  452. state = Aes.Encrypt(state, roundKeys[4]);
  453. state = Aes.Encrypt(state, roundKeys[5]);
  454. state = Aes.Encrypt(state, roundKeys[6]);
  455. state = Aes.Encrypt(state, roundKeys[7]);
  456. state = Aes.Encrypt(state, roundKeys[8]);
  457. state = Aes.Encrypt(state, roundKeys[9]);
  458. state = Aes.Encrypt(state, roundKeys[10]);
  459. state = Aes.Encrypt(state, roundKeys[11]);
  460. state = Aes.EncryptLast(state, roundKeys[12]);
  461. }
  462. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  463. private static void Encrypt256(Vector128<byte>[] roundKeys, ref Vector128<byte> state)
  464. {
  465. state = Sse2.Xor(state, roundKeys[0]);
  466. state = Aes.Encrypt(state, roundKeys[1]);
  467. state = Aes.Encrypt(state, roundKeys[2]);
  468. state = Aes.Encrypt(state, roundKeys[3]);
  469. state = Aes.Encrypt(state, roundKeys[4]);
  470. state = Aes.Encrypt(state, roundKeys[5]);
  471. state = Aes.Encrypt(state, roundKeys[6]);
  472. state = Aes.Encrypt(state, roundKeys[7]);
  473. state = Aes.Encrypt(state, roundKeys[8]);
  474. state = Aes.Encrypt(state, roundKeys[9]);
  475. state = Aes.Encrypt(state, roundKeys[10]);
  476. state = Aes.Encrypt(state, roundKeys[11]);
  477. state = Aes.Encrypt(state, roundKeys[12]);
  478. state = Aes.Encrypt(state, roundKeys[13]);
  479. state = Aes.EncryptLast(state, roundKeys[14]);
  480. }
  481. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  482. private static void EncryptFour128(Vector128<byte>[] rk,
  483. ref Vector128<byte> s1, ref Vector128<byte> s2, ref Vector128<byte> s3, ref Vector128<byte> s4)
  484. {
  485. s1 = Sse2.Xor(s1, rk[0]);
  486. s2 = Sse2.Xor(s2, rk[0]);
  487. s3 = Sse2.Xor(s3, rk[0]);
  488. s4 = Sse2.Xor(s4, rk[0]);
  489. s1 = Aes.Encrypt(s1, rk[1]);
  490. s2 = Aes.Encrypt(s2, rk[1]);
  491. s3 = Aes.Encrypt(s3, rk[1]);
  492. s4 = Aes.Encrypt(s4, rk[1]);
  493. s1 = Aes.Encrypt(s1, rk[2]);
  494. s2 = Aes.Encrypt(s2, rk[2]);
  495. s3 = Aes.Encrypt(s3, rk[2]);
  496. s4 = Aes.Encrypt(s4, rk[2]);
  497. s1 = Aes.Encrypt(s1, rk[3]);
  498. s2 = Aes.Encrypt(s2, rk[3]);
  499. s3 = Aes.Encrypt(s3, rk[3]);
  500. s4 = Aes.Encrypt(s4, rk[3]);
  501. s1 = Aes.Encrypt(s1, rk[4]);
  502. s2 = Aes.Encrypt(s2, rk[4]);
  503. s3 = Aes.Encrypt(s3, rk[4]);
  504. s4 = Aes.Encrypt(s4, rk[4]);
  505. s1 = Aes.Encrypt(s1, rk[5]);
  506. s2 = Aes.Encrypt(s2, rk[5]);
  507. s3 = Aes.Encrypt(s3, rk[5]);
  508. s4 = Aes.Encrypt(s4, rk[5]);
  509. s1 = Aes.Encrypt(s1, rk[6]);
  510. s2 = Aes.Encrypt(s2, rk[6]);
  511. s3 = Aes.Encrypt(s3, rk[6]);
  512. s4 = Aes.Encrypt(s4, rk[6]);
  513. s1 = Aes.Encrypt(s1, rk[7]);
  514. s2 = Aes.Encrypt(s2, rk[7]);
  515. s3 = Aes.Encrypt(s3, rk[7]);
  516. s4 = Aes.Encrypt(s4, rk[7]);
  517. s1 = Aes.Encrypt(s1, rk[8]);
  518. s2 = Aes.Encrypt(s2, rk[8]);
  519. s3 = Aes.Encrypt(s3, rk[8]);
  520. s4 = Aes.Encrypt(s4, rk[8]);
  521. s1 = Aes.Encrypt(s1, rk[9]);
  522. s2 = Aes.Encrypt(s2, rk[9]);
  523. s3 = Aes.Encrypt(s3, rk[9]);
  524. s4 = Aes.Encrypt(s4, rk[9]);
  525. s1 = Aes.EncryptLast(s1, rk[10]);
  526. s2 = Aes.EncryptLast(s2, rk[10]);
  527. s3 = Aes.EncryptLast(s3, rk[10]);
  528. s4 = Aes.EncryptLast(s4, rk[10]);
  529. }
  530. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  531. private static void EncryptFour192(Vector128<byte>[] rk,
  532. ref Vector128<byte> s1, ref Vector128<byte> s2, ref Vector128<byte> s3, ref Vector128<byte> s4)
  533. {
  534. s1 = Sse2.Xor(s1, rk[0]);
  535. s2 = Sse2.Xor(s2, rk[0]);
  536. s3 = Sse2.Xor(s3, rk[0]);
  537. s4 = Sse2.Xor(s4, rk[0]);
  538. s1 = Aes.Encrypt(s1, rk[1]);
  539. s2 = Aes.Encrypt(s2, rk[1]);
  540. s3 = Aes.Encrypt(s3, rk[1]);
  541. s4 = Aes.Encrypt(s4, rk[1]);
  542. s1 = Aes.Encrypt(s1, rk[2]);
  543. s2 = Aes.Encrypt(s2, rk[2]);
  544. s3 = Aes.Encrypt(s3, rk[2]);
  545. s4 = Aes.Encrypt(s4, rk[2]);
  546. s1 = Aes.Encrypt(s1, rk[3]);
  547. s2 = Aes.Encrypt(s2, rk[3]);
  548. s3 = Aes.Encrypt(s3, rk[3]);
  549. s4 = Aes.Encrypt(s4, rk[3]);
  550. s1 = Aes.Encrypt(s1, rk[4]);
  551. s2 = Aes.Encrypt(s2, rk[4]);
  552. s3 = Aes.Encrypt(s3, rk[4]);
  553. s4 = Aes.Encrypt(s4, rk[4]);
  554. s1 = Aes.Encrypt(s1, rk[5]);
  555. s2 = Aes.Encrypt(s2, rk[5]);
  556. s3 = Aes.Encrypt(s3, rk[5]);
  557. s4 = Aes.Encrypt(s4, rk[5]);
  558. s1 = Aes.Encrypt(s1, rk[6]);
  559. s2 = Aes.Encrypt(s2, rk[6]);
  560. s3 = Aes.Encrypt(s3, rk[6]);
  561. s4 = Aes.Encrypt(s4, rk[6]);
  562. s1 = Aes.Encrypt(s1, rk[7]);
  563. s2 = Aes.Encrypt(s2, rk[7]);
  564. s3 = Aes.Encrypt(s3, rk[7]);
  565. s4 = Aes.Encrypt(s4, rk[7]);
  566. s1 = Aes.Encrypt(s1, rk[8]);
  567. s2 = Aes.Encrypt(s2, rk[8]);
  568. s3 = Aes.Encrypt(s3, rk[8]);
  569. s4 = Aes.Encrypt(s4, rk[8]);
  570. s1 = Aes.Encrypt(s1, rk[9]);
  571. s2 = Aes.Encrypt(s2, rk[9]);
  572. s3 = Aes.Encrypt(s3, rk[9]);
  573. s4 = Aes.Encrypt(s4, rk[9]);
  574. s1 = Aes.Encrypt(s1, rk[10]);
  575. s2 = Aes.Encrypt(s2, rk[10]);
  576. s3 = Aes.Encrypt(s3, rk[10]);
  577. s4 = Aes.Encrypt(s4, rk[10]);
  578. s1 = Aes.Encrypt(s1, rk[11]);
  579. s2 = Aes.Encrypt(s2, rk[11]);
  580. s3 = Aes.Encrypt(s3, rk[11]);
  581. s4 = Aes.Encrypt(s4, rk[11]);
  582. s1 = Aes.EncryptLast(s1, rk[12]);
  583. s2 = Aes.EncryptLast(s2, rk[12]);
  584. s3 = Aes.EncryptLast(s3, rk[12]);
  585. s4 = Aes.EncryptLast(s4, rk[12]);
  586. }
  587. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  588. private static void EncryptFour256(Vector128<byte>[] rk,
  589. ref Vector128<byte> s1, ref Vector128<byte> s2, ref Vector128<byte> s3, ref Vector128<byte> s4)
  590. {
  591. s1 = Sse2.Xor(s1, rk[0]);
  592. s2 = Sse2.Xor(s2, rk[0]);
  593. s3 = Sse2.Xor(s3, rk[0]);
  594. s4 = Sse2.Xor(s4, rk[0]);
  595. s1 = Aes.Encrypt(s1, rk[1]);
  596. s2 = Aes.Encrypt(s2, rk[1]);
  597. s3 = Aes.Encrypt(s3, rk[1]);
  598. s4 = Aes.Encrypt(s4, rk[1]);
  599. s1 = Aes.Encrypt(s1, rk[2]);
  600. s2 = Aes.Encrypt(s2, rk[2]);
  601. s3 = Aes.Encrypt(s3, rk[2]);
  602. s4 = Aes.Encrypt(s4, rk[2]);
  603. s1 = Aes.Encrypt(s1, rk[3]);
  604. s2 = Aes.Encrypt(s2, rk[3]);
  605. s3 = Aes.Encrypt(s3, rk[3]);
  606. s4 = Aes.Encrypt(s4, rk[3]);
  607. s1 = Aes.Encrypt(s1, rk[4]);
  608. s2 = Aes.Encrypt(s2, rk[4]);
  609. s3 = Aes.Encrypt(s3, rk[4]);
  610. s4 = Aes.Encrypt(s4, rk[4]);
  611. s1 = Aes.Encrypt(s1, rk[5]);
  612. s2 = Aes.Encrypt(s2, rk[5]);
  613. s3 = Aes.Encrypt(s3, rk[5]);
  614. s4 = Aes.Encrypt(s4, rk[5]);
  615. s1 = Aes.Encrypt(s1, rk[6]);
  616. s2 = Aes.Encrypt(s2, rk[6]);
  617. s3 = Aes.Encrypt(s3, rk[6]);
  618. s4 = Aes.Encrypt(s4, rk[6]);
  619. s1 = Aes.Encrypt(s1, rk[7]);
  620. s2 = Aes.Encrypt(s2, rk[7]);
  621. s3 = Aes.Encrypt(s3, rk[7]);
  622. s4 = Aes.Encrypt(s4, rk[7]);
  623. s1 = Aes.Encrypt(s1, rk[8]);
  624. s2 = Aes.Encrypt(s2, rk[8]);
  625. s3 = Aes.Encrypt(s3, rk[8]);
  626. s4 = Aes.Encrypt(s4, rk[8]);
  627. s1 = Aes.Encrypt(s1, rk[9]);
  628. s2 = Aes.Encrypt(s2, rk[9]);
  629. s3 = Aes.Encrypt(s3, rk[9]);
  630. s4 = Aes.Encrypt(s4, rk[9]);
  631. s1 = Aes.Encrypt(s1, rk[10]);
  632. s2 = Aes.Encrypt(s2, rk[10]);
  633. s3 = Aes.Encrypt(s3, rk[10]);
  634. s4 = Aes.Encrypt(s4, rk[10]);
  635. s1 = Aes.Encrypt(s1, rk[11]);
  636. s2 = Aes.Encrypt(s2, rk[11]);
  637. s3 = Aes.Encrypt(s3, rk[11]);
  638. s4 = Aes.Encrypt(s4, rk[11]);
  639. s1 = Aes.Encrypt(s1, rk[12]);
  640. s2 = Aes.Encrypt(s2, rk[12]);
  641. s3 = Aes.Encrypt(s3, rk[12]);
  642. s4 = Aes.Encrypt(s4, rk[12]);
  643. s1 = Aes.Encrypt(s1, rk[13]);
  644. s2 = Aes.Encrypt(s2, rk[13]);
  645. s3 = Aes.Encrypt(s3, rk[13]);
  646. s4 = Aes.Encrypt(s4, rk[13]);
  647. s1 = Aes.EncryptLast(s1, rk[14]);
  648. s2 = Aes.EncryptLast(s2, rk[14]);
  649. s3 = Aes.EncryptLast(s3, rk[14]);
  650. s4 = Aes.EncryptLast(s4, rk[14]);
  651. }
  652. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  653. private static Vector128<byte> Load128(ReadOnlySpan<byte> t)
  654. {
  655. #if NET7_0_OR_GREATER
  656. return Vector128.Create<byte>(t);
  657. #else
  658. if (BitConverter.IsLittleEndian && Unsafe.SizeOf<Vector128<byte>>() == 16)
  659. return MemoryMarshal.Read<Vector128<byte>>(t);
  660. return Vector128.Create(
  661. BinaryPrimitives.ReadUInt64LittleEndian(t[..8]),
  662. BinaryPrimitives.ReadUInt64LittleEndian(t[8..])
  663. ).AsByte();
  664. #endif
  665. }
  666. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  667. private static Vector64<byte> Load64(ReadOnlySpan<byte> t)
  668. {
  669. #if NET7_0_OR_GREATER
  670. return Vector64.Create<byte>(t);
  671. #else
  672. if (BitConverter.IsLittleEndian && Unsafe.SizeOf<Vector64<byte>>() == 8)
  673. return MemoryMarshal.Read<Vector64<byte>>(t);
  674. return Vector64.Create(
  675. BinaryPrimitives.ReadUInt64LittleEndian(t[..8])
  676. ).AsByte();
  677. #endif
  678. }
  679. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  680. private static void Store128(Vector128<byte> s, Span<byte> t)
  681. {
  682. #if NET7_0_OR_GREATER
  683. Vector128.CopyTo(s, t);
  684. #else
  685. if (BitConverter.IsLittleEndian && Unsafe.SizeOf<Vector128<byte>>() == 16)
  686. {
  687. MemoryMarshal.Write(t, ref s);
  688. return;
  689. }
  690. var u = s.AsUInt64();
  691. BinaryPrimitives.WriteUInt64LittleEndian(t[..8], u.GetElement(0));
  692. BinaryPrimitives.WriteUInt64LittleEndian(t[8..], u.GetElement(1));
  693. #endif
  694. }
  695. }
  696. }
  697. #endif
  698. #pragma warning restore
  699. #endif