// IBM PC Implementation of the DES Cryptographic Algorithm // // Encryption and Decryption Routines // // by Dr B R Gladman (gladman@seven77.demon.co.uk) // Note on Bit Numbering. The DES bit numbering is the reverse of that // used on the intel series processors. Thus to translate between bits // al0 numeric values requires a reversal of bit sequences. To achieve // this for external numbers the initial al0 final DES permutations al0 // the initial key permutation are adjusted to take care of the changed // bit order. The other changes required are in the calculation of the // s_box inputs al0 outputs. The bits numbering reversal on s_box input // is obtained by reordering the s_box tables. The bit reversal within // output nibbles is done by reordering the exit permutation. // The following permutation tables can be in either of two two forms. // In the output form, table[i] gives the bit number in the input bit // sequence from from which output bit 'i' comes. In the input form, // table[i] gives the bit number in the output sequence to which bit // 'i' goes. Bits marked xx are not used in the transformations. // DES Timings: // Key Setup: 1003 cycles // Encrypt: 466.3 cycles = 27.45 mbits/sec // Decrypt: 470.4 cycles = 27.21 mbits/sec // Mean: 468.3 cycles = 27.33 mbits/sec // s_box al0 post s_box permutation table #include "des.h" unsigned long sx_tab[8][64] = { { 0x00820200L, 0x00020000L, 0x80800000L, 0x80820200L, 0x00800000L, 0x80020200L, 0x80020000L, 0x80800000L, 0x80020200L, 0x00820200L, 0x00820000L, 0x80000200L, 0x80800200L, 0x00800000L, 0x00000000L, 0x80020000L, 0x00020000L, 0x80000000L, 0x00800200L, 0x00020200L, 0x80820200L, 0x00820000L, 0x80000200L, 0x00800200L, 0x80000000L, 0x00000200L, 0x00020200L, 0x80820000L, 0x00000200L, 0x80800200L, 0x80820000L, 0x00000000L, 0x00000000L, 0x80820200L, 0x00800200L, 0x80020000L, 0x00820200L, 0x00020000L, 0x80000200L, 0x00800200L, 0x80820000L, 0x00000200L, 0x00020200L, 0x80800000L, 0x80020200L, 0x80000000L, 0x80800000L, 0x00820000L, 0x80820200L, 0x00020200L, 0x00820000L, 0x80800200L, 0x00800000L, 0x80000200L, 0x80020000L, 0x00000000L, 0x00020000L, 0x00800000L, 0x80800200L, 0x00820200L, 0x80000000L, 0x80820000L, 0x00000200L, 0x80020200L }, { 0x10042004L, 0x00000000L, 0x00042000L, 0x10040000L, 0x10000004L, 0x00002004L, 0x10002000L, 0x00042000L, 0x00002000L, 0x10040004L, 0x00000004L, 0x10002000L, 0x00040004L, 0x10042000L, 0x10040000L, 0x00000004L, 0x00040000L, 0x10002004L, 0x10040004L, 0x00002000L, 0x00042004L, 0x10000000L, 0x00000000L, 0x00040004L, 0x10002004L, 0x00042004L, 0x10042000L, 0x10000004L, 0x10000000L, 0x00040000L, 0x00002004L, 0x10042004L, 0x00040004L, 0x10042000L, 0x10002000L, 0x00042004L, 0x10042004L, 0x00040004L, 0x10000004L, 0x00000000L, 0x10000000L, 0x00002004L, 0x00040000L, 0x10040004L, 0x00002000L, 0x10000000L, 0x00042004L, 0x10002004L, 0x10042000L, 0x00002000L, 0x00000000L, 0x10000004L, 0x00000004L, 0x10042004L, 0x00042000L, 0x10040000L, 0x10040004L, 0x00040000L, 0x00002004L, 0x10002000L, 0x10002004L, 0x00000004L, 0x10040000L, 0x00042000L }, { 0x41000000L, 0x01010040L, 0x00000040L, 0x41000040L, 0x40010000L, 0x01000000L, 0x41000040L, 0x00010040L, 0x01000040L, 0x00010000L, 0x01010000L, 0x40000000L, 0x41010040L, 0x40000040L, 0x40000000L, 0x41010000L, 0x00000000L, 0x40010000L, 0x01010040L, 0x00000040L, 0x40000040L, 0x41010040L, 0x00010000L, 0x41000000L, 0x41010000L, 0x01000040L, 0x40010040L, 0x01010000L, 0x00010040L, 0x00000000L, 0x01000000L, 0x40010040L, 0x01010040L, 0x00000040L, 0x40000000L, 0x00010000L, 0x40000040L, 0x40010000L, 0x01010000L, 0x41000040L, 0x00000000L, 0x01010040L, 0x00010040L, 0x41010000L, 0x40010000L, 0x01000000L, 0x41010040L, 0x40000000L, 0x40010040L, 0x41000000L, 0x01000000L, 0x41010040L, 0x00010000L, 0x01000040L, 0x41000040L, 0x00010040L, 0x01000040L, 0x00000000L, 0x41010000L, 0x40000040L, 0x41000000L, 0x40010040L, 0x00000040L, 0x01010000L }, { 0x00100402L, 0x04000400L, 0x00000002L, 0x04100402L, 0x00000000L, 0x04100000L, 0x04000402L, 0x00100002L, 0x04100400L, 0x04000002L, 0x04000000L, 0x00000402L, 0x04000002L, 0x00100402L, 0x00100000L, 0x04000000L, 0x04100002L, 0x00100400L, 0x00000400L, 0x00000002L, 0x00100400L, 0x04000402L, 0x04100000L, 0x00000400L, 0x00000402L, 0x00000000L, 0x00100002L, 0x04100400L, 0x04000400L, 0x04100002L, 0x04100402L, 0x00100000L, 0x04100002L, 0x00000402L, 0x00100000L, 0x04000002L, 0x00100400L, 0x04000400L, 0x00000002L, 0x04100000L, 0x04000402L, 0x00000000L, 0x00000400L, 0x00100002L, 0x00000000L, 0x04100002L, 0x04100400L, 0x00000400L, 0x04000000L, 0x04100402L, 0x00100402L, 0x00100000L, 0x04100402L, 0x00000002L, 0x04000400L, 0x00100402L, 0x00100002L, 0x00100400L, 0x04100000L, 0x04000402L, 0x00000402L, 0x04000000L, 0x04000002L, 0x04100400L }, { 0x02000000L, 0x00004000L, 0x00000100L, 0x02004108L, 0x02004008L, 0x02000100L, 0x00004108L, 0x02004000L, 0x00004000L, 0x00000008L, 0x02000008L, 0x00004100L, 0x02000108L, 0x02004008L, 0x02004100L, 0x00000000L, 0x00004100L, 0x02000000L, 0x00004008L, 0x00000108L, 0x02000100L, 0x00004108L, 0x00000000L, 0x02000008L, 0x00000008L, 0x02000108L, 0x02004108L, 0x00004008L, 0x02004000L, 0x00000100L, 0x00000108L, 0x02004100L, 0x02004100L, 0x02000108L, 0x00004008L, 0x02004000L, 0x00004000L, 0x00000008L, 0x02000008L, 0x02000100L, 0x02000000L, 0x00004100L, 0x02004108L, 0x00000000L, 0x00004108L, 0x02000000L, 0x00000100L, 0x00004008L, 0x02000108L, 0x00000100L, 0x00000000L, 0x02004108L, 0x02004008L, 0x02004100L, 0x00000108L, 0x00004000L, 0x00004100L, 0x02004008L, 0x02000100L, 0x00000108L, 0x00000008L, 0x00004108L, 0x02004000L, 0x02000008L }, { 0x20000010L, 0x00080010L, 0x00000000L, 0x20080800L, 0x00080010L, 0x00000800L, 0x20000810L, 0x00080000L, 0x00000810L, 0x20080810L, 0x00080800L, 0x20000000L, 0x20000800L, 0x20000010L, 0x20080000L, 0x00080810L, 0x00080000L, 0x20000810L, 0x20080010L, 0x00000000L, 0x00000800L, 0x00000010L, 0x20080800L, 0x20080010L, 0x20080810L, 0x20080000L, 0x20000000L, 0x00000810L, 0x00000010L, 0x00080800L, 0x00080810L, 0x20000800L, 0x00000810L, 0x20000000L, 0x20000800L, 0x00080810L, 0x20080800L, 0x00080010L, 0x00000000L, 0x20000800L, 0x20000000L, 0x00000800L, 0x20080010L, 0x00080000L, 0x00080010L, 0x20080810L, 0x00080800L, 0x00000010L, 0x20080810L, 0x00080800L, 0x00080000L, 0x20000810L, 0x20000010L, 0x20080000L, 0x00080810L, 0x00000000L, 0x00000800L, 0x20000010L, 0x20000810L, 0x20080800L, 0x20080000L, 0x00000810L, 0x00000010L, 0x20080010L }, { 0x00001000L, 0x00000080L, 0x00400080L, 0x00400001L, 0x00401081L, 0x00001001L, 0x00001080L, 0x00000000L, 0x00400000L, 0x00400081L, 0x00000081L, 0x00401000L, 0x00000001L, 0x00401080L, 0x00401000L, 0x00000081L, 0x00400081L, 0x00001000L, 0x00001001L, 0x00401081L, 0x00000000L, 0x00400080L, 0x00400001L, 0x00001080L, 0x00401001L, 0x00001081L, 0x00401080L, 0x00000001L, 0x00001081L, 0x00401001L, 0x00000080L, 0x00400000L, 0x00001081L, 0x00401000L, 0x00401001L, 0x00000081L, 0x00001000L, 0x00000080L, 0x00400000L, 0x00401001L, 0x00400081L, 0x00001081L, 0x00001080L, 0x00000000L, 0x00000080L, 0x00400001L, 0x00000001L, 0x00400080L, 0x00000000L, 0x00400081L, 0x00400080L, 0x00001080L, 0x00000081L, 0x00001000L, 0x00401081L, 0x00400000L, 0x00401080L, 0x00000001L, 0x00001001L, 0x00401081L, 0x00400001L, 0x00401080L, 0x00401000L, 0x00001001L }, { 0x08200020L, 0x08208000L, 0x00008020L, 0x00000000L, 0x08008000L, 0x00200020L, 0x08200000L, 0x08208020L, 0x00000020L, 0x08000000L, 0x00208000L, 0x00008020L, 0x00208020L, 0x08008020L, 0x08000020L, 0x08200000L, 0x00008000L, 0x00208020L, 0x00200020L, 0x08008000L, 0x08208020L, 0x08000020L, 0x00000000L, 0x00208000L, 0x08000000L, 0x00200000L, 0x08008020L, 0x08200020L, 0x00200000L, 0x00008000L, 0x08208000L, 0x00000020L, 0x00200000L, 0x00008000L, 0x08000020L, 0x08208020L, 0x00008020L, 0x08000000L, 0x00000000L, 0x00208000L, 0x08200020L, 0x08008020L, 0x08008000L, 0x00200020L, 0x08208000L, 0x00000020L, 0x00200020L, 0x08008000L, 0x08208020L, 0x00200000L, 0x08200000L, 0x08000020L, 0x00208000L, 0x00008020L, 0x08008020L, 0x08200000L, 0x00000020L, 0x08208000L, 0x00208020L, 0x00000000L, 0x08000000L, 0x08200020L, 0x00008000L, 0x00208020L } }; unsigned long bs_tab[] = { 0x00000001L, 0x00000002L, 0x00000004L, 0x00000008L, 0x00000010L, 0x00000020L, 0x00000040L, 0x00000080L, 0x00000100L, 0x00000200L, 0x00000400L, 0x00000800L, 0x00001000L, 0x00002000L, 0x00004000L, 0x00008000L, 0x00010000L, 0x00020000L, 0x00040000L, 0x00080000L, 0x00100000L, 0x00200000L, 0x00400000L, 0x00800000L, 0x01000000L, 0x02000000L, 0x04000000L, 0x08000000L, 0x10000000L, 0x20000000L, 0x40000000L, 0x80000000L }; extern unsigned long key[32]; void des_ec(const void *i_blk, void *o_blk, void *key) { unsigned long q0, q1, l0, l1, tt; q0 = *(((unsigned long*)i_blk) + 1); q1 = *(((unsigned long*)i_blk)); ip(q0,q1); q0 = rotl(q0, 1); q1 = rotl(q1, 1); round(q0, q1, 0); round(q1, q0, 2); round(q0, q1, 4); round(q1, q0, 6); round(q0, q1, 8); round(q1, q0, 10); round(q0, q1, 12); round(q1, q0, 14); round(q0, q1, 16); round(q1, q0, 18); round(q0, q1, 20); round(q1, q0, 22); round(q0, q1, 24); round(q1, q0, 26); round(q0, q1, 28); round(q1, q0, 30); q0 = rotr(q0, 1); q1 = rotr(q1, 1); fp(q0, q1); *(((unsigned long*)o_blk)) = q0; *(((unsigned long*)o_blk) + 1) = q1; }; void des_dc(const void *i_blk, void *o_blk, void *key) { unsigned long q0, q1, l0, l1, tt; q0 = *(((unsigned long*)i_blk) + 1); q1 = *(((unsigned long*)i_blk)); ip(q0, q1); q0 = rotl(q0, 1); q1 = rotl(q1, 1); round(q0, q1, 30); round(q1, q0, 28); round(q0, q1, 26); round(q1, q0, 24); round(q0, q1, 22); round(q1, q0, 20); round(q0, q1, 18); round(q1, q0, 16); round(q0, q1, 14); round(q1, q0, 12); round(q0, q1, 10); round(q1, q0, 8); round(q0, q1, 6); round(q1, q0, 4); round(q0, q1, 2); round(q1, q0, 0); q0 = rotr(q0, 1); q1 = rotr(q1, 1); fp(q0, q1); *(((unsigned long*)o_blk)) = q0; *(((unsigned long*)o_blk) + 1) = q1; };