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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> [C++] Реализация алгоритма, Алгоритм шифрования RC5 
V
    Опции темы
Демидрол
Дата 6.11.2008, 14:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 73
Регистрация: 7.6.2008
Где: СПб

Репутация: нет
Всего: нет



Доброе время суток,уважаемые программисты.У меня возникли сложности с реализацией алгоритма шифрования rc5 и поэтому я хочу попросить Вас помочь мне решить сию проблему. smile 
Алгоритм по заданию выглядит следующим образом:
1.Установить счетчик и число раундов шифрования R и выполнить преобразование:
                             A:=(A+Q0) mod 2b;
                             B:=(B+Q1) mod 2b;
2.Преобразовать:
                             A:={[(A (сумма по модулю 2) B)<<<B]+Q2i} mod 2b;
                             B:={[(B (сумма по модулю 2) A)<<<A]+Q2i+1} mod 2b;
3.Если i != R, то прирастить i=i+1 и перейти к шагу 2.
4.Стоп.
5.Преобразованное значение подблоков  A и В.
В приведенном алгоритме b - это длина подблоков в битах, R - число раундов шифрования, (сумма по модулю 2) - сложение по модулю 2, <<< - циклический сдвиг влево на количество бит, указанное справа, Qi - значение b - битного подключа. Типичной является модификация алгоритма с параметрами b=32, R=12, К=128 бит, где К - это значение секретного ключа из которого формируются подключи Qi.
Дешифрование выполняется в обратной последовательности и вместо сложения по модулю 2b используется вычитание, а вместо циклического сдвига влево - циклический сдвиг вправо.

То есть, приходят данные, например char *Text. Далее мы разбиваем эти данные на подблоки по 32 бита, приходит char *Key, размером 128 бит и разбивается на подключи.

Нужно написать функции char* Kodirovanie (char *Text, char *Key) и char* DeKodirovanie (char *Text, char *Key), которые бы возвращали зашифрованный и дешифрованный текст соответственно.

Заранее благодарю всех,кто решит мне помочь.

В сети нашел вот такой  код:
Код

/* RC5REF.C -- Reference implementation of RC5-32/12/16 in C.        */

/* Copyright (C) 1995 RSA Data Security, Inc.                        */

#include <stdio.h>

#include <time.h>

typedef unsigned long int WORD; /* Should be 32-bit = 4 bytes        */

#define w        32             /* word size in bits                 */

#define r        12             /* number of rounds                  */  

#define b        16             /* number of bytes in key            */

#define c         4             /* number  words in key = ceil(8*b/w)*/

#define t        26             /* size of table S = 2*(r+1) words   */

WORD S[t];                      /* expanded key table                */

WORD P = 0xb7e15163, Q = 0x9e3779b9;  /* magic constants             */

/* Rotation operators. x must be unsigned, to get logical right shift*/

#define ROTL(x,y) (((x)<<(y&(w-1))) | ((x)>>(w-(y&(w-1)))))

#define ROTR(x,y) (((x)>>(y&(w-1))) | ((x)<<(w-(y&(w-1)))))



void RC5_ENCRYPT(WORD *pt, WORD *ct) /* 2 WORD input pt/output ct    */

{ WORD i, A=pt[0]+S[0], B=pt[1]+S[1];

  for (i=1; i<=r; i++) 

    { A = ROTL(A^B,B)+S[2*i]; 

      B = ROTL(B^A,A)+S[2*i+1]; 

    }

  ct[0] = A; ct[1] = B;  

} 



void RC5_DECRYPT(WORD *ct, WORD *pt) /* 2 WORD input ct/output pt    */

{ WORD i, B=ct[1], A=ct[0];

  for (i=r; i>0; i--) 

    { B = ROTR(B-S[2*i+1],A)^A; 

      A = ROTR(A-S[2*i],B)^B; 

    }

  pt[1] = B-S[1]; pt[0] = A-S[0];  

} 



