Добавил:
korayakov
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:
//
// Copyright (C) 1995, by Stanislav Asanov
// FIDOnet: 2:5030/53.30
// Internet: acm@opensys.spb.su
//
#include "Gost.h"
//=================================================================================
/*
Параметры: data - массив из 8 байтов.
key - массив из 8 double(ов).
*/
void Encrypt (byte* data, DWORD* dwKey) {
int indexes[] = {0,1,2,3,4,5,6,7,0,1,2,3,4,5,6,7,0,1,2,3,4,5,6,7,7,6,5,4,3,2,1,0};
DWORD X [32];
byte H[8][16] = {
{0x2, 0xE, 0x9, 0x5, 0x7, 0x6, 0x4, 0xA, 0x0, 0xB, 0x8, 0xD, 0x3, 0x1, 0xF, 0xC },
{0xA, 0xB, 0xE, 0x3, 0x4, 0xD, 0x7, 0x1, 0x6, 0x5, 0x2, 0x8, 0x0, 0xF, 0x9, 0xC },
{0x3, 0xA, 0x2, 0xC, 0x8, 0xE, 0xF, 0x4, 0x5, 0x6, 0xD, 0x0, 0x9, 0xB, 0x1, 0x7 },
{0xB, 0xE, 0xC, 0x4, 0x7, 0x6, 0xF, 0x9, 0x3, 0x8, 0x5, 0xD, 0x2, 0x1, 0x0, 0xA },
{0xC, 0xF, 0xA, 0x8, 0x2, 0x9, 0x7, 0x6, 0x3, 0x4, 0xE, 0x5, 0x1, 0xB, 0xD, 0x0 },
{0x8, 0x6, 0x2, 0x5, 0x3, 0xA, 0x4, 0x7, 0xD, 0x1, 0x9, 0xB, 0xC, 0xE, 0x0, 0xF },
{0x3, 0xF, 0xA, 0xE, 0x6, 0x2, 0x4, 0xD, 0x1, 0x0, 0x9, 0x7, 0xB, 0xC, 0x5, 0x8 },
{0x2, 0x9, 0xE, 0x4, 0x7, 0xB, 0x1, 0x0, 0x8, 0x3, 0xD, 0xA, 0xF, 0xC, 0x5, 0x6 }
};
DWORD key[8];
memcpy (key, dwKey, 8*sizeof(DWORD));
int i, j;
DWORD a, b, a_new;
// Initialization:
for (i = 0; i <= 31; i++)
X[i] = key[indexes[i]];
DWORD d;
struct {
byte b0: 4;
byte b1: 4;
byte b2: 4;
byte b3: 4;
byte b4: 4;
byte b5: 4;
byte b6: 4;
byte b7: 4;
} tmp;
a = data[0]*256*256*256 + data[1]*256*256 + data[2]*256 + data[3];
b = data[4]*256*256*256 + data[5]*256*256 + data[6]*256 + data[7];
for( j = 0; j < 32; j++ ) { // Encryption cycles
d = fmod (a + X[j], pow(2,32));
memcpy(&tmp,&d,32);
tmp.b0 = H[0][tmp.b0];
tmp.b1 = H[1][tmp.b1];
tmp.b2 = H[2][tmp.b2];
tmp.b3 = H[3][tmp.b3];
tmp.b4 = H[4][tmp.b4];
tmp.b5 = H[5][tmp.b5];
tmp.b6 = H[6][tmp.b6];
tmp.b7 = H[7][tmp.b7];
memcpy(&d,&tmp,32);
a_new = ( ((d&0x001FFFFFUL) << 11) + ((d&0xFFE00000UL)>>21) ) ^ b;
b = a;
a = a_new;
};
data[0] = fmod(b>>24,256);
data[1] = fmod(b>>16,256);
data[2] = fmod(b>>8,256);
data[3] = fmod(b>>0,256);
data[4] = fmod(a>>24,256);
data[5] = fmod(a>>16,256);
data[6] = fmod(a>>8,256);
data[7] = fmod(a>>0,256);
};
//=================================================================================
/*
Параметры: data - массив из 8 байтов.
key - строка типа "10010101..." из 256 символов.
*/
void Encrypt2 (byte* data, ANSI strKey) {
DWORD key[8];
for (int i = 0; i <= 7; i++) {
key[i] = 0;
for (int j = 0; j <= 31; j++) {
key[i] += (strKey.at(i*32+j)-48) * pow(2,31-j);
}
}
Encrypt(data, key);
}
//=================================================================================
/*
Параметры: data - массив из 8 байтов.
key - массив из 8 double(ов).
*/
void Decrypt (byte* data, DWORD* dwKey) {
int indexes[] = {0,1,2,3,4,5,6,7,0,1,2,3,4,5,6,7,0,1,2,3,4,5,6,7,7,6,5,4,3,2,1,0};
DWORD X [32];
byte H[8][16] = {
{0x2, 0xE, 0x9, 0x5, 0x7, 0x6, 0x4, 0xA, 0x0, 0xB, 0x8, 0xD, 0x3, 0x1, 0xF, 0xC },
{0xA, 0xB, 0xE, 0x3, 0x4, 0xD, 0x7, 0x1, 0x6, 0x5, 0x2, 0x8, 0x0, 0xF, 0x9, 0xC },
{0x3, 0xA, 0x2, 0xC, 0x8, 0xE, 0xF, 0x4, 0x5, 0x6, 0xD, 0x0, 0x9, 0xB, 0x1, 0x7 },
{0xB, 0xE, 0xC, 0x4, 0x7, 0x6, 0xF, 0x9, 0x3, 0x8, 0x5, 0xD, 0x2, 0x1, 0x0, 0xA },
{0xC, 0xF, 0xA, 0x8, 0x2, 0x9, 0x7, 0x6, 0x3, 0x4, 0xE, 0x5, 0x1, 0xB, 0xD, 0x0 },
{0x8, 0x6, 0x2, 0x5, 0x3, 0xA, 0x4, 0x7, 0xD, 0x1, 0x9, 0xB, 0xC, 0xE, 0x0, 0xF },
{0x3, 0xF, 0xA, 0xE, 0x6, 0x2, 0x4, 0xD, 0x1, 0x0, 0x9, 0x7, 0xB, 0xC, 0x5, 0x8 },
{0x2, 0x9, 0xE, 0x4, 0x7, 0xB, 0x1, 0x0, 0x8, 0x3, 0xD, 0xA, 0xF, 0xC, 0x5, 0x6 }
};
DWORD key[8];
memcpy (key, dwKey, 8*sizeof(DWORD));
int i, j;
DWORD a, b, a_new;
// Initialization:
for (i = 0; i <= 31; i++)
X[i] = key[indexes[i]];
DWORD d;
struct {
byte b0: 4;
byte b1: 4;
byte b2: 4;
byte b3: 4;
byte b4: 4;
byte b5: 4;
byte b6: 4;
byte b7: 4;
} tmp;
a = data[0]*256*256*256 + data[1]*256*256 + data[2]*256 + data[3];
b = data[4]*256*256*256 + data[5]*256*256 + data[6]*256 + data[7];
for( j = 0; j < 32; j++ ) { // Decryption cycles
d = fmod(a + X[31-j], pow(2,32)); // !!! The only difference between encryption and decryption
memcpy(&tmp,&d,32);
tmp.b0 = H[0][tmp.b0];
tmp.b1 = H[1][tmp.b1];
tmp.b2 = H[2][tmp.b2];
tmp.b3 = H[3][tmp.b3];
tmp.b4 = H[4][tmp.b4];
tmp.b5 = H[5][tmp.b5];
tmp.b6 = H[6][tmp.b6];
tmp.b7 = H[7][tmp.b7];
memcpy(&d,&tmp,32);
a_new = ( ((d&0x001FFFFFUL) << 11) + ((d&0xFFE00000UL)>>21) ) ^ b;
b = a;
a = a_new;
};
data[0] = fmod(b>>24,256);
data[1] = fmod(b>>16,256);
data[2] = fmod(b>>8,256);
data[3] = fmod(b>>0,256);
data[4] = fmod(a>>24,256);
data[5] = fmod(a>>16,256);
data[6] = fmod(a>>8,256);
data[7] = fmod(a>>0,256);
};
//=================================================================================
/*
Параметры: data - массив из 8 байтов.
key - строка типа "10010101..." из 256 символов.
*/
void Decrypt2 (byte* data, ANSI strKey) {
DWORD key[8];
for (int i = 0; i <= 7; i++) {
key[i] = 0;
for (int j = 0; j <= 31; j++) {
key[i] += (strKey.at(i*32+j)-48) * pow(2,31-j);
}
}
Decrypt(data, key);
}
//=================================================================================
// Вспомогательная функция для перевода массива из 8 double(ов) в строку типа "1101010...".
ANSI DWORD8toANSI256 (DWORD* key) {
ANSI strData;
for (int k = 0; k <= 7; k++) {
char tmp[100];
ANSI strTmp = (byte*)ultoa(key[k],tmp,2);
int m = strTmp.size();
for (int mm = m; mm < 32; mm++) {
strTmp.insert(0,'0');
}
strData += strTmp;
}
return strData;
}