Главная
Архив новостей
Безопасность в Unix
Безопасность в Windows
Сборник FAQ'ов
Телефония, фрикинг
Кредитные карты
Криптография
Истории о хакерах
Программы, утилиты
_el@sp.sz.ru

RB2 Network

Что такое 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 к этому тексту, я думаю, Вы напишете сами.
          
<== Back to main page