void RC5_SETUP(unsigned char *K) /* secret input key K[0...b-1]      */

{  WORD i, j, k, u=w/8, A, B, L[c]; 

   /* Initialize L, then S, then mix key into S */

   for (i=b-1,L[c-1]=0; i!=-1; i--) L[i/u] = (L[i/u]<<8)+K[i];

   for (S[0]=P,i=1; i<t; i++) S[i] = S[i-1]+Q;

   for (A=B=i=j=k=0; k<3*t; k++,i=(i+1)%t,j=(j+1)%c)   /* 3*t > 3*c */

     { A = S[i] = ROTL(S[i]+(A+B),3);  

       B = L[j] = ROTL(L[j]+(A+B),(A+B)); 

     } 

} 



void main()

{ WORD i, j, pt1[2], pt2[2], ct[2] = {0,0};

  unsigned char key[b];

  time_t t0, t1;

  if (sizeof(WORD)!=4) 

    printf("RC5 error: WORD has %d bytes.\n",sizeof(WORD));

  printf("RC5-32/12/16 examples:\n");

  for (i=1;i<6;i++)

    { /* Initialize pt1 and key pseudorandomly based on previous ct */

      pt1[0]=ct[0]; pt1[1]=ct[1]; 

      for (j=0;j<b;j++) key[j] = ct[0]%(255-j);

      /* Setup, encrypt, and decrypt */

      RC5_SETUP(key);  

      RC5_ENCRYPT(pt1,ct);  

      RC5_DECRYPT(ct,pt2);

      /* Print out results, checking for decryption failure */

      printf("\n%d. key = ",i); 

      for (j=0; j<b; j++) printf("%.2X ",key[j]);

      printf("\n   plaintext %.8lX %.8lX  --->  ciphertext %.8lX %.8lX  \n",

             pt1[0], pt1[1], ct[0], ct[1]);

      if (pt1[0]!=pt2[0] || pt1[1]!=pt2[1]) 

        printf("Decryption Error!");

    }

  time (&t0);

  for (i=1;i<100000;i++)

    RC5_ENCRYPT(ct,ct);

  time (&t1);

  printf ("\n   Time_t for 100000 blocks:  %ld \n", t1-t0);

}



вот только не пойму,как приспособить это под свои нужды.
Как нужно в этом коде подправить что-нить,чтобы я вводил текст, ключ и передавал их в функции в виде char *Text и char *Key, для декодирования аналогично. Помогите,пожалуйста разобраться!!! smile 

мммм...просто лес рук желающих помочь...Пожалуйста,завтра уже наступит скоро и сдавать надо че-нить,а я не очень понимаю как все сделать...Помогите,пожалуйста,очень  надо!

Это сообщение отредактировал(а) Демидрол - 9.11.2008, 17:54
PM MAIL   Вверх
Демидрол
Дата 12.11.2008, 18:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 73
Регистрация: 7.6.2008
Где: СПб

Репутация: нет
Всего: нет



Вот,нашел почти то, что нужно, только я на Билдере пишу и он не знает типа CString
Горю!!!Плз, помогите перевести на доступный Билдеру язык:
Код

//Выровнять строку пробелами до кратной длины
void AlignString(CString& str, int len)
{
    //Повторять до тех пор, пока длина строки делится на len с остатком
    while(str.GetLength() % len)
        str.AppendChar(' '); //Добавить пробел в конец строки
}

