GcmUtilities.cs 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357
  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.Modes.Gcm
  7. {
  8. internal abstract class GcmUtilities
  9. {
  10. private const uint E1 = 0xe1000000;
  11. private const ulong E1L = (ulong)E1 << 32;
  12. private static uint[] GenerateLookup()
  13. {
  14. uint[] lookup = new uint[256];
  15. for (int c = 0; c < 256; ++c)
  16. {
  17. uint v = 0;
  18. for (int i = 7; i >= 0; --i)
  19. {
  20. if ((c & (1 << i)) != 0)
  21. {
  22. v ^= (E1 >> (7 - i));
  23. }
  24. }
  25. lookup[c] = v;
  26. }
  27. return lookup;
  28. }
  29. private static readonly uint[] LOOKUP = GenerateLookup();
  30. internal static byte[] OneAsBytes()
  31. {
  32. byte[] tmp = new byte[16];
  33. tmp[0] = 0x80;
  34. return tmp;
  35. }
  36. internal static uint[] OneAsUints()
  37. {
  38. uint[] tmp = new uint[4];
  39. tmp[0] = 0x80000000;
  40. return tmp;
  41. }
  42. internal static ulong[] OneAsUlongs()
  43. {
  44. ulong[] tmp = new ulong[2];
  45. tmp[0] = 1UL << 63;
  46. return tmp;
  47. }
  48. internal static byte[] AsBytes(uint[] x)
  49. {
  50. return Pack.UInt32_To_BE(x);
  51. }
  52. internal static void AsBytes(uint[] x, byte[] z)
  53. {
  54. Pack.UInt32_To_BE(x, z, 0);
  55. }
  56. internal static byte[] AsBytes(ulong[] x)
  57. {
  58. byte[] z = new byte[16];
  59. Pack.UInt64_To_BE(x, z, 0);
  60. return z;
  61. }
  62. internal static void AsBytes(ulong[] x, byte[] z)
  63. {
  64. Pack.UInt64_To_BE(x, z, 0);
  65. }
  66. internal static uint[] AsUints(byte[] bs)
  67. {
  68. uint[] output = new uint[4];
  69. Pack.BE_To_UInt32(bs, 0, output);
  70. return output;
  71. }
  72. internal static void AsUints(byte[] bs, uint[] output)
  73. {
  74. Pack.BE_To_UInt32(bs, 0, output);
  75. }
  76. internal static ulong[] AsUlongs(byte[] x)
  77. {
  78. ulong[] z = new ulong[2];
  79. Pack.BE_To_UInt64(x, 0, z);
  80. return z;
  81. }
  82. public static void AsUlongs(byte[] x, ulong[] z)
  83. {
  84. Pack.BE_To_UInt64(x, 0, z);
  85. }
  86. internal static void Multiply(byte[] x, byte[] y)
  87. {
  88. uint[] t1 = GcmUtilities.AsUints(x);
  89. uint[] t2 = GcmUtilities.AsUints(y);
  90. GcmUtilities.Multiply(t1, t2);
  91. GcmUtilities.AsBytes(t1, x);
  92. }
  93. internal static void Multiply(uint[] x, uint[] y)
  94. {
  95. uint r00 = x[0], r01 = x[1], r02 = x[2], r03 = x[3];
  96. uint r10 = 0, r11 = 0, r12 = 0, r13 = 0;
  97. for (int i = 0; i < 4; ++i)
  98. {
  99. int bits = (int)y[i];
  100. for (int j = 0; j < 32; ++j)
  101. {
  102. uint m1 = (uint)(bits >> 31); bits <<= 1;
  103. r10 ^= (r00 & m1);
  104. r11 ^= (r01 & m1);
  105. r12 ^= (r02 & m1);
  106. r13 ^= (r03 & m1);
  107. uint m2 = (uint)((int)(r03 << 31) >> 8);
  108. r03 = (r03 >> 1) | (r02 << 31);
  109. r02 = (r02 >> 1) | (r01 << 31);
  110. r01 = (r01 >> 1) | (r00 << 31);
  111. r00 = (r00 >> 1) ^ (m2 & E1);
  112. }
  113. }
  114. x[0] = r10;
  115. x[1] = r11;
  116. x[2] = r12;
  117. x[3] = r13;
  118. }
  119. internal static void Multiply(ulong[] x, ulong[] y)
  120. {
  121. ulong r00 = x[0], r01 = x[1], r10 = 0, r11 = 0;
  122. for (int i = 0; i < 2; ++i)
  123. {
  124. long bits = (long)y[i];
  125. for (int j = 0; j < 64; ++j)
  126. {
  127. ulong m1 = (ulong)(bits >> 63); bits <<= 1;
  128. r10 ^= (r00 & m1);
  129. r11 ^= (r01 & m1);
  130. ulong m2 = (ulong)((long)(r01 << 63) >> 8);
  131. r01 = (r01 >> 1) | (r00 << 63);
  132. r00 = (r00 >> 1) ^ (m2 & E1L);
  133. }
  134. }
  135. x[0] = r10;
  136. x[1] = r11;
  137. }
  138. // P is the value with only bit i=1 set
  139. internal static void MultiplyP(uint[] x)
  140. {
  141. uint m = (uint)((int)ShiftRight(x) >> 8);
  142. x[0] ^= (m & E1);
  143. }
  144. internal static void MultiplyP(uint[] x, uint[] z)
  145. {
  146. uint m = (uint)((int)ShiftRight(x, z) >> 8);
  147. z[0] ^= (m & E1);
  148. }
  149. internal static void MultiplyP8(uint[] x)
  150. {
  151. // for (int i = 8; i != 0; --i)
  152. // {
  153. // MultiplyP(x);
  154. // }
  155. uint c = ShiftRightN(x, 8);
  156. x[0] ^= LOOKUP[c >> 24];
  157. }
  158. internal static void MultiplyP8(uint[] x, uint[] y)
  159. {
  160. uint c = ShiftRightN(x, 8, y);
  161. y[0] ^= LOOKUP[c >> 24];
  162. }
  163. internal static uint ShiftRight(uint[] x)
  164. {
  165. uint b = x[0];
  166. x[0] = b >> 1;
  167. uint c = b << 31;
  168. b = x[1];
  169. x[1] = (b >> 1) | c;
  170. c = b << 31;
  171. b = x[2];
  172. x[2] = (b >> 1) | c;
  173. c = b << 31;
  174. b = x[3];
  175. x[3] = (b >> 1) | c;
  176. return b << 31;
  177. }
  178. internal static uint ShiftRight(uint[] x, uint[] z)
  179. {
  180. uint b = x[0];
  181. z[0] = b >> 1;
  182. uint c = b << 31;
  183. b = x[1];
  184. z[1] = (b >> 1) | c;
  185. c = b << 31;
  186. b = x[2];
  187. z[2] = (b >> 1) | c;
  188. c = b << 31;
  189. b = x[3];
  190. z[3] = (b >> 1) | c;
  191. return b << 31;
  192. }
  193. internal static uint ShiftRightN(uint[] x, int n)
  194. {
  195. uint b = x[0]; int nInv = 32 - n;
  196. x[0] = b >> n;
  197. uint c = b << nInv;
  198. b = x[1];
  199. x[1] = (b >> n) | c;
  200. c = b << nInv;
  201. b = x[2];
  202. x[2] = (b >> n) | c;
  203. c = b << nInv;
  204. b = x[3];
  205. x[3] = (b >> n) | c;
  206. return b << nInv;
  207. }
  208. internal static uint ShiftRightN(uint[] x, int n, uint[] z)
  209. {
  210. uint b = x[0]; int nInv = 32 - n;
  211. z[0] = b >> n;
  212. uint c = b << nInv;
  213. b = x[1];
  214. z[1] = (b >> n) | c;
  215. c = b << nInv;
  216. b = x[2];
  217. z[2] = (b >> n) | c;
  218. c = b << nInv;
  219. b = x[3];
  220. z[3] = (b >> n) | c;
  221. return b << nInv;
  222. }
  223. internal static void Xor(byte[] x, byte[] y)
  224. {
  225. int i = 0;
  226. do
  227. {
  228. x[i] ^= y[i]; ++i;
  229. x[i] ^= y[i]; ++i;
  230. x[i] ^= y[i]; ++i;
  231. x[i] ^= y[i]; ++i;
  232. }
  233. while (i < 16);
  234. }
  235. internal static void Xor(byte[] x, byte[] y, int yOff)
  236. {
  237. int i = 0;
  238. do
  239. {
  240. x[i] ^= y[yOff + i]; ++i;
  241. x[i] ^= y[yOff + i]; ++i;
  242. x[i] ^= y[yOff + i]; ++i;
  243. x[i] ^= y[yOff + i]; ++i;
  244. }
  245. while (i < 16);
  246. }
  247. internal static void Xor(byte[] x, int xOff, byte[] y, int yOff, byte[] z, int zOff)
  248. {
  249. int i = 0;
  250. do
  251. {
  252. z[zOff + i] = (byte)(x[xOff + i] ^ y[yOff + i]); ++i;
  253. z[zOff + i] = (byte)(x[xOff + i] ^ y[yOff + i]); ++i;
  254. z[zOff + i] = (byte)(x[xOff + i] ^ y[yOff + i]); ++i;
  255. z[zOff + i] = (byte)(x[xOff + i] ^ y[yOff + i]); ++i;
  256. }
  257. while (i < 16);
  258. }
  259. internal static void Xor(byte[] x, byte[] y, int yOff, int yLen)
  260. {
  261. while (--yLen >= 0)
  262. {
  263. x[yLen] ^= y[yOff + yLen];
  264. }
  265. }
  266. internal static void Xor(byte[] x, int xOff, byte[] y, int yOff, int len)
  267. {
  268. while (--len >= 0)
  269. {
  270. x[xOff + len] ^= y[yOff + len];
  271. }
  272. }
  273. internal static void Xor(byte[] x, byte[] y, byte[] z)
  274. {
  275. int i = 0;
  276. do
  277. {
  278. z[i] = (byte)(x[i] ^ y[i]); ++i;
  279. z[i] = (byte)(x[i] ^ y[i]); ++i;
  280. z[i] = (byte)(x[i] ^ y[i]); ++i;
  281. z[i] = (byte)(x[i] ^ y[i]); ++i;
  282. }
  283. while (i < 16);
  284. }
  285. internal static void Xor(uint[] x, uint[] y)
  286. {
  287. x[0] ^= y[0];
  288. x[1] ^= y[1];
  289. x[2] ^= y[2];
  290. x[3] ^= y[3];
  291. }
  292. internal static void Xor(uint[] x, uint[] y, uint[] z)
  293. {
  294. z[0] = x[0] ^ y[0];
  295. z[1] = x[1] ^ y[1];
  296. z[2] = x[2] ^ y[2];
  297. z[3] = x[3] ^ y[3];
  298. }
  299. internal static void Xor(ulong[] x, ulong[] y)
  300. {
  301. x[0] ^= y[0];
  302. x[1] ^= y[1];
  303. }
  304. internal static void Xor(ulong[] x, ulong[] y, ulong[] z)
  305. {
  306. z[0] = x[0] ^ y[0];
  307. z[1] = x[1] ^ y[1];
  308. }
  309. }
  310. }
  311. #pragma warning restore
  312. #endif