/*
 * Copyright (c) 1990 David G. Koontz.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms are permitted
 * provided that the above copyright notice and this paragraph are
 * duplicated in all such forms and that any documentation,
 * advertising materials, and other materials related to such
 * distribution and use acknowledge that the software was developed
 * by the above mentioned individual.
 * THIS SOFTWARE IS PROVIDED AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE
 */
/*
 *	fdes.h  - faster implementation of DES algorithm
 */

#include "DESdefs.h"


/* Key Schedule permuted for S Box input: */

static unsigned long K_S[8][16];	/*  K_S[sbox][Key] */

/* PC1_C/D are ByteBit indexes into an key input as a string of 8 chars */

static int PC1_C[28] = {
	        0x77, 0x67, 0x57, 0x47, 0x37, 0x27, 0x17, 0x07,
		0x76, 0x66, 0x56, 0x46, 0x36, 0x26, 0x16, 0x06,
		0x75, 0x65, 0x55, 0x45, 0x35, 0x25, 0x15, 0x05,
		0x74, 0x64, 0x54, 0x44
		};
static int PC1_D[28] = {
		0x71, 0x61, 0x51, 0x41, 0x31, 0x21, 0x11, 0x01,
		0x72, 0x62, 0x52, 0x42, 0x32, 0x22, 0x12, 0x02,
		0x73, 0x63, 0x53, 0x43, 0x33, 0x23, 0x13, 0x03,
		                        0x34, 0x24, 0x14, 0x04 
		};

/* Key Schedule shifts*/
static int leftshift[] = { 1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1 };

/* PC2 has been converted to C and D lookups, 6 bits input to 8 s boxes
 * Column and row straightened out LSB to MSB.  Bit 0 - 5 order.
 */
/* S1 thru S4 from C, S5 thru S8 from D */
 static int PC2_S18[8][6] = {
	   13,  16,  10,  23,   0,   4,	    /* S1 */
	    2,  27,  14,   5,  20,   9,	    /* S2 */
	   22,  18,  11,   3,  25,   7,	    /* S3 */
	   15,   6,  26,  19,  12,   1,	    /* S4 */
	   12,  23,   2,   8,  18,  26,	    /* S5 */
	    1,  11,  22,  16,   4,  19,     /* S6 */
	   15,  20,  10,  27,   5,  24,	    /* S7 */
	   17,  13,  21,   7,   0,   3	    /* S8 */
};

#ifdef BIG_ENDIAN

static unsigned long  IP[8][8] = {
1 << 31, 1 << 31, 1 << 23, 1 << 23, 1 << 15, 1 << 15, 1 << 7, 1 << 7,
1 << 30, 1 << 30, 1 << 22, 1 << 22, 1 << 14, 1 << 14, 1 << 6, 1 << 6,
1 << 29, 1 << 29, 1 << 21, 1 << 21, 1 << 13, 1 << 13, 1 << 5, 1 << 5,
1 << 28, 1 << 28, 1 << 20, 1 << 20, 1 << 12, 1 << 12, 1 << 4, 1 << 4,
1 << 27, 1 << 27, 1 << 19, 1 << 19, 1 << 11, 1 << 11, 1 << 3, 1 << 3,
1 << 26, 1 << 26, 1 << 18, 1 << 18, 1 << 10, 1 << 10, 1 << 2, 1 << 2,
1 << 25, 1 << 25, 1 << 17, 1 << 17, 1 <<  9, 1 <<  9, 1 << 1, 1 << 1,
1 << 24, 1 << 24, 1 << 16, 1 << 16, 1 <<  8, 1 <<  8, 1 << 0, 1 << 0
};
static unsigned long IIP[8][8] = {
1 <<  0, 1 <<  8, 1 << 16, 1 << 24, 1 <<  0, 1 <<  8, 1 << 16, 1 << 24, 
1 <<  2, 1 << 10, 1 << 18, 1 << 26, 1 <<  2, 1 << 10, 1 << 18, 1 << 26,
1 <<  4, 1 << 12, 1 << 20, 1 << 28, 1 <<  4, 1 << 12, 1 << 20, 1 << 28,
1 <<  6, 1 << 14, 1 << 22, 1 << 30, 1 <<  6, 1 << 14, 1 << 22, 1 << 30,
1 <<  1, 1 <<  9, 1 << 17, 1 << 25, 1 <<  1, 1 <<  9, 1 << 17, 1 << 25,
1 <<  3, 1 << 11, 1 << 19, 1 << 27, 1 <<  3, 1 << 11, 1 << 19, 1 << 27,
1 <<  5, 1 << 13, 1 << 21, 1 << 29, 1 <<  5, 1 << 13, 1 << 21, 1 << 29,
1 <<  7, 1 << 15, 1 << 23, 1 << 31, 1 <<  7, 1 << 15, 1 << 23, 1 << 31
};

