mix_decode.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439
  1. /*
  2. XCC Utilities and Library
  3. Copyright (C) 2000 Olaf van der Spek <[email protected]>
  4. This program is free software: you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation, either version 3 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program. If not, see <https://www.gnu.org/licenses/>.
  14. */
  15. #include "stdafx.h"
  16. #include <memory>
  17. #include <mix_decode.h>
  18. const static char* pubkey_str = "AihRvNoIbTn85FZRYNZRcT+i6KpU+maCsEqr3Q5q+LDB5tH7Tz2qQ38V";
  19. const static char char2num[] =
  20. {
  21. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  22. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  23. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63,
  24. 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1,
  25. -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
  26. 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,
  27. -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
  28. 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1,
  29. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  30. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  31. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  32. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  33. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  34. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  35. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  36. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
  37. };
  38. using word = unsigned short;
  39. using bignum = uint32_t[64];
  40. static struct
  41. {
  42. bignum key1;
  43. bignum key2;
  44. uint32_t len;
  45. } pubkey;
  46. static bignum glob1;
  47. static uint32_t glob1_bitlen;
  48. static uint32_t glob1_len_x2;
  49. static uint32_t glob2[130];
  50. static uint32_t glob1_hi[4];
  51. static uint32_t glob1_hi_inv[4];
  52. static uint32_t glob1_hi_bitlen;
  53. static uint32_t glob1_hi_inv_lo;
  54. static uint32_t glob1_hi_inv_hi;
  55. static void init_bignum(bignum n, uint32_t val, uint32_t len)
  56. {
  57. memset(n, 0, len * 4);
  58. n[0] = val;
  59. }
  60. static void move_key_to_big(bignum n, const char* key, uint32_t klen, uint32_t blen)
  61. {
  62. uint32_t sign = key[0] & 0x80 ? 0xff : 0;
  63. int i = blen * 4;
  64. for (; i > klen; i--)
  65. ((char *)n)[i - 1] = sign;
  66. for (; i > 0; i--)
  67. ((char *)n)[i - 1] = key[klen - i];
  68. }
  69. static void key_to_bignum(bignum n, char *key, uint32_t len)
  70. {
  71. uint32_t keylen;
  72. int i;
  73. if (key[0] != 2)
  74. return;
  75. key++;
  76. if (key[0] & 0x80)
  77. {
  78. keylen = 0;
  79. for (i = 0; i < (key[0] & 0x7f); i++) keylen = (keylen << 8) | key[i+1];
  80. key += (key[0] & 0x7f) + 1;
  81. }
  82. else
  83. {
  84. keylen = key[0];
  85. key++;
  86. }
  87. if (keylen <= len * 4)
  88. move_key_to_big(n, key, keylen, len);
  89. }
  90. static uint32_t len_bignum(bignum n, uint32_t len)
  91. {
  92. int i = len - 1;
  93. while (i >= 0 && n[i] == 0)
  94. i--;
  95. return i + 1;
  96. }
  97. static uint32_t bitlen_bignum(bignum n, uint32_t len)
  98. {
  99. uint32_t ddlen = len_bignum(n, len);
  100. if (ddlen == 0)
  101. return 0;
  102. uint32_t bitlen = ddlen * 32;
  103. uint32_t mask = 0x80000000;
  104. while ((mask & n[ddlen - 1]) == 0)
  105. {
  106. mask >>= 1;
  107. bitlen--;
  108. }
  109. return bitlen;
  110. }
  111. static void init_pubkey()
  112. {
  113. init_bignum(pubkey.key2, 0x10001, 64);
  114. char keytmp[256];
  115. uint32_t i2 = 0;
  116. for (uint32_t i = 0; i < strlen(pubkey_str);)
  117. {
  118. uint32_t tmp = char2num[pubkey_str[i++]];
  119. tmp <<= 6; tmp |= char2num[pubkey_str[i++]];
  120. tmp <<= 6; tmp |= char2num[pubkey_str[i++]];
  121. tmp <<= 6; tmp |= char2num[pubkey_str[i++]];
  122. keytmp[i2++] = (tmp >> 16) & 0xff;
  123. keytmp[i2++] = (tmp >> 8) & 0xff;
  124. keytmp[i2++] = tmp & 0xff;
  125. }
  126. key_to_bignum(pubkey.key1, keytmp, 64);
  127. pubkey.len = bitlen_bignum(pubkey.key1, 64) - 1;
  128. }
  129. static uint32_t len_predata()
  130. {
  131. uint32_t a = (pubkey.len - 1) / 8;
  132. return (55 / a + 1) * (a + 1);
  133. }
  134. static int cmp_bignum(bignum n1, bignum n2, uint32_t len)
  135. {
  136. n1 += len - 1;
  137. n2 += len - 1;
  138. while (len > 0)
  139. {
  140. if (*n1 < *n2) return -1;
  141. if (*n1 > *n2) return 1;
  142. n1--;
  143. n2--;
  144. len--;
  145. }
  146. return 0;
  147. }
  148. static void mov_bignum(bignum dest, bignum src, uint32_t len)
  149. {
  150. memmove(dest, src, len * 4);
  151. }
  152. static void shr_bignum(bignum n, uint32_t bits, long int len)
  153. {
  154. uint32_t i;
  155. if (uint32_t i2 = bits / 32)
  156. {
  157. for (i = 0; i < len - i2; i++)
  158. n[i] = n[i + i2];
  159. for (; i < len; i++)
  160. n[i] = 0;
  161. bits %= 32;
  162. }
  163. if (!bits)
  164. return;
  165. for (i = 0; i < len - 1; i++)
  166. n[i] = (n[i] >> bits) | (n[i + 1] << (32 - bits));
  167. n[i] >>= bits;
  168. }
  169. static void shl_bignum(bignum n, uint32_t bits, uint32_t len)
  170. {
  171. uint32_t i;
  172. if (uint32_t i2 = bits / 32)
  173. {
  174. for (i = len - 1; i > i2; i--)
  175. n[i] = n[i - i2];
  176. for (; i > 0; i--)
  177. n[i] = 0;
  178. bits %= 32;
  179. }
  180. if (!bits)
  181. return;
  182. for (i = len - 1; i > 0; i--)
  183. n[i] = (n[i] << bits) | (n[i - 1] >> (32 - bits));
  184. n[0] <<= bits;
  185. }
  186. static uint32_t sub_bignum(bignum dest, bignum src1, bignum src2, uint32_t carry, uint32_t len)
  187. {
  188. len *= 2;
  189. while (--len != -1)
  190. {
  191. uint32_t i1 = *(word *)src1;
  192. uint32_t i2 = *(word *)src2;
  193. *(word *)dest = i1 - i2 - carry;
  194. src1 = (uint32_t *)(((word *)src1) + 1);
  195. src2 = (uint32_t *)(((word *)src2) + 1);
  196. dest = (uint32_t *)(((word *)dest) + 1);
  197. carry = ((i1 - i2 - carry) & 0x10000) ? 1 : 0;
  198. }
  199. return carry;
  200. }
  201. static void inv_bignum(bignum n1, bignum n2, uint32_t len)
  202. {
  203. bignum n_tmp;
  204. init_bignum(n_tmp, 0, len);
  205. init_bignum(n1, 0, len);
  206. int n2_bitlen = bitlen_bignum(n2, len);
  207. uint32_t bit = ((uint32_t)1) << (n2_bitlen % 32);
  208. n1 += ((n2_bitlen + 32) / 32) - 1;
  209. uint32_t n2_bytelen = ((n2_bitlen - 1) / 32) * 4;
  210. n_tmp[n2_bytelen / 4] |= ((uint32_t)1) << ((n2_bitlen - 1) & 0x1f);
  211. while (n2_bitlen > 0)
  212. {
  213. n2_bitlen--;
  214. shl_bignum(n_tmp, 1, len);
  215. if (cmp_bignum(n_tmp, n2, len) != -1)
  216. {
  217. sub_bignum(n_tmp, n_tmp, n2, 0, len);
  218. *n1 |= bit;
  219. }
  220. bit >>= 1;
  221. if (bit == 0)
  222. {
  223. n1--;
  224. bit = 0x80000000;
  225. }
  226. }
  227. init_bignum(n_tmp, 0, len);
  228. }
  229. static void inc_bignum(bignum n, uint32_t len)
  230. {
  231. while ((++*n == 0) && (--len > 0))
  232. n++;
  233. }
  234. static void init_two_dw(bignum n, uint32_t len)
  235. {
  236. mov_bignum(glob1, n, len);
  237. glob1_bitlen = bitlen_bignum(glob1, len);
  238. glob1_len_x2 = (glob1_bitlen + 15) / 16;
  239. mov_bignum(glob1_hi, glob1 + len_bignum(glob1, len) - 2, 2);
  240. glob1_hi_bitlen = bitlen_bignum(glob1_hi, 2) - 32;
  241. shr_bignum(glob1_hi, glob1_hi_bitlen, 2);
  242. inv_bignum(glob1_hi_inv, glob1_hi, 2);
  243. shr_bignum(glob1_hi_inv, 1, 2);
  244. glob1_hi_bitlen = (glob1_hi_bitlen + 15) % 16 + 1;
  245. inc_bignum(glob1_hi_inv, 2);
  246. if (bitlen_bignum(glob1_hi_inv, 2) > 32)
  247. {
  248. shr_bignum(glob1_hi_inv, 1, 2);
  249. glob1_hi_bitlen--;
  250. }
  251. glob1_hi_inv_lo = *(word *)glob1_hi_inv;
  252. glob1_hi_inv_hi = *(((word *)glob1_hi_inv) + 1);
  253. }
  254. static void mul_bignum_word(bignum n1, bignum n2, uint32_t mul, uint32_t len)
  255. {
  256. uint32_t tmp = 0;
  257. for (uint32_t i = 0; i < len; i++)
  258. {
  259. tmp = mul * (*(word *)n2) + *(word *)n1 + tmp;
  260. *(word *)n1 = tmp;
  261. n1 = (uint32_t *)(((word *)n1) + 1);
  262. n2 = (uint32_t *)(((word *)n2) + 1);
  263. tmp >>= 16;
  264. }
  265. *(word *)n1 += tmp;
  266. }
  267. static void mul_bignum(bignum dest, bignum src1, bignum src2, uint32_t len)
  268. {
  269. init_bignum(dest, 0, len * 2);
  270. for (uint32_t i = 0; i < len * 2; i++)
  271. {
  272. mul_bignum_word(dest, src1, *(word *)src2, len * 2);
  273. src2 = (uint32_t *)(((word *)src2) + 1);
  274. dest = (uint32_t *)(((word *)dest) + 1);
  275. }
  276. }
  277. static void not_bignum(bignum n, uint32_t len)
  278. {
  279. for (uint32_t i = 0; i < len; i++)
  280. *(n++) = ~*n;
  281. }
  282. static void neg_bignum(bignum n, uint32_t len)
  283. {
  284. not_bignum(n, len);
  285. inc_bignum(n, len);
  286. }
  287. static uint32_t get_mulword(bignum n)
  288. {
  289. word* wn = (word *)n;
  290. uint32_t i = (((((((((*(wn - 1) ^ 0xffff) & 0xffff) * glob1_hi_inv_lo + 0x10000) >> 1)
  291. + (((*(wn-2) ^ 0xffff) * glob1_hi_inv_hi + glob1_hi_inv_hi) >> 1) + 1)
  292. >> 16) + ((((*(wn-1) ^ 0xffff) & 0xffff) * glob1_hi_inv_hi) >> 1) +
  293. (((*wn ^ 0xffff) * glob1_hi_inv_lo) >> 1) + 1) >> 14) + glob1_hi_inv_hi
  294. * (*wn ^ 0xffff) * 2) >> glob1_hi_bitlen;
  295. if (i > 0xffff)
  296. i = 0xffff;
  297. return i & 0xffff;
  298. }
  299. static void dec_bignum(bignum n, uint32_t len)
  300. {
  301. while ((--*n == 0xffffffff) && (--len > 0))
  302. n++;
  303. }
  304. static void calc_a_bignum(bignum n1, bignum n2, bignum n3, uint32_t len)
  305. {
  306. mul_bignum(glob2, n2, n3, len);
  307. glob2[len * 2] = 0;
  308. uint32_t g2_len_x2 = len_bignum(glob2, len * 2 + 1) * 2;
  309. if (g2_len_x2 >= glob1_len_x2)
  310. {
  311. inc_bignum(glob2, len * 2 + 1);
  312. neg_bignum(glob2, len * 2 + 1);
  313. uint32_t len_diff = g2_len_x2 + 1 - glob1_len_x2;
  314. word* esi = ((word *)glob2) + (1 + g2_len_x2 - glob1_len_x2);
  315. word* edi = ((word *)glob2) + (g2_len_x2 + 1);
  316. for (; len_diff != 0; len_diff--)
  317. {
  318. edi--;
  319. word tmp = get_mulword((uint32_t *)edi);
  320. esi--;
  321. if (tmp > 0)
  322. {
  323. mul_bignum_word((uint32_t *)esi, glob1, tmp, 2 * len);
  324. if ((*edi & 0x8000) == 0)
  325. {
  326. if (sub_bignum((uint32_t *)esi, (uint32_t *)esi, glob1, 0, len))
  327. (*edi)--;
  328. }
  329. }
  330. }
  331. neg_bignum(glob2, len);
  332. dec_bignum(glob2, len);
  333. }
  334. mov_bignum(n1, glob2, len);
  335. }
  336. static void calc_a_key(bignum n1, bignum n2, bignum n3, bignum n4, uint32_t len)
  337. {
  338. bignum n_tmp;
  339. init_bignum(n1, 1, len);
  340. uint32_t n4_len = len_bignum(n4, len);
  341. init_two_dw(n4, n4_len);
  342. uint32_t n3_bitlen = bitlen_bignum(n3, n4_len);
  343. uint32_t n3_len = (n3_bitlen + 31) / 32;
  344. uint32_t bit_mask = (((uint32_t)1) << ((n3_bitlen - 1) % 32)) >> 1;
  345. n3 += n3_len - 1;
  346. n3_bitlen--;
  347. mov_bignum(n1, n2, n4_len);
  348. while (--n3_bitlen != -1)
  349. {
  350. if (bit_mask == 0)
  351. {
  352. bit_mask = 0x80000000;
  353. n3--;
  354. }
  355. calc_a_bignum(n_tmp, n1, n1, n4_len);
  356. if (*n3 & bit_mask)
  357. calc_a_bignum(n1, n_tmp, n2, n4_len);
  358. else
  359. mov_bignum(n1, n_tmp, n4_len);
  360. bit_mask >>= 1;
  361. }
  362. init_bignum(n_tmp, 0, n4_len);
  363. init_bignum(glob1, 0, len);
  364. init_bignum(glob2, 0, len);
  365. init_bignum(glob1_hi_inv, 0, 4);
  366. init_bignum(glob1_hi, 0, 4);
  367. glob1_bitlen = 0;
  368. glob1_hi_bitlen = 0;
  369. glob1_len_x2 = 0;
  370. glob1_hi_inv_lo = 0;
  371. glob1_hi_inv_hi = 0;
  372. }
  373. static void process_predata(const byte* pre, uint32_t pre_len, byte *buf)
  374. {
  375. bignum n2, n3;
  376. const uint32_t a = (pubkey.len - 1) / 8;
  377. while (a + 1 <= pre_len)
  378. {
  379. init_bignum(n2, 0, 64);
  380. memmove(n2, pre, a + 1);
  381. calc_a_key(n3, n2, pubkey.key2, pubkey.key1, 64);
  382. memmove(buf, n3, a);
  383. pre_len -= a + 1;
  384. pre += a + 1;
  385. buf += a;
  386. }
  387. }
  388. void get_blowfish_key(const byte* s, span<byte> d)
  389. {
  390. static bool public_key_initialized = false;
  391. if (!public_key_initialized)
  392. {
  393. init_pubkey();
  394. public_key_initialized = true;
  395. }
  396. byte key[256];
  397. process_predata(s, len_predata(), key);
  398. memcpy(d.data(), key, 56);
  399. }