荔园在线
荔园之美,在春之萌芽,在夏之绽放,在秋之收获,在冬之沉淀
[回到开始]
[上一篇][下一篇]
发信人: Lg (创造人生的传奇), 信区: Linux
标 题: DES算法的C源程序(2)(fwd)
发信站: BBS 荔园晨风站 (Fri Jan 21 22:33:42 2000), 站内信件
【 以下文字转载自 Hacker 讨论区 】
【 原文由 bstone 所发表 】
发信人: blizzard (大炮), 信区: Encrypt
标 题: DES算法的C源程序(2)(fwd)
发信站: 武汉白云黄鹤站 (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, ,
0x80000L, 0x40000L, 0x20000L, ,
0x8000L, 0x4000L, 0x2000L, ,
0x800L, 0x400L, 0x200L, ,
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
* 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[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;
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;
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,
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,
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,
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,
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,
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,
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];
| (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));
right = ((right >> 1) | (right << 31));
for (round = 0; round < 8; round++) {
s = (right & 0xfcfcfcfc) ^ keys[0];
t = (((right >> 28) | (right << 4)) & 0xfcfcfcf)
^ 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 >> 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);
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[i]){
key.byte[i%8]^=(password[i]+(i>>3)+37);
key.byte[i%8]^=(password[i]+(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[i]=a.byte[i];
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[i]^b.byte[i%8];
};
return 0;
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[i]=source[i];
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[i]=source[j]^b.byte[i%8];
};
return 0;
};
// Below contains no useful code, only for test
// So Remark them when used in project
// 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.hig)
;
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][i]=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][i]==b[j][i])continue;
else goto Finish;
};
};
cout<<"Success";
goto Finish;
if(a[j][i]==b[j][i])continue;
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]
--
☆ 来源:.BBS 荔园晨风站 bbs.szu.edu.cn.[FROM: bbs@192.168.28.28]
--
※ 转载:·BBS 荔园晨风站 bbs.szu.edu.cn·[FROM: 210.39.3.97]
[回到开始]
[上一篇][下一篇]
荔园在线首页 友情链接:深圳大学 深大招生 荔园晨风BBS S-Term软件 网络书店