Студопедия

КАТЕГОРИИ:


Архитектура-(3434)Астрономия-(809)Биология-(7483)Биотехнологии-(1457)Военное дело-(14632)Высокие технологии-(1363)География-(913)Геология-(1438)Государство-(451)Демография-(1065)Дом-(47672)Журналистика и СМИ-(912)Изобретательство-(14524)Иностранные языки-(4268)Информатика-(17799)Искусство-(1338)История-(13644)Компьютеры-(11121)Косметика-(55)Кулинария-(373)Культура-(8427)Лингвистика-(374)Литература-(1642)Маркетинг-(23702)Математика-(16968)Машиностроение-(1700)Медицина-(12668)Менеджмент-(24684)Механика-(15423)Науковедение-(506)Образование-(11852)Охрана труда-(3308)Педагогика-(5571)Полиграфия-(1312)Политика-(7869)Право-(5454)Приборостроение-(1369)Программирование-(2801)Производство-(97182)Промышленность-(8706)Психология-(18388)Религия-(3217)Связь-(10668)Сельское хозяйство-(299)Социология-(6455)Спорт-(42831)Строительство-(4793)Торговля-(5050)Транспорт-(2929)Туризм-(1568)Физика-(3942)Философия-(17015)Финансы-(26596)Химия-(22929)Экология-(12095)Экономика-(9961)Электроника-(8441)Электротехника-(4623)Энергетика-(12629)Юриспруденция-(1492)Ядерная техника-(1748)

Создание псевдослучайной функции




Для шифрования текста необходимо создать псевдослучайную функцию.

 

Процесс шифрования состоит из большого числа итераций, каждая из которых завершается генерацией псевдослучайной функции. Количество пройденных итераций показывает счетчик l. Все они подразделяются на несколько этапов с похожими операциями. На каждом этапе старшие 9 битов одного из регистров (A, B, C или D) используются в качестве указателя, по которому из таблицы T выбирается значение. Это значение складывается арифметически или поразрядно по модулю 2 (XOR) со следующим регистром (снова один из A, B, C или D). Затем первый выбранный регистр преобразуется циклическим сдвигом вправо на 9 позиций. Далее либо значение второго регистра модифицируется сложением или XORом с содержимым первого (уже сдвинутым) и выполняется переход к следующему этапу, либо этот переход выполняется сразу. После 8 таких этапов значения A, B, C и D складываются (арифметически или XORом) с определенными словами из таблицы S и добавляются в ключевую последовательность y. Завершающий этап итерации заключается в прибавлении к регистрам дополнительных 32-битных значений (n1, n2 или n3, n4). Причем выбор конкретного значения зависит от четности номера данной итерации.

Для шифрования каждого байта текста SEAL требует около пяти элементарных операций. На 50-мегагерцовом процессоре i486 он работает со скоростью 58 Мбит/с.

С другой стороны SEAL должен выполнить предварительную обработку, заполняя внутренние таблицы. Размер этих таблиц составляет примерно 3 Кбайт, а для их расчета нужно примерно 200 вычислений SHA. Та­ким образом, SEAL не подходит для тех случаев, когда не хватает времени для обработки ключа или памяти для хранения таблиц.

 


Листинг программы

 

#include <stdio.h>

#undef SEAL_DEBUG

#define ALG_OK 0

#define ALG_NOTOK 1

#define WORDS_PER_SEAL_CALL 1024

typedef struct {

unsigned long t[520]; /* 512 rounded up to a multiple of 5 + 5*/

unsigned long s[265]; /* 256 rounded up to a multiple of 5 + 5*/

unsigned long r[20]; /* 16 rounded up to multiple of 5 */

unsigned long counter; /* 32-bit synch value. */

unsigned long ks_buf[WORDS_PER_SEAL_CALL];

int ks_pos;

} seal_ctx;

#define ROT2(x) (((x) >> 2) | ((x) << 30))

#define ROT9(x) (((x) >> 9) | ((x) << 23))

#define ROT8(x) (((x) >> 8) | ((x) << 24))

#define ROT16(x) (((x) >> 16) | ((x) << 16))

