0x800000L,0x400000L,0x200000L,0x100000L,0x80000L,0x40000L,0x20000L,0x10000L,0x8000L,0x4000L,0x2000L,0x1000L,0x800L,0x400L,0x200L,0x100L,0x80L,0x40L,0x20L,0x10L,0x8L,0x4L,0x2L,0x1L};/* Use the key schedule specified in the Standard (ANSI X3.92-1981). */
13,16,10,23,0,4,2,27,14,5,20,9,22,18,11,3,25,7,15,6,26,19,12,1,40,51,30,36,46,54,29,39,50,44,32,47,43,48,38,55,33,52,45,41,49,35,28,31};voiddeskey(key,edf)/* Thanks to James Gillogly & Phil Karn! */unsignedchar*key;intedf;{registerinti,j,l,m,n;unsignedcharpc1m[56],pcr[56];unsignedlongkn[32];for(j=0;j<56;j++){l=pc1[j];m=l&07;pc1m[j]=(key[l>>3]&bytebit[m])?1:0;}for(i=0;i<16;i++){if(edf==DE1)m=(15-i)<<1;elsem=i<<1;n=m+1;kn[m]=kn[n]=0L;for(j=0;j<28;j++){l=j+totrot[i];if(l<28)pcr[j]=pc1m[l];elsepcr[j]=pc1m[l-28];}for(j=28;j<56;j++){l=j+totrot[i];if(l<56)pcr[j]=pc1m[l];elsepcr[j]=pc1m[l-28];}for(j=0;j<24;j++){if(pcr[pc2[j]])kn[m]|=bigbyte[j];if(pcr[pc2[j+24]])kn[n]|=bigbyte[j];}}cookey(kn);return;}staticvoidcookey(raw1)registerunsignedlong*raw1;{registerunsignedlong*cook,*raw0;unsignedlongdough[32];registerinti;cook=dough;for(i=0;i<16;i++,raw1++){raw0=raw1++;*cook=(*raw0&0x00fc0000L)<<6;*cook|=(*raw0&0x00000fc0L)<<10;*cook|=(*raw1&0x00fc0000L)>>10;*cook++|=(*raw1&0x00000fc0L)>>6;*cook=(*raw0&0x0003f000L)<<12;*cook|=(*raw0&0x0000003fL)<<16;*cook|=(*raw1&0x0003f000L)>>4;*cook++|=(*raw1&0x0000003fL);}usekey(dough);return;}voidcpkey(into)registerunsignedlong*into;{registerunsignedlong*from,*endp;from=KnL,endp=&KnL[32];while(from<endp)*into++=*from++;return;}voidusekey(from)registerunsignedlong*from;{registerunsignedlong*to,*endp;to=KnL,endp=&KnL[32];while(to<endp)*to++=*from++;return;}voiddes(inblock,outblock)unsignedchar*inblock,*outblock;{unsignedlongwork[2];scrunch(inblock,work);desfunc(work,KnL);unscrun(work,outblock);return;}staticvoidscrunch(outof,into)registerunsignedchar*outof;registerunsignedlong*into;{*into=(*outof++&0xffL)<<24;*into|=(*outof++&0xffL)<<16;*into|=(*outof++&0xffL)<<8;*into++|=(*outof++&0xffL);*into=(*outof++&0xffL)<<24;*into|=(*outof++&0xffL)<<16;*into|=(*outof++&0xffL)<<8;*into|=(*outof&0xffL);return;}staticvoidunscrun(outof,into)registerunsignedlong*outof;registerunsignedchar*into;{*into++=(unsignedchar)((*outof>>24)&0xffL);*into++=(unsignedchar)((*outof>>16)&0xffL);*into++=(unsignedchar)((*outof>>8)&0xffL);*into++=(unsignedchar)(*outof++&0xffL);*into++=(unsignedchar)((*outof>>24)&0xffL);*into++=(unsignedchar)((*outof>>16)&0xffL);*into++=(unsignedchar)((*outof>>8)&0xffL);*into=(unsignedchar)(*outof&0xffL);return;}staticunsignedlongSP1[64]={0x01010400L,0x00000000L,0x00010000L,0x01010404L,0x01010004L,0x00010404L,0x00000004L,0x00010000L,0x00000400L,0x01010400L,0x01010404L,0x00000400L,0x01000404L,0x01010004L,0x01000000L,0x00000004L,0x00000404L,0x01000400L,0x01000400L,0x00010400L,0x00010400L,0x01010000L,0x01010000L,0x01000404L,0x00010004L,0x01000004L,0x01000004L,0x00010004L,0x00000000L,0x00000404L,0x00010404L,0x01000000L,0x00010000L,0x01010404L,0x00000004L,0x01010000L,0x01010400L,0x01000000L,0x01000000L,0x00000400L,0x01010004L,0x00010000L,0x00010400L,0x01000004L,0x00000400L,0x00000004L,0x01000404L,0x00010404L,0x01010404L,0x00010004L,0x01010000L,0x01000404L,0x01000004L,0x00000404L,0x00010404L,0x01010400L,0x00000404L,0x01000400L,0x01000400L,0x00000000L,0x00010004L,0x00010400L,0x00000000L,0x01010004L};staticunsignedlongSP2[64]={0x80108020L,0x80008000L,0x00008000L,0x00108020L,0x00100000L,0x00000020L,0x80100020L,0x80008020L,0x80000020L,0x80108020L,0x80108000L,0x80000000L,0x80008000L,0x00100000L,0x00000020L,0x80100020L,0x00108000L,0x00100020L,0x80008020L,0x00000000L,0x80000000L,0x00008000L,0x00108020L,0x80100000L,0x00100020L,0x80000020L,0x00000000L,0x00108000L,0x00008020L,0x80108000L,0x80100000L,0x00008020L,0x00000000L,0x00108020L,0x80100020L,0x00100000L,0x80008020L,0x80100000L,0x80108000L,0x00008000L,0x80100000L,0x80008000L,0x00000020L,0x80108020L,0x00108020L,0x00000020L,0x00008000L,0x80000000L,0x00008020L,0x80108000L,0x00100000L,0x80000020L,0x00100020L,0x80008020L,0x80000020L,0x00100020L,0x00108000L,0x00000000L,0x80008000L,0x00008020L,0x80000000L,0x80100020L,0x80108020L,0x00108000L};staticunsignedlongSP3[64]={0x00000208L,0x08020200L,0x00000000L,0x08020008L,0x08000200L,0x00000000L,0x00020208L,0x08000200L,0x00020008L,0x08000008L,0x08000008L,0x00020000L,0x08020208L,0x00020008L,0x08020000L,0x00000208L,0x08000000L,0x00000008L,0x08020200L,0x00000200L,0x00020200L,0x08020000L,0x08020008L,0x00020208L,0x08000208L,0x00020200L,0x00020000L,0x08000208L,0x00000008L,0x08020208L,0x00000200L,0x08000000L,0x08020200L,0x08000000L,0x00020008L,0x00000208L,0x00020000L,0x08020200L,0x08000200L,0x00000000L,0x00000200L,0x00020008L,0x08020208L,0x08000200L,0x08000008L,0x00000200L,0x00000000L,0x08020008L,0x08000208L,0x00020000L,0x08000000L,0x08020208L,0x00000008L,0x00020208L,0x00020200L,0x08000008L,0x08020000L,0x08000208L,0x00000208L,0x08020000L,0x00020208L,0x00000008L,0x08020008L,0x00020200L};staticunsignedlongSP4[64]={0x00802001L,0x00002081L,0x00002081L,0x00000080L,0x00802080L,0x00800081L,0x00800001L,0x00002001L,0x00000000L,0x00802000L,0x00802000L,0x00802081L,0x00000081L,0x00000000L,0x00800080L,0x00800001L,0x00000001L,0x00002000L,0x00800000L,0x00802001L,0x00000080L,0x00800000L,0x00002001L,0x00002080L,0x00800081L,0x00000001L,0x00002080L,0x00800080L,0x00002000L,0x00802080L,0x00802081L,0x00000081L,0x00800080L,0x00800001L,0x00802000L,0x00802081L,0x00000081L,0x00000000L,0x00000000L,0x00802000L,0x00002080L,0x00800080L,0x00800081L,0x00000001L,0x00802001L,0x00002081L,0x00002081L,0x00000080L,0x00802081L,0x00000081L,0x00000001L,0x00002000L,0x00800001L,0x00002001L,0x00802080L,0x00800081L,0x00002001L,0x00002080L,0x00800000L,0x00802001L,0x00000080L,0x00800000L,0x00002000L,0x00802080L};staticunsignedlongSP5[64]={0x00000100L,0x02080100L,0x02080000L,0x42000100L,0x00080000L,0x00000100L,0x40000000L,0x02080000L,0x40080100L,0x00080000L,0x02000100L,0x40080100L,0x42000100L,0x42080000L,0x00080100L,0x40000000L,0x02000000L,0x40080000L,0x40080000L,0x00000000L,0x40000100L,0x42080100L,0x42080100L,0x02000100L,0x42080000L,0x40000100L,0x00000000L,0x42000000L,0x02080100L,0x02000000L,0x42000000L,0x00080100L,0x00080000L,0x42000100L,0x00000100L,0x02000000L,0x40000000L,0x02080000L,0x42000100L,0x40080100L,0x02000100L,0x40000000L,0x42080000L,0x02080100L,0x40080100L,0x00000100L,0x02000000L,0x42080000L,0x42080100L,0x00080100L,0x42000000L,0x42080100L,0x02080000L,0x00000000L,0x40080000L,0x42000000L,0x00080100L,0x02000100L,0x40000100L,0x00080000L,0x00000000L,0x40080000L,0x02080100L,0x40000100L};staticunsignedlongSP6[64]={0x20000010L,0x20400000L,0x00004000L,0x20404010L,0x20400000L,0x00000010L,0x20404010L,0x00400000L,0x20004000L,0x00404010L,0x00400000L,0x20000010L,0x00400010L,0x20004000L,0x20000000L,0x00004010L,0x00000000L,0x00400010L,0x20004010L,0x00004000L,0x00404000L,0x20004010L,0x00000010L,0x20400010L,0x20400010L,0x00000000L,0x00404010L,0x20404000L,0x00004010L,0x00404000L,0x20404000L,0x20000000L,0x20004000L,0x00000010L,0x20400010L,0x00404000L,0x20404010L,0x00400000L,0x00004010L,0x20000010L,0x00400000L,0x20004000L,0x20000000L,0x00004010L,0x20000010L,0x20404010L,0x00404000L,0x20400000L,0x00404010L,0x20404000L,0x00000000L,0x20400010L,0x00000010L,0x00004000L,0x20400000L,0x00404010L,0x00004000L,0x00400010L,0x20004010L,0x00000000L,0x20404000L,0x20000000L,0x00400010L,0x20004010L};staticunsignedlongSP7[64]={0x00200000L,0x04200002L,0x04000802L,0x00000000L,0x00000800L,0x04000802L,0x00200802L,0x04200800L,0x04200802L,0x00200000L,0x00000000L,0x04000002L,0x00000002L,0x04000000L,0x04200002L,0x00000802L,0x04000800L,0x00200802L,0x00200002L,0x04000800L,0x04000002L,0x04200000L,0x04200800L,0x00200002L,0x04200000L,0x00000800L,0x00000802L,0x04200802L,0x00200800L,0x00000002L,0x04000000L,0x00200800L,0x04000000L,0x00200800L,0x00200000L,0x04000802L,0x04000802L,0x04200002L,0x04200002L,0x00000002L,0x00200002L,0x04000000L,0x04000800L,0x00200000L,0x04200800L,0x00000802L,0x00200802L,0x04200800L,0x00000802L,0x04000002L,0x04200802L,0x04200000L,0x00200800L,0x00000000L,0x00000002L,0x04200802L,0x00000000L,0x00200802L,0x04200000L,0x00000800L,0x04000002L,0x04000800L,0x00000800L,0x00200002L};staticunsignedlongSP8[64]={0x10001040L,0x00001000L,0x00040000L,0x10041040L,0x10000000L,0x10001040L,0x00000040L,0x10000000L,0x00040040L,0x10040000L,0x10041040L,0x00041000L,0x10041000L,0x00041040L,0x00001000L,0x00000040L,0x10040000L,0x10000040L,0x10001000L,0x00001040L,0x00041000L,0x00040040L,0x10040040L,0x10041000L,0x00001040L,0x00000000L,0x00000000L,0x10040040L,0x10000040L,0x10001000L,0x00041040L,0x00040000L,0x00041040L,0x00040000L,0x10041000L,0x00001000L,0x00000040L,0x10040040L,0x00001000L,0x00041040L,0x10001000L,0x00000040L,0x10000040L,0x10040000L,0x10040040L,0x10000000L,0x00040000L,0x10001040L,0x00000000L,0x10041040L,0x00040040L,0x10000040L,0x10040000L,0x10001000L,0x10001040L,0x00000000L,0x10041040L,0x00041000L,0x00041000L,0x00001040L,0x00001040L,0x00040040L,0x10000000L,0x10041000L};staticvoiddesfunc(block,keys)registerunsignedlong*block,*keys;{registerunsignedlongfval,work,right,leftt;registerintround;leftt=block[0];right=block[1];work=((leftt>>4)^right)&0x0f0f0f0fL;right^=work;leftt^=(work<<4);work=((leftt>>16)^right)&0x0000ffffL;right^=work;leftt^=(work<<16);work=((right>>2)^leftt)&0x33333333L;leftt^=work;right^=(work<<2);work=((right>>8)^leftt)&0x00ff00ffL;leftt^=work;right^=(work<<8);right=((right<<1)|((right>>31)&1L))&0xffffffffL;work=(leftt^right)&0xaaaaaaaaL;leftt^=work;right^=work;leftt=((leftt<<1)|((leftt>>31)&1L))&0xffffffffL;for(round=0;round<8;round++){work=(right<<28)|(right>>4);work^=*keys++;fval=SP7[work&0x3fL];fval|=SP5[(work>>8)&0x3fL];fval|=SP3[(work>>16)&0x3fL];fval|=SP1[(work>>24)&0x3fL];work=right^*keys++;fval|=SP8[work&0x3fL];fval|=SP6[(work>>8)&0x3fL];fval|=SP4[(work>>16)&0x3fL];fval|=SP2[(work>>24)&0x3fL];leftt^=fval;work=(leftt<<28)|(leftt>>4);work^=*keys++;fval=SP7[work&0x3fL];fval|=SP5[(work>>8)&0x3fL];fval|=SP3[(work>>16)&0x3fL];fval|=SP1[(work>>24)&0x3fL];work=leftt^*keys++;fval|=SP8[work&0x3fL];fval|=SP6[(work>>8)&0x3fL];fval|=SP4[(work>>16)&0x3fL];fval|=SP2[(work>>24)&0x3fL];right^=fval;}right=(right<<31)|(right>>1);work=(leftt^right)&0xaaaaaaaaL;leftt^=work;right^=work;leftt=(leftt<<31)|(leftt>>1);work=((leftt>>8)^right)&0x00ff00ffL;right^=work;leftt^=(work<<8);work=((leftt>>2)^right)&0x33333333L;right^=work;leftt^=(work<<2);work=((right>>16)^leftt)&0x0000ffffL;leftt^=work;right^=(work<<16);work=((right>>4)^leftt)&0x0f0f0f0fL;leftt^=work;right^=(work<<4);*block++=right;*block=leftt;return;}/*Validationsets:**Single-lengthkey,single-lengthplaintext-*Key:0123456789abcdef*Plain:0123456789abcde7*Cipher:c95744256a5ed31d**Double-lengthkey,single-lengthplaintext-*Key:0123456789abcdeffedcba9876543210*Plain:0123456789abcde7*Cipher:7f1d0a77826b8aff**Double-lengthkey,double-lengthplaintext-*Key:0123456789abcdeffedcba9876543210*Plain:0123456789abcdef0123456789abcdff*Cipher:27a08440406adf60278f47cf42d615d7**Triple-lengthkey,single-lengthplaintext-*Key:0123456789abcdeffedcba987654321089abcdef01234567*Plain:0123456789abcde7*Cipher:de0b7c06ae5e0ed5**Triple-lengthkey,double-lengthplaintext-*Key:0123456789abcdeffedcba987654321089abcdef01234567*Plain:0123456789abcdef0123456789abcdff*Cipher:ad0d1b30ac17cf070ed11c6381e44de5**d3desV5.0arwo9208.0718:44GravenImagery**********************************************************************/