#include <stdio.h>
#include <string.h>
#include <malloc.h>
/*
 * by w.j.hengeveld nov1999
 *    itsme@xs4all.nl
 * 
 * based on a source file named des_pc.c of unknown origin
 * (my code starts at the *------*  comment line.)
 *
 */

void endes(char* inblock, char* outblock);
void dedes(char *inblock, char *outblock);
void permute( char *inblock, char perm[][16][8], char *outblock);
void desinit(char *key);
void sinit(void);
int getcomp(int k, int v);
void kinit( char *key);
void p32init(void);
void perminit( char perm[][16][8], char p[]);
void iter( int num, char *inblock, char *outblock);
void f( char *right, int num, char *fret);
void perm32( char *inblock, char *outblock);
void expand( char *right, char *bigright);
void contract( char *in48, char *out32);


char iperm[16][16][8],fperm[16][16][8]; /* inital and final permutations*/
char s[4][4096];			/* S1 thru S8 precomputed	*/
char p32[4][256][4];			/* for permuting 32-bit f output*/
char kn[16][6];				/* key selections		*/

void endes(char* inblock, char* outblock)			/* encrypt 64-bit inblock	*/
{	char iters[17][8];		/* workspace for each iteration */
	char swap[8];			/* place to interchange L and R */
	int i;
	char *s, *t;

	permute(inblock,iperm,iters[0]);/* apply initial permutation	*/
	for (i=0; i<16; i++)		/* 16 churning operations	*/
		iter(i,iters[i],iters[i+1]);
					/* don't re-copy to save space  */
	s = swap; t = &iters[16][4];	/* interchange left		*/
	*s++ = *t++; *s++ = *t++; *s++ = *t++; *s++ = *t++;
	t = &iters[16][0];		/* and right			*/
	*s++ = *t++; *s++ = *t++; *s++ = *t++; *s++ = *t++;
	permute(swap,fperm,outblock);   /* apply final permutation	*/
}

void dedes(char *inblock, char *outblock)			/* decrypt 64-bit inblock	*/
{	char iters[17][8];		/* workspace for each iteration */
	char swap[8];			/* place to interchange L and R */
	int i;
	char *s, *t;

	permute(inblock,iperm,iters[0]);/* apply initial permutation	*/
	for (i=0; i<16; i++)		/* 16 churning operations	*/
		iter(15-i,iters[i],iters[i+1]);
					/* reverse order from encrypting*/
	s = swap; t = &iters[16][4];	/* interchange left		*/
	*s++ = *t++; *s++ = *t++; *s++ = *t++; *s++ = *t++;
	t = &iters[16][0];		/* and right			*/
	*s++ = *t++; *s++ = *t++; *s++ = *t++; *s++ = *t++;
	permute(swap,fperm,outblock);   /* apply final permutation	*/
}

void permute(		/* permute inblock with perm	*/
		char *inblock,
		char perm[][16][8],	/* 2K bytes defining perm.	*/
		char *outblock)		/* result into outblock,64 bits */
// char perm[16][16][8];
{	int i,j;
	char *ib, *ob;		/* ptr to input or output block */
	char *p, *q;

	for (i=0, ob = outblock; i<8; i++)
		*ob++ = 0;		/* clear output block		*/
	ib = inblock;
	for (j = 0; j < 16; j += 2, ib++) /* for each input nibble	*/
	{	ob = outblock;
		p = perm[j][(*ib >> 4) & 017];
		q = perm[j + 1][*ib & 017];
		for (i = 0; i < 8; i++)   /* and each output byte	*/
			*ob++ |= *p++ | *q++;   /* OR the masks together*/
	}
}

char ip[]				/* initial permutation P	*/
= {	58, 50, 42, 34, 26, 18, 10,  2,
	60, 52, 44, 36, 28, 20, 12,  4,
	62, 54, 46, 38, 30, 22, 14,  6,
	64, 56, 48, 40, 32, 24, 16,  8,
	57, 49, 41, 33, 25, 17,  9,  1,
	59, 51, 43, 35, 27, 19, 11,  3,
	61, 53, 45, 37, 29, 21, 13,  5,
	63, 55, 47, 39, 31, 23, 15,  7	};