#define ROT24(x) (((x) >> 24) | ((x) << 8))

#define ROT27(x) (((x) >> 27) | ((x) << 5))

#define WORD(cp) ((cp[0] << 24)|(cp[1] << 16)|(cp[2] << 8)|(cp[3]))

#define F1(x, y, z) (((x) & (y)) | ((~(x)) & (z)))

#define F2(x, y, z) ((x)^(y)^(z))

#define F3(x, y, z) (((x) & (y)) | ((x) & (z)) | ((y) & (z)))

#define F4(x, y, z) ((x)^(y)^(z))

int g(unsigned char *in, int i, unsigned long *h){

unsigned long h0;

unsigned long w[80];

unsigned long temp;

kp = in;

h0 = WORD(kp); kp += 4;

w[0] = i;

for (i=1;i<16;i++)

w[i] = 0;

for (i=16;i<80;i++)

w[i] = w[i-3]^w[i-8]^w[i-14]^w[i-16];

a = h0;

b = h1;

c = h2;

d = h3;

e = h4;

for (i=0;i<20;i++)

{

temp = ROT27(a) + F1(b, c, d) + e + w[i] + 0x5a827999;

e = d;

d = c;

c = ROT2(b);

b = a;

a = temp;

}

for (i=20;i<40;i++)

{

temp = ROT27(a) + F2(b, c, d) + e + w[i] + 0x6ed9eba1;

e = d;

d = c;

c = ROT2(b);

b = a;

a = temp;

}

for (i=40;i<60;i++)

{

temp = ROT27(a) + F3(b, c, d) + e + w[i] + 0x8f1bbcdc;

e = d;

d = c;

c = ROT2(b);

b = a;

a = temp;

}

for (i=60;i<80;i++)

{

temp = ROT27(a) + F4(b, c, d) + e + w[i] + 0xca62c1d6;

e = d;

d = c;

c = ROT2(b);

b = a;

a = temp;

}

h[0] = h0+a;

return (ALG_OK);

}

unsigned long gamma(unsigned char *a,int i)

{

unsigned long h[5];

(void) g(a, i/5, h);

return h[i % 5];

}

int seal_init(seal_ctx *result, unsigned char *key)

{

int i;

unsigned long h[5];

for (i=0;i<510;i+=5)

g(key, i/5, &(result->t[i]));

/* horrible special case for the end */

g(key, 510/5, h);

for (i=510;i<512;i++)

result->t[i] = h[i-510];

/* 0x1000 mod 5 is +1, so have horrible special case for the start */

g(key, (-1+0x1000)/5, h);

for (i=0;i<4;i++)

result->s[i] = h[i+1];

for (i=4;i<254;i+=5)

g(key, (i+0x1000)/5, &(result->s[i]));

/* horrible special case for the end */

g(key, (254+0x1000)/5, h);

for (i=254;i<256;i++)

result->s[i] = h[i-254];

/* 0x2000 mod 5 is +2, so have horrible special case at the start */

g(key, (-2+0x2000)/5, h);

for (i=0;i<3;i++)

result->r[i] = h[i+2];

for (i=3;i<13;i+=5)

g(key, (i+0x2000)/5, &(result->r[i]));

/* horrible special case for the end */

g(key, (13+0x2000)/5, h);

for (i=13;i<16;i++)

result->r[i] = h[i-13];

return (ALG_OK);

}

int seal(seal_ctx *key, unsigned long in, unsigned long *out)

