МІНІСТЕРСТВО ОСВІТИ І НАУКИ УКРАЇНИ
НАЦІОНАЛЬНИЙ УНІВЕРСИТЕТ “ЛЬВІВСЬКА ПОЛІТЕХНІКА”
кафедра «Захист інформації»
Звіт
про виконання лабораторної роботи №3
з дисципліни:
" Криптографія і стеганографія "
на тему:
«ПОТОКОВІ ШИФРИ»
Мета роботи – Ознайомитися з основними алгоритмами побудови генераторів псевдовипадкових послідовностей та лінійними регістрами зсуву з зворотнім зв’язком.
Завдання
Підготувати програму на об'єктно-орієнтованій мові програмування, яка реалізовуватиме потоковий шифр на основі генератора з кількома РЗЛЗЗ, об’єднаних нелінійним способом, використовуючи дані відповідно до індивідуального завдання (див. табл.1).
Таблиця 1
Варіант
Генератор
РЗЛЗЗ
Поліном Р(х)
Текст
2
Pike
2 Галуа
ПІБ
Теоретичні відомості
Pike
Pike - це збіднена і урізана версія Fish, запропонована Росом Андерсоном, тим, хто зламав Fish . Він використовує три адитивні генератори. Наприклад:
Для генерації слова потоку ключів погляньте на біти перенесення при складанні . Якщо усі три однакові (всі нулі або усі одиниці), то тактуються усі три генератори. Якщо ні, то тактуються тільки два співпадаючі генератори. Збережіть біти перенесення для наступного разу. Остаточним виходом є XOR виходів трьох генераторів.
Pike швидше Fish, оскільки в середньому для отримання результату треба 2.75 дій, а не 3. Він також слиш-ком нова, щоб йому довіряти, але виглядає дуже непогано.
Регістр Галуа
На відміну від регістра Фібоначчі, де зворотний зв'язок є функцією від всіх комірок в регістрі, а результат поміщається в саму ліву комірку, зворотний зв'язок в регістрі Галуа потенційно застосований до кожної комірки регістра, хоча є функцією тільки від самої правої комірки.
У РЗЛЗЗ Галуа можна модифікувати схему зворотного зв'язку перетворивши регістр в так звану "конфігурацію Галуа". Не можна сказати, що генератор, що вийшов в результаті, стає кращим з криптографічної точки зору, але він теж може мати максимальний період і простий в програмній реалізації. У цій схемі замість використання біт з точок знімання для генерації нового найлівішого біта, кожен біт з точки знімання XOR з виходом генератора і замінюється сумою, що вийшла; потім вихід генератора стає новим самим лівим бітом.[6] Таким чином, на відміну від регістру Фібоначчі, де зворотний зв'язок є функцією від всіх комірок в регістрі, а результат поміщається в найлівішу комірку, зворотний зв'язок в регістрі Галуа потенційно застосовний до кожної комірки регістра, хоча є функцією тільки від значення найправішої комірки.
Рис. 5. Схема регістру Галуа з лінійним зворотним зв’язком
Виграш тут в тому, що всі операції XOR можна виконувати як одну операцію. Цю схему також можна розпаралелювати, а окремі многочлени зворотного зв'язку можуть бути різні. Крім того, конфігурація Галуа може працювати швидше і при апаратній реалізації.
Підводячи загальний підсумок, можна сказати, що якщо використовується елементна база з швидкою реалізацією зсуву, то слід звернутися до регістрів Фібоначчі; якщо ж є можливість застосувати розпаралелювання, то кращий вибір - регістр Галуа.
У разі програмної реалізації найшвидшими є примітивні тричлени, оскільки для генерації кожного нового біту послідовності складаються всього два біти.
Текст програми:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
class Make
{
public void PrintIntArray(int[] array)
{
for (int i = 0; i < array.Length; i++)
Console.Write("{0}\t", array[i]);
Console.WriteLine();
}
public void PrintULongArray(ulong[] array)
{
for (int i = 0; i < array.Length; i++)
Console.Write("{0}\t", array[i]);
Console.WriteLine();
}
public uint SumModTwo(uint num1, uint num2)
{
if (num1 == num2)
return 0;
else
return 1;
}
public uint[] Galya(uint[] PreKey, uint[] Start, uint[] Koef)
{
//PrintIntArray(Start);
for (int i = 0; i < PreKey.Length; i++)
{
PreKey[i] = Start[Start.Length - 1];
for (int j = Koef.Length - 1; j >= 0; j--)
{
if (Koef[j] == 1)
Start[j] = SumModTwo(Start[j], PreKey[i]);
}
//PrintIntArray(Start);
for (int j = Start.Length - 1; j > 0; j--)
Start[j] = Start[j - 1];
Start[0] = PreKey[i];
//PrintIntArray(Start);
}
//PrintIntArray(PreKey);
return PreKey;
}
public void Source()
{
StreamReader streamReader = new StreamReader(@"C:\lab_3\1_word.txt");
string str = "";
while (!streamReader.EndOfStream)
{
str += streamReader.ReadLine();
}
streamReader.Close();
Console.WriteLine(str);
uint[] Start = new uint[] { 0, 1, 1, 0, 1, 1, 0, 1, 1, 0 };
uint[] PreKey = new uint[33];
uint[] FinKey = new uint[1760];
uint[] Koef1 = new uint[] { 1, 0, 0, 0, 0, 0, 1, 0, 0, 1 };
uint[] Koef2 = new uint[] { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1 };
PreKey = Galya(PreKey, Start, Koef1);
//PrintIntArray(PreKey);
FinKey = Galya(FinKey, PreKey, Koef2);
//PrintIntArray(FinKey);
ulong[] TenKey = new ulong[55];
TenKey = MakeTenArray(FinKey, 55, 32);
PrintULongArray(TenKey);
ulong[] ATenKey = new ulong[300];
ulong[] BTenKey = new ulong[300];
for (int i = 0; i < TenKey.Length; i++)
{
ATenKey[i] = TenKey[i];
BTenKey[i] = TenKey[i];
}
uint k1 = 55;
uint k2 = 52;
uint a = 0;
uint b = 1;
char[] Word = str.ToCharArray();
Console.WriteLine(Word);
uint length_masseg = (UInt32)Word.Length;
ulong[] InWord = new ulong[Word.Length];
Console.WriteLine(Word.Length);
for (int i = 0; i < Word.Length; i++)
InWord[i] = (UInt64)((int)(Word[i]));
PrintULongArray(InWord);
uint[] TwoFormWord = new uint[InWord.Length * 8];
TwoFormWord = MakeTwoArray(InWord, 0, length_masseg, 8);
Console.WriteLine(TwoFormWord.Length);
uint key_length = length_masseg * 8;
if (key_length % 32 != 0)
key_length = (UInt32)(key_length / 32) + 1;
else
key_length = (UInt32)(key_length / 32);
Console.WriteLine(key_length);
while (k1 < (key_length+55) && k2 < (key_length+52))
{
if (b == 1)
{
ATenKey[k1] = ATenKey[k1 - 55] + ATenKey[k1 - 24];
if (ATenKey[k1] >= (UInt64)(Math.Pow(2, 32)))
{
ATenKey[k1] = ATenKey[k1] % (UInt64)(Math.Pow(2, 32));
b = 0;
a = 1;
}
k1++;
}
if (a == 1)
{
BTenKey[k2] = BTenKey[k2 - 52] + BTenKey[k2 - 7];
if (BTenKey[k2] >= (UInt64)(Math.Pow(2, 32)))
{
BTenKey[k2] = BTenKey[k2] % (UInt64)(Math.Pow(2, 32));
b = 1;
a = 0;
}
k2++;
}
}
uint[] ATwoArray = new uint[key_length * 32];
uint[] BTwoArray = new uint[key_length * 32];
ATwoArray = MakeTwoArray(ATenKey, 55, key_length, 32);
BTwoArray = MakeTwoArray(BTenKey, 52, key_length, 32);
uint[] Key = new uint[key_length * 32];
for (int i = 0; i < Key.Length; i++)
Key[i] = SumModTwo(ATwoArray[i], BTwoArray[i]);
Console.WriteLine(Key.Length);
string ShyfrWord = "";
uint[] ShyfrTwoForm = new uint[TwoFormWord.Length];
for (int i = 0; i < ShyfrTwoForm.Length; i++)
ShyfrTwoForm[i] = SumModTwo(TwoFormWord[i], Key[i]);
ulong[] ShyfrTenForm = new ulong[Word.Length];
ShyfrTenForm = MakeTenArray(ShyfrTwoForm, (UInt32)Word.Length, 8);
PrintULongArray(ShyfrTenForm);
for (int i = 0; i < ShyfrTenForm.Length; i++)
ShyfrWord += (char)ShyfrTenForm[i];
Console.WriteLine(ShyfrWord);
StreamWriter sw = new StreamWriter(@"C:\lab_3\2_ShyfwrWord.txt");
sw.Write(ShyfrWord);
sw.Close();
}
public uint[] MakeTwoArray(ulong[] Array, uint Start, uint values, uint bits)
{
uint[] TwoArray = new uint[values * bits];
uint t = 0;
ulong k = 0;
for (uint i = Start; i < (Start + values); i++)
{
k = Array[i];
for (int j = 0; j < bits; j++)
{
if (k >= (UInt64)(Math.Pow(2, bits - 1 - j)))
{
TwoArray[t] = 1;
t++;
k = k - (UInt64)(Math.Pow(2, bits - 1 - j));
}
else
{
TwoArray[t] = 0;
t++;
}
}
}
return TwoArray;
}
public ulong[] MakeTenArray(uint[] Array, uint value, uint bits)
{
ulong[] TenArray = new ulong[value];
uint k = 0;
for (int i = 0; i < value; i++)
{
TenArray[i] = 0;
for (int j = 0; j < bits; j++)
{
//Console.WriteLine((Array[i][j]));
TenArray[i] += (UInt64)(Array[j + k] * Math.Pow(2, bits - 1 - j));
//Console.WriteLine(TenArray[i]);
}
k += bits;
}
return TenArray;
}
}
class Program
{
static void Main(string[] args)
{
Make m = new Make();
m.Source();
Console.ReadLine();
}
}
Результат роботи програми
Вміст файлу 1_word.txt: havrulyuk oksana vadumivna
Вміст файлу 2_ShyfwrWord.txt: þä¶L¦#·½¼8á£dùɴʸk
Вміст файлу 1_ 3_ReShyfwrWord.txt: havrulyuk oksana vadumivna
Висновок
На цій лабораторній роботі я ознайомилась з основними алгоритмами побудови генераторів псевдовипадкових послідовностей та лінійними регістрами зсуву з зворотнім зв’язком. Написала програму, яка поєднувала два лінійні регістри зсуву з зворотнім зв’язком Галуа із різними поліномами, та генератор псевдовипадкових чисел Pike.