- •Вариант типа шифрования определяется числом n, или выбирается самостоятельно и согласуется с преподавателем. Литература.
- •Методические указания
- •Пример курсовой работы приведен в приложении.
- •Приложение
- •Федеральное государственное образовательное учреждение высшего профессионального образования
- •«Чувашский государственный университет им. И.Н. Ульянова»
- •Описание метода
- •Логика построения шифра и структура ключевой информации госТа.
- •Основной шаг криптопреобразования.
- •Базовые циклы криптографических преобразований.
- •Основные режимы шифрования.
- •Режимы шифрования Простая замена
- •Гаммирование.
- •Гаммирование с обратной связью.
- •Выработка имитовставки к массиву данных.
- •Выполнение
- •Блок-схема выработки эммитерной вставки
- •Программа
- •Пример работы
Выполнение
Для написания программы построим блок-схемы.
Блок-схема цикла зашифрования 32-З
Блок-схема цикла зашифрования 32-Р
Блок-схема выработки эммитерной вставки
Блок-схема зашифрования данных в режиме простой замены.
Блок-схема расшифрования данных в режиме простой замены.
Блок-схема выработки гаммы
Блок-схема зашифрования данных в режиме гаммирования с обратной связью
Блок-схема расшифрования данных в режиме гаммирования с обратной связью
Программа
//---------------------------------------------------------------------------
#include <vcl.h>
#include <stdio.h>
#pragma hdrstop
#include "main.h"
#include "utils.h"
#include "gost.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void trans_file(FILE *f0, FILE *f1)
{
int n;
char s[100], s0[100];
char a[16];
while (!feof(f0) ) {
n = fread(a, 1, 16, f0);
if (!n)
break;
strcpy(s, "");
for (int i=0; i<n ; i++) {
sprintf(s0, " %2x", a[i] & 0xff);
strcat(s, s0);
}
strcat(s, "\n");
fprintf(f1, s);
}
}
void __fastcall TForm1::RadioGroupActionClick(TObject *Sender)
{
switch (RadioGroupAction->ItemIndex) {
case 0:
/* 1 */
EditFileIn->ReadOnly = false;
BtnBrowseIn->Enabled = true;
/* 2 */
EditFileOut->ReadOnly = true;
BtnBrowseOut->Enabled = false;
break;
case 1:
/* 1 */
EditFileIn->ReadOnly = true;
BtnBrowseIn->Enabled = false;
/* 2 */
EditFileOut->ReadOnly = false;
BtnBrowseOut->Enabled = true;
break;
}
}
//---------------------------------------------------------------------------
void __fastcall TForm1::BtnBrowseInClick(TObject *Sender)
{
if (OpenDialog1->Execute() ) {
EditFileIn->Text = OpenDialog1->FileName;
Memo1->Lines->LoadFromFile(OpenDialog1->FileName);
}
}
//---------------------------------------------------------------------------
void __fastcall TForm1::BtnBrowseOutClick(TObject *Sender)
{
if (OpenDialog1->Execute() ) {
EditFileOut->Text = OpenDialog1->FileName;
Memo2->Lines->LoadFromFile(OpenDialog1->FileName);
}
}
//---------------------------------------------------------------------------
void __fastcall TForm1::BtnRunClick(TObject *Sender)
{
FILE *fin, *fout;
uint64 S;
for (int i=0; i<sizeof(uint64); i++)
S.bytes[i] = random(256);
if (EditKey->Text.Length() != 32) {
ShowMessage("Ключ должен быть 32 символов");
Abort();
}
memcpy((char *)K, (char *)EditKey->Text.data(), 32);
if (RadioGroupAction->ItemIndex == 0) {
Memo1->Lines->LoadFromFile(EditFileIn->Text);
fin = fopen( (char *)EditFileIn->Text.data(), "rb");
EditFileOut->Text = "1.txt";
fout = fopen("1.txt", "wb");
if (RadioGroupMode->ItemIndex == 0)
gost_ecb_encode(fin, fout);
else
gost_cfb_encode(fin, fout, S);
fclose(fin);
fclose(fout);
fin = fopen("1.txt", "rb");
fout = fopen("1.hex", "w");
trans_file(fin, fout);
fclose(fin);
fclose(fout);
Memo2->Lines->LoadFromFile("1.hex");
} else {
fin = fopen( (char *)EditFileOut->Text.data(), "rb");
EditFileIn->Text = "2.txt";
fout = fopen("2.txt", "wb");
if (RadioGroupMode->ItemIndex == 0)
gost_ecb_decode(fin, fout);
else
gost_cfb_decode(fin, fout);
fclose(fin);
fclose(fout);
Cursor = crDefault;
Memo1->Lines->LoadFromFile("2.txt");
}
}
//---------------------------------------------------------------------------
void __fastcall TForm1::BtnExitClick(TObject *Sender)
{
Close();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
FILE *ftbl = fopen("table", "rb");
fread(H, sizeof(uint8), 8 * 16, ftbl);
fclose(ftbl);
randomize();
}
//---------------------------------------------------------------------------
#include <stdio.h>
#include <string.h>
#include "utils.h"
uint32 K[8]; /* ключ */
uint8 H[8][16]; /* таблица замен */
uint8 K_Z[32] = { 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 };
uint8 K_R[32] = { 0, 1, 2, 3, 4, 5, 6, 7,
7, 6, 5, 4, 3, 2, 1, 0,
7, 6, 5, 4, 3, 2, 1, 0,
7, 6, 5, 4, 3, 2, 1, 0 };
uint8 K_I[16] = { 0, 1, 2, 3, 4, 5, 6, 7,
0, 1, 2, 3, 4, 5, 6, 7 };
void step(uint64 &N, uint32 X)
{
uint8 Z[8];
uint32 S;
int m;
S = sum_32_mod(N.parts[0], X);
split_32_by_4(S, Z);
for (m=0; m<8; m++)
Z[m] = H[m][Z[m]];
S = join_32_from_4(Z);
S = cycled_shift_left_11(S);
S ^= N.parts[1];
N.parts[1] = N.parts[0];
N.parts[0] = S;
}
void do_crypt(uint64 &N)
{
for (int i=0; i<32; i++)
step(N, K[K_Z[i]]);
xchg_64(N);
}
void do_decrypt(uint64 &N)
{
for (int i=0; i<32; i++)
step(N, K[K_R[i]]);
xchg_64(N);
}
void gost_ecb_encode(FILE *from, FILE *to)
{
uint64 a;
int n;
while (true) {
n = fread(&a, 1, sizeof(uint64), from);
if (!n)
break;
if (n != 8)
memset((uint8 *)&a + n, 0, 8 - n);
do_crypt(a);
fwrite(&a, sizeof(uint64), 1, to);
}
}
void gost_ecb_decode(FILE *from, FILE *to)
{
uint64 a;
while (true) {
if (!fread(&a, sizeof(uint64), 1, from))
break;
do_decrypt(a);
fwrite(&a, sizeof(uint64), 1, to);
}
}
void gost_ofb_encode(FILE *from, FILE *to, uint64 S)
{
uint64 a;
int n;
fwrite(&S, sizeof(uint64), 1, to);
while (true) {
do_crypt(S);
n = fread(&a, 1, sizeof(uint64), from);
if (!n)
break;
a.parts[0] ^= S.parts[0];
a.parts[1] ^= S.parts[1]; /* a ^= S */
fwrite(&a, 1, n, to);
}
}
void gost_ofb_decode(FILE *from, FILE *to)
{
uint64 S;
uint64 a;
int n;
fread(&S, sizeof(uint64), 1, from); /* read synchro */
while (true) {
do_crypt(S);
n = fread(&a, 1, sizeof(uint64), from);
if (!n)
break;
a.parts[0] ^= S.parts[0];
a.parts[1] ^= S.parts[1]; /* a ^= S */
fwrite(&a, 1, n, to);
}
}
void gost_cbc_encode(FILE *from, FILE *to, uint64 S)
{
uint64 a, a0, a1;
int n;
a0 = S;
fwrite(&S, sizeof(uint64), 1, to); /* write synchro */
while (true) {
n = fread(&a, 1, sizeof(uint64), from);
if (!n)
break;
if (n != 8)
memset((uint8 *)&a + n, 0, 8 - n);
a1.parts[0] = a.parts[0] ^ a0.parts[0];
a1.parts[1] = a.parts[1] ^ a0.parts[1]; /* a1 = a ^ a0 */
a0 = a;
do_crypt(a1);
fwrite(&a1, 1, 8, to);
}
}
void gost_cbc_decode(FILE *from, FILE *to)
{
uint64 S;
uint64 a, a0, a1;
int n;
fread(&S, sizeof(uint64), 1, from); /* read synchro */
a0 = S;
while (true) {
n = fread(&a, 1, sizeof(uint64), from);
if (!n)
break;
do_decrypt(a);
a1.parts[0] = a.parts[0] ^ a0.parts[0];
a1.parts[1] = a.parts[1] ^ a0.parts[1]; /* a1 = a ^ a0 */
a0 = a1;
fwrite(&a1, 1, n, to);
}
}
void gost_ctr_encode(FILE *from, FILE *to)
{
uint64 a;
uint64 C, T;
int n;
C.parts[0] = 0;
C.parts[1] = 0; /* C = 0 */
while (true) {
n = fread(&a, 1, sizeof(uint64), from);
if (!n)
break;
T = C;
do_crypt(T);
a.parts[0] ^= T.parts[0];
a.parts[1] ^= T.parts[1]; /* a ^= T */
fwrite(&a, 1, n, to);
C.parts[0]++;
if (C.parts[0] == 0)
C.parts[1]++;
}
}
void gost_cfb_encode(FILE *from, FILE *to, uint64 S)
{
uint64 a, b;
int n;
fwrite(&S, sizeof(uint64), 1, to); /* write synchro */
while (true) {
n = fread(&a, 1, sizeof(uint64), from);
if (!n)
break;
do_crypt(S);
a.parts[0] ^= S.parts[0];
a.parts[1] ^= S.parts[1]; /* a ^= S */
S = a;
fwrite(&a, 1, n, to);
}
}
void gost_cfb_decode(FILE *from, FILE *to)
{
uint64 S;
uint64 a, a0, a1, b;
int n;
fread(&S, sizeof(uint64), 1, from); /* read synchro */
while (true) {
n = fread(&a, 1, sizeof(uint64), from);
if (!n)
break;
do_crypt(S);
a0 = a;
a.parts[0] ^= S.parts[0];
a.parts[1] ^= S.parts[1]; /* a ^= S */
S = a0;
fwrite(&a, 1, n, to);
}
}
#include <stdio.h>
#include "utils.h"
uint32 sum_32_mod(uint32 A, uint32 B)
{
unsigned __int64 R = A + B;
return (uint32)R;
}
void split_32_by_4(uint32 what, uint8 where[])
{
for (int i=0; i<8; i++) {
where[i] = what & 0x0f;
what >>= 4;
}
}
uint32 join_32_from_4(uint8 from[])
{
uint32 r = 0;
for (int i=7; i>=0; i--) {
r <<= 4;
r |= from[i];
}
return r;
}
uint32 cycled_shift_left_11(uint32 a)
{
uint32 l = a & 0xffe00000;
uint32 r = a & 0x001fffff;
l >>= 21;
r = (r << 11) & 0xfffff800;
return r | l;
}
void xchg_64(uint64 &N)
{
uint32 t = N.parts[0];
N.parts[0] = N.parts[1];
N.parts[1] = t;
}
void outd(char *msg, uint64 a)
{
printf("%20s: ", msg);
for (int i=0; i<8; i++)
printf("%3x", a.bytes[i]);
printf("\n");
}