|
|
1.1.1.2 ! root 1: // serpent.cpp - written and placed in the public domain by Wei Dai 1.1 root 2: 1.1.1.2 ! root 3: /* Adapted for TrueCrypt by the TrueCrypt Foundation */ 1.1 root 4: 1.1.1.2 ! root 5: #include "Serpent.h" ! 6: #include "Endian.h" 1.1 root 7: 1.1.1.2 ! root 8: #ifndef LINUX_DRIVER ! 9: #include <memory.h> ! 10: #endif 1.1 root 11: 1.1.1.2 ! root 12: #if defined(_WIN32) && !defined(_DEBUG) ! 13: #include <stdlib.h> ! 14: #define rotlFixed _rotl ! 15: #define rotrFixed _rotr 1.1 root 16: #else 1.1.1.2 ! root 17: #define rotlFixed(x,n) (((x) << (n)) | ((x) >> (32 - (n)))) ! 18: #define rotrFixed(x,n) (((x) >> (n)) | ((x) << (32 - (n)))) 1.1 root 19: #endif 20: 1.1.1.2 ! root 21: // linear transformation ! 22: #define LT(i,a,b,c,d,e) {\ ! 23: a = rotlFixed(a, 13); \ ! 24: c = rotlFixed(c, 3); \ ! 25: d = rotlFixed(d ^ c ^ (a << 3), 7); \ ! 26: b = rotlFixed(b ^ a ^ c, 1); \ ! 27: a = rotlFixed(a ^ b ^ d, 5); \ ! 28: c = rotlFixed(c ^ d ^ (b << 7), 22);} ! 29: ! 30: // inverse linear transformation ! 31: #define ILT(i,a,b,c,d,e) {\ ! 32: c = rotrFixed(c, 22); \ ! 33: a = rotrFixed(a, 5); \ ! 34: c ^= d ^ (b << 7); \ ! 35: a ^= b ^ d; \ ! 36: b = rotrFixed(b, 1); \ ! 37: d = rotrFixed(d, 7) ^ c ^ (a << 3); \ ! 38: b ^= a ^ c; \ ! 39: c = rotrFixed(c, 3); \ ! 40: a = rotrFixed(a, 13);} ! 41: ! 42: // order of output from S-box functions ! 43: #define beforeS0(f) f(0,a,b,c,d,e) ! 44: #define afterS0(f) f(1,b,e,c,a,d) ! 45: #define afterS1(f) f(2,c,b,a,e,d) ! 46: #define afterS2(f) f(3,a,e,b,d,c) ! 47: #define afterS3(f) f(4,e,b,d,c,a) ! 48: #define afterS4(f) f(5,b,a,e,c,d) ! 49: #define afterS5(f) f(6,a,c,b,e,d) ! 50: #define afterS6(f) f(7,a,c,d,b,e) ! 51: #define afterS7(f) f(8,d,e,b,a,c) ! 52: ! 53: // order of output from inverse S-box functions ! 54: #define beforeI7(f) f(8,a,b,c,d,e) ! 55: #define afterI7(f) f(7,d,a,b,e,c) ! 56: #define afterI6(f) f(6,a,b,c,e,d) ! 57: #define afterI5(f) f(5,b,d,e,c,a) ! 58: #define afterI4(f) f(4,b,c,e,a,d) ! 59: #define afterI3(f) f(3,a,b,e,c,d) ! 60: #define afterI2(f) f(2,b,d,e,c,a) ! 61: #define afterI1(f) f(1,a,b,c,e,d) ! 62: #define afterI0(f) f(0,a,d,b,e,c) ! 63: ! 64: // The instruction sequences for the S-box functions ! 65: // come from Dag Arne Osvik's paper "Speeding up Serpent". ! 66: ! 67: #define S0(i, r0, r1, r2, r3, r4) \ ! 68: { \ ! 69: r3 ^= r0; \ ! 70: r4 = r1; \ ! 71: r1 &= r3; \ ! 72: r4 ^= r2; \ ! 73: r1 ^= r0; \ ! 74: r0 |= r3; \ ! 75: r0 ^= r4; \ ! 76: r4 ^= r3; \ ! 77: r3 ^= r2; \ ! 78: r2 |= r1; \ ! 79: r2 ^= r4; \ ! 80: r4 = ~r4; \ ! 81: r4 |= r1; \ ! 82: r1 ^= r3; \ ! 83: r1 ^= r4; \ ! 84: r3 |= r0; \ ! 85: r1 ^= r3; \ ! 86: r4 ^= r3; \ ! 87: } ! 88: ! 89: #define I0(i, r0, r1, r2, r3, r4) \ ! 90: { \ ! 91: r2 = ~r2; \ ! 92: r4 = r1; \ ! 93: r1 |= r0; \ ! 94: r4 = ~r4; \ ! 95: r1 ^= r2; \ ! 96: r2 |= r4; \ ! 97: r1 ^= r3; \ ! 98: r0 ^= r4; \ ! 99: r2 ^= r0; \ ! 100: r0 &= r3; \ ! 101: r4 ^= r0; \ ! 102: r0 |= r1; \ ! 103: r0 ^= r2; \ ! 104: r3 ^= r4; \ ! 105: r2 ^= r1; \ ! 106: r3 ^= r0; \ ! 107: r3 ^= r1; \ ! 108: r2 &= r3; \ ! 109: r4 ^= r2; \ ! 110: } ! 111: ! 112: #define S1(i, r0, r1, r2, r3, r4) \ ! 113: { \ ! 114: r0 = ~r0; \ ! 115: r2 = ~r2; \ ! 116: r4 = r0; \ ! 117: r0 &= r1; \ ! 118: r2 ^= r0; \ ! 119: r0 |= r3; \ ! 120: r3 ^= r2; \ ! 121: r1 ^= r0; \ ! 122: r0 ^= r4; \ ! 123: r4 |= r1; \ ! 124: r1 ^= r3; \ ! 125: r2 |= r0; \ ! 126: r2 &= r4; \ ! 127: r0 ^= r1; \ ! 128: r1 &= r2; \ ! 129: r1 ^= r0; \ ! 130: r0 &= r2; \ ! 131: r0 ^= r4; \ ! 132: } ! 133: ! 134: #define I1(i, r0, r1, r2, r3, r4) \ ! 135: { \ ! 136: r4 = r1; \ ! 137: r1 ^= r3; \ ! 138: r3 &= r1; \ ! 139: r4 ^= r2; \ ! 140: r3 ^= r0; \ ! 141: r0 |= r1; \ ! 142: r2 ^= r3; \ ! 143: r0 ^= r4; \ ! 144: r0 |= r2; \ ! 145: r1 ^= r3; \ ! 146: r0 ^= r1; \ ! 147: r1 |= r3; \ ! 148: r1 ^= r0; \ ! 149: r4 = ~r4; \ ! 150: r4 ^= r1; \ ! 151: r1 |= r0; \ ! 152: r1 ^= r0; \ ! 153: r1 |= r4; \ ! 154: r3 ^= r1; \ ! 155: } ! 156: ! 157: #define S2(i, r0, r1, r2, r3, r4) \ ! 158: { \ ! 159: r4 = r0; \ ! 160: r0 &= r2; \ ! 161: r0 ^= r3; \ ! 162: r2 ^= r1; \ ! 163: r2 ^= r0; \ ! 164: r3 |= r4; \ ! 165: r3 ^= r1; \ ! 166: r4 ^= r2; \ ! 167: r1 = r3; \ ! 168: r3 |= r4; \ ! 169: r3 ^= r0; \ ! 170: r0 &= r1; \ ! 171: r4 ^= r0; \ ! 172: r1 ^= r3; \ ! 173: r1 ^= r4; \ ! 174: r4 = ~r4; \ ! 175: } ! 176: ! 177: #define I2(i, r0, r1, r2, r3, r4) \ ! 178: { \ ! 179: r2 ^= r3; \ ! 180: r3 ^= r0; \ ! 181: r4 = r3; \ ! 182: r3 &= r2; \ ! 183: r3 ^= r1; \ ! 184: r1 |= r2; \ ! 185: r1 ^= r4; \ ! 186: r4 &= r3; \ ! 187: r2 ^= r3; \ ! 188: r4 &= r0; \ ! 189: r4 ^= r2; \ ! 190: r2 &= r1; \ ! 191: r2 |= r0; \ ! 192: r3 = ~r3; \ ! 193: r2 ^= r3; \ ! 194: r0 ^= r3; \ ! 195: r0 &= r1; \ ! 196: r3 ^= r4; \ ! 197: r3 ^= r0; \ ! 198: } ! 199: ! 200: #define S3(i, r0, r1, r2, r3, r4) \ ! 201: { \ ! 202: r4 = r0; \ ! 203: r0 |= r3; \ ! 204: r3 ^= r1; \ ! 205: r1 &= r4; \ ! 206: r4 ^= r2; \ ! 207: r2 ^= r3; \ ! 208: r3 &= r0; \ ! 209: r4 |= r1; \ ! 210: r3 ^= r4; \ ! 211: r0 ^= r1; \ ! 212: r4 &= r0; \ ! 213: r1 ^= r3; \ ! 214: r4 ^= r2; \ ! 215: r1 |= r0; \ ! 216: r1 ^= r2; \ ! 217: r0 ^= r3; \ ! 218: r2 = r1; \ ! 219: r1 |= r3; \ ! 220: r1 ^= r0; \ ! 221: } ! 222: ! 223: #define I3(i, r0, r1, r2, r3, r4) \ ! 224: { \ ! 225: r4 = r2; \ ! 226: r2 ^= r1; \ ! 227: r1 &= r2; \ ! 228: r1 ^= r0; \ ! 229: r0 &= r4; \ ! 230: r4 ^= r3; \ ! 231: r3 |= r1; \ ! 232: r3 ^= r2; \ ! 233: r0 ^= r4; \ ! 234: r2 ^= r0; \ ! 235: r0 |= r3; \ ! 236: r0 ^= r1; \ ! 237: r4 ^= r2; \ ! 238: r2 &= r3; \ ! 239: r1 |= r3; \ ! 240: r1 ^= r2; \ ! 241: r4 ^= r0; \ ! 242: r2 ^= r4; \ ! 243: } ! 244: ! 245: #define S4(i, r0, r1, r2, r3, r4) \ ! 246: { \ ! 247: r1 ^= r3; \ ! 248: r3 = ~r3; \ ! 249: r2 ^= r3; \ ! 250: r3 ^= r0; \ ! 251: r4 = r1; \ ! 252: r1 &= r3; \ ! 253: r1 ^= r2; \ ! 254: r4 ^= r3; \ ! 255: r0 ^= r4; \ ! 256: r2 &= r4; \ ! 257: r2 ^= r0; \ ! 258: r0 &= r1; \ ! 259: r3 ^= r0; \ ! 260: r4 |= r1; \ ! 261: r4 ^= r0; \ ! 262: r0 |= r3; \ ! 263: r0 ^= r2; \ ! 264: r2 &= r3; \ ! 265: r0 = ~r0; \ ! 266: r4 ^= r2; \ ! 267: } ! 268: ! 269: #define I4(i, r0, r1, r2, r3, r4) \ ! 270: { \ ! 271: r4 = r2; \ ! 272: r2 &= r3; \ ! 273: r2 ^= r1; \ ! 274: r1 |= r3; \ ! 275: r1 &= r0; \ ! 276: r4 ^= r2; \ ! 277: r4 ^= r1; \ ! 278: r1 &= r2; \ ! 279: r0 = ~r0; \ ! 280: r3 ^= r4; \ ! 281: r1 ^= r3; \ ! 282: r3 &= r0; \ ! 283: r3 ^= r2; \ ! 284: r0 ^= r1; \ ! 285: r2 &= r0; \ ! 286: r3 ^= r0; \ ! 287: r2 ^= r4; \ ! 288: r2 |= r3; \ ! 289: r3 ^= r0; \ ! 290: r2 ^= r1; \ ! 291: } ! 292: ! 293: #define S5(i, r0, r1, r2, r3, r4) \ ! 294: { \ ! 295: r0 ^= r1; \ ! 296: r1 ^= r3; \ ! 297: r3 = ~r3; \ ! 298: r4 = r1; \ ! 299: r1 &= r0; \ ! 300: r2 ^= r3; \ ! 301: r1 ^= r2; \ ! 302: r2 |= r4; \ ! 303: r4 ^= r3; \ ! 304: r3 &= r1; \ ! 305: r3 ^= r0; \ ! 306: r4 ^= r1; \ ! 307: r4 ^= r2; \ ! 308: r2 ^= r0; \ ! 309: r0 &= r3; \ ! 310: r2 = ~r2; \ ! 311: r0 ^= r4; \ ! 312: r4 |= r3; \ ! 313: r2 ^= r4; \ ! 314: } ! 315: ! 316: #define I5(i, r0, r1, r2, r3, r4) \ ! 317: { \ ! 318: r1 = ~r1; \ ! 319: r4 = r3; \ ! 320: r2 ^= r1; \ ! 321: r3 |= r0; \ ! 322: r3 ^= r2; \ ! 323: r2 |= r1; \ ! 324: r2 &= r0; \ ! 325: r4 ^= r3; \ ! 326: r2 ^= r4; \ ! 327: r4 |= r0; \ ! 328: r4 ^= r1; \ ! 329: r1 &= r2; \ ! 330: r1 ^= r3; \ ! 331: r4 ^= r2; \ ! 332: r3 &= r4; \ ! 333: r4 ^= r1; \ ! 334: r3 ^= r0; \ ! 335: r3 ^= r4; \ ! 336: r4 = ~r4; \ ! 337: } ! 338: ! 339: #define S6(i, r0, r1, r2, r3, r4) \ ! 340: { \ ! 341: r2 = ~r2; \ ! 342: r4 = r3; \ ! 343: r3 &= r0; \ ! 344: r0 ^= r4; \ ! 345: r3 ^= r2; \ ! 346: r2 |= r4; \ ! 347: r1 ^= r3; \ ! 348: r2 ^= r0; \ ! 349: r0 |= r1; \ ! 350: r2 ^= r1; \ ! 351: r4 ^= r0; \ ! 352: r0 |= r3; \ ! 353: r0 ^= r2; \ ! 354: r4 ^= r3; \ ! 355: r4 ^= r0; \ ! 356: r3 = ~r3; \ ! 357: r2 &= r4; \ ! 358: r2 ^= r3; \ ! 359: } ! 360: ! 361: #define I6(i, r0, r1, r2, r3, r4) \ ! 362: { \ ! 363: r0 ^= r2; \ ! 364: r4 = r2; \ ! 365: r2 &= r0; \ ! 366: r4 ^= r3; \ ! 367: r2 = ~r2; \ ! 368: r3 ^= r1; \ ! 369: r2 ^= r3; \ ! 370: r4 |= r0; \ ! 371: r0 ^= r2; \ ! 372: r3 ^= r4; \ ! 373: r4 ^= r1; \ ! 374: r1 &= r3; \ ! 375: r1 ^= r0; \ ! 376: r0 ^= r3; \ ! 377: r0 |= r2; \ ! 378: r3 ^= r1; \ ! 379: r4 ^= r0; \ ! 380: } ! 381: ! 382: #define S7(i, r0, r1, r2, r3, r4) \ ! 383: { \ ! 384: r4 = r2; \ ! 385: r2 &= r1; \ ! 386: r2 ^= r3; \ ! 387: r3 &= r1; \ ! 388: r4 ^= r2; \ ! 389: r2 ^= r1; \ ! 390: r1 ^= r0; \ ! 391: r0 |= r4; \ ! 392: r0 ^= r2; \ ! 393: r3 ^= r1; \ ! 394: r2 ^= r3; \ ! 395: r3 &= r0; \ ! 396: r3 ^= r4; \ ! 397: r4 ^= r2; \ ! 398: r2 &= r0; \ ! 399: r4 = ~r4; \ ! 400: r2 ^= r4; \ ! 401: r4 &= r0; \ ! 402: r1 ^= r3; \ ! 403: r4 ^= r1; \ ! 404: } ! 405: ! 406: #define I7(i, r0, r1, r2, r3, r4) \ ! 407: { \ ! 408: r4 = r2; \ ! 409: r2 ^= r0; \ ! 410: r0 &= r3; \ ! 411: r2 = ~r2; \ ! 412: r4 |= r3; \ ! 413: r3 ^= r1; \ ! 414: r1 |= r0; \ ! 415: r0 ^= r2; \ ! 416: r2 &= r4; \ ! 417: r1 ^= r2; \ ! 418: r2 ^= r0; \ ! 419: r0 |= r2; \ ! 420: r3 &= r4; \ ! 421: r0 ^= r3; \ ! 422: r4 ^= r1; \ ! 423: r3 ^= r4; \ ! 424: r4 |= r0; \ ! 425: r3 ^= r2; \ ! 426: r4 ^= r2; \ ! 427: } ! 428: ! 429: // key xor ! 430: #define KX(r, a, b, c, d, e) {\ ! 431: a ^= k[4 * r + 0]; \ ! 432: b ^= k[4 * r + 1]; \ ! 433: c ^= k[4 * r + 2]; \ ! 434: d ^= k[4 * r + 3];} 1.1 root 435: 436: 1.1.1.2 ! root 437: void serpent_set_key(const unsigned __int8 userKey[], int keylen, unsigned __int8 *ks) 1.1 root 438: { 1.1.1.2 ! root 439: unsigned __int32 a,b,c,d,e; ! 440: unsigned __int32 *k = (unsigned __int32 *)ks; ! 441: unsigned __int32 t; ! 442: int i; ! 443: ! 444: for (i = 0; i < keylen / (int)sizeof(__int32); i++) ! 445: k[i] = LE32(((unsigned __int32*)userKey)[i]); ! 446: ! 447: if (keylen < 32) ! 448: k[keylen/4] |= (unsigned __int32)1 << ((keylen%4)*8); ! 449: ! 450: k += 8; ! 451: t = k[-1]; ! 452: for (i = 0; i < 132; ++i) ! 453: k[i] = t = rotlFixed(k[i-8] ^ k[i-5] ^ k[i-3] ^ t ^ 0x9e3779b9 ^ i, 11); ! 454: k -= 20; ! 455: ! 456: #define LK(r, a, b, c, d, e) {\ ! 457: a = k[(8-r)*4 + 0]; \ ! 458: b = k[(8-r)*4 + 1]; \ ! 459: c = k[(8-r)*4 + 2]; \ ! 460: d = k[(8-r)*4 + 3];} ! 461: ! 462: #define SK(r, a, b, c, d, e) {\ ! 463: k[(8-r)*4 + 4] = a; \ ! 464: k[(8-r)*4 + 5] = b; \ ! 465: k[(8-r)*4 + 6] = c; \ ! 466: k[(8-r)*4 + 7] = d;} \ ! 467: ! 468: for (i=0; i<4; i++) ! 469: { ! 470: afterS2(LK); afterS2(S3); afterS3(SK); ! 471: afterS1(LK); afterS1(S2); afterS2(SK); ! 472: afterS0(LK); afterS0(S1); afterS1(SK); ! 473: beforeS0(LK); beforeS0(S0); afterS0(SK); ! 474: k += 8*4; ! 475: afterS6(LK); afterS6(S7); afterS7(SK); ! 476: afterS5(LK); afterS5(S6); afterS6(SK); ! 477: afterS4(LK); afterS4(S5); afterS5(SK); ! 478: afterS3(LK); afterS3(S4); afterS4(SK); ! 479: } ! 480: afterS2(LK); afterS2(S3); afterS3(SK); 1.1 root 481: } 482: 483: 1.1.1.2 ! root 484: void serpent_encrypt(const unsigned __int8 *inBlock, unsigned __int8 *outBlock, unsigned __int8 *ks) 1.1 root 485: { 1.1.1.2 ! root 486: unsigned __int32 a, b, c, d, e; ! 487: unsigned int i=1; ! 488: const unsigned __int32 *k = (unsigned __int32 *)ks + 8; ! 489: unsigned __int32 *in = (unsigned __int32 *) inBlock; ! 490: unsigned __int32 *out = (unsigned __int32 *) outBlock; ! 491: ! 492: a = LE32(in[0]); ! 493: b = LE32(in[1]); ! 494: c = LE32(in[2]); ! 495: d = LE32(in[3]); ! 496: ! 497: do ! 498: { ! 499: beforeS0(KX); beforeS0(S0); afterS0(LT); ! 500: afterS0(KX); afterS0(S1); afterS1(LT); ! 501: afterS1(KX); afterS1(S2); afterS2(LT); ! 502: afterS2(KX); afterS2(S3); afterS3(LT); ! 503: afterS3(KX); afterS3(S4); afterS4(LT); ! 504: afterS4(KX); afterS4(S5); afterS5(LT); ! 505: afterS5(KX); afterS5(S6); afterS6(LT); ! 506: afterS6(KX); afterS6(S7); ! 507: ! 508: if (i == 4) ! 509: break; ! 510: ! 511: ++i; ! 512: c = b; ! 513: b = e; ! 514: e = d; ! 515: d = a; ! 516: a = e; ! 517: k += 32; ! 518: beforeS0(LT); ! 519: } ! 520: while (1); ! 521: ! 522: afterS7(KX); ! 523: ! 524: out[0] = LE32(d); ! 525: out[1] = LE32(e); ! 526: out[2] = LE32(b); ! 527: out[3] = LE32(a); ! 528: } 1.1 root 529: 1.1.1.2 ! root 530: ! 531: void serpent_decrypt(const unsigned __int8 *inBlock, unsigned __int8 *outBlock, unsigned __int8 *ks) ! 532: { ! 533: unsigned __int32 a, b, c, d, e; ! 534: const unsigned __int32 *k = (unsigned __int32 *)ks + 104; ! 535: unsigned int i=4; ! 536: unsigned __int32 *in = (unsigned __int32 *) inBlock; ! 537: unsigned __int32 *out = (unsigned __int32 *) outBlock; ! 538: ! 539: a = LE32(in[0]); ! 540: b = LE32(in[1]); ! 541: c = LE32(in[2]); ! 542: d = LE32(in[3]); ! 543: ! 544: beforeI7(KX); ! 545: goto start; ! 546: ! 547: do ! 548: { ! 549: c = b; ! 550: b = d; ! 551: d = e; ! 552: k -= 32; ! 553: beforeI7(ILT); ! 554: start: ! 555: beforeI7(I7); afterI7(KX); ! 556: afterI7(ILT); afterI7(I6); afterI6(KX); ! 557: afterI6(ILT); afterI6(I5); afterI5(KX); ! 558: afterI5(ILT); afterI5(I4); afterI4(KX); ! 559: afterI4(ILT); afterI4(I3); afterI3(KX); ! 560: afterI3(ILT); afterI3(I2); afterI2(KX); ! 561: afterI2(ILT); afterI2(I1); afterI1(KX); ! 562: afterI1(ILT); afterI1(I0); afterI0(KX); ! 563: } ! 564: while (--i != 0); ! 565: ! 566: out[0] = LE32(a); ! 567: out[1] = LE32(d); ! 568: out[2] = LE32(b); ! 569: out[3] = LE32(e); 1.1 root 570: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.