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