char fp[]				/* final permutation F	  */
= {	40,  8, 48, 16, 56, 24, 64, 32,
	39,  7, 47, 15, 55, 23, 63, 31,
	38,  6, 46, 14, 54, 22, 62, 30,
	37,  5, 45, 13, 53, 21, 61, 29,
	36,  4, 44, 12, 52, 20, 60, 28,
	35,  3, 43, 11, 51, 19, 59, 27,
	34,  2, 42, 10, 50, 18, 58, 26,
	33,  1, 41,  9, 49, 17, 57, 25	};

/* expansion operation matrix   */	/* rwo: unused	*/
/* char ei[] = {	32,  1,  2,  3,  4,  5,
	 4,  5,  6,  7,  8,  9,
	 8,  9, 10, 11, 12, 13,
	12, 13, 14, 15, 16, 17,
	16, 17, 18, 19, 20, 21,
	20, 21, 22, 23, 24, 25,
	24, 25, 26, 27, 28, 29,
	28, 29, 30, 31, 32,  1  };	*/

char pc1[]				/* permuted choice table (key)  */
= {	57, 49, 41, 33, 25, 17,  9,
	 1, 58, 50, 42, 34, 26, 18,
	10,  2, 59, 51, 43, 35, 27,
	19, 11,  3, 60, 52, 44, 36,

	63, 55, 47, 39, 31, 23, 15,
	 7, 62, 54, 46, 38, 30, 22,
	14,  6, 61, 53, 45, 37, 29,
	21, 13,  5, 28, 20, 12,  4	};

char totrot[]			   /* number left rotations of pc1 */
= {	1,2,4,6,8,10,12,14,15,17,19,21,23,25,27,28	};

char pc1m[56];			  /* place to modify pc1 into	*/
char pcr[56];			   /* place to rotate pc1 into	*/

char pc2[]				/* permuted choice key (table)  */
= {	14, 17, 11, 24,  1,  5,
	 3, 28, 15,  6, 21, 10,
	23, 19, 12,  4, 26,  8,
	16,  7, 27, 20, 13,  2,
	41, 52, 31, 37, 47, 55,
	30, 40, 51, 45, 33, 48,
	44, 49, 39, 56, 34, 53,
	46, 42, 50, 36, 29, 32	};

char si[8][64]			  /* 48->32 bit compression tables*/
= {					/* S[1]			 */
	14,  4, 13,  1,  2, 15, 11,  8,  3, 10,  6, 12,  5,  9,  0,  7,
	 0, 15,  7,  4, 14,  2, 13,  1, 10,  6, 12, 11,  9,  5,  3,  8,
	 4,  1, 14,  8, 13,  6,  2, 11, 15, 12,  9,  7,  3, 10,  5,  0,
	15, 12,  8,  2,  4,  9,  1,  7,  5, 11,  3, 14, 10,  0,  6, 13,
					/* S[2]			 */
	15,  1,  8, 14,  6, 11,  3,  4,  9,  7,  2, 13, 12,  0,  5, 10,
	 3, 13,  4,  7, 15,  2,  8, 14, 12,  0,  1, 10,  6,  9, 11,  5,
	 0, 14,  7, 11, 10,  4, 13,  1,  5,  8, 12,  6,  9,  3,  2, 15,
	13,  8, 10,  1,  3, 15,  4,  2, 11,  6,  7, 12,  0,  5, 14,  9,
					/* S[3]			 */
	10,  0,  9, 14,  6,  3, 15,  5,  1, 13, 12,  7, 11,  4,  2,  8,
	13,  7,  0,  9,  3,  4,  6, 10,  2,  8,  5, 14, 12, 11, 15,  1,
	13,  6,  4,  9,  8, 15,  3,  0, 11,  1,  2, 12,  5, 10, 14,  7,
	 1, 10, 13,  0,  6,  9,  8,  7,  4, 15, 14,  3, 11,  5,  2, 12,
					/* S[4]			 */
	 7, 13, 14,  3,  0,  6,  9, 10,  1,  2,  8,  5, 11, 12,  4, 15,
	13,  8, 11,  5,  6, 15,  0,  3,  4,  7,  2, 12,  1, 10, 14,  9,
	10,  6,  9,  0, 12, 11,  7, 13, 15,  1,  3, 14,  5,  2,  8,  4,
	 3, 15,  0,  6, 10,  1, 13,  8,  9,  4,  5, 11, 12,  7,  2, 14,
					/* S[5]			 */
	 2, 12,  4,  1,  7, 10, 11,  6,  8,  5,  3, 15, 13,  0, 14,  9,
	14, 11,  2, 12,  4,  7, 13,  1,  5,  0, 15, 10,  3,  9,  8,  6,
	 4,  2,  1, 11, 10, 13,  7,  8, 15,  9, 12,  5,  6,  3,  0, 14,
	11,  8, 12,  7,  1, 14,  2, 13,  6, 15,  0,  9, 10,  4,  5,  3,
					/* S[6]			 */
	12,  1, 10, 15,  9,  2,  6,  8,  0, 13,  3,  4, 14,  7,  5, 11,
	10, 15,  4,  2,  7, 12,  9,  5,  6,  1, 13, 14,  0, 11,  3,  8,
	 9, 14, 15,  5,  2,  8, 12,  3,  7,  0,  4, 10,  1, 13, 11,  6,
	 4,  3,  2, 12,  9,  5, 15, 10, 11, 14,  1,  7,  6,  0,  8, 13,
					/* S[7]			 */
	 4, 11,  2, 14, 15,  0,  8, 13,  3, 12,  9,  7,  5, 10,  6,  1,
	13,  0, 11,  7,  4,  9,  1, 10, 14,  3,  5, 12,  2, 15,  8,  6,
	 1,  4, 11, 13, 12,  3,  7, 14, 10, 15,  6,  8,  0,  5,  9,  2,
	 6, 11, 13,  8,  1,  4, 10,  7,  9,  5,  0, 15, 14,  2,  3, 12,
					/* S[8]			 */
	13,  2,  8,  4,  6, 15, 11,  1, 10,  9,  3, 14,  5,  0, 12,  7,
	 1, 15, 13,  8, 10,  3,  7,  4, 12,  5,  6, 11,  0, 14,  9,  2,
	 7, 11,  4,  1,  9, 12, 14,  2,  0,  6, 10, 13, 15,  3,  5,  8,
	 2,  1, 14,  7,  4, 10,  8, 13, 15, 12,  9,  0,  3,  5,  6, 11	};