#else /* LITTLE_ENDIAN */

static unsigned long  IP[8][8] = {
1 << 7, 1 << 7, 1 << 15, 1 << 15, 1 << 23, 1 << 23, 1 << 31, 1 << 31,
1 << 6, 1 << 6, 1 << 14, 1 << 14, 1 << 22, 1 << 22, 1 << 30, 1 << 30,
1 << 5, 1 << 5, 1 << 13, 1 << 13, 1 << 21, 1 << 21, 1 << 29, 1 << 29,
1 << 4, 1 << 4, 1 << 12, 1 << 12, 1 << 20, 1 << 20, 1 << 28, 1 << 28,
1 << 3, 1 << 3, 1 << 11, 1 << 11, 1 << 19, 1 << 19, 1 << 27, 1 << 27,
1 << 2, 1 << 2, 1 << 10, 1 << 10, 1 << 18, 1 << 18, 1 << 26, 1 << 26,
1 << 1, 1 << 1, 1 <<  9, 1 <<  9, 1 << 17, 1 << 17, 1 << 25, 1 << 25,
1 << 0, 1 << 0, 1 <<  8, 1 <<  8, 1 << 16, 1 << 16, 1 << 24, 1 << 24
};
static unsigned long IIP[8][8] = {
1 << 24, 1 << 16, 1 <<  8, 1 <<  0, 1 << 24, 1 << 16, 1 <<  8, 1 <<  0,
1 << 26, 1 << 18, 1 << 10, 1 <<  2, 1 << 26, 1 << 18, 1 << 10, 1 <<  2,
1 << 28, 1 << 20, 1 << 12, 1 <<  4, 1 << 28, 1 << 20, 1 << 12, 1 <<  4,
1 << 30, 1 << 22, 1 << 14, 1 <<  6, 1 << 30, 1 << 22, 1 << 14, 1 <<  6, 
1 << 25, 1 << 17, 1 <<  9, 1 <<  1, 1 << 25, 1 << 17, 1 <<  9, 1 <<  1,
1 << 27, 1 << 19, 1 << 11, 1 <<  3, 1 << 27, 1 << 19, 1 << 11, 1 <<  3,
1 << 29, 1 << 21, 1 << 13, 1 <<  5, 1 << 29, 1 << 21, 1 << 13, 1 <<  5,
1 << 31, 1 << 23, 1 << 15, 1 <<  7, 1 << 31, 1 << 23, 1 << 15, 1 <<  7
};
#endif

/*
 * sp.h appended here by Mark Boyns
 */

/*
 * sp.h - contains combined Sbox and P permutation table
 *	      defined as left or right block (long)
 *	      Input bit ordering 5 3 2 1 0 4
 */