////////////////////////////////////////////////////////////////////////////////
//Циклический сдвиг 32-битного значения на 1 бит влево
DWORD RotateLeft(DWORD value)
{
    if(value & 0x80000000) //Проверка значения старшего бита
        //Если старший бит = 1, то сдвигаем значение и прибавляем 1
        //(Единица из старшего разряда переносится в младший разряд)
        return (value << 1) + 1;
    //Иначе просто выполняем сдвиг влево на 1 бит
    //Младший бит будет равен 0
    return (value << 1);
}
//Циклический свдиг 32-битного значения на несколько бит влево
DWORD RotateLeft(DWORD value, DWORD nBits)
{
    //В цикле сдвигаем необходимое количество раз
    for(nBits %= 32; nBits != 0; nBits--)
        value = RotateLeft(value);
    return value;
}
//Циклический сдвиг 32-битного значения на 1 бит вправо
DWORD RotateRight(DWORD value)
{
    if(value & 1) //Проверка значения младшего бита
        //Если младший бит = 1, то сдвигаем значение и прибавляем 1 к старшему разряду
        //(Единица из младшего разряда переносится в старший разряд)
        return (value >> 1) + 0x80000000;
    //Иначе просто выполняем сдвиг вправо на 1 бит
    //Старший бит будет равен 0
    return (value >> 1);
}
//Циклический свдиг 32-битного значения на несколько бит вправо
DWORD RotateRight(DWORD value, DWORD nBits)
{
    //В цикле сдвигаем необходимое количество раз
    for(nBits %= 32; nBits != 0; nBits--)
        value = RotateRight(value);
    return value;
}
////////////////////////////////////////////////////////////////////////////////
// Шифрование по алгоритму RC5
void RC5Crypt(PBYTE pX, int len, PBYTE pKey, int keyLen, PBYTE pY)
{
    DWORD A, B, Q0, Q1;
    //Цикл по всему открытому тексту
    for(int i = 0; i < len; i += 8)
    {
        //Шифрование очередного блока
        //A и B - подблоки открытого текста длиной 32 бита
        A = *(DWORD*)&pX[i];
        B = *(DWORD*)&pX[i + 4];
        //Находим нулевой и первый подключи
        Q0 = *(DWORD*)&pKey[0];
        Q1 = *(DWORD*)&pKey[1];
        //Прибавляем
        A = A + Q0;
        B = B + Q1;
//выделяются подключи по 2 штуки в каждой итерации и с ними делается шифрующая хрень
        for(int j = 1; j < 6; j++)
        {
            //Находим подключи
            Q0 = *(DWORD*)&pKey[j * 2];
            Q1 = *(DWORD*)&pKey[j * 2 + 1];
            //Выполняем шифрование
            A = RotateLeft(A ^ B, B) + Q0;
            B = RotateLeft(B ^ A, A) + Q1;
        }
        //Сохраняем зашифрованные подблоки
        *(DWORD*)&pY[i] = A;
        *(DWORD*)&pY[i + 4] = B;
    }
}
void RC5Crypt(CString& x, CString& key, PBYTE pY)
{
    //Если длина ключа равна 0, то не шифруем ничего
    if(key.GetLength() == 0)
        return;
    //Дополняем ключ пробелами до длины 16 байт
    AlignString(key, 16);
    //Длина строки должна быть кратна 8
    AlignString(x, 8); //Добавляем пробелы при необходимости
    //Вызов функции шифрования
    RC5Crypt((PBYTE)x.GetBuffer(), x.GetLength(), (PBYTE)key.GetBuffer(),
        key.GetLength(), pY);
}
////////////////////////////////////////////////////////////////////////////////
//Расшифрование по алгоритму RC5
//расшифрование выполняется точно таким же образом, только все действия в обратном порядке
void RC5Decrypt(PBYTE pX, int len, PBYTE pKey, int keyLen, PBYTE pY)
{
    DWORD A, B, Q0, Q1;
    //Цикл по криптограмме
    for(int i = 0; i < len; i += 8)
    {
        //Расшифрование очередного блока
        //A и B - подблоки криптограммы
        A = *(DWORD*)&pX[i];
        B = *(DWORD*)&pX[i + 4];
        for(int j = 5; j >= 1; j--)
        {
            //Находим подключи
            Q1 = *(DWORD*)&pKey[j * 2 + 1];
            Q0 = *(DWORD*)&pKey[j * 2];
            //Выполняем расшифрование
            B = RotateRight(B - Q1, A) ^ A;
            A = RotateRight(A - Q0, B) ^ B;
        }
        //Находим подключи
        Q1 = *(DWORD*)&pKey[1];
        Q0 = *(DWORD*)&pKey[0];
        //Вычитаем
        A = A - Q0;
        B = B - Q1;
        //Сохраняем расшифрованные подблоки
        *(DWORD*)&pY[i] = A;
        *(DWORD*)&pY[i + 4] = B;
    }
}
void RC5Decrypt(CString& x, CString& key, PBYTE pY)
{
    //Если длина ключа равна 0, то ничего не делаем
    if(key.GetLength() == 0)
        return;
    //Дополняем ключ пробелами до длины 16 байт
    AlignString(key, 16);
    //Длина строки должна быть кратна 8
    AlignString(x, 8);
    //Вызов функции расшифрования
    RC5Decrypt((PBYTE)x.GetBuffer(), x.GetLength(), (PBYTE)key.GetBuffer(),
        key.GetLength(), pY);
}

 
Очень-очень надо,только не знаю как.Помогите,пожалуйста!!!!!
PM MAIL   Вверх
mr.Anderson
Дата 12.11.2008, 20:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


