Скачиваний:
71
Добавлен:
17.04.2013
Размер:
47.1 Кб
Скачать

Здесь приведена реализация ГОСТ, пусть не самая эффективная, но содержащая

несколько интересных, на мой взгляд, идей. Константы 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 <stdio.h>

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

Соседние файлы в папке Лаба2