Скачиваний:
64
Добавлен:
17.04.2013
Размер:
4.98 Кб
Скачать
//
// Copyright (C) 1995, by Stanislav Asanov
//     FIDOnet:  2:5030/53.30
//     Internet: acm@opensys.spb.su
//
// (PATCHED)
//

#include "Gost.h"

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};
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 }
};
byte H_ [4][256];
DWORD X [32];
DWORD a, b, a_new, d;
long pow_2_32 = 4294967296;

typedef struct {
	byte b1: 8;
	byte b2: 8;
	byte b3: 8;
	byte b4: 8;
} _tmp;
_tmp tmp;

//=================================================================================
// Обязятельна инициализация перед использованием:
void Init () {
	memset (H_,0,sizeof(H_));
	for (int i = 0; i <= 3; i++) {
		for (int j = 0; j <= 255; j++) {
			int j1 = (int)floor(j/16);
			int j2 = j%16;
			H_[i][j] = H[i*2+1][j1]*16 + H[i*2][j2];
		}
	}
}

//=================================================================================
void Encrypt (DWORD* data, ANSI strKey) { // DWORD data[2]
	DWORD key[8];
	memcpy (key,ANSI256toDWORD8(strKey),8*sizeof(DWORD));
	for(int i = 0; i <= 31; i++ ) 
		X[i] = key[indexes[i]];
	a = data[0];
	b = data[1];
	for(int j = 0; j <= 31; j++ ) { // Encryption cycles
		d = a+X[j]-pow_2_32;
		if (d<0) d = -d;
		memcpy (&tmp,&d,4);
		tmp.b1 = H_[0][tmp.b1];
		tmp.b2 = H_[1][tmp.b2];
		tmp.b3 = H_[2][tmp.b3];
		tmp.b4 = H_[3][tmp.b4];
		memcpy (&d,&tmp,4);
		a_new = ( ((d&0x001FFFFFUL) << 11) + ((d&0xFFE00000UL)>>21) ) ^ b;
		b = a;
		a = a_new;
	};
	data[0] = b;
	data[1] = a;
}

//=================================================================================
void EncryptNum (DWORD* data, DWORD* key) { // DWORD data[2]; DWORD key[8];
	for(int i = 0; i <= 31; i++ ) 
		X[i] = key[indexes[i]];
	a = data[0];
	b = data[1];
	for(int j = 0; j <= 31; j++ ) { // Encryption cycles
		d = a+X[j]-pow_2_32;
		if (d<0) d = -d;
		memcpy (&tmp,&d,4);
		tmp.b1 = H_[0][tmp.b1];
		tmp.b2 = H_[1][tmp.b2];
		tmp.b3 = H_[2][tmp.b3];
		tmp.b4 = H_[3][tmp.b4];
		memcpy (&d,&tmp,4);
		a_new = ( ((d&0x001FFFFFUL) << 11) + ((d&0xFFE00000UL)>>21) ) ^ b;
		b = a;
		a = a_new;
	};
	data[0] = b;
	data[1] = a;
}

//=================================================================================
void Decrypt (DWORD* data, ANSI strKey) { // DWORD data[2]
	DWORD key[8];
	memcpy (key,ANSI256toDWORD8(strKey),8*sizeof(DWORD));
	for(int i = 0; i <= 31; i++ ) 
		X[i] = key[indexes[i]];
	a = data[0];
	b = data[1];
	for(int j = 0; j <= 31; j++ ) { // Encryption cycles
		d = a+X[31-j]-pow_2_32;
		if (d<0) d = -d;
		memcpy (&tmp,&d,4);
		tmp.b1 = H_[0][tmp.b1];
		tmp.b2 = H_[1][tmp.b2];
		tmp.b3 = H_[2][tmp.b3];
		tmp.b4 = H_[3][tmp.b4];
		memcpy (&d,&tmp,4);
		a_new = ( ((d&0x001FFFFFUL) << 11) + ((d&0xFFE00000UL)>>21) ) ^ b;
		b = a;
		a = a_new;
	};
	data[0] = b;
	data[1] = a;
}

//=================================================================================
void DecryptNum (DWORD* data, DWORD* key) { // DWORD data[2]; DWORD key[8];
	for(int i = 0; i <= 31; i++ ) 
		X[i] = key[indexes[i]];
	a = data[0];
	b = data[1];
	for(int j = 0; j <= 31; j++ ) { // Encryption cycles
		d = a+X[31-j]-pow_2_32;
		if (d<0) d = -d;
		memcpy (&tmp,&d,4);
		tmp.b1 = H_[0][tmp.b1];
		tmp.b2 = H_[1][tmp.b2];
		tmp.b3 = H_[2][tmp.b3];
		tmp.b4 = H_[3][tmp.b4];
		memcpy (&d,&tmp,4);
		a_new = ( ((d&0x001FFFFFUL) << 11) + ((d&0xFFE00000UL)>>21) ) ^ b;
		b = a;
		a = a_new;
	};
	data[0] = b;
	data[1] = a;
}

//=================================================================================
// Вспомогательная функция для перевода массива из 8-ми double(ов) в строку типа "1101010...".
ANSI DWORD8toANSI256 (DWORD* key) {
	ANSI strData;
	char tmp[100];
	for (int k = 0; k <= 7; k++) {
		ANSI strTmp = (byte*)ultoa(key[k],tmp,2);
		while (strTmp.size() <= 31)
			strTmp.insert(0,'0');
		strData += strTmp;
	}
	return strData;
}

//=================================================================================
// Вспомогательная функция для перевода строки "10110011..." в массив из 8-ми DWORD(ов).
DWORD* ANSI256toDWORD8 (ANSI str) {
	DWORD d[8];
	for (int k = 0; k <= 7; k++) {
		d[k] = 0;
		for (int i = 0; i <= 31; i++)
			d[k] += (str.at(k*32 + i)-48) * pow(2,31-i);
	}
	return d;
}
Соседние файлы в папке Gost89