[My Home Page] [Contact information] [My Bookmark] [Music Page] [Articles] [HackPage] [Sign Guestbook] [My Public PGP Key]


Что такое 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 counter
My Home Page How to contact me My Bookmarks Music Page Articles Hack Page Welcome to Guestbook Windows (1251) encoding Unix  (Koi8) encoding My Public PGP Key
Hosted by uCoz