{

int i;

int j;

int l;

unsigned long a;

unsigned long *wp;

wp = out;

for (l=0;l<4;l++)

{

a = in ^ key->r[4*l];

b = ROT8(in) ^ key->r[4*l+1];

c = ROT16(in) ^ key->r[4*l+2];

d = ROT24(in) ^ key->r[4*l+3];

for (j=0;j<2;j++)

{

p = a & 0x7fc;

b += key->t[p/4];

a = ROT9(a);

p = b & 0x7fc;

c += key->t[p/4];

b = ROT9(b);

p = c & 0x7fc;

d += key->t[p/4];

c = ROT9(c);

p = d & 0x7fc;

a += key->t[p/4];

d = ROT9(d);

}

n1 = d;

n2 = b;

n3 = a;

n4 = c;

p = a & 0x7fc;

b += key->t[p/4];

a = ROT9(a);

p = b & 0x7fc;

c += key->t[p/4];

b = ROT9(b);

p = c & 0x7fc;

d += key->t[p/4];

c = ROT9(c);

p = d & 0x7fc;

a += key->t[p/4];

d = ROT9(d);

/* This generates 64 32-bit words, or 256 bytes of keystream. */

for (i=0;i<64;i++)

{

p = a & 0x7fc;

b += key->t[p/4];

a = ROT9(a);

b ^= a;

q = b & 0x7fc;

c ^= key->t[q/4];

c = ROT9(c);

q = (q+d) & 0x7fc;

a += key->t[q/4];

d = ROT9(d);

*wp = b + key->s[4*i];

wp++;

*wp = c ^ key->s[4*i+1];

wp++;

*wp = d + key->s[4*i+2];

wp++;

*wp = a ^ key->s[4*i+3];

wp++;

if (i & 1)

{

a += n3;

c += n4;

}

else

{

a += n1;

c += n2;

}

}

}

return (ALG_OK);

}

/* Added call to refill ks_buf and reset counter and ks_pos. */

void seal_refill_buffer(seal_ctx *c){

seal(c,c->counter,c->ks_buf);

c->counter++;

c->ks_pos = 0;

}

void seal_key(seal_ctx *c, unsigned char *key){

seal_init(c,key);

c->counter = 0; /* By default, init to zero. */

c->ks_pos = WORDS_PER_SEAL_CALL;

/* Refill keystream buffer on next call. */

}

/* This encrypts the next w words with SEAL. */

void seal_encrypt(seal_ctx *c, unsigned long *data_ptr, int w){

int i;

for(i=0;i<w;i++){

if(c->ks_pos>=WORDS_PER_SEAL_CALL) seal_refill_buffer(c);

data_ptr[i]^=c->ks_buf[c->ks_pos];

c->ks_pos++;

}

}

void seal_decrypt(seal_ctx *c, unsigned long *data_ptr, int w) {

seal_encrypt(c,data_ptr,w);

}

void seal_resynch(seal_ctx *c, unsigned long synch_word){

c->counter = synch_word;

c->ks_pos = WORDS_PER_SEAL_CALL;

}

void main(void){

seal_ctx sc;

unsigned long buf[1000],t;

int i,flag;

unsigned char key[] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19};

seal_key(&sc,key);

FILE * in;

char win[100],wout[100];

printf("Vvedite ima vhodnogo faila: ");

gets(win);

printf("\nVvedite ima vihodnogo faila: ");

gets(wout);

in=fopen(win,"rt");

char stroka[1000];

/* printf("Algoritm shifrovania SEAL. \n\n1. Vvedite stroku:"); */

for(i=0;!feof(in);i++) stroka[i]=getc(in);

int kol=i-1;

for(i=0;i<1000;i++) buf[i]= int(stroka[i]);

/* for(kol=0;(kol<1000)&(buf[kol]!=0);kol++); */

seal_encrypt(&sc,buf,kol);

printf("\n\n");

printf("2. Encrypt: ");

t = 0;

for(i=0;i<kol;i++) t = t ^ buf[i];

FILE * out;

out=fopen(wout,"wt");

for(i=0;i<kol;i++) putc(char(buf[i]),out);

fclose(out);

for(i=0;i<kol;i++) printf("%c",buf[i]);

printf("\n\n");

seal_key(&sc,key);

seal_decrypt(&sc,buf,1);

seal_decrypt(&sc,buf+1,999);

printf("3. Decrypt: ");

for(i=0;i<kol;i++) printf("%c",buf[i]);

getchar();

}

 





Поделиться с друзьями:


Дата добавления: 2015-05-07; Просмотров: 452; Нарушение авторских прав?; Мы поможем в написании вашей работы!


Нам важно ваше мнение! Был ли полезен опубликованный материал? Да | Нет



studopedia.su - Студопедия (2013 - 2024) год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! Последнее добавление




Генерация страницы за: 0.041 сек.