XOR Decryption

I'm trying to XOR decrypt a cyphertext with a known plaintext.
the plaintext size is 256bit, the key is 64bit and the cyphertext is huge with >16000 bits. I'm suppose to find the key and this is my code. I have some problems running this, it keep telling me stack overflow and i dont know how to solve it. Please help!!! Thanks in advance

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <iso646.h>

using namespace std;

const int plainSize = 256;
const int numKey = 64;
const int keyRepeat = 4;
int *plainArray;
int *keyArray;
bool endList = false;

void takingPlaintext();

class LL{
private:
	struct node{
		int oriValue; //store original value from ciphertext
		int tempXORvalue;  //store temporary XOR value 
		struct node *next;
	};
	node *head;
public:
	int numMatch;

	LL() { 	head = nullptr;
			numMatch = 0;}
	~LL();

	void appendN(int); //append each int from ciphertext into linked list
	void giveXORvalue(int []); //tempXORvalue = oriValue ^ plaintext
	void delHead(); //delete head function
	void compareNode(int&, bool); //compare first tempXORvalue 8 times (because key is repeated 8*32 = 256 plaintext)
	void gatherKey(int[], int&);
};

int main()
{	
	ifstream inCipher;
	inCipher.open("ciphertext4.txt");

	LL oriList;
	keyArray = new int [numKey];
	
	int value;
	while(!inCipher.eof()){
		inCipher >> value;
		oriList.appendN(value);
	}

	takingPlaintext();

	oriList.gatherKey(keyArray,oriList.numMatch);

	delete []plainArray;
	delete []keyArray;
	inCipher.close();
	system("pause");
	return 0;
}

//functions
void takingPlaintext(){
	ifstream inPlain;
	inPlain.open("known plaintext fragment4.txt");
	plainArray = new int[plainSize];
	for (int i = 0; i < plainSize; i++)
		inPlain >> plainArray[i];
	inPlain.close();
}

LL::~LL(){
	node *nodePtr;
	node *nextNode;

	if(!head)
		return;
	
	nodePtr = head;
	while(nodePtr){
		nextNode = nodePtr->next;
		delete nodePtr;
		nodePtr = nextNode;
	}
}

void LL::appendN(int n){
	node *newNode;
	node *nodePtr;

	newNode = new node;
	newNode->oriValue = n;
	newNode->next = nullptr;

	if(!head)
		head = newNode;
	else{
		nodePtr = head;
		
		while(nodePtr->next != nullptr)
			nodePtr = nodePtr->next;

		nodePtr->next = newNode;
		}
}

void LL::giveXORvalue(int plainArray[]){
	node *nodePtr;
	nodePtr = head;
	for (int i = 0; i < plainSize; i++){
		nodePtr->tempXORvalue = plainArray[i] ^ nodePtr->oriValue;
		nodePtr = nodePtr->next;
	}
}

void LL::delHead(){
	node *tempHead;

	tempHead = head;
	head = head->next;
	delete tempHead;
}

void LL::compareNode(int &a, bool endList){
	node *nodePtr;
	giveXORvalue(plainArray);
	nodePtr = head;
	
	for (int i = 0; i < numKey; i++)
		if (nodePtr->next)
			nodePtr = nodePtr->next;
		else endList = true;


	if ((nodePtr->tempXORvalue == head->tempXORvalue) && (a != keyRepeat) && (endList == false)){
		a++;
		compareNode(a, endList);
	}
}

void LL::gatherKey(int keyArray[],int& numMatch){
	int a = 1;
	compareNode(a, endList);
	if (endList == false){
		if (numMatch < numKey)
			if (a != keyRepeat){
				if (numMatch != 0)
					numMatch = 0;

				delHead();
				gatherKey(keyArray,numMatch);
			}
			else{
				keyArray[numMatch] = head->tempXORvalue;
				numMatch++;
				delHead();
				gatherKey(keyArray,numMatch);
			}
		else
		{
			cout << "Key is found!" << endl;
			for (int i = 0; i < numKey; i++)
				cout << keyArray[i] << " ";
		}
	}
}
Last edited on
Known plaintext was encrypted using a simple xor mechanism, you're trying to find the original key correct?

(in other words, for me to recreate your problem I need to create a plaintext file then encrypt it)

(If this is for a cryptography lesson, how far have you gotten, do we include advanced techniques in the situation? Salt? Is it a moving key or just a static repeating key?)

(edit 2: if you would like to include a link to the plaintext and encrypted file that could possibly be useful, though not strictly necessary)
Last edited on
Yes, I'm trying to find the original key.
I'm doing this for an assignment in c++ data structure course.
I try to put every bit of the cypher text into a linked list and try to XOR it with the plain text, if the key is repetitively matched (4time because key is 64 bits and plain text is 256) then it is found. If it is matched, the program will delete the head of the linked list and move on to the next one.
here is cipher text file and plain text file.
http://www.mediafire.com/download/mxr8nx7n83lrtlt/ciphertext4.txt
http://www.mediafire.com/download/rh3sy3s5v4c1m44/known+plaintext+fragment4.txt
I'm just curious, why is the cipher text 16000+ bits when the plain text is only 256? Shouldn't they be the same length? Or is it that once you figure out the key using the first 256 bits, you need to decode the rest of the cipher text?
The message(16000+bits) is encrypted but we only know a piece of the outcome which is 256bits and the key to encrypt is unknown but for sure it's 64bits (so the message ^ plaintext = 4 time keys). The key is repeated 4 times to come up with 256bits.
The catch is we don't know which part of the message is the plaintext.
For example: let plaintext is 8bits and key is 4.
1 0 1 0 0 1 0 0 1 1 1 0 1 0 1 0 0 0 Message
0 1 1 0 1 0 1 1 Plaintext
-------------------
1 1 0 0-1 1 1 1 <- Wrong KEY


1 0 1 0 0 1 0 0 1 1 1 0 1 0 1 0 0 0 Message
---0 1 1 0 1 0 1 1 XOR Plaintext
---------------------
---0 0 1 0-0 0 1 0 <- Right Key


P/s: sorry, i dont know how to line them up in here
Last edited on
Topic archived. No new replies allowed.