|
Что такое GOST?
Здесь приведена реализация ГОСТ, пусть не самая эффективная, но содержащая
несколько интересных, на мой взгляд, идей. Константы C1 и C2 каждый желающий
может посмотреть в ГОСТе, здесь я их публиковать не буду (как я понимаю, именно
из-за них он -- ДСП).
ВАЖHОЕ ЗАМЕЧАHИЕ. Убедительная просьба при дальнейшей передаче исходников
передать Copyright и это важное замечание. Если же вы собираетесь использовать
этот код в коммерческих целях, прошу Вас связаться со мной и получить более
шуструю версию этих подпрограмм (до 500 KB/сек на 486 DX2/66), а также (если
пригодится) ЭЦП и хеширование.
Итак, %subj%.
-------------------------- Ghost.c ---
// The full implementation of the encryption/decryption algorithm
// GHOST-28147-89
// ( GHosudarstvenniy Obscherossiyskiy STandard Nr 28147 Dated 1989 ),
// electronic digital signature algorithm
// GHOST R 34.10-94
// ( GHOsudarstvenniy STandard Rossii Nr 10 Group 34 Dated 1994 )
// and hashing algorithm
// GHOST R 34.11-94
// ( GHOsudarstvenniy STandard Rossii Nr 11 Group 34 Dated 1994 )
// The first algorithm provides three modes of operation:
// -- Simple permutations;
// -- Gamming;
// -- Gamming with feedback;
// ( and a special mode for generating cryptographic checksum,
// which is not included in this package )
// The second and third algorithms were designed to work together
// to compute and check digital signatures.
// You MUST include the following copyright in each copy of these
// subroutines (except made for diplomas etc...)
// Copyright (C) 1995, by Stanislav Asanov
// FIDOnet: 2:5030/53.30
// Internet: acm@opensys.spb.su
#include
#include "ghost.h"
#pragma hdrstop
// Internal types
typedef BYTE PERM_TABLE[256];
// Internal variables
static Inited = NO;
// Keys
static DWORD X[32];
static PERM_TABLE K[4];
// Internal constant -- initialization order
static 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 };
void print_block( BYTE * addr, int len );
BOOL init( KEY key, SBOX sbox[8] )
{
int i, j, k;
if( Inited )
return( NO );
for( i = 0; i < NITEMS( X ); i++ )
X[i] = key[indexes[i]];
for( i = 0; i < 4; i++ )
for( j = 0; j < 16; j++ )
for( k = 0; k < 16; k++ )
K[i][ (j<<4) + k ] = ( sbox[i*2+1][j] << 4 ) + sbox[i*2][k];
return( Inited = YES );
};
BOOL terminate( void )
{
int i, j;
if( !Inited )
return( NO );
for( i = 0; i < NITEMS( X ); i++ )
X[i] = 0;
for( i = 0; i < 4; i++ )
for( j = 0; j < 256; j++ )
K[i][j] = 0;
Inited = NO;
return( YES );
};
// Simple permutation
void ghost_encrypt_sp( void ); // This function is done in assembler and does
all
void encrypt_sp( KEY key, BLOCK data )
{
DWORD a, b, a_new;
int i, j;
union {
DWORD d;
BYTE b[4];
} tmp;
if( !Inited )
return;
a = data[0];
b = data[1];
for( j = 0; j < 32; j++ ) { // Encryption cycles
tmp.d = a + X[j];
for( i = 0; i < NITEMS( tmp.b ); i++ )
tmp.b[i] = K[i][tmp.b[i]];
a_new = ( ((tmp.d&0x001FFFFFUL) << 11) + ((tmp.d&0xFFE00000UL)>>21) ) ^ b;
b = a;
a = a_new;
};
data[0] = b;
data[1] = a;
};
void decrypt_sp( BLOCK data )
{
DWORD a, b, a_new;
int i, j;
union {
DWORD d;
BYTE b[4];
} tmp;
if( !Inited )
return;
a = data[0];
b = data[1];
for( j = 0; j < 32; j++ ) { // Decryption cycles
tmp.d = a + X[31-j]; // !!! The only difference
// between encryption and decryption
for( i = 0; i < NITEMS( tmp.b ); i++ )
tmp.b[i] = K[i][tmp.b[i]];
a_new = ( ((tmp.d&0x001FFFFFUL) << 11) + ((tmp.d&0xFFE00000UL)>>21) ) ^ b;
b = a;
a = a_new;
};
data[0] = b;
data[1] = a;
};
#define Const_C1 0xXXXXXXXXUL
#define Const_C2 0xXXXXXXXXUL
void encrypt_g( BLOCK synchro, BYTE * data, UINT len )
{
BLOCK gamma;
ULONG lo, hi;
UINT chunk;
BYTE * p;
gamma[0] = synchro[0];
gamma[1] = synchro[1];
encrypt_sp( X, gamma );
lo = gamma[0];
hi = gamma[1];
while( len > 0 ) {
lo += Const_C2;
if( hi < (0xFFFFFFFFUL - Const_C1) )
hi += Const_C1;
else
hi += Const_C1 - 0xFFFFFFFFUL;
gamma[0] = lo;
gamma[1] = hi;
encrypt_sp( X, gamma );
chunk = ( len > 8 ) ? 8 : len;
len -= chunk;
p = (BYTE *) gamma;
while( chunk-- > 0 )
*data++ ^= *p++;
}
};
void encrypt_gfb( BLOCK synchro, BYTE * data, UINT len )
{
BLOCK gamma, * blk_data;
BYTE * p;
gamma[0] = synchro[0];
gamma[1] = synchro[1];
encrypt_sp( X, gamma );
while( len >= sizeof( BLOCK ) ) {
blk_data = (BLOCK *) data;
data += sizeof( BLOCK );
gamma[0] ^= (*blk_data)[0];
gamma[1] ^= (*blk_data)[1];
(*blk_data)[0] = gamma[0];
(*blk_data)[1] = gamma[1];
encrypt_sp( X, gamma );
len -= sizeof( BLOCK );
}
p = (BYTE *) gamma;
while( len-- > 0 )
*data++ ^= *p++;
};
void decrypt_gfb( BLOCK synchro, BYTE * data, UINT len )
{
BLOCK newgamma, gamma, * blk_data;
BYTE * p;
gamma[0] = synchro[0];
gamma[1] = synchro[1];
encrypt_sp( X, gamma );
while( len >= sizeof( BLOCK ) ) {
blk_data = (BLOCK *) data;
data += sizeof( BLOCK );
newgamma[0] = (*blk_data)[0];
newgamma[1] = (*blk_data)[1];
(*blk_data)[0] ^= gamma[0];
(*blk_data)[1] ^= gamma[1];
gamma[0] = newgamma[0];
gamma[1] = newgamma[1];
encrypt_sp( X, gamma );
len -= sizeof( BLOCK );
}
p = (BYTE *) gamma;
while( len-- > 0 )
*data++ ^= *p++;
};
-------------------------- End of Ghost.c ---
.h к этому тексту, я думаю, Вы напишете сами.
|