Simple AES chat program
Du kannst nicht mehr als 25 Themen auswählen Themen müssen mit entweder einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295
  1. // I'm aware that this file is written horribly and dooesn't have inverse functions
  2. #include <stdlib.h>
  3. #include <stdio.h>
  4. #include <stdint.h>
  5. #include <string.h>
  6. #define LROT8(v, b) ((v) << (b) | (v) >> (8 - (b)))
  7. #define LROT32(v, b) ((v) << (b) | (v) >> (32 - (b)))
  8. char sbox[256], inv_sbox[256];
  9. struct polydiv_result
  10. {
  11. uint16_t q;
  12. uint16_t r;
  13. };
  14. struct polyeeuclid_result
  15. {
  16. uint16_t u;
  17. uint16_t v;
  18. uint16_t g;
  19. };
  20. static uint16_t msb(uint16_t x)
  21. {
  22. x |= x >> 1;
  23. x |= x >> 2;
  24. x |= x >> 4;
  25. x |= x >> 8;
  26. x ^= (x >> 1);
  27. return x;
  28. }
  29. static uint16_t poly_mult(uint16_t multiplicand, uint16_t multiplier)
  30. {
  31. uint16_t accum = 0;
  32. int ii;
  33. for (ii = 0; ii < 16; ii++)
  34. {
  35. if (multiplier & 1)
  36. accum ^= multiplicand;
  37. multiplier >>= 1;
  38. multiplicand <<= 1;
  39. }
  40. return accum;
  41. }
  42. static void poly_div(uint16_t dividend, uint16_t divisor, struct polydiv_result *out)
  43. {
  44. uint16_t quotient = 0;
  45. if (divisor == 0)
  46. return;
  47. while (msb(dividend) >= msb(divisor))
  48. {
  49. uint16_t intermittent = msb(dividend) / msb(divisor);
  50. quotient ^= intermittent;
  51. dividend ^= divisor * intermittent;
  52. }
  53. out->q = quotient;
  54. out->r = dividend;
  55. }
  56. static uint16_t poly_mult_mod(uint16_t a, uint16_t b, uint16_t m)
  57. {
  58. struct polydiv_result qr;
  59. poly_div(poly_mult(a, b), m, &qr);
  60. return qr.r;
  61. }
  62. static void poly_eeuclid(uint16_t a, uint16_t b, struct polyeeuclid_result *out)
  63. {
  64. struct polydiv_result qr;
  65. uint16_t x0 = 1, y0 = 0, x1 = 0, y1 = 1;
  66. poly_div(a, b, &qr);
  67. while (qr.r)
  68. {
  69. uint16_t xn = x0 ^ poly_mult(qr.q, x1), yn = y0 ^ poly_mult(qr.q, y1);
  70. a = b;
  71. b = qr.r;
  72. poly_div(a, b, &qr);
  73. x0 = x1;
  74. y0 = y1;
  75. x1 = xn;
  76. y1 = yn;
  77. }
  78. out->g = b;
  79. out->u = x1;
  80. out->v = y1;
  81. }
  82. //void print_poly(uint16_t p)
  83. //{
  84. // int ii;
  85. // for (ii = 0; ii < 16; ii++)
  86. // {
  87. // printf((p & 32768) ? "1" : "0");
  88. // p <<= 1;
  89. // }
  90. // printf("\n");
  91. //}
  92. static uint8_t inv_Rijndael(uint8_t p)
  93. {
  94. if (!p)
  95. return 0;
  96. struct polyeeuclid_result guv;
  97. poly_eeuclid(p, 0x11b, &guv);
  98. return (uint8_t) guv.u;
  99. }
  100. static uint8_t Nyberg(uint8_t i)
  101. {
  102. return i ^ LROT8(i, 1) ^ LROT8(i, 2) ^ LROT8(i, 3) ^ LROT8(i, 4) ^ 0x63;
  103. }
  104. static uint8_t sbox_transform(uint8_t i)
  105. {
  106. return Nyberg(inv_Rijndael(i));
  107. }
  108. void initializeSBox()
  109. {
  110. int ii;
  111. for (ii = 0; ii < 256; ii++)
  112. {
  113. uint8_t in = (uint8_t) ii;
  114. uint8_t out = sbox_transform(ii);
  115. sbox[in] = out;
  116. inv_sbox[out] = in;
  117. }
  118. }
  119. static uint32_t wordSBox(uint32_t word)
  120. {
  121. return
  122. (sbox[(uint8_t) word]) |
  123. (sbox[(uint8_t) (word >> 8)] << 8) |
  124. (sbox[(uint8_t) (word >> 16)] << 16) |
  125. (sbox[(uint8_t) (word >> 24)] << 24);
  126. }
  127. void expandKey(uint32_t short_key[8], uint32_t expanded_key[60])
  128. {
  129. // TODO: Make the round constants constant
  130. uint8_t rcs[8] = {1};
  131. int ii;
  132. for (ii = 1; ii < 8; ii++)
  133. {
  134. if (rcs[ii - 1] < 0x80)
  135. {
  136. rcs[ii] = rcs[ii - 1] << 1;
  137. } else
  138. {
  139. rcs[ii] = 0x1b ^ (rcs[ii - 1] << 1);
  140. }
  141. }
  142. memcpy(expanded_key, short_key, 8 * sizeof(uint32_t));
  143. int rci = 0;
  144. for (ii = 8; ii < 60; ii++)
  145. {
  146. if (ii % 8 == 0)
  147. {
  148. expanded_key[ii] = expanded_key[ii - 8] ^ wordSBox(LROT32(expanded_key[ii - 1], 8)) ^ (rcs[rci] << 24);
  149. rci++;
  150. } else if (ii % 8 == 4)
  151. {
  152. expanded_key[ii] = expanded_key[ii - 8] ^ wordSBox(expanded_key[ii - 1]);
  153. } else
  154. {
  155. expanded_key[ii] = expanded_key[ii - 8] ^ expanded_key[ii - 1];
  156. }
  157. }
  158. }
  159. void AESRound(uint32_t state[4], uint32_t key[60])
  160. {
  161. int ii, ij;
  162. for (ii = 0; ii < 4; ii++)
  163. {
  164. state[ii] ^= *key;
  165. key++;
  166. }
  167. for (ij = 0; ij < 13; ij++)
  168. {
  169. for (ii = 0; ii < 4; ii++)
  170. state[ii] = wordSBox(state[ii]);
  171. for (ii = 0; ii < 4; ii++)
  172. state[ii] = LROT32(state[ii], 8 * ii);
  173. uint32_t newstate[4] = {0};
  174. for (ii = 0; ii < 4; ii++)
  175. {
  176. int shc = 8 * ii;
  177. newstate[0] |= (poly_mult_mod((uint8_t) (state[0] >> shc), 2, 0x11b) ^
  178. poly_mult_mod((uint8_t) (state[1] >> shc), 3, 0x11b) ^
  179. ((uint8_t) (state[2] >> shc)) ^ ((uint8_t) (state[3] >> shc))) << shc;
  180. newstate[1] |= (poly_mult_mod((uint8_t) (state[1] >> shc), 2, 0x11b) ^
  181. poly_mult_mod((uint8_t) (state[2] >> shc), 3, 0x11b) ^
  182. ((uint8_t) (state[3] >> shc)) ^ ((uint8_t) (state[0] >> shc))) << shc;
  183. newstate[2] |= (poly_mult_mod((uint8_t) (state[2] >> shc), 2, 0x11b) ^
  184. poly_mult_mod((uint8_t) (state[3] >> shc), 3, 0x11b) ^
  185. ((uint8_t) (state[0] >> shc)) ^ ((uint8_t) (state[1] >> shc))) << shc;
  186. newstate[3] |= (poly_mult_mod((uint8_t) (state[3] >> shc), 2, 0x11b) ^
  187. poly_mult_mod((uint8_t) (state[0] >> shc), 3, 0x11b) ^
  188. ((uint8_t) (state[1] >> shc)) ^ ((uint8_t) (state[2] >> shc))) << shc;
  189. }
  190. memcpy(state, newstate, 4 * sizeof(uint32_t));
  191. for (ii = 0; ii < 4; ii++)
  192. {
  193. state[ii] ^= *key;
  194. key++;
  195. }
  196. }
  197. for (ii = 0; ii < 4; ii++)
  198. state[ii] = wordSBox(state[ii]);
  199. for (ii = 0; ii < 4; ii++)
  200. state[ii] = LROT32(state[ii], 8 * ii);
  201. for (ii = 0; ii < 4; ii++)
  202. {
  203. state[ii] ^= *key;
  204. key++;
  205. }
  206. }
  207. void dataToState(char data[16], uint32_t state[4])
  208. {
  209. int ii;
  210. for (ii = 0; ii < 4; ii++)
  211. {
  212. state[ii] = data[0] | (data[1] << 8) | (data[2] << 16) | (data[3] << 24);
  213. data += 4;
  214. }
  215. }
  216. void stateToData(uint32_t state[4], char data[16])
  217. {
  218. int ii, ij;;
  219. for (ii = 0; ii < 4; ii++)
  220. {
  221. uint32_t d = state[ii];
  222. for (ij = 0; ij < 4; ij++)
  223. {
  224. *data = d;
  225. data++;
  226. d >>= 8;
  227. }
  228. }
  229. }
  230. void AESRound_data(char data[16], uint32_t key[60])
  231. {
  232. uint32_t state[4];
  233. dataToState(data, state);
  234. AESRound(state, key);
  235. stateToData(state, data);
  236. }
  237. //int main()
  238. //{
  239. // int ii;
  240. // //for (ii = 0; ii < 256; ii++)
  241. // //{
  242. // // printf("%02x %02x %02x\n", ii & 0xf0, ii & 0x0f, sbox_transform(ii));
  243. // //}
  244. //
  245. // uint8_t state[4] = {0xf2, 0x0a, 0x22, 0x5c};
  246. // uint8_t newstate[4] = {0};
  247. // int shc = 0;
  248. // newstate[0] |= (poly_mult_mod((uint8_t) (state[0] >> shc), 2, 0x11b) ^
  249. // poly_mult_mod((uint8_t) (state[1] >> shc), 3, 0x11b) ^
  250. // ((uint8_t) (state[2] >> shc)) ^ ((uint8_t) (state[3] >> shc))) << shc;
  251. // newstate[1] |= (poly_mult_mod((uint8_t) (state[1] >> shc), 2, 0x11b) ^
  252. // poly_mult_mod((uint8_t) (state[2] >> shc), 3, 0x11b) ^
  253. // ((uint8_t) (state[3] >> shc)) ^ ((uint8_t) (state[0] >> shc))) << shc;
  254. // newstate[2] |= (poly_mult_mod((uint8_t) (state[2] >> shc), 2, 0x11b) ^
  255. // poly_mult_mod((uint8_t) (state[3] >> shc), 3, 0x11b) ^
  256. // ((uint8_t) (state[0] >> shc)) ^ ((uint8_t) (state[1] >> shc))) << shc;
  257. // newstate[3] |= (poly_mult_mod((uint8_t) (state[3] >> shc), 2, 0x11b) ^
  258. // poly_mult_mod((uint8_t) (state[0] >> shc), 3, 0x11b) ^
  259. // ((uint8_t) (state[1] >> shc)) ^ ((uint8_t) (state[2] >> shc))) << shc;
  260. //
  261. // for (ii = 0; ii < 4; ii++)
  262. // {
  263. // printf("%02x ", newstate[ii]);
  264. // }
  265. // printf("\n");
  266. // return 0;
  267. //}
  268. //