static unsigned long sbox_P[8][64] = {
/* SBOX 1 */ 
	  0x410100,	   0x10000,	0x40400000,	0x40410100,
	  0x400000,	0x40010100,	0x40010000,	0x40400000,
	0x40010100,	  0x410100,	  0x410000,	0x40000100,
	0x40400100,	  0x400000,	         0,	0x40010000,
	   0x10000,	0x40000000,	  0x400100,	   0x10100,
	0x40410100,	  0x410000,	0x40000100,	  0x400100,
	0x40000000,	     0x100,	   0x10100,	0x40410000,
	     0x100,	0x40400100,	0x40410000,	         0,
	         0,	0x40410100,	  0x400100,	0x40010000,
	  0x410100,	   0x10000,	0x40000100,	  0x400100,
	0x40410000,	     0x100,	   0x10100,	0x40400000,
	0x40010100,	0x40000000,	0x40400000,	  0x410000,
	0x40410100,	   0x10100,	  0x410000,	0x40400100,
	  0x400000,	0x40000100,	0x40010000,	         0,
	   0x10000,	  0x400000,	0x40400100,	  0x410100,
	0x40000000,	0x40410000,	     0x100,	0x40010100,
/* SBOX 2 */ 
	 0x8021002,	         0,	   0x21000,	 0x8020000,
	 0x8000002,	    0x1002,	 0x8001000,	   0x21000,
	    0x1000,	 0x8020002,	       0x2,	 0x8001000,
	   0x20002,	 0x8021000,	 0x8020000,	       0x2,
	   0x20000,	 0x8001002,	 0x8020002,	    0x1000,
	   0x21002,	 0x8000000,	         0,	   0x20002,
	 0x8001002,	   0x21002,	 0x8021000,	 0x8000002,
	 0x8000000,	   0x20000,	    0x1002,	 0x8021002,
	   0x20002,	 0x8021000,	 0x8001000,	   0x21002,
	 0x8021002,	   0x20002,	 0x8000002,	         0,
	 0x8000000,	    0x1002,	   0x20000,	 0x8020002,
	    0x1000,	 0x8000000,	   0x21002,	 0x8001002,
	 0x8021000,	    0x1000,	         0,	 0x8000002,
	       0x2,	 0x8021002,	   0x21000,	 0x8020000,
	 0x8020002,	   0x20000,	    0x1002,	 0x8001000,
	 0x8001002,	       0x2,	 0x8020000,	   0x21000,
/* SBOX 3 */ 
	0x20800000,	  0x808020,	      0x20,	0x20800020,
	0x20008000,	  0x800000,	0x20800020,	    0x8020,
	  0x800020,	    0x8000,	  0x808000,	0x20000000,
	0x20808020,	0x20000020,	0x20000000,	0x20808000,
	         0,	0x20008000,	  0x808020,	      0x20,
	0x20000020,	0x20808020,	    0x8000,	0x20800000,
	0x20808000,	  0x800020,	0x20008020,	  0x808000,
	    0x8020,	         0,	  0x800000,	0x20008020,
	  0x808020,	      0x20,	0x20000000,	    0x8000,
	0x20000020,	0x20008000,	  0x808000,	0x20800020,
	         0,	  0x808020,	    0x8020,	0x20808000,
	0x20008000,	  0x800000,	0x20808020,	0x20000000,
	0x20008020,	0x20800000,	  0x800000,	0x20808020,
	    0x8000,	  0x800020,	0x20800020,	    0x8020,
	  0x800020,	         0,	0x20808000,	0x20000020,
	0x20800000,	0x20008020,	      0x20,	  0x808000,
/* SBOX 4 */ 
	   0x80201,	 0x2000200,	       0x1,	 0x2080201,
	         0,	 0x2080000,	 0x2000201,	   0x80001,
	 0x2080200,	 0x2000001,	 0x2000000,	     0x201,
	 0x2000001,	   0x80201,	   0x80000,	 0x2000000,
	 0x2080001,	   0x80200,	     0x200,	       0x1,
	   0x80200,	 0x2000201,	 0x2080000,	     0x200,
	     0x201,	         0,	   0x80001,	 0x2080200,
	 0x2000200,	 0x2080001,	 0x2080201,	   0x80000,
	 0x2080001,	     0x201,	   0x80000,	 0x2000001,
	   0x80200,	 0x2000200,	       0x1,	 0x2080000,
	 0x2000201,	         0,	     0x200,	   0x80001,
	         0,	 0x2080001,	 0x2080200,	     0x200,
	 0x2000000,	 0x2080201,	   0x80201,	   0x80000,
	 0x2080201,	       0x1,	 0x2000200,	   0x80201,
	   0x80001,	   0x80200,	 0x2080000,	 0x2000201,
	     0x201,	 0x2000000,	 0x2000001,	 0x2080200,
/* SBOX 5 */ 
	 0x1000000,	    0x2000,	      0x80,	 0x1002084,
	 0x1002004,	 0x1000080,	    0x2084,	 0x1002000,
	    0x2000,	       0x4,	 0x1000004,	    0x2080,
	 0x1000084,	 0x1002004,	 0x1002080,	         0,
	    0x2080,	 0x1000000,	    0x2004,	      0x84,
	 0x1000080,	    0x2084,	         0,	 0x1000004,
	       0x4,	 0x1000084,	 0x1002084,	    0x2004,
	 0x1002000,	      0x80,	      0x84,	 0x1002080,
	 0x1002080,	 0x1000084,	    0x2004,	 0x1002000,
	    0x2000,	       0x4,	 0x1000004,	 0x1000080,
	 0x1000000,	    0x2080,	 0x1002084,	         0,
	    0x2084,	 0x1000000,	      0x80,	    0x2004,
	 0x1000084,	      0x80,	         0,	 0x1002084,
	 0x1002004,	 0x1002080,	      0x84,	    0x2000,
	    0x2080,	 0x1002004,	 0x1000080,	      0x84,
	       0x4,	    0x2084,	 0x1002000,	 0x1000004,
/* SBOX 6 */ 
	0x10000008,	   0x40008,	         0,	0x10040400,
	   0x40008,	     0x400,	0x10000408,	   0x40000,
	     0x408,	0x10040408,	   0x40400,	0x10000000,
	0x10000400,	0x10000008,	0x10040000,	   0x40408,
	   0x40000,	0x10000408,	0x10040008,	         0,
	     0x400,	       0x8,	0x10040400,	0x10040008,
	0x10040408,	0x10040000,	0x10000000,	     0x408,
	       0x8,	   0x40400,	   0x40408,	0x10000400,
	     0x408,	0x10000000,	0x10000400,	   0x40408,
	0x10040400,	   0x40008,	         0,	0x10000400,
	0x10000000,	     0x400,	0x10040008,	   0x40000,
	   0x40008,	0x10040408,	   0x40400,	       0x8,
	0x10040408,	   0x40400,	   0x40000,	0x10000408,
	0x10000008,	0x10040000,	   0x40408,	         0,
	     0x400,	0x10000008,	0x10000408,	0x10040400,
	0x10040000,	     0x408,	       0x8,	0x10040008,
/* SBOX 7 */ 
	     0x800,	      0x40,	  0x200040,	0x80200000,
	0x80200840,	0x80000800,	     0x840,	         0,
	  0x200000,	0x80200040,	0x80000040,	  0x200800,
	0x80000000,	  0x200840,	  0x200800,	0x80000040,
	0x80200040,	     0x800,	0x80000800,	0x80200840,
	         0,	  0x200040,	0x80200000,	     0x840,
	0x80200800,	0x80000840,	  0x200840,	0x80000000,
	0x80000840,	0x80200800,	      0x40,	  0x200000,
	0x80000840,	  0x200800,	0x80200800,	0x80000040,
	     0x800,	      0x40,	  0x200000,	0x80200800,
	0x80200040,	0x80000840,	     0x840,	         0,
	      0x40,	0x80200000,	0x80000000,	  0x200040,
	         0,	0x80200040,	  0x200040,	     0x840,
	0x80000040,	     0x800,	0x80200840,	  0x200000,
	  0x200840,	0x80000000,	0x80000800,	0x80200840,
	0x80200000,	  0x200840,	  0x200800,	0x80000800,
/* SBOX 8 */ 
	 0x4100010,	 0x4104000,	    0x4010,	         0,
	 0x4004000,	  0x100010,	 0x4100000,	 0x4104010,
	      0x10,	 0x4000000,	  0x104000,	    0x4010,
	  0x104010,	 0x4004010,	 0x4000010,	 0x4100000,
	    0x4000,	  0x104010,	  0x100010,	 0x4004000,
	 0x4104010,	 0x4000010,	         0,	  0x104000,
	 0x4000000,	  0x100000,	 0x4004010,	 0x4100010,
	  0x100000,	    0x4000,	 0x4104000,	      0x10,
	  0x100000,	    0x4000,	 0x4000010,	 0x4104010,
	    0x4010,	 0x4000000,	         0,	  0x104000,
	 0x4100010,	 0x4004010,	 0x4004000,	  0x100010,
	 0x4104000,	      0x10,	  0x100010,	 0x4004000,
	 0x4104010,	  0x100000,	 0x4100000,	 0x4000010,
	  0x104000,	    0x4010,	 0x4004010,	 0x4100000,
	      0x10,	 0x4104000,	  0x104010,	         0,
	 0x4000000,	 0x4100010,	    0x4000,	  0x104010,
};
