阅读:1424回复:0
DES的C源程序(2)
〖Encrypt〗
上一篇|下一篇|回文章 分类讨论区 全部讨论区 本讨论区 发信人: blizzard (大炮), 信区: Encrypt 标 题: DES的C源程序(2) 发信站: 武汉白云黄鹤站 (Thu Jan 6 12:37:46 2000), 站内信件 /****************************************************** The Main Body Of This File (DES) is Writen In \"C\" \"C++\" Is Only the Interface Of it *******************************************************/ #include \"encrypt.h\" #define word32 unsigned long #define byte unsigned char /* The size of a scheduled DES key */ #define DES_KEYWORDS 32 #define DES_KEYBYTES (sizeof(word32)*DES_KEYWORDS) static word32 const bigbyte[24] = { 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). */ static byte const pc1[56] = { 56, 48, 40, 32, 24, 16, 8, 0, 57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18, 10, 2, 59, 51, 43, 35, 62, 54, 46, 38, 30, 22, 14, 6, 61, 53, 45, 37, 29, 21, 13, 5, 60, 52, 44, 36, 28, 20, 12, 4, 27, 19, 11, 3 }; static byte const totrot[16] = { 1, 2, 4, 6, 8, 10, 12, 14, 15, 17, 19, 21, 23, 25, 27, 28 }; static byte const pc2[48] = { 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 }; /* * This is a less-that-brilliant key scheduling routine. * It could stand optimization some time. * * cookey \"cooks\" the key into the desired form, from the basic one that * has the keys for S-boxes 1 through 8 in adjacent words of the * \"raw\" array. I.e. the bits start out like this: * xxxxxxxx111111222222333333444444 * xxxxxxxx555555666666777777888888 * We actually want the keys to look like this: * 111111xx333333xx555555xx777777xx * 222222xx444444xx666666xx888888xx * Where the \"xx\" patterns are set to 01020300 for use by the s-box * lookup code in the main encrypt loop. */ static void cookey (word32 *raw, word32 *cooked) { int i; for (i = 0; i < 16; i++, raw += 2, cooked += 2) { cooked[0] = (raw[0] & 0x00fc0000L) << 8; cooked[0] |= (raw[0] & 0x00000fc0L) << 12; cooked[0] |= (raw[1] & 0x00fc0000L) >> 8; cooked[0] |= (raw[1] & 0x00000fc0L) >> 4; cooked[0] |= 0x01020300; cooked[1] = (raw[0] & 0x0003f000L) << 14; cooked[1] |= (raw[0] & 0x0000003fL) << 18; cooked[1] |= (raw[1] & 0x0003f000L) >> 2; cooked[1] |= (raw[1] & 0x0000003fL) << 2; cooked[1] |= 0x01020300; } return; } static void deskey (byte const *key, int decryptf, word32 *outbuf) { int i, j, l, m, n; byte pc1m[56], pcr[56]; word32 kn[32]; for (j = 0; j < 56; j++) { l = pc1[j]; m = l & 07; pc1m[j] = ( key[l >> 3] >> (~l & 7) ) & 1; } for (i = 0; i < 16; i++ ) { m = (decryptf ? 15-i : i) << 1; n = m + 1; kn[m] = kn[n] = 0L; for (j = 0; j < 28; j++) { l = j + totrot; if (l >= 28) l -= 28; pcr[j] = pc1m[l]; } for (j = 28; j < 56; j++) { l = j + totrot; if (l >= 56) l -= 28; pcr[j] = pc1m[l]; } 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, outbuf); return; } /* S-boxes 1, 3, 5, 7, plus P permutation, rotated */ static word32 const SP0[512] = { 0x00404100, 0x00000000, 0x00004000, 0x00404101, 0x00404001, 0x00004101, 0x00000001, 0x00004000, 0x00000100, 0x00404100, 0x00404101, 0x00000100, 0x00400101, 0x00404001, 0x00400000, 0x00000001, 0x00000101, 0x00400100, 0x00400100, 0x00004100, 0x00004100, 0x00404000, 0x00404000, 0x00400101, 0x00004001, 0x00400001, 0x00400001, 0x00004001, 0x00000000, 0x00000101, 0x00004101, 0x00400000, 0x00004000, 0x00404101, 0x00000001, 0x00404000, 0x00404100, 0x00400000, 0x00400000, 0x00000100, 0x00404001, 0x00004000, 0x00004100, 0x00400001, 0x00000100, 0x00000001, 0x00400101, 0x00004101, 0x00404101, 0x00004001, 0x00404000, 0x00400101, 0x00400001, 0x00000101, 0x00004101, 0x00404100, 0x00000101, 0x00400100, 0x00400100, 0x00000000, 0x00004001, 0x00004100, 0x00000000, 0x00404001, 0x00000082, 0x02008080, 0x00000000, 0x02008002, 0x02000080, 0x00000000, 0x00008082, 0x02000080, 0x00008002, 0x02000002, 0x02000002, 0x00008000, 0x02008082, 0x00008002, 0x02008000, 0x00000082, 0x02000000, 0x00000002, 0x02008080, 0x00000080, 0x00008080, 0x02008000, 0x02008002, 0x00008082, 0x02000082, 0x00008080, 0x00008000, 0x02000082, 0x00000002, 0x02008082, 0x00000080, 0x02000000, 0x02008080, 0x02000000, 0x00008002, 0x00000082, 0x00008000, 0x02008080, 0x02000080, 0x00000000, 0x00000080, 0x00008002, 0x02008082, 0x02000080, 0x02000002, 0x00000080, 0x00000000, 0x02008002, 0x02000082, 0x00008000, 0x02000000, 0x02008082, 0x00000002, 0x00008082, 0x00008080, 0x02000002, 0x02008000, 0x02000082, 0x00000082, 0x02008000, 0x00008082, 0x00000002, 0x02008002, 0x00008080, 0x00000040, 0x00820040, 0x00820000, 0x10800040, 0x00020000, 0x00000040, 0x10000000, 0x00820000, 0x10020040, 0x00020000, 0x00800040, 0x10020040, 0x10800040, 0x10820000, 0x00020040, 0x10000000, 0x00800000, 0x10020000, 0x10020000, 0x00000000, 0x10000040, 0x10820040, 0x10820040, 0x00800040, 0x10820000, 0x10000040, 0x00000000, 0x10800000, 0x00820040, 0x00800000, 0x10800000, 0x00020040, 0x00020000, 0x10800040, 0x00000040, 0x00800000, 0x10000000, 0x00820000, 0x10800040, 0x10020040, 0x00800040, 0x10000000, 0x10820000, 0x00820040, 0x10020040, 0x00000040, 0x00800000, 0x10820000, 0x10820040, 0x00020040, 0x10800000, 0x10820040, 0x00820000, 0x00000000, 0x10020000, 0x10800000, 0x00020040, 0x00800040, 0x10000040, 0x00020000, 0x00000000, 0x10020000, 0x00820040, 0x10000040, 0x00080000, 0x81080000, 0x81000200, 0x00000000, 0x00000200, 0x81000200, 0x80080200, 0x01080200, 0x81080200, 0x00080000, 0x00000000, 0x81000000, 0x80000000, 0x01000000, 0x81080000, 0x80000200, 0x01000200, 0x80080200, 0x80080000, 0x01000200, 0x81000000, 0x01080000, 0x01080200, 0x80080000, 0x01080000, 0x00000200, 0x80000200, 0x81080200, 0x00080200, 0x80000000, 0x01000000, 0x00080200, 0x01000000, 0x00080200, 0x00080000, 0x81000200, 0x81000200, 0x81080000, 0x81080000, 0x80000000, 0x80080000, 0x01000000, 0x01000200, 0x00080000, 0x01080200, 0x80000200, 0x80080200, 0x01080200, 0x80000200, 0x81000000, 0x81080200, 0x01080000, 0x00080200, 0x00000000, 0x80000000, 0x81080200, 0x00000000, 0x80080200, 0x01080000, 0x00000200, 0x81000000, 0x01000200, 0x00000200, 0x80080000 }; /* S-boxes 2, 4, 6, 8, plus P permutation, rotated */ static word32 const SP1[512] = { 0x20042008, 0x20002000, 0x00002000, 0x00042008, 0x00040000, 0x00000008, 0x20040008, 0x20002008, 0x20000008, 0x20042008, 0x20042000, 0x20000000, 0x20002000, 0x00040000, 0x00000008, 0x20040008, 0x00042000, 0x00040008, 0x20002008, 0x00000000, 0x20000000, 0x00002000, 0x00042008, 0x20040000, 0x00040008, 0x20000008, 0x00000000, 0x00042000, 0x00002008, 0x20042000, 0x20040000, 0x00002008, 0x00000000, 0x00042008, 0x20040008, 0x00040000, 0x20002008, 0x20040000, 0x20042000, 0x00002000, 0x20040000, 0x20002000, 0x00000008, 0x20042008, 0x00042008, 0x00000008, 0x00002000, 0x20000000, 0x00002008, 0x20042000, 0x00040000, 0x20000008, 0x00040008, 0x20002008, 0x20000008, 0x00040008, 0x00042000, 0x00000000, 0x20002000, 0x00002008, 0x20000000, 0x20040008, 0x20042008, 0x00042000, 0x40200800, 0x40000820, 0x40000820, 0x00000020, 0x00200820, 0x40200020, 0x40200000, 0x40000800, 0x00000000, 0x00200800, 0x00200800, 0x40200820, 0x40000020, 0x00000000, 0x00200020, 0x40200000, 0x40000000, 0x00000800, 0x00200000, 0x40200800, 0x00000020, 0x00200000, 0x40000800, 0x00000820, 0x40200020, 0x40000000, 0x00000820, 0x00200020, 0x00000800, 0x00200820, 0x40200820, 0x40000020, 0x00200020, 0x40200000, 0x00200800, 0x40200820, 0x40000020, 0x00000000, 0x00000000, 0x00200800, 0x00000820, 0x00200020, 0x40200020, 0x40000000, 0x40200800, 0x40000820, 0x40000820, 0x00000020, 0x40200820, 0x40000020, 0x40000000, 0x00000800, 0x40200000, 0x40000800, 0x00200820, 0x40200020, 0x40000800, 0x00000820, 0x00200000, 0x40200800, 0x00000020, 0x00200000, 0x00000800, 0x00200820, 0x08000004, 0x08100000, 0x00001000, 0x08101004, 0x08100000, 0x00000004, 0x08101004, 0x00100000, 0x08001000, 0x00101004, 0x00100000, 0x08000004, 0x00100004, 0x08001000, 0x08000000, 0x00001004, 0x00000000, 0x00100004, 0x08001004, 0x00001000, 0x00101000, 0x08001004, 0x00000004, 0x08100004, 0x08100004, 0x00000000, 0x00101004, 0x08101000, 0x00001004, 0x00101000, 0x08101000, 0x08000000, 0x08001000, 0x00000004, 0x08100004, 0x00101000, 0x08101004, 0x00100000, 0x00001004, 0x08000004, 0x00100000, 0x08001000, 0x08000000, 0x00001004, 0x08000004, 0x08101004, 0x00101000, 0x08100000, 0x00101004, 0x08101000, 0x00000000, 0x08100004, 0x00000004, 0x00001000, 0x08100000, 0x00101004, 0x00001000, 0x00100004, 0x08001004, 0x00000000, 0x08101000, 0x08000000, 0x00100004, 0x08001004, 0x04000410, 0x00000400, 0x00010000, 0x04010410, 0x04000000, 0x04000410, 0x00000010, 0x04000000, 0x00010010, 0x04010000, 0x04010410, 0x00010400, 0x04010400, 0x00010410, 0x00000400, 0x00000010, 0x04010000, 0x04000010, 0x04000400, 0x00000410, 0x00010400, 0x00010010, 0x04010010, 0x04010400, 0x00000410, 0x00000000, 0x00000000, 0x04010010, 0x04000010, 0x04000400, 0x00010410, 0x00010000, 0x00010410, 0x00010000, 0x04010400, 0x00000400, 0x00000010, 0x04010010, 0x00000400, 0x00010410, 0x04000400, 0x00000010, 0x04000010, 0x04010000, 0x04010010, 0x04000000, 0x00010000, 0x04000410, 0x00000000, 0x04010410, 0x00010010, 0x04000010, 0x04010000, 0x04000400, 0x04000410, 0x00000000, 0x04010410, 0x00010400, 0x00010400, 0x00000410, 0x00000410, 0x00010010, 0x04000000, 0x04010400 }; /* * This encryption function is fairly clever in the way it does its * s-box lookup. The S-boxes are indexed by bytes, rather than * words, because that\'s faster on many machines, and shifting * everything two bits to do the multiply by 4 is trivial. * Then, the indexing into the various S boxes is done by * adding the appropriate offset bits into the key array, so the * addition is done by the XOR with the key rather than having to * be done explicitly here. */ static void desDES (byte const inblock[8], byte outblock[8], word32 const *keys) { word32 s, t, right, leftt; int round; leftt = ((word32)inblock[0] << 24) | ((word32)inblock[1] << 16) | ((word32)inblock[2] << 8) | (word32)inblock[3]; right = ((word32)inblock[4] << 24) | ((word32)inblock[5] << 16) | ((word32)inblock[6] << 8) | (word32)inblock[7]; /* Initial permutation IP */ t = ((leftt >> 4) ^ right) & 0x0f0f0f0fL; right ^= t; leftt ^= (t << 4); t = ((leftt >> 16) ^ right) & 0x0000ffffL; right ^= t; leftt ^= (t << 16); t = ((right >> 2) ^ leftt) & 0x33333333L; leftt ^= t; right ^= (t << 2); t = ((right >> 8) ^ leftt) & 0x00ff00ffL; leftt ^= t; right ^= (t << 8); leftt = ((leftt >> 1) | (leftt << 31)); t = (leftt ^ right) & 0x55555555L; leftt ^= t; right ^= t; right = ((right >> 1) | (right << 31)); for (round = 0; round < 8; round++) { s = (right & 0xfcfcfcfc) ^ keys[0]; t = (((right >> 28) | (right << 4)) & 0xfcfcfcfc) ^ keys[1]; leftt ^= *(word32 *)((char *)SP0+( s & 0x3fc)) ^ *(word32 *)((char *)SP0+((s >> 8 ) & 0x3fc)) ^ *(word32 *)((char *)SP0+((s >> 16) & 0x3fc)) ^ *(word32 *)((char *)SP0+((s >> 24) & 0x0fc)) ^ *(word32 *)((char *)SP1+( t & 0x3fc)) ^ *(word32 *)((char *)SP1+((t >> 8 ) & 0x3fc)) ^ *(word32 *)((char *)SP1+((t >> 16) & 0x3fc)) ^ *(word32 *)((char *)SP1+((t >> 24) & 0x0fc)); s = (leftt & 0xfcfcfcfc) ^ keys[2]; t = (((leftt >> 28) | (leftt << 4)) & 0xfcfcfcfc) ^ keys[3]; right ^= *(word32 *)((char *)SP0+( s & 0x3fc)) ^ *(word32 *)((char *)SP0+((s >> 8 ) & 0x3fc)) ^ *(word32 *)((char *)SP0+((s >> 16) & 0x3fc)) ^ *(word32 *)((char *)SP0+((s >> 24) & 0x0fc)) ^ *(word32 *)((char *)SP1+( t & 0x3fc)) ^ *(word32 *)((char *)SP1+((t >> 8 ) & 0x3fc)) ^ *(word32 *)((char *)SP1+((t >> 16) & 0x3fc)) ^ *(word32 *)((char *)SP1+((t >> 24) & 0x0fc)); keys += 4; }; /* Inverse IP */ leftt = ((leftt << 1) | (leftt >> 31)); t = (leftt ^ right) & 0x55555555L; leftt ^= t; right ^= t; right = ((right << 1) | (right >> 31)); t = ((leftt >> 8) ^ right) & 0x00ff00ffL; right ^= t; leftt ^= (t << 8); t = ((leftt >> 2) ^ right) & 0x33333333L; right ^= t; leftt ^= (t << 2); t = ((right >> 16) ^ leftt) & 0x0000ffffL; leftt ^= t; right ^= (t << 16); t = ((right >> 4) ^ leftt) & 0x0f0f0f0fL; leftt ^= t; right ^= (t << 4); outblock[0] = (byte)(right >> 24); outblock[1] = (byte)(right >> 16); outblock[2] = (byte)(right >> 8); outblock[3] = (byte)(right ); outblock[4] = (byte)(leftt >> 24); outblock[5] = (byte)(leftt >> 16); outblock[6] = (byte)(leftt >> 8); outblock[7] = (byte)(leftt ); return; }; #undef word32 #undef byte /****************************************************** The Below Code (Package Coder) is Writen In \"C++\" *******************************************************/ void CPackage_Encoder::SetKey(const char* password){ unsigned i=0; SBitBlock key; key.dword.low=0x476226E8; key.dword.high=0x87F5F4AD; while(password){ key.byte[i%8]^=(password+(i>>3)+37); i++; }; theDEScoder.SetKey(key); SetSeed(0x31A68E0D,0x6508CB93); }; int CPackage_Encoder::Encrypt(unsigned char destination[],const unsigned cha r source[], unsigned sourcesize)const{ unsigned i,j; SBitBlock a,b; theDEScoder.Encrypt(a,seed); for(i=0;i<8;i++)destination=a.byte; a.dword.low=seed.dword.low; a.dword.high=seed.dword.high; for(i=0,j=8;i<sourcesize;i++,j++){ if((i%8)==0){ a.dword.low+=23; a.dword.high-=71; theDEScoder.Encrypt(b,a); }; destination[j]=source^b.byte[i%8]; }; return 0; }; int CPackage_Encoder::Decrypt(unsigned char destination[],const unsigned cha r source[], unsigned sourcesize){ unsigned i,j; SBitBlock a,b; if(sourcesize<8)return -201; //Too Small Package for(i=0;i<8;i++)a.byte=source; theDEScoder.Decrypt(seed,a); a.dword.low=seed.dword.low; a.dword.high=seed.dword.high; for(i=0,j=8;j<sourcesize;i++,j++){ if((i%8)==0){ a.dword.low+=23; a.dword.high-=71; theDEScoder.Encrypt(b,a); }; destination=source[j]^b.byte[i%8]; }; return 0; }; // Below contains no useful code, only for test // So Remark them when used in project /*****************************************************************/ #include <stdio.h> #include <stdlib.h> #include <iostream.h> #include <conio.h> #include <time.h> const long T=1000; const long N=2000; unsigned char a[N][T],b[N][T],c[T]; unsigned long s1[N],s2[N],s3[N],s4[N]; main(){ CDES_Encoder des; SBitBlock x,y,z,k; k.dword.low=0x01234567; k.dword.high=0x89ABCDEF; x.dword.low=0x4E6F7720; x.dword.high=0x69732074; for(int l=0;l<8;l++){ y.byte[l]=x.byte[7-l]; z.byte[l]=k.byte[7-l]; }; for(l=0;l<8;l++){ x.byte[l]=y.byte[l]; k.byte[l]=z.byte[l]; }; des.SetKey(k); des.Encrypt(y,x); des.Decrypt(z,y); printf(\"%lX%lX,%lX%lX\",y.dword.low,y.dword.high,z.dword.low,z.dword.high); const char k1[256]=\"dsa3425Hello\"; const char k2[256]=\"dsa3425Hello\"; CPackage_Encoder coder1,coder2; unsigned long i,j; unsigned long starttime,endtime; srand(time(NULL)); for(j=0;j<N;j++) for(i=0;i<T-8;i++) a[j]=rand(); for(j=0;j<N;j++){ s1[j]=rand(); s2[j]=rand(); }; coder1.SetKey(k1); coder2.SetKey(k2); cout<<\"Starting...\"; starttime=time(NULL); for(j=0;j<N;j++){ coder1.SetSeed(s1[j],s2[j]); coder1.Encrypt(c,a[j],T-8); coder2.Decrypt(b[j],c,T); coder2.GetSeed(s3[j],s4[j]); }; endtime=time(NULL); cout<<\"\\nFinished.Using \"<<(endtime-starttime)<<\" seconds.\\n\"; for(j=0;j<N;j++){ if(s1[j]!=s3[j])goto Error; if(s2[j]!=s4[j])goto Error; for(i=0;i<T-8;i++){ if(a[j]==b[j])continue; else goto Finish; }; }; cout<<\"Success\"; goto Finish; Error: cout<<\"Fail\"; Finish: cout<<\"\\nPress any key to finish...\"; getch(); return 0; }; /*****************************************************************/ -- I\'m Sailing; I\'m Flying Through The Dark Night; Far Away I\'m Dying; Forever Crying To Be With You; To Be Free! ※ 来源:.武汉白云黄鹤站 bbs.whnet.edu.cn.[FROM: 203.95.7.153] 上一篇|下一篇|回文章 分类讨论区 全部讨论区 本讨论区 Copyright(c)2000 白云黄鹤BBS站 All Rights Reserved. |
|
|