Модераторы: Poseidon
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> [C Builder] алгоритм DES помогите найти ошибку? 
:(
    Опции темы
PrettyGirl
Дата 9.5.2007, 10:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 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
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Центр помощи"

ВНИМАНИЕ! Прежде чем создавать темы, или писать сообщения в данный раздел, ознакомьтесь, пожалуйста, с Правилами форума и конкретно этого раздела.
Несоблюдение правил может повлечь за собой самые строгие меры от закрытия/удаления темы до бана пользователя!


  • Название темы должно отражать её суть! (Не следует добавлять туда слова "помогите", "срочно" и т.п.)
  • При создании темы, первым делом в квадратных скобках укажите область, из которой исходит вопрос (язык, дисциплина, диплом). Пример: [C++].
  • В названии темы не нужно указывать происхождение задачи (например "школьная задача", "задача из учебника" и т.п.), не нужно указывать ее сложность ("простая задача", "легкий вопрос" и т.п.). Все это можно писать в тексте самой задачи.
  • Если Вы ошиблись при вводе названия темы, отправьте письмо любому из модераторов раздела (через личные сообщения или report).
  • Для подсветки кода пользуйтесь тегами [code][/code] (выделяйте код и нажимаете на кнопку "Код"). Не забывайте выбирать при этом соответствующий язык.
  • Помните: один топик - один вопрос!
  • В данном разделе запрещено поднимать темы, т.е. при отсутствии ответов на Ваш вопрос добавлять новые ответы к теме, тем самым поднимая тему на верх списка.
  • Если вы хотите, чтобы вашу проблему решили при помощи определенного алгоритма, то не забудьте описать его!
  • Если вопрос решён, то воспользуйтесь ссылкой "Пометить как решённый", которая находится под кнопками создания темы или специальным флажком при ответе.

Более подробно с правилами данного раздела Вы можете ознакомится в этой теме.

Если Вам помогли и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, Poseidon, Rodman

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Центр помощи | Следующая тема »


 




[ Время генерации скрипта: 0.0428 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.