char p32i[]				/* 32-bit permutation function  */
= {	16,  7, 20, 21,
	29, 12, 28, 17,
	 1, 15, 23, 26,
	 5, 18, 31, 10,
	 2,  8, 24, 14,
	32, 27,  3,  9,
	19, 13, 30,  6,
	22, 11,  4, 25	};

void desinit(char *key)				/* initialize all des arrays	*/
{
	perminit(iperm,ip);		/* initial permutation		*/
	perminit(fperm,fp);		/* final permutation		*/
	kinit(key);			/* key schedule			*/
	sinit();			/* compression functions	*/

	p32init();			/* 32-bit permutation in f	*/
}

int bytebit[]			   /* bit 0 is left-most in byte	*/
	= {	0200,0100,040,020,010,04,02,01 };

int nibblebit[] = { 010,04,02,01 };

void sinit(void)				 /* initialize s1-s8 arrays		*/
{
	int i,j;

	for (i=0; i<4; i++)		/* each 12-bit position		*/
		for (j=0; j<4096; j++)  /* each possible 12-bit value   */
			s[i][j]=(getcomp(i*2,j>>6)<<4) |
				(017&getcomp(i*2+1,j&077));
					/* store 2 compressions per char*/
}

int getcomp(int k, int v)				/* 1 compression value for sinit*/
{	int i,j;		/* correspond to i and j in FIPS*/

	i=((v&040)>>4)|(v&1);		/* first and last bits make row */
	j=(v&037)>>1;			/* middle 4 bits are column	*/
	return (int) si[k][(i<<4)+j];   /* result is ith row, jth col   */
}

void kinit(				/* initialize key schedule array*/
		char *key)			/* 64 bits (will use only 56)   */
{	int i,j,l;
	int m;

	for (j=0; j<56; j++)		/* convert pc1 to bits of key   */
	{	l=pc1[j]-1;		/* integer bit location		*/
		m = l & 07;		/* find bit			*/
		pc1m[j]=(key[l>>3] &	/* find which key byte l is in  */
			bytebit[m])	/* and which bit of that byte   */
			? 1 : 0;	/* and store 1-bit result	*/
	}
	for (i=0; i<16; i++)		/* for each key sched section   */
		for (j=0; j<6; j++)	/* and each byte of the kn	*/
			kn[i][j]=0;	/* clear it for accumulation	*/
	for (i=0; i<16; i++)		/* key chunk for each iteration */
	{	for (j=0; j<56; j++)	/* rotate pc1 the right amount  */
		pcr[j] = pc1m[(l=j+totrot[i])<(j<28? 28 : 56) ? l: l-28];
			/* rotate left and right halves independently   */
		for (j=0; j<48; j++)	/* select bits individually	*/
		if (pcr[pc2[j]-1])	/* check bit that goes to kn[j] */
			{	l= j & 07;
				kn[i][j>>3] |= bytebit[l];
			}		/* mask it in if it's there	*/
	}
}

