Shannon.cpp 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393
  1. #include "Shannon.h"
  2. #include <limits.h> // for CHAR_BIT
  3. #include <stddef.h> // for size_t
  4. using std::size_t;
  5. static inline uint32_t rotl(uint32_t n, unsigned int c) {
  6. const unsigned int mask =
  7. (CHAR_BIT * sizeof(n) - 1); // assumes width is a power of 2.
  8. // assert ( (c<=mask) &&"rotate by type width or more");
  9. c &= mask;
  10. return (n << c) | (n >> ((-c) & mask));
  11. }
  12. static inline uint32_t rotr(uint32_t n, unsigned int c) {
  13. const unsigned int mask =
  14. (CHAR_BIT * sizeof(n) - 1); // assumes width is a power of 2.
  15. // assert ( (c<=mask) &&"rotate by type width or more");
  16. c &= mask;
  17. return (n >> c) | (n << ((-c) & mask));
  18. }
  19. uint32_t Shannon::sbox1(uint32_t w) {
  20. w ^= rotl(w, 5) | rotl(w, 7);
  21. w ^= rotl(w, 19) | rotl(w, 22);
  22. return w;
  23. }
  24. uint32_t Shannon::sbox2(uint32_t w) {
  25. w ^= rotl(w, 7) | rotl(w, 22);
  26. w ^= rotl(w, 5) | rotl(w, 19);
  27. return w;
  28. }
  29. void Shannon::cycle() {
  30. uint32_t t;
  31. int i;
  32. /* nonlinear feedback function */
  33. t = this->R[12] ^ this->R[13] ^ this->konst;
  34. t = Shannon::sbox1(t) ^ rotl(this->R[0], 1);
  35. /* shift register */
  36. for (i = 1; i < N; ++i)
  37. this->R[i - 1] = this->R[i];
  38. this->R[N - 1] = t;
  39. t = Shannon::sbox2(this->R[2] ^ this->R[15]);
  40. this->R[0] ^= t;
  41. this->sbuf = t ^ this->R[8] ^ this->R[12];
  42. }
  43. void Shannon::crcfunc(uint32_t i) {
  44. uint32_t t;
  45. int j;
  46. /* Accumulate CRC of input */
  47. t = this->CRC[0] ^ this->CRC[2] ^ this->CRC[15] ^ i;
  48. for (j = 1; j < N; ++j)
  49. this->CRC[j - 1] = this->CRC[j];
  50. this->CRC[N - 1] = t;
  51. }
  52. void Shannon::macfunc(uint32_t i) {
  53. this->crcfunc(i);
  54. this->R[KEYP] ^= i;
  55. }
  56. void Shannon::initState() {
  57. int i;
  58. /* Register initialised to Fibonacci numbers; Counter zeroed. */
  59. this->R[0] = 1;
  60. this->R[1] = 1;
  61. for (i = 2; i < N; ++i)
  62. this->R[i] = this->R[i - 1] + this->R[i - 2];
  63. this->konst = Shannon::INITKONST;
  64. }
  65. void Shannon::saveState() {
  66. int i;
  67. for (i = 0; i < Shannon::N; ++i)
  68. this->initR[i] = this->R[i];
  69. }
  70. void Shannon::reloadState() {
  71. int i;
  72. for (i = 0; i < Shannon::N; ++i)
  73. this->R[i] = this->initR[i];
  74. }
  75. void Shannon::genkonst() {
  76. this->konst = this->R[0];
  77. }
  78. void Shannon::diffuse() {
  79. int i;
  80. for (i = 0; i < Shannon::FOLD; ++i)
  81. this->cycle();
  82. }
  83. #define Byte(x, i) ((uint32_t)(((x) >> (8 * (i))) & 0xFF))
  84. #define BYTE2WORD(b) \
  85. ((((uint32_t)(b)[3] & 0xFF) << 24) | (((uint32_t)(b)[2] & 0xFF) << 16) | \
  86. (((uint32_t)(b)[1] & 0xFF) << 8) | (((uint32_t)(b)[0] & 0xFF)))
  87. #define WORD2BYTE(w, b) \
  88. { \
  89. (b)[3] = Byte(w, 3); \
  90. (b)[2] = Byte(w, 2); \
  91. (b)[1] = Byte(w, 1); \
  92. (b)[0] = Byte(w, 0); \
  93. }
  94. #define XORWORD(w, b) \
  95. { \
  96. (b)[3] ^= Byte(w, 3); \
  97. (b)[2] ^= Byte(w, 2); \
  98. (b)[1] ^= Byte(w, 1); \
  99. (b)[0] ^= Byte(w, 0); \
  100. }
  101. #define XORWORD(w, b) \
  102. { \
  103. (b)[3] ^= Byte(w, 3); \
  104. (b)[2] ^= Byte(w, 2); \
  105. (b)[1] ^= Byte(w, 1); \
  106. (b)[0] ^= Byte(w, 0); \
  107. }
  108. /* Load key material into the register
  109. */
  110. #define ADDKEY(k) this->R[KEYP] ^= (k);
  111. void Shannon::loadKey(const std::vector<uint8_t>& key) {
  112. int i, j;
  113. uint32_t k;
  114. uint8_t xtra[4];
  115. size_t keylen = key.size();
  116. /* start folding in key */
  117. for (i = 0; i < (keylen & ~0x3); i += 4) {
  118. k = BYTE2WORD(&key[i]);
  119. ADDKEY(k);
  120. this->cycle();
  121. }
  122. /* if there were any extra key bytes, zero pad to a word */
  123. if (i < keylen) {
  124. for (j = 0 /* i unchanged */; i < keylen; ++i)
  125. xtra[j++] = key[i];
  126. for (/* j unchanged */; j < 4; ++j)
  127. xtra[j] = 0;
  128. k = BYTE2WORD(xtra);
  129. ADDKEY(k);
  130. this->cycle();
  131. }
  132. /* also fold in the length of the key */
  133. ADDKEY(keylen);
  134. this->cycle();
  135. /* save a copy of the register */
  136. for (i = 0; i < N; ++i)
  137. this->CRC[i] = this->R[i];
  138. /* now diffuse */
  139. this->diffuse();
  140. /* now xor the copy back -- makes key loading irreversible */
  141. for (i = 0; i < N; ++i)
  142. this->R[i] ^= this->CRC[i];
  143. }
  144. void Shannon::key(const std::vector<uint8_t>& key) {
  145. this->initState();
  146. this->loadKey(key);
  147. this->genkonst(); /* in case we proceed to stream generation */
  148. this->saveState();
  149. this->nbuf = 0;
  150. }
  151. void Shannon::nonce(const std::vector<uint8_t>& nonce) {
  152. this->reloadState();
  153. this->konst = Shannon::INITKONST;
  154. this->loadKey(nonce);
  155. this->genkonst();
  156. this->nbuf = 0;
  157. }
  158. void Shannon::stream(std::vector<uint8_t>& bufVec) {
  159. uint8_t* endbuf;
  160. size_t nbytes = bufVec.size();
  161. uint8_t* buf = bufVec.data();
  162. /* handle any previously buffered bytes */
  163. while (this->nbuf != 0 && nbytes != 0) {
  164. *buf++ ^= this->sbuf & 0xFF;
  165. this->sbuf >>= 8;
  166. this->nbuf -= 8;
  167. --nbytes;
  168. }
  169. /* handle whole words */
  170. endbuf = &buf[nbytes & ~((uint32_t)0x03)];
  171. while (buf < endbuf) {
  172. this->cycle();
  173. XORWORD(this->sbuf, buf);
  174. buf += 4;
  175. }
  176. /* handle any trailing bytes */
  177. nbytes &= 0x03;
  178. if (nbytes != 0) {
  179. this->cycle();
  180. this->nbuf = 32;
  181. while (this->nbuf != 0 && nbytes != 0) {
  182. *buf++ ^= this->sbuf & 0xFF;
  183. this->sbuf >>= 8;
  184. this->nbuf -= 8;
  185. --nbytes;
  186. }
  187. }
  188. }
  189. void Shannon::maconly(std::vector<uint8_t>& bufVec) {
  190. size_t nbytes = bufVec.size();
  191. uint8_t* buf = bufVec.data();
  192. uint8_t* endbuf;
  193. /* handle any previously buffered bytes */
  194. if (this->nbuf != 0) {
  195. while (this->nbuf != 0 && nbytes != 0) {
  196. this->mbuf ^= (*buf++) << (32 - this->nbuf);
  197. this->nbuf -= 8;
  198. --nbytes;
  199. }
  200. if (this->nbuf != 0) /* not a whole word yet */
  201. return;
  202. /* LFSR already cycled */
  203. this->macfunc(this->mbuf);
  204. }
  205. /* handle whole words */
  206. endbuf = &buf[nbytes & ~((uint32_t)0x03)];
  207. while (buf < endbuf) {
  208. this->cycle();
  209. this->macfunc(BYTE2WORD(buf));
  210. buf += 4;
  211. }
  212. /* handle any trailing bytes */
  213. nbytes &= 0x03;
  214. if (nbytes != 0) {
  215. this->cycle();
  216. this->mbuf = 0;
  217. this->nbuf = 32;
  218. while (this->nbuf != 0 && nbytes != 0) {
  219. this->mbuf ^= (*buf++) << (32 - this->nbuf);
  220. this->nbuf -= 8;
  221. --nbytes;
  222. }
  223. }
  224. }
  225. void Shannon::encrypt(std::vector<uint8_t>& bufVec) {
  226. size_t nbytes = bufVec.size();
  227. uint8_t* buf = bufVec.data();
  228. uint8_t* endbuf;
  229. uint32_t t = 0;
  230. /* handle any previously buffered bytes */
  231. if (this->nbuf != 0) {
  232. while (this->nbuf != 0 && nbytes != 0) {
  233. this->mbuf ^= *buf << (32 - this->nbuf);
  234. *buf ^= (this->sbuf >> (32 - this->nbuf)) & 0xFF;
  235. ++buf;
  236. this->nbuf -= 8;
  237. --nbytes;
  238. }
  239. if (this->nbuf != 0) /* not a whole word yet */
  240. return;
  241. /* LFSR already cycled */
  242. this->macfunc(this->mbuf);
  243. }
  244. /* handle whole words */
  245. endbuf = &buf[nbytes & ~((uint32_t)0x03)];
  246. while (buf < endbuf) {
  247. this->cycle();
  248. t = BYTE2WORD(buf);
  249. this->macfunc(t);
  250. t ^= this->sbuf;
  251. WORD2BYTE(t, buf);
  252. buf += 4;
  253. }
  254. /* handle any trailing bytes */
  255. nbytes &= 0x03;
  256. if (nbytes != 0) {
  257. this->cycle();
  258. this->mbuf = 0;
  259. this->nbuf = 32;
  260. while (this->nbuf != 0 && nbytes != 0) {
  261. this->mbuf ^= *buf << (32 - this->nbuf);
  262. *buf ^= (this->sbuf >> (32 - this->nbuf)) & 0xFF;
  263. ++buf;
  264. this->nbuf -= 8;
  265. --nbytes;
  266. }
  267. }
  268. }
  269. void Shannon::decrypt(std::vector<uint8_t>& bufVec) {
  270. size_t nbytes = bufVec.size();
  271. uint8_t* buf = bufVec.data();
  272. uint8_t* endbuf;
  273. uint32_t t = 0;
  274. /* handle any previously buffered bytes */
  275. if (this->nbuf != 0) {
  276. while (this->nbuf != 0 && nbytes != 0) {
  277. *buf ^= (this->sbuf >> (32 - this->nbuf)) & 0xFF;
  278. this->mbuf ^= *buf << (32 - this->nbuf);
  279. ++buf;
  280. this->nbuf -= 8;
  281. --nbytes;
  282. }
  283. if (this->nbuf != 0) /* not a whole word yet */
  284. return;
  285. /* LFSR already cycled */
  286. this->macfunc(this->mbuf);
  287. }
  288. /* handle whole words */
  289. endbuf = &buf[nbytes & ~((uint32_t)0x03)];
  290. while (buf < endbuf) {
  291. this->cycle();
  292. t = BYTE2WORD(buf) ^ this->sbuf;
  293. this->macfunc(t);
  294. WORD2BYTE(t, buf);
  295. buf += 4;
  296. }
  297. /* handle any trailing bytes */
  298. nbytes &= 0x03;
  299. if (nbytes != 0) {
  300. this->cycle();
  301. this->mbuf = 0;
  302. this->nbuf = 32;
  303. while (this->nbuf != 0 && nbytes != 0) {
  304. *buf ^= (this->sbuf >> (32 - this->nbuf)) & 0xFF;
  305. this->mbuf ^= *buf << (32 - this->nbuf);
  306. ++buf;
  307. this->nbuf -= 8;
  308. --nbytes;
  309. }
  310. }
  311. }
  312. void Shannon::finish(std::vector<uint8_t>& bufVec) {
  313. size_t nbytes = bufVec.size();
  314. uint8_t* buf = bufVec.data();
  315. int i;
  316. /* handle any previously buffered bytes */
  317. if (this->nbuf != 0) {
  318. /* LFSR already cycled */
  319. this->macfunc(this->mbuf);
  320. }
  321. /* perturb the MAC to mark end of input.
  322. * Note that only the stream register is updated, not the CRC. This is an
  323. * action that can't be duplicated by passing in plaintext, hence
  324. * defeating any kind of extension attack.
  325. */
  326. this->cycle();
  327. ADDKEY(INITKONST ^ (this->nbuf << 3));
  328. this->nbuf = 0;
  329. /* now add the CRC to the stream register and diffuse it */
  330. for (i = 0; i < N; ++i)
  331. this->R[i] ^= this->CRC[i];
  332. this->diffuse();
  333. /* produce output from the stream buffer */
  334. while (nbytes > 0) {
  335. this->cycle();
  336. if (nbytes >= 4) {
  337. WORD2BYTE(this->sbuf, buf);
  338. nbytes -= 4;
  339. buf += 4;
  340. } else {
  341. for (i = 0; i < nbytes; ++i)
  342. buf[i] = Byte(this->sbuf, i);
  343. break;
  344. }
  345. }
  346. }