In: Computer Science
SDES C++
The code is not working currently I know the functions are correct but the original plaintext should match the "ciphertext after" when inputting 4
#include <iostream>
#include <iomanip>
#include <string>
#include <stdlib.h>
#include <stdio.h>
#include <cstdlib>
#include <time.h>
#include <windows.h>
using namespace std;
//function prototypes
void splitString(string &x, string &y, string
&original);
void expansionFunction(string &input);
string XORstring(string& str1, string& str2);
string getSBOXValue(string arr[][8], string val);
int binaryToDecimal(int n);
string generateKey();
string findKey(string Key, int round);
string Encryption(string &plaintext, string key);
string Decryption(string& cipher, string key);
int main()
{
string plaintext = "011100100110", key =
"010011001";
cout << "SDES
Encryption|\n---------------|\n";
cout << "Original Plaintext = " <<
plaintext;
cout << "\nOriginal Key" << setw(9)
<<" = " << key << endl;
//split string int left and right
string left, right;
splitString(left, right, plaintext);
cout << endl << "L0 = " << left
<< endl << "R0 = " << right << endl;
cout << "\nL1 = R0" << endl;
string l1 = right; //assign l1 to be r0
//find r1
//first expand r0
string eRight = right;
expansionFunction(eRight);
//reduce key value by 1
key.resize(key.size() - 1);
cout << "\nXOR\n";
cout << "E(Right) = " << eRight <<
endl;
cout << "K1"<< setw(9) <<" = "
<< key << endl;
cout << "--------------------------" <<
endl;
// E(R0) xor k1
string XORresult = XORstring(eRight, key);
cout << setw(19) << XORresult;
//split string into s1 and s2
string S1BOX[2][8] =
{"101","010","001","110","011","100","111","000","001","100","110","010","000","111","101","011"};
string S2BOX[2][8] =
{"100","000","110","101","111","001","011","010","101","011","000","111","110","010","001","100"};
string s1, s2;
splitString(s1, s2, XORresult);
string s1result = getSBOXValue(S1BOX, s1);
string s2result = getSBOXValue(S2BOX, s2);
cout << "\nS1 = " << s1 << " = "
<< s1result << endl << "S2 = " << s2
<< " = " << s2result << endl;
string functionResult = s1result + s2result;
cout << endl << "Result from SBOX's is = "
<< functionResult << endl;
cout << "L0 XOR f(R0,K1) = " <<
XORstring(left, functionResult) << "(R1)\n";
string ciphertext = right + XORstring(left,
functionResult);
cout << "\nCiphertext(L1R1) = " <<
ciphertext << endl;
cout <<
"----------------------------------------------------------------------------------------\n"
<< endl;
int rounds;
cout << "Round SDES\n";
key = generateKey();
cout << endl;
string saveKey = key;
plaintext = "011100100110";
cout << "Random Key = " << key <<
endl;
cout << "Plaintext = " << plaintext
<< endl;
cout << "\nSelect number of SDES rounds\n->
";
cin >> rounds;
cout << endl;
cout << "Plaintext = " << plaintext
<< endl << endl;
for (int i = 0; i < rounds; i++)
{
key = findKey(key, i+1);
plaintext = Encryption(plaintext,
key);
cout << "Round " << i+1
<< " Ciphertext = " << plaintext << endl;
}
ciphertext = "";
ciphertext.append(plaintext, 6, 6);
ciphertext.append(plaintext, 0, 6);
cout << endl << "Ciphertext after "
<< rounds << " rounds: " << ciphertext <<
endl << endl;
cout << "Proof by decryption:\n\n" <<
"Ciphertext: " << ciphertext << endl << endl;
string d;
d.append(ciphertext, 6, 6);
d.append(ciphertext, 0, 6);
for (int j = rounds; j > 0; j--)
{
key = findKey(saveKey, j);
d = Decryption(d, key);
if (j != 1)
cout <<
"Round " << j << " Ciphertext = " << d <<
endl;
else if (j == 1)
cout <<
"\nSucceeding Plaintext is: " << d << endl;
}
return 0;
}
//function definitions
void splitString(string &x, string &y, string
&original)
{
x = original.substr(0,
original.length() / 2);
y =
original.substr(original.length() / 2);
}
void expansionFunction(string &input)
{
char temp;
//add two more letters to meet size requirement
input.append(input, 4, 2);
temp = input[3];
input[5] = input[2];
input[4] = temp;
input[3] = input[2];
input[2] = temp;
}
string XORstring(string& str1, string& str2)
{
string temp = str2;
for (int i = 0; i < str2.length(); i++)
{
temp[i] = (str1[i] ^ str2[i]) +
'0';
}
return temp;
}
string getSBOXValue(string arr[][8], string val)
{
int column;
if (val[0] == '0')
{
column = stoi(val.substr(1,
val.length()));
column =
binaryToDecimal(column);
for (int i = 0; i < 8;
i++)
if (i ==
column)
return arr[0][i];
}
else
{
column = stoi(val.substr(1,
val.length()));
column =
binaryToDecimal(column);
for (int i = 0; i < 8;
i++)
if (i ==
column)
return arr[1][i];
}
}
int binaryToDecimal(int n)
{
int decimal = 0;
// Initializing base value to 1, i.e 2^0
int base = 1;
int temp = n;
while (temp) {
int last = temp % 10;
temp = temp / 10;
decimal += last * base;
base = base * 2;
}
return decimal;
}
string generateKey()
{
string randomKey;
string binary[2] = { "0","1" };
randomKey.reserve(8);
srand(time(0));
cout << "Generating KEY...\n";
for (int i = 0; i < 9; i++)
{
randomKey +=
binary[rand()%2];
}
return randomKey;
}
string findKey(string Key, int round)
{
string temp;
//Get the key for the round
if (round == 1)
temp.append(Key, 0, 8);
else if (round == 2)
temp.append(Key, 1, 8);
else if (round == 3)
{
temp.append(Key, 2, 7);
temp.append(Key, 0, 1);
}
else if (round == 4)
{
temp.append(Key, 3, 6);
temp.append(Key, 0, 2);
}
return temp;
}
string Encryption(string &plaintext, string key)
{
string left, right, eRight, result, s1, s2, Ln,
Rn;
string S1BOX[2][8] = {
"101","010","001","110","011","100","111","000","001","100","110","010","000","111","101","011"
};
string S2BOX[2][8] = {
"100","000","110","101","111","001","011","010","101","011","000","111","110","010","001","100"
};
splitString(left, right, plaintext);
Ln = right; // Ln = Rn - 1
eRight = right;
//use expansion on right side
expansionFunction(eRight);
result = XORstring(eRight, key);
splitString(s1, s2, result);
string s1result = getSBOXValue(S1BOX, s1);
string s2result = getSBOXValue(S2BOX, s2);
string functionResult = s1result + s2result;
Rn = XORstring(left, functionResult);
return Ln + Rn; //L1R2
}
string Decryption(string& cipher, string key)
{
string Left, Right, eRight, Ln, Rn, result, s1,
s2;
string S1BOX[2][8] = {
"101","010","001","110","011","100","111","000","001","100","110","010","000","111","101","011"
};
string S2BOX[2][8] = {
"100","000","110","101","111","001","011","010","101","011","000","111","110","010","001","100"
};
//find key
splitString(Left, Right, cipher);
Rn = Left;
eRight = Rn;
expansionFunction(eRight);
result = XORstring(eRight, key);
splitString(s1, s2, result);
string s1result = getSBOXValue(S1BOX, s1);
string s2result = getSBOXValue(S2BOX, s2);
string functionResult = s1result + s2result;
Ln = XORstring(Right, functionResult);
return Ln + Rn;
}
#include <iostream>
#include <iomanip>
#include <string>
#include <stdlib.h>
#include <stdio.h>
#include <cstdlib>
#include <time.h>
#include <windows.h>
using namespace std;
//function prototypes
void splitString(string &x, string &y, string
&original);
void expansionFunction(string &input);
string XORstring(string& str1, string& str2);
string getSBOXValue(string arr[][8], string val);
int binaryToDecimal(int n);
string generateKey();
string findKey(string Key, int round);
string Encryption(string &plaintext, string key);
string Decryption(string& cipher, string key);
int main()
{
string plaintext = "011100100110", key =
"010011001";
cout << "SDES
Encryption|\n---------------|\n";
cout << "Original Plaintext = " <<
plaintext;
cout << "\nOriginal Key" << setw(9)
<< " = " << key << endl;
//split string int left and right
string left, right;
splitString(left, right, plaintext);
cout << endl << "L0 = " << left
<< endl << "R0 = " << right << endl;
cout << "\nL1 = R0" << endl;
string l1 = right; //assign l1 to be r0
//find r1
//first expand r0
string eRight = right;
expansionFunction(eRight);
//reduce key value by 1
key.resize(key.size() - 1);
cout << "\nXOR\n";
cout << "E(Right) = " << eRight <<
endl;
cout << "K1" << setw(9) << " = "
<< key << endl;
cout << "--------------------------" <<
endl;
// E(R0) xor k1
string XORresult = XORstring(eRight, key);
cout << setw(19) << XORresult;
//split string into s1 and s2
string S1BOX[2][8] = {
"101","010","001","110","011","100","111","000","001","100","110","010","000","111","101","011"
};
string S2BOX[2][8] = {
"100","000","110","101","111","001","011","010","101","011","000","111","110","010","001","100"
};
string s1, s2;
splitString(s1, s2, XORresult);
string s1result = getSBOXValue(S1BOX, s1);
string s2result = getSBOXValue(S2BOX, s2);
cout << "\nS1 = " << s1 << " = "
<< s1result << endl << "S2 = " << s2
<< " = " << s2result << endl;
string functionResult = s1result + s2result;
cout << endl << "Result from SBOX's is = "
<< functionResult << endl;
cout << "L0 XOR f(R0,K1) = " <<
XORstring(left, functionResult) << "(R1)\n";
string ciphertext = right + XORstring(left,
functionResult);
cout << "\nCiphertext(L1R1) = " <<
ciphertext << endl;
cout <<
"----------------------------------------------------------------------------------------\n"
<< endl;
int rounds;
cout << "Round SDES\n";
key = generateKey();
cout << endl;
string saveKey = key;
plaintext = "011100100110";
cout << "Random Key = " << key <<
endl;
cout << "Plaintext = " << plaintext
<< endl;
cout << "\nSelect number of SDES
rounds\n-> ";
cin >> rounds;
string *keyarray = new string[rounds];
for (int i = 0; i < rounds; i++)
{
keyarray[i] = generateKey();
}
cout << "Plaintext = " << plaintext
<< endl << endl;
for (int i = 0; i < rounds; i++)
{
key = keyarray[i];
plaintext = Encryption(plaintext,
key);
cout << "Round " << i +
1 << " Ciphertext = " << plaintext << endl;
}
ciphertext = "";
ciphertext.append(plaintext, 6, 6);
ciphertext.append(plaintext, 0, 6);
cout << endl << "Ciphertext after "
<< rounds << " rounds: " << ciphertext <<
endl << endl;
cout << "Proof by decryption:\n\n" <<
"Ciphertext: " << ciphertext << endl << endl;
string d;
d.append(ciphertext, 6, 6);
d.append(ciphertext, 0, 6);
for (int j = rounds; j > 0; j--)
{
key = keyarray[rounds - j];
d = Decryption(d, key);
if (j != 1)
cout <<
"Round " << j << " Ciphertext = " << d <<
endl;
else if (j == 1)
cout <<
"\nSucceeding Plaintext is: " << d << endl;
}
return 0;
}
//function definitions
void splitString(string &x, string &y, string
&original)
{
x = original.substr(0, original.length() / 2);
y = original.substr(original.length() / 2);
}
void expansionFunction(string &input)
{
char temp;
//add two more letters to meet size requirement
input.append(input, 4, 2);
temp = input[3];
input[5] = input[2];
input[4] = temp;
input[3] = input[2];
input[2] = temp;
}
string XORstring(string& str1, string& str2)
{
string temp = str2;
for (int i = 0; i < str2.length(); i++)
{
temp[i] = (str1[i] ^ str2[i]) +
'0';
}
return temp;
}
string getSBOXValue(string arr[][8], string val)
{
int column;
if (val[0] == '0')
{
column = stoi(val.substr(1,
val.length()));
column =
binaryToDecimal(column);
for (int i = 0; i < 8;
i++)
if (i ==
column)
return arr[0][i];
}
else
{
column = stoi(val.substr(1,
val.length()));
column =
binaryToDecimal(column);
for (int i = 0; i < 8;
i++)
if (i ==
column)
return arr[1][i];
}
}
int binaryToDecimal(int n)
{
int decimal = 0;
// Initializing base value to 1, i.e 2^0
int base = 1;
int temp = n;
while (temp) {
int last = temp % 10;
temp = temp / 10;
decimal += last * base;
base = base * 2;
}
return decimal;
}
string generateKey()
{
string randomKey;
string binary[2] = { "0","1" };
randomKey.reserve(8);
srand(time(0));
cout << "Generating KEY...\n";
for (int i = 0; i < 9; i++)
{
randomKey += binary[rand() %
2];
}
return randomKey;
}
string Encryption(string &plaintext, string key)
{
string left, right, eRight, result, s1, s2, Ln,
Rn;
string S1BOX[2][8] = {
"101","010","001","110","011","100","111","000","001","100","110","010","000","111","101","011"
};
string S2BOX[2][8] = {
"100","000","110","101","111","001","011","010","101","011","000","111","110","010","001","100"
};
splitString(left, right, plaintext);
Ln = right; // Ln = Rn - 1
eRight = right;
//use expansion on right side
expansionFunction(eRight);
result = XORstring(eRight, key);
splitString(s1, s2, result);
string s1result = getSBOXValue(S1BOX, s1);
string s2result = getSBOXValue(S2BOX, s2);
string functionResult = s1result + s2result;
Rn = XORstring(left, functionResult);
return Ln + Rn; //L1R2
}
string Decryption(string& cipher, string key)
{
string Left, Right, eRight, Ln, Rn, result, s1,
s2;
string S1BOX[2][8] = {
"101","010","001","110","011","100","111","000","001","100","110","010","000","111","101","011"
};
string S2BOX[2][8] = {
"100","000","110","101","111","001","011","010","101","011","000","111","110","010","001","100"
};
//find key
splitString(Left, Right, cipher);
Rn = Left;
eRight = Rn;
expansionFunction(eRight);
result = XORstring(eRight, key);
splitString(s1, s2, result);
string s1result = getSBOXValue(S1BOX, s1);
string s2result = getSBOXValue(S2BOX, s2);
string functionResult = s1result + s2result;
Ln = XORstring(Right, functionResult);
return Ln + Rn;
}
OUTPUT:
SDES Encryption|
---------------|
Original Plaintext = 011100100110
Original Key = 010011001
L0 = 011100
R0 = 100110
L1 = R0
XOR
E(Right) = 10101010
K1 = 01001100
--------------------------
11100110
S1 = 1110 = 101
S2 = 0110 = 011
Result from SBOX's is = 101011
L0 XOR f(R0,K1) = 110111(R1)
Ciphertext(L1R1) = 100110110111
----------------------------------------------------------------------------------------
Round SDES
Generating KEY...
Random Key = 110000011
Plaintext = 011100100110
Select number of SDES rounds
-> 4
Generating KEY...
Generating KEY...
Generating KEY...
Generating KEY...
Plaintext = 011100100110
Round 1 Ciphertext = 100110001011
Round 2 Ciphertext = 001011001101
Round 3 Ciphertext = 001101000110
Round 4 Ciphertext = 000110111010
Ciphertext after 4 rounds: 111010000110
Proof by decryption:
Ciphertext: 111010000110
Round 4 Ciphertext = 001101000110
Round 3 Ciphertext = 001011001101
Round 2 Ciphertext = 100110001011
Succeeding Plaintext is: 011100100110
NOTE: findKey() gave away wrong key for decryption hence wrong value was generated.