void p32init(void)				/* initialize 32-bit permutation*/
{	int l, j, k;
	int i,m;

	for (i=0; i<4; i++)		/* each input byte position	*/
		for (j=0; j<256; j++)	/* all possible input bytes	*/
		for (k=0; k<4; k++)	/* each byte of the mask	*/
			p32[i][j][k]=0;	/* clear permutation array	*/
	for (i=0; i<4; i++)		/* each input byte position	*/
		for (j=0; j<256; j++)	/* each possible input byte	*/
		for (k=0; k<32; k++)	/* each output bit position	*/
		{   l=p32i[k]-1;	/* invert this bit (0-31)	*/
			if ((l>>3)!=i)	/* does it come from input posn?*/
			continue;	/* if not, bit k is 0		*/
			if (!(j&bytebit[l&07]))
			continue;	/* any such bit in input?	*/
			m = k & 07;	 /* which bit is it?		*/
			p32[i][j][k>>3] |= bytebit[m];
		}
}

void perminit(		/* initialize a perm array	*/
			char perm[][16][8],	// char perm[16][16][8]  64-bit, either init or final
			char p[])				// char p[64];
{	int l, j, k;
	int i,m;

	for (i=0; i<16; i++)		/* each input nibble position   */
		for (j=0; j<16; j++)	/* all possible input nibbles   */
		for (k=0; k<8; k++)	/* each byte of the mask	*/
			perm[i][j][k]=0;/* clear permutation array	*/
	for (i=0; i<16; i++)		/* each input nibble position   */
		for (j = 0; j < 16; j++)/* each possible input nibble   */
		for (k = 0; k < 64; k++)/* each output bit position	*/
		{   l = p[k] - 1;	/* where does this bit come from*/
			if ((l >> 2) != i)  /* does it come from input posn?*/
			continue;	/* if not, bit k is 0		*/
			if (!(j & nibblebit[l & 3]))
			continue;	/* any such bit in input?	*/
			m = k & 07;	/* which bit is this in the byte*/
			perm[i][j][k>>3] |= bytebit[m];
		}
}

void iter(		/* 1 churning operation		*/
			int num,	/* i.e. the num-th one		*/
			char *inblock,/* 64 bits each			*/
			char *outblock)
{	char fret[4];			/* return from f(R[i-1],key)	*/
	char *ib, *ob, *fb;

	ob = outblock; ib = &inblock[4];
	f(ib, num, fret);		/* the primary transformation   */
	*ob++ = *ib++;			/* L[i] = R[i-1]		*/
	*ob++ = *ib++;
	*ob++ = *ib++;
	*ob++ = *ib++;
	ib = inblock; fb = fret;	/* R[i]=L[i] XOR f(R[i-1],key)  */
	*ob++ = *ib++ ^ *fb++;
	*ob++ = *ib++ ^ *fb++;
	*ob++ = *ib++ ^ *fb++;
	*ob++ = *ib++ ^ *fb++;
}

void f(			/* critical cryptographic trans */
			char *right,			/* 32 bits each			*/
			int num,		/* index number of this iter	*/
			char *fret)
{	char *kb, *rb, *bb;	/* ptr to key selection &c	*/
	char bigright[6];		/* right expanded to 48 bits	*/
	char result[6];			/* expand(R) XOR keyselect[num] */
	char preout[4];			/* result of 32-bit permutation */

	kb = kn[num];			/* fast version of iteration	*/
	bb = bigright;
	rb = result;
	expand(right,bb);		/* expand to 48 bits		*/
	*rb++ = *bb++ ^ *kb++;		/* expanded R XOR chunk of key  */
	*rb++ = *bb++ ^ *kb++;
	*rb++ = *bb++ ^ *kb++;
	*rb++ = *bb++ ^ *kb++;
	*rb++ = *bb++ ^ *kb++;
	*rb++ = *bb++ ^ *kb++;
	contract(result,preout);	/* use S fns to get 32 bits	*/
	perm32(preout,fret);		/* and do final 32-bit perm	*/
}

