- •Постановка задачі
- •Теоретична частина
- •Виконання роботи
- •3.1 Знаходження ключів
- •3.2 Шифрування
- •Виконаємо дії описані у функції fK Розділимо результат на 2 частини і пропустимо праву її частину через матрицю е/р:
- •3.3 Дешифрування
- •Виконаємо дії описані у функції fK
- •Ілюстрація роботи програми
- •Висновки
3.3 Дешифрування
Тепер 8-бітним текстом для дешифрування буде:
Encrypted = 0011 00102
Пропустимо наш шифрований текст через матрицю IP
IP |
3 |
1 |
4 |
8 |
5 |
7 |
2 |
6 |
00110010->10100100
Виконаємо дії описані у функції fK
E/P:
E/P |
4 |
1 |
2 |
3 |
2 |
3 |
4 |
1 |
0100->00101000
Виконаємо операцію XOR з K2
K2 |
1 |
0 |
0 |
0 |
0 |
1 |
1 |
0 |
00101000
1100 0110
11101110
Розділимо результат на 2 частини 1110 і 1110 і пропустимо їх через матриці S0 і S1 i отримаємо 1000
Пропустимо отримане значення через матрицю P4
P4 |
2 |
4 |
3 |
1 |
1000-> 0001
Виконаємо операцію XOR :
0001
1010
1011
Складаємо результат з правою частиною результату перетворення матрицею ІР і отримуємо функцію fK :
fK2 = 1011 0100
Пропустимо fK2 через SW отримаємо 0100 1011
Далі виконаємо ту саму функцію fK але для значення після SW 0100 1011:
Розділимо результат SW на 2 частини і пропустимо праву її частину через матрицю Е/Р:
E/P |
4 |
1 |
2 |
3 |
2 |
3 |
4 |
1 |
1011->11010111
Виконаємо операцію XOR з першим ключем K1
K1 |
0 |
1 |
1 |
1 |
1 |
0 |
0 |
0 |
11010111
01111000
10101111
Розділимо результат на 2 частини 1010 і 1111 і пропустимо їх через матриці S0 і S1 i отримаємо 1011
Пропустимо через матрицю P4
P4 |
2 |
4 |
3 |
1 |
1011->0111
Виконаємо операцію XOR:
0111
0100
0011
Об’єднуємо результат з правою частино результату SW і отримуємо результат другої функції fK:
fK1 = 0011 1011
Цей результат fK1 пропустимо через матрицю IP-
ІP- |
2 |
7 |
1 |
3 |
5 |
8 |
6 |
4 |
Decrypted = 0101 11012 (9310) - наше дешифроване значення, яке співпадає з тим, що ми подавали на самому початку на шифрування. Отже, розрахунки виконані правильно.
Ілюстрація роботи програми
Рис. 1. Головне вікно програми
У головному вікні програми (рис. 1) вводимо необхідні нам дані і натискаємо кнопку шифрування «Encrypt».
У полі «Encrypted text» з’являється десяткове значення шифрованого тексту (Рис. 2).
Рис. 2 Головне вікно програми (шифрування) Рис. 3. Головне вікно (результат дешифрування)
Щоб дешифрувати текст перемикаємо на режим «Decrypt» .Результат роботи програми бачимо на Рис. 3.
Вихідний код програми.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace Is.CourseWork
{
public partial class IsCourseWork : Form
{
#region Constants
int[] p10 = { 3, 5, 2, 7, 4, 10, 1, 9, 8, 6 };
int[] p8 = { 6, 3, 7, 4, 8, 5, 10, 9 };
int[] ep = { 4, 1, 2, 3, 2, 3, 4, 1 };
int[] p4 = { 2, 4, 3, 1 };
int[,] s0 = {
{ 1, 0, 3, 2 },
{ 3, 2, 1, 0 },
{ 0, 2, 1, 3 },
{ 3, 1, 3, 1 }
};
int[,] s1 = {
{ 1, 1, 2, 3 },
{ 2, 0, 1, 3 },
{ 3, 0, 1, 0 },
{ 2, 1, 0, 3 }
};
#endregion
#region Properties & Values
#region Keys block
string key = null; //initializing string for key
int[] tempArr; //declaring the temp massive
int[] keyArr = new int[10]; //initializing the massive for key
int[] Ls1Arr1 = new int[5]; //initializing the massive for Ls-1 Massive 1
int[] Ls1Arr2 = new int[5]; //initializing the massive for Ls-1 Massive 2
int[] Ls1And2Arr = new int[10]; //initializing the massive for union of Ls1Mass1 & Ls1Mass2
int[] k1Arr = new int[8]; //initializing the massive for key K1
int[] k2Arr = new int[8]; //initializing the massive for key K2
#endregion
#region Encrypting block
int[] textArr = new int[8];
int[] first4AftOp = new int[4]; //first four after IP shifting
int[] second4AftOp = new int[4];
int[] ipArr = new int[8];
int[] ipMinusArr = new int[8];
int[] s0Arr = new int[4];
int[] s1Arr = new int[4];
int[] convertArr = new int[4];
#endregion
int[] k1Array = null;
int[] k2Array = null;
IsCourseWorkKeyAlgorithm _keyAlg;
IsCourseWorkKeyAlgorithm keyAlg
{
get
{
if (_keyAlg == null)
{
_keyAlg = new IsCourseWorkKeyAlgorithm();
}
return _keyAlg;
}
}
IsCourseWorkEncDecAlgorithm _encDecAlg;
IsCourseWorkEncDecAlgorithm encDecAlg
{
get
{
if (_encDecAlg == null)
{
_encDecAlg = new IsCourseWorkEncDecAlgorithm();
}
return _encDecAlg;
}
}
#endregion
public IsCourseWork()
{
InitializeComponent();
}
#region Help Methods
private string toBin(int a, int length)
{
int a1 = (int)a;
float a2 = a - a1;
string result = null;
int[] bin = new int[255];
int i;
for (i = 0; ; i++)
{
bin[i] = a1 % 2;
a1 = a1 / 2;
if (a1 < 2)
break;
}
for (int j = 0; j <= i; j++)
{
a1 = a1 * 10 + bin[i - j];
}
result = a1.ToString();
while (result.Length != length)
{
result = "0" + result;
}
return result;
}
private int toDecimal(string bin)
{
long l = Convert.ToInt64(bin, 2);
int i = (int)l;
return i;
}
#endregion
#region Event Handlers
private void encryptDecrypt_Click(object sender, EventArgs e)
{
if (!String.IsNullOrEmpty(keyTb.Text) && !String.IsNullOrEmpty(textTb.Text) && !String.IsNullOrEmpty(ipTb.Text) && !String.IsNullOrEmpty(ipMinusTb.Text))
{
key = "01" + toBin(Convert.ToInt32(keyTb.Text), 8); //getting key from the form
if (k1Array == null)
k1Array = k1();
if (k2Array == null)
k2Array = k2();
_encDecAlg = new IsCourseWorkEncDecAlgorithm();
if (encryptRb.Checked == true)
{
encDecAlg.TextLbl.Text = "Text: ";
encDecAlg.IpMinusLbl.Text = "Encrypted Text: ";
encDecAlg.K1Lbl.Text = "K1: ";
encDecAlg.K2Lbl.Text = "K2: ";
encTextTb.Text = toDecimal(encryptDecryptText(textTb.Text, ipTb.Text, ipMinusTb.Text, k1Array, k2Array)).ToString();
}
if (decryptRb.Checked == true)
{
encDecAlg.TextLbl.Text = "Encrypted Text: ";
encDecAlg.IpMinusLbl.Text = "Decrypted Text: ";
encDecAlg.K1Lbl.Text = "K2: ";
encDecAlg.K2Lbl.Text = "K1: ";
encTextTb.Text = toDecimal(encryptDecryptText(textTb.Text, ipTb.Text, ipMinusTb.Text, k2Array, k1Array)).ToString();
}
}
else
{
MessageBox.Show("Input values!");
}
}
private void expandKeyAlg_Click(object sender, EventArgs e)
{
keyAlg.Show();
}
private void expandEncDecAlg_Click(object sender, EventArgs e)
{
encDecAlg.Show();
}
private void encryptRb_MouseClick(object sender, MouseEventArgs e)
{
encryptRb.Checked = true;
decryptRb.Checked = false;
encryptDecrypt.Text = "Encrypt";
expandEncDecAlg.Text = "Show enc alg";
textLabel.Text = "Text:";
encTextLbl.Text = "Encrypted text:";
textTb.Text = "";
encTextTb.Text = "";
}
private void decryptRb_MouseClick(object sender, MouseEventArgs e)
{
decryptRb.Checked = true;
encryptRb.Checked = false;
encryptDecrypt.Text = "Decrypt";
expandEncDecAlg.Text = "Show dec alg";
textLabel.Text = "Encrypted text:";
encTextLbl.Text = "Decrypted text:";
textTb.Text = "";
encTextTb.Text = "";
}
#endregion
#region Logic Methods
private int[] k1()
{
int i = 0, j = 0; //initializing counters
#region Text to P10
keyAlg.keyLbl.Text += key;
foreach (char symb in key) //writing key from string to massive
{
keyArr[i] = Convert.ToInt32(symb.ToString());
i++;
}
i = 0;
tempArr = new int[10];
foreach (int pos in p10) //making shifting using P10
{
tempArr[i] = keyArr[pos - 1];
keyAlg.P10Lbl.Text += tempArr[i];
i++;
}
keyArr = tempArr;
i = 0;
#endregion
#region LS-1
foreach (int symb in keyArr) //divide the array into two subarrays
{
if (i < 5)
Ls1Arr1[i++] = symb;
else
Ls1Arr2[j++] = symb;
}
i = 0;
j = 0;
tempArr = new int[Ls1Arr1.Length];
for (int k = 0; k < Ls1Arr1.Length; k++) //making shift for first array
{
if (k + 1 > 4)
{
tempArr[k] = Ls1Arr1[1];
keyAlg.Ls1LeftLbl.Text += tempArr[k];
}
else
{
tempArr[k] = Ls1Arr1[k + 1];
keyAlg.Ls1LeftLbl.Text += tempArr[k];
}
}
Ls1Arr1 = tempArr;
tempArr = new int[Ls1Arr2.Length];
for (int k = 0; k < Ls1Arr1.Length; k++) //making shift for second array
{
if (k + 1 > 4)
{
tempArr[k] = Ls1Arr2[1];
keyAlg.Ls1RightLbl.Text += tempArr[k];
}
else
{
tempArr[k] = Ls1Arr2[k + 1];
keyAlg.Ls1RightLbl.Text += tempArr[k];
}
}
Ls1Arr2 = tempArr;
#endregion
#region Text to P8 (K1)
//join two subarrays into one array
foreach (int symb in Ls1Arr1)
{
Ls1And2Arr[i++] = symb;
}
foreach (int symb in Ls1Arr2)
{
Ls1And2Arr[i++] = symb;
}
i = 0;
foreach (int pos in p8) //making shifting using P8
{
k1Arr[i] = Ls1And2Arr[pos - 1];
keyAlg.K1Lbl.Text += k1Arr[i];
i++;
}
i = 0;
#endregion
return k1Arr; //returning key
}
private int[] k2()
{
int i = 0; //initializing counters
#region LS2
tempArr = new int[Ls1Arr1.Length];
for (int k = 0; k < Ls1Arr1.Length; k++) //shifting first array
{
if (k + 1 > 3)
{
tempArr[k] = Ls1Arr1[0];
tempArr[k + 1] = Ls1Arr1[1];
keyAlg.Ls2LeftLbl.Text += tempArr[k];
keyAlg.Ls2LeftLbl.Text += tempArr[k + 1];
break;
}
else
{
tempArr[k] = Ls1Arr1[k + 2];
keyAlg.Ls2LeftLbl.Text += tempArr[k];
}
}
Ls1Arr1 = tempArr;
tempArr = new int[Ls1Arr2.Length];
for (int k = 0; k < Ls1Arr1.Length; k++) //shifting second array
{
if (k + 1 > 3)
{
tempArr[k] = Ls1Arr2[0];
tempArr[k + 1] = Ls1Arr2[1];
keyAlg.Ls2RightLbl.Text += tempArr[k];
keyAlg.Ls2RightLbl.Text += tempArr[k + 1];
break;
}
else
{
tempArr[k] = Ls1Arr2[k + 2];
keyAlg.Ls2RightLbl.Text += tempArr[k];
}
}
Ls1Arr2 = tempArr;
#endregion
#region Text to P8 again (K2)
Ls1And2Arr = new int[10];
//join two subarrays into one array
foreach (int symb in Ls1Arr1)
{
Ls1And2Arr[i++] = symb;
}
foreach (int symb in Ls1Arr2)
{
Ls1And2Arr[i++] = symb;
}
i = 0;
foreach (int pos in p8) //making shifting using P8
{
k2Arr[i] = Ls1And2Arr[pos - 1];
keyAlg.K2Lbl.Text += k2Arr[i].ToString();
i++;
}
i = 0;
#endregion
return k2Arr; //returning key
}
private string encryptDecryptText(string text, string ip, string ipMinus, int[] k1Arr, int[] k2Arr)
{
int i = 0;
string encText = null;
#region Getting masks & text
string binText = toBin(Convert.ToInt32(text), 8);
foreach (char symb in binText) //filling text array
{
textArr[i] = Convert.ToInt32(symb.ToString());
encDecAlg.TextLbl.Text += textArr[i].ToString();
i++;
}
i = 0;
foreach (char symb in ip) //filling IP array
{
ipArr[i++] = Convert.ToInt32(symb.ToString());
}
i = 0;
foreach (char symb in ipMinus) //filling ip- array
{
ipMinusArr[i++] = Convert.ToInt32(symb.ToString());
}
i = 0;
#endregion
#region First block
tempArr = new int[8];
foreach (int pos in ipArr) //shifting using IP mask
{
tempArr[i] = textArr[pos - 1];
encDecAlg.IpLbl.Text += tempArr[i].ToString();
if (i < 4)
first4AftOp[i] = textArr[pos - 1];
else
second4AftOp[i - 4] = textArr[pos - 1];
i++;
}
textArr = tempArr;
i = 0;
tempArr = new int[8];
foreach (int pos in ep) //shifting using E/P
{
tempArr[i] = textArr[pos + 4 - 1]; //+4 because of using the second four bits
encDecAlg.EpLbl.Text += tempArr[i];
i++;
}
textArr = tempArr;
i = 0;
#region XOR
foreach (int bit in textArr) //XOR
{
if (i < 4)
{
s0Arr[i] = bit ^ k1Arr[i];
encDecAlg.Xor11Lbl.Text += s0Arr[i];
}
else
{
s1Arr[i - 4] = bit ^ k1Arr[i];
encDecAlg.Xor11Lbl.Text += s1Arr[i - 4];
}
encDecAlg.K1Lbl.Text += k1Arr[i].ToString();
i++;
}
i = 0;
#endregion
#region S0 & S1
int s0_14 = toDecimal(s0Arr[0].ToString() + s0Arr[3].ToString());
int s0_23 = toDecimal(s0Arr[1].ToString() + s0Arr[2].ToString());
int s1_14 = toDecimal(s1Arr[0].ToString() + s1Arr[3].ToString());
int s1_23 = toDecimal(s1Arr[1].ToString() + s1Arr[2].ToString());
string s0Str = toBin(s0[s0_14, s0_23], 2);
string s1Str = toBin(s1[s1_14, s1_23], 2);
encDecAlg.S0Lbl.Text += s0Str;
encDecAlg.S1Lbl.Text += s1Str;
tempArr = new int[4];
foreach (char symb in s0Str + s1Str)
{
tempArr[i++] = Convert.ToInt32(symb.ToString());
}
i = 0;
#endregion
foreach (int pos in p4) //shifting using P4
{
convertArr[i] = tempArr[pos - 1];
encDecAlg.P4Lbl.Text += convertArr[i].ToString();
i++;
}
i = 0;
#region XOR
tempArr = new int[4];
foreach (int bit in first4AftOp) //XOR
{
tempArr[i] = bit ^ convertArr[i];
encDecAlg.Xor12Lbl.Text += tempArr[i];
i++;
}
i = 0;
#endregion
#region SW
for (int k = 0; k < 8; k++) //SW
{
if (k < 4)
textArr[k] = second4AftOp[k];
else
textArr[k] = tempArr[k - 4];
encDecAlg.SwLbl.Text += textArr[k].ToString();
}
#endregion
#endregion
#region Second block
foreach (int bit in textArr) //divide the array into two subarrays
{
if (i < 4)
first4AftOp[i] = bit;
else
second4AftOp[i - 4] = bit;
i++;
}
i = 0;
foreach (int pos in ep) //shifting using E/P
{
textArr[i] = second4AftOp[pos - 1];
encDecAlg.Ep2Lbl.Text += textArr[i];
i++;
}
i = 0;
#region XOR
foreach (int bit in textArr) //XOR
{
if (i < 4)
{
s0Arr[i] = bit ^ k2Arr[i];
encDecAlg.Xor21Lbl.Text += s0Arr[i].ToString();
}
else
{
s1Arr[i - 4] = bit ^ k2Arr[i];
encDecAlg.Xor21Lbl.Text += s1Arr[i - 4].ToString();
}
encDecAlg.K2Lbl.Text += k2Arr[i].ToString();
i++;
}
i = 0;
#endregion
#region S0 & S1
s0_14 = toDecimal(s0Arr[0].ToString() + s0Arr[3].ToString());
s0_23 = toDecimal(s0Arr[1].ToString() + s0Arr[2].ToString());
s1_14 = toDecimal(s1Arr[0].ToString() + s1Arr[3].ToString());
s1_23 = toDecimal(s1Arr[1].ToString() + s1Arr[2].ToString());
s0Str = toBin(s0[s0_14, s0_23], 2);
s1Str = toBin(s1[s1_14, s1_23], 2);
encDecAlg.S02Lbl.Text += s0Str;
encDecAlg.S12Lbl.Text += s1Str;
tempArr = new int[4];
foreach (char symb in s0Str + s1Str)
{
tempArr[i++] = Convert.ToInt32(symb.ToString());
}
i = 0;
#endregion
foreach (int pos in p4) //shifting using P4
{
convertArr[i] = tempArr[pos - 1];
encDecAlg.P42Lbl.Text += convertArr[i];
i++;
}
i = 0;
tempArr = new int[4];
foreach (int bit in first4AftOp) //XOR
{
tempArr[i] = bit ^ convertArr[i];
encDecAlg.Xor22Lbl.Text += tempArr[i];
i++;
}
i = 0;
for (int k = 0; k < 8; k++) //the union of two arrays into one
{
if (k < 4)
textArr[k] = tempArr[k];
else
textArr[k] = second4AftOp[k - 4];
}
tempArr = new int[8];
foreach (int pos in ipMinusArr)
{
tempArr[i++] = textArr[pos - 1];
}
i = 0;
#endregion
foreach (int elem in tempArr) //wtiting encoded text to string
{
encText += elem;
}
encDecAlg.IpMinusLbl.Text += encText;
return encText; //returning encoded text
}
#endregion
}
}