Шустрый

Профиль
Группа: Участник
Сообщений: 62
Регистрация: 9.5.2006
Репутация: нет Всего: нет
|
приветик всем! вот пытаюсь найти ошибку в DES'e файл компилится, но работает не верно... Помогите пожалуйста найти ошибку. С алгоритмической точки зрения все правильно. | Код | #include "stdafx.h" #include <conio.h> #include <stdio.h> #include "des_lib.h" #include "windows.h"
#define ENCODE 0 // Флаг шифрования #define DECODE 1// Флаг дешифрования
const rounds=16; // Количество раундов шифрования
byte CipherKey[N*N]; // Исходный ключ шифрования
byte shifts [2*N]= {1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1}; // Таблица сдвигов раундовых ключей
void ByteToStr(byte b,byte *buf) // Функция разбиения числа в битовый массив { _asm { mov esi,buf mov ecx,8 // !!! mov al,b next: shl al,1 setc [esi] inc esi loop next }
}
byte StrToByte(byte *buf) // Функция, собирающая битовый массив в число { byte b;
_asm { push esi mov esi,buf mov ecx,8 xor eax,eax cld next: lodsb and al,1 shl ah,1 or ah,al loop next mov b,ah pop esi } }
void ShowAsBits(byte *state) // Показывает обрабатываемый блок в виде массива битов { int i,j,pos=0; for (i=0;i<N;i++) { for (j=0;j<N;j++) { printf("%d",state[pos++]); if((j+1)%N==0) printf(" "); } } }
void ShowAsBytes(byte *state) // Показывает обраьатываемый блок виде массива байтов { int i; for (i=0;i<N;i++) { printf("%.2X ",StrToByte(&state[i*N])); if((i+1)%N==0) printf(" "); } }
void FirstChangeBits(byte *state)// Функция, осуществляющая перестановку по матрице P { int i,j,pos=0; byte buf[N*N]; for (i=0;i<N;i++) { j=first_table[i]-1; while (j>=0) { buf[pos++] = state[j]; j-=8; } }
for (i=0;i<N*N;i++) state[i]=buf[i]; }
void FinalChangeBits(byte *state) // Функция, осуществляющая перестановку по матрице, обратной P { int i,j,pos=0,k; byte buf[N*N];
for (i=0;i<N;i++) { for (j=0;j<N;j++) { k=final_table[i*N+j]-1; buf[pos++]= state[k]; } } for (i=0;i<N*N;i++) state[i]=buf[i]; }
byte **KeyShedule(byte Key[N*N]) // Функция "расширения" ключа, создание раундовых ключей { int i,j,nr=0,pos=0; byte **ExtKey=new byte *[rounds]; // Массив, который буде содержать раундовые ключи for (i=0;i<rounds;i++) ExtKey[i]=new byte [N*6]; // 16 ключей по 48 бит byte buf[N*7]; byte tmp; for (i=0;i<N*7;i++) { buf[i]=Key[b_table[i]-1]; // Выделение из исходного ключа значащих бит и перестановка по B таблице } while (nr<rounds) { for (j=0;j<shifts[nr];j++) { // Сдвиг первой части (С) tmp=buf[0]; for (i=0;i<((N*7)/2)-1;i++) buf[i] = buf[i+1]; buf[i]=tmp; } for (j=0;j<shifts[nr];j++) { // Сдвиг второй части (D) tmp=buf[(N*7)/2]; for (i=(N*7)/2;i<(N*7)-1;i++) buf[i] = buf[i+1]; buf[i]=tmp; } for (i=0;i<N*6;i++) ExtKey[nr][i]=buf[k_table[i]-1]; // Запомнить раундовый ключ nr++; }
return ExtKey; }
byte *RoundFunction(byte *r, byte *RoundKey) // Раундовая функция { int i,j,k,pos=0; byte bcol[N], // Массив для битового представления столбца координат С-таблиц brow[N], // Массив для битового представления строки координат С-таблиц bits[N]; // Массив для битового представления содержимого С-таблицы по указанным координатам byte *buf=new byte [N*6]; // Расширение полублока состояния r из 32 бит в 48 с помощью таблицы Е for (pos=0;pos<N*6;pos++) buf[pos]=r[e_table[pos]-1]; for (i=0;i<N*6;i++) buf[i]^=RoundKey[i]; // Наложение раундового ключа
k=0; // Подстановка на S блоке pos=0; for (i=0;i<N;i++){ // 8 итераций ZeroMemory(&bcol,N); // bcol=0 ZeroMemory(&brow,N); // brow=0
brow[7]=buf[pos+5]; // Первый и последний биты brow[6]=buf[pos+0]; // определяют номер строки
bcol[7]=buf[pos+4]; // остальные bcol[6]=buf[pos+3]; // биты определяют bcol[5]=buf[pos+2]; // позицию ячейки bcol[4]=buf[pos+1]; // в этой строке
pos+=6; // рассмотрение следующих 6ти бит
byte p1=StrToByte(&brow[0]); // Координата строки byte p2=StrToByte(&bcol[0]); // Координата столбца ByteToStr(s_function[i][(p1<<4)+p2],bits); for (j=4;j<N;j++) buf[k++]=bits[j]; } // подстановка на П блоке. byte *buf_final=new byte [N*4]; for (pos=0;pos<N*4;pos++) buf_final[pos]=buf[p_table[pos]-1]; delete buf; return buf_final; }
void CryptBlock(byte *state, byte **ExtKey) // Функция шифрования блока указанными раундовыми ключами { int i=0,j=0,k; byte *l=state, // Указатель на левый полублок L *r=&state[N*N/2], // Указатель на правый полублок R *buf; // Буферный указатель FirstChangeBits(state); // Первая подстановка - замена бит по P таблице for (i=0;i<rounds;i++){ // 16 раундов шифрования buf=RoundFunction(r,ExtKey[i]); // Вычисление раундовой функции for (j=0;j<N*4;j++) buf[j]^=l[j]; // Наложение раундовой функции
for (k=0;k<N*4;k++) l[k]=r[k]; // l=r for (k=0;k<N*4;k++) r[k]=buf[k]; // r=l+func delete buf; } FinalChangeBits(state); // Вторая подстановка - обратная перестановке на P таблице }
void deCryptBlock(byte *state, byte **ExtKey) // Функция дешифрования блока указанными раундовыми ключами { int i=0,j=0,k; byte *r=state, // Указатель на правый полублок R *l=&state[N*N/2], // Указатель на левый полублок L *buf; FirstChangeBits(state); // Первая подстановка - замена бит по P таблице for (i=rounds-1;i>=0;i--){ // 16 раундов шифрования, ключи подаются в обратном порядке buf=RoundFunction(r,ExtKey[i]); // Вычисление раундовой функции for (j=0;j<N*4;j++) buf[j]^=l[j]; // Наложение раундовой функции
for (k=0;k<N*4;k++) l[k]=r[k]; // l=r for (k=0;k<N*4;k++) r[k]=buf[k]; // r=l+func delete buf; } FinalChangeBits(state); // Вторая подстановка - обратная перестановке на P таблице }
void modeECB(char *in_name,char *out_name,byte **ExtKey,byte action) // Чистый DES { int i; FILE *in, *out; byte buf[N], state[N*N]; // Буферные массивы byte wasread; // Количество прочитанных байт
in =fopen(in_name,"rb"); out=fopen(out_name,"wb"); while (1) { ZeroMemory(buf,N); // Зануление массива wasread=fread(buf,1,N,in); // Чтение блока 64 бит if (wasread==0) break; // Если ничего не прочитали - выйти //ShowAsBits(state); //ShowAsBytes(state); for (i=0;i<N;i++) ByteToStr(buf[i],&state[i*N]); // Перевод байтов в битовый массив if (action) deCryptBlock(state,ExtKey); // Дешифрование else CryptBlock(state,ExtKey); // Шифрование for (i=0;i<N;i++) buf[i]=StrToByte(&state[i*N]); // Перевод из битового массива в байты fwrite(buf,N,1,out); // Запись блока } fclose(in); fclose(out); }
void modeCBC(char *in_name,char *out_name,byte **ExtKey,byte action) // Code Block Chaining { int i; FILE *in, *out; byte buf[N], c_buf[N], sc_buf[N], state[N*N]; byte wasread;
ZeroMemory(c_buf,N); in =fopen(in_name,"rb"); out=fopen(out_name,"wb"); while (1) { wasread=fread(buf,N,1,in); if (wasread==0) break; if (action==DECODE) CopyMemory(sc_buf,buf,N); for (i=0;i<N;i++) { if (action==ENCODE) buf[i]^=c_buf[i]; // Если кодирование, то сначала наложить цепочный буфер ByteToStr(buf[i],&state[i*N]); }
if (action==DECODE) deCryptBlock(state,ExtKey); else CryptBlock(state,ExtKey); for (i=0;i<N;i++) { buf[i]=StrToByte(&state[i*N]); if (action==DECODE) buf[i]^=c_buf[i]; // Если декодиование, то снять цепочный буфер после декодирования }
fwrite(buf,N,1,out); if (action==DECODE) CopyMemory(c_buf,sc_buf,N); if (action==ENCODE) CopyMemory(c_buf,buf,N); } fclose(in); fclose(out); }
void modeCFB(char *in_name,char *out_name,byte **ExtKey,byte k,byte action) // Обратная связь по шифру { int i; FILE *in, *out; byte buf[N],state[N*N], shifter[N*N]; byte wasread,rpos=0,cnt=0,ready=1; byte rbuf[N*N],kbuf[N*N];
in =fopen(in_name,"rb"); out=fopen(out_name,"wb"); CopyMemory(shifter,CipherKey,N*N); while (1) { rpos=0; ZeroMemory(buf,N); wasread=fread(buf,1,N,in); if (wasread==0) break; for (i=0;i<N;i++) ByteToStr(buf[i],&rbuf[i*N]); while (rpos<wasread*N) { if (ready) { CopyMemory(state, shifter, N*N); // Shifter -> state CryptBlock(state,ExtKey); // DES ready=0; // Ready to encode } while ((rpos<wasread*N)&&(cnt<k)) { if (action==ENCODE) { rbuf[rpos]^=state[cnt]; kbuf[cnt]=rbuf[rpos];} else { kbuf[cnt]=rbuf[rpos]; rbuf[rpos]^=state[cnt];} cnt++; rpos++; } if (cnt==k) { cnt=0;ready=1; CopyMemory(shifter,&shifter[k],N*N-k); // Shift shifter for (i=0;i<k;i++) shifter[N*N-k+i]=kbuf[i]; } else break; } for (i=0;i<N;i++) buf[i]=StrToByte(&rbuf[i*N]); fwrite(buf,N,1,out); }
fclose(in); fclose(out); }
void modeOFB(char *in_name,char *out_name,byte **ExtKey,byte k) // Обратная связь по шифру { int i; FILE *in, *out; byte buf[N],state[N*N], shifter[N*N]; byte wasread,rpos=0,cnt=0,ready=1; byte rbuf[N*N],kbuf[N*N];
in =fopen(in_name,"rb"); out=fopen(out_name,"wb"); CopyMemory(shifter,CipherKey,N*N); while (1) { rpos=0; ZeroMemory(buf,N); wasread=fread(buf,1,N,in); if (wasread==0) break; for (i=0;i<N;i++) ByteToStr(buf[i],&rbuf[i*N]); while (rpos<wasread*N) { if (ready) { CopyMemory(state, shifter, N*N); // Shifter -> state CryptBlock(state,ExtKey); // DES ready=0; // Ready to encode } while ((rpos<wasread*N)&&(cnt<k)) { kbuf[cnt]=state[cnt]; rbuf[rpos]^=state[cnt]; cnt++; rpos++; } if (cnt==k) { cnt=0;ready=1; CopyMemory(shifter,&shifter[k],N*N-k); // Shift shifter for (i=0;i<k;i++) shifter[N*N-k+i]=kbuf[i]; } else break; } for (i=0;i<N;i++) buf[i]=StrToByte(&rbuf[i*N]); fwrite(buf,N,1,out); }
fclose(in); fclose(out); }
void main() { int i,j; char keyname[80]; char inname[80]; char outname[80]; int action,mode,bits;
/*printf("Input file: "); scanf ("%s",inname); printf("Output file: "); scanf ("%s",outname); */ printf("Key file: "); scanf ("%s",keyname); /*printf("Action: "); scanf ("%d",&action); printf("Mode: "); scanf ("%d",&mode);
if (mode>1) { printf("Block len: "); scanf("%d",&bits); } */ FILE *f = fopen (keyname,"rb"); byte buf[N]; ZeroMemory (buf,N); fread(buf,1,N,f); fclose(f);
for (i=0;i<N;i++) ByteToStr(buf[i],&CipherKey[i*N]);// Заполнение ключа.
for (j=0;j<N*N;j++) {printf ("%d",CipherKey[j]); if((j+1)%N==0) printf(" "); }printf("\n");
ZeroMemory (buf,N); for (i=0;i<N;i++) buf[i]=StrToByte(&CipherKey[i*N]);
for (j=0;j<N;j++) { printf ("%d ",buf[j]); if((j+1)%N==0) printf(" "); }printf("\n");
byte **ExtKey=KeyShedule(CipherKey); // Расширение ключа // for (j=0;j<N*N;j++) printf ("%d",CipherKey[j]); printf("\n"); // Вывод ключа в двоичном виде
/*switch (mode) { case 0: { modeECB(inname,outname,ExtKey,action); break; } case 1: { modeCBC(inname,outname,ExtKey,action); break; } case 2: { modeCFB(inname,outname,ExtKey,13,action); break; } case 3: { modeOFB(inname,outname,ExtKey,13); break; } } */ modeECB("d:\\e.txt","d:\\e.des",ExtKey,ENCODE); // modeECB("d:\\e.des","d:\\a.txt",ExtKey,DECODE);
// modeCBC("d:\\e.txt","d:\\e.des",ExtKey,ENCODE); // modeCBC("d:\\e.des","d:\\a.txt",ExtKey,DECODE);
// modeCFB("d:\\e.txt","d:\\e.des",ExtKey,13,ENCODE); // modeCFB("d:\\e.des","d:\\a.txt",ExtKey,13,DECODE);
// modeOFB("d:\\e.txt","d:\\e.des",ExtKey,13); // modeOFB("d:\\e.des","d:\\a.txt",ExtKey,13); printf("Done."); getch(); }
|
Заранее спасибо!!! P.S.может быть, у кого-ниб есть исходники на С++ DES'а? Вышлите пожалуйста! Это сообщение отредактировал(а) Alexeis - 10.5.2007, 15:12
|