void perm32(			/* 32-bit permutation at end	*/
		char *inblock,
		char *outblock)		/* of the f crypto function	*/
{	int j;
	char *ib, *ob;
	char *q;

	ob = outblock;			/* clear output block		*/
	*ob++ = 0; *ob++ = 0; *ob++ = 0; *ob++ = 0;
	ib=inblock;			/* ptr to 1st byte of input	*/
	for (j=0; j<4; j++, ib++)	/* for each input byte		*/
	{	q = p32[j][*ib & 0377];
		ob = outblock;		/* and each output byte		*/
		*ob++ |= *q++;		/* OR the 16 masks together	*/
		*ob++ |= *q++;
		*ob++ |= *q++;
		*ob++ |= *q++;
	}
}

void expand(			/* 32 to 48 bits with E oper	*/
			char *right,
			char *bigright)			/* right is 32, bigright 48	*/
{
	char *bb, *r, r0, r1, r2, r3;

	bb = bigright;
	r = right; r0 = *r++; r1 = *r++; r2 = *r++; r3 = *r++;
	*bb++ = ((r3 & 0001) << 7) |	/* 32				*/
		((r0 & 0370) >> 1) |	/* 1 2 3 4 5			*/
		((r0 & 0030) >> 3);	/* 4 5				*/
	*bb++ = ((r0 & 0007) << 5) |	/* 6 7 8			*/
		((r1 & 0200) >> 3) |	/* 9				*/
		((r0 & 0001) << 3) |	/* 8				*/
		((r1 & 0340) >> 5);	/* 9 10 11			*/
	*bb++ = ((r1 & 0030) << 3) |	/* 12 13			*/
		((r1 & 0037) << 1) |	/* 12 13 14 15 16		*/
		((r2 & 0200) >> 7);	/* 17				*/
	*bb++ = ((r1 & 0001) << 7) |	/* 16				*/
		((r2 & 0370) >> 1) |	/* 17 18 19 20 21		*/
		((r2 & 0030) >> 3);	/* 20 21			*/
	*bb++ = ((r2 & 0007) << 5) |	/* 22 23 24			*/
		((r3 & 0200) >> 3) |	/* 25				*/
		((r2 & 0001) << 3) |	/* 24				*/
		((r3 & 0340) >> 5);	/* 25 26 27			*/
	*bb++ = ((r3 & 0030) << 3) |	/* 28 29			*/
		((r3 & 0037) << 1) |	/* 28 29 30 31 32		*/
		((r0 & 0200) >> 7);	/* 1				*/
}

void contract(				/* contract f from 48 to 32 bits*/
			char *in48, char *out32)	/* using 12-bit pieces into bytes */
{	char *c;
	char *i;
	int i0, i1, i2, i3, i4, i5;

	i = in48;
	i0 = *i++; i1 = *i++; i2 = *i++; i3 = *i++; i4 = *i++; i5 = *i++;
	c = out32;			/* do output a byte at a time   */
	*c++ = s[0][07777 & ((i0 << 4) | ((i1 >> 4) & 017  ))];
	*c++ = s[1][07777 & ((i1 << 8) | ( i2	& 0377 ))];
	*c++ = s[2][07777 & ((i3 << 4) | ((i4 >> 4) & 017  ))];
	*c++ = s[3][07777 & ((i4 << 8) | ( i5	& 0377 ))];
}

/*-------------------------------------------------------------*/
/* everything below this line was added by itsme@xs4all.nl */

void writehex(char *str)   /* write the 64-bit hex string */
{	int i;

	for (i = 0; i < 8; i++)
		printf("%02x", str[i] & 0377);
}

int hex(int n)  /* convert hex nibble into integer */
{
	if (n >= 'A' && n <= 'F') return n - 'A' + 10;
	if (n >= 'a' && n <= 'f') return n - 'a' + 10;
	if (n >= '0' && n <= '9') return n - '0';
	return 0;
}