iOS Lead Developer
****


Профиль
Группа: Участник Клуба
Сообщений: 3374
Регистрация: 20.12.2004
Где: далеко

Репутация: 16
Всего: 128



Демидрол, насколько мне помнится, CString - это класс строк в Visual C++, в билдере свой класс - AnsiString. Но там, соответственно, и функции не такие. Придется малость подработать код, но факт есть факт - CString везде заменяй на AnsiString. Это как минимум.


--------------------
user posted image

user posted image
PM MAIL ICQ Skype   Вверх
mrbrooks
Дата 13.11.2008, 09:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


трололомен
****


Профиль
Группа: Завсегдатай
Сообщений: 4259
Регистрация: 4.10.2006
Где: Дол Гулдур

Репутация: 16
Всего: 306



Демидрол, на самом деле к Борману (шестой версии) можно подцепить классы MFC. Кто не верит - смотрим Example  smile 
Ходя действительно вполне можно заменить строковые типы с CString на AnsiString. Проблем быть не должно
PM MAIL   Вверх
Демидрол
Дата 13.11.2008, 13:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 73
Регистрация: 7.6.2008
Где: СПб

Репутация: нет
Всего: нет



Проблемы есть с функцияей GetBuffer().
как можно её заменить?
Нашел про неё немного информации, но как заменить её ума не приложу... 

Это сообщение отредактировал(а) Демидрол - 13.11.2008, 19:28
PM MAIL   Вверх
Демидрол
Дата 14.11.2008, 17:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 73
Регистрация: 7.6.2008
Где: СПб

Репутация: нет
Всего: нет



Ну, справился я с этой проблемой, заменив GetBuffer() на c_str(). Не знаю, правильно ли это с точки зрения теории, но радует то, что работает так, как должно работать.
Все, тему закрываю, спасибо всем, кто принял в её обсуждении участие, напоследок хочется спросить  не в тему, но я вот озадачился:
Допустим, я пишу:
Код

int i = 10;
char* Array = new char[i];

А как место высвобождать в конце?
Так:
Код

delete [] Array;

или так:
Код

delete Array;

Я поймал себя на мысли, что туплю и вопрос глупый, но как надо на самом деле делать?
PM MAIL   Вверх
mr.Anderson
Дата 14.11.2008, 20:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


iOS Lead Developer
****


Профиль
Группа: Участник Клуба
Сообщений: 3374
Регистрация: 20.12.2004
Где: далеко

Репутация: 16
Всего: 128



Первое, delete [] Array. В случае со скобками освободится вся область памяти, занятая массивом, а если написать без скобок, то освободится только память, занятая первым элементом массива, остальные останутся лежать, как лежали.


--------------------
user posted image

user posted image
PM MAIL ICQ Skype   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Центр помощи"

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


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

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

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

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


 




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


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

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