void hextodata(char *str, char *data)	/* read 64 bits of hex code */
{
	int i, c;

	for (i = 0; i < 8; i++)
	{
		c = 0;
		if (*str) c |= hex(*str++) << 4;
		if (*str) c |= hex(*str++);
		data[i] = c;
	}
}

char dseg06[]={
/*  0     1     2     3     4     5     6     7     8     9     a     b     c     d     e     f */
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0 */
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 1 */
 0x40, 0x5A, 0x7F, 0x5B, 0x4A, 0x6C, 0x50, 0x7D, 0x4D, 0x5D, 0x5C, 0x4E, 0x6B, 0x60, 0x4B, 0x61, /* 2 */
 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0x7A, 0x5E, 0x4C, 0x7E, 0x6E, 0x6F, /* 3 */
 0x7C, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, /* 4 */
 0xD7, 0xD8, 0xD9, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xAD, 0xE0, 0xBD, 0x5F, 0x7B, /* 5 */
 0x6D, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, /* 6 */
 0x97, 0x98, 0x99, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xC0, 0x6A, 0xD0, 0xA1, 0x00, /* 7 */
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 8 */
};

void giro_encode(char *plain, char *encoded)
{
	while (*plain)
	{
		*encoded++ = dseg06[(*plain++)&0xff];
	}
	*encoded=0;
}

long giro_check(char *message)
{
	long check=0L;
	int count=1;

	while (*message)
	{
		check += (count++) * dseg06[(*message++)&0xff];
	}
	return check;
}

void usage(void)
{
	printf("des_pc [option] keydata [option] textdata\n");
	printf(" data optionally preceeded by '-x' or '-e'\n");
	printf("   -x : read as hex (instead of ascii)\n");
	printf("   -e : encode using girotel encoding\n");
}

#define BUFSIZE 10
int main(int argc, char **argv)
{
	char encodedkey[BUFSIZE];
	char encodedtext[BUFSIZE];
	char cipher[BUFSIZE];
	char xorkey[BUFSIZE];
	char xortxt[BUFSIZE];

	char *key=NULL;
	char *text=NULL;

	int i, j;
	int readashex=0;
	int encodevalue=0;
	int do_encode_text=0;
	int do_encode_key=0;

	memset(encodedkey, 0, BUFSIZE);
	memset(encodedtext, 0, BUFSIZE);
	memset(cipher, 0, BUFSIZE);
	memset(xorkey, 0, BUFSIZE);
	memset(xortxt, 0, BUFSIZE);

	for (i=1 ; i<argc ; i++)
	{
		if (readashex)
		{
			if (key==NULL) { key=malloc(BUFSIZE); hextodata(argv[i], key); do_encode_key=encodevalue; }
			else if (text==NULL) { text = malloc(BUFSIZE); hextodata(argv[i], text); do_encode_text=encodevalue; }
			readashex=0;
			encodevalue=0;
		}
		else if (argv[i][0]=='-')
		{
			readashex=0;
			encodevalue=0;
			for (j=0 ; j<strlen(argv[i]) ; j++)
			{
				if (argv[i][j]=='x') readashex=1;
				else if (argv[i][j]=='e') encodevalue=1;
				else if (argv[i][j]=='h')
				{
					usage();
					exit(1);
				}
			}
		}
		else
		{
			if (key==NULL) { key = argv[i]; do_encode_key=encodevalue; }
			else if (text==NULL) { text = argv[i]; do_encode_text=encodevalue; }
			readashex=0;
			encodevalue=0;
		}
	}

	if (key==NULL || text==NULL)
	{
		usage();
		exit(1);
	}
	if (do_encode_key)
		giro_encode(key, encodedkey);
	else
		memcpy(encodedkey, key, 8);

	if (do_encode_text)
		giro_encode(text, encodedtext);
	else
		memcpy(encodedtext, text, 8);

	desinit(encodedkey);

	endes(encodedtext, cipher);
	for (i=0 ; i<8 ; i++) xorkey[i] = cipher[i] ^ encodedkey[i];
	for (i=0 ; i<8 ; i++) xortxt[i] = cipher[i] ^ encodedtext[i];

	printf("key   : "); writehex(encodedkey); printf("\n");
	printf("text  : "); writehex(encodedtext); printf("\n");
	printf("cipher: "); writehex(cipher); printf("\n");

	printf("xorkey: "); writehex(xorkey); printf("\n");
	printf("xortxt: "); writehex(xortxt); printf("\n");

